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 #include <botan/exceptn.h> 10 11 namespace Botan { 12 13 /* 14 * Filter Constructor 15 */ Filter()16Filter::Filter() 17 { 18 m_next.resize(1); 19 m_port_num = 0; 20 m_filter_owns = 0; 21 m_owned = false; 22 } 23 24 /* 25 * Send data to all ports 26 */ send(const uint8_t input[],size_t length)27void Filter::send(const uint8_t input[], size_t length) 28 { 29 if(!length) 30 return; 31 32 bool nothing_attached = true; 33 for(size_t j = 0; j != total_ports(); ++j) 34 if(m_next[j]) 35 { 36 if(m_write_queue.size()) 37 m_next[j]->write(m_write_queue.data(), m_write_queue.size()); 38 m_next[j]->write(input, length); 39 nothing_attached = false; 40 } 41 42 if(nothing_attached) 43 m_write_queue += std::make_pair(input, length); 44 else 45 m_write_queue.clear(); 46 } 47 48 /* 49 * Start a new message 50 */ new_msg()51void Filter::new_msg() 52 { 53 start_msg(); 54 for(size_t j = 0; j != total_ports(); ++j) 55 if(m_next[j]) 56 m_next[j]->new_msg(); 57 } 58 59 /* 60 * End the current message 61 */ finish_msg()62void Filter::finish_msg() 63 { 64 end_msg(); 65 for(size_t j = 0; j != total_ports(); ++j) 66 if(m_next[j]) 67 m_next[j]->finish_msg(); 68 } 69 70 /* 71 * Attach a filter to the current port 72 */ attach(Filter * new_filter)73void Filter::attach(Filter* new_filter) 74 { 75 if(new_filter) 76 { 77 Filter* last = this; 78 while(last->get_next()) 79 last = last->get_next(); 80 last->m_next[last->current_port()] = new_filter; 81 } 82 } 83 84 /* 85 * Set the active port on a filter 86 */ set_port(size_t new_port)87void Filter::set_port(size_t new_port) 88 { 89 if(new_port >= total_ports()) 90 throw Invalid_Argument("Filter: Invalid port number"); 91 m_port_num = new_port; 92 } 93 94 /* 95 * Return the next Filter in the logical chain 96 */ get_next() const97Filter* Filter::get_next() const 98 { 99 if(m_port_num < m_next.size()) 100 return m_next[m_port_num]; 101 return nullptr; 102 } 103 104 /* 105 * Set the next Filters 106 */ set_next(Filter * filters[],size_t size)107void Filter::set_next(Filter* filters[], size_t size) 108 { 109 m_next.clear(); 110 111 m_port_num = 0; 112 m_filter_owns = 0; 113 114 while(size && filters && (filters[size-1] == nullptr)) 115 --size; 116 117 if(filters && size) 118 m_next.assign(filters, filters + size); 119 } 120 121 /* 122 * Return the total number of ports 123 */ total_ports() const124size_t Filter::total_ports() const 125 { 126 return m_next.size(); 127 } 128 129 } 130