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

randombit / botan / 15656488073

14 Jun 2025 04:56PM UTC coverage: 90.561% (-0.02%) from 90.585%
15656488073

push

github

web-flow
Merge pull request #4912 from randombit/jack/clang-tidy-headers-part-2

Further clang-tidy fixes in header files

98779 of 109074 relevant lines covered (90.56%)

12362398.38 hits per line

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

93.62
/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/mem_ops.h>
11
#include <botan/internal/fmt.h>
12
#include <botan/internal/out_buf.h>
13
#include <botan/internal/secqueue.h>
14
#include <memory>
15

16
namespace Botan {
17

18
namespace {
19

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

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

30
}  // namespace
31

32
Pipe::Pipe(Pipe&&) noexcept = default;
×
33

34
Pipe::Invalid_Message_Number::Invalid_Message_Number(std::string_view where, message_id msg) :
1✔
35
      Invalid_Argument(fmt("Pipe::{}: Invalid message number {}", where, msg)) {}
2✔
36

37
/*
38
* Pipe Constructor
39
*/
40
Pipe::Pipe(Filter* f1, Filter* f2, Filter* f3, Filter* f4) : Pipe({f1, f2, f3, f4}) {}
18✔
41

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

51
   for(auto arg : args) {
90✔
52
      do_append(arg);
72✔
53
   }
54
}
18✔
55

56
/*
57
* Pipe Destructor
58
*/
59
Pipe::~Pipe() {
18✔
60
   destruct(m_pipe);
18✔
61
}
18✔
62

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

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

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

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

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

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

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

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

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

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

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

168
   m_outputs->retire();
65✔
169
}
65✔
170

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

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

201
void Pipe::append(Filter* filter) {
19✔
202
   do_append(filter);
19✔
203
}
17✔
204

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

210
   do_append(filter);
2✔
211
}
2✔
212

213
void Pipe::prepend(Filter* filter) {
5✔
214
   do_prepend(filter);
5✔
215
}
3✔
216

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

222
   do_prepend(filter);
2✔
223
}
2✔
224

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

239
   if(m_inside_msg) {
40✔
240
      throw Invalid_State("Cannot append to a Pipe while it is processing");
1✔
241
   }
242

243
   filter->m_owned = true;
39✔
244

245
   if(!m_pipe) {
39✔
246
      m_pipe = filter;
25✔
247
   } else {
248
      m_pipe->attach(filter);
14✔
249
   }
250
}
251

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

269
   filter->m_owned = true;
2✔
270

271
   if(m_pipe) {
2✔
272
      filter->attach(m_pipe);
×
273
   }
274
   m_pipe = filter;
2✔
275
}
276

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

285
   if(!m_pipe) {
9✔
286
      return;
287
   }
288

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

293
   size_t to_remove = m_pipe->owns() + 1;
7✔
294

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

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

308
/*
309
* Static Member Variables
310
*/
311
const Pipe::message_id Pipe::LAST_MESSAGE = static_cast<Pipe::message_id>(-2);
312

313
const Pipe::message_id Pipe::DEFAULT_MESSAGE = static_cast<Pipe::message_id>(-1);
314

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