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>
23class Null_Filter
final :
public Filter {
25 void write(
const uint8_t input[],
size_t length)
override { send(input, length); }
27 std::string
name()
const override {
return "Null"; }
44 m_outputs = std::make_unique<Output_Buffers>();
49 for(
auto arg : args) {
73void Pipe::destruct(
Filter* to_kill) {
74 if(!to_kill ||
dynamic_cast<SecureQueue*
>(to_kill)) {
77 for(
size_t j = 0; j != to_kill->total_ports(); ++j) {
78 destruct(to_kill->m_next[j]);
105 write(input, length);
141 throw Invalid_State(
"Pipe::start_msg: Message was already started");
143 if(m_pipe ==
nullptr) {
144 m_pipe =
new Null_Filter;
146 find_endpoints(m_pipe);
156 throw Invalid_State(
"Pipe::end_msg: Message was already ended");
158 m_pipe->finish_msg();
159 clear_endpoints(m_pipe);
160 if(
dynamic_cast<Null_Filter*
>(m_pipe)) {
164 m_inside_msg =
false;
172void Pipe::find_endpoints(
Filter* f) {
173 for(
size_t j = 0; j != f->total_ports(); ++j) {
174 if(f->m_next[j] && !
dynamic_cast<SecureQueue*
>(f->m_next[j])) {
175 find_endpoints(f->m_next[j]);
177 SecureQueue* q =
new SecureQueue;
187void Pipe::clear_endpoints(Filter* f) {
191 for(
size_t j = 0; j != f->total_ports(); ++j) {
192 if(f->m_next[j] &&
dynamic_cast<SecureQueue*
>(f->m_next[j])) {
193 f->m_next[j] =
nullptr;
195 clear_endpoints(f->m_next[j]);
204 if(m_outputs->message_count() != 0) {
205 throw Invalid_State(
"Cannot call Pipe::append_filter after start_msg");
216 if(m_outputs->message_count() != 0) {
217 throw Invalid_State(
"Cannot call Pipe::prepend_filter after start_msg");
226void Pipe::do_append(
Filter* filter) {
230 if(
dynamic_cast<SecureQueue*
>(filter)) {
231 throw Invalid_Argument(
"Pipe::append: SecureQueue cannot be used");
233 if(filter->m_owned) {
234 throw Invalid_Argument(
"Filters cannot be shared among multiple Pipes");
238 throw Invalid_State(
"Cannot append to a Pipe while it is processing");
241 filter->m_owned =
true;
246 m_pipe->attach(filter);
253void Pipe::do_prepend(Filter* filter) {
255 throw Invalid_State(
"Cannot prepend to a Pipe while it is processing");
260 if(
dynamic_cast<SecureQueue*
>(filter)) {
261 throw Invalid_Argument(
"Pipe::prepend: SecureQueue cannot be used");
263 if(filter->m_owned) {
264 throw Invalid_Argument(
"Filters cannot be shared among multiple Pipes");
267 filter->m_owned =
true;
270 filter->attach(m_pipe);
280 throw Invalid_State(
"Cannot pop off a Pipe while it is processing");
287 if(m_pipe->total_ports() > 1) {
288 throw Invalid_State(
"Cannot pop off a Filter with multiple ports");
291 size_t to_remove = m_pipe->owns() + 1;
294 std::unique_ptr<Filter> to_destroy(m_pipe);
295 m_pipe = m_pipe->m_next[0];
303 return m_outputs->message_count();
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)
void write(const uint8_t in[], size_t length)
static const message_id DEFAULT_MESSAGE
Pipe(Filter *=nullptr, Filter *=nullptr, Filter *=nullptr, Filter *=nullptr)
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)
int(* final)(unsigned char *, CTX *)
std::string fmt(std::string_view format, const T &... args)
std::vector< T, secure_allocator< T > > secure_vector
const uint8_t * cast_char_ptr_to_uint8(const char *s)