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 size_t MessageQueue::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword 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 size_t MessageQueue::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking)
00025 {
00026 transferBytes = STDMIN(MaxRetrievable(), transferBytes);
00027 size_t 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<lword>::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(size_t &contiguousSize) const
00066 {
00067 const byte *result = m_queue.Spy(contiguousSize);
00068 contiguousSize = UnsignedMin(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 size_t EqualityComparisonFilter::ChannelPut2(const std::string &channel, const byte *inString, size_t 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 size_t 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