|
|
// channels.cpp - written and placed in the public domain by Wei Dai
#include "pch.h"
#ifndef CRYPTOPP_IMPORTS
#include "channels.h"
NAMESPACE_BEGIN(CryptoPP) USING_NAMESPACE(std)
#if 0
void MessageSwitch::AddDefaultRoute(BufferedTransformation &destination, const std::string &channel) { m_defaultRoutes.push_back(Route(&destination, channel)); }
void MessageSwitch::AddRoute(unsigned int begin, unsigned int end, BufferedTransformation &destination, const std::string &channel) { RangeRoute route(begin, end, Route(&destination, channel)); RouteList::iterator it = upper_bound(m_routes.begin(), m_routes.end(), route); m_routes.insert(it, route); }
/*
class MessageRouteIterator { public: typedef MessageSwitch::RouteList::const_iterator RouteIterator; typedef MessageSwitch::DefaultRouteList::const_iterator DefaultIterator;
bool m_useDefault; RouteIterator m_itRouteCurrent, m_itRouteEnd; DefaultIterator m_itDefaultCurrent, m_itDefaultEnd;
MessageRouteIterator(MessageSwitch &ms, const std::string &channel) : m_channel(channel) { pair<MapIterator, MapIterator> range = cs.m_routeMap.equal_range(channel); if (range.first == range.second) { m_useDefault = true; m_itListCurrent = cs.m_defaultRoutes.begin(); m_itListEnd = cs.m_defaultRoutes.end(); } else { m_useDefault = false; m_itMapCurrent = range.first; m_itMapEnd = range.second; } }
bool End() const { return m_useDefault ? m_itListCurrent == m_itListEnd : m_itMapCurrent == m_itMapEnd; }
void Next() { if (m_useDefault) ++m_itListCurrent; else ++m_itMapCurrent; }
BufferedTransformation & Destination() { return m_useDefault ? *m_itListCurrent->first : *m_itMapCurrent->second.first; }
const std::string & Message() { if (m_useDefault) return m_itListCurrent->second.get() ? *m_itListCurrent->second.get() : m_channel; else return m_itMapCurrent->second.second; } };
void MessageSwitch::Put(byte inByte); void MessageSwitch::Put(const byte *inString, unsigned int length);
void MessageSwitch::Flush(bool completeFlush, int propagation=-1); void MessageSwitch::MessageEnd(int propagation=-1); void MessageSwitch::PutMessageEnd(const byte *inString, unsigned int length, int propagation=-1); void MessageSwitch::MessageSeriesEnd(int propagation=-1); */ #endif
//
// ChannelRouteIterator
//////////////////////////
void ChannelRouteIterator::Reset(const std::string &channel) { m_channel = channel; pair<MapIterator, MapIterator> range = m_cs.m_routeMap.equal_range(channel); if (range.first == range.second) { m_useDefault = true; m_itListCurrent = m_cs.m_defaultRoutes.begin(); m_itListEnd = m_cs.m_defaultRoutes.end(); } else { m_useDefault = false; m_itMapCurrent = range.first; m_itMapEnd = range.second; } }
bool ChannelRouteIterator::End() const { return m_useDefault ? m_itListCurrent == m_itListEnd : m_itMapCurrent == m_itMapEnd; }
void ChannelRouteIterator::Next() { if (m_useDefault) ++m_itListCurrent; else ++m_itMapCurrent; }
BufferedTransformation & ChannelRouteIterator::Destination() { return m_useDefault ? *m_itListCurrent->first : *m_itMapCurrent->second.first; }
const std::string & ChannelRouteIterator::Channel() { if (m_useDefault) return m_itListCurrent->second.get() ? *m_itListCurrent->second.get() : m_channel; else return m_itMapCurrent->second.second; }
//
// ChannelSwitch
///////////////////
size_t ChannelSwitch::ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking) { if (m_blocked) { m_blocked = false; goto WasBlocked; }
m_it.Reset(channel);
while (!m_it.End()) { WasBlocked: if (m_it.Destination().ChannelPut2(m_it.Channel(), begin, length, messageEnd, blocking)) { m_blocked = true; return 1; }
m_it.Next(); }
return 0; }
void ChannelSwitch::IsolatedInitialize(const NameValuePairs ¶meters/* =g_nullNameValuePairs */) { m_routeMap.clear(); m_defaultRoutes.clear(); m_blocked = false; }
bool ChannelSwitch::ChannelFlush(const std::string &channel, bool completeFlush, int propagation, bool blocking) { if (m_blocked) { m_blocked = false; goto WasBlocked; }
m_it.Reset(channel);
while (!m_it.End()) { WasBlocked: if (m_it.Destination().ChannelFlush(m_it.Channel(), completeFlush, propagation, blocking)) { m_blocked = true; return true; }
m_it.Next(); }
return false; }
bool ChannelSwitch::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking) { if (m_blocked) { m_blocked = false; goto WasBlocked; }
m_it.Reset(channel);
while (!m_it.End()) { WasBlocked: if (m_it.Destination().ChannelMessageSeriesEnd(m_it.Channel(), propagation)) { m_blocked = true; return true; }
m_it.Next(); }
return false; }
byte * ChannelSwitch::ChannelCreatePutSpace(const std::string &channel, size_t &size) { m_it.Reset(channel); if (!m_it.End()) { BufferedTransformation &target = m_it.Destination(); const std::string &channel = m_it.Channel(); m_it.Next(); if (m_it.End()) // there is only one target channel
return target.ChannelCreatePutSpace(channel, size); } size = 0; return NULL; }
size_t ChannelSwitch::ChannelPutModifiable2(const std::string &channel, byte *inString, size_t length, int messageEnd, bool blocking) { ChannelRouteIterator it(*this); it.Reset(channel);
if (!it.End()) { BufferedTransformation &target = it.Destination(); const std::string &targetChannel = it.Channel(); it.Next(); if (it.End()) // there is only one target channel
return target.ChannelPutModifiable2(targetChannel, inString, length, messageEnd, blocking); }
return ChannelPut2(channel, inString, length, messageEnd, blocking); }
void ChannelSwitch::AddDefaultRoute(BufferedTransformation &destination) { m_defaultRoutes.push_back(DefaultRoute(&destination, value_ptr<std::string>(NULL))); }
void ChannelSwitch::RemoveDefaultRoute(BufferedTransformation &destination) { for (DefaultRouteList::iterator it = m_defaultRoutes.begin(); it != m_defaultRoutes.end(); ++it) if (it->first == &destination && !it->second.get()) { m_defaultRoutes.erase(it); break; } }
void ChannelSwitch::AddDefaultRoute(BufferedTransformation &destination, const std::string &outChannel) { m_defaultRoutes.push_back(DefaultRoute(&destination, outChannel)); }
void ChannelSwitch::RemoveDefaultRoute(BufferedTransformation &destination, const std::string &outChannel) { for (DefaultRouteList::iterator it = m_defaultRoutes.begin(); it != m_defaultRoutes.end(); ++it) if (it->first == &destination && (it->second.get() && *it->second == outChannel)) { m_defaultRoutes.erase(it); break; } }
void ChannelSwitch::AddRoute(const std::string &inChannel, BufferedTransformation &destination, const std::string &outChannel) { m_routeMap.insert(RouteMap::value_type(inChannel, Route(&destination, outChannel))); }
void ChannelSwitch::RemoveRoute(const std::string &inChannel, BufferedTransformation &destination, const std::string &outChannel) { typedef ChannelSwitch::RouteMap::iterator MapIterator; pair<MapIterator, MapIterator> range = m_routeMap.equal_range(inChannel); for (MapIterator it = range.first; it != range.second; ++it) if (it->second.first == &destination && it->second.second == outChannel) { m_routeMap.erase(it); break; } }
NAMESPACE_END
#endif
|