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