libzypp 17.31.23
PluginFrame.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
12#include <iostream>
13#include <zypp/base/LogTools.h>
14#include <zypp/base/String.h>
15
16#include <zypp/PluginFrame.h>
17
18using std::endl;
19
20#undef ZYPP_BASE_LOGGER_LOGGROUP
21#define ZYPP_BASE_LOGGER_LOGGROUP "zypp::plugin"
22
24namespace zypp
25{
26
28 //
29 // CLASS NAME : PluginFrame::Impl
30 //
33 {
34 public:
36 {}
37
38 Impl( const std::string & command_r )
39 { setCommand( command_r ); }
40
41 Impl( const std::string & command_r, const std::string & body_r )
42 : _body( body_r )
43 { setCommand( command_r ); }
44
45 Impl( const std::string & command_r, HeaderInitializerList contents_r )
46 { setCommand( command_r ); addHeader( contents_r ); }
47
48 Impl( const std::string & command_r, const std::string & body_r, HeaderInitializerList contents_r )
49 : _body( body_r )
50 { setCommand( command_r ); addHeader( contents_r ); }
51
52 Impl( std::istream & stream_r );
53
54 public:
55 bool empty() const
56 { return _command.empty() && _body.empty(); }
57
58 const std::string & command() const
59 { return _command; }
60
61 void setCommand( const std::string & command_r )
62 {
63 if ( command_r.find( '\n' ) != std::string::npos )
64 ZYPP_THROW( PluginFrameException( "Multiline command", command_r ) );
65 _command = command_r;
66 }
67
68 const std::string & body() const
69 { return _body; }
70
71 std::string & bodyRef()
72 { return _body; }
73
74 void setBody( const std::string & body_r )
75 { _body = body_r; }
76
77 public:
78 typedef std::pair<HeaderListIterator,HeaderListIterator> constKeyRange;
79 typedef std::pair<HeaderList::iterator,HeaderList::iterator> KeyRange;
80
82 { return _header; }
83
84 const HeaderList & headerList() const
85 { return _header; }
86
87 const std::string & getHeader( const std::string & key_r ) const
88 {
89 constKeyRange r( _header.equal_range( key_r ) );
90 if ( r.first == r.second )
91 ZYPP_THROW( PluginFrameException( "No value for key", key_r ) );
92 const std::string & ret( r.first->second );
93 if ( ++r.first != r.second )
94 ZYPP_THROW( PluginFrameException( "Multiple values for key", key_r ) );
95 return ret;
96 }
97
98 const std::string & getHeader( const std::string & key_r, const std::string & default_r ) const
99 {
100 constKeyRange r( _header.equal_range( key_r ) );
101 if ( r.first == r.second )
102 return default_r;
103 const std::string & ret( r.first->second );
104 if ( ++r.first != r.second )
105 ZYPP_THROW( PluginFrameException( "Multiple values for key", key_r ) );
106 return ret;
107 }
108
109 const std::string & getHeaderNT( const std::string & key_r, const std::string & default_r ) const
110 {
111 HeaderListIterator iter( _header.find( key_r ) );
112 return iter != _header.end() ? iter->second : default_r;
113 }
114
115 HeaderList::value_type mkHeaderPair( const std::string & key_r, const std::string & value_r )
116 {
117 if ( key_r.find_first_of( ":\n" ) != std::string::npos )
118 ZYPP_THROW( PluginFrameException( "Illegal char in header key", key_r ) );
119 if ( value_r.find_first_of( "\n" ) != std::string::npos )
120 ZYPP_THROW( PluginFrameException( "Illegal char in header value", value_r ) );
121 return HeaderList::value_type( key_r, value_r );
122 }
123
124 void setHeader( const std::string & key_r, const std::string & value_r )
125 {
126 clearHeader( key_r );
127 addHeader( key_r, value_r );
128 }
129
130 void addHeader( const std::string & key_r, const std::string & value_r )
131 {
132 _header.insert( mkHeaderPair( key_r, value_r ) );
133 }
134
136 {
137 for ( const auto & el : contents_r )
138 addHeader( el.first, el.second );
139 }
140
141 void clearHeader( const std::string & key_r )
142 {
143 _header.erase( key_r );
144 }
145
146 public:
147 std::ostream & writeTo( std::ostream & stream_r ) const;
148
149 private:
150 std::string _command;
151 std::string _body;
153
154 public:
156 static shared_ptr<Impl> nullimpl()
157 {
158 static shared_ptr<Impl> _nullimpl( new Impl );
159 return _nullimpl;
160 }
161 private:
162 friend Impl * rwcowClone<Impl>( const Impl * rhs );
164 Impl * clone() const
165 { return new Impl( *this ); }
166 };
168
170 inline std::ostream & operator<<( std::ostream & str, const PluginFrame::Impl & obj )
171 {
172 return str << "PluginFrame[" << obj.command() << "](" << obj.headerList().size() << "){" << obj.body().size() << "}";
173 }
174
175 PluginFrame::Impl::Impl( std::istream & stream_r )
176 {
177 //DBG << "Parse from " << stream_r << endl;
178 if ( ! stream_r )
179 ZYPP_THROW( PluginFrameException( "Bad Stream" ) );
180
181 // JFYI: stream status after getline():
182 // Bool | Bits
183 // ------|---------------
184 // true | [g___] >FOO< : FOO line was \n-terminated
185 // true | [_e__] >BAA< : BAA before EOF, but not \n-terminated
186 // false | [_eF_] >< : No valid data to consume
187
188 //command
189 _command = str::getline( stream_r );
190 if ( ! stream_r.good() )
191 ZYPP_THROW( PluginFrameException( "Missing NL after command" ) );
192
193 // header
194 do {
195 std::string data = str::getline( stream_r );
196 if ( ! stream_r.good() )
197 ZYPP_THROW( PluginFrameException( "Missing NL after header" ) );
198
199 if ( data.empty() )
200 break; // --> empty line sep. header and body
201
202 std::string::size_type sep( data.find( ':') );
203 if ( sep == std::string::npos )
204 ZYPP_THROW( PluginFrameException( "Missing colon in header" ) );
205
206 _header.insert( HeaderList::value_type( data.substr(0,sep), data.substr(sep+1) ) );
207 } while ( true );
208
209 // data
210 _body = str::receiveUpTo( stream_r, '\0' );
211 if ( ! stream_r.good() )
212 ZYPP_THROW( PluginFrameException( "Missing NUL after body" ) );
213 }
214
215 std::ostream & PluginFrame::Impl::writeTo( std::ostream & stream_r ) const
216 {
217 //DBG << "Write " << *this << " to " << stream_r << endl;
218 if ( ! stream_r )
219 ZYPP_THROW( PluginFrameException( "Bad Stream" ) );
220
221 // command
222 stream_r << _command << endl;
223 // header
224 for_( it, _header.begin(), _header.end() )
225 stream_r << it->first << ':' << it->second << endl;
226 // body
227 stream_r << endl
228 << _body << '\0';
229
230 if ( ! stream_r )
231 ZYPP_THROW( PluginFrameException( "Write error" ) );
232 return stream_r;
233 }
234
236 //
237 // CLASS NAME : PluginFrame
238 //
240
241 const std::string & PluginFrame::ackCommand()
242 {
243 static std::string _val( "ACK" );
244 return _val;
245 }
246
247 const std::string & PluginFrame::errorCommand()
248 {
249 static std::string _val( "ERROR" );
250 return _val;
251 }
252
253 const std::string & PluginFrame::enomethodCommand()
254 {
255 static std::string _val( "_ENOMETHOD" );
256 return _val;
257 }
258
260 : _pimpl( Impl::nullimpl() )
261 {}
262
263 PluginFrame::PluginFrame( const std::string & command_r )
264 : _pimpl( new Impl( command_r ) )
265 {}
266
267 PluginFrame::PluginFrame( const std::string & command_r, const std::string & body_r )
268 : _pimpl( new Impl( command_r, body_r ) )
269 {}
270
271 PluginFrame::PluginFrame( const std::string & command_r, HeaderInitializerList contents_r )
272 : _pimpl( new Impl( command_r, contents_r ) )
273 {}
274
275 PluginFrame::PluginFrame( const std::string & command_r, const std::string & body_r, HeaderInitializerList contents_r )
276 : _pimpl( new Impl( command_r, body_r, contents_r ) )
277 {}
278
279 PluginFrame::PluginFrame( std::istream & stream_r )
280 : _pimpl( new Impl( stream_r ) )
281 {}
282
284 { return _pimpl->empty(); }
285
286 const std::string & PluginFrame::command() const
287 { return _pimpl->command(); }
288
289 void PluginFrame::setCommand( const std::string & command_r )
290 { _pimpl->setCommand( command_r ); }
291
292 const std::string & PluginFrame::body() const
293 { return _pimpl->body(); }
294
295 std::string & PluginFrame::bodyRef()
296 { return _pimpl->bodyRef(); }
297
298 void PluginFrame::setBody( const std::string & body_r )
299 { _pimpl->setBody( body_r ); }
300
301 std::ostream & PluginFrame::writeTo( std::ostream & stream_r ) const
302 { return _pimpl->writeTo( stream_r ); }
303
305 { return _pimpl->headerList(); }
306
308 { return _pimpl->headerList(); }
309
310 const std::string & PluginFrame::getHeader( const std::string & key_r ) const
311 { return _pimpl->getHeader( key_r ); }
312
313 const std::string & PluginFrame::getHeader( const std::string & key_r, const std::string & default_r ) const
314 { return _pimpl->getHeader( key_r, default_r ); }
315
316 const std::string & PluginFrame::getHeaderNT( const std::string & key_r, const std::string & default_r ) const
317 { return _pimpl->getHeaderNT( key_r, default_r ); }
318
319 void PluginFrame::setHeader( const std::string & key_r, const std::string & value_r )
320 { _pimpl->setHeader( key_r, value_r ); }
321
322 void PluginFrame::addHeader( const std::string & key_r, const std::string & value_r )
323 { _pimpl->addHeader( key_r, value_r ); }
324
326 { _pimpl->addHeader( contents_r ); }
327
328 void PluginFrame::clearHeader( const std::string & key_r )
329 { _pimpl->clearHeader( key_r ); }
330
332
333 std::ostream & operator<<( std::ostream & str, const PluginFrame & obj )
334 { return str << *obj._pimpl; }
335
336 bool operator==( const PluginFrame & lhs, const PluginFrame & rhs )
337 {
338 return ( lhs._pimpl == rhs._pimpl )
339 || (( lhs.command() == rhs.command() ) && ( lhs.headerList() == rhs.headerList() ) && ( lhs.body() == rhs.body() ));
340 }
341
343} // namespace zypp
Base class for PluginFrame Exception.
Command frame for communication with PluginScript.
Definition: PluginFrame.h:41
const std::initializer_list< std::pair< std::string, std::string > > & HeaderInitializerList
Definition: PluginFrame.h:45
static const std::string & ackCommand()
"ACK" command.
Definition: PluginFrame.cc:241
void setCommand(const std::string &command_r)
Set the frame command.
Definition: PluginFrame.cc:289
void setBody(const std::string &body_r)
Set the frame body.
Definition: PluginFrame.cc:298
const std::string & body() const
Return the frame body.
Definition: PluginFrame.cc:292
PluginFrame()
Default ctor (empty frame)
Definition: PluginFrame.cc:259
std::string & bodyRef()
Return a reference to the frame body.
Definition: PluginFrame.cc:295
void clearHeader(const std::string &key_r)
Remove all headers for key_r.
Definition: PluginFrame.cc:328
HeaderList::const_iterator HeaderListIterator
Header list iterator.
Definition: PluginFrame.h:138
bool empty() const
Whether this is an empty frame.
Definition: PluginFrame.cc:283
static const std::string & enomethodCommand()
"_ENOMETHOD" command.
Definition: PluginFrame.cc:253
const std::string & command() const
Return the frame command.
Definition: PluginFrame.cc:286
void addHeader(const std::string &key_r, const std::string &value_r=std::string())
Add header for key_r leaving already existing headers for key_r unchanged.
Definition: PluginFrame.cc:322
RWCOW_pointer< Impl > _pimpl
Pointer to implementation.
Definition: PluginFrame.h:253
static const std::string & errorCommand()
"ERROR" command.
Definition: PluginFrame.cc:247
std::multimap< std::string, std::string > HeaderList
The header list.
Definition: PluginFrame.h:135
const std::string & getHeader(const std::string &key_r) const
Return header value for key_r.
Definition: PluginFrame.cc:310
HeaderList & headerList()
Modifyalble header list for internal use only.
Definition: PluginFrame.cc:304
void setHeader(const std::string &key_r, const std::string &value_r=std::string())
Set header for key_r removing all other occurrences of key_r.
Definition: PluginFrame.cc:319
const std::string & getHeaderNT(const std::string &key_r, const std::string &default_r=std::string()) const
Not throwing version returing one of the matching header values or default_r string.
Definition: PluginFrame.cc:316
std::ostream & writeTo(std::ostream &stream_r) const
Write frame to stream.
Definition: PluginFrame.cc:301
String related utilities and Regular expression matching.
std::string getline(std::istream &str, const Trim trim_r)
Return stream content up to (but not returning) the next newline.
Definition: String.cc:478
std::string receiveUpTo(std::istream &str, const char delim_r, bool returnDelim_r)
Return stream content up to the next ocurrence of delim_r or EOF delim_r, if found,...
Definition: String.cc:488
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
bool operator==(const SetRelation::Enum &lhs, const SetCompare &rhs)
This is an overloaded member function, provided for convenience. It differs from the above function o...
std::ostream & operator<<(std::ostream &str, const SerialNumber &obj)
Definition: SerialNumber.cc:52
PluginFrame implementation.
Definition: PluginFrame.cc:33
std::ostream & writeTo(std::ostream &stream_r) const
Definition: PluginFrame.cc:215
const std::string & body() const
Definition: PluginFrame.cc:68
void setCommand(const std::string &command_r)
Definition: PluginFrame.cc:61
Impl(const std::string &command_r, HeaderInitializerList contents_r)
Definition: PluginFrame.cc:45
const std::string & getHeader(const std::string &key_r) const
Definition: PluginFrame.cc:87
static shared_ptr< Impl > nullimpl()
Offer default Impl.
Definition: PluginFrame.cc:156
const std::string & command() const
Definition: PluginFrame.cc:58
const std::string & getHeaderNT(const std::string &key_r, const std::string &default_r) const
Definition: PluginFrame.cc:109
HeaderList & headerList()
Definition: PluginFrame.cc:81
Impl(const std::string &command_r)
Definition: PluginFrame.cc:38
const HeaderList & headerList() const
Definition: PluginFrame.cc:84
const std::string & getHeader(const std::string &key_r, const std::string &default_r) const
Definition: PluginFrame.cc:98
void setBody(const std::string &body_r)
Definition: PluginFrame.cc:74
std::pair< HeaderListIterator, HeaderListIterator > constKeyRange
Definition: PluginFrame.cc:78
std::string & bodyRef()
Definition: PluginFrame.cc:71
std::pair< HeaderList::iterator, HeaderList::iterator > KeyRange
Definition: PluginFrame.cc:79
void setHeader(const std::string &key_r, const std::string &value_r)
Definition: PluginFrame.cc:124
void clearHeader(const std::string &key_r)
Definition: PluginFrame.cc:141
void addHeader(const std::string &key_r, const std::string &value_r)
Definition: PluginFrame.cc:130
Impl(const std::string &command_r, const std::string &body_r, HeaderInitializerList contents_r)
Definition: PluginFrame.cc:48
Impl * clone() const
clone for RWCOW_pointer
Definition: PluginFrame.cc:164
void addHeader(HeaderInitializerList contents_r)
Definition: PluginFrame.cc:135
HeaderList::value_type mkHeaderPair(const std::string &key_r, const std::string &value_r)
Definition: PluginFrame.cc:115
Impl(const std::string &command_r, const std::string &body_r)
Definition: PluginFrame.cc:41
std::ostream & operator<<(std::ostream &str, const PluginFrame::Impl &obj)
Stream output.
Definition: PluginFrame.cc:170
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:28
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:428