~zooko/cryptopp/trunk

1 by weidai
Initial revision
1
// channels.cpp - written and placed in the public domain by Wei Dai
2
3
#include "pch.h"
75 by weidai
create DLL version, fix GetNextIV() bug in CTR and OFB modes
4
5
#ifndef CRYPTOPP_IMPORTS
6
1 by weidai
Initial revision
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
43 by weidai
fix bug in Grouper
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
///////////////////
1 by weidai
Initial revision
144
184 by weidai
port to MSVC .NET 2005 beta 2
145
size_t ChannelSwitch::ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking)
1 by weidai
Initial revision
146
{
43 by weidai
fix bug in Grouper
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
	{
75 by weidai
create DLL version, fix GetNextIV() bug in CTR and OFB modes
157
WasBlocked:
43 by weidai
fix bug in Grouper
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
1 by weidai
Initial revision
167
	return 0;
168
}
169
86 by weidai
added support for using encoding parameters and key derivation parameters
170
void ChannelSwitch::IsolatedInitialize(const NameValuePairs &parameters/* =g_nullNameValuePairs */)
1 by weidai
Initial revision
171
{
86 by weidai
added support for using encoding parameters and key derivation parameters
172
	m_routeMap.clear();
173
	m_defaultRoutes.clear();
174
	m_blocked = false;
1 by weidai
Initial revision
175
}
176
177
bool ChannelSwitch::ChannelFlush(const std::string &channel, bool completeFlush, int propagation, bool blocking)
178
{
43 by weidai
fix bug in Grouper
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
1 by weidai
Initial revision
199
	return false;
200
}
201
202
bool ChannelSwitch::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking)
203
{
43 by weidai
fix bug in Grouper
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
1 by weidai
Initial revision
224
	return false;
225
}
226
184 by weidai
port to MSVC .NET 2005 beta 2
227
byte * ChannelSwitch::ChannelCreatePutSpace(const std::string &channel, size_t &size)
1 by weidai
Initial revision
228
{
43 by weidai
fix bug in Grouper
229
	m_it.Reset(channel);
230
	if (!m_it.End())
1 by weidai
Initial revision
231
	{
43 by weidai
fix bug in Grouper
232
		BufferedTransformation &target = m_it.Destination();
87 by weidai
fix bug in ChannelSwitch::ChannelCreatePutSpace() when a channel has only one route
233
		const std::string &channel = m_it.Channel();
43 by weidai
fix bug in Grouper
234
		m_it.Next();
235
		if (m_it.End())	// there is only one target channel
87 by weidai
fix bug in ChannelSwitch::ChannelCreatePutSpace() when a channel has only one route
236
			return target.ChannelCreatePutSpace(channel, size);
1 by weidai
Initial revision
237
	}
238
	size = 0;
239
	return NULL;
240
}
241
184 by weidai
port to MSVC .NET 2005 beta 2
242
size_t ChannelSwitch::ChannelPutModifiable2(const std::string &channel, byte *inString, size_t length, int messageEnd, bool blocking)
1 by weidai
Initial revision
243
{
43 by weidai
fix bug in Grouper
244
	ChannelRouteIterator it(*this);
245
	it.Reset(channel);
1 by weidai
Initial revision
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
	}
43 by weidai
fix bug in Grouper
255
256
	return ChannelPut2(channel, inString, length, messageEnd, blocking);
1 by weidai
Initial revision
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
75 by weidai
create DLL version, fix GetNextIV() bug in CTR and OFB modes
308
309
#endif