00001
00002
00003
#include "pch.h"
00004
#include "mqueue.h"
00005
00006 NAMESPACE_BEGIN(CryptoPP)
00007
00008
MessageQueue::
MessageQueue(
unsigned int nodeSize)
00009 : m_queue(nodeSize), m_lengths(1, 0U), m_messageCounts(1, 0U)
00010 {
00011 }
00012
00013
unsigned int MessageQueue::CopyRangeTo2(
BufferedTransformation &target,
unsigned long &begin,
unsigned long end,
const std::string &channel,
bool blocking)
const
00014
{
00015
if (begin >= MaxRetrievable())
00016
return 0;
00017
00018
return m_queue.
CopyRangeTo2(target, begin, STDMIN(MaxRetrievable(), end), channel, blocking);
00019 }
00020
00021
unsigned int MessageQueue::TransferTo2(
BufferedTransformation &target,
unsigned long &transferBytes,
const std::string &channel,
bool blocking)
00022 {
00023 transferBytes = STDMIN(MaxRetrievable(), transferBytes);
00024
unsigned int blockedBytes = m_queue.
TransferTo2(target, transferBytes, channel, blocking);
00025 m_lengths.front() -= transferBytes;
00026
return blockedBytes;
00027 }
00028
00029
bool MessageQueue::GetNextMessage()
00030 {
00031
if (NumberOfMessages() > 0 && !AnyRetrievable())
00032 {
00033 m_lengths.pop_front();
00034
if (m_messageCounts[0] == 0 && m_messageCounts.size() > 1)
00035 m_messageCounts.pop_front();
00036
return true;
00037 }
00038
else
00039
return false;
00040 }
00041
00042
unsigned int MessageQueue::CopyMessagesTo(
BufferedTransformation &target,
unsigned int count,
const std::string &channel)
const
00043
{
00044 ByteQueue::Walker walker(m_queue);
00045 std::deque<unsigned long>::const_iterator it = m_lengths.begin();
00046
unsigned int i;
00047
for (i=0; i<count && it != --m_lengths.end(); ++i, ++it)
00048 {
00049 walker.TransferTo(target, *it, channel);
00050
if (GetAutoSignalPropagation())
00051 target.
ChannelMessageEnd(channel, GetAutoSignalPropagation()-1);
00052 }
00053
return i;
00054 }
00055
00056
void MessageQueue::swap(
MessageQueue &rhs)
00057 {
00058 m_queue.
swap(rhs.
m_queue);
00059 m_lengths.swap(rhs.
m_lengths);
00060 }
00061
00062
const byte * MessageQueue::Spy(
unsigned int &contiguousSize)
const
00063
{
00064
const byte *result = m_queue.
Spy(contiguousSize);
00065 contiguousSize = (
unsigned int)STDMIN((
unsigned long)contiguousSize, MaxRetrievable());
00066
return result;
00067 }
00068
00069
00070
00071
unsigned int EqualityComparisonFilter::MapChannel(
const std::string &channel)
const
00072
{
00073
if (channel == m_firstChannel)
00074
return 0;
00075
else if (channel == m_secondChannel)
00076
return 1;
00077
else
00078
return 2;
00079 }
00080
00081
unsigned int EqualityComparisonFilter::ChannelPut2(
const std::string &channel,
const byte *inString,
unsigned int length,
int messageEnd,
bool blocking)
00082 {
00083
if (!blocking)
00084
throw BlockingInputOnly(
"EqualityComparisonFilter");
00085
00086
unsigned int i = MapChannel(channel);
00087
00088
if (i == 2)
00089
return Output(3, inString, length, messageEnd, blocking, channel);
00090
else if (m_mismatchDetected)
00091
return 0;
00092
else
00093 {
00094
MessageQueue &q1 = m_q[i], &q2 = m_q[1-i];
00095
00096
if (q2.AnyMessages() && q2.
MaxRetrievable() < length)
00097
goto mismatch;
00098
00099
while (length > 0 && q2.
AnyRetrievable())
00100 {
00101
unsigned int len = length;
00102
const byte *data = q2.
Spy(len);
00103 len = STDMIN(len, length);
00104
if (memcmp(inString, data, len) != 0)
00105
goto mismatch;
00106 inString += len;
00107 length -= len;
00108 q2.Skip(len);
00109 }
00110
00111 q1.Put(inString, length);
00112
00113
if (messageEnd)
00114 {
00115
if (q2.
AnyRetrievable())
00116
goto mismatch;
00117
else if (q2.AnyMessages())
00118 q2.
GetNextMessage();
00119
else if (q2.
NumberOfMessageSeries() > 0)
00120
goto mismatch;
00121
else
00122 q1.MessageEnd();
00123 }
00124
00125
return 0;
00126
00127 mismatch:
00128
return HandleMismatchDetected(blocking);
00129 }
00130 }
00131
00132
void EqualityComparisonFilter::ChannelInitialize(
const std::string &channel,
const NameValuePairs ¶meters,
int propagation)
00133 {
00134
unsigned int i = MapChannel(channel);
00135
00136
if (i == 2)
00137 PropagateInitialize(parameters, propagation, channel);
00138
else
00139 {
00140 m_q[i].Initialize();
00141 m_mismatchDetected =
false;
00142 }
00143 }
00144
00145
bool EqualityComparisonFilter::ChannelMessageSeriesEnd(
const std::string &channel,
int propagation,
bool blocking)
00146 {
00147
unsigned int i = MapChannel(channel);
00148
00149
if (i == 2)
00150 {
00151 OutputMessageSeriesEnd(4, propagation, blocking, channel);
00152
return false;
00153 }
00154
else if (m_mismatchDetected)
00155
return false;
00156
else
00157 {
00158
MessageQueue &q1 = m_q[i], &q2 = m_q[1-i];
00159
00160
if (q2.
AnyRetrievable() || q2.AnyMessages())
00161
goto mismatch;
00162
else if (q2.
NumberOfMessageSeries() > 0)
00163
return Output(2, (
const byte *)
"\1", 1, 0, blocking) != 0;
00164
else
00165 q1.MessageSeriesEnd();
00166
00167
return false;
00168
00169 mismatch:
00170
return HandleMismatchDetected(blocking);
00171 }
00172 }
00173
00174
bool EqualityComparisonFilter::HandleMismatchDetected(
bool blocking)
00175 {
00176 m_mismatchDetected =
true;
00177
if (m_throwIfNotEqual)
00178
throw MismatchDetected();
00179
return Output(1, (
const byte *)
"\0", 1, 0, blocking) != 0;
00180 }
00181
00182 NAMESPACE_END