Botan
1.11.15
|
00001 /* 00002 * Pipe 00003 * (C) 1999-2007 Jack Lloyd 00004 * 2012 Markus Wanner 00005 * 00006 * Botan is released under the Simplified BSD License (see license.txt) 00007 */ 00008 00009 #ifndef BOTAN_PIPE_H__ 00010 #define BOTAN_PIPE_H__ 00011 00012 #include <botan/data_src.h> 00013 #include <botan/filter.h> 00014 #include <botan/exceptn.h> 00015 #include <initializer_list> 00016 #include <iosfwd> 00017 00018 namespace Botan { 00019 00020 /** 00021 * This class represents pipe objects. 00022 * A set of filters can be placed into a pipe, and information flows 00023 * through the pipe until it reaches the end, where the output is 00024 * collected for retrieval. If you're familiar with the Unix shell 00025 * environment, this design will sound quite familiar. 00026 */ 00027 class BOTAN_DLL Pipe : public DataSource 00028 { 00029 public: 00030 /** 00031 * An opaque type that identifies a message in this Pipe 00032 */ 00033 typedef size_t message_id; 00034 00035 /** 00036 * Exception if you use an invalid message as an argument to 00037 * read, remaining, etc 00038 */ 00039 struct BOTAN_DLL Invalid_Message_Number : public Invalid_Argument 00040 { 00041 /** 00042 * @param where the error occured 00043 * @param msg the invalid message id that was used 00044 */ 00045 Invalid_Message_Number(const std::string& where, message_id msg) : 00046 Invalid_Argument("Pipe::" + where + ": Invalid message number " + 00047 std::to_string(msg)) 00048 {} 00049 }; 00050 00051 /** 00052 * A meta-id for whatever the last message is 00053 */ 00054 static const message_id LAST_MESSAGE; 00055 00056 /** 00057 * A meta-id for the default message (set with set_default_msg) 00058 */ 00059 static const message_id DEFAULT_MESSAGE; 00060 00061 /** 00062 * Write input to the pipe, i.e. to its first filter. 00063 * @param in the byte array to write 00064 * @param length the length of the byte array in 00065 */ 00066 void write(const byte in[], size_t length); 00067 00068 /** 00069 * Write input to the pipe, i.e. to its first filter. 00070 * @param in the secure_vector containing the data to write 00071 */ 00072 void write(const secure_vector<byte>& in) 00073 { write(in.data(), in.size()); } 00074 00075 /** 00076 * Write input to the pipe, i.e. to its first filter. 00077 * @param in the std::vector containing the data to write 00078 */ 00079 void write(const std::vector<byte>& in) 00080 { write(in.data(), in.size()); } 00081 00082 /** 00083 * Write input to the pipe, i.e. to its first filter. 00084 * @param in the string containing the data to write 00085 */ 00086 void write(const std::string& in); 00087 00088 /** 00089 * Write input to the pipe, i.e. to its first filter. 00090 * @param in the DataSource to read the data from 00091 */ 00092 void write(DataSource& in); 00093 00094 /** 00095 * Write input to the pipe, i.e. to its first filter. 00096 * @param in a single byte to be written 00097 */ 00098 void write(byte in); 00099 00100 /** 00101 * Perform start_msg(), write() and end_msg() sequentially. 00102 * @param in the byte array containing the data to write 00103 * @param length the length of the byte array to write 00104 */ 00105 void process_msg(const byte in[], size_t length); 00106 00107 /** 00108 * Perform start_msg(), write() and end_msg() sequentially. 00109 * @param in the secure_vector containing the data to write 00110 */ 00111 void process_msg(const secure_vector<byte>& in); 00112 00113 /** 00114 * Perform start_msg(), write() and end_msg() sequentially. 00115 * @param in the secure_vector containing the data to write 00116 */ 00117 void process_msg(const std::vector<byte>& in); 00118 00119 /** 00120 * Perform start_msg(), write() and end_msg() sequentially. 00121 * @param in the string containing the data to write 00122 */ 00123 void process_msg(const std::string& in); 00124 00125 /** 00126 * Perform start_msg(), write() and end_msg() sequentially. 00127 * @param in the DataSource providing the data to write 00128 */ 00129 void process_msg(DataSource& in); 00130 00131 /** 00132 * Find out how many bytes are ready to read. 00133 * @param msg the number identifying the message 00134 * for which the information is desired 00135 * @return number of bytes that can still be read 00136 */ 00137 size_t remaining(message_id msg = DEFAULT_MESSAGE) const; 00138 00139 /** 00140 * Read the default message from the pipe. Moves the internal 00141 * offset so that every call to read will return a new portion of 00142 * the message. 00143 * 00144 * @param output the byte array to write the read bytes to 00145 * @param length the length of the byte array output 00146 * @return number of bytes actually read into output 00147 */ 00148 size_t read(byte output[], size_t length); 00149 00150 /** 00151 * Read a specified message from the pipe. Moves the internal 00152 * offset so that every call to read will return a new portion of 00153 * the message. 00154 * @param output the byte array to write the read bytes to 00155 * @param length the length of the byte array output 00156 * @param msg the number identifying the message to read from 00157 * @return number of bytes actually read into output 00158 */ 00159 size_t read(byte output[], size_t length, message_id msg); 00160 00161 /** 00162 * Read a single byte from the pipe. Moves the internal offset so 00163 * that every call to read will return a new portion of the 00164 * message. 00165 * 00166 * @param output the byte to write the result to 00167 * @param msg the message to read from 00168 * @return number of bytes actually read into output 00169 */ 00170 size_t read(byte& output, message_id msg = DEFAULT_MESSAGE); 00171 00172 /** 00173 * Read the full contents of the pipe. 00174 * @param msg the number identifying the message to read from 00175 * @return secure_vector holding the contents of the pipe 00176 */ 00177 secure_vector<byte> read_all(message_id msg = DEFAULT_MESSAGE); 00178 00179 /** 00180 * Read the full contents of the pipe. 00181 * @param msg the number identifying the message to read from 00182 * @return string holding the contents of the pipe 00183 */ 00184 std::string read_all_as_string(message_id = DEFAULT_MESSAGE); 00185 00186 /** Read from the default message but do not modify the internal 00187 * offset. Consecutive calls to peek() will return portions of 00188 * the message starting at the same position. 00189 * @param output the byte array to write the peeked message part to 00190 * @param length the length of the byte array output 00191 * @param offset the offset from the current position in message 00192 * @return number of bytes actually peeked and written into output 00193 */ 00194 size_t peek(byte output[], size_t length, size_t offset) const; 00195 00196 /** Read from the specified message but do not modify the 00197 * internal offset. Consecutive calls to peek() will return 00198 * portions of the message starting at the same position. 00199 * @param output the byte array to write the peeked message part to 00200 * @param length the length of the byte array output 00201 * @param offset the offset from the current position in message 00202 * @param msg the number identifying the message to peek from 00203 * @return number of bytes actually peeked and written into output 00204 */ 00205 size_t peek(byte output[], size_t length, 00206 size_t offset, message_id msg) const; 00207 00208 /** Read a single byte from the specified message but do not 00209 * modify the internal offset. Consecutive calls to peek() will 00210 * return portions of the message starting at the same position. 00211 * @param output the byte to write the peeked message byte to 00212 * @param offset the offset from the current position in message 00213 * @param msg the number identifying the message to peek from 00214 * @return number of bytes actually peeked and written into output 00215 */ 00216 size_t peek(byte& output, size_t offset, 00217 message_id msg = DEFAULT_MESSAGE) const; 00218 00219 /** 00220 * @return the number of bytes read from the default message. 00221 */ 00222 size_t get_bytes_read() const; 00223 00224 /** 00225 * @return the number of bytes read from the specified message. 00226 */ 00227 size_t get_bytes_read(message_id msg = DEFAULT_MESSAGE) const; 00228 00229 /** 00230 * @return currently set default message 00231 */ 00232 size_t default_msg() const { return default_read; } 00233 00234 /** 00235 * Set the default message 00236 * @param msg the number identifying the message which is going to 00237 * be the new default message 00238 */ 00239 void set_default_msg(message_id msg); 00240 00241 /** 00242 * Get the number of messages the are in this pipe. 00243 * @return number of messages the are in this pipe 00244 */ 00245 message_id message_count() const; 00246 00247 /** 00248 * Test whether this pipe has any data that can be read from. 00249 * @return true if there is more data to read, false otherwise 00250 */ 00251 bool end_of_data() const; 00252 00253 /** 00254 * Start a new message in the pipe. A potential other message in this pipe 00255 * must be closed with end_msg() before this function may be called. 00256 */ 00257 void start_msg(); 00258 00259 /** 00260 * End the current message. 00261 */ 00262 void end_msg(); 00263 00264 /** 00265 * Insert a new filter at the front of the pipe 00266 * @param filt the new filter to insert 00267 */ 00268 void prepend(Filter* filt); 00269 00270 /** 00271 * Insert a new filter at the back of the pipe 00272 * @param filt the new filter to insert 00273 */ 00274 void append(Filter* filt); 00275 00276 /** 00277 * Remove the first filter at the front of the pipe. 00278 */ 00279 void pop(); 00280 00281 /** 00282 * Reset this pipe to an empty pipe. 00283 */ 00284 void reset(); 00285 00286 /** 00287 * Construct a Pipe of up to four filters. The filters are set up 00288 * in the same order as the arguments. 00289 */ 00290 Pipe(Filter* = nullptr, Filter* = nullptr, 00291 Filter* = nullptr, Filter* = nullptr); 00292 00293 /** 00294 * Construct a Pipe from a list of filters 00295 * @param filters the set of filters to use 00296 */ 00297 Pipe(std::initializer_list<Filter*> filters); 00298 00299 Pipe(const Pipe&) = delete; 00300 Pipe& operator=(const Pipe&) = delete; 00301 00302 ~Pipe(); 00303 private: 00304 void init(); 00305 void destruct(Filter*); 00306 void find_endpoints(Filter*); 00307 void clear_endpoints(Filter*); 00308 00309 message_id get_message_no(const std::string&, message_id) const; 00310 00311 Filter* pipe; 00312 class Output_Buffers* outputs; 00313 message_id default_read; 00314 bool inside_msg; 00315 }; 00316 00317 /** 00318 * Stream output operator; dumps the results from pipe's default 00319 * message to the output stream. 00320 * @param out an output stream 00321 * @param pipe the pipe 00322 */ 00323 BOTAN_DLL std::ostream& operator<<(std::ostream& out, Pipe& pipe); 00324 00325 /** 00326 * Stream input operator; dumps the remaining bytes of input 00327 * to the (assumed open) pipe message. 00328 * @param in the input stream 00329 * @param pipe the pipe 00330 */ 00331 BOTAN_DLL std::istream& operator>>(std::istream& in, Pipe& pipe); 00332 00333 } 00334 00335 #if defined(BOTAN_HAS_PIPE_UNIXFD_IO) 00336 #include <botan/fd_unix.h> 00337 #endif 00338 00339 #endif