Botan
1.11.15
|
00001 /* 00002 * Filter 00003 * (C) 1999-2007 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #include <botan/filter.h> 00009 #include <botan/secqueue.h> 00010 #include <botan/exceptn.h> 00011 00012 namespace Botan { 00013 00014 /* 00015 * Filter Constructor 00016 */ 00017 Filter::Filter() 00018 { 00019 next.resize(1); 00020 port_num = 0; 00021 filter_owns = 0; 00022 owned = false; 00023 } 00024 00025 /* 00026 * Send data to all ports 00027 */ 00028 void Filter::send(const byte input[], size_t length) 00029 { 00030 if(!length) 00031 return; 00032 00033 bool nothing_attached = true; 00034 for(size_t j = 0; j != total_ports(); ++j) 00035 if(next[j]) 00036 { 00037 if(write_queue.size()) 00038 next[j]->write(&write_queue[0], write_queue.size()); 00039 next[j]->write(input, length); 00040 nothing_attached = false; 00041 } 00042 00043 if(nothing_attached) 00044 write_queue += std::make_pair(input, length); 00045 else 00046 write_queue.clear(); 00047 } 00048 00049 /* 00050 * Start a new message 00051 */ 00052 void Filter::new_msg() 00053 { 00054 start_msg(); 00055 for(size_t j = 0; j != total_ports(); ++j) 00056 if(next[j]) 00057 next[j]->new_msg(); 00058 } 00059 00060 /* 00061 * End the current message 00062 */ 00063 void Filter::finish_msg() 00064 { 00065 end_msg(); 00066 for(size_t j = 0; j != total_ports(); ++j) 00067 if(next[j]) 00068 next[j]->finish_msg(); 00069 } 00070 00071 /* 00072 * Attach a filter to the current port 00073 */ 00074 void Filter::attach(Filter* new_filter) 00075 { 00076 if(new_filter) 00077 { 00078 Filter* last = this; 00079 while(last->get_next()) 00080 last = last->get_next(); 00081 last->next[last->current_port()] = new_filter; 00082 } 00083 } 00084 00085 /* 00086 * Set the active port on a filter 00087 */ 00088 void Filter::set_port(size_t new_port) 00089 { 00090 if(new_port >= total_ports()) 00091 throw Invalid_Argument("Filter: Invalid port number"); 00092 port_num = new_port; 00093 } 00094 00095 /* 00096 * Return the next Filter in the logical chain 00097 */ 00098 Filter* Filter::get_next() const 00099 { 00100 if(port_num < next.size()) 00101 return next[port_num]; 00102 return nullptr; 00103 } 00104 00105 /* 00106 * Set the next Filters 00107 */ 00108 void Filter::set_next(Filter* filters[], size_t size) 00109 { 00110 next.clear(); 00111 00112 port_num = 0; 00113 filter_owns = 0; 00114 00115 while(size && filters && (filters[size-1] == nullptr)) 00116 --size; 00117 00118 if(filters && size) 00119 next.assign(filters, filters + size); 00120 } 00121 00122 /* 00123 * Return the total number of ports 00124 */ 00125 size_t Filter::total_ports() const 00126 { 00127 return next.size(); 00128 } 00129 00130 }