Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

mqueue.cpp

00001 // mqueue.cpp - written and placed in the public domain by Wei Dai
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 &parameters, 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

Generated on Sun Mar 14 20:44:27 2004 for Crypto++ by doxygen 1.3.6-20040222