libzypp  13.10.6
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 
18 using std::endl;
19 
21 namespace zypp
22 {
23 
25  //
26  // CLASS NAME : PluginFrame::Impl
27  //
30  {
31  public:
32  Impl()
33  {}
34 
35  Impl( const std::string & command_r )
36  { setCommand( command_r ); }
37 
38  Impl( const std::string & command_r, const std::string body_r )
39  : _body( body_r )
40  { setCommand( command_r ); }
41 
42  Impl( std::istream & stream_r );
43 
44  public:
45  bool empty() const
46  { return _command.empty() && _body.empty(); }
47 
48  const std::string & command() const
49  { return _command; }
50 
51  void setCommand( const std::string & command_r )
52  {
53  if ( command_r.find( '\n' ) != std::string::npos )
54  ZYPP_THROW( PluginFrameException( "Multiline command", command_r ) );
55  _command = command_r;
56  }
57 
58  const std::string & body() const
59  { return _body; }
60 
61  std::string & bodyRef()
62  { return _body; }
63 
64  void setBody( const std::string & body_r )
65  { _body = body_r; }
66 
67  public:
68  typedef std::pair<HeaderListIterator,HeaderListIterator> constKeyRange;
69  typedef std::pair<HeaderList::iterator,HeaderList::iterator> KeyRange;
70 
72  { return _header; }
73 
74  const HeaderList & headerList() const
75  { return _header; }
76 
77  const std::string & getHeader( const std::string & key_r ) const
78  {
79  constKeyRange r( _header.equal_range( key_r ) );
80  if ( r.first == r.second )
81  ZYPP_THROW( PluginFrameException( "No value for key", key_r ) );
82  const std::string & ret( r.first->second );
83  if ( ++r.first != r.second )
84  ZYPP_THROW( PluginFrameException( "Multiple values for key", key_r ) );
85  return ret;
86  }
87 
88  const std::string & getHeader( const std::string & key_r, const std::string & default_r ) const
89  {
90  constKeyRange r( _header.equal_range( key_r ) );
91  if ( r.first == r.second )
92  return default_r;
93  const std::string & ret( r.first->second );
94  if ( ++r.first != r.second )
95  ZYPP_THROW( PluginFrameException( "Multiple values for key", key_r ) );
96  return ret;
97  }
98 
99  const std::string & getHeaderNT( const std::string & key_r, const std::string & default_r ) const
100  {
101  HeaderListIterator iter( _header.find( key_r ) );
102  return iter != _header.end() ? iter->second : default_r;
103  }
104 
105  HeaderList::value_type mkHeaderPair( const std::string & key_r, const std::string & value_r )
106  {
107  if ( key_r.find_first_of( ":\n" ) != std::string::npos )
108  ZYPP_THROW( PluginFrameException( "Illegal char in header key", key_r ) );
109  if ( value_r.find_first_of( ":\n" ) != std::string::npos )
110  ZYPP_THROW( PluginFrameException( "Illegal char in header value", value_r ) );
111  return HeaderList::value_type( key_r, value_r );
112  }
113 
114  void setHeader( const std::string & key_r, const std::string & value_r )
115  {
116  clearHeader( key_r );
117  addHeader( key_r, value_r );
118  }
119 
120  void addHeader( const std::string & key_r, const std::string & value_r )
121  {
122  _header.insert( mkHeaderPair( key_r, value_r ) );
123  }
124 
125  void clearHeader( const std::string & key_r )
126  {
127  _header.erase( key_r );
128  }
129 
130  public:
131  std::ostream & writeTo( std::ostream & stream_r ) const;
132 
133  private:
134  std::string _command;
135  std::string _body;
137 
138  public:
140  static shared_ptr<Impl> nullimpl()
141  {
142  static shared_ptr<Impl> _nullimpl( new Impl );
143  return _nullimpl;
144  }
145  private:
146  friend Impl * rwcowClone<Impl>( const Impl * rhs );
148  Impl * clone() const
149  { return new Impl( *this ); }
150  };
152 
154  inline std::ostream & operator<<( std::ostream & str, const PluginFrame::Impl & obj )
155  {
156  return str << "PluginFrame[" << obj.command() << "](" << obj.headerList().size() << "){" << obj.body().size() << "}";
157  }
158 
159  PluginFrame::Impl::Impl( std::istream & stream_r )
160  {
161  //DBG << "Parse from " << stream_r << endl;
162  if ( ! stream_r )
163  ZYPP_THROW( PluginFrameException( "Bad Stream" ) );
164 
165  // JFYI: stream status after getline():
166  // Bool | Bits
167  // ------|---------------
168  // true | [g___] >FOO< : FOO line was \n-terminated
169  // true | [_e__] >BAA< : BAA before EOF, but not \n-terminated
170  // false | [_eF_] >< : No valid data to consume
171 
172  //command
173  _command = str::getline( stream_r );
174  if ( ! stream_r.good() )
175  ZYPP_THROW( PluginFrameException( "Missing NL after command" ) );
176 
177  // header
178  do {
179  std::string data = str::getline( stream_r );
180  if ( ! stream_r.good() )
181  ZYPP_THROW( PluginFrameException( "Missing NL after header" ) );
182 
183  if ( data.empty() )
184  break; // --> empty line sep. header and body
185 
186  std::string::size_type sep( data.find( ':') );
187  if ( sep == std::string::npos )
188  ZYPP_THROW( PluginFrameException( "Missing colon in header" ) );
189 
190  _header.insert( HeaderList::value_type( data.substr(0,sep), data.substr(sep+1) ) );
191  } while ( true );
192 
193  // data
194  _body = str::receiveUpTo( stream_r, '\0' );
195  if ( ! stream_r.good() )
196  ZYPP_THROW( PluginFrameException( "Missing NUL after body" ) );
197  }
198 
199  std::ostream & PluginFrame::Impl::writeTo( std::ostream & stream_r ) const
200  {
201  //DBG << "Write " << *this << " to " << stream_r << endl;
202  if ( ! stream_r )
203  ZYPP_THROW( PluginFrameException( "Bad Stream" ) );
204 
205  // command
206  stream_r << _command << endl;
207  // header
208  for_( it, _header.begin(), _header.end() )
209  stream_r << it->first << ':' << it->second << endl;
210  // body
211  stream_r << endl
212  << _body << '\0';
213 
214  if ( ! stream_r )
215  ZYPP_THROW( PluginFrameException( "Write error" ) );
216  return stream_r;
217  }
218 
220  //
221  // CLASS NAME : PluginFrame
222  //
224 
225  const std::string & PluginFrame::ackCommand()
226  {
227  static std::string _val( "ACK" );
228  return _val;
229  }
230 
231  const std::string & PluginFrame::errorCommand()
232  {
233  static std::string _val( "ERROR" );
234  return _val;
235  }
236 
238  : _pimpl( Impl::nullimpl() )
239  {}
240 
241  PluginFrame::PluginFrame( const std::string & command_r )
242  : _pimpl( new Impl( command_r ) )
243  {}
244 
245  PluginFrame::PluginFrame( const std::string & command_r, const std::string body_r )
246  : _pimpl( new Impl( command_r, body_r ) )
247  {}
248 
249  PluginFrame::PluginFrame( std::istream & stream_r )
250  : _pimpl( new Impl( stream_r ) )
251  {}
252 
253  bool PluginFrame::empty() const
254  { return _pimpl->empty(); }
255 
256  const std::string & PluginFrame::command() const
257  { return _pimpl->command(); }
258 
259  void PluginFrame::setCommand( const std::string & command_r )
260  { _pimpl->setCommand( command_r ); }
261 
262  const std::string & PluginFrame::body() const
263  { return _pimpl->body(); }
264 
265  std::string & PluginFrame::bodyRef()
266  { return _pimpl->bodyRef(); }
267 
268  void PluginFrame::setBody( const std::string & body_r )
269  { _pimpl->setBody( body_r ); }
270 
271  std::ostream & PluginFrame::writeTo( std::ostream & stream_r ) const
272  { return _pimpl->writeTo( stream_r ); }
273 
275  { return _pimpl->headerList(); }
276 
278  { return _pimpl->headerList(); }
279 
280  const std::string & PluginFrame::getHeader( const std::string & key_r ) const
281  { return _pimpl->getHeader( key_r ); }
282 
283  const std::string & PluginFrame::getHeader( const std::string & key_r, const std::string & default_r ) const
284  { return _pimpl->getHeader( key_r, default_r ); }
285 
286  const std::string & PluginFrame::getHeaderNT( const std::string & key_r, const std::string & default_r ) const
287  { return _pimpl->getHeaderNT( key_r, default_r ); }
288 
289  void PluginFrame::setHeader( const std::string & key_r, const std::string & value_r )
290  { _pimpl->setHeader( key_r, value_r ); }
291 
292  void PluginFrame::addHeader( const std::string & key_r, const std::string & value_r )
293  { _pimpl->addHeader( key_r, value_r ); }
294 
295  void PluginFrame::clearHeader( const std::string & key_r )
296  { _pimpl->clearHeader( key_r ); }
297 
299 
300  std::ostream & operator<<( std::ostream & str, const PluginFrame & obj )
301  { return str << *obj._pimpl; }
302 
303  bool operator==( const PluginFrame & lhs, const PluginFrame & rhs )
304  {
305  return ( lhs._pimpl == rhs._pimpl )
306  || (( lhs.command() == rhs.command() ) && ( lhs.headerList() == rhs.headerList() ) && ( lhs.body() == rhs.body() ));
307  }
308 
310 } // namespace zypp
PluginFrame()
Default ctor (empty frame)
Definition: PluginFrame.cc:237
static shared_ptr< Impl > nullimpl()
Offer default Impl.
Definition: PluginFrame.cc:140
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:320
const std::string & getHeaderNT(const std::string &key_r, const std::string &default_r) const
Definition: PluginFrame.cc:99
Command frame for communication with PluginScript.
Definition: PluginFrame.h:40
void setCommand(const std::string &command_r)
Set the frame command.
Definition: PluginFrame.cc:259
const std::string & command() const
Return the frame command.
Definition: PluginFrame.cc:256
const std::string & getHeader(const std::string &key_r, const std::string &default_r) const
Definition: PluginFrame.cc:88
void clearHeader(const std::string &key_r)
Definition: PluginFrame.cc:125
Impl * clone() const
clone for RWCOW_pointer
Definition: PluginFrame.cc:148
Impl(const std::string &command_r)
Definition: PluginFrame.cc:35
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:27
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:292
static const std::string & errorCommand()
&quot;ERROR&quot; command.
Definition: PluginFrame.cc:231
void setCommand(const std::string &command_r)
Definition: PluginFrame.cc:51
const std::string & getHeader(const std::string &key_r) const
Definition: PluginFrame.cc:77
std::pair< HeaderListIterator, HeaderListIterator > constKeyRange
Definition: PluginFrame.cc:68
std::ostream & operator<<(std::ostream &str, const Exception &obj)
Definition: Exception.cc:120
Base class for PluginFrame Exception.
std::pair< HeaderList::iterator, HeaderList::iterator > KeyRange
Definition: PluginFrame.cc:69
std::string getline(std::istream &str, const Trim trim_r)
Return stream content up to (but not returning) the next newline.
Definition: String.cc:361
static const std::string & ackCommand()
&quot;ACK&quot; command.
Definition: PluginFrame.cc:225
RWCOW_pointer< Impl > _pimpl
Pointer to implementation.
Definition: PluginFrame.h:223
void setHeader(const std::string &key_r, const std::string &value_r)
Definition: PluginFrame.cc:114
SolvableIdType size_type
Definition: PoolMember.h:99
HeaderList & headerList()
Definition: PluginFrame.cc:71
bool operator==(const StrMatcher &lhs, const StrMatcher &rhs)
Definition: StrMatcher.cc:309
void setBody(const std::string &body_r)
Set the frame body.
Definition: PluginFrame.cc:268
std::multimap< std::string, std::string > HeaderList
The header list.
Definition: PluginFrame.h:117
const std::string & getHeader(const std::string &key_r) const
Return header value for key_r.
Definition: PluginFrame.cc:280
HeaderList::value_type mkHeaderPair(const std::string &key_r, const std::string &value_r)
Definition: PluginFrame.cc:105
void addHeader(const std::string &key_r, const std::string &value_r)
Definition: PluginFrame.cc:120
HeaderList::const_iterator HeaderListIterator
Header list iterator.
Definition: PluginFrame.h:120
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, is always read from the stream.
Definition: String.cc:371
const std::string & command() const
Definition: PluginFrame.cc:48
void setHeader(const std::string &key_r, const std::string &value_r=std::string())
Set header for key_r removing all other occurences of key_r.
Definition: PluginFrame.cc:289
HeaderList & headerList()
Modifyalble header list for internal use only.
Definition: PluginFrame.cc:274
std::ostream & writeTo(std::ostream &stream_r) const
Definition: PluginFrame.cc:199
std::ostream & operator<<(std::ostream &str, const PluginFrame::Impl &obj)
Definition: PluginFrame.cc:154
PluginFrame implementation.
Definition: PluginFrame.cc:29
std::ostream & writeTo(std::ostream &stream_r) const
Write frame to stream.
Definition: PluginFrame.cc:271
std::string & bodyRef()
Return a reference to the frame body.
Definition: PluginFrame.cc:265
bool empty() const
Whether this is an empty frame.
Definition: PluginFrame.cc:253
Impl(const std::string &command_r, const std::string body_r)
Definition: PluginFrame.cc:38
void clearHeader(const std::string &key_r)
Remove all headers for key_r.
Definition: PluginFrame.cc:295
std::string & bodyRef()
Definition: PluginFrame.cc:61
void setBody(const std::string &body_r)
Definition: PluginFrame.cc:64
const HeaderList & headerList() const
Definition: PluginFrame.cc:74
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:286
const std::string & body() const
Definition: PluginFrame.cc:58
const std::string & body() const
Return the frame body.
Definition: PluginFrame.cc:262