mqueue.cpp
// mqueue.cpp - originally written and placed in the public domain by Wei Dai
#include "pch.h"
#ifndef CRYPTOPP_IMPORTS
#include "mqueue.h"
NAMESPACE_BEGIN(CryptoPP)
MessageQueue::MessageQueue(unsigned int nodeSize)
: m_queue(nodeSize), m_lengths(1, 0U), m_messageCounts(1, 0U)
{
}
size_t MessageQueue::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const
{
if (begin >= MaxRetrievable())
return 0;
return m_queue.CopyRangeTo2(target, begin, STDMIN(MaxRetrievable(), end), channel, blocking);
}
size_t MessageQueue::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking)
{
transferBytes = STDMIN(MaxRetrievable(), transferBytes);
size_t blockedBytes = m_queue.TransferTo2(target, transferBytes, channel, blocking);
m_lengths.front() -= transferBytes;
return blockedBytes;
}
bool MessageQueue::GetNextMessage()
{
if (NumberOfMessages() > 0 && !AnyRetrievable())
{
m_lengths.pop_front();
if (m_messageCounts[0] == 0 && m_messageCounts.size() > 1)
m_messageCounts.pop_front();
return true;
}
else
return false;
}
unsigned int MessageQueue::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const
{
ByteQueue::Walker walker(m_queue);
std::deque<lword>::const_iterator it = m_lengths.begin();
unsigned int i;
for (i=0; i<count && it != --m_lengths.end(); ++i, ++it)
{
walker.TransferTo(target, *it, channel);
if (GetAutoSignalPropagation())
target.ChannelMessageEnd(channel, GetAutoSignalPropagation()-1);
}
return i;
}
void MessageQueue::swap(MessageQueue &rhs)
{
m_queue.swap(rhs.m_queue);
m_lengths.swap(rhs.m_lengths);
}
const byte * MessageQueue::Spy(size_t &contiguousSize) const
{
const byte *result = m_queue.Spy(contiguousSize);
contiguousSize = UnsignedMin(contiguousSize, MaxRetrievable());
return result;
}
// *************************************************************
unsigned int EqualityComparisonFilter::MapChannel(const std::string &channel) const
{
if (channel == m_firstChannel)
return 0;
else if (channel == m_secondChannel)
return 1;
else
return 2;
}
size_t EqualityComparisonFilter::ChannelPut2(const std::string &channel, const byte *inString, size_t length, int messageEnd, bool blocking)
{
if (!blocking)
throw BlockingInputOnly("EqualityComparisonFilter");
unsigned int i = MapChannel(channel);
if (i == 2)
return Output(3, inString, length, messageEnd, blocking, channel);
else if (m_mismatchDetected)
return 0;
else
{
MessageQueue &q1 = m_q[i], &q2 = m_q[1-i];
if (q2.AnyMessages() && q2.MaxRetrievable() < length)
goto mismatch;
while (length > 0 && q2.AnyRetrievable())
{
size_t len = length;
const byte *data = q2.Spy(len);
len = STDMIN(len, length);
if (memcmp(inString, data, len) != 0)
goto mismatch;
inString += len;
length -= len;
q2.Skip(len);
}
q1.Put(inString, length);
if (messageEnd)
{
if (q2.AnyRetrievable())
goto mismatch;
else if (q2.AnyMessages())
q2.GetNextMessage();
else if (q2.NumberOfMessageSeries() > 0)
goto mismatch;
else
q1.MessageEnd();
}
return 0;
mismatch:
return HandleMismatchDetected(blocking);
}
}
bool EqualityComparisonFilter::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking)
{
unsigned int i = MapChannel(channel);
if (i == 2)
{
OutputMessageSeriesEnd(4, propagation, blocking, channel);
return false;
}
else if (m_mismatchDetected)
return false;
else
{
MessageQueue &q1 = m_q[i], &q2 = m_q[1-i];
if (q2.AnyRetrievable() || q2.AnyMessages())
goto mismatch;
else if (q2.NumberOfMessageSeries() > 0)
return Output(2, (const byte *)"\1", 1, 0, blocking) != 0;
else
q1.MessageSeriesEnd();
return false;
mismatch:
return HandleMismatchDetected(blocking);
}
}
bool EqualityComparisonFilter::HandleMismatchDetected(bool blocking)
{
m_mismatchDetected = true;
if (m_throwIfNotEqual)
throw MismatchDetected();
const byte b[1] = {0};
return Output(1, b, 1, 0, blocking) != 0;
}
NAMESPACE_END
#endif
AutoSignaling< BufferedTransformation >::GetAutoSignalPropagation
int GetAutoSignalPropagation() const
Retrieve automatic signal propagation value.
Definition: simple.h:439
BufferedTransformation
Interface for buffered transformations.
Definition: cryptlib.h:1652
BufferedTransformation::MessageEnd
bool MessageEnd(int propagation=-1, bool blocking=true)
Signals the end of messages to the object.
Definition: cryptlib.h:1743
BufferedTransformation::MessageSeriesEnd
virtual bool MessageSeriesEnd(int propagation=-1, bool blocking=true)
Marks the end of a series of messages, with signal propagation.
BufferedTransformation::ChannelMessageEnd
bool ChannelMessageEnd(const std::string &channel, int propagation=-1, bool blocking=true)
Signal the end of a message.
Definition: cryptlib.h:2252
BufferedTransformation::Put
size_t Put(byte inByte, bool blocking=true)
Input a byte for processing.
Definition: cryptlib.h:1673
ByteQueue::Walker
A ByteQueue iterator.
Definition: queue.h:165
ByteQueue::Spy
const byte * Spy(size_t &contiguousSize) const
Peek data in the queue.
ByteQueue::TransferTo2
size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true)
Transfer bytes from this object to another BufferedTransformation.
ByteQueue::swap
void swap(ByteQueue &rhs)
Swap contents with another ByteQueue.
ByteQueue::CopyRangeTo2
size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const
Copy bytes from this object to another BufferedTransformation.
EqualityComparisonFilter::ChannelPut2
size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing on a channel.
MessageQueue
Data structure used to store messages.
Definition: mqueue.h:24
MessageQueue::swap
void swap(MessageQueue &rhs)
Swap contents with another MessageQueue.
MessageQueue::AnyRetrievable
bool AnyRetrievable() const
Determines whether bytes are ready for retrieval.
Definition: mqueue.h:54
MessageQueue::GetNextMessage
bool GetNextMessage()
Start retrieving the next message.
MessageQueue::CopyRangeTo2
size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const
Copy bytes from this object to another BufferedTransformation.
MessageQueue::TransferTo2
size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true)
Transfer bytes from this object to another BufferedTransformation.
MessageQueue::MessageQueue
MessageQueue(unsigned int nodeSize=256)
Construct a MessageQueue.
MessageQueue::NumberOfMessages
unsigned int NumberOfMessages() const
Provides the number of meesages processed by this object.
Definition: mqueue.h:62
MessageQueue::CopyMessagesTo
unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=DEFAULT_CHANNEL) const
Copy messages from this object to another BufferedTransformation.
MessageQueue::Spy
const byte * Spy(size_t &contiguousSize) const
Peek data in the queue.
MessageQueue::MaxRetrievable
lword MaxRetrievable() const
Provides the number of bytes ready for retrieval.
Definition: mqueue.h:52
lword
word64 lword
Large word type.
Definition: config_int.h:158
STDMIN
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:655
UnsignedMin
const T1 UnsignedMin(const T1 &a, const T2 &b)
Safe comparison of values that could be negative and incorrectly promoted.
Definition: misc.h:694
mqueue.h
Classes for an unlimited queue to store messages.
CryptoPP
Crypto++ library namespace.
pch.h
Precompiled header file.