~thopiekar/zypper/libzypp-manual-import

« back to all changes in this revision

Viewing changes to zypp/PluginFrame.h

  • Committer: Thomas-Karl Pietrowski
  • Date: 2014-01-29 22:44:28 UTC
  • Revision ID: thopiekar@googlemail.com-20140129224428-gpcqnsdakby362n8
firstĀ import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*---------------------------------------------------------------------\
 
2
|                          ____ _   __ __ ___                          |
 
3
|                         |__  / \ / / . \ . \                         |
 
4
|                           / / \ V /|  _/  _/                         |
 
5
|                          / /__ | | | | | |                           |
 
6
|                         /_____||_| |_| |_|                           |
 
7
|                                                                      |
 
8
\---------------------------------------------------------------------*/
 
9
/** \file       zypp/PluginFrame.h
 
10
 *
 
11
*/
 
12
#ifndef ZYPP_PLUGINFRAME_H
 
13
#define ZYPP_PLUGINFRAME_H
 
14
 
 
15
#include <iosfwd>
 
16
#include <string>
 
17
#include <map>
 
18
 
 
19
#include "zypp/base/PtrTypes.h"
 
20
 
 
21
#include "zypp/PluginFrameException.h"
 
22
 
 
23
///////////////////////////////////////////////////////////////////
 
24
namespace zypp
 
25
{ /////////////////////////////////////////////////////////////////
 
26
 
 
27
  /** Command frame for communication with \ref PluginScript
 
28
   *
 
29
   * \code
 
30
   *   COMMAND
 
31
   *   key:value header lines
 
32
   *
 
33
   *   multiline body separated from header
 
34
   *   by an empty line and terminated by NUL.
 
35
   *   ^@
 
36
   * \endcode
 
37
   *
 
38
   * \see PluginScript
 
39
   */
 
40
  class PluginFrame
 
41
  {
 
42
    friend std::ostream & operator<<( std::ostream & str, const PluginFrame & obj );
 
43
    friend bool operator==( const PluginFrame & lhs, const PluginFrame & rhs );
 
44
 
 
45
    typedef const std::initializer_list<std::pair<std::string,std::string>> & HeaderInitializerList;
 
46
 
 
47
    public:
 
48
      /** "ACK" command. */
 
49
      static const std::string & ackCommand();
 
50
      /** "ERROR" command. */
 
51
      static const std::string & errorCommand();
 
52
      /** "_ENOMETHOD" command. */
 
53
      static const std::string & enomethodCommand();
 
54
 
 
55
    public:
 
56
      /** Default exception type */
 
57
      typedef PluginFrameException Exception;
 
58
 
 
59
      /** Default ctor (empty frame) */
 
60
      PluginFrame();
 
61
 
 
62
      /** Ctor taking the command
 
63
       * \throw PluginFrameException If \ref setCommand throws
 
64
       */
 
65
      PluginFrame( const std::string & command_r );
 
66
 
 
67
      /** Ctor taking command and body
 
68
       * \throw PluginFrameException If \ref setCommand throws
 
69
       */
 
70
      PluginFrame( const std::string & command_r, const std::string & body_r );
 
71
 
 
72
      /** Ctor taking the command and a HeaderInitializerList
 
73
       * \throw PluginFrameException If \ref setCommand throws
 
74
       */
 
75
      PluginFrame( const std::string & command_r, HeaderInitializerList contents_r );
 
76
 
 
77
      /** Ctor taking command, body and a HeaderInitializerList
 
78
       * \throw PluginFrameException If \ref setCommand throws
 
79
       */
 
80
      PluginFrame( const std::string & command_r, const std::string & body_r, HeaderInitializerList contents_r );
 
81
 
 
82
      /** Ctor reading frame data from a stream
 
83
       * \throw PluginFrameException On error reading from stream
 
84
       * \throw PluginFrameException On error parsing the data
 
85
       */
 
86
      PluginFrame( std::istream & stream_r );
 
87
 
 
88
    public:
 
89
      /** Whether this is an empty frame. */
 
90
      bool empty() const;
 
91
 
 
92
      /** Evaluate in a boolean context (empty frame) */
 
93
      explicit operator bool() const
 
94
      { return empty(); }
 
95
 
 
96
    public:
 
97
      /** Return the frame command. */
 
98
      const std::string & command() const;
 
99
 
 
100
      /** Set the frame command
 
101
       * \throw PluginFrameException If illegal command string (e.g. multiline)
 
102
       */
 
103
      void setCommand( const std::string & command_r );
 
104
 
 
105
      /** Convenience to identify an ACK command. */
 
106
      bool isAckCommand() const
 
107
      { return command() == ackCommand(); }
 
108
 
 
109
      /** Convenience to identify an ERROR command. */
 
110
      bool isErrorCommand() const
 
111
      {return command() == errorCommand(); }
 
112
 
 
113
      /** Convenience to identify an _ENOMETHOD command. */
 
114
      bool isEnomethodCommand() const
 
115
      {return command() == enomethodCommand(); }
 
116
 
 
117
      /** Return the frame body. */
 
118
      const std::string & body() const;
 
119
 
 
120
      /** Return a reference to the frame body.
 
121
       * This may avoid creating unnecessary copies if you
 
122
       * want to manipulate large body data.
 
123
       * \code
 
124
       *   std::string tmp;
 
125
       *   frame.bodyRef().swap( tmp );
 
126
       * \endcode
 
127
       */
 
128
      std::string & bodyRef();
 
129
 
 
130
      /** Set the frame body */
 
131
      void setBody( const std::string & body_r );
 
132
 
 
133
    public:
 
134
      /** The header list */
 
135
      typedef std::multimap<std::string, std::string> HeaderList;
 
136
 
 
137
      /** Header list iterator */
 
138
      typedef HeaderList::const_iterator HeaderListIterator;
 
139
 
 
140
    private:
 
141
      /** Modifyalble header list for internal use only. */
 
142
      HeaderList & headerList();
 
143
 
 
144
    public:
 
145
      /** The header list. */
 
146
      const HeaderList & headerList() const;
 
147
 
 
148
      /** Whether header list is empty. */
 
149
      bool headerEmpty() const
 
150
      { return headerList().empty(); }
 
151
 
 
152
      /** Return size of the header list. */
 
153
      unsigned headerSize() const
 
154
      { return headerList().size(); }
 
155
 
 
156
      /** Return iterator pointing to the 1st header (or \ref headerEnd) */
 
157
      HeaderListIterator headerBegin() const
 
158
      { return headerList().begin(); }
 
159
 
 
160
      /** Return iterator pointing behind the last header. */
 
161
      HeaderListIterator headerEnd() const
 
162
      { return headerList().end(); }
 
163
 
 
164
      /** Clear the list of headers. */
 
165
      void headerClear()
 
166
      { headerList().clear(); }
 
167
 
 
168
 
 
169
      /** Whether the header list contains at least one entry for \c key_r. */
 
170
      bool hasKey( const std::string & key_r ) const
 
171
      { return ! keyEmpty( key_r ); }
 
172
 
 
173
      /** \overload */
 
174
      bool keyEmpty( const std::string & key_r ) const
 
175
      { return headerList().find( key_r ) == headerEnd(); }
 
176
 
 
177
      /** Return number of header entires for \c key_r. */
 
178
      bool keySize( const std::string & key_r ) const
 
179
      { return headerList().count( key_r ); }
 
180
 
 
181
      /** Return iterator pointing to the 1st header for \c key_r (or \ref keyEnd(key_r)) */
 
182
      HeaderListIterator keyBegin( const std::string & key_r ) const
 
183
      { return headerList().lower_bound( key_r ); }
 
184
 
 
185
      /** Return iterator pointing behind the last header for \c key_r.*/
 
186
      HeaderListIterator keyEnd( const std::string & key_r ) const
 
187
      { return headerList().upper_bound( key_r ); }
 
188
 
 
189
 
 
190
      /** Return header value for \c key_r.
 
191
       * \throw PluginFrameException If no header for key_r exists.
 
192
       * \throw PluginFrameException If multiple header for key_r exist.
 
193
       */
 
194
      const std::string & getHeader( const std::string & key_r ) const;
 
195
 
 
196
      /** Return header value for \c key_r or \c default_r if it does not exist.
 
197
       * \throw PluginFrameException If multiple header for key_r exist.
 
198
       */
 
199
      const std::string & getHeader( const std::string & key_r, const std::string & default_r ) const;
 
200
 
 
201
      /** Not throwing version returing one of the matching header values or \c default_r string. */
 
202
      const std::string & getHeaderNT( const std::string & key_r, const std::string & default_r = std::string() ) const;
 
203
 
 
204
      /** Set header for \c key_r removing all other occurences of \c key_r.
 
205
       * \throw PluginFrameException If key contains illegal chars (\c NL or \c :)
 
206
       * \throw PluginFrameException If value contains illegal chars (\c NL)
 
207
       */
 
208
      void setHeader( const std::string & key_r, const std::string & value_r = std::string() );
 
209
 
 
210
      /** Set a new header list
 
211
       * \throw PluginFrameException If key contains illegal chars (\c NL or \c :)
 
212
       * \throw PluginFrameException If value contains illegal chars (\c NL)
 
213
       */
 
214
      void setHeader( HeaderInitializerList contents_r )
 
215
      { headerList().clear(); addHeader( contents_r ); }
 
216
 
 
217
      /** Add header for \c key_r leaving already existing headers for \c key_r unchanged.
 
218
       * \throw PluginFrameException If key contains illegal chars (\c NL or \c :)
 
219
       * \throw PluginFrameException If value contains illegal chars (\c NL)
 
220
       */
 
221
      void addHeader( const std::string & key_r, const std::string & value_r = std::string() );
 
222
      /** \overload taking an initializer_list */
 
223
      void addHeader( HeaderInitializerList contents_r );
 
224
 
 
225
      /** Remove all headers for \c key_r. */
 
226
      void clearHeader( const std::string & key_r );
 
227
 
 
228
    public:
 
229
      /** Write frame to stream
 
230
       * \throw PluginFrameException On error writing to stream
 
231
       */
 
232
      std::ostream & writeTo( std::ostream & stream_r ) const;
 
233
 
 
234
      /** \overload Static version. */
 
235
      static std::ostream & writeTo( std::ostream & stream_r, const PluginFrame & frame_r )
 
236
      { return frame_r.writeTo( stream_r ); }
 
237
 
 
238
      /** Read frame from stream
 
239
       * \throw PluginFrameException If \ref PluginFrame(std::istream&) throws
 
240
       */
 
241
      std::istream & readFrom( std::istream & stream_r )
 
242
      { *this = PluginFrame( stream_r ); return stream_r; }
 
243
 
 
244
      /** \overload Static version. */
 
245
      static std::istream & readFrom( std::istream & stream_r, PluginFrame & frame_r )
 
246
      { frame_r = PluginFrame( stream_r ); return stream_r; }
 
247
 
 
248
    public:
 
249
      /** Implementation */
 
250
      class Impl;
 
251
    private:
 
252
      /** Pointer to implementation */
 
253
      RWCOW_pointer<Impl> _pimpl;
 
254
  };
 
255
 
 
256
  /** \relates PluginFrame Stream output for logging */
 
257
  std::ostream & operator<<( std::ostream & str, const PluginFrame & obj );
 
258
 
 
259
  /** \relates PluginFrame Stream output sending all data */
 
260
  inline std::ostream & dumpOn( std::ostream & str, const PluginFrame & obj )
 
261
  { return PluginFrame::writeTo( str, obj ); }
 
262
 
 
263
  /** \relates PluginFrame Construct from stream. */
 
264
  inline std::istream & operator>>( std::istream & str, PluginFrame & obj )
 
265
  { return PluginFrame::readFrom( str, obj ); }
 
266
 
 
267
  /** \relates PluginFrame Comparison based on content. */
 
268
  bool operator==( const PluginFrame & lhs, const PluginFrame & rhs );
 
269
 
 
270
  /** \relates PluginFrame Comparison based on content. */
 
271
  inline bool operator!=( const PluginFrame & lhs, const PluginFrame & rhs )
 
272
  { return( ! operator==( lhs, rhs ) ); }
 
273
 
 
274
  /////////////////////////////////////////////////////////////////
 
275
} // namespace zypp
 
276
///////////////////////////////////////////////////////////////////
 
277
#endif // ZYPP_PLUGINFRAME_H