1
// mqueue.cpp - written and placed in the public domain by Wei Dai
5
#ifndef CRYPTOPP_IMPORTS
9
NAMESPACE_BEGIN(CryptoPP)
11
MessageQueue::MessageQueue(unsigned int nodeSize)
12
: m_queue(nodeSize), m_lengths(1, 0U), m_messageCounts(1, 0U)
16
size_t MessageQueue::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const
18
if (begin >= MaxRetrievable())
21
return m_queue.CopyRangeTo2(target, begin, STDMIN(MaxRetrievable(), end), channel, blocking);
24
size_t MessageQueue::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking)
26
transferBytes = STDMIN(MaxRetrievable(), transferBytes);
27
size_t blockedBytes = m_queue.TransferTo2(target, transferBytes, channel, blocking);
28
m_lengths.front() -= transferBytes;
32
bool MessageQueue::GetNextMessage()
34
if (NumberOfMessages() > 0 && !AnyRetrievable())
36
m_lengths.pop_front();
37
if (m_messageCounts[0] == 0 && m_messageCounts.size() > 1)
38
m_messageCounts.pop_front();
45
unsigned int MessageQueue::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const
47
ByteQueue::Walker walker(m_queue);
48
std::deque<lword>::const_iterator it = m_lengths.begin();
50
for (i=0; i<count && it != --m_lengths.end(); ++i, ++it)
52
walker.TransferTo(target, *it, channel);
53
if (GetAutoSignalPropagation())
54
target.ChannelMessageEnd(channel, GetAutoSignalPropagation()-1);
59
void MessageQueue::swap(MessageQueue &rhs)
61
m_queue.swap(rhs.m_queue);
62
m_lengths.swap(rhs.m_lengths);
65
const byte * MessageQueue::Spy(size_t &contiguousSize) const
67
const byte *result = m_queue.Spy(contiguousSize);
68
contiguousSize = UnsignedMin(contiguousSize, MaxRetrievable());
72
// *************************************************************
74
unsigned int EqualityComparisonFilter::MapChannel(const std::string &channel) const
76
if (channel == m_firstChannel)
78
else if (channel == m_secondChannel)
84
size_t EqualityComparisonFilter::ChannelPut2(const std::string &channel, const byte *inString, size_t length, int messageEnd, bool blocking)
87
throw BlockingInputOnly("EqualityComparisonFilter");
89
unsigned int i = MapChannel(channel);
92
return Output(3, inString, length, messageEnd, blocking, channel);
93
else if (m_mismatchDetected)
97
MessageQueue &q1 = m_q[i], &q2 = m_q[1-i];
99
if (q2.AnyMessages() && q2.MaxRetrievable() < length)
102
while (length > 0 && q2.AnyRetrievable())
105
const byte *data = q2.Spy(len);
106
len = STDMIN(len, length);
107
if (memcmp(inString, data, len) != 0)
114
q1.Put(inString, length);
118
if (q2.AnyRetrievable())
120
else if (q2.AnyMessages())
122
else if (q2.NumberOfMessageSeries() > 0)
131
return HandleMismatchDetected(blocking);
135
bool EqualityComparisonFilter::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking)
137
unsigned int i = MapChannel(channel);
141
OutputMessageSeriesEnd(4, propagation, blocking, channel);
144
else if (m_mismatchDetected)
148
MessageQueue &q1 = m_q[i], &q2 = m_q[1-i];
150
if (q2.AnyRetrievable() || q2.AnyMessages())
152
else if (q2.NumberOfMessageSeries() > 0)
153
return Output(2, (const byte *)"\1", 1, 0, blocking) != 0;
155
q1.MessageSeriesEnd();
160
return HandleMismatchDetected(blocking);
164
bool EqualityComparisonFilter::HandleMismatchDetected(bool blocking)
166
m_mismatchDetected = true;
167
if (m_throwIfNotEqual)
168
throw MismatchDetected();
169
return Output(1, (const byte *)"\0", 1, 0, blocking) != 0;