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

randombit / botan / 16099930912

06 Jul 2025 02:16PM UTC coverage: 90.574% (+0.001%) from 90.573%
16099930912

push

github

web-flow
Merge pull request #4961 from randombit/jack/fix-clang-tidy-readability-implicit-bool-conversion

Fix some clang-tidy readability-implicit-bool-conversion warnings

99052 of 109360 relevant lines covered (90.57%)

12406513.44 hits per line

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

93.66
/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 == nullptr) {
80✔
77
      return;
78
   }
79

80
   if(dynamic_cast<SecureQueue*>(to_kill) != nullptr) {
49✔
81
      return;
82
   }
83

84
   for(size_t j = 0; j != to_kill->total_ports(); ++j) {
105✔
85
      destruct(to_kill->m_next[j]);
56✔
86
   }
87
   delete to_kill;
49✔
88
}
89

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

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

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

116
/*
117
* Process a full message at once
118
*/
119
void Pipe::process_msg(const secure_vector<uint8_t>& input) {
2✔
120
   process_msg(input.data(), input.size());
2✔
121
}
2✔
122

123
void Pipe::process_msg(const std::vector<uint8_t>& input) {
1✔
124
   process_msg(input.data(), input.size());
1✔
125
}
1✔
126

127
/*
128
* Process a full message at once
129
*/
130
void Pipe::process_msg(std::string_view input) {
36✔
131
   process_msg(cast_char_ptr_to_uint8(input.data()), input.length());
36✔
132
}
36✔
133

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

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

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

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

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

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

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

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

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

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

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

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

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

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

248
   filter->m_owned = true;
39✔
249

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

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

274
   filter->m_owned = true;
2✔
275

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

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

290
   if(!m_pipe) {
9✔
291
      return;
292
   }
293

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

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

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

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

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

318
const Pipe::message_id Pipe::DEFAULT_MESSAGE = static_cast<Pipe::message_id>(-1);
319

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