1// channels.cpp - written and placed in the public domain by Wei Dai 2 3#include "pch.h" 4 5#ifndef CRYPTOPP_IMPORTS 6 7#include "channels.h" 8 9NAMESPACE_BEGIN(CryptoPP) 10USING_NAMESPACE(std) 11 12#if 0 13void MessageSwitch::AddDefaultRoute(BufferedTransformation &destination, const std::string &channel) 14{ 15 m_defaultRoutes.push_back(Route(&destination, channel)); 16} 17 18void MessageSwitch::AddRoute(unsigned int begin, unsigned int end, BufferedTransformation &destination, const std::string &channel) 19{ 20 RangeRoute route(begin, end, Route(&destination, channel)); 21 RouteList::iterator it = upper_bound(m_routes.begin(), m_routes.end(), route); 22 m_routes.insert(it, route); 23} 24 25/* 26class MessageRouteIterator 27{ 28public: 29 typedef MessageSwitch::RouteList::const_iterator RouteIterator; 30 typedef MessageSwitch::DefaultRouteList::const_iterator DefaultIterator; 31 32 bool m_useDefault; 33 RouteIterator m_itRouteCurrent, m_itRouteEnd; 34 DefaultIterator m_itDefaultCurrent, m_itDefaultEnd; 35 36 MessageRouteIterator(MessageSwitch &ms, const std::string &channel) 37 : m_channel(channel) 38 { 39 pair<MapIterator, MapIterator> range = cs.m_routeMap.equal_range(channel); 40 if (range.first == range.second) 41 { 42 m_useDefault = true; 43 m_itListCurrent = cs.m_defaultRoutes.begin(); 44 m_itListEnd = cs.m_defaultRoutes.end(); 45 } 46 else 47 { 48 m_useDefault = false; 49 m_itMapCurrent = range.first; 50 m_itMapEnd = range.second; 51 } 52 } 53 54 bool End() const 55 { 56 return m_useDefault ? m_itListCurrent == m_itListEnd : m_itMapCurrent == m_itMapEnd; 57 } 58 59 void Next() 60 { 61 if (m_useDefault) 62 ++m_itListCurrent; 63 else 64 ++m_itMapCurrent; 65 } 66 67 BufferedTransformation & Destination() 68 { 69 return m_useDefault ? *m_itListCurrent->first : *m_itMapCurrent->second.first; 70 } 71 72 const std::string & Message() 73 { 74 if (m_useDefault) 75 return m_itListCurrent->second.get() ? *m_itListCurrent->second.get() : m_channel; 76 else 77 return m_itMapCurrent->second.second; 78 } 79}; 80 81void MessageSwitch::Put(byte inByte); 82void MessageSwitch::Put(const byte *inString, unsigned int length); 83 84void MessageSwitch::Flush(bool completeFlush, int propagation=-1); 85void MessageSwitch::MessageEnd(int propagation=-1); 86void MessageSwitch::PutMessageEnd(const byte *inString, unsigned int length, int propagation=-1); 87void MessageSwitch::MessageSeriesEnd(int propagation=-1); 88*/ 89#endif 90 91 92// 93// ChannelRouteIterator 94////////////////////////// 95 96void ChannelRouteIterator::Reset(const std::string &channel) 97{ 98 m_channel = channel; 99 pair<MapIterator, MapIterator> range = m_cs.m_routeMap.equal_range(channel); 100 if (range.first == range.second) 101 { 102 m_useDefault = true; 103 m_itListCurrent = m_cs.m_defaultRoutes.begin(); 104 m_itListEnd = m_cs.m_defaultRoutes.end(); 105 } 106 else 107 { 108 m_useDefault = false; 109 m_itMapCurrent = range.first; 110 m_itMapEnd = range.second; 111 } 112} 113 114bool ChannelRouteIterator::End() const 115{ 116 return m_useDefault ? m_itListCurrent == m_itListEnd : m_itMapCurrent == m_itMapEnd; 117} 118 119void ChannelRouteIterator::Next() 120{ 121 if (m_useDefault) 122 ++m_itListCurrent; 123 else 124 ++m_itMapCurrent; 125} 126 127BufferedTransformation & ChannelRouteIterator::Destination() 128{ 129 return m_useDefault ? *m_itListCurrent->first : *m_itMapCurrent->second.first; 130} 131 132const std::string & ChannelRouteIterator::Channel() 133{ 134 if (m_useDefault) 135 return m_itListCurrent->second.get() ? *m_itListCurrent->second.get() : m_channel; 136 else 137 return m_itMapCurrent->second.second; 138} 139 140 141// 142// ChannelSwitch 143/////////////////// 144 145size_t ChannelSwitch::ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking) 146{ 147 if (m_blocked) 148 { 149 m_blocked = false; 150 goto WasBlocked; 151 } 152 153 m_it.Reset(channel); 154 155 while (!m_it.End()) 156 { 157WasBlocked: 158 if (m_it.Destination().ChannelPut2(m_it.Channel(), begin, length, messageEnd, blocking)) 159 { 160 m_blocked = true; 161 return 1; 162 } 163 164 m_it.Next(); 165 } 166 167 return 0; 168} 169 170void ChannelSwitch::IsolatedInitialize(const NameValuePairs ¶meters/* =g_nullNameValuePairs */) 171{ 172 m_routeMap.clear(); 173 m_defaultRoutes.clear(); 174 m_blocked = false; 175} 176 177bool ChannelSwitch::ChannelFlush(const std::string &channel, bool completeFlush, int propagation, bool blocking) 178{ 179 if (m_blocked) 180 { 181 m_blocked = false; 182 goto WasBlocked; 183 } 184 185 m_it.Reset(channel); 186 187 while (!m_it.End()) 188 { 189 WasBlocked: 190 if (m_it.Destination().ChannelFlush(m_it.Channel(), completeFlush, propagation, blocking)) 191 { 192 m_blocked = true; 193 return true; 194 } 195 196 m_it.Next(); 197 } 198 199 return false; 200} 201 202bool ChannelSwitch::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking) 203{ 204 if (m_blocked) 205 { 206 m_blocked = false; 207 goto WasBlocked; 208 } 209 210 m_it.Reset(channel); 211 212 while (!m_it.End()) 213 { 214 WasBlocked: 215 if (m_it.Destination().ChannelMessageSeriesEnd(m_it.Channel(), propagation)) 216 { 217 m_blocked = true; 218 return true; 219 } 220 221 m_it.Next(); 222 } 223 224 return false; 225} 226 227byte * ChannelSwitch::ChannelCreatePutSpace(const std::string &channel, size_t &size) 228{ 229 m_it.Reset(channel); 230 if (!m_it.End()) 231 { 232 BufferedTransformation &target = m_it.Destination(); 233 const std::string &channel = m_it.Channel(); 234 m_it.Next(); 235 if (m_it.End()) // there is only one target channel 236 return target.ChannelCreatePutSpace(channel, size); 237 } 238 size = 0; 239 return NULL; 240} 241 242size_t ChannelSwitch::ChannelPutModifiable2(const std::string &channel, byte *inString, size_t length, int messageEnd, bool blocking) 243{ 244 ChannelRouteIterator it(*this); 245 it.Reset(channel); 246 247 if (!it.End()) 248 { 249 BufferedTransformation &target = it.Destination(); 250 const std::string &targetChannel = it.Channel(); 251 it.Next(); 252 if (it.End()) // there is only one target channel 253 return target.ChannelPutModifiable2(targetChannel, inString, length, messageEnd, blocking); 254 } 255 256 return ChannelPut2(channel, inString, length, messageEnd, blocking); 257} 258 259void ChannelSwitch::AddDefaultRoute(BufferedTransformation &destination) 260{ 261 m_defaultRoutes.push_back(DefaultRoute(&destination, value_ptr<std::string>(NULL))); 262} 263 264void ChannelSwitch::RemoveDefaultRoute(BufferedTransformation &destination) 265{ 266 for (DefaultRouteList::iterator it = m_defaultRoutes.begin(); it != m_defaultRoutes.end(); ++it) 267 if (it->first == &destination && !it->second.get()) 268 { 269 m_defaultRoutes.erase(it); 270 break; 271 } 272} 273 274void ChannelSwitch::AddDefaultRoute(BufferedTransformation &destination, const std::string &outChannel) 275{ 276 m_defaultRoutes.push_back(DefaultRoute(&destination, outChannel)); 277} 278 279void ChannelSwitch::RemoveDefaultRoute(BufferedTransformation &destination, const std::string &outChannel) 280{ 281 for (DefaultRouteList::iterator it = m_defaultRoutes.begin(); it != m_defaultRoutes.end(); ++it) 282 if (it->first == &destination && (it->second.get() && *it->second == outChannel)) 283 { 284 m_defaultRoutes.erase(it); 285 break; 286 } 287} 288 289void ChannelSwitch::AddRoute(const std::string &inChannel, BufferedTransformation &destination, const std::string &outChannel) 290{ 291 m_routeMap.insert(RouteMap::value_type(inChannel, Route(&destination, outChannel))); 292} 293 294void ChannelSwitch::RemoveRoute(const std::string &inChannel, BufferedTransformation &destination, const std::string &outChannel) 295{ 296 typedef ChannelSwitch::RouteMap::iterator MapIterator; 297 pair<MapIterator, MapIterator> range = m_routeMap.equal_range(inChannel); 298 299 for (MapIterator it = range.first; it != range.second; ++it) 300 if (it->second.first == &destination && it->second.second == outChannel) 301 { 302 m_routeMap.erase(it); 303 break; 304 } 305} 306 307NAMESPACE_END 308 309#endif 310