Crypto++ 8.7
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
15NAMESPACE_BEGIN(CryptoPP)
16
17#if 0
18void MessageSwitch::AddDefaultRoute(BufferedTransformation &destination, const std::string &channel)
19{
20 m_defaultRoutes.push_back(Route(&destination, channel));
21}
22
23void 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/*
31class MessageRouteIterator
32{
33public:
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
86void MessageSwitch::Put(byte inByte);
87void MessageSwitch::Put(const byte *inString, unsigned int length);
88
89void MessageSwitch::Flush(bool completeFlush, int propagation=-1);
90void MessageSwitch::MessageEnd(int propagation=-1);
91void MessageSwitch::PutMessageEnd(const byte *inString, unsigned int length, int propagation=-1);
92void MessageSwitch::MessageSeriesEnd(int propagation=-1);
93*/
94#endif
95
96
97//
98// ChannelRouteIterator
99//////////////////////////
100
101void 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
119bool ChannelRouteIterator::End() const
120{
121 return m_useDefault ? m_itListCurrent == m_itListEnd : m_itMapCurrent == m_itMapEnd;
122}
123
124void ChannelRouteIterator::Next()
125{
126 if (m_useDefault)
127 ++m_itListCurrent;
128 else
129 ++m_itMapCurrent;
130}
131
132BufferedTransformation & ChannelRouteIterator::Destination()
133{
134 return m_useDefault ? *m_itListCurrent->first : *m_itMapCurrent->second.first;
135}
136
137const 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
150size_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 {
162WasBlocked:
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
176{
177 CRYPTOPP_UNUSED(parameters);
178 m_routeMap.clear();
179 m_defaultRoutes.clear();
180 m_blocked = false;
181}
182
183bool 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
208bool 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
234byte * 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
249size_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
266void ChannelSwitch::AddDefaultRoute(BufferedTransformation &destination)
267{
268 m_defaultRoutes.push_back(DefaultRoute(&destination, value_ptr<std::string>(NULLPTR)));
269}
270
271void 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
281void ChannelSwitch::AddDefaultRoute(BufferedTransformation &destination, const std::string &outChannel)
282{
283 m_defaultRoutes.push_back(DefaultRoute(&destination, outChannel));
284}
285
286void 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
296void 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
301void 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
314NAMESPACE_END
315
316#endif
Classes for multiple named channels.
Interface for buffered transformations.
Definition: cryptlib.h:1652
virtual byte * ChannelCreatePutSpace(const std::string &channel, size_t &size)
Request space which can be written into by the caller.
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 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.
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.
byte * ChannelCreatePutSpace(const std::string &channel, size_t &size)
Request space which can be written into by the caller.
bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true)
Flush buffered input and/or output on a channel.
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.
void IsolatedInitialize(const NameValuePairs &parameters=g_nullNameValuePairs)
Initialize or reinitialize this object, without signal propagation.
Interface for retrieving values given their names.
Definition: cryptlib.h:322
Value pointer.
Definition: smartptr.h:77
Abstract base classes that provide a uniform interface to this library.
Crypto++ library namespace.
Precompiled header file.