5 #ifndef CRYPTOPP_IMPORTS
13 static const unsigned int s_maxAutoNodeSize = 16*1024;
26 inline size_t MaxSize()
const {
return m_buf.
size();}
28 inline size_t CurrentSize()
const
33 inline bool UsedUp()
const
35 return (m_head==MaxSize());
43 inline size_t Put(
const byte *begin,
size_t length)
46 if (!begin || !length)
return length;
47 size_t l =
STDMIN(length, MaxSize()-m_tail);
48 if (m_buf+m_tail != begin)
49 memcpy(m_buf+m_tail, begin, l);
54 inline size_t Peek(
byte &outByte)
const
59 outByte=m_buf[m_head];
63 inline size_t Peek(
byte *target,
size_t copyMax)
const
65 size_t len =
STDMIN(copyMax, m_tail-m_head);
66 memcpy(target, m_buf+m_head, len);
72 size_t len = m_tail-m_head;
73 target.ChannelPut(channel, m_buf+m_head, len);
79 size_t len =
STDMIN(copyMax, m_tail-m_head);
80 target.ChannelPut(channel, m_buf+m_head, len);
84 inline size_t Get(
byte &outByte)
86 size_t len = Peek(outByte);
91 inline size_t Get(
byte *outString,
size_t getMax)
93 size_t len = Peek(outString, getMax);
100 size_t len = m_tail-m_head;
101 target.ChannelPutModifiable(channel, m_buf+m_head, len);
108 size_t len =
UnsignedMin(m_tail-m_head, transferMax);
109 target.ChannelPutModifiable(channel, m_buf+m_head, len);
114 inline size_t Skip(
size_t skipMax)
116 size_t len =
STDMIN(skipMax, m_tail-m_head);
121 inline byte operator[](
size_t i)
const
123 return m_buf[m_head+i];
129 size_t m_head, m_tail;
136 , m_head(NULLPTR), m_tail(NULLPTR), m_lazyString(NULLPTR), m_lazyLength(0), m_lazyStringModifiable(false)
138 SetNodeSize(nodeSize);
142 void ByteQueue::SetNodeSize(
size_t nodeSize)
144 m_autoNodeSize = !nodeSize;
145 m_nodeSize = m_autoNodeSize ? 256 : nodeSize;
154 void ByteQueue::CopyFrom(
const ByteQueue ©)
157 m_autoNodeSize = copy.m_autoNodeSize;
158 m_nodeSize = copy.m_nodeSize;
161 for (
ByteQueueNode *current=copy.m_head->m_next; current; current=current->m_next)
164 m_tail = m_tail->m_next;
167 m_tail->m_next = NULLPTR;
169 Put(copy.m_lazyString, copy.m_lazyLength);
172 ByteQueue::~ByteQueue()
177 void ByteQueue::Destroy()
179 for (
ByteQueueNode *next, *current=m_head; current; current=next)
181 next=current->m_next;
192 lword ByteQueue::CurrentSize()
const
196 for (
ByteQueueNode *current=m_head; current; current=current->m_next)
197 size += current->CurrentSize();
199 return size + m_lazyLength;
202 bool ByteQueue::IsEmpty()
const
204 return m_head==m_tail && m_head->CurrentSize()==0 && m_lazyLength==0;
207 void ByteQueue::Clear()
209 for (
ByteQueueNode *next, *current=m_head->m_next; current; current=next)
211 next=current->m_next;
217 m_head->m_next = NULLPTR;
221 size_t ByteQueue::Put2(
const byte *inString,
size_t length,
int messageEnd,
bool blocking)
223 CRYPTOPP_UNUSED(messageEnd), CRYPTOPP_UNUSED(blocking);
225 if (m_lazyLength > 0)
229 while ((len=m_tail->Put(inString, length)) < length)
231 inString =
PtrAdd(inString, len);
233 if (m_autoNodeSize && m_nodeSize < s_maxAutoNodeSize)
238 while (m_nodeSize < length && m_nodeSize < s_maxAutoNodeSize);
240 m_tail = m_tail->m_next;
246 void ByteQueue::CleanupUsedNodes()
249 while (m_head && m_head != m_tail && m_head->UsedUp())
252 m_head=m_head->m_next;
257 if (m_head && m_head->CurrentSize() == 0)
261 void ByteQueue::LazyPut(
const byte *inString,
size_t size)
263 if (m_lazyLength > 0)
266 if (inString == m_tail->m_buf+m_tail->m_tail)
270 m_lazyString =
const_cast<byte *
>(inString);
272 m_lazyStringModifiable =
false;
276 void ByteQueue::LazyPutModifiable(
byte *inString,
size_t size)
278 if (m_lazyLength > 0)
280 m_lazyString = inString;
282 m_lazyStringModifiable =
true;
285 void ByteQueue::UndoLazyPut(
size_t size)
287 if (m_lazyLength < size)
288 throw InvalidArgument(
"ByteQueue: size specified for UndoLazyPut is too large");
290 m_lazyLength -= size;
293 void ByteQueue::FinalizeLazyPut()
295 size_t len = m_lazyLength;
298 Put(m_lazyString, len);
303 if (m_head->Get(outByte))
305 if (m_head->UsedUp())
309 else if (m_lazyLength > 0)
311 outByte = *m_lazyString++;
327 if (m_head->Peek(outByte))
329 else if (m_lazyLength > 0)
331 outByte = *m_lazyString;
341 return (
size_t)
CopyTo(sink, peekMax);
348 lword bytesLeft = transferBytes;
349 for (
ByteQueueNode *current=m_head; bytesLeft && current; current=current->m_next)
350 bytesLeft -= current->TransferTo(target, bytesLeft, channel);
353 size_t len = (size_t)
STDMIN(bytesLeft, (lword)m_lazyLength);
356 if (m_lazyStringModifiable)
359 target.
ChannelPut(channel, m_lazyString, len);
360 m_lazyString =
PtrAdd(m_lazyString, len);
364 transferBytes -= bytesLeft;
370 size_t blockedBytes = walker.
TransferTo2(target, transferBytes, channel, blocking);
380 lword transferBytes = end-begin;
381 size_t blockedBytes = walker.
TransferTo2(target, transferBytes, channel, blocking);
382 begin += transferBytes;
386 void ByteQueue::Unget(
byte inByte)
391 void ByteQueue::Unget(
const byte *inString,
size_t length)
393 size_t len =
STDMIN(length, m_head->m_head);
395 m_head->m_head = m_head->m_head - len;
396 memcpy(m_head->m_buf + m_head->m_head, inString + length, len);
401 newHead->m_next = m_head;
403 m_head->Put(inString, length);
407 const byte * ByteQueue::Spy(
size_t &contiguousSize)
const
409 contiguousSize = m_head->m_tail - m_head->m_head;
410 if (contiguousSize == 0 && m_lazyLength > 0)
412 contiguousSize = m_lazyLength;
416 return m_head->m_buf + m_head->m_head;
421 if (m_lazyLength > 0)
424 if (m_tail->m_tail == m_tail->MaxSize())
427 m_tail = m_tail->m_next;
430 size = m_tail->MaxSize() - m_tail->m_tail;
431 return PtrAdd(m_tail->m_buf.
begin(), m_tail->m_tail);
441 bool ByteQueue::operator==(
const ByteQueue &rhs)
const
443 const lword currentSize = CurrentSize();
445 if (currentSize != rhs.CurrentSize())
448 Walker walker1(*
this), walker2(rhs);
451 while (walker1.Get(b1) && walker2.Get(b2))
458 byte ByteQueue::operator[](lword i)
const
460 for (
ByteQueueNode *current=m_head; current; current=current->m_next)
462 if (i < current->CurrentSize())
463 return (*current)[(size_t)i];
465 i -= current->CurrentSize();
469 return m_lazyString[i];
474 std::swap(m_autoNodeSize, rhs.m_autoNodeSize);
475 std::swap(m_nodeSize, rhs.m_nodeSize);
476 std::swap(m_head, rhs.m_head);
477 std::swap(m_tail, rhs.m_tail);
478 std::swap(m_lazyString, rhs.m_lazyString);
479 std::swap(m_lazyLength, rhs.m_lazyLength);
480 std::swap(m_lazyStringModifiable, rhs.m_lazyStringModifiable);
487 CRYPTOPP_UNUSED(parameters);
489 m_node = m_queue.m_head;
492 m_lazyString = m_queue.m_lazyString;
493 m_lazyLength = m_queue.m_lazyLength;
511 return (
size_t)
CopyTo(sink, 1);
517 return (
size_t)
CopyTo(sink, peekMax);
522 lword bytesLeft = transferBytes;
523 size_t blockedBytes = 0;
527 size_t len = (size_t)
STDMIN(bytesLeft, (lword)m_node->CurrentSize()-m_offset);
528 blockedBytes = target.
ChannelPut2(channel, m_node->m_buf+m_node->m_head+m_offset, len, 0, blocking);
542 m_node = m_node->m_next;
546 if (bytesLeft && m_lazyLength)
548 size_t len = (size_t)
STDMIN(bytesLeft, (lword)m_lazyLength);
549 blockedBytes = target.
ChannelPut2(channel, m_lazyString, len, 0, blocking);
553 m_lazyString =
PtrAdd(m_lazyString, len);
559 transferBytes -= bytesLeft;
567 lword transferBytes = end-begin;
568 size_t blockedBytes = walker.
TransferTo2(target, transferBytes, channel, blocking);
569 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.
size_t Get(byte &outByte)
Retrieve a 8-bit byte.
size_t Peek(byte &outByte) const
Peek a 8-bit byte.
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
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.
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.
An invalid argument was detected.
Interface for retrieving values given their names.
int GetIntValueWithDefault(const char *name, int defaultValue) const
Get a named value with type int, with default.
iterator begin()
Provides an iterator pointing to the first element in the memory block.
size_type size() const
Provides the count of elements in the SecBlock.
const std::string DEFAULT_CHANNEL
Default channel for BufferedTransformation.
Implementation of BufferedTransformation's attachment interface.
Utility functions for the Crypto++ library.
PTR PtrAdd(PTR pointer, OFF offset)
Create a pointer with an offset.
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
const T1 UnsignedMin(const T1 &a, const T2 &b)
Safe comparison of values that could be neagtive and incorrectly promoted.
const T & STDMAX(const T &a, const T &b)
Replacement function for std::max.
Crypto++ library namespace.
Classes for an unlimited queue to store bytes.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.