Botan 3.0.0-alpha0
Crypto and TLS for C&
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
17namespace Botan {
18
19class Filter;
20class 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*/
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 */
58
59 /**
60 * A meta-id for the default message (set with set_default_msg)
61 */
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 */
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 [[nodiscard]] size_t remaining(message_id msg = DEFAULT_MESSAGE) const;
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 [[nodiscard]] size_t read(uint8_t output[], size_t length) override;
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 [[nodiscard]] size_t read(uint8_t output[], size_t length, message_id msg);
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 [[nodiscard]] size_t read(uint8_t& output, message_id msg = DEFAULT_MESSAGE);
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 [[nodiscard]] secure_vector<uint8_t> read_all(message_id msg = DEFAULT_MESSAGE);
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 [[nodiscard]] std::string read_all_as_string(message_id msg = DEFAULT_MESSAGE);
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 [[nodiscard]] size_t peek(uint8_t output[], size_t length, size_t offset) const override;
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 [[nodiscard]] size_t peek(uint8_t output[], size_t length,
210 size_t offset, message_id msg) const;
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 [[nodiscard]] size_t peek(uint8_t& output, size_t offset,
221 message_id msg = DEFAULT_MESSAGE) const;
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) const;
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 * Deprecated because runtime modification of Pipes is deprecated.
274 * You can instead use prepend_filter which only works before the first
275 * message is processed.
276 * @param filt the new filter to insert
277 */
278 BOTAN_DEPRECATED("Runtime modification of Pipe deprecated")
279 void prepend(Filter* filt);
280
281 /**
282 * Insert a new filter at the back of the pipe
283 * Deprecated because runtime modification of Pipes is deprecated.
284 * You can instead use append_filter which only works before the first
285 * message is processed.
286 * @param filt the new filter to insert
287 */
288 BOTAN_DEPRECATED("Runtime modification of Pipe deprecated")
289 void append(Filter* filt);
290
291 /**
292 * Remove the first filter at the front of the pipe.
293 */
294 BOTAN_DEPRECATED("Runtime modification of Pipe deprecated")
295 void pop();
296
297 /**
298 * Reset this pipe to an empty pipe.
299 */
300 BOTAN_DEPRECATED("Runtime modification of Pipe deprecated")
301 void reset();
302
303 /**
304 * Append a new filter onto the filter sequence. This may only be
305 * called immediately after initial construction, before _any_
306 * calls to start_msg have been made.
307 *
308 * This function (unlike append) is not deprecated, as it allows
309 * only modification of the pipe at initialization (before use)
310 * rather than after messages have been processed.
311 */
312 void append_filter(Filter* filt);
313
314 /**
315 * Prepend a new filter onto the filter sequence. This may only be
316 * called immediately after initial construction, before _any_
317 * calls to start_msg have been made.
318 *
319 * This function (unlike prepend) is not deprecated, as it allows
320 * only modification of the pipe at initialization (before use)
321 * rather than after messages have been processed.
322 */
323 void prepend_filter(Filter* filt);
324
325 /**
326 * Construct a Pipe of up to four filters. The filters are set up
327 * in the same order as the arguments.
328 */
329 Pipe(Filter* = nullptr, Filter* = nullptr,
330 Filter* = nullptr, Filter* = nullptr);
331
332 /**
333 * Construct a Pipe from a list of filters
334 * @param filters the set of filters to use
335 */
336 explicit Pipe(std::initializer_list<Filter*> filters);
337
338 Pipe(const Pipe&) = delete;
339 Pipe& operator=(const Pipe&) = delete;
340
341 ~Pipe();
342 private:
343 void destruct(Filter*);
344 void do_append(Filter* filt);
345 void do_prepend(Filter* filt);
346 void find_endpoints(Filter*);
347 void clear_endpoints(Filter*);
348
349 message_id get_message_no(const std::string&, message_id) const;
350
351 Filter* m_pipe;
352 std::unique_ptr<Output_Buffers> m_outputs;
353 message_id m_default_read;
354 bool m_inside_msg;
355 };
356
357/**
358* Stream output operator; dumps the results from pipe's default
359* message to the output stream.
360* @param out an output stream
361* @param pipe the pipe
362*/
363BOTAN_PUBLIC_API(2,0) std::ostream& operator<<(std::ostream& out, Pipe& pipe);
364
365/**
366* Stream input operator; dumps the remaining bytes of input
367* to the (assumed open) pipe message.
368* @param in the input stream
369* @param pipe the pipe
370*/
371BOTAN_PUBLIC_API(2,0) std::istream& operator>>(std::istream& in, Pipe& pipe);
372
373}
374
375#if defined(BOTAN_HAS_PIPE_UNIXFD_IO)
376 #include <botan/fd_unix.h>
377#endif
378
379#endif
Invalid_Message_Number(const std::string &where, message_id msg)
Definition: pipe.h:48
size_t message_id
Definition: pipe.h:35
static const message_id LAST_MESSAGE
Definition: pipe.h:57
size_t default_msg() const
Definition: pipe.h:239
static const message_id DEFAULT_MESSAGE
Definition: pipe.h:62
void write(const secure_vector< uint8_t > &in)
Definition: pipe.h:75
void write(const std::vector< uint8_t > &in)
Definition: pipe.h:82
int(* final)(unsigned char *, CTX *)
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:31
Definition: alg_id.cpp:13
std::string to_string(ErrorType type)
Convert an ErrorType to string.
Definition: exceptn.cpp:11
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:65
Definition: bigint.h:1077