• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 5123321399

30 May 2023 04:06PM UTC coverage: 92.213% (+0.004%) from 92.209%
5123321399

Pull #3558

github

web-flow
Merge dd72f7389 into 057bcbc35
Pull Request #3558: Add braces around all if/else statements

75602 of 81986 relevant lines covered (92.21%)

11859779.3 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.65
/src/lib/filters/pipe.cpp
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

10
#include <botan/internal/fmt.h>
11
#include <botan/internal/out_buf.h>
12
#include <botan/internal/secqueue.h>
13
#include <memory>
14

15
namespace Botan {
16

17
namespace {
18

19
/*
20
* A Filter that does nothing
21
*/
22
class Null_Filter final : public Filter {
4✔
23
   public:
24
      void write(const uint8_t input[], size_t length) override { send(input, length); }
1✔
25

26
      std::string name() const override { return "Null"; }
×
27
};
28

29
}  // namespace
30

31
Pipe::Invalid_Message_Number::Invalid_Message_Number(std::string_view where, message_id msg) :
1✔
32
      Invalid_Argument(fmt("Pipe::{}: Invalid message number {}", where, msg)) {}
2✔
33

34
/*
35
* Pipe Constructor
36
*/
37
Pipe::Pipe(Filter* f1, Filter* f2, Filter* f3, Filter* f4) : Pipe({f1, f2, f3, f4}) {}
18✔
38

39
/*
40
* Pipe Constructor
41
*/
42
Pipe::Pipe(std::initializer_list<Filter*> args) {
18✔
43
   m_outputs = std::make_unique<Output_Buffers>();
18✔
44
   m_pipe = nullptr;
18✔
45
   m_default_read = 0;
18✔
46
   m_inside_msg = false;
18✔
47

48
   for(auto arg : args) {
90✔
49
      do_append(arg);
72✔
50
   }
51
}
18✔
52

53
/*
54
* Pipe Destructor
55
*/
56
Pipe::~Pipe() { destruct(m_pipe); }
18✔
57

58
/*
59
* Reset the Pipe
60
*/
61
void Pipe::reset() {
6✔
62
   destruct(m_pipe);
6✔
63
   m_pipe = nullptr;
6✔
64
   m_inside_msg = false;
6✔
65
}
6✔
66

67
/*
68
* Destroy the Pipe
69
*/
70
void Pipe::destruct(Filter* to_kill) {
80✔
71
   if(!to_kill || dynamic_cast<SecureQueue*>(to_kill)) {
80✔
72
      return;
73
   }
74
   for(size_t j = 0; j != to_kill->total_ports(); ++j) {
105✔
75
      destruct(to_kill->m_next[j]);
56✔
76
   }
77
   delete to_kill;
49✔
78
}
79

80
/*
81
* Test if the Pipe has any data in it
82
*/
83
bool Pipe::end_of_data() const { return (remaining() == 0); }
2✔
84

85
/*
86
* Set the default read message
87
*/
88
void Pipe::set_default_msg(message_id msg) {
3✔
89
   if(msg >= message_count()) {
3✔
90
      throw Invalid_Argument("Pipe::set_default_msg: msg number is too high");
×
91
   }
92
   m_default_read = msg;
3✔
93
}
3✔
94

95
/*
96
* Process a full message at once
97
*/
98
void Pipe::process_msg(const uint8_t input[], size_t length) {
39✔
99
   start_msg();
39✔
100
   write(input, length);
39✔
101
   end_msg();
39✔
102
}
39✔
103

104
/*
105
* Process a full message at once
106
*/
107
void Pipe::process_msg(const secure_vector<uint8_t>& input) { process_msg(input.data(), input.size()); }
2✔
108

109
void Pipe::process_msg(const std::vector<uint8_t>& input) { process_msg(input.data(), input.size()); }
1✔
110

111
/*
112
* Process a full message at once
113
*/
114
void Pipe::process_msg(std::string_view input) { process_msg(cast_char_ptr_to_uint8(input.data()), input.length()); }
36✔
115

116
/*
117
* Process a full message at once
118
*/
119
void Pipe::process_msg(DataSource& input) {
4✔
120
   start_msg();
4✔
121
   write(input);
4✔
122
   end_msg();
4✔
123
}
4✔
124

125
/*
126
* Start a new message
127
*/
128
void Pipe::start_msg() {
65✔
129
   if(m_inside_msg) {
65✔
130
      throw Invalid_State("Pipe::start_msg: Message was already started");
×
131
   }
132
   if(m_pipe == nullptr) {
65✔
133
      m_pipe = new Null_Filter;
2✔
134
   }
135
   find_endpoints(m_pipe);
65✔
136
   m_pipe->new_msg();
65✔
137
   m_inside_msg = true;
65✔
138
}
65✔
139

140
/*
141
* End the current message
142
*/
143
void Pipe::end_msg() {
65✔
144
   if(!m_inside_msg) {
65✔
145
      throw Invalid_State("Pipe::end_msg: Message was already ended");
×
146
   }
147
   m_pipe->finish_msg();
65✔
148
   clear_endpoints(m_pipe);
65✔
149
   if(dynamic_cast<Null_Filter*>(m_pipe)) {
65✔
150
      delete m_pipe;
2✔
151
      m_pipe = nullptr;
2✔
152
   }
153
   m_inside_msg = false;
65✔
154

155
   m_outputs->retire();
65✔
156
}
65✔
157

158
/*
159
* Find the endpoints of the Pipe
160
*/
161
void Pipe::find_endpoints(Filter* f) {
135✔
162
   for(size_t j = 0; j != f->total_ports(); ++j) {
277✔
163
      if(f->m_next[j] && !dynamic_cast<SecureQueue*>(f->m_next[j])) {
142✔
164
         find_endpoints(f->m_next[j]);
70✔
165
      } else {
166
         SecureQueue* q = new SecureQueue;
72✔
167
         f->m_next[j] = q;
72✔
168
         m_outputs->add(q);
72✔
169
      }
170
   }
171
}
135✔
172

173
/*
174
* Remove the SecureQueues attached to the Filter
175
*/
176
void Pipe::clear_endpoints(Filter* f) {
207✔
177
   if(!f) {
207✔
178
      return;
179
   }
180
   for(size_t j = 0; j != f->total_ports(); ++j) {
277✔
181
      if(f->m_next[j] && dynamic_cast<SecureQueue*>(f->m_next[j])) {
142✔
182
         f->m_next[j] = nullptr;
72✔
183
      }
184
      clear_endpoints(f->m_next[j]);
142✔
185
   }
186
}
187

188
void Pipe::append(Filter* filter) { do_append(filter); }
19✔
189

190
void Pipe::append_filter(Filter* filter) {
4✔
191
   if(m_outputs->message_count() != 0) {
4✔
192
      throw Invalid_State("Cannot call Pipe::append_filter after start_msg");
2✔
193
   }
194

195
   do_append(filter);
2✔
196
}
2✔
197

198
void Pipe::prepend(Filter* filter) { do_prepend(filter); }
5✔
199

200
void Pipe::prepend_filter(Filter* filter) {
4✔
201
   if(m_outputs->message_count() != 0) {
4✔
202
      throw Invalid_State("Cannot call Pipe::prepend_filter after start_msg");
2✔
203
   }
204

205
   do_prepend(filter);
2✔
206
}
2✔
207

208
/*
209
* Append a Filter to the Pipe
210
*/
211
void Pipe::do_append(Filter* filter) {
93✔
212
   if(!filter) {
93✔
213
      return;
214
   }
215
   if(dynamic_cast<SecureQueue*>(filter)) {
41✔
216
      throw Invalid_Argument("Pipe::append: SecureQueue cannot be used");
1✔
217
   }
218
   if(filter->m_owned) {
40✔
219
      throw Invalid_Argument("Filters cannot be shared among multiple Pipes");
×
220
   }
221

222
   if(m_inside_msg) {
40✔
223
      throw Invalid_State("Cannot append to a Pipe while it is processing");
1✔
224
   }
225

226
   filter->m_owned = true;
39✔
227

228
   if(!m_pipe) {
39✔
229
      m_pipe = filter;
25✔
230
   } else {
231
      m_pipe->attach(filter);
14✔
232
   }
233
}
234

235
/*
236
* Prepend a Filter to the Pipe
237
*/
238
void Pipe::do_prepend(Filter* filter) {
7✔
239
   if(m_inside_msg) {
7✔
240
      throw Invalid_State("Cannot prepend to a Pipe while it is processing");
1✔
241
   }
242
   if(!filter) {
6✔
243
      return;
244
   }
245
   if(dynamic_cast<SecureQueue*>(filter)) {
3✔
246
      throw Invalid_Argument("Pipe::prepend: SecureQueue cannot be used");
1✔
247
   }
248
   if(filter->m_owned) {
2✔
249
      throw Invalid_Argument("Filters cannot be shared among multiple Pipes");
×
250
   }
251

252
   filter->m_owned = true;
2✔
253

254
   if(m_pipe) {
2✔
255
      filter->attach(m_pipe);
×
256
   }
257
   m_pipe = filter;
2✔
258
}
259

260
/*
261
* Pop a Filter off the Pipe
262
*/
263
void Pipe::pop() {
10✔
264
   if(m_inside_msg) {
10✔
265
      throw Invalid_State("Cannot pop off a Pipe while it is processing");
1✔
266
   }
267

268
   if(!m_pipe) {
9✔
269
      return;
270
   }
271

272
   if(m_pipe->total_ports() > 1) {
7✔
273
      throw Invalid_State("Cannot pop off a Filter with multiple ports");
×
274
   }
275

276
   size_t to_remove = m_pipe->owns() + 1;
7✔
277

278
   while(to_remove--) {
16✔
279
      std::unique_ptr<Filter> to_destroy(m_pipe);
9✔
280
      m_pipe = m_pipe->m_next[0];
9✔
281
   }
9✔
282
}
283

284
/*
285
* Return the number of messages in this Pipe
286
*/
287
Pipe::message_id Pipe::message_count() const { return m_outputs->message_count(); }
243✔
288

289
/*
290
* Static Member Variables
291
*/
292
const Pipe::message_id Pipe::LAST_MESSAGE = static_cast<Pipe::message_id>(-2);
293

294
const Pipe::message_id Pipe::DEFAULT_MESSAGE = static_cast<Pipe::message_id>(-1);
295

296
}  // namespace Botan
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc