Botan 2.13.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

pipe.cpp
Go to the documentation of this file.
1 /*
2 * Pipe
3 * (C) 1999-2007 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7
8 #include <botan/pipe.h>
9 #include <botan/internal/out_buf.h>
10 #include <botan/secqueue.h>
11
12 namespace Botan {
13
14 namespace {
15
16 /*
17 * A Filter that does nothing
18 */
19 class Null_Filter final : public Filter
20 {
21 public:
22 void write(const uint8_t input[], size_t length) override
23 { send(input, length); }
24
25 std::string name() const override { return "Null"; }
26 };
27
28 }
29
30 /*
31 * Pipe Constructor
32 */
33 Pipe::Pipe(Filter* f1, Filter* f2, Filter* f3, Filter* f4) :
34 Pipe({f1,f2,f3,f4})
35 {
36 }
37
38 /*
39 * Pipe Constructor
40 */
41 Pipe::Pipe(std::initializer_list<Filter*> args)
42 {
43 m_outputs.reset(new Output_Buffers);
44 m_pipe = nullptr;
45 m_default_read = 0;
46 m_inside_msg = false;
47
48 for(auto i = args.begin(); i != args.end(); ++i)
49 do_append(*i);
50 }
51
52 /*
53 * Pipe Destructor
54 */
55 Pipe::~Pipe()
56 {
57 destruct(m_pipe);
58 }
59
60 /*
61 * Reset the Pipe
62 */
63 void Pipe::reset()
64 {
65 destruct(m_pipe);
66 m_pipe = nullptr;
67 m_inside_msg = false;
68 }
69
70 /*
71 * Destroy the Pipe
72 */
73 void Pipe::destruct(Filter* to_kill)
74 {
75 if(!to_kill || dynamic_cast<SecureQueue*>(to_kill))
76 return;
77 for(size_t j = 0; j != to_kill->total_ports(); ++j)
78 destruct(to_kill->m_next[j]);
79 delete to_kill;
80 }
81
82 /*
83 * Test if the Pipe has any data in it
84 */
85 bool Pipe::end_of_data() const
86 {
87 return (remaining() == 0);
88 }
89
90 /*
91 * Set the default read message
92 */
93 void Pipe::set_default_msg(message_id msg)
94 {
95 if(msg >= message_count())
96 throw Invalid_Argument("Pipe::set_default_msg: msg number is too high");
97 m_default_read = msg;
98 }
99
100 /*
101 * Process a full message at once
102 */
103 void Pipe::process_msg(const uint8_t input[], size_t length)
104 {
105 start_msg();
106 write(input, length);
107 end_msg();
108 }
109
110 /*
111 * Process a full message at once
112 */
113 void Pipe::process_msg(const secure_vector<uint8_t>& input)
114 {
115 process_msg(input.data(), input.size());
116 }
117
118 void Pipe::process_msg(const std::vector<uint8_t>& input)
119 {
120 process_msg(input.data(), input.size());
121 }
122
123 /*
124 * Process a full message at once
125 */
126 void Pipe::process_msg(const std::string& input)
127 {
128 process_msg(cast_char_ptr_to_uint8(input.data()), input.length());
129 }
130
131 /*
132 * Process a full message at once
133 */
134 void Pipe::process_msg(DataSource& input)
135 {
136 start_msg();
137 write(input);
138 end_msg();
139 }
140
141 /*
142 * Start a new message
143 */
144 void Pipe::start_msg()
145 {
146 if(m_inside_msg)
147 throw Invalid_State("Pipe::start_msg: Message was already started");
148 if(m_pipe == nullptr)
149 m_pipe = new Null_Filter;
150 find_endpoints(m_pipe);
151 m_pipe->new_msg();
152 m_inside_msg = true;
153 }
154
155 /*
156 * End the current message
157 */
158 void Pipe::end_msg()
159 {
160 if(!m_inside_msg)
161 throw Invalid_State("Pipe::end_msg: Message was already ended");
162 m_pipe->finish_msg();
163 clear_endpoints(m_pipe);
164 if(dynamic_cast<Null_Filter*>(m_pipe))
165 {
166 delete m_pipe;
167 m_pipe = nullptr;
168 }
169 m_inside_msg = false;
170
171 m_outputs->retire();
172 }
173
174 /*
175 * Find the endpoints of the Pipe
176 */
177 void Pipe::find_endpoints(Filter* f)
178 {
179 for(size_t j = 0; j != f->total_ports(); ++j)
180 if(f->m_next[j] && !dynamic_cast<SecureQueue*>(f->m_next[j]))
181 find_endpoints(f->m_next[j]);
182 else
183 {
184 SecureQueue* q = new SecureQueue;
185 f->m_next[j] = q;
186 m_outputs->add(q);
187 }
188 }
189
190 /*
191 * Remove the SecureQueues attached to the Filter
192 */
193 void Pipe::clear_endpoints(Filter* f)
194 {
195 if(!f) return;
196 for(size_t j = 0; j != f->total_ports(); ++j)
197 {
198 if(f->m_next[j] && dynamic_cast<SecureQueue*>(f->m_next[j]))
199 f->m_next[j] = nullptr;
200 clear_endpoints(f->m_next[j]);
201 }
202 }
203
204 void Pipe::append(Filter* filter)
205 {
206 do_append(filter);
207 }
208
209 void Pipe::append_filter(Filter* filter)
210 {
211 if(m_outputs->message_count() != 0)
212 throw Invalid_State("Cannot call Pipe::append_filter after start_msg");
213
214 do_append(filter);
215 }
216
217 void Pipe::prepend(Filter* filter)
218 {
219 do_prepend(filter);
220 }
221
222 void Pipe::prepend_filter(Filter* filter)
223 {
224 if(m_outputs->message_count() != 0)
225 throw Invalid_State("Cannot call Pipe::prepend_filter after start_msg");
226
227 do_prepend(filter);
228 }
229
230 /*
231 * Append a Filter to the Pipe
232 */
233 void Pipe::do_append(Filter* filter)
234 {
235 if(!filter)
236 return;
237 if(dynamic_cast<SecureQueue*>(filter))
238 throw Invalid_Argument("Pipe::append: SecureQueue cannot be used");
239 if(filter->m_owned)
240 throw Invalid_Argument("Filters cannot be shared among multiple Pipes");
241
242 if(m_inside_msg)
243 throw Invalid_State("Cannot append to a Pipe while it is processing");
244
245 filter->m_owned = true;
246
247 if(!m_pipe) m_pipe = filter;
248 else m_pipe->attach(filter);
249 }
250
251 /*
252 * Prepend a Filter to the Pipe
253 */
254 void Pipe::do_prepend(Filter* filter)
255 {
256 if(m_inside_msg)
257 throw Invalid_State("Cannot prepend to a Pipe while it is processing");
258 if(!filter)
259 return;
260 if(dynamic_cast<SecureQueue*>(filter))
261 throw Invalid_Argument("Pipe::prepend: SecureQueue cannot be used");
262 if(filter->m_owned)
263 throw Invalid_Argument("Filters cannot be shared among multiple Pipes");
264
265 filter->m_owned = true;
266
267 if(m_pipe) filter->attach(m_pipe);
268 m_pipe = filter;
269 }
270
271 /*
272 * Pop a Filter off the Pipe
273 */
274 void Pipe::pop()
275 {
276 if(m_inside_msg)
277 throw Invalid_State("Cannot pop off a Pipe while it is processing");
278
279 if(!m_pipe)
280 return;
281
282 if(m_pipe->total_ports() > 1)
283 throw Invalid_State("Cannot pop off a Filter with multiple ports");
284
285 size_t to_remove = m_pipe->owns() + 1;
286
287 while(to_remove--)
288 {
289 std::unique_ptr<Filter> to_destroy(m_pipe);
290 m_pipe = m_pipe->m_next[0];
291 }
292 }
293
294 /*
295 * Return the number of messages in this Pipe
296 */
297 Pipe::message_id Pipe::message_count() const
298 {
299 return m_outputs->message_count();
300 }
301
302 /*
303 * Static Member Variables
304 */
305 const Pipe::message_id Pipe::LAST_MESSAGE =
306 static_cast<Pipe::message_id>(-2);
307
308 const Pipe::message_id Pipe::DEFAULT_MESSAGE =
309 static_cast<Pipe::message_id>(-1);
310
311 }
Botan::Pipe::start_msg
void start_msg()
Definition: pipe.cpp:144
Botan::Invalid_Argument
Definition: exceptn.h:136
Botan::Pipe::append
void append(Filter *filt)
Definition: pipe.cpp:204
Botan::SecureQueue
Definition: secqueue.h:22
Botan::Pipe::remaining
size_t remaining(message_id msg=DEFAULT_MESSAGE) const BOTAN_WARN_UNUSED_RESULT
Definition: pipe_rw.cpp:131
Botan::Pipe::prepend_filter
void prepend_filter(Filter *filt)
Definition: pipe.cpp:222
Botan::Pipe::message_id
size_t message_id
Definition: pipe.h:35
final
int(* final)(unsigned char *, CTX *)
Definition: commoncrypto_hash.cpp:28
Botan::cast_char_ptr_to_uint8
const uint8_t * cast_char_ptr_to_uint8(const char *s)
Definition: mem_ops.h:189
Botan::Output_Buffers
Definition: out_buf.h:21
Botan::DataSource
Definition: data_src.h:21
Botan::Pipe::reset
void reset()
Definition: pipe.cpp:63
Botan::Pipe::DEFAULT_MESSAGE
static const message_id DEFAULT_MESSAGE
Definition: pipe.h:62
Botan::Pipe::end_msg
void end_msg()
Definition: pipe.cpp:158
name
std::string name
Definition: commoncrypto_hash.cpp:23
Botan::secure_vector
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:65
Botan::Pipe::LAST_MESSAGE
static const message_id LAST_MESSAGE
Definition: pipe.h:57
Botan::Filter
Definition: filter.h:21
Botan::Pipe::Pipe
Pipe(Filter *=nullptr, Filter *=nullptr, Filter *=nullptr, Filter *=nullptr)
Definition: pipe.cpp:33
Botan::Pipe::process_msg
void process_msg(const uint8_t in[], size_t length)
Definition: pipe.cpp:103
Botan
Definition: alg_id.cpp:13
Botan::Pipe::~Pipe
~Pipe()
Definition: pipe.cpp:55
Botan::Invalid_State
Definition: exceptn.h:215
Botan::Pipe::append_filter
void append_filter(Filter *filt)
Definition: pipe.cpp:209
Botan::Pipe::pop
void pop()
Definition: pipe.cpp:274
Botan::Pipe::set_default_msg
void set_default_msg(message_id msg)
Definition: pipe.cpp:93
Botan::Pipe
Definition: pipe.h:29
Botan::Pipe::message_count
message_id message_count() const
Definition: pipe.cpp:297
Botan::Pipe::process_msg
void process_msg(const std::vector< uint8_t > &in)
Definition: pipe.cpp:118
Botan::Pipe::end_of_data
bool end_of_data() const override
Definition: pipe.cpp:85
Botan::Pipe::prepend
void prepend(Filter *filt)
Definition: pipe.cpp:217
Botan::Pipe::write
void write(const uint8_t in[], size_t length)
Definition: pipe_rw.cpp:35