Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

# channels.cpp

    00001 // channels.cpp - written and placed in the public domain by Wei Dai
    00002
    00003 #include "pch.h"
    00004
    00005 #ifndef CRYPTOPP_IMPORTS
    00006
    00007 #include "channels.h"
    00008
    00009 NAMESPACE_BEGIN(CryptoPP)
    00010 USING_NAMESPACE(std)
    00011
    00012 #if 0
    00013 void MessageSwitch::AddDefaultRoute(BufferedTransformation &destination, const std::string &channel)
    00014 {
    00015         m_defaultRoutes.push_back(Route(&destination, channel));
    00016 }
    00017
    00018 void MessageSwitch::AddRoute(unsigned int begin, unsigned int end, BufferedTransformation &destination, const std::string &channel)
    00019 {
    00020         RangeRoute route(begin, end, Route(&destination, channel));
    00021         RouteList::iterator it = upper_bound(m_routes.begin(), m_routes.end(), route);
    00022         m_routes.insert(it, route);
    00023 }
    00024
    00025 /*
    00026 class MessageRouteIterator
    00027 {
    00028 public:
    00029         typedef MessageSwitch::RouteList::const_iterator RouteIterator;
    00030         typedef MessageSwitch::DefaultRouteList::const_iterator DefaultIterator;
    00031
    00032         bool m_useDefault;
    00033         RouteIterator m_itRouteCurrent, m_itRouteEnd;
    00034         DefaultIterator m_itDefaultCurrent, m_itDefaultEnd;
    00035
    00036         MessageRouteIterator(MessageSwitch &ms, const std::string &channel)
    00037                 : m_channel(channel)
    00038         {
    00039                 pair<MapIterator, MapIterator> range = cs.m_routeMap.equal_range(channel);
    00040                 if (range.first == range.second)
    00041                 {
    00042                         m_useDefault = true;
    00043                         m_itListCurrent = cs.m_defaultRoutes.begin();
    00044                         m_itListEnd = cs.m_defaultRoutes.end();
    00045                 }
    00046                 else
    00047                 {
    00048                         m_useDefault = false;
    00049                         m_itMapCurrent = range.first;
    00050                         m_itMapEnd = range.second;
    00051                 }
    00052         }
    00053
    00054         bool End() const
    00055         {
    00056                 return m_useDefault ? m_itListCurrent == m_itListEnd : m_itMapCurrent == m_itMapEnd;
    00057         }
    00058
    00059         void Next()
    00060         {
    00061                 if (m_useDefault)
    00062                         ++m_itListCurrent;
    00063                 else
    00064                         ++m_itMapCurrent;
    00065         }
    00066
    00067         BufferedTransformation & Destination()
    00068         {
    00069                 return m_useDefault ? *m_itListCurrent->first : *m_itMapCurrent->second.first;
    00070         }
    00071
    00072         const std::string & Message()
    00073         {
    00074                 if (m_useDefault)
    00075                         return m_itListCurrent->second.get() ? *m_itListCurrent->second.get() : m_channel;
    00076                 else
    00077                         return m_itMapCurrent->second.second;
    00078         }
    00079 };
    00080
    00081 void MessageSwitch::Put(byte inByte);
    00082 void MessageSwitch::Put(const byte *inString, unsigned int length);
    00083
    00084 void MessageSwitch::Flush(bool completeFlush, int propagation=-1);
    00085 void MessageSwitch::MessageEnd(int propagation=-1);
    00086 void MessageSwitch::PutMessageEnd(const byte *inString, unsigned int length, int propagation=-1);
    00087 void MessageSwitch::MessageSeriesEnd(int propagation=-1);
    00088 */
    00089 #endif
    00090
    00091 class ChannelRouteIterator
    00092 {
    00093 public:
    00094         typedef ChannelSwitch::RouteMap::const_iterator MapIterator;
    00095         typedef ChannelSwitch::DefaultRouteList::const_iterator ListIterator;
    00096
    00097         const std::string m_channel;
    00098         bool m_useDefault;
    00099         MapIterator m_itMapCurrent, m_itMapEnd;
    00100         ListIterator m_itListCurrent, m_itListEnd;
    00101
    00102         ChannelRouteIterator(ChannelSwitch &cs, const std::string &channel)
    00103                 : m_channel(channel)
    00104         {
    00105                 pair<MapIterator, MapIterator> range = cs.m_routeMap.equal_range(channel);
    00106                 if (range.first == range.second)
    00107                 {
    00108                         m_useDefault = true;
    00109                         m_itListCurrent = cs.m_defaultRoutes.begin();
    00110                         m_itListEnd = cs.m_defaultRoutes.end();
    00111                 }
    00112                 else
    00113                 {
    00114                         m_useDefault = false;
    00115                         m_itMapCurrent = range.first;
    00116                         m_itMapEnd = range.second;
    00117                 }
    00118         }
    00119
    00120         bool End() const
    00121         {
    00122                 return m_useDefault ? m_itListCurrent == m_itListEnd : m_itMapCurrent == m_itMapEnd;
    00123         }
    00124
    00125         void Next()
    00126         {
    00127                 if (m_useDefault)
    00128                         ++m_itListCurrent;
    00129                 else
    00130                         ++m_itMapCurrent;
    00131         }
    00132
    00133         BufferedTransformation & Destination()
    00134         {
    00135                 return m_useDefault ? *m_itListCurrent->first : *m_itMapCurrent->second.first;
    00136         }
    00137
    00138         const std::string & Channel()
    00139         {
    00140                 if (m_useDefault)
    00141                         return m_itListCurrent->second.get() ? *m_itListCurrent->second.get() : m_channel;
    00142                 else
    00143                         return m_itMapCurrent->second.second;
    00144         }
    00145 };
    00146
    00147 unsigned int ChannelSwitch::ChannelPut2(const std::string &channel, const byte *begin, unsigned int length, int messageEnd, bool blocking)
    00148 {
    00149         if (!blocking)
    00150                 throw BlockingInputOnly("ChannelSwitch");
    00151
    00152         ChannelRouteIterator it(*this, channel);
    00153         while (!it.End())
    00154         {
    00155                 it.Destination().ChannelPut2(it.Channel(), begin, length, messageEnd, blocking);
    00156                 it.Next();
    00157         }
    00158         return 0;
    00159 }
    00160
    00161 void ChannelSwitch::ChannelInitialize(const std::string &channel, const NameValuePairs &parameters/* =g_nullNameValuePairs */, int propagation/* =-1 */)
    00162 {
    00163         if (channel.empty())
    00164         {
    00165                 m_routeMap.clear();
    00166                 m_defaultRoutes.clear();
    00167         }
    00168
    00169         ChannelRouteIterator it(*this, channel);
    00170         while (!it.End())
    00171         {
    00172                 it.Destination().ChannelInitialize(it.Channel(), parameters, propagation);
    00173                 it.Next();
    00174         }
    00175 }
    00176
    00177 bool ChannelSwitch::ChannelFlush(const std::string &channel, bool completeFlush, int propagation, bool blocking)
    00178 {
    00179         if (!blocking)
    00180                 throw BlockingInputOnly("ChannelSwitch");
    00181
    00182         ChannelRouteIterator it(*this, channel);
    00183         while (!it.End())
    00184         {
    00185                 it.Destination().ChannelFlush(it.Channel(), completeFlush, propagation, blocking);
    00186                 it.Next();
    00187         }
    00188         return false;
    00189 }
    00190
    00191 bool ChannelSwitch::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking)
    00192 {
    00193         if (!blocking)
    00194                 throw BlockingInputOnly("ChannelSwitch");
    00195
    00196         ChannelRouteIterator it(*this, channel);
    00197         while (!it.End())
    00198         {
    00199                 it.Destination().ChannelMessageSeriesEnd(it.Channel(), propagation);
    00200                 it.Next();
    00201         }
    00202         return false;
    00203 }
    00204
    00205 byte * ChannelSwitch::ChannelCreatePutSpace(const std::string &channel, unsigned int &size)
    00206 {
    00207         ChannelRouteIterator it(*this, channel);
    00208         if (!it.End())
    00209         {
    00210                 BufferedTransformation &target = it.Destination();
    00211                 it.Next();
    00212                 if (it.End())   // there is only one target channel
    00213                         return target.ChannelCreatePutSpace(it.Channel(), size);
    00214         }
    00215         size = 0;
    00216         return NULL;
    00217 }
    00218
    00219 unsigned int ChannelSwitch::ChannelPutModifiable2(const std::string &channel, byte *inString, unsigned int length, int messageEnd, bool blocking)
    00220 {
    00221         if (!blocking)
    00222                 throw BlockingInputOnly("ChannelSwitch");
    00223
    00224         ChannelRouteIterator it(*this, channel);
    00225         if (!it.End())
    00226         {
    00227                 BufferedTransformation &target = it.Destination();
    00228                 const std::string &targetChannel = it.Channel();
    00229                 it.Next();
    00230                 if (it.End())   // there is only one target channel
    00231                         return target.ChannelPutModifiable2(targetChannel, inString, length, messageEnd, blocking);
    00232         }
    00233         ChannelPut2(channel, inString, length, messageEnd, blocking);
    00234         return false;
    00235 }
    00236
    00237 void ChannelSwitch::AddDefaultRoute(BufferedTransformation &destination)
    00238 {
    00239         m_defaultRoutes.push_back(DefaultRoute(&destination, value_ptr<std::string>(NULL)));
    00240 }
    00241
    00242 void ChannelSwitch::RemoveDefaultRoute(BufferedTransformation &destination)
    00243 {
    00244         for (DefaultRouteList::iterator it = m_defaultRoutes.begin(); it != m_defaultRoutes.end(); ++it)
    00245                 if (it->first == &destination && !it->second.get())
    00246                 {
    00247                         m_defaultRoutes.erase(it);
    00248                         break;
    00249                 }
    00250 }
    00251
    00252 void ChannelSwitch::AddDefaultRoute(BufferedTransformation &destination, const std::string &outChannel)
    00253 {
    00254         m_defaultRoutes.push_back(DefaultRoute(&destination, outChannel));
    00255 }
    00256
    00257 void ChannelSwitch::RemoveDefaultRoute(BufferedTransformation &destination, const std::string &outChannel)
    00258 {
    00259         for (DefaultRouteList::iterator it = m_defaultRoutes.begin(); it != m_defaultRoutes.end(); ++it)
    00260                 if (it->first == &destination && (it->second.get() && *it->second == outChannel))
    00261                 {
    00262                         m_defaultRoutes.erase(it);
    00263                         break;
    00264                 }
    00265 }
    00266
    00267 void ChannelSwitch::AddRoute(const std::string &inChannel, BufferedTransformation &destination, const std::string &outChannel)
    00268 {
    00269         m_routeMap.insert(RouteMap::value_type(inChannel, Route(&destination, outChannel)));
    00270 }
    00271
    00272 void ChannelSwitch::RemoveRoute(const std::string &inChannel, BufferedTransformation &destination, const std::string &outChannel)
    00273 {
    00274         typedef ChannelSwitch::RouteMap::iterator MapIterator;
    00275         pair<MapIterator, MapIterator> range = m_routeMap.equal_range(inChannel);
    00276
    00277         for (MapIterator it = range.first; it != range.second; ++it)
    00278                 if (it->second.first == &destination && it->second.second == outChannel)
    00279                 {
    00280                         m_routeMap.erase(it);
    00281                         break;
    00282                 }
    00283 }
    00284
    00285 NAMESPACE_END
    00286
    00287 #endif