Crypto++
channels.cpp
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 
9 NAMESPACE_BEGIN(CryptoPP)
10 USING_NAMESPACE(std)
11 
12 #if 0
13 void MessageSwitch::AddDefaultRoute(BufferedTransformation &destination, const std::string &channel)
14 {
15  m_defaultRoutes.push_back(Route(&destination, channel));
16 }
17 
18 void 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 /*
26 class MessageRouteIterator
27 {
28 public:
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 
81 void MessageSwitch::Put(byte inByte);
82 void MessageSwitch::Put(const byte *inString, unsigned int length);
83 
84 void MessageSwitch::Flush(bool completeFlush, int propagation=-1);
85 void MessageSwitch::MessageEnd(int propagation=-1);
86 void MessageSwitch::PutMessageEnd(const byte *inString, unsigned int length, int propagation=-1);
87 void MessageSwitch::MessageSeriesEnd(int propagation=-1);
88 */
89 #endif
90 
91 
92 //
93 // ChannelRouteIterator
94 //////////////////////////
95 
96 void 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 
114 bool ChannelRouteIterator::End() const
115 {
116  return m_useDefault ? m_itListCurrent == m_itListEnd : m_itMapCurrent == m_itMapEnd;
117 }
118 
119 void ChannelRouteIterator::Next()
120 {
121  if (m_useDefault)
122  ++m_itListCurrent;
123  else
124  ++m_itMapCurrent;
125 }
126 
127 BufferedTransformation & ChannelRouteIterator::Destination()
128 {
129  return m_useDefault ? *m_itListCurrent->first : *m_itMapCurrent->second.first;
130 }
131 
132 const 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 
145 size_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  {
157 WasBlocked:
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 
170 void ChannelSwitch::IsolatedInitialize(const NameValuePairs &parameters/* =g_nullNameValuePairs */)
171 {
172  m_routeMap.clear();
173  m_defaultRoutes.clear();
174  m_blocked = false;
175 }
176 
177 bool 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 
202 bool 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 
227 byte * 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 
242 size_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 
259 void ChannelSwitch::AddDefaultRoute(BufferedTransformation &destination)
260 {
261  m_defaultRoutes.push_back(DefaultRoute(&destination, value_ptr<std::string>(NULL)));
262 }
263 
264 void 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 
274 void ChannelSwitch::AddDefaultRoute(BufferedTransformation &destination, const std::string &outChannel)
275 {
276  m_defaultRoutes.push_back(DefaultRoute(&destination, outChannel));
277 }
278 
279 void 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 
289 void 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 
294 void 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 
307 NAMESPACE_END
308 
309 #endif