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

mqueue.cpp

00001 // mqueue.cpp - written and placed in the public domain by Wei Dai
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 void EqualityComparisonFilter::ChannelInitialize(const std::string &channel, const NameValuePairs &parameters, int propagation)
00136 {
00137         unsigned int i = MapChannel(channel);
00138 
00139         if (i == 2)
00140                 PropagateInitialize(parameters, propagation, channel);
00141         else
00142         {
00143                 m_q[i].Initialize();
00144                 m_mismatchDetected = false;
00145         }
00146 }
00147 
00148 bool EqualityComparisonFilter::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking)
00149 {
00150         unsigned int i = MapChannel(channel);
00151 
00152         if (i == 2)
00153         {
00154                 OutputMessageSeriesEnd(4, propagation, blocking, channel);
00155                 return false;
00156         }
00157         else if (m_mismatchDetected)
00158                 return false;
00159         else
00160         {
00161                 MessageQueue &q1 = m_q[i], &q2 = m_q[1-i];
00162 
00163                 if (q2.AnyRetrievable() || q2.AnyMessages())
00164                         goto mismatch;
00165                 else if (q2.NumberOfMessageSeries() > 0)
00166                         return Output(2, (const byte *)"\1", 1, 0, blocking) != 0;
00167                 else
00168                         q1.MessageSeriesEnd();
00169 
00170                 return false;
00171 
00172 mismatch:
00173                 return HandleMismatchDetected(blocking);
00174         }
00175 }
00176 
00177 bool EqualityComparisonFilter::HandleMismatchDetected(bool blocking)
00178 {
00179         m_mismatchDetected = true;
00180         if (m_throwIfNotEqual)
00181                 throw MismatchDetected();
00182         return Output(1, (const byte *)"\0", 1, 0, blocking) != 0;
00183 }
00184 
00185 NAMESPACE_END
00186 
00187 #endif

Generated on Tue Jul 8 23:34:20 2003 for Crypto++ by doxygen 1.3.2