#ifndef CRYPTOPP_MQUEUE_H
#define CRYPTOPP_MQUEUE_H
#include "queue.h"
#include "filters.h"
#include <deque>
NAMESPACE_BEGIN(CryptoPP)
class MessageQueue : public BufferedTransformationWithAutoSignal
{
public:
MessageQueue(unsigned int nodeSize=256);
void Put(byte inByte)
{m_queue.Put(inByte); m_lengths.back()++;}
void Put(const byte *inString, unsigned int length)
{m_queue.Put(inString, length); m_lengths.back()+=length;}
unsigned long MaxRetrievable() const
{return m_lengths.front();}
bool AnyRetrievable() const
{return m_lengths.front() > 0;}
unsigned long TransferTo(BufferedTransformation &target, unsigned long transferMax=ULONG_MAX)
{return Got(m_queue.TransferTo(target, STDMIN(MaxRetrievable(), transferMax)));}
unsigned long CopyTo(BufferedTransformation &target, unsigned long copyMax=ULONG_MAX) const
{return m_queue.CopyTo(target, STDMIN(MaxRetrievable(), copyMax));}
void MessageEnd(int=-1)
{m_lengths.push_back(0);}
unsigned long TotalBytesRetrievable() const
{return m_queue.MaxRetrievable();}
unsigned int NumberOfMessages() const
{return m_lengths.size()-1;}
bool GetNextMessage();
unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX) const;
void swap(MessageQueue &rhs);
private:
unsigned long Got(unsigned long length)
{assert(m_lengths.front() >= length); m_lengths.front() -= length; return length;}
ByteQueue m_queue;
std::deque<unsigned long> m_lengths;
};
NAMESPACE_END
NAMESPACE_BEGIN(std)
template<> inline void swap(CryptoPP::MessageQueue &a, CryptoPP::MessageQueue &b)
{
a.swap(b);
}
NAMESPACE_END
#endif