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