BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
StreamFactory.cxx
Go to the documentation of this file.
1/*
2 * StreamFactory.cxx
3 * ERS
4 *
5 * Created by Matthias Wiesmann on 21.01.05.
6 * Copyright 2005 CERN. All rights reserved.
7 *
8 */
9
10#include <cstdlib>
11#include <iostream>
12
13#include "ers/DefaultStream.h"
14#include "ers/StreamFactory.h"
15#include "ers/ers.h"
16
17/** This variable contains the default keys for building the default streams.
18 * The default is to use the default stream, in verbose mode for errors and fatals.
19 */
20
21const char* ers::StreamFactory::DEFAULT_STREAMS[] = { "null:", // none
22 "default:", "default:", "default:",
23 "default:", // debug levels
24 "default:", "default:",
25 "default:", // information, notification,
26 // warning
27 "default:verbose",
28 "default:verbose", // Errors and Fatals
29 "null:" }; // max
30
31/** Pointer to the singleton instance
32 */
33
35
36// Constructors & Instance access methods
37// --------------------------------------
38
39/** Constructor - should never be called by user code, use the \c instance() method instead
40 * \see instance()
41 */
42
44 for ( int i = static_cast<int>( severity_none ); i < static_cast<int>( severity_max ); i++ )
45 {
46 severity_t s = static_cast<severity_t>( i );
47 m_streams[s] = 0;
48 } // for*/
49} // StreamFactory
50
51/** Copy constructor - disabled, use the \c instance() method instead
52 * \see instance()
53 * \throw ers::NotImplemented in all cases
54 */
55
57 (void)other; // shut up the compiler
59} // StreamFactory
60
61/** Destructor - basic cleanup
62 * \note in practice this method should never be called, the singleton should never be
63 * deallocated
64 */
65
67 for ( int i = static_cast<int>( severity_none ); i < static_cast<int>( severity_max ); i++ )
68 {
69 severity_t s = static_cast<severity_t>( i );
70 if ( m_streams[s] )
71 {
72 delete ( m_streams[s] );
73 m_streams[s] = 0;
74 } // if stream
75 } // for*/
76} // ~StreamFactory
77
78/** This method returns the singleton instance.
79 * It should be used for every operation on the factory.
80 * \return a pointer to the singleton instance
81 */
82
84 if ( 0 == s_instance ) { s_instance = new StreamFactory(); } // if
85 return s_instance;
86} // instance
87
88/** Dumps all registered types of streams */
89
92 std::cerr << *factory;
93} // print_registered
94
95// Static methods
96// --------------------------------------
97
98/** Finds the default stream for a given severity.
99 * The stream is searched in the default instance
100 * \param s the severity_t
101 * \return the default stream for the severity_t
102 */
103
105 return instance()->get_stream( s );
106} // get_default_stream
107
108/** Searches for the textual key for a given severity.
109 * This key is first searched in the environnement variables,
110 * if this fails, the default values are loaded.
111 * The environnement variable should have the same name than the severity
112 * with the prefix ERS_ in front. The whole name should be in uppercases.
113 * For instance for severity_t warning, the environnement variable should be
114 * \c ERS_WARNING.
115 * \param s the severity_t
116 * \return the key describing the stream.
117 */
118
120 char key_buffer[64];
121 snprintf( key_buffer, sizeof( key_buffer ), "ERS_%s", ers::Core::to_string( s ) );
122 char* c = &( key_buffer[0] );
123 while ( *c )
124 {
125 *c = toupper( *c );
126 c++;
127 } // while
128 const char* env = ::getenv( key_buffer );
129 if ( env != 0 ) return env;
130 const char* static_key = DEFAULT_STREAMS[s];
131 if ( static_key ) return static_key;
133} // key_for_severity
134
135/** Builds a stream from a textual key
136 * The key should have the format \c protocol:path.extension
137 * In certain cases, the path will be empty.
138 * For instance to write in XML format to the error stream, the key is:
139 * \c cerr:.xml
140 * \param key the textual key
141 * \note the stream is allocated on the stack, it is the caller's responsibility to delete it.
142 */
143
145 std::string protocol;
146 std::string uri;
147
148 std::string::size_type colon = key.find( ':' );
149 if ( colon == std::string::npos ) { protocol = key; }
150 else
151 {
152 protocol = key.substr( 0, colon );
153 std::string::size_type uri_start = colon + 1;
154 if ( uri_start < key.size() ) { uri = key.substr( uri_start ); } // if
155 } // colon present
156 for ( stream_factory_collection::const_iterator pos = m_factories.begin();
157 pos != m_factories.end(); ++pos )
158 {
159 create_stream_callback callback = pos->second;
160 Stream* s = callback( protocol, uri );
161 if ( s != 0 ) return s;
162 } // for
163 fprintf( stderr, "Warning, could not find stream for key protocol=\"%s\" uri=\"%s\" (%s)\n",
164 protocol.c_str(), uri.c_str(), key.c_str() );
165 return new DefaultStream();
166} // create_stream
167
168/** Builds a stream for a given severity.
169 * The actual key for the severity_t is found using \c key_for_severity,
170 * then the appropriate stream is constructred using \c create_stream
171 * \see key_for_severity()
172 * \see create_stream()
173 * \param s the severity_t of the requested stream
174 * \return the newly created stream
175 * \note the stream is allocated on the stack, it is the caller's responsibility to delete it.
176 */
177
179 const char* key = key_for_severity( s );
180 return create_stream( key );
181} // get_stream
182
183/** Sends an Issue to the fatal error stream
184 * \param issue_ptr
185 */
186
188 ERS_PRE_CHECK_PTR( issue_ptr );
189 issue_ptr->severity( ers::fatal );
190 dispatch( issue_ptr, false );
191} // fatal
192
193/** Sends an Issue to the error stream
194 * \param issue_ptr
195 */
196
198 ERS_PRE_CHECK_PTR( issue_ptr );
199 issue_ptr->severity( ers::error );
200 dispatch( issue_ptr, false );
201} // error
202
203/** Sends an Issue to the warning stream
204 * \param issue_ptr the issue to send
205 */
206
208 ERS_PRE_CHECK_PTR( issue_ptr );
209 issue_ptr->severity( ers::warning );
210 dispatch( issue_ptr, false );
211} // warning
212
213/** Sends an issue to the debug stream
214 * \param issue_ptr the Issue to send
215 * \param s the severity_t of the associated stream.
216 * Accepted values: \li \c ers_debug_0 \li \c ers_debug_1 \li \c ers_debug_2 \li \c
217 * ers_debug_3
218 */
219
221 ERS_PRE_CHECK_PTR( issue_ptr );
222 ERS_PRECONDITION( s < ers::information, "severity_t is not debug : %s (%d) %d",
224 issue_ptr->severity( s );
225 dispatch( issue_ptr, false );
226} // debug
227
228/** Sends a message to the debug stream
229 * \param c the Context of the message
230 * \param message the text of the message
231 * \param s the severity_t of the associated stream. Accepted values: \li \c ers_debug_0 \li \c
232 * ers_debug_1 \li \c ers_debug_2 \li \c ers_debug_3
233 */
234
235void ers::StreamFactory::debug( const Context& c, const std::string& message, severity_t s ) {
236 LogIssue log_issue( c, s, message );
237 debug( &log_issue, s );
238} // debug
239
240/** Sends a message to the warning stream
241 * \param c the context of the message
242 * \param message the message to send
243 */
244
245void ers::StreamFactory::warning( const Context& c, const std::string& message ) {
246 LogIssue log_issue( c, ers::warning, message );
247 warning( &log_issue );
248} // warning
249
250/** Dispatches an issue to the appropriate stream.
251 * The stream is decided based upon the severity_t specified in the Issue.
252 * If \c throw_error is true errors and fatal errors are not sent to a stream, but thrown in
253 * the context of the caller. \param issue_ptr the Issue to dispatch \param throw_error should
254 * errors and fatals are thrown
255 */
256
257void ers::StreamFactory::dispatch( Issue* issue_ptr, bool throw_error ) {
258 ERS_PRE_CHECK_PTR( issue_ptr );
259 if ( throw_error && issue_ptr->is_error() ) { throw *issue_ptr; }
260 const severity_t s = issue_ptr->severity();
261 Stream* stream_ptr = instance()->get_stream( s );
262 ERS_CHECK_PTR( stream_ptr );
263 stream_ptr->send( issue_ptr );
264} // dispatch
265
266void ers::StreamFactory::dispatch( Issue& issue_ref, bool throw_error ) {
267 dispatch( &issue_ref, throw_error );
268} // dispatch
269
270void ers::StreamFactory::set_stream( severity_t s, const std::string& key ) {
271 instance()->set( s, key.c_str() );
272} // set
273
274// Member methods
275// --------------------------------------
276
277/** Gets stream for severity_t
278 * \param s the severity_t of the requested stream
279 * \return the stream
280 */
281
283 if ( m_streams[s] == 0 ) { m_streams[s] = create_stream( s ); } // if
284 return m_streams[s];
285} // get_stream
286
287/** Sets the stream for a given severity_t
288 * \param severity_t severity_t of the stream
289 * Accepted values: \li \c ers_debug_0 \li \c ers_debug_1 \li \c ers_debug_2 \li \c ers_debug_3
290 * \li \c ers_information \li \c ers_notification \li \c ers_warning
291 * \li \c ers::error \li \c ers_fatal
292 * \param s the new stream
293 */
294
297 ERS_PRECONDITION( severity_none < severity && severity < severity_max,
298 "illegal severity_t %d", (int)severity );
299 if ( m_streams[severity] ) { delete m_streams[severity]; } // if there is a stream defined
300 m_streams[severity] = s;
301} // stream
302
303/** Builds a stream using a string key and sets it up for a given severity
304 * \param severity_t severity_t of the stream
305 * Accepted values: \li \c ers_debug_0 \li \c ers_debug_1 \li \c ers_debug_2 \li \c ers_debug_3
306 * \li \c ers_information \li \c ers_notification \li \c ers_warning
307 * \li \c ers::error \li \c ers_fatal
308 * \param key the key used to build the new stream
309 */
310
311void ers::StreamFactory::set( severity_t severity, const char* key ) {
314 set( severity, s );
315} //
316
317/**
318 * \return the current fatal stream
319 */
320
322
323/**
324 * \return the current error stream
325 */
326
328
329/**
330 * \return the current warning stream
331 */
332
334
335/** Finds the debug stream
336 * \param s the severity_t of the associated stream.
337 * Accepted values: \li \c ers_debug_0 \li \c ers_debug_1 \li \c ers_debug_2 \li \c ers_debug_3
338 * \return debug stream
339 */
340
343 "severity_t is not debug : %s (%d)", ers::Core::to_string( s ), s );
344 return get_stream( s );
345} // debug
346
347/** Registers a factory function with the stream factory.
348 * The callback is function that takes two parameters <ol>
349 * <li>a string describing the protocol, for instance \c file </li>
350 * <li>a string describing a uri, can be a path, a suffix or anything</li>
351 * </ol>
352 * The function should return a heap allocated stream, or null if it does not
353 * understand the protocol.
354 * \param name name of the stream type (human display only).
355 * \param callback the callback function
356 * \return \c true if the registration was sucessfull
357 */
358
359bool ers::StreamFactory::register_factory( const std::string& name,
360 create_stream_callback callback ) {
361 // std::cerr << "registering " << name << std::endl ;
362 m_factories[name] = callback;
363 return true;
364} // register_factory
365
366/** Writes a description of the factory to a stream.
367 * This method gives a list of all registered stream types.
368 * \param stream the stream to write into
369 */
370
371void ers::StreamFactory::write_to( std::ostream& stream ) const {
372 stream << "Stream factory - registered streams\n";
373 stream << "-----------------------------------\n";
374 int i = 0;
375 for ( stream_factory_collection::const_iterator pos = m_factories.begin();
376 pos != m_factories.end(); ++pos )
377 {
378 std::string name = pos->first;
379 stream << i << ")\t" << name << std::endl;
380 i++;
381 } // for
382 stream << "-----------------------------------\n";
383} // write_to
384
385/** Streaming operator
386 * \param stream destination stream
387 * \param factory the factory object to display
388 * \return the stream passed as first parameter
389 * \see ers::StreamFactory::write_to()
390 */
391
392std::ostream& ers::operator<<( std::ostream& stream, const ers::StreamFactory& factory ) {
393 factory.write_to( stream );
394 return stream;
395} // operator
#define ERS_NOT_IMPLEMENTED()
#define ERS_PRECONDITION(expr,...)
XmlRpcServer s
*************DOUBLE PRECISION m_pi *DOUBLE PRECISION m_HvecTau2 DOUBLE PRECISION m_HvClone2 DOUBLE PRECISION m_gamma1 DOUBLE PRECISION m_gamma2 DOUBLE PRECISION m_thet1 DOUBLE PRECISION m_thet2 INTEGER m_IFPHOT *COMMON c_Taupair $ !Spin Polarimeter vector first Tau $ !Spin Polarimeter vector second Tau $ !Clone Spin Polarimeter vector first Tau $ !Clone Spin Polarimeter vector second Tau $ !Random Euler angle for cloning st tau $ !Random Euler angle for cloning st tau $ !Random Euler angle for cloning st tau $ !Random Euler angle for cloning nd tau $ !Random Euler angle for cloning nd tau $ !Random Euler angle for cloning nd tau $ !phi of HvecTau1 $ !theta of HvecTau1 $ !phi of HvecTau2 $ !theta of HvecTau2 $ !super key
Definition Taupair.h:42
Source context for Issue.
static const char * to_string(severity_t s)
severity_t to string
Definition Core.cxx:25
Root Issue class.
severity_t severity() const
severity_t of the issue
bool is_error()
is the issue an error (or fatal).
Wrapper for log messages.
Factory for Stream objects and repository of default streams.
static const char * key_for_severity(severity_t s)
finds key for severity_t
static void set_stream(severity_t, const std::string &key)
Stream * create_stream(severity_t s)
create a stream for severity_t
Stream * warning()
Warning stream.
static void dispatch(Issue *i, bool throw_error=false)
Sends an issue to the appropriate stream according to its severity_t.
static Stream * get_default_stream(severity_t s)
builds default stream for severity_t
bool register_factory(const std::string &name, create_stream_callback callback)
register a factory method
Stream *(* create_stream_callback)(const std::string &, const std::string &)
static void print_registered()
static const char * DEFAULT_STREAMS[]
keys for default streams
static StreamFactory * instance()
return the singleton
Stream * fatal()
Fatal stream.
stream_factory_collection m_factories
collection of factories to build streams
static StreamFactory * s_instance
singleton instance
void set(severity_t severity, Stream *s)
Sets the stream for a given severity_t.
Stream * get_stream(severity_t s)
get stream for severity_t
Stream * m_streams[severity_max]
array of pointers to streams per severity_t
void write_to(std::ostream &stream) const
write content of factory to stream
static void debug(Issue *i, severity_t)
sends an Issue to the debug stream
Stream * error()
Error stream.
Root/Null issue stream.
virtual void send(const Issue *i)
Sends an issue into the stream.
Definition Stream.cxx:47
efhlt::Interface * factory(void)
Definition factory.cxx:15
std::ostream & operator<<(std::ostream &, const Issue &)
enum ers::_severity_t severity_t