Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:55:05

0001 // mqueue.h - originally written and placed in the public domain by Wei Dai

0002 
0003 /// \file

0004 /// \brief Classes for an unlimited queue to store messages

0005 
0006 #ifndef CRYPTOPP_MQUEUE_H
0007 #define CRYPTOPP_MQUEUE_H
0008 
0009 #include "cryptlib.h"
0010 #include "queue.h"
0011 #include "filters.h"
0012 #include "misc.h"
0013 
0014 #include <deque>
0015 
0016 NAMESPACE_BEGIN(CryptoPP)
0017 
0018 /// \brief Data structure used to store messages

0019 /// \details The queue is implemented with a ByteQueue.

0020 /// \sa <A HREF="https://www.cryptopp.com/wiki/MessageQueue">MessageQueue</A>

0021 ///  on the Crypto++ wiki.

0022 /// \since Crypto++ 2.0

0023 class CRYPTOPP_DLL MessageQueue : public AutoSignaling<BufferedTransformation>
0024 {
0025 public:
0026     virtual ~MessageQueue() {}
0027 
0028     /// \brief Construct a MessageQueue

0029     /// \param nodeSize the initial node size

0030     MessageQueue(unsigned int nodeSize=256);
0031 
0032     // BufferedTransformation

0033     void IsolatedInitialize(const NameValuePairs &parameters)
0034         {m_queue.IsolatedInitialize(parameters); m_lengths.assign(1, 0U); m_messageCounts.assign(1, 0U);}
0035     size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
0036     {
0037         CRYPTOPP_UNUSED(blocking);
0038         m_queue.Put(begin, length);
0039         m_lengths.back() += length;
0040         if (messageEnd)
0041         {
0042             m_lengths.push_back(0);
0043             m_messageCounts.back()++;
0044         }
0045         return 0;
0046     }
0047     bool IsolatedFlush(bool hardFlush, bool blocking)
0048         {CRYPTOPP_UNUSED(hardFlush), CRYPTOPP_UNUSED(blocking); return false;}
0049     bool IsolatedMessageSeriesEnd(bool blocking)
0050         {CRYPTOPP_UNUSED(blocking); m_messageCounts.push_back(0); return false;}
0051 
0052     lword MaxRetrievable() const
0053         {return m_lengths.front();}
0054     bool AnyRetrievable() const
0055         {return m_lengths.front() > 0;}
0056 
0057     size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
0058     size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const;
0059 
0060     lword TotalBytesRetrievable() const
0061         {return m_queue.MaxRetrievable();}
0062     unsigned int NumberOfMessages() const
0063         {return (unsigned int)m_lengths.size()-1;}
0064     bool GetNextMessage();
0065 
0066     unsigned int NumberOfMessagesInThisSeries() const
0067         {return m_messageCounts[0];}
0068     unsigned int NumberOfMessageSeries() const
0069         {return (unsigned int)m_messageCounts.size()-1;}
0070 
0071     /// \brief Copy messages from this object to another BufferedTransformation.

0072     /// \param target the destination BufferedTransformation

0073     /// \param count the number of messages to copy

0074     /// \param channel the channel on which the transfer should occur

0075     /// \return the number of messages that remain in the copy (i.e., messages not copied)

0076     unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=DEFAULT_CHANNEL) const;
0077 
0078     /// \brief Peek data in the queue

0079     /// \param contiguousSize the size of the data

0080     /// \details Spy() peeks at data at the head of the queue. Spy() does

0081     ///  not remove data from the queue.

0082     /// \details The data's size is returned in <tt>contiguousSize</tt>.

0083     ///  Spy() returns the size of the first message in the list.

0084     const byte * Spy(size_t &contiguousSize) const;
0085 
0086     /// \brief Swap contents with another MessageQueue

0087     /// \param rhs the other MessageQueue

0088     void swap(MessageQueue &rhs);
0089 
0090 private:
0091     ByteQueue m_queue;
0092     std::deque<lword> m_lengths;
0093     std::deque<unsigned int> m_messageCounts;
0094 };
0095 
0096 /// \brief Filter that checks messages on two channels for equality

0097 class CRYPTOPP_DLL EqualityComparisonFilter : public Unflushable<Multichannel<Filter> >
0098 {
0099 public:
0100     /// \brief Different messages were detected

0101     struct MismatchDetected : public Exception
0102     {
0103         /// \brief Construct a MismatchDetected exception

0104         MismatchDetected() : Exception(DATA_INTEGRITY_CHECK_FAILED, "EqualityComparisonFilter: did not receive the same data on two channels") {}
0105     };
0106 
0107     /// \brief Construct an EqualityComparisonFilter

0108     /// \param attachment an attached transformation

0109     /// \param throwIfNotEqual flag indicating whether the objects throws

0110     /// \param firstChannel string naming the first channel

0111     /// \param secondChannel string naming the second channel

0112     /// \throw MismatchDetected if throwIfNotEqual is true and not equal

0113     /// \details If throwIfNotEqual is false, this filter will output a '\\0'

0114     ///  byte when it detects a mismatch, '\\1' otherwise.

0115     EqualityComparisonFilter(BufferedTransformation *attachment=NULLPTR, bool throwIfNotEqual=true, const std::string &firstChannel="0", const std::string &secondChannel="1")
0116         : m_throwIfNotEqual(throwIfNotEqual), m_mismatchDetected(false)
0117         , m_firstChannel(firstChannel), m_secondChannel(secondChannel)
0118         {Detach(attachment);}
0119 
0120     // BufferedTransformation

0121     size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking);
0122     bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true);
0123 
0124 protected:
0125     unsigned int MapChannel(const std::string &channel) const;
0126     bool HandleMismatchDetected(bool blocking);
0127 
0128 private:
0129     bool m_throwIfNotEqual, m_mismatchDetected;
0130     std::string m_firstChannel, m_secondChannel;
0131     MessageQueue m_q[2];
0132 };
0133 
0134 NAMESPACE_END
0135 
0136 #ifndef __BORLANDC__
0137 NAMESPACE_BEGIN(std)
0138 template<> inline void swap(CryptoPP::MessageQueue &a, CryptoPP::MessageQueue &b)
0139 {
0140     a.swap(b);
0141 }
0142 NAMESPACE_END
0143 #endif
0144 
0145 #endif