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