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