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