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

randombit / botan / 19012754211

02 Nov 2025 01:10PM UTC coverage: 90.677% (+0.006%) from 90.671%
19012754211

push

github

web-flow
Merge pull request #5137 from randombit/jack/clang-tidy-includes

Remove various unused includes flagged by clang-tidy misc-include-cleaner

100457 of 110786 relevant lines covered (90.68%)

12189873.8 hits per line

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

93.71
/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/mem_utils.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) : m_pipe(nullptr), m_default_read(0), m_inside_msg(false) {
18✔
46
   m_outputs = std::make_unique<Output_Buffers>();
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 == nullptr) {
80✔
74
      return;
75
   }
76

77
   if(dynamic_cast<SecureQueue*>(to_kill) != nullptr) {
49✔
78
      return;
79
   }
80

81
   for(size_t j = 0; j != to_kill->total_ports(); ++j) {
105✔
82
      destruct(to_kill->m_next[j]);
56✔
83
   }
84
   delete to_kill;  // NOLINT(*owning-memory)
49✔
85
}
86

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

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

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

113
void Pipe::process_msg(std::span<const uint8_t> input) {
39✔
114
   this->process_msg(input.data(), input.size());
39✔
115
}
39✔
116

117
/*
118
* Process a full message at once
119
*/
120
void Pipe::process_msg(const secure_vector<uint8_t>& input) {
2✔
121
   this->process_msg(std::span{input});
2✔
122
}
2✔
123

124
void Pipe::process_msg(const std::vector<uint8_t>& input) {
1✔
125
   this->process_msg(std::span{input});
1✔
126
}
1✔
127

128
/*
129
* Process a full message at once
130
*/
131
void Pipe::process_msg(std::string_view input) {
36✔
132
   process_msg(as_span_of_bytes(input));
36✔
133
}
36✔
134

135
/*
136
* Process a full message at once
137
*/
138
void Pipe::process_msg(DataSource& input) {
4✔
139
   start_msg();
4✔
140
   write(input);
4✔
141
   end_msg();
4✔
142
}
4✔
143

144
/*
145
* Start a new message
146
*/
147
void Pipe::start_msg() {
65✔
148
   if(m_inside_msg) {
65✔
149
      throw Invalid_State("Pipe::start_msg: Message was already started");
×
150
   }
151
   if(m_pipe == nullptr) {
65✔
152
      m_pipe = new Null_Filter;  // NOLINT(*-owning-memory)
2✔
153
   }
154
   find_endpoints(m_pipe);
65✔
155
   m_pipe->new_msg();
65✔
156
   m_inside_msg = true;
65✔
157
}
65✔
158

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

174
   m_outputs->retire();
65✔
175
}
65✔
176

177
/*
178
* Find the endpoints of the Pipe
179
*/
180
void Pipe::find_endpoints(Filter* f) {
135✔
181
   for(size_t j = 0; j != f->total_ports(); ++j) {
277✔
182
      if(f->m_next[j] != nullptr && dynamic_cast<SecureQueue*>(f->m_next[j]) == nullptr) {
142✔
183
         find_endpoints(f->m_next[j]);
70✔
184
      } else {
185
         SecureQueue* q = new SecureQueue;  // NOLINT(*-owning-memory)
72✔
186
         f->m_next[j] = q;
72✔
187
         m_outputs->add(q);
72✔
188
      }
189
   }
190
}
135✔
191

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

207
void Pipe::append(Filter* filter) {
19✔
208
   do_append(filter);
19✔
209
}
17✔
210

211
void Pipe::append_filter(Filter* filter) {
4✔
212
   if(m_outputs->message_count() != 0) {
4✔
213
      throw Invalid_State("Cannot call Pipe::append_filter after start_msg");
2✔
214
   }
215

216
   do_append(filter);
2✔
217
}
2✔
218

219
void Pipe::prepend(Filter* filter) {
5✔
220
   do_prepend(filter);
5✔
221
}
3✔
222

223
void Pipe::prepend_filter(Filter* filter) {
4✔
224
   if(m_outputs->message_count() != 0) {
4✔
225
      throw Invalid_State("Cannot call Pipe::prepend_filter after start_msg");
2✔
226
   }
227

228
   do_prepend(filter);
2✔
229
}
2✔
230

231
/*
232
* Append a Filter to the Pipe
233
*/
234
void Pipe::do_append(Filter* filter) {
93✔
235
   if(filter == nullptr) {
93✔
236
      return;
237
   }
238
   if(dynamic_cast<SecureQueue*>(filter) != nullptr) {
41✔
239
      throw Invalid_Argument("Pipe::append: SecureQueue cannot be used");
1✔
240
   }
241
   if(filter->m_owned) {
40✔
242
      throw Invalid_Argument("Filters cannot be shared among multiple Pipes");
×
243
   }
244

245
   if(m_inside_msg) {
40✔
246
      throw Invalid_State("Cannot append to a Pipe while it is processing");
1✔
247
   }
248

249
   filter->m_owned = true;
39✔
250

251
   if(m_pipe == nullptr) {
39✔
252
      m_pipe = filter;
25✔
253
   } else {
254
      m_pipe->attach(filter);
14✔
255
   }
256
}
257

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

275
   filter->m_owned = true;
2✔
276

277
   if(m_pipe != nullptr) {
2✔
278
      filter->attach(m_pipe);
×
279
   }
280
   m_pipe = filter;
2✔
281
}
282

283
/*
284
* Pop a Filter off the Pipe
285
*/
286
void Pipe::pop() {
10✔
287
   if(m_inside_msg) {
10✔
288
      throw Invalid_State("Cannot pop off a Pipe while it is processing");
1✔
289
   }
290

291
   if(m_pipe == nullptr) {
9✔
292
      return;
293
   }
294

295
   if(m_pipe->total_ports() > 1) {
7✔
296
      throw Invalid_State("Cannot pop off a Filter with multiple ports");
×
297
   }
298

299
   size_t to_remove = m_pipe->owns() + 1;
7✔
300

301
   while(to_remove > 0) {
16✔
302
      std::unique_ptr<Filter> to_destroy(m_pipe);
9✔
303
      m_pipe = m_pipe->m_next[0];
9✔
304
      to_remove -= 1;
9✔
305
   }
9✔
306
}
307

308
/*
309
* Return the number of messages in this Pipe
310
*/
311
Pipe::message_id Pipe::message_count() const {
243✔
312
   return m_outputs->message_count();
243✔
313
}
314

315
/*
316
* Static Member Variables
317
*/
318
const Pipe::message_id Pipe::LAST_MESSAGE = static_cast<Pipe::message_id>(-2);
319

320
const Pipe::message_id Pipe::DEFAULT_MESSAGE = static_cast<Pipe::message_id>(-1);
321

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