Line data Source code
1 : /*
2 : * StreamFactory.cxx
3 : * ERS
4 : *
5 : * Created by Serguei Kolos on 21.01.05.
6 : * Modified by Serguei Kolos on 21.11.05.
7 : * Copyright 2005 CERN. All rights reserved.
8 : *
9 : */
10 :
11 : #include <iostream>
12 :
13 : #include <ers/Issue.hpp>
14 : #include <ers/OutputStream.hpp>
15 : #include <ers/StreamFactory.hpp>
16 : #include <ers/Severity.hpp>
17 : #include <ers/ers.hpp>
18 : #include <ers/internal/Util.hpp>
19 : #include <ers/internal/NullStream.hpp>
20 : #include <ers/internal/PluginManager.hpp>
21 : #include <ers/internal/macro.hpp>
22 : #include <ers/internal/SingletonCreator.hpp>
23 :
24 : /** This method returns the singleton instance.
25 : * It should be used for every operation on the factory.
26 : * \return a reference to the singleton instance
27 : */
28 : ers::StreamFactory &
29 13221 : ers::StreamFactory::instance()
30 : {
31 : /**Singleton instance
32 : */
33 13221 : static ers::StreamFactory * instance = ers::SingletonCreator<ers::StreamFactory>::create();
34 :
35 13221 : return *instance;
36 : } // instance
37 :
38 : /** Builds a stream from a textual key
39 : * The key should have the format \c stream_name[(stream_parameters)]
40 : * For some streams parameters can be ommitted.
41 : * For instance to write to the error stream, the key is:
42 : * \c stderr
43 : * \param format the format, which describes new stream
44 : * \note the stream is allocated on the heap, it is the caller's responsibility to delete it.
45 : */
46 : ers::OutputStream *
47 76 : ers::StreamFactory::create_out_stream( const std::string & format ) const
48 : {
49 76 : std::string key = format;
50 76 : std::string param;
51 76 : std::string::size_type start = format.find( '(' );
52 76 : if ( start != std::string::npos )
53 : {
54 0 : key = format.substr( 0, start );
55 0 : std::string::size_type end = format.find( ')', start );
56 0 : if ( end != std::string::npos )
57 0 : param = format.substr( start + 1, end - start - 1 );
58 : }
59 :
60 76 : OutFunctionMap::const_iterator it = m_out_factories.find( key );
61 :
62 76 : if( it != m_out_factories.end() )
63 : {
64 76 : try
65 : {
66 76 : return it->second( param );
67 : }
68 0 : catch( ers::Issue & issue )
69 : {
70 0 : ERS_INTERNAL_ERROR( issue )
71 0 : }
72 : }
73 : else
74 : {
75 0 : ERS_INTERNAL_ERROR( "Creator for the \"" << key << "\" stream is not found" )
76 : }
77 :
78 : return 0;
79 76 : }
80 :
81 : /** Builds a stream from a textual key
82 : * The key should have the format \c stream_name[(stream_parameters)]
83 : * For some streams parameters can be ommitted.
84 : * For instance to write to the error stream, the key is:
85 : * \c stderr
86 : * \param param parameter to be passed to the new stream constructor
87 : * \note the stream is allocated on the heap, it is the caller's responsibility to delete it.
88 : */
89 : ers::InputStream *
90 0 : ers::StreamFactory::create_in_stream( const std::string & stream,
91 : const std::string & param ) const
92 : {
93 0 : return create_in_stream( stream, { param } );
94 0 : }
95 :
96 : /** Builds a stream from a textual key
97 : * The key should have the format \c stream_name[(stream_parameters)]
98 : * For some streams parameters can be ommitted.
99 : * For instance to write to the error stream, the key is:
100 : * \c stderr
101 : * \param params parameters to be passed to the new stream constructor
102 : * \note the stream is allocated on the heap, it is the caller's responsibility to delete it.
103 : */
104 : ers::InputStream *
105 0 : ers::StreamFactory::create_in_stream(
106 : const std::string & stream,
107 : const std::initializer_list<std::string> & params ) const
108 : {
109 0 : InFunctionMap::const_iterator it = m_in_factories.find( stream );
110 :
111 0 : if( it != m_in_factories.end() )
112 : {
113 0 : try
114 : {
115 0 : return it->second( params );
116 : }
117 0 : catch( ers::Issue & issue )
118 : {
119 0 : throw ers::InvalidFormat( ERS_HERE, stream, issue );
120 0 : }
121 : }
122 :
123 0 : throw ers::InvalidFormat( ERS_HERE, stream );
124 : }
125 :
126 : /** Registers a factory function with the stream factory.
127 : * The callback is function that takes two parameters <ol>
128 : * <li>a string describing the protocol, for instance \c file </li>
129 : * <li>a string describing a uri, can be a path, a suffix or anything</li>
130 : * </ol>
131 : * The function should return a heap allocated stream, or null if it does not
132 : * understand the protocol.
133 : * \param name name of the stream type (human display only).
134 : * \param callback the creator function
135 : */
136 : void
137 0 : ers::StreamFactory::register_in_stream( const std::string & name, InputStreamCreator callback )
138 : {
139 0 : m_in_factories[name] = callback;
140 0 : }
141 :
142 : /** Registers a factory function with the stream factory.
143 : * The callback is function that takes two parameters <ol>
144 : * <li>a string describing the protocol, for instance \c file </li>
145 : * <li>a string describing a uri, can be a path, a suffix or anything</li>
146 : * </ol>
147 : * The function should return a heap allocated stream, or null if it does not
148 : * understand the protocol.
149 : * \param name name of the stream type (human display only).
150 : * \param callback the creator function
151 : */
152 : void
153 13145 : ers::StreamFactory::register_out_stream( const std::string & name, OutputStreamCreator callback )
154 : {
155 13145 : m_out_factories[name] = callback;
156 13145 : }
157 :
158 : std::ostream &
159 0 : ers::operator<<( std::ostream & out, const ers::StreamFactory & sf )
160 : {
161 0 : StreamFactory::OutFunctionMap::const_iterator oit = sf.m_out_factories.begin();
162 0 : for( ; oit != sf.m_out_factories.end(); ++oit )
163 : {
164 0 : out << oit->first << "\t\"" << oit->second << "\"" << std::endl;
165 : }
166 :
167 0 : StreamFactory::InFunctionMap::const_iterator iit = sf.m_in_factories.begin();
168 0 : for( ; iit != sf.m_in_factories.end(); ++iit )
169 : {
170 0 : out << iit->first << "\t\"" << iit->second << "\"" << std::endl;
171 : }
172 0 : return out;
173 : }
|