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 Wed Jul 28 08:07:08 2004 for Crypto++ by doxygen 1.3.7