Back to home page

EIC code displayed by LXR

 
 

    


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

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

0002 
0003 /// \file

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

0005 
0006 #ifndef CRYPTOPP_QUEUE_H
0007 #define CRYPTOPP_QUEUE_H
0008 
0009 #include "cryptlib.h"
0010 #include "simple.h"
0011 
0012 NAMESPACE_BEGIN(CryptoPP)
0013 
0014 class ByteQueueNode;
0015 
0016 /// \brief Data structure used to store byte strings

0017 /// \details The queue is implemented as a linked list of byte arrays.

0018 ///  Each byte array is stored in a ByteQueueNode.

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

0020 ///  on the Crypto++ wiki.

0021 /// \since Crypto++ 2.0

0022 class CRYPTOPP_DLL ByteQueue : public Bufferless<BufferedTransformation>
0023 {
0024 public:
0025     virtual ~ByteQueue();
0026 
0027     /// \brief Construct a ByteQueue

0028     /// \param nodeSize the initial node size

0029     /// \details Internally, ByteQueue uses a ByteQueueNode to store bytes,

0030     ///  and <tt>nodeSize</tt> determines the size of the ByteQueueNode. A value

0031     ///  of 0 indicates the ByteQueueNode should be automatically sized,

0032     ///  which means a value of 256 is used.

0033     ByteQueue(size_t nodeSize=0);
0034 
0035     /// \brief Copy construct a ByteQueue

0036     /// \param copy the other ByteQueue

0037     ByteQueue(const ByteQueue &copy);
0038 
0039     // BufferedTransformation

0040     lword MaxRetrievable() const
0041         {return CurrentSize();}
0042     bool AnyRetrievable() const
0043         {return !IsEmpty();}
0044 
0045     void IsolatedInitialize(const NameValuePairs &parameters);
0046     byte * CreatePutSpace(size_t &size);
0047     size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking);
0048 
0049     size_t Get(byte &outByte);
0050     size_t Get(byte *outString, size_t getMax);
0051 
0052     size_t Peek(byte &outByte) const;
0053     size_t Peek(byte *outString, size_t peekMax) const;
0054 
0055     size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
0056     size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const;
0057 
0058     /// \brief Set node size

0059     /// \param nodeSize the new node size, in bytes

0060     /// \details The default node size is 256.

0061     void SetNodeSize(size_t nodeSize);
0062 
0063     /// \brief Determine data size

0064     /// \return the data size, in bytes

0065     lword CurrentSize() const;
0066 
0067     /// \brief Determine data availability

0068     /// \return true if the ByteQueue has data, false otherwise

0069     bool IsEmpty() const;
0070 
0071     /// \brief Empty the queue

0072     void Clear();
0073 
0074     /// \brief Insert data in the queue

0075     /// \param inByte a byte to insert

0076     /// \details Unget() inserts a byte at the head of the queue

0077     void Unget(byte inByte);
0078 
0079     /// \brief Insert data in the queue

0080     /// \param inString a byte array to insert

0081     /// \param length the size of the byte array

0082     /// \details Unget() inserts a byte array at the head of the queue

0083     void Unget(const byte *inString, size_t length);
0084 
0085     /// \brief Peek data in the queue

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

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

0088     ///  not remove data from the queue.

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

0090     ///  Spy() returns the size of the first byte array in the list. The

0091     ///  entire data may be larger since the queue is a linked list of

0092     ///  byte arrays.

0093     const byte * Spy(size_t &contiguousSize) const;
0094 
0095     /// \brief Insert data in the queue

0096     /// \param inString a byte array to insert

0097     /// \param size the length of the byte array

0098     /// \details LazyPut() inserts a byte array at the tail of the queue.

0099     ///  The data may not be copied at this point. Rather, the pointer

0100     ///  and size to external data are recorded.

0101     /// \details Another call to Put() or LazyPut() will force the data to

0102     ///  be copied. When lazy puts are used, the data is copied when

0103     ///  FinalizeLazyPut() is called.

0104     /// \sa LazyPutter

0105     void LazyPut(const byte *inString, size_t size);
0106 
0107     /// \brief Insert data in the queue

0108     /// \param inString a byte array to insert

0109     /// \param size the length of the byte array

0110     /// \details LazyPut() inserts a byte array at the tail of the queue.

0111     ///  The data may not be copied at this point. Rather, the pointer

0112     ///  and size to external data are recorded.

0113     /// \details Another call to Put() or LazyPut() will force the data to

0114     ///  be copied. When lazy puts are used, the data is copied when

0115     ///  FinalizeLazyPut() is called.

0116     /// \sa LazyPutter

0117     void LazyPutModifiable(byte *inString, size_t size);
0118 
0119     /// \brief Remove data from the queue

0120     /// \param size the length of the data

0121     /// \throw InvalidArgument if there is no lazy data in the queue or if

0122     ///  size is larger than the lazy string

0123     /// \details UndoLazyPut() truncates data inserted using LazyPut() by

0124     ///  modifying size.

0125     /// \sa LazyPutter

0126     void UndoLazyPut(size_t size);
0127 
0128     /// \brief Insert data in the queue

0129     /// \details FinalizeLazyPut() copies external data inserted using

0130     ///  LazyPut() or LazyPutModifiable() into the tail of the queue.

0131     /// \sa LazyPutter

0132     void FinalizeLazyPut();
0133 
0134     /// \brief Assign contents from another ByteQueue

0135     /// \param rhs the other ByteQueue

0136     /// \return reference to this ByteQueue

0137     ByteQueue & operator=(const ByteQueue &rhs);
0138 
0139     /// \brief Bitwise compare two ByteQueue

0140     /// \param rhs the other ByteQueue

0141     /// \return true if the size and bits are equal, false otherwise

0142     /// \details operator==() walks each ByteQueue comparing bytes in

0143     ///  each queue. operator==() is not constant time.

0144     bool operator==(const ByteQueue &rhs) const;
0145 
0146     /// \brief Bitwise compare two ByteQueue

0147     /// \param rhs the other ByteQueue

0148     /// \return true if the size and bits are not equal, false otherwise

0149     /// \details operator!=() is implemented in terms of operator==().

0150     ///  operator==() is not constant time.

0151     bool operator!=(const ByteQueue &rhs) const {return !operator==(rhs);}
0152 
0153     /// \brief Retrieve data from the queue

0154     /// \param index of byte to retrieve

0155     /// \return byte at the specified index

0156     /// \details operator[]() does not perform bounds checking.

0157     byte operator[](lword index) const;
0158 
0159     /// \brief Swap contents with another ByteQueue

0160     /// \param rhs the other ByteQueue

0161     void swap(ByteQueue &rhs);
0162 
0163     /// \brief A ByteQueue iterator

0164     class Walker : public InputRejecting<BufferedTransformation>
0165     {
0166     public:
0167         /// \brief Construct a ByteQueue Walker

0168         /// \param queue a ByteQueue

0169         Walker(const ByteQueue &queue)
0170             : m_queue(queue), m_node(NULLPTR), m_position(0), m_offset(0), m_lazyString(NULLPTR), m_lazyLength(0)
0171                 {Initialize();}
0172 
0173         lword GetCurrentPosition() {return m_position;}
0174 
0175         lword MaxRetrievable() const
0176             {return m_queue.CurrentSize() - m_position;}
0177 
0178         void IsolatedInitialize(const NameValuePairs &parameters);
0179 
0180         size_t Get(byte &outByte);
0181         size_t Get(byte *outString, size_t getMax);
0182 
0183         size_t Peek(byte &outByte) const;
0184         size_t Peek(byte *outString, size_t peekMax) const;
0185 
0186         size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
0187         size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const;
0188 
0189     private:
0190         const ByteQueue &m_queue;
0191         const ByteQueueNode *m_node;
0192         lword m_position;
0193         size_t m_offset;
0194         const byte *m_lazyString;
0195         size_t m_lazyLength;
0196     };
0197 
0198     friend class Walker;
0199 
0200 protected:
0201     void CleanupUsedNodes();
0202     void CopyFrom(const ByteQueue &copy);
0203     void Destroy();
0204 
0205 private:
0206     ByteQueueNode *m_head, *m_tail;
0207     byte *m_lazyString;
0208     size_t m_lazyLength;
0209     size_t m_nodeSize;
0210     bool m_lazyStringModifiable;
0211     bool m_autoNodeSize;
0212 };
0213 
0214 /// \brief Helper class to finalize Puts on ByteQueue

0215 /// \details LazyPutter ensures LazyPut is committed to the ByteQueue

0216 ///  in event of exception. During destruction, the LazyPutter class

0217 ///  calls FinalizeLazyPut.

0218 class CRYPTOPP_DLL LazyPutter
0219 {
0220 public:
0221     virtual ~LazyPutter() {
0222         try {m_bq.FinalizeLazyPut();}
0223         catch(const Exception&) {CRYPTOPP_ASSERT(0);}
0224     }
0225 
0226     /// \brief Construct a LazyPutter

0227     /// \param bq the ByteQueue

0228     /// \param inString a byte array to insert

0229     /// \param size the length of the byte array

0230     /// \details LazyPutter ensures LazyPut is committed to the ByteQueue

0231     ///  in event of exception. During destruction, the LazyPutter class

0232     ///  calls FinalizeLazyPut.

0233     LazyPutter(ByteQueue &bq, const byte *inString, size_t size)
0234         : m_bq(bq) {bq.LazyPut(inString, size);}
0235 
0236 protected:
0237     LazyPutter(ByteQueue &bq) : m_bq(bq) {}
0238 
0239 private:
0240     ByteQueue &m_bq;
0241 };
0242 
0243 /// \brief Helper class to finalize Puts on ByteQueue

0244 /// \details LazyPutterModifiable ensures LazyPut is committed to the

0245 ///  ByteQueue in event of exception. During destruction, the

0246 ///  LazyPutterModifiable class calls FinalizeLazyPut.

0247 class LazyPutterModifiable : public LazyPutter
0248 {
0249 public:
0250     /// \brief Construct a LazyPutterModifiable

0251     /// \param bq the ByteQueue

0252     /// \param inString a byte array to insert

0253     /// \param size the length of the byte array

0254     /// \details LazyPutterModifiable ensures LazyPut is committed to the

0255     ///  ByteQueue in event of exception. During destruction, the

0256     ///  LazyPutterModifiable class calls FinalizeLazyPut.

0257     LazyPutterModifiable(ByteQueue &bq, byte *inString, size_t size)
0258         : LazyPutter(bq) {bq.LazyPutModifiable(inString, size);}
0259 };
0260 
0261 NAMESPACE_END
0262 
0263 #ifndef __BORLANDC__
0264 NAMESPACE_BEGIN(std)
0265 template<> inline void swap(CryptoPP::ByteQueue &a, CryptoPP::ByteQueue &b)
0266 {
0267     a.swap(b);
0268 }
0269 NAMESPACE_END
0270 #endif
0271 
0272 #endif