BOSS 7.0.5
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 <iostream>
11#include <cstdlib>
12
13#include "ers/StreamFactory.h"
14#include "ers/DefaultStream.h"
15#include "ers/ers.h"
16
17
18/** This variable contains the default keys for building the default streams.
19 * The default is to use the default stream, in verbose mode for errors and fatals.
20 */
21
23 "null:", // none
24 "default:", "default:", "default:", "default:", // debug levels
25 "default:", "default:", "default:", // information, notification, warning
26 "default:verbose", "default:verbose", // Errors and Fatals
27 "null:" } ; // max
28
29
30/** Pointer to the singleton instance
31 */
32
34
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 severity_t s = static_cast<severity_t> (i) ;
46 m_streams[s]=0 ;
47 } // for*/
48} // StreamFactory
49
50/** Copy constructor - disabled, use the \c instance() method instead
51 * \see instance()
52 * \throw ers::NotImplemented in all cases
53 */
54
56 (void) other ; // shut up the compiler
58} // StreamFactory
59
60/** Destructor - basic cleanup
61 * \note in practice this method should never be called, the singleton should never be deallocated
62 */
63
65 for(int i= static_cast<int> (severity_none);i< static_cast<int> (severity_max);i++) {
66 severity_t s = static_cast<severity_t> (i) ;
67 if(m_streams[s]) {
68 delete(m_streams[s]);
69 m_streams[s]=0 ;
70 } // if stream
71 } // for*/
72} // ~StreamFactory
73
74
75/** This method returns the singleton instance.
76 * It should be used for every operation on the factory.
77 * \return a pointer to the singleton instance
78 */
79
81 if (0==s_instance) {
82 s_instance = new StreamFactory();
83 } // if
84 return s_instance ;
85} // instance
86
87/** Dumps all registered types of streams */
88
90 const StreamFactory *factory = instance();
91 std::cerr << *factory ;
92} // print_registered
93
94// Static methods
95// --------------------------------------
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 *c = toupper(*c) ;
125 c++ ;
126 } // while
127 const char *env = ::getenv(key_buffer) ;
128 if (env!=0) return env ;
129 const char* static_key = DEFAULT_STREAMS[s] ;
130 if (static_key) return static_key ;
132} // key_for_severity
133
134/** Builds a stream from a textual key
135 * The key should have the format \c protocol:path.extension
136 * In certain cases, the path will be empty.
137 * For instance to write in XML format to the error stream, the key is:
138 * \c cerr:.xml
139 * \param key the textual key
140 * \note the stream is allocated on the stack, it is the caller's responsibility to delete it.
141 */
142
144 std::string protocol ;
145 std::string uri ;
146
147 std::string::size_type colon = key.find(':') ;
148 if (colon==std::string::npos) {
149 protocol = key ;
150 } else {
151 protocol = key.substr(0,colon) ;
152 std::string::size_type uri_start = colon+1 ;
153 if (uri_start<key.size()) {
154 uri = key.substr(uri_start) ;
155 } // if
156 } // colon present
157 for(stream_factory_collection::const_iterator pos=m_factories.begin();pos!=m_factories.end();++pos) {
158 create_stream_callback callback = pos->second;
159 Stream *s = callback(protocol,uri);
160 if (s!=0) return s ;
161 } // for
162 fprintf(stderr,"Warning, could not find stream for key protocol=\"%s\" uri=\"%s\" (%s)\n",protocol.c_str(),uri.c_str(),key.c_str());
163 return new DefaultStream();
164} // create_stream
165
166/** Builds a stream for a given severity.
167 * The actual key for the severity_t is found using \c key_for_severity,
168 * then the appropriate stream is constructred using \c create_stream
169 * \see key_for_severity()
170 * \see create_stream()
171 * \param s the severity_t of the requested stream
172 * \return the newly created stream
173 * \note the stream is allocated on the stack, it is the caller's responsibility to delete it.
174 */
175
177 const char* key = key_for_severity(s);
178 return create_stream(key);
179} // get_stream
180
181
182/** Sends an Issue to the fatal error stream
183 * \param issue_ptr
184 */
185
187 ERS_PRE_CHECK_PTR(issue_ptr);
188 issue_ptr->severity(ers::fatal);
189 dispatch(issue_ptr,false);
190} // fatal
191
192/** Sends an Issue to the error stream
193 * \param issue_ptr
194 */
195
197 ERS_PRE_CHECK_PTR(issue_ptr);
198 issue_ptr->severity(ers::error);
199 dispatch(issue_ptr,false);
200} // error
201
202/** Sends an Issue to the warning stream
203* \param issue_ptr the issue to send
204*/
205
207 ERS_PRE_CHECK_PTR(issue_ptr);
208 issue_ptr->severity(ers::warning);
209 dispatch(issue_ptr,false);
210} // warning
211
212/** Sends an issue to the debug stream
213 * \param issue_ptr the Issue to send
214 * \param s the severity_t of the associated stream.
215 * Accepted values: \li \c ers_debug_0 \li \c ers_debug_1 \li \c ers_debug_2 \li \c ers_debug_3
216 */
217
219 ERS_PRE_CHECK_PTR(issue_ptr);
220 ERS_PRECONDITION(s<ers::information,"severity_t is not debug : %s (%d) %d",ers::Core::to_string(s),s,ers::information);
221 issue_ptr->severity(s) ;
222 dispatch(issue_ptr,false);
223} // debug
224
225/** Sends a message to the debug stream
226* \param c the Context of the message
227* \param message the text of the message
228* \param s the severity_t of the associated stream. Accepted values: \li \c ers_debug_0 \li \c ers_debug_1 \li \c ers_debug_2 \li \c ers_debug_3
229*/
230
231void ers::StreamFactory::debug(const Context &c, const std::string &message, severity_t s) {
232 LogIssue log_issue(c,s,message);
233 debug(&log_issue,s);
234} // debug
235
236/** Sends a message to the warning stream
237 * \param c the context of the message
238 * \param message the message to send
239 */
240
241void ers::StreamFactory::warning(const Context &c, const std::string &message) {
242 LogIssue log_issue(c,ers::warning,message);
243 warning(&log_issue);
244} // warning
245
246
247/** Dispatches an issue to the appropriate stream.
248 * The stream is decided based upon the severity_t specified in the Issue.
249 * If \c throw_error is true errors and fatal errors are not sent to a stream, but thrown in the context of the caller.
250 * \param issue_ptr the Issue to dispatch
251 * \param throw_error should errors and fatals are thrown
252 */
253
254void ers::StreamFactory::dispatch(Issue *issue_ptr, bool throw_error) {
255 ERS_PRE_CHECK_PTR(issue_ptr);
256 if (throw_error && issue_ptr->is_error()) { throw *issue_ptr ; }
257 const severity_t s = issue_ptr->severity() ;
258 Stream *stream_ptr = instance()->get_stream(s) ;
259 ERS_CHECK_PTR(stream_ptr);
260 stream_ptr->send(issue_ptr);
261} // dispatch
262
263
264void ers::StreamFactory::dispatch(Issue &issue_ref, bool throw_error) {
265 dispatch(&issue_ref,throw_error);
266} // dispatch
267
268
270 instance()->set(s,key.c_str()) ;
271} // set
272
273
274
275// Member methods
276// --------------------------------------
277
278/** Gets stream for severity_t
279 * \param s the severity_t of the requested stream
280 * \return the stream
281 */
282
284 if (m_streams[s]==0) {
285 m_streams[s]=create_stream(s) ;
286 } // if
287 return m_streams[s] ;
288} // get_stream
289
290
291/** Sets the stream for a given severity_t
292 * \param severity_t severity_t of the stream
293 * Accepted values: \li \c ers_debug_0 \li \c ers_debug_1 \li \c ers_debug_2 \li \c ers_debug_3
294 * \li \c ers_information \li \c ers_notification \li \c ers_warning
295 * \li \c ers::error \li \c ers_fatal
296 * \param s the new stream
297 */
298
301 ERS_PRECONDITION(severity_none < severity && severity < severity_max,"illegal severity_t %d",(int) severity);
302 if (m_streams[severity]) {
303 delete m_streams[severity] ;
304 } // if there is a stream defined
305 m_streams[severity] = s ;
306} // stream
307
308/** Builds a stream using a string key and sets it up for a given severity
309 * \param severity_t severity_t of the stream
310 * Accepted values: \li \c ers_debug_0 \li \c ers_debug_1 \li \c ers_debug_2 \li \c ers_debug_3
311 * \li \c ers_information \li \c ers_notification \li \c ers_warning
312 * \li \c ers::error \li \c ers_fatal
313 * \param key the key used to build the new stream
314 */
315
316void ers::StreamFactory::set(severity_t severity, const char* key) {
318 Stream *s = create_stream(key);
319 set(severity,s);
320} //
321
322/**
323 * \return the current fatal stream
324 */
325
326ers::Stream *ers::StreamFactory::fatal() { return get_stream(ers::fatal) ; } // fatal
327
328/**
329 * \return the current error stream
330 */
331
332ers::Stream* ers::StreamFactory::error() { return get_stream(ers::error) ; } // error
333
334/**
335 * \return the current warning stream
336 */
337
338ers::Stream* ers::StreamFactory::warning() { return get_stream(ers::warning); } // warning
339
340
341/** Finds the debug stream
342 * \param s the severity_t of the associated stream.
343 * Accepted values: \li \c ers_debug_0 \li \c ers_debug_1 \li \c ers_debug_2 \li \c ers_debug_3
344 * \return debug stream
345 */
346
348 ERS_PRECONDITION(s<ers::information && s>ers::severity_none,"severity_t is not debug : %s (%d)",ers::Core::to_string(s),s);
349 return get_stream(s) ;
350} // debug
351
352
353
354
355/** Registers a factory function with the stream factory.
356 * The callback is function that takes two parameters <ol>
357 * <li>a string describing the protocol, for instance \c file </li>
358 * <li>a string describing a uri, can be a path, a suffix or anything</li>
359 * </ol>
360 * The function should return a heap allocated stream, or null if it does not
361 * understand the protocol.
362 * \param name name of the stream type (human display only).
363 * \param callback the callback function
364 * \return \c true if the registration was sucessfull
365 */
366
367bool ers::StreamFactory::register_factory(const std::string &name, create_stream_callback callback) {
368 // std::cerr << "registering " << name << std::endl ;
369 m_factories[name] = callback ;
370 return true ;
371} // register_factory
372
373/** Writes a description of the factory to a stream.
374 * This method gives a list of all registered stream types.
375 * \param stream the stream to write into
376 */
377
378void ers::StreamFactory::write_to(std::ostream& stream) const {
379 stream << "Stream factory - registered streams\n" ;
380 stream << "-----------------------------------\n" ;
381 int i = 0 ;
382 for(stream_factory_collection::const_iterator pos=m_factories.begin();pos!=m_factories.end();++pos) {
383 std::string name = pos->first;
384 stream << i << ")\t" << name << std::endl;
385 i++ ;
386 } // for
387 stream << "-----------------------------------\n" ;
388} // write_to
389
390
391/** Streaming operator
392 * \param stream destination stream
393 * \param factory the factory object to display
394 * \return the stream passed as first parameter
395 * \see ers::StreamFactory::write_to()
396 */
397
398std::ostream& ers::operator<<(std::ostream& stream, const ers::StreamFactory& factory) {
399 factory.write_to(stream);
400 return stream ;
401} // operator
402
403
404
405
efhlt::Interface * factory(void)
Definition: factory.cxx:17
#define ERS_PRECONDITION(expr,...)
XmlRpcServer s
Definition: HelloServer.cpp:11
*************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:22
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
static void print_registered()
static const char * DEFAULT_STREAMS[]
keys for default streams
static StreamFactory * instance()
return the singleton
Stream * fatal()
Fatal stream.
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:46
std::ostream & operator<<(std::ostream &, const Issue &)
enum ers::_severity_t severity_t