- Main Page
- Namespaces
- Classes
- Files

# 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
    00092 //
    00093 // ChannelRouteIterator
    00094 //////////////////////////
    00095
    00096 void ChannelRouteIterator::Reset(const std::string &channel)
    00097 {
    00098         m_channel = channel;
    00099         pair<MapIterator, MapIterator> range = m_cs.m_routeMap.equal_range(channel);
    00100         if (range.first == range.second)
    00101         {
    00102                 m_useDefault = true;
    00103                 m_itListCurrent = m_cs.m_defaultRoutes.begin();
    00104                 m_itListEnd = m_cs.m_defaultRoutes.end();
    00105         }
    00106         else
    00107         {
    00108                 m_useDefault = false;
    00109                 m_itMapCurrent = range.first;
    00110                 m_itMapEnd = range.second;
    00111         }
    00112 }
    00113
    00114 bool ChannelRouteIterator::End() const
    00115 {
    00116         return m_useDefault ? m_itListCurrent == m_itListEnd : m_itMapCurrent == m_itMapEnd;
    00117 }
    00118
    00119 void ChannelRouteIterator::Next()
    00120 {
    00121         if (m_useDefault)
    00122                 ++m_itListCurrent;
    00123         else
    00124                 ++m_itMapCurrent;
    00125 }
    00126
    00127 BufferedTransformation & ChannelRouteIterator::Destination()
    00128 {
    00129         return m_useDefault ? *m_itListCurrent->first : *m_itMapCurrent->second.first;
    00130 }
    00131
    00132 const std::string & ChannelRouteIterator::Channel()
    00133 {
    00134         if (m_useDefault)
    00135                 return m_itListCurrent->second.get() ? *m_itListCurrent->second.get() : m_channel;
    00136         else
    00137                 return m_itMapCurrent->second.second;
    00138 }
    00139
    00140
    00141 //
    00142 // ChannelSwitch
    00143 ///////////////////
    00144
    00145 size_t ChannelSwitch::ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking)
    00146 {
    00147         if (m_blocked)
    00148         {
    00149                 m_blocked = false;
    00150                 goto WasBlocked;
    00151         }
    00152
    00153         m_it.Reset(channel);
    00154
    00155         while (!m_it.End())
    00156         {
    00157 WasBlocked:
    00158                 if (m_it.Destination().ChannelPut2(m_it.Channel(), begin, length, messageEnd, blocking))
    00159                 {
    00160                         m_blocked = true;
    00161                         return 1;
    00162                 }
    00163
    00164                 m_it.Next();
    00165         }
    00166
    00167         return 0;
    00168 }
    00169
    00170 void ChannelSwitch::IsolatedInitialize(const NameValuePairs &parameters/* =g_nullNameValuePairs */)
    00171 {
    00172         m_routeMap.clear();
    00173         m_defaultRoutes.clear();
    00174         m_blocked = false;
    00175 }
    00176
    00177 bool ChannelSwitch::ChannelFlush(const std::string &channel, bool completeFlush, int propagation, bool blocking)
    00178 {
    00179         if (m_blocked)
    00180         {
    00181                 m_blocked = false;
    00182                 goto WasBlocked;
    00183         }
    00184
    00185         m_it.Reset(channel);
    00186
    00187         while (!m_it.End())
    00188         {
    00189           WasBlocked:
    00190                 if (m_it.Destination().ChannelFlush(m_it.Channel(), completeFlush, propagation, blocking))
    00191                 {
    00192                         m_blocked = true;
    00193                         return true;
    00194                 }
    00195
    00196                 m_it.Next();
    00197         }
    00198
    00199         return false;
    00200 }
    00201
    00202 bool ChannelSwitch::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking)
    00203 {
    00204         if (m_blocked)
    00205         {
    00206                 m_blocked = false;
    00207                 goto WasBlocked;
    00208         }
    00209
    00210         m_it.Reset(channel);
    00211
    00212         while (!m_it.End())
    00213         {
    00214           WasBlocked:
    00215                 if (m_it.Destination().ChannelMessageSeriesEnd(m_it.Channel(), propagation))
    00216                 {
    00217                         m_blocked = true;
    00218                         return true;
    00219                 }
    00220
    00221                 m_it.Next();
    00222         }
    00223
    00224         return false;
    00225 }
    00226
    00227 byte * ChannelSwitch::ChannelCreatePutSpace(const std::string &channel, size_t &size)
    00228 {
    00229         m_it.Reset(channel);
    00230         if (!m_it.End())
    00231         {
    00232                 BufferedTransformation &target = m_it.Destination();
    00233                 const std::string &channel = m_it.Channel();
    00234                 m_it.Next();
    00235                 if (m_it.End()) // there is only one target channel
    00236                         return target.ChannelCreatePutSpace(channel, size);
    00237         }
    00238         size = 0;
    00239         return NULL;
    00240 }
    00241
    00242 size_t ChannelSwitch::ChannelPutModifiable2(const std::string &channel, byte *inString, size_t length, int messageEnd, bool blocking)
    00243 {
    00244         ChannelRouteIterator it(*this);
    00245         it.Reset(channel);
    00246
    00247         if (!it.End())
    00248         {
    00249                 BufferedTransformation &target = it.Destination();
    00250                 const std::string &targetChannel = it.Channel();
    00251                 it.Next();
    00252                 if (it.End())   // there is only one target channel
    00253                         return target.ChannelPutModifiable2(targetChannel, inString, length, messageEnd, blocking);
    00254         }
    00255
    00256         return ChannelPut2(channel, inString, length, messageEnd, blocking);
    00257 }
    00258
    00259 void ChannelSwitch::AddDefaultRoute(BufferedTransformation &destination)
    00260 {
    00261         m_defaultRoutes.push_back(DefaultRoute(&destination, value_ptr<std::string>(NULL)));
    00262 }
    00263
    00264 void ChannelSwitch::RemoveDefaultRoute(BufferedTransformation &destination)
    00265 {
    00266         for (DefaultRouteList::iterator it = m_defaultRoutes.begin(); it != m_defaultRoutes.end(); ++it)
    00267                 if (it->first == &destination && !it->second.get())
    00268                 {
    00269                         m_defaultRoutes.erase(it);
    00270                         break;
    00271                 }
    00272 }
    00273
    00274 void ChannelSwitch::AddDefaultRoute(BufferedTransformation &destination, const std::string &outChannel)
    00275 {
    00276         m_defaultRoutes.push_back(DefaultRoute(&destination, outChannel));
    00277 }
    00278
    00279 void ChannelSwitch::RemoveDefaultRoute(BufferedTransformation &destination, const std::string &outChannel)
    00280 {
    00281         for (DefaultRouteList::iterator it = m_defaultRoutes.begin(); it != m_defaultRoutes.end(); ++it)
    00282                 if (it->first == &destination && (it->second.get() && *it->second == outChannel))
    00283                 {
    00284                         m_defaultRoutes.erase(it);
    00285                         break;
    00286                 }
    00287 }
    00288
    00289 void ChannelSwitch::AddRoute(const std::string &inChannel, BufferedTransformation &destination, const std::string &outChannel)
    00290 {
    00291         m_routeMap.insert(RouteMap::value_type(inChannel, Route(&destination, outChannel)));
    00292 }
    00293
    00294 void ChannelSwitch::RemoveRoute(const std::string &inChannel, BufferedTransformation &destination, const std::string &outChannel)
    00295 {
    00296         typedef ChannelSwitch::RouteMap::iterator MapIterator;
    00297         pair<MapIterator, MapIterator> range = m_routeMap.equal_range(inChannel);
    00298
    00299         for (MapIterator it = range.first; it != range.second; ++it)
    00300                 if (it->second.first == &destination && it->second.second == outChannel)
    00301                 {
    00302                         m_routeMap.erase(it);
    00303                         break;
    00304                 }
    00305 }
    00306
    00307 NAMESPACE_END
    00308
    00309 #endif