Crypto++  8.8
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
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
133 
134  /// \brief Assign contents from another ByteQueue
135  /// \param rhs the other ByteQueue
136  /// \return reference to this ByteQueue
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 
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.
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
bool operator==(const OID &lhs, const OID &rhs)
Compare two OIDs for equality.
Interface for buffered transformations.
Definition: cryptlib.h:1657
Base class for bufferless filters.
Definition: simple.h:120
A ByteQueue iterator.
Definition: queue.h:165
size_t Peek(byte *outString, size_t peekMax) const
Peek a block of bytes.
size_t Get(byte &outByte)
Retrieve a 8-bit byte.
size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true)
Transfer bytes from this object to another BufferedTransformation.
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.
Walker(const ByteQueue &queue)
Construct a ByteQueue Walker.
Definition: queue.h:169
size_t Peek(byte &outByte) const
Peek a 8-bit byte.
lword MaxRetrievable() const
Provides the number of bytes ready for retrieval.
Definition: queue.h:175
size_t Get(byte *outString, size_t getMax)
Retrieve a block of bytes.
void IsolatedInitialize(const NameValuePairs &parameters)
Initialize or reinitialize this object, without signal propagation.
Data structure used to store byte strings.
Definition: queue.h:23
lword CurrentSize() const
Determine data size.
ByteQueue(const ByteQueue &copy)
Copy construct a ByteQueue.
const byte * Spy(size_t &contiguousSize) const
Peek data in the queue.
void LazyPut(const byte *inString, size_t size)
Insert data in the queue.
byte * CreatePutSpace(size_t &size)
Request space which can be written into by the caller.
size_t Get(byte &outByte)
Retrieve a 8-bit byte.
byte operator[](lword index) const
Retrieve data from the queue.
void Clear()
Empty the queue.
void Unget(const byte *inString, size_t length)
Insert data in the queue.
void SetNodeSize(size_t nodeSize)
Set node size.
ByteQueue & operator=(const ByteQueue &rhs)
Assign contents from another ByteQueue.
size_t Peek(byte &outByte) const
Peek a 8-bit byte.
bool operator==(const ByteQueue &rhs) const
Bitwise compare two ByteQueue.
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
void FinalizeLazyPut()
Insert data in the queue.
size_t Peek(byte *outString, size_t peekMax) const
Peek a block of bytes.
ByteQueue(size_t nodeSize=0)
Construct a ByteQueue.
void IsolatedInitialize(const NameValuePairs &parameters)
Initialize or reinitialize this object, without signal propagation.
size_t Get(byte *outString, size_t getMax)
Retrieve a block of bytes.
size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true)
Transfer bytes from this object to another BufferedTransformation.
void UndoLazyPut(size_t size)
Remove data from the queue.
lword MaxRetrievable() const
Provides the number of bytes ready for retrieval.
Definition: queue.h:40
void Unget(byte inByte)
Insert data in the queue.
bool IsEmpty() const
Determine data availability.
void LazyPutModifiable(byte *inString, size_t size)
Insert data in the queue.
bool operator!=(const ByteQueue &rhs) const
Bitwise compare two ByteQueue.
Definition: queue.h:151
void swap(ByteQueue &rhs)
Swap contents with another ByteQueue.
bool AnyRetrievable() const
Determines whether bytes are ready for retrieval.
Definition: queue.h:42
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.
Base class for all exceptions thrown by the library.
Definition: cryptlib.h:164
Base class for input rejecting filters.
Definition: simple.h:195
Helper class to finalize Puts on ByteQueue.
Definition: queue.h:219
LazyPutter(ByteQueue &bq, const byte *inString, size_t size)
Construct a LazyPutter.
Definition: queue.h:233
Helper class to finalize Puts on ByteQueue.
Definition: queue.h:248
LazyPutterModifiable(ByteQueue &bq, byte *inString, size_t size)
Construct a LazyPutterModifiable.
Definition: queue.h:257
Interface for retrieving values given their names.
Definition: cryptlib.h:327
const lword LWORD_MAX
Large word type max value.
Definition: config_int.h:174
word64 lword
Large word type.
Definition: config_int.h:168
Abstract base classes that provide a uniform interface to this library.
const std::string DEFAULT_CHANNEL
Default channel for BufferedTransformation.
Definition: cryptlib.h:516
Crypto++ library namespace.
void swap(::SecBlock< T, A > &a, ::SecBlock< T, A > &b)
Swap two SecBlocks.
Definition: secblock.h:1289
Classes providing basic library services.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:68