1// specification file for an unlimited queue for storing bytes 2 3#ifndef CRYPTOPP_QUEUE_H 4#define CRYPTOPP_QUEUE_H 5 6#include "simple.h" 7//#include <algorithm> 8 9NAMESPACE_BEGIN(CryptoPP) 10 11/** The queue is implemented as a linked list of byte arrays, but you don't need to 12 know about that. So just ignore this next line. :) */ 13class ByteQueueNode; 14 15//! Byte Queue 16class CRYPTOPP_DLL ByteQueue : public Bufferless<BufferedTransformation> 17{ 18public: 19 ByteQueue(size_t nodeSize=0); 20 ByteQueue(const ByteQueue ©); 21 ~ByteQueue(); 22 23 lword MaxRetrievable() const 24 {return CurrentSize();} 25 bool AnyRetrievable() const 26 {return !IsEmpty();} 27 28 void IsolatedInitialize(const NameValuePairs ¶meters); 29 byte * CreatePutSpace(size_t &size); 30 size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking); 31 32 size_t Get(byte &outByte); 33 size_t Get(byte *outString, size_t getMax); 34 35 size_t Peek(byte &outByte) const; 36 size_t Peek(byte *outString, size_t peekMax) const; 37 38 size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); 39 size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const; 40 41 // these member functions are not inherited 42 void SetNodeSize(size_t nodeSize); 43 44 lword CurrentSize() const; 45 bool IsEmpty() const; 46 47 void Clear(); 48 49 void Unget(byte inByte); 50 void Unget(const byte *inString, size_t length); 51 52 const byte * Spy(size_t &contiguousSize) const; 53 54 void LazyPut(const byte *inString, size_t size); 55 void LazyPutModifiable(byte *inString, size_t size); 56 void UndoLazyPut(size_t size); 57 void FinalizeLazyPut(); 58 59 ByteQueue & operator=(const ByteQueue &rhs); 60 bool operator==(const ByteQueue &rhs) const; 61 byte operator[](lword i) const; 62 void swap(ByteQueue &rhs); 63 64 class Walker : public InputRejecting<BufferedTransformation> 65 { 66 public: 67 Walker(const ByteQueue &queue) 68 : m_queue(queue) {Initialize();} 69 70 lword GetCurrentPosition() {return m_position;} 71 72 lword MaxRetrievable() const 73 {return m_queue.CurrentSize() - m_position;} 74 75 void IsolatedInitialize(const NameValuePairs ¶meters); 76 77 size_t Get(byte &outByte); 78 size_t Get(byte *outString, size_t getMax); 79 80 size_t Peek(byte &outByte) const; 81 size_t Peek(byte *outString, size_t peekMax) const; 82 83 size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); 84 size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const; 85 86 private: 87 const ByteQueue &m_queue; 88 const ByteQueueNode *m_node; 89 lword m_position; 90 size_t m_offset; 91 const byte *m_lazyString; 92 size_t m_lazyLength; 93 }; 94 95 friend class Walker; 96 97private: 98 void CleanupUsedNodes(); 99 void CopyFrom(const ByteQueue ©); 100 void Destroy(); 101 102 bool m_autoNodeSize; 103 size_t m_nodeSize; 104 ByteQueueNode *m_head, *m_tail; 105 byte *m_lazyString; 106 size_t m_lazyLength; 107 bool m_lazyStringModifiable; 108}; 109 110//! use this to make sure LazyPut is finalized in event of exception 111class CRYPTOPP_DLL LazyPutter 112{ 113public: 114 LazyPutter(ByteQueue &bq, const byte *inString, size_t size) 115 : m_bq(bq) {bq.LazyPut(inString, size);} 116 ~LazyPutter() 117 {try {m_bq.FinalizeLazyPut();} catch(...) {}} 118protected: 119 LazyPutter(ByteQueue &bq) : m_bq(bq) {} 120private: 121 ByteQueue &m_bq; 122}; 123 124//! like LazyPutter, but does a LazyPutModifiable instead 125class LazyPutterModifiable : public LazyPutter 126{ 127public: 128 LazyPutterModifiable(ByteQueue &bq, byte *inString, size_t size) 129 : LazyPutter(bq) {bq.LazyPutModifiable(inString, size);} 130}; 131 132NAMESPACE_END 133 134#ifndef __BORLANDC__ 135NAMESPACE_BEGIN(std) 136template<> inline void swap(CryptoPP::ByteQueue &a, CryptoPP::ByteQueue &b) 137{ 138 a.swap(b); 139} 140NAMESPACE_END 141#endif 142 143#endif 144