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

randombit / botan / 5079590438

25 May 2023 12:28PM UTC coverage: 92.228% (+0.5%) from 91.723%
5079590438

Pull #3502

github

Pull Request #3502: Apply clang-format to the codebase

75589 of 81959 relevant lines covered (92.23%)

12139530.51 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
}
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
}
18✔
51

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

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

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

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

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

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

100
/*
101
* Process a full message at once
102
*/
103
void Pipe::process_msg(const secure_vector<uint8_t>& input) { process_msg(input.data(), input.size()); }
2✔
104

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

107
/*
108
* Process a full message at once
109
*/
110
void Pipe::process_msg(std::string_view input) { process_msg(cast_char_ptr_to_uint8(input.data()), input.length()); }
36✔
111

112
/*
113
* Process a full message at once
114
*/
115
void Pipe::process_msg(DataSource& input) {
4✔
116
   start_msg();
4✔
117
   write(input);
4✔
118
   end_msg();
4✔
119
}
4✔
120

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

134
/*
135
* End the current message
136
*/
137
void Pipe::end_msg() {
65✔
138
   if(!m_inside_msg)
65✔
139
      throw Invalid_State("Pipe::end_msg: Message was already ended");
×
140
   m_pipe->finish_msg();
65✔
141
   clear_endpoints(m_pipe);
65✔
142
   if(dynamic_cast<Null_Filter*>(m_pipe)) {
65✔
143
      delete m_pipe;
2✔
144
      m_pipe = nullptr;
2✔
145
   }
146
   m_inside_msg = false;
65✔
147

148
   m_outputs->retire();
65✔
149
}
65✔
150

151
/*
152
* Find the endpoints of the Pipe
153
*/
154
void Pipe::find_endpoints(Filter* f) {
135✔
155
   for(size_t j = 0; j != f->total_ports(); ++j)
277✔
156
      if(f->m_next[j] && !dynamic_cast<SecureQueue*>(f->m_next[j]))
142✔
157
         find_endpoints(f->m_next[j]);
70✔
158
      else {
159
         SecureQueue* q = new SecureQueue;
72✔
160
         f->m_next[j] = q;
72✔
161
         m_outputs->add(q);
72✔
162
      }
163
}
135✔
164

165
/*
166
* Remove the SecureQueues attached to the Filter
167
*/
168
void Pipe::clear_endpoints(Filter* f) {
207✔
169
   if(!f)
207✔
170
      return;
171
   for(size_t j = 0; j != f->total_ports(); ++j) {
277✔
172
      if(f->m_next[j] && dynamic_cast<SecureQueue*>(f->m_next[j]))
142✔
173
         f->m_next[j] = nullptr;
72✔
174
      clear_endpoints(f->m_next[j]);
142✔
175
   }
176
}
177

178
void Pipe::append(Filter* filter) { do_append(filter); }
19✔
179

180
void Pipe::append_filter(Filter* filter) {
4✔
181
   if(m_outputs->message_count() != 0)
4✔
182
      throw Invalid_State("Cannot call Pipe::append_filter after start_msg");
2✔
183

184
   do_append(filter);
2✔
185
}
2✔
186

187
void Pipe::prepend(Filter* filter) { do_prepend(filter); }
5✔
188

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

193
   do_prepend(filter);
2✔
194
}
2✔
195

196
/*
197
* Append a Filter to the Pipe
198
*/
199
void Pipe::do_append(Filter* filter) {
93✔
200
   if(!filter)
93✔
201
      return;
202
   if(dynamic_cast<SecureQueue*>(filter))
41✔
203
      throw Invalid_Argument("Pipe::append: SecureQueue cannot be used");
1✔
204
   if(filter->m_owned)
40✔
205
      throw Invalid_Argument("Filters cannot be shared among multiple Pipes");
×
206

207
   if(m_inside_msg)
40✔
208
      throw Invalid_State("Cannot append to a Pipe while it is processing");
1✔
209

210
   filter->m_owned = true;
39✔
211

212
   if(!m_pipe)
39✔
213
      m_pipe = filter;
25✔
214
   else
215
      m_pipe->attach(filter);
14✔
216
}
217

218
/*
219
* Prepend a Filter to the Pipe
220
*/
221
void Pipe::do_prepend(Filter* filter) {
7✔
222
   if(m_inside_msg)
7✔
223
      throw Invalid_State("Cannot prepend to a Pipe while it is processing");
1✔
224
   if(!filter)
6✔
225
      return;
226
   if(dynamic_cast<SecureQueue*>(filter))
3✔
227
      throw Invalid_Argument("Pipe::prepend: SecureQueue cannot be used");
1✔
228
   if(filter->m_owned)
2✔
229
      throw Invalid_Argument("Filters cannot be shared among multiple Pipes");
×
230

231
   filter->m_owned = true;
2✔
232

233
   if(m_pipe)
2✔
234
      filter->attach(m_pipe);
×
235
   m_pipe = filter;
2✔
236
}
237

238
/*
239
* Pop a Filter off the Pipe
240
*/
241
void Pipe::pop() {
10✔
242
   if(m_inside_msg)
10✔
243
      throw Invalid_State("Cannot pop off a Pipe while it is processing");
1✔
244

245
   if(!m_pipe)
9✔
246
      return;
247

248
   if(m_pipe->total_ports() > 1)
7✔
249
      throw Invalid_State("Cannot pop off a Filter with multiple ports");
×
250

251
   size_t to_remove = m_pipe->owns() + 1;
7✔
252

253
   while(to_remove--) {
16✔
254
      std::unique_ptr<Filter> to_destroy(m_pipe);
9✔
255
      m_pipe = m_pipe->m_next[0];
9✔
256
   }
9✔
257
}
258

259
/*
260
* Return the number of messages in this Pipe
261
*/
262
Pipe::message_id Pipe::message_count() const { return m_outputs->message_count(); }
243✔
263

264
/*
265
* Static Member Variables
266
*/
267
const Pipe::message_id Pipe::LAST_MESSAGE = static_cast<Pipe::message_id>(-2);
268

269
const Pipe::message_id Pipe::DEFAULT_MESSAGE = static_cast<Pipe::message_id>(-1);
270

271
}
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