Botan 3.13.0
Crypto and TLS for C&
filter.cpp
Go to the documentation of this file.
1/*
2* Filter
3* (C) 1999-2007 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/filter.h>
9
10#include <botan/assert.h>
11#include <botan/exceptn.h>
12
13namespace Botan {
14
15/*
16* Filter Constructor
17*/
19 m_next.resize(1);
20}
21
22void Filter::send(std::span<const uint8_t> in, size_t length) {
23 BOTAN_ASSERT_NOMSG(length <= in.size());
24 send(in.data(), length);
25}
26
27/*
28* Send data to all ports
29*/
30void Filter::send(const uint8_t input[], size_t length) {
31 if(length == 0) {
32 return;
33 }
34
35 bool nothing_attached = true;
36 for(size_t j = 0; j != total_ports(); ++j) {
37 if(m_next[j] != nullptr) {
38 if(!m_write_queue.empty()) {
39 m_next[j]->write(m_write_queue.data(), m_write_queue.size());
40 }
41 m_next[j]->write(input, length);
42 nothing_attached = false;
43 }
44 }
45
46 if(nothing_attached) {
47 m_write_queue += std::make_pair(input, length);
48 } else {
49 m_write_queue.clear();
50 }
51}
52
53/*
54* Start a new message
55*/
56void Filter::new_msg() {
57 start_msg();
58 for(size_t j = 0; j != total_ports(); ++j) {
59 if(m_next[j] != nullptr) {
60 m_next[j]->new_msg();
61 }
62 }
63}
64
65/*
66* End the current message
67*/
68void Filter::finish_msg() {
69 end_msg();
70 for(size_t j = 0; j != total_ports(); ++j) {
71 if(m_next[j] != nullptr) {
72 m_next[j]->finish_msg();
73 }
74 }
75}
76
77/*
78* Attach a filter to the current port
79*/
80void Filter::attach(Filter* new_filter) {
81 if(new_filter != nullptr) {
82 Filter* last = this;
83 while(last->get_next() != nullptr) {
84 last = last->get_next();
85 }
86 // A filter with no ports (e.g. Fork(nullptr, 0)) has an empty m_next, so
87 // indexing current_port() would be out of bounds. Such a filter has no
88 // free port to attach to.
89 if(last->current_port() < last->m_next.size()) {
90 last->m_next[last->current_port()] = new_filter;
91 } else {
92 throw Invalid_Argument("Filter::attach: cannot attach to a filter with no output port");
93 }
94 }
95}
96
97/*
98* Set the active port on a filter
99*/
100void Filter::set_port(size_t new_port) {
101 if(new_port >= total_ports()) {
102 throw Invalid_Argument("Filter: Invalid port number");
103 }
104 m_port_num = new_port;
105}
106
107/*
108* Return the next Filter in the logical chain
109*/
110Filter* Filter::get_next() const {
111 if(m_port_num < m_next.size()) {
112 return m_next[m_port_num];
113 }
114 return nullptr;
115}
116
117/*
118* Set the next Filters
119*/
120void Filter::set_next(Filter* filters[], size_t size) {
121 m_next.clear();
122
123 m_port_num = 0;
124 m_filter_owns = 0;
125
126 while(size > 0 && filters != nullptr && (filters[size - 1] == nullptr)) {
127 --size;
128 }
129
130 if(filters != nullptr && size > 0) {
131 m_next.assign(filters, filters + size);
132 }
133}
134
135/*
136* Return the total number of ports
137*/
138size_t Filter::total_ports() const {
139 return m_next.size();
140}
141
142} // namespace Botan
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
Filter(const Filter &)=delete
virtual void send(const uint8_t in[], size_t length)
Definition filter.cpp:30
virtual void end_msg()
Definition filter.h:47
virtual void start_msg()
Definition filter.h:41