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