Crypto++ 8.6 Free C++ class library of cryptographic schemes

queue.h
Go to the documentation of this file.
1 // queue.h - originally written and placed in the public domain by Wei Dai
2
3 /// \file
4 /// \brief Classes for an unlimited queue to store bytes
5
6 #ifndef CRYPTOPP_QUEUE_H
7 #define CRYPTOPP_QUEUE_H
8
9 #include "cryptlib.h"
10 #include "simple.h"
11
12 NAMESPACE_BEGIN(CryptoPP)
13
14 class ByteQueueNode;
15
16 /// \brief Data structure used to store byte strings
17 /// \details The queue is implemented as a linked list of byte arrays.
18 /// Each byte array is stored in a ByteQueueNode.
19 /// \sa <A HREF="https://www.cryptopp.com/wiki/ByteQueue">ByteQueue</A>
20 /// on the Crypto++ wiki.
21 /// \since Crypto++ 2.0
22 class CRYPTOPP_DLL ByteQueue : public Bufferless<BufferedTransformation>
23 {
24 public:
25 virtual ~ByteQueue();
26
27 /// \brief Construct a ByteQueue
28 /// \param nodeSize the initial node size
29 /// \details Internally, ByteQueue uses a ByteQueueNode to store bytes,
30 /// and <tt>nodeSize</tt> determines the size of the ByteQueueNode. A value
31 /// of 0 indicates the ByteQueueNode should be automatically sized,
32 /// which means a value of 256 is used.
33 ByteQueue(size_t nodeSize=0);
34
35 /// \brief Copy construct a ByteQueue
36 /// \param copy the other ByteQueue
37 ByteQueue(const ByteQueue &copy);
38
39 // BufferedTransformation
40 lword MaxRetrievable() const
41 {return CurrentSize();}
42 bool AnyRetrievable() const
43 {return !IsEmpty();}
44
45 void IsolatedInitialize(const NameValuePairs &parameters);
46 byte * CreatePutSpace(size_t &size);
47 size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking);
48
49 size_t Get(byte &outByte);
50 size_t Get(byte *outString, size_t getMax);
51
52 size_t Peek(byte &outByte) const;
53 size_t Peek(byte *outString, size_t peekMax) const;
54
55 size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
56 size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const;
57
58 /// \brief Set node size
59 /// \param nodeSize the new node size, in bytes
60 /// \details The default node size is 256.
61 void SetNodeSize(size_t nodeSize);
62
63 /// \brief Determine data size
64 /// \return the data size, in bytes
65 lword CurrentSize() const;
66
67 /// \brief Determine data availability
68 /// \return true if the ByteQueue has data, false otherwise
69 bool IsEmpty() const;
70
71 /// \brief Empty the queue
72 void Clear();
73
74 /// \brief Insert data in the queue
75 /// \param inByte a byte to insert
76 /// \details Unget() inserts a byte at the head of the queue
77 void Unget(byte inByte);
78
79 /// \brief Insert data in the queue
80 /// \param inString a byte array to insert
81 /// \param length the size of the byte array
82 /// \details Unget() inserts a byte array at the head of the queue
83 void Unget(const byte *inString, size_t length);
84
85 /// \brief Peek data in the queue
86 /// \param contiguousSize the size of the data
87 /// \details Spy() peeks at data at the head of the queue. Spy() does
88 /// not remove data from the queue.
89 /// \details The data's size is returned in <tt>contiguousSize</tt>.
90 /// Spy() returns the size of the first byte array in the list. The
91 /// entire data may be larger since the queue is a linked list of
92 /// byte arrays.
93 const byte * Spy(size_t &contiguousSize) const;
94
95 /// \brief Insert data in the queue
96 /// \param inString a byte array to insert
97 /// \param size the length of the byte array
98 /// \details LazyPut() inserts a byte array at the tail of the queue.
99 /// The data may not be copied at this point. Rather, the pointer
100 /// and size to external data are recorded.
101 /// \details Another call to Put() or LazyPut() will force the data to
102 /// be copied. When lazy puts are used, the data is copied when
103 /// FinalizeLazyPut() is called.
104 /// \sa LazyPutter
105 void LazyPut(const byte *inString, size_t size);
106
107 /// \brief Insert data in the queue
108 /// \param inString a byte array to insert
109 /// \param size the length of the byte array
110 /// \details LazyPut() inserts a byte array at the tail of the queue.
111 /// The data may not be copied at this point. Rather, the pointer
112 /// and size to external data are recorded.
113 /// \details Another call to Put() or LazyPut() will force the data to
114 /// be copied. When lazy puts are used, the data is copied when
115 /// FinalizeLazyPut() is called.
116 /// \sa LazyPutter
117 void LazyPutModifiable(byte *inString, size_t size);
118
119 /// \brief Remove data from the queue
120 /// \param size the length of the data
121 /// \throw InvalidArgument if there is no lazy data in the queue or if
122 /// size is larger than the lazy string
123 /// \details UndoLazyPut() truncates data inserted using LazyPut() by
124 /// modifying size.
125 /// \sa LazyPutter
126 void UndoLazyPut(size_t size);
127
128 /// \brief Insert data in the queue
129 /// \details FinalizeLazyPut() copies external data inserted using
130 /// LazyPut() or LazyPutModifiable() into the tail of the queue.
131 /// \sa LazyPutter
132 void FinalizeLazyPut();
133
134 /// \brief Assign contents from another ByteQueue
135 /// \param rhs the other ByteQueue
136 /// \return reference to this ByteQueue
137 ByteQueue & operator=(const ByteQueue &rhs);
138
139 /// \brief Bitwise compare two ByteQueue
140 /// \param rhs the other ByteQueue
141 /// \return true if the size and bits are equal, false otherwise
142 /// \details operator==() walks each ByteQueue comparing bytes in
143 /// each queue. operator==() is not constant time.
144 bool operator==(const ByteQueue &rhs) const;
145
146 /// \brief Bitwise compare two ByteQueue
147 /// \param rhs the other ByteQueue
148 /// \return true if the size and bits are not equal, false otherwise
149 /// \details operator!=() is implemented in terms of operator==().
150 /// operator==() is not constant time.
151 bool operator!=(const ByteQueue &rhs) const {return !operator==(rhs);}
152
153 /// \brief Retrieve data from the queue
154 /// \param index of byte to retrieve
155 /// \return byte at the specified index
156 /// \details operator[]() does not perform bounds checking.
157 byte operator[](lword index) const;
158
159 /// \brief Swap contents with another ByteQueue
160 /// \param rhs the other ByteQueue
161 void swap(ByteQueue &rhs);
162
163 /// \brief A ByteQueue iterator
164 class Walker : public InputRejecting<BufferedTransformation>
165 {
166 public:
167 /// \brief Construct a ByteQueue Walker
168 /// \param queue a ByteQueue
169 Walker(const ByteQueue &queue)
170 : m_queue(queue), m_node(NULLPTR), m_position(0), m_offset(0), m_lazyString(NULLPTR), m_lazyLength(0)
171 {Initialize();}
172
173 lword GetCurrentPosition() {return m_position;}
174
175 lword MaxRetrievable() const
176 {return m_queue.CurrentSize() - m_position;}
177
178 void IsolatedInitialize(const NameValuePairs &parameters);
179
180 size_t Get(byte &outByte);
181 size_t Get(byte *outString, size_t getMax);
182
183 size_t Peek(byte &outByte) const;
184 size_t Peek(byte *outString, size_t peekMax) const;
185
186 size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
187 size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const;
188
189 private:
190 const ByteQueue &m_queue;
191 const ByteQueueNode *m_node;
192 lword m_position;
193 size_t m_offset;
194 const byte *m_lazyString;
195 size_t m_lazyLength;
196 };
197
198 friend class Walker;
199
200 protected:
201 void CleanupUsedNodes();
202 void CopyFrom(const ByteQueue &copy);
203 void Destroy();
204
205 private:
206 ByteQueueNode *m_head, *m_tail;
207 byte *m_lazyString;
208 size_t m_lazyLength;
209 size_t m_nodeSize;
210 bool m_lazyStringModifiable;
211 bool m_autoNodeSize;
212 };
213
214 /// \brief Helper class to finalize Puts on ByteQueue
215 /// \details LazyPutter ensures LazyPut is committed to the ByteQueue
216 /// in event of exception. During destruction, the LazyPutter class
217 /// calls FinalizeLazyPut.
218 class CRYPTOPP_DLL LazyPutter
219 {
220 public:
221 virtual ~LazyPutter() {
222 try {m_bq.FinalizeLazyPut();}
223 catch(const Exception&) {CRYPTOPP_ASSERT(0);}
224 }
225
226 /// \brief Construct a LazyPutter
227 /// \param bq the ByteQueue
228 /// \param inString a byte array to insert
229 /// \param size the length of the byte array
230 /// \details LazyPutter ensures LazyPut is committed to the ByteQueue
231 /// in event of exception. During destruction, the LazyPutter class
232 /// calls FinalizeLazyPut.
233 LazyPutter(ByteQueue &bq, const byte *inString, size_t size)
234 : m_bq(bq) {bq.LazyPut(inString, size);}
235
236 protected:
237 LazyPutter(ByteQueue &bq) : m_bq(bq) {}
238
239 private:
240 ByteQueue &m_bq;
241 };
242
243 /// \brief Helper class to finalize Puts on ByteQueue
244 /// \details LazyPutterModifiable ensures LazyPut is committed to the
245 /// ByteQueue in event of exception. During destruction, the
246 /// LazyPutterModifiable class calls FinalizeLazyPut.
247 class LazyPutterModifiable : public LazyPutter
248 {
249 public:
250 /// \brief Construct a LazyPutterModifiable
251 /// \param bq the ByteQueue
252 /// \param inString a byte array to insert
253 /// \param size the length of the byte array
254 /// \details LazyPutterModifiable ensures LazyPut is committed to the
255 /// ByteQueue in event of exception. During destruction, the
256 /// LazyPutterModifiable class calls FinalizeLazyPut.
257 LazyPutterModifiable(ByteQueue &bq, byte *inString, size_t size)
258 : LazyPutter(bq) {bq.LazyPutModifiable(inString, size);}
259 };
260
261 NAMESPACE_END
262
263 #ifndef __BORLANDC__
264 NAMESPACE_BEGIN(std)
265 template<> inline void swap(CryptoPP::ByteQueue &a, CryptoPP::ByteQueue &b)
266 {
267 a.swap(b);
268 }
269 NAMESPACE_END
270 #endif
271
272 #endif
operator==
bool operator==(const OID &lhs, const OID &rhs)
Compare two OIDs for equality.
BufferedTransformation
Interface for buffered transformations.
Definition: cryptlib.h:1657
Bufferless
Base class for bufferless filters.
Definition: simple.h:120
ByteQueue::Walker
A ByteQueue iterator.
Definition: queue.h:165
ByteQueue::Walker::Peek
size_t Peek(byte *outString, size_t peekMax) const
Peek a block of bytes.
ByteQueue::Walker::Get
size_t Get(byte &outByte)
Retrieve a 8-bit byte.
ByteQueue::Walker::TransferTo2
size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true)
Transfer bytes from this object to another BufferedTransformation.
ByteQueue::Walker::CopyRangeTo2
size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const
Copy bytes from this object to another BufferedTransformation.
ByteQueue::Walker::Walker
Walker(const ByteQueue &queue)
Construct a ByteQueue Walker.
Definition: queue.h:169
ByteQueue::Walker::Peek
size_t Peek(byte &outByte) const
Peek a 8-bit byte.
ByteQueue::Walker::MaxRetrievable
lword MaxRetrievable() const
Provides the number of bytes ready for retrieval.
Definition: queue.h:175
ByteQueue::Walker::Get
size_t Get(byte *outString, size_t getMax)
Retrieve a block of bytes.
ByteQueue::Walker::IsolatedInitialize
void IsolatedInitialize(const NameValuePairs &parameters)
Initialize or reinitialize this object, without signal propagation.
ByteQueue
Data structure used to store byte strings.
Definition: queue.h:23
ByteQueue::CurrentSize
lword CurrentSize() const
Determine data size.
ByteQueue::ByteQueue
ByteQueue(const ByteQueue &copy)
Copy construct a ByteQueue.
ByteQueue::Spy
const byte * Spy(size_t &contiguousSize) const
Peek data in the queue.
ByteQueue::LazyPut
void LazyPut(const byte *inString, size_t size)
Insert data in the queue.
ByteQueue::CreatePutSpace
byte * CreatePutSpace(size_t &size)
Request space which can be written into by the caller.
ByteQueue::Get
size_t Get(byte &outByte)
Retrieve a 8-bit byte.
ByteQueue::operator[]
byte operator[](lword index) const
Retrieve data from the queue.
ByteQueue::Clear
void Clear()
Empty the queue.
ByteQueue::Unget
void Unget(const byte *inString, size_t length)
Insert data in the queue.
ByteQueue::SetNodeSize
void SetNodeSize(size_t nodeSize)
Set node size.
ByteQueue::operator=
ByteQueue & operator=(const ByteQueue &rhs)
Assign contents from another ByteQueue.
ByteQueue::Peek
size_t Peek(byte &outByte) const
Peek a 8-bit byte.
ByteQueue::operator==
bool operator==(const ByteQueue &rhs) const
Bitwise compare two ByteQueue.
ByteQueue::Put2
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
ByteQueue::FinalizeLazyPut
void FinalizeLazyPut()
Insert data in the queue.
ByteQueue::Peek
size_t Peek(byte *outString, size_t peekMax) const
Peek a block of bytes.
ByteQueue::ByteQueue
ByteQueue(size_t nodeSize=0)
Construct a ByteQueue.
ByteQueue::IsolatedInitialize
void IsolatedInitialize(const NameValuePairs &parameters)
Initialize or reinitialize this object, without signal propagation.
ByteQueue::Get
size_t Get(byte *outString, size_t getMax)
Retrieve a block of bytes.
ByteQueue::TransferTo2
size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true)
Transfer bytes from this object to another BufferedTransformation.
ByteQueue::UndoLazyPut
void UndoLazyPut(size_t size)
Remove data from the queue.
ByteQueue::MaxRetrievable
lword MaxRetrievable() const
Provides the number of bytes ready for retrieval.
Definition: queue.h:40
ByteQueue::Unget
void Unget(byte inByte)
Insert data in the queue.
ByteQueue::IsEmpty
bool IsEmpty() const
Determine data availability.
ByteQueue::LazyPutModifiable
void LazyPutModifiable(byte *inString, size_t size)
Insert data in the queue.
ByteQueue::operator!=
bool operator!=(const ByteQueue &rhs) const
Bitwise compare two ByteQueue.
Definition: queue.h:151
ByteQueue::swap
void swap(ByteQueue &rhs)
Swap contents with another ByteQueue.
ByteQueue::AnyRetrievable
bool AnyRetrievable() const
Determines whether bytes are ready for retrieval.
Definition: queue.h:42
ByteQueue::CopyRangeTo2
size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const
Copy bytes from this object to another BufferedTransformation.
Exception
Base class for all exceptions thrown by the library.
Definition: cryptlib.h:164
InputRejecting
Base class for input rejecting filters.
Definition: simple.h:195
LazyPutter
Helper class to finalize Puts on ByteQueue.
Definition: queue.h:219
LazyPutter::LazyPutter
LazyPutter(ByteQueue &bq, const byte *inString, size_t size)
Construct a LazyPutter.
Definition: queue.h:233
LazyPutterModifiable
Helper class to finalize Puts on ByteQueue.
Definition: queue.h:248
LazyPutterModifiable::LazyPutterModifiable
LazyPutterModifiable(ByteQueue &bq, byte *inString, size_t size)
Construct a LazyPutterModifiable.
Definition: queue.h:257
NameValuePairs
Interface for retrieving values given their names.
Definition: cryptlib.h:327
LWORD_MAX
const lword LWORD_MAX
Large word type max value.
Definition: config_int.h:174
lword
word64 lword
Large word type.
Definition: config_int.h:168
cryptlib.h
Abstract base classes that provide a uniform interface to this library.
DEFAULT_CHANNEL
const std::string DEFAULT_CHANNEL
Default channel for BufferedTransformation.
Definition: cryptlib.h:516
CryptoPP
Crypto++ library namespace.
swap
void swap(::SecBlock< T, A > &a, ::SecBlock< T, A > &b)
Swap two SecBlocks.
Definition: secblock.h:1289
simple.h
Classes providing basic library services.
CRYPTOPP_ASSERT
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:68