Botan  2.4.0
Crypto and TLS for C++11
pipe.h
Go to the documentation of this file.
1 /*
2 * Pipe
3 * (C) 1999-2007 Jack Lloyd
4 * 2012 Markus Wanner
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 */
8 
9 #ifndef BOTAN_PIPE_H_
10 #define BOTAN_PIPE_H_
11 
12 #include <botan/data_src.h>
13 #include <botan/exceptn.h>
14 #include <initializer_list>
15 #include <iosfwd>
16 
17 namespace Botan {
18 
19 class Filter;
20 class Output_Buffers;
21 
22 /**
23 * This class represents pipe objects.
24 * A set of filters can be placed into a pipe, and information flows
25 * through the pipe until it reaches the end, where the output is
26 * collected for retrieval. If you're familiar with the Unix shell
27 * environment, this design will sound quite familiar.
28 */
29 class BOTAN_PUBLIC_API(2,0) Pipe final : public DataSource
30  {
31  public:
32  /**
33  * An opaque type that identifies a message in this Pipe
34  */
35  typedef size_t message_id;
36 
37  /**
38  * Exception if you use an invalid message as an argument to
39  * read, remaining, etc
40  */
42  {
43  public:
44  /**
45  * @param where the error occurred
46  * @param msg the invalid message id that was used
47  */
48  Invalid_Message_Number(const std::string& where, message_id msg) :
49  Invalid_Argument("Pipe::" + where + ": Invalid message number " +
50  std::to_string(msg))
51  {}
52  };
53 
54  /**
55  * A meta-id for whatever the last message is
56  */
57  static const message_id LAST_MESSAGE;
58 
59  /**
60  * A meta-id for the default message (set with set_default_msg)
61  */
62  static const message_id DEFAULT_MESSAGE;
63 
64  /**
65  * Write input to the pipe, i.e. to its first filter.
66  * @param in the byte array to write
67  * @param length the length of the byte array in
68  */
69  void write(const uint8_t in[], size_t length);
70 
71  /**
72  * Write input to the pipe, i.e. to its first filter.
73  * @param in the secure_vector containing the data to write
74  */
75  void write(const secure_vector<uint8_t>& in)
76  { write(in.data(), in.size()); }
77 
78  /**
79  * Write input to the pipe, i.e. to its first filter.
80  * @param in the std::vector containing the data to write
81  */
82  void write(const std::vector<uint8_t>& in)
83  { write(in.data(), in.size()); }
84 
85  /**
86  * Write input to the pipe, i.e. to its first filter.
87  * @param in the string containing the data to write
88  */
89  void write(const std::string& in);
90 
91  /**
92  * Write input to the pipe, i.e. to its first filter.
93  * @param in the DataSource to read the data from
94  */
95  void write(DataSource& in);
96 
97  /**
98  * Write input to the pipe, i.e. to its first filter.
99  * @param in a single byte to be written
100  */
101  void write(uint8_t in);
102 
103  /**
104  * Perform start_msg(), write() and end_msg() sequentially.
105  * @param in the byte array containing the data to write
106  * @param length the length of the byte array to write
107  */
108  void process_msg(const uint8_t in[], size_t length);
109 
110  /**
111  * Perform start_msg(), write() and end_msg() sequentially.
112  * @param in the secure_vector containing the data to write
113  */
114  void process_msg(const secure_vector<uint8_t>& in);
115 
116  /**
117  * Perform start_msg(), write() and end_msg() sequentially.
118  * @param in the secure_vector containing the data to write
119  */
120  void process_msg(const std::vector<uint8_t>& in);
121 
122  /**
123  * Perform start_msg(), write() and end_msg() sequentially.
124  * @param in the string containing the data to write
125  */
126  void process_msg(const std::string& in);
127 
128  /**
129  * Perform start_msg(), write() and end_msg() sequentially.
130  * @param in the DataSource providing the data to write
131  */
132  void process_msg(DataSource& in);
133 
134  /**
135  * Find out how many bytes are ready to read.
136  * @param msg the number identifying the message
137  * for which the information is desired
138  * @return number of bytes that can still be read
139  */
140  size_t remaining(message_id msg = DEFAULT_MESSAGE) const BOTAN_WARN_UNUSED_RESULT;
141 
142  /**
143  * Read the default message from the pipe. Moves the internal
144  * offset so that every call to read will return a new portion of
145  * the message.
146  *
147  * @param output the byte array to write the read bytes to
148  * @param length the length of the byte array output
149  * @return number of bytes actually read into output
150  */
151  size_t read(uint8_t output[], size_t length) override BOTAN_WARN_UNUSED_RESULT;
152 
153  /**
154  * Read a specified message from the pipe. Moves the internal
155  * offset so that every call to read will return a new portion of
156  * the message.
157  * @param output the byte array to write the read bytes to
158  * @param length the length of the byte array output
159  * @param msg the number identifying the message to read from
160  * @return number of bytes actually read into output
161  */
162  size_t read(uint8_t output[], size_t length, message_id msg) BOTAN_WARN_UNUSED_RESULT;
163 
164  /**
165  * Read a single byte from the pipe. Moves the internal offset so
166  * that every call to read will return a new portion of the
167  * message.
168  *
169  * @param output the byte to write the result to
170  * @param msg the message to read from
171  * @return number of bytes actually read into output
172  */
173  size_t read(uint8_t& output, message_id msg = DEFAULT_MESSAGE) BOTAN_WARN_UNUSED_RESULT;
174 
175  /**
176  * Read the full contents of the pipe.
177  * @param msg the number identifying the message to read from
178  * @return secure_vector holding the contents of the pipe
179  */
180  secure_vector<uint8_t> read_all(message_id msg = DEFAULT_MESSAGE) BOTAN_WARN_UNUSED_RESULT;
181 
182  /**
183  * Read the full contents of the pipe.
184  * @param msg the number identifying the message to read from
185  * @return string holding the contents of the pipe
186  */
187  std::string read_all_as_string(message_id msg = DEFAULT_MESSAGE) BOTAN_WARN_UNUSED_RESULT;
188 
189  /**
190  * Read from the default message but do not modify the internal
191  * offset. Consecutive calls to peek() will return portions of
192  * the message starting at the same position.
193  * @param output the byte array to write the peeked message part to
194  * @param length the length of the byte array output
195  * @param offset the offset from the current position in message
196  * @return number of bytes actually peeked and written into output
197  */
198  size_t peek(uint8_t output[], size_t length, size_t offset) const override BOTAN_WARN_UNUSED_RESULT;
199 
200  /** Read from the specified message but do not modify the
201  * internal offset. Consecutive calls to peek() will return
202  * portions of the message starting at the same position.
203  * @param output the byte array to write the peeked message part to
204  * @param length the length of the byte array output
205  * @param offset the offset from the current position in message
206  * @param msg the number identifying the message to peek from
207  * @return number of bytes actually peeked and written into output
208  */
209  size_t peek(uint8_t output[], size_t length,
210  size_t offset, message_id msg) const BOTAN_WARN_UNUSED_RESULT;
211 
212  /** Read a single byte from the specified message but do not
213  * modify the internal offset. Consecutive calls to peek() will
214  * return portions of the message starting at the same position.
215  * @param output the byte to write the peeked message byte to
216  * @param offset the offset from the current position in message
217  * @param msg the number identifying the message to peek from
218  * @return number of bytes actually peeked and written into output
219  */
220  size_t peek(uint8_t& output, size_t offset,
221  message_id msg = DEFAULT_MESSAGE) const BOTAN_WARN_UNUSED_RESULT;
222 
223  /**
224  * @return the number of bytes read from the default message.
225  */
226  size_t get_bytes_read() const override;
227 
228  /**
229  * @return the number of bytes read from the specified message.
230  */
231  size_t get_bytes_read(message_id msg) const;
232 
233  bool check_available(size_t n) override;
234  bool check_available_msg(size_t n, message_id msg);
235 
236  /**
237  * @return currently set default message
238  */
239  size_t default_msg() const { return m_default_read; }
240 
241  /**
242  * Set the default message
243  * @param msg the number identifying the message which is going to
244  * be the new default message
245  */
246  void set_default_msg(message_id msg);
247 
248  /**
249  * Get the number of messages the are in this pipe.
250  * @return number of messages the are in this pipe
251  */
252  message_id message_count() const;
253 
254  /**
255  * Test whether this pipe has any data that can be read from.
256  * @return true if there is more data to read, false otherwise
257  */
258  bool end_of_data() const override;
259 
260  /**
261  * Start a new message in the pipe. A potential other message in this pipe
262  * must be closed with end_msg() before this function may be called.
263  */
264  void start_msg();
265 
266  /**
267  * End the current message.
268  */
269  void end_msg();
270 
271  /**
272  * Insert a new filter at the front of the pipe
273  * @param filt the new filter to insert
274  */
275  BOTAN_DEPRECATED("Runtime modification of Pipe deprecated")
276  void prepend(Filter* filt);
277 
278  /**
279  * Insert a new filter at the back of the pipe
280  * @param filt the new filter to insert
281  */
282  BOTAN_DEPRECATED("Runtime modification of Pipe deprecated")
283  void append(Filter* filt);
284 
285  /**
286  * Remove the first filter at the front of the pipe.
287  */
288  BOTAN_DEPRECATED("Runtime modification of Pipe deprecated")
289  void pop();
290 
291  /**
292  * Reset this pipe to an empty pipe.
293  */
294  BOTAN_DEPRECATED("Runtime modification of Pipe deprecated")
295  void reset();
296 
297  /**
298  * Append a new filter onto the filter sequence. This may only be
299  * called immediately after initial construction, before _any_
300  * calls to start_msg have been made.
301  *
302  * This function (unlike append) is not deprecated, as it allows
303  * only modification of the pipe at initialization (before use)
304  * rather than after messages have been processed.
305  */
306  void append_filter(Filter* filt);
307 
308  /**
309  * Construct a Pipe of up to four filters. The filters are set up
310  * in the same order as the arguments.
311  */
312  Pipe(Filter* = nullptr, Filter* = nullptr,
313  Filter* = nullptr, Filter* = nullptr);
314 
315  /**
316  * Construct a Pipe from a list of filters
317  * @param filters the set of filters to use
318  */
319  explicit Pipe(std::initializer_list<Filter*> filters);
320 
321  Pipe(const Pipe&) = delete;
322  Pipe& operator=(const Pipe&) = delete;
323 
324  ~Pipe();
325  private:
326  void destruct(Filter*);
327  void do_append(Filter* filt);
328  void find_endpoints(Filter*);
329  void clear_endpoints(Filter*);
330 
331  message_id get_message_no(const std::string&, message_id) const;
332 
333  Filter* m_pipe;
334  std::unique_ptr<Output_Buffers> m_outputs;
335  message_id m_default_read;
336  bool m_inside_msg;
337  };
338 
339 /**
340 * Stream output operator; dumps the results from pipe's default
341 * message to the output stream.
342 * @param out an output stream
343 * @param pipe the pipe
344 */
345 BOTAN_PUBLIC_API(2,0) std::ostream& operator<<(std::ostream& out, Pipe& pipe);
346 
347 /**
348 * Stream input operator; dumps the remaining bytes of input
349 * to the (assumed open) pipe message.
350 * @param in the input stream
351 * @param pipe the pipe
352 */
353 BOTAN_PUBLIC_API(2,0) std::istream& operator>>(std::istream& in, Pipe& pipe);
354 
355 }
356 
357 #if defined(BOTAN_HAS_PIPE_UNIXFD_IO)
358  #include <botan/fd_unix.h>
359 #endif
360 
361 #endif
size_t default_msg() const
Definition: pipe.h:239
int operator<<(int fd, Pipe &pipe)
Definition: fd_unix.cpp:17
size_t message_id
Definition: pipe.h:35
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:27
Definition: bigint.h:635
#define BOTAN_WARN_UNUSED_RESULT
Definition: compiler.h:84
static const message_id DEFAULT_MESSAGE
Definition: pipe.h:62
static const message_id LAST_MESSAGE
Definition: pipe.h:57
Definition: alg_id.cpp:13
void write(const secure_vector< uint8_t > &in)
Definition: pipe.h:75
void write(const std::vector< uint8_t > &in)
Definition: pipe.h:82
std::string to_string(const secure_vector< uint8_t > &bytes)
Definition: stl_util.h:25
int operator>>(int fd, Pipe &pipe)
Definition: fd_unix.cpp:40
Invalid_Message_Number(const std::string &where, message_id msg)
Definition: pipe.h:48
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:88