1 | // queue.h - written and placed in the public domain by Wei Dai |
---|
2 | |
---|
3 | //! \file |
---|
4 | //! \headerfile queue.h |
---|
5 | //! \brief Classes for an unlimited queue to store bytes |
---|
6 | |
---|
7 | #ifndef CRYPTOPP_QUEUE_H |
---|
8 | #define CRYPTOPP_QUEUE_H |
---|
9 | |
---|
10 | #include "cryptlib.h" |
---|
11 | #include "simple.h" |
---|
12 | |
---|
13 | NAMESPACE_BEGIN(CryptoPP) |
---|
14 | |
---|
15 | class ByteQueueNode; |
---|
16 | |
---|
17 | //! \class ByteQueue |
---|
18 | //! \brief Data structure used to store byte strings |
---|
19 | //! \details The queue is implemented as a linked list of byte arrays |
---|
20 | class CRYPTOPP_DLL ByteQueue : public Bufferless<BufferedTransformation> |
---|
21 | { |
---|
22 | public: |
---|
23 | //! \brief Construct a ByteQueue |
---|
24 | //! \param nodeSize the initial node size |
---|
25 | //! \details Internally, ByteQueue uses a ByteQueueNode to store bytes, and \p nodeSize determines the |
---|
26 | //! size of the ByteQueueNode. A value of 0 indicates the ByteQueueNode should be automatically sized, |
---|
27 | //! which means a value of 256 is used. |
---|
28 | ByteQueue(size_t nodeSize=0); |
---|
29 | |
---|
30 | //! \brief Copy construct a ByteQueue |
---|
31 | //! \param copy the other ByteQueue |
---|
32 | ByteQueue(const ByteQueue ©); |
---|
33 | ~ByteQueue(); |
---|
34 | |
---|
35 | lword MaxRetrievable() const |
---|
36 | {return CurrentSize();} |
---|
37 | bool AnyRetrievable() const |
---|
38 | {return !IsEmpty();} |
---|
39 | |
---|
40 | void IsolatedInitialize(const NameValuePairs ¶meters); |
---|
41 | byte * CreatePutSpace(size_t &size); |
---|
42 | size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking); |
---|
43 | |
---|
44 | size_t Get(byte &outByte); |
---|
45 | size_t Get(byte *outString, size_t getMax); |
---|
46 | |
---|
47 | size_t Peek(byte &outByte) const; |
---|
48 | size_t Peek(byte *outString, size_t peekMax) const; |
---|
49 | |
---|
50 | size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); |
---|
51 | size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const; |
---|
52 | |
---|
53 | // these member functions are not inherited |
---|
54 | void SetNodeSize(size_t nodeSize); |
---|
55 | |
---|
56 | lword CurrentSize() const; |
---|
57 | bool IsEmpty() const; |
---|
58 | |
---|
59 | void Clear(); |
---|
60 | |
---|
61 | void Unget(byte inByte); |
---|
62 | void Unget(const byte *inString, size_t length); |
---|
63 | |
---|
64 | const byte * Spy(size_t &contiguousSize) const; |
---|
65 | |
---|
66 | void LazyPut(const byte *inString, size_t size); |
---|
67 | void LazyPutModifiable(byte *inString, size_t size); |
---|
68 | void UndoLazyPut(size_t size); |
---|
69 | void FinalizeLazyPut(); |
---|
70 | |
---|
71 | ByteQueue & operator=(const ByteQueue &rhs); |
---|
72 | bool operator==(const ByteQueue &rhs) const; |
---|
73 | bool operator!=(const ByteQueue &rhs) const {return !operator==(rhs);} |
---|
74 | byte operator[](lword i) const; |
---|
75 | void swap(ByteQueue &rhs); |
---|
76 | |
---|
77 | //! \class Walker |
---|
78 | //! \brief A ByteQueue iterator |
---|
79 | class Walker : public InputRejecting<BufferedTransformation> |
---|
80 | { |
---|
81 | public: |
---|
82 | //! \brief Construct a ByteQueue Walker |
---|
83 | //! \param queue a ByteQueue |
---|
84 | Walker(const ByteQueue &queue) |
---|
85 | : m_queue(queue), m_node(NULL), m_position(0), m_offset(0), m_lazyString(NULL), m_lazyLength(0) |
---|
86 | {Initialize();} |
---|
87 | |
---|
88 | lword GetCurrentPosition() {return m_position;} |
---|
89 | |
---|
90 | lword MaxRetrievable() const |
---|
91 | {return m_queue.CurrentSize() - m_position;} |
---|
92 | |
---|
93 | void IsolatedInitialize(const NameValuePairs ¶meters); |
---|
94 | |
---|
95 | size_t Get(byte &outByte); |
---|
96 | size_t Get(byte *outString, size_t getMax); |
---|
97 | |
---|
98 | size_t Peek(byte &outByte) const; |
---|
99 | size_t Peek(byte *outString, size_t peekMax) const; |
---|
100 | |
---|
101 | size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); |
---|
102 | size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const; |
---|
103 | |
---|
104 | private: |
---|
105 | const ByteQueue &m_queue; |
---|
106 | const ByteQueueNode *m_node; |
---|
107 | lword m_position; |
---|
108 | size_t m_offset; |
---|
109 | const byte *m_lazyString; |
---|
110 | size_t m_lazyLength; |
---|
111 | }; |
---|
112 | |
---|
113 | friend class Walker; |
---|
114 | |
---|
115 | private: |
---|
116 | void CleanupUsedNodes(); |
---|
117 | void CopyFrom(const ByteQueue ©); |
---|
118 | void Destroy(); |
---|
119 | |
---|
120 | bool m_autoNodeSize; |
---|
121 | size_t m_nodeSize; |
---|
122 | ByteQueueNode *m_head, *m_tail; |
---|
123 | byte *m_lazyString; |
---|
124 | size_t m_lazyLength; |
---|
125 | bool m_lazyStringModifiable; |
---|
126 | }; |
---|
127 | |
---|
128 | //! use this to make sure LazyPut is finalized in event of exception |
---|
129 | class CRYPTOPP_DLL LazyPutter |
---|
130 | { |
---|
131 | public: |
---|
132 | LazyPutter(ByteQueue &bq, const byte *inString, size_t size) |
---|
133 | : m_bq(bq) {bq.LazyPut(inString, size);} |
---|
134 | ~LazyPutter() |
---|
135 | {try {m_bq.FinalizeLazyPut();} catch(const Exception&) {CRYPTOPP_ASSERT(0);}} |
---|
136 | protected: |
---|
137 | LazyPutter(ByteQueue &bq) : m_bq(bq) {} |
---|
138 | private: |
---|
139 | ByteQueue &m_bq; |
---|
140 | }; |
---|
141 | |
---|
142 | //! like LazyPutter, but does a LazyPutModifiable instead |
---|
143 | class LazyPutterModifiable : public LazyPutter |
---|
144 | { |
---|
145 | public: |
---|
146 | LazyPutterModifiable(ByteQueue &bq, byte *inString, size_t size) |
---|
147 | : LazyPutter(bq) {bq.LazyPutModifiable(inString, size);} |
---|
148 | }; |
---|
149 | |
---|
150 | NAMESPACE_END |
---|
151 | |
---|
152 | #ifndef __BORLANDC__ |
---|
153 | NAMESPACE_BEGIN(std) |
---|
154 | template<> inline void swap(CryptoPP::ByteQueue &a, CryptoPP::ByteQueue &b) |
---|
155 | { |
---|
156 | a.swap(b); |
---|
157 | } |
---|
158 | NAMESPACE_END |
---|
159 | #endif |
---|
160 | |
---|
161 | #endif |
---|