Crypto++ 8.9 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
channels.h
Classes for multiple named channels.
BufferedTransformation
Interface for buffered transformations.
Definition: cryptlib.h:1657
BufferedTransformation::ChannelFlush
virtual bool ChannelFlush(const std::string &channel, bool hardFlush, int propagation=-1, bool blocking=true)
Flush buffered input and/or output on a channel.
BufferedTransformation::ChannelPutModifiable2
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.
BufferedTransformation::ChannelCreatePutSpace
virtual byte * ChannelCreatePutSpace(const std::string &channel, size_t &size)
Request space which can be written into by the caller.
BufferedTransformation::ChannelPut2
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.
BufferedTransformation::ChannelMessageSeriesEnd
virtual bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true)
Marks the end of a series of messages on a channel.
ChannelRouteIterator
Definition: channels.h:74
ChannelSwitch::ChannelPut2
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.
ChannelSwitch::ChannelFlush
bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true)
Flush buffered input and/or output on a channel.
NameValuePairs
Interface for retrieving values given their names.
Definition: cryptlib.h:327
value_ptr
Value pointer.
Definition: smartptr.h:77
cryptlib.h
Abstract base classes that provide a uniform interface to this library.
CryptoPP
Crypto++ library namespace.
pch.h
Precompiled header file.