Botan  1.11.15
src/lib/filters/filter.cpp
Go to the documentation of this file.
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 }