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 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

Generated on Fri Aug 27 15:51:08 2004 for Crypto++ by doxygen 1.3.8