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

randombit / botan / 5230455705

10 Jun 2023 02:30PM UTC coverage: 91.715% (-0.03%) from 91.746%
5230455705

push

github

randombit
Merge GH #3584 Change clang-format AllowShortFunctionsOnASingleLine config from All to Inline

77182 of 84154 relevant lines covered (91.72%)

11975295.43 hits per line

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

94.29
/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() {
18✔
57
   destruct(m_pipe);
18✔
58
}
18✔
59

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

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

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

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

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

108
/*
109
* Process a full message at once
110
*/
111
void Pipe::process_msg(const secure_vector<uint8_t>& input) {
2✔
112
   process_msg(input.data(), input.size());
2✔
113
}
2✔
114

115
void Pipe::process_msg(const std::vector<uint8_t>& input) {
1✔
116
   process_msg(input.data(), input.size());
1✔
117
}
1✔
118

119
/*
120
* Process a full message at once
121
*/
122
void Pipe::process_msg(std::string_view input) {
36✔
123
   process_msg(cast_char_ptr_to_uint8(input.data()), input.length());
36✔
124
}
36✔
125

126
/*
127
* Process a full message at once
128
*/
129
void Pipe::process_msg(DataSource& input) {
4✔
130
   start_msg();
4✔
131
   write(input);
4✔
132
   end_msg();
4✔
133
}
4✔
134

135
/*
136
* Start a new message
137
*/
138
void Pipe::start_msg() {
65✔
139
   if(m_inside_msg) {
65✔
140
      throw Invalid_State("Pipe::start_msg: Message was already started");
×
141
   }
142
   if(m_pipe == nullptr) {
65✔
143
      m_pipe = new Null_Filter;
2✔
144
   }
145
   find_endpoints(m_pipe);
65✔
146
   m_pipe->new_msg();
65✔
147
   m_inside_msg = true;
65✔
148
}
65✔
149

150
/*
151
* End the current message
152
*/
153
void Pipe::end_msg() {
65✔
154
   if(!m_inside_msg) {
65✔
155
      throw Invalid_State("Pipe::end_msg: Message was already ended");
×
156
   }
157
   m_pipe->finish_msg();
65✔
158
   clear_endpoints(m_pipe);
65✔
159
   if(dynamic_cast<Null_Filter*>(m_pipe)) {
65✔
160
      delete m_pipe;
2✔
161
      m_pipe = nullptr;
2✔
162
   }
163
   m_inside_msg = false;
65✔
164

165
   m_outputs->retire();
65✔
166
}
65✔
167

168
/*
169
* Find the endpoints of the Pipe
170
*/
171
void Pipe::find_endpoints(Filter* f) {
135✔
172
   for(size_t j = 0; j != f->total_ports(); ++j) {
277✔
173
      if(f->m_next[j] && !dynamic_cast<SecureQueue*>(f->m_next[j])) {
142✔
174
         find_endpoints(f->m_next[j]);
70✔
175
      } else {
176
         SecureQueue* q = new SecureQueue;
72✔
177
         f->m_next[j] = q;
72✔
178
         m_outputs->add(q);
72✔
179
      }
180
   }
181
}
135✔
182

183
/*
184
* Remove the SecureQueues attached to the Filter
185
*/
186
void Pipe::clear_endpoints(Filter* f) {
207✔
187
   if(!f) {
207✔
188
      return;
189
   }
190
   for(size_t j = 0; j != f->total_ports(); ++j) {
277✔
191
      if(f->m_next[j] && dynamic_cast<SecureQueue*>(f->m_next[j])) {
142✔
192
         f->m_next[j] = nullptr;
72✔
193
      }
194
      clear_endpoints(f->m_next[j]);
142✔
195
   }
196
}
197

198
void Pipe::append(Filter* filter) {
19✔
199
   do_append(filter);
19✔
200
}
17✔
201

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

207
   do_append(filter);
2✔
208
}
2✔
209

210
void Pipe::prepend(Filter* filter) {
5✔
211
   do_prepend(filter);
5✔
212
}
3✔
213

214
void Pipe::prepend_filter(Filter* filter) {
4✔
215
   if(m_outputs->message_count() != 0) {
4✔
216
      throw Invalid_State("Cannot call Pipe::prepend_filter after start_msg");
2✔
217
   }
218

219
   do_prepend(filter);
2✔
220
}
2✔
221

222
/*
223
* Append a Filter to the Pipe
224
*/
225
void Pipe::do_append(Filter* filter) {
93✔
226
   if(!filter) {
93✔
227
      return;
228
   }
229
   if(dynamic_cast<SecureQueue*>(filter)) {
41✔
230
      throw Invalid_Argument("Pipe::append: SecureQueue cannot be used");
1✔
231
   }
232
   if(filter->m_owned) {
40✔
233
      throw Invalid_Argument("Filters cannot be shared among multiple Pipes");
×
234
   }
235

236
   if(m_inside_msg) {
40✔
237
      throw Invalid_State("Cannot append to a Pipe while it is processing");
1✔
238
   }
239

240
   filter->m_owned = true;
39✔
241

242
   if(!m_pipe) {
39✔
243
      m_pipe = filter;
25✔
244
   } else {
245
      m_pipe->attach(filter);
14✔
246
   }
247
}
248

249
/*
250
* Prepend a Filter to the Pipe
251
*/
252
void Pipe::do_prepend(Filter* filter) {
7✔
253
   if(m_inside_msg) {
7✔
254
      throw Invalid_State("Cannot prepend to a Pipe while it is processing");
1✔
255
   }
256
   if(!filter) {
6✔
257
      return;
258
   }
259
   if(dynamic_cast<SecureQueue*>(filter)) {
3✔
260
      throw Invalid_Argument("Pipe::prepend: SecureQueue cannot be used");
1✔
261
   }
262
   if(filter->m_owned) {
2✔
263
      throw Invalid_Argument("Filters cannot be shared among multiple Pipes");
×
264
   }
265

266
   filter->m_owned = true;
2✔
267

268
   if(m_pipe) {
2✔
269
      filter->attach(m_pipe);
×
270
   }
271
   m_pipe = filter;
2✔
272
}
273

274
/*
275
* Pop a Filter off the Pipe
276
*/
277
void Pipe::pop() {
10✔
278
   if(m_inside_msg) {
10✔
279
      throw Invalid_State("Cannot pop off a Pipe while it is processing");
1✔
280
   }
281

282
   if(!m_pipe) {
9✔
283
      return;
284
   }
285

286
   if(m_pipe->total_ports() > 1) {
7✔
287
      throw Invalid_State("Cannot pop off a Filter with multiple ports");
×
288
   }
289

290
   size_t to_remove = m_pipe->owns() + 1;
7✔
291

292
   while(to_remove--) {
16✔
293
      std::unique_ptr<Filter> to_destroy(m_pipe);
9✔
294
      m_pipe = m_pipe->m_next[0];
9✔
295
   }
9✔
296
}
297

298
/*
299
* Return the number of messages in this Pipe
300
*/
301
Pipe::message_id Pipe::message_count() const {
243✔
302
   return m_outputs->message_count();
243✔
303
}
304

305
/*
306
* Static Member Variables
307
*/
308
const Pipe::message_id Pipe::LAST_MESSAGE = static_cast<Pipe::message_id>(-2);
309

310
const Pipe::message_id Pipe::DEFAULT_MESSAGE = static_cast<Pipe::message_id>(-1);
311

312
}  // 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