|
||||
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 ©); 0038 0039 // BufferedTransformation 0040 lword MaxRetrievable() const 0041 {return CurrentSize();} 0042 bool AnyRetrievable() const 0043 {return !IsEmpty();} 0044 0045 void IsolatedInitialize(const NameValuePairs ¶meters); 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 ¶meters); 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 ©); 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
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |