1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/PluginFrame.h
12 #ifndef ZYPP_PLUGINFRAME_H
13 #define ZYPP_PLUGINFRAME_H
19 #include "zypp/base/PtrTypes.h"
21 #include "zypp/PluginFrameException.h"
23 ///////////////////////////////////////////////////////////////////
25 { /////////////////////////////////////////////////////////////////
27 /** Command frame for communication with \ref PluginScript
31 * key:value header lines
33 * multiline body separated from header
34 * by an empty line and terminated by NUL.
42 friend std::ostream & operator<<( std::ostream & str, const PluginFrame & obj );
43 friend bool operator==( const PluginFrame & lhs, const PluginFrame & rhs );
45 typedef const std::initializer_list<std::pair<std::string,std::string>> & HeaderInitializerList;
49 static const std::string & ackCommand();
50 /** "ERROR" command. */
51 static const std::string & errorCommand();
52 /** "_ENOMETHOD" command. */
53 static const std::string & enomethodCommand();
56 /** Default exception type */
57 typedef PluginFrameException Exception;
59 /** Default ctor (empty frame) */
62 /** Ctor taking the command
63 * \throw PluginFrameException If \ref setCommand throws
65 PluginFrame( const std::string & command_r );
67 /** Ctor taking command and body
68 * \throw PluginFrameException If \ref setCommand throws
70 PluginFrame( const std::string & command_r, const std::string & body_r );
72 /** Ctor taking the command and a HeaderInitializerList
73 * \throw PluginFrameException If \ref setCommand throws
75 PluginFrame( const std::string & command_r, HeaderInitializerList contents_r );
77 /** Ctor taking command, body and a HeaderInitializerList
78 * \throw PluginFrameException If \ref setCommand throws
80 PluginFrame( const std::string & command_r, const std::string & body_r, HeaderInitializerList contents_r );
82 /** Ctor reading frame data from a stream
83 * \throw PluginFrameException On error reading from stream
84 * \throw PluginFrameException On error parsing the data
86 PluginFrame( std::istream & stream_r );
89 /** Whether this is an empty frame. */
92 /** Evaluate in a boolean context (empty frame) */
93 explicit operator bool() const
97 /** Return the frame command. */
98 const std::string & command() const;
100 /** Set the frame command
101 * \throw PluginFrameException If illegal command string (e.g. multiline)
103 void setCommand( const std::string & command_r );
105 /** Convenience to identify an ACK command. */
106 bool isAckCommand() const
107 { return command() == ackCommand(); }
109 /** Convenience to identify an ERROR command. */
110 bool isErrorCommand() const
111 {return command() == errorCommand(); }
113 /** Convenience to identify an _ENOMETHOD command. */
114 bool isEnomethodCommand() const
115 {return command() == enomethodCommand(); }
117 /** Return the frame body. */
118 const std::string & body() const;
120 /** Return a reference to the frame body.
121 * This may avoid creating unnecessary copies if you
122 * want to manipulate large body data.
125 * frame.bodyRef().swap( tmp );
128 std::string & bodyRef();
130 /** Set the frame body */
131 void setBody( const std::string & body_r );
134 /** The header list */
135 typedef std::multimap<std::string, std::string> HeaderList;
137 /** Header list iterator */
138 typedef HeaderList::const_iterator HeaderListIterator;
141 /** Modifyalble header list for internal use only. */
142 HeaderList & headerList();
145 /** The header list. */
146 const HeaderList & headerList() const;
148 /** Whether header list is empty. */
149 bool headerEmpty() const
150 { return headerList().empty(); }
152 /** Return size of the header list. */
153 unsigned headerSize() const
154 { return headerList().size(); }
156 /** Return iterator pointing to the 1st header (or \ref headerEnd) */
157 HeaderListIterator headerBegin() const
158 { return headerList().begin(); }
160 /** Return iterator pointing behind the last header. */
161 HeaderListIterator headerEnd() const
162 { return headerList().end(); }
164 /** Clear the list of headers. */
166 { headerList().clear(); }
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 ); }
174 bool keyEmpty( const std::string & key_r ) const
175 { return headerList().find( key_r ) == headerEnd(); }
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 ); }
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 ); }
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 ); }
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.
194 const std::string & getHeader( const std::string & key_r ) const;
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.
199 const std::string & getHeader( const std::string & key_r, const std::string & default_r ) const;
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;
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)
208 void setHeader( const std::string & key_r, const std::string & value_r = std::string() );
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)
214 void setHeader( HeaderInitializerList contents_r )
215 { headerList().clear(); addHeader( contents_r ); }
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)
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 );
225 /** Remove all headers for \c key_r. */
226 void clearHeader( const std::string & key_r );
229 /** Write frame to stream
230 * \throw PluginFrameException On error writing to stream
232 std::ostream & writeTo( std::ostream & stream_r ) const;
234 /** \overload Static version. */
235 static std::ostream & writeTo( std::ostream & stream_r, const PluginFrame & frame_r )
236 { return frame_r.writeTo( stream_r ); }
238 /** Read frame from stream
239 * \throw PluginFrameException If \ref PluginFrame(std::istream&) throws
241 std::istream & readFrom( std::istream & stream_r )
242 { *this = PluginFrame( stream_r ); return stream_r; }
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; }
249 /** Implementation */
252 /** Pointer to implementation */
253 RWCOW_pointer<Impl> _pimpl;
256 /** \relates PluginFrame Stream output for logging */
257 std::ostream & operator<<( std::ostream & str, const PluginFrame & obj );
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 ); }
263 /** \relates PluginFrame Construct from stream. */
264 inline std::istream & operator>>( std::istream & str, PluginFrame & obj )
265 { return PluginFrame::readFrom( str, obj ); }
267 /** \relates PluginFrame Comparison based on content. */
268 bool operator==( const PluginFrame & lhs, const PluginFrame & rhs );
270 /** \relates PluginFrame Comparison based on content. */
271 inline bool operator!=( const PluginFrame & lhs, const PluginFrame & rhs )
272 { return( ! operator==( lhs, rhs ) ); }
274 /////////////////////////////////////////////////////////////////
276 ///////////////////////////////////////////////////////////////////
277 #endif // ZYPP_PLUGINFRAME_H