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