10#include <botan/mem_ops.h>
11#include <botan/internal/fmt.h>
12#include <botan/internal/mem_utils.h>
13#include <botan/internal/out_buf.h>
14#include <botan/internal/secqueue.h>
24class Null_Filter final :
public Filter {
26 void write(
const uint8_t input[],
size_t length)
override { send(input, length); }
28 std::string name()
const override {
return "Null"; }
46Pipe::Pipe(std::initializer_list<Filter*> args) : m_pipe(nullptr), m_default_read(0), m_inside_msg(false) {
47 m_outputs = std::make_unique<Output_Buffers>();
49 for(
auto* arg : args) {
73void Pipe::destruct(
Filter* to_kill) {
74 if(to_kill ==
nullptr) {
78 if(
dynamic_cast<SecureQueue*
>(to_kill) !=
nullptr) {
82 for(
size_t j = 0; j != to_kill->total_ports(); ++j) {
83 destruct(to_kill->m_next[j]);
102 m_default_read = msg;
110 write(input, length);
150 throw Invalid_State(
"Pipe::start_msg: Message was already started");
152 if(m_pipe ==
nullptr) {
153 m_pipe =
new Null_Filter;
155 find_endpoints(m_pipe);
165 throw Invalid_State(
"Pipe::end_msg: Message was already ended");
167 m_pipe->finish_msg();
168 clear_endpoints(m_pipe);
169 if(
dynamic_cast<Null_Filter*
>(m_pipe) !=
nullptr) {
173 m_inside_msg =
false;
181void Pipe::find_endpoints(
Filter* f) {
182 for(
size_t j = 0; j != f->total_ports(); ++j) {
183 if(f->m_next[j] !=
nullptr &&
dynamic_cast<SecureQueue*
>(f->m_next[j]) ==
nullptr) {
184 find_endpoints(f->m_next[j]);
186 SecureQueue* q =
new SecureQueue;
196void Pipe::clear_endpoints(
Filter* f) {
200 for(
size_t j = 0; j != f->total_ports(); ++j) {
201 if(f->m_next[j] !=
nullptr &&
dynamic_cast<SecureQueue*
>(f->m_next[j]) !=
nullptr) {
202 f->m_next[j] =
nullptr;
204 clear_endpoints(f->m_next[j]);
213 if(m_outputs->message_count() != 0) {
214 throw Invalid_State(
"Cannot call Pipe::append_filter after start_msg");
225 if(m_outputs->message_count() != 0) {
226 throw Invalid_State(
"Cannot call Pipe::prepend_filter after start_msg");
235void Pipe::do_append(
Filter* filter) {
236 if(filter ==
nullptr) {
239 if(
dynamic_cast<SecureQueue*
>(filter) !=
nullptr) {
240 throw Invalid_Argument(
"Pipe::append: SecureQueue cannot be used");
242 if(filter->m_owned) {
243 throw Invalid_Argument(
"Filters cannot be shared among multiple Pipes");
247 throw Invalid_State(
"Cannot append to a Pipe while it is processing");
250 filter->m_owned =
true;
252 if(m_pipe ==
nullptr) {
255 m_pipe->attach(filter);
262void Pipe::do_prepend(
Filter* filter) {
264 throw Invalid_State(
"Cannot prepend to a Pipe while it is processing");
266 if(filter ==
nullptr) {
269 if(
dynamic_cast<SecureQueue*
>(filter) !=
nullptr) {
270 throw Invalid_Argument(
"Pipe::prepend: SecureQueue cannot be used");
272 if(filter->m_owned) {
273 throw Invalid_Argument(
"Filters cannot be shared among multiple Pipes");
276 filter->m_owned =
true;
278 if(m_pipe !=
nullptr) {
279 filter->attach(m_pipe);
289 throw Invalid_State(
"Cannot pop off a Pipe while it is processing");
292 if(m_pipe ==
nullptr) {
296 if(m_pipe->total_ports() > 1) {
297 throw Invalid_State(
"Cannot pop off a Filter with multiple ports");
300 size_t to_remove = m_pipe->owns() + 1;
302 while(to_remove > 0) {
303 std::unique_ptr<Filter> to_destroy(m_pipe);
304 m_pipe = m_pipe->m_next[0];
313 return m_outputs->message_count();
Invalid_Argument(std::string_view msg)
Invalid_Message_Number(std::string_view where, message_id msg)
static const message_id LAST_MESSAGE
void process_msg(const uint8_t in[], size_t length)
BOTAN_FUTURE_EXPLICIT Pipe(Filter *f1=nullptr, Filter *f2=nullptr, Filter *f3=nullptr, Filter *f4=nullptr)
void write(const uint8_t in[], size_t length)
static const message_id DEFAULT_MESSAGE
size_t remaining(message_id msg=DEFAULT_MESSAGE) const
void prepend_filter(Filter *filt)
void append(Filter *filt)
void append_filter(Filter *filt)
message_id message_count() const
void prepend(Filter *filt)
bool end_of_data() const override
void set_default_msg(message_id msg)
std::span< const uint8_t > as_span_of_bytes(const char *s, size_t len)
std::string fmt(std::string_view format, const T &... args)
std::vector< T, secure_allocator< T > > secure_vector