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