5#ifndef CRYPTOPP_IMPORTS
14static const unsigned int s_maxAutoNodeSize = 16*1024u;
20 ByteQueueNode(
size_t maxSize)
30 inline size_t MaxSize()
const {
return m_buf.size();}
32 inline size_t CurrentSize()
const
37 inline bool UsedUp()
const
39 return (m_head==MaxSize());
47 inline size_t Put(
const byte *begin,
size_t length)
50 if (!begin || !length)
return length;
51 size_t l =
STDMIN(length, MaxSize()-m_tail);
52 if (m_buf+m_tail != begin)
53 std::memcpy(m_buf+m_tail, begin, l);
58 inline size_t Peek(
byte &outByte)
const
63 outByte=m_buf[m_head];
67 inline size_t Peek(
byte *target,
size_t copyMax)
const
69 size_t len =
STDMIN(copyMax, m_tail-m_head);
70 std::memcpy(target, m_buf+m_head, len);
76 size_t len = m_tail-m_head;
83 size_t len =
STDMIN(copyMax, m_tail-m_head);
88 inline size_t Get(
byte &outByte)
90 size_t len = Peek(outByte);
95 inline size_t Get(
byte *outString,
size_t getMax)
97 size_t len = Peek(outString, getMax);
104 size_t len = m_tail-m_head;
112 size_t len =
UnsignedMin(m_tail-m_head, transferMax);
118 inline size_t Skip(
size_t skipMax)
120 size_t len =
STDMIN(skipMax, m_tail-m_head);
125 inline byte operator[](
size_t i)
const
127 return m_buf[m_head+i];
130 ByteQueueNode* m_next;
133 size_t m_head, m_tail;
140 , m_head(NULLPTR), m_tail(NULLPTR), m_lazyString(NULLPTR), m_lazyLength(0)
141 , m_nodeSize(nodeSize), m_lazyStringModifiable(false), m_autoNodeSize(!nodeSize)
146 SetNodeSize(nodeSize);
147 m_head = m_tail =
new ByteQueueNode(m_nodeSize);
152 m_autoNodeSize = !nodeSize;
153 m_nodeSize = m_autoNodeSize ? 256 : nodeSize;
162void ByteQueue::CopyFrom(
const ByteQueue ©)
165 m_autoNodeSize = copy.m_autoNodeSize;
166 m_nodeSize = copy.m_nodeSize;
167 m_head = m_tail =
new ByteQueueNode(*copy.m_head);
169 for (ByteQueueNode *current=copy.m_head->m_next; current; current=current->m_next)
171 m_tail->m_next =
new ByteQueueNode(*current);
172 m_tail = m_tail->m_next;
175 m_tail->m_next = NULLPTR;
177 Put(copy.m_lazyString, copy.m_lazyLength);
180ByteQueue::~ByteQueue()
185void ByteQueue::Destroy()
187 for (ByteQueueNode *next, *current=m_head; current; current=next)
189 next=current->m_next;
204 for (ByteQueueNode *current=m_head; current; current=current->m_next)
205 size += current->CurrentSize();
207 return size + m_lazyLength;
212 return m_head==m_tail && m_head->CurrentSize()==0 && m_lazyLength==0;
217 for (ByteQueueNode *next, *current=m_head->m_next; current; current=next)
219 next=current->m_next;
225 m_head->m_next = NULLPTR;
229size_t ByteQueue::Put2(
const byte *inString,
size_t length,
int messageEnd,
bool blocking)
231 CRYPTOPP_UNUSED(messageEnd), CRYPTOPP_UNUSED(blocking);
233 if (m_lazyLength > 0)
237 while ((len=m_tail->Put(inString, length)) < length)
239 inString =
PtrAdd(inString, len);
241 if (m_autoNodeSize && m_nodeSize < s_maxAutoNodeSize)
247 while (m_nodeSize < length && m_nodeSize < s_maxAutoNodeSize);
249 m_tail->m_next =
new ByteQueueNode(
STDMAX(m_nodeSize, length));
250 m_tail = m_tail->m_next;
256void ByteQueue::CleanupUsedNodes()
259 while (m_head && m_head != m_tail && m_head->UsedUp())
261 ByteQueueNode *temp=m_head;
262 m_head=m_head->m_next;
267 if (m_head && m_head->CurrentSize() == 0)
273 if (m_lazyLength > 0)
276 if (inString == m_tail->m_buf+m_tail->m_tail)
280 m_lazyString =
const_cast<byte *
>(inString);
282 m_lazyStringModifiable =
false;
288 if (m_lazyLength > 0)
290 m_lazyString = inString;
292 m_lazyStringModifiable =
true;
297 if (m_lazyLength < size)
298 throw InvalidArgument(
"ByteQueue: size specified for UndoLazyPut is too large");
300 m_lazyLength -= size;
305 size_t len = m_lazyLength;
308 Put(m_lazyString, len);
313 if (m_head->Get(outByte))
315 if (m_head->UsedUp())
319 else if (m_lazyLength > 0)
321 outByte = *m_lazyString++;
337 if (m_head->Peek(outByte))
339 else if (m_lazyLength > 0)
341 outByte = *m_lazyString;
351 return (
size_t)
CopyTo(sink, peekMax);
361 lword bytesLeft = transferBytes;
362 for (ByteQueueNode *current=m_head; bytesLeft && current; current=current->m_next)
363 bytesLeft -= current->TransferTo(target, bytesLeft, channel);
366 size_t len = (size_t)
STDMIN(bytesLeft, (
lword)m_lazyLength);
369 if (m_lazyStringModifiable)
372 target.
ChannelPut(channel, m_lazyString, len);
373 m_lazyString =
PtrAdd(m_lazyString, len);
377 transferBytes -= bytesLeft;
382 Walker walker(*
this);
383 size_t blockedBytes = walker.TransferTo2(target, transferBytes, channel, blocking);
391 Walker walker(*
this);
393 lword transferBytes = end-begin;
395 size_t blockedBytes = walker.TransferTo2(target, transferBytes, channel, blocking);
396 begin += transferBytes;
410 size_t len =
STDMIN(length, m_head->m_head);
412 m_head->m_head = m_head->m_head - len;
413 std::memcpy(m_head->m_buf + m_head->m_head, inString + length, len);
417 ByteQueueNode *newHead =
new ByteQueueNode(length);
418 newHead->m_next = m_head;
420 m_head->Put(inString, length);
426 contiguousSize = m_head->m_tail - m_head->m_head;
427 if (contiguousSize == 0 && m_lazyLength > 0)
429 contiguousSize = m_lazyLength;
433 return m_head->m_buf + m_head->m_head;
443 if (m_lazyLength > 0)
446 if (m_tail->m_tail == m_tail->MaxSize())
448 m_tail->m_next =
new ByteQueueNode(
STDMAX(m_nodeSize, size));
449 m_tail = m_tail->m_next;
452 size = m_tail->MaxSize() - m_tail->m_tail;
453 return PtrAdd(m_tail->m_buf.begin(), m_tail->m_tail);
470 Walker walker1(*
this), walker2(rhs);
473 while (walker1.Get(b1) && walker2.Get(b2))
482 for (ByteQueueNode *current=m_head; current; current=current->m_next)
485 return (*current)[(size_t)index];
487 index -= current->CurrentSize();
491 return m_lazyString[index];
496 std::swap(m_autoNodeSize, rhs.m_autoNodeSize);
497 std::swap(m_nodeSize, rhs.m_nodeSize);
498 std::swap(m_head, rhs.m_head);
499 std::swap(m_tail, rhs.m_tail);
500 std::swap(m_lazyString, rhs.m_lazyString);
501 std::swap(m_lazyLength, rhs.m_lazyLength);
502 std::swap(m_lazyStringModifiable, rhs.m_lazyStringModifiable);
509 CRYPTOPP_UNUSED(parameters);
511 m_node = m_queue.m_head;
514 m_lazyString = m_queue.m_lazyString;
515 m_lazyLength = m_queue.m_lazyLength;
533 return (
size_t)
CopyTo(sink, 1);
539 return (
size_t)
CopyTo(sink, peekMax);
547 lword bytesLeft = transferBytes;
548 size_t blockedBytes = 0;
552 size_t len = (size_t)
STDMIN(bytesLeft, (
lword)m_node->CurrentSize()-m_offset);
553 blockedBytes = target.
ChannelPut2(channel, m_node->m_buf+m_node->m_head+m_offset, len, 0, blocking);
567 m_node = m_node->m_next;
571 if (bytesLeft && m_lazyLength)
573 size_t len = (size_t)
STDMIN(bytesLeft, (
lword)m_lazyLength);
574 blockedBytes = target.
ChannelPut2(channel, m_lazyString, len, 0, blocking);
578 m_lazyString =
PtrAdd(m_lazyString, len);
584 transferBytes -= bytesLeft;
590 Walker walker(*
this);
592 lword transferBytes = end-begin;
594 size_t blockedBytes = walker.TransferTo2(target, transferBytes, channel, blocking);
595 begin += transferBytes;
Copy input to a memory buffer.
Base class for bufferless filters.
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.
size_t Peek(byte &outByte) const
Peek a 8-bit byte.
void IsolatedInitialize(const NameValuePairs ¶meters)
Initialize or reinitialize this object, without signal propagation.
Data structure used to store byte strings.
lword CurrentSize() const
Determine data size.
void LazyPut(const byte *inString, size_t size)
Insert data in the queue.
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 SetNodeSize(size_t nodeSize)
Set node size.
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.
ByteQueue & operator=(const ByteQueue &rhs)
Assign contents from another ByteQueue.
ByteQueue(size_t nodeSize=0)
Construct a ByteQueue.
void IsolatedInitialize(const NameValuePairs ¶meters)
Initialize or reinitialize this object, without signal propagation.
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.
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.
void swap(ByteQueue &rhs)
Swap contents with another ByteQueue.
byte * CreatePutSpace(size_t &size)
Request space which can be written into by the caller.
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.
const byte * Spy(size_t &contiguousSize) const
Peek data in the queue.
An invalid argument was detected.
Interface for retrieving values given their names.
CRYPTOPP_DLL int GetIntValueWithDefault(const char *name, int defaultValue) const
Get a named value with type int, with default.
word64 lword
Large word type.
const std::string DEFAULT_CHANNEL
Default channel for BufferedTransformation.
Implementation of BufferedTransformation's attachment interface.
Utility functions for the Crypto++ library.
const T & STDMAX(const T &a, const T &b)
Replacement function for std::max.
#define SIZE_MAX
The maximum value of a machine word.
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
PTR PtrAdd(PTR pointer, OFF offset)
Create a pointer with an offset.
const T1 UnsignedMin(const T1 &a, const T2 &b)
Safe comparison of values that could be negative and incorrectly promoted.
Crypto++ library namespace.
Classes for an unlimited queue to store bytes.
Debugging and diagnostic assertions.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.