00001
00002
00003 #include "pch.h"
00004 #include "queue.h"
00005 #include "filters.h"
00006
00007 NAMESPACE_BEGIN(CryptoPP)
00008
00009
00010 class ByteQueueNode
00011 {
00012 public:
00013 ByteQueueNode(unsigned int maxSize)
00014 : buf(maxSize)
00015 {
00016 m_head = m_tail = 0;
00017 next = 0;
00018 }
00019
00020 inline unsigned int MaxSize() const {return buf.size;}
00021
00022 inline unsigned int CurrentSize() const
00023 {
00024 return m_tail-m_head;
00025 }
00026
00027 inline bool UsedUp() const
00028 {
00029 return (m_head==MaxSize());
00030 }
00031
00032 inline void Clear()
00033 {
00034 m_head = m_tail = 0;
00035 }
00036
00037 inline unsigned int Put(byte inByte)
00038 {
00039 if (MaxSize()==m_tail)
00040 return 0;
00041
00042 buf[m_tail++]=inByte;
00043 return 1;
00044 }
00045
00046 inline unsigned int Put(const byte *inString, unsigned int length)
00047 {
00048 unsigned int l = STDMIN(length, MaxSize()-m_tail);
00049 memcpy(buf+m_tail, inString, l);
00050 m_tail += l;
00051 return l;
00052 }
00053
00054 inline unsigned int Peek(byte &outByte) const
00055 {
00056 if (m_tail==m_head)
00057 return 0;
00058
00059 outByte=buf[m_head];
00060 return 1;
00061 }
00062
00063 inline unsigned int Peek(byte *target, unsigned int copyMax) const
00064 {
00065 unsigned int len = STDMIN(copyMax, m_tail-m_head);
00066 memcpy(target, buf+m_head, len);
00067 return len;
00068 }
00069
00070 inline unsigned int CopyTo(BufferedTransformation &target) const
00071 {
00072 unsigned int len = m_tail-m_head;
00073 target.Put(buf+m_head, len);
00074 return len;
00075 }
00076
00077 inline unsigned int CopyTo(BufferedTransformation &target, unsigned int copyMax) const
00078 {
00079 unsigned int len = STDMIN(copyMax, m_tail-m_head);
00080 target.Put(buf+m_head, len);
00081 return len;
00082 }
00083
00084 inline unsigned int Get(byte &outByte)
00085 {
00086 unsigned int len = Peek(outByte);
00087 m_head += len;
00088 return len;
00089 }
00090
00091 inline unsigned int Get(byte *outString, unsigned int getMax)
00092 {
00093 unsigned int len = Peek(outString, getMax);
00094 m_head += len;
00095 return len;
00096 }
00097
00098 inline unsigned int TransferTo(BufferedTransformation &target)
00099 {
00100 unsigned int len = CopyTo(target);
00101 m_head += len;
00102 return len;
00103 }
00104
00105 inline unsigned int TransferTo(BufferedTransformation &target, unsigned int transferMax)
00106 {
00107 unsigned int len = CopyTo(target, transferMax);
00108 m_head += len;
00109 return len;
00110 }
00111
00112 inline unsigned int Skip(unsigned int skipMax)
00113 {
00114 unsigned int len = STDMIN(skipMax, m_tail-m_head);
00115 m_head += len;
00116 return len;
00117 }
00118
00119 inline byte operator[](unsigned int i) const
00120 {
00121 return buf[m_head+i];
00122 }
00123
00124 ByteQueueNode *next;
00125
00126 SecByteBlock buf;
00127 unsigned int m_head, m_tail;
00128 };
00129
00130
00131
00132 ByteQueue::ByteQueue(unsigned int m_nodeSize)
00133 : m_nodeSize(m_nodeSize), m_lazyLength(0)
00134 {
00135 m_head = m_tail = new ByteQueueNode(m_nodeSize);
00136 }
00137
00138 ByteQueue::ByteQueue(const ByteQueue ©)
00139 {
00140 CopyFrom(copy);
00141 }
00142
00143 void ByteQueue::CopyFrom(const ByteQueue ©)
00144 {
00145 m_lazyLength = 0;
00146 m_nodeSize = copy.m_nodeSize;
00147 m_head = m_tail = new ByteQueueNode(*copy.m_head);
00148
00149 for (ByteQueueNode *current=copy.m_head->next; current; current=current->next)
00150 {
00151 m_tail->next = new ByteQueueNode(*current);
00152 m_tail = m_tail->next;
00153 }
00154
00155 m_tail->next = NULL;
00156
00157 Put(copy.m_lazyString, copy.m_lazyLength);
00158 }
00159
00160 ByteQueue::~ByteQueue()
00161 {
00162 Destroy();
00163 }
00164
00165 void ByteQueue::Destroy()
00166 {
00167 ByteQueueNode *next;
00168
00169 for (ByteQueueNode *current=m_head; current; current=next)
00170 {
00171 next=current->next;
00172 delete current;
00173 }
00174 }
00175
00176 unsigned long ByteQueue::CurrentSize() const
00177 {
00178 unsigned long size=0;
00179
00180 for (ByteQueueNode *current=m_head; current; current=current->next)
00181 size += current->CurrentSize();
00182
00183 return size + m_lazyLength;
00184 }
00185
00186 bool ByteQueue::IsEmpty() const
00187 {
00188 return m_head==m_tail && m_head->CurrentSize()==0 && m_lazyLength==0;
00189 }
00190
00191 void ByteQueue::Clear()
00192 {
00193 Destroy();
00194 m_head = m_tail = new ByteQueueNode(m_nodeSize);
00195 m_lazyLength = 0;
00196 }
00197
00198 void ByteQueue::Put(byte inByte)
00199 {
00200 if (m_lazyLength > 0)
00201 FinalizeLazyPut();
00202
00203 if (!m_tail->Put(inByte))
00204 {
00205 m_tail->next = new ByteQueueNode(m_nodeSize);
00206 m_tail = m_tail->next;
00207 m_tail->Put(inByte);
00208 }
00209 }
00210
00211 void ByteQueue::Put(const byte *inString, unsigned int length)
00212 {
00213 if (m_lazyLength > 0)
00214 FinalizeLazyPut();
00215
00216 unsigned int len;
00217 while ((len=m_tail->Put(inString, length)) < length)
00218 {
00219 m_tail->next = new ByteQueueNode(m_nodeSize);
00220 m_tail = m_tail->next;
00221 inString += len;
00222 length -= len;
00223 }
00224 }
00225
00226 void ByteQueue::CleanupUsedNodes()
00227 {
00228 while (m_head != m_tail && m_head->UsedUp())
00229 {
00230 ByteQueueNode *temp=m_head;
00231 m_head=m_head->next;
00232 delete temp;
00233 }
00234
00235 if (m_head->CurrentSize() == 0)
00236 m_head->Clear();
00237 }
00238
00239 void ByteQueue::LazyPut(const byte *inString, unsigned int size)
00240 {
00241 if (m_lazyLength > 0)
00242 FinalizeLazyPut();
00243 m_lazyString = inString;
00244 m_lazyLength = size;
00245 }
00246
00247 void ByteQueue::FinalizeLazyPut()
00248 {
00249 unsigned int len = m_lazyLength;
00250 m_lazyLength = 0;
00251 Put(m_lazyString, len);
00252 }
00253
00254 unsigned int ByteQueue::Get(byte &outByte)
00255 {
00256 if (m_head->Get(outByte))
00257 {
00258 if (m_head->UsedUp())
00259 CleanupUsedNodes();
00260 return 1;
00261 }
00262 else if (m_lazyLength > 0)
00263 {
00264 outByte = *m_lazyString++;
00265 m_lazyLength--;
00266 return 1;
00267 }
00268 else
00269 return 0;
00270 }
00271
00272 unsigned int ByteQueue::Get(byte *outString, unsigned int getMax)
00273 {
00274 ArraySink sink(outString, getMax);
00275 return TransferTo(sink, getMax);
00276 }
00277
00278 unsigned int ByteQueue::Peek(byte &outByte) const
00279 {
00280 if (m_head->Peek(outByte))
00281 return 1;
00282 else if (m_lazyLength > 0)
00283 {
00284 outByte = *m_lazyString;
00285 return 1;
00286 }
00287 else
00288 return 0;
00289 }
00290
00291 unsigned int ByteQueue::Peek(byte *outString, unsigned int peekMax) const
00292 {
00293 ArraySink sink(outString, peekMax);
00294 return CopyTo(sink, peekMax);
00295 }
00296
00297 unsigned long ByteQueue::Skip(unsigned long skipMax)
00298 {
00299 return TransferTo(g_bitBucket, skipMax);
00300 }
00301
00302 unsigned long ByteQueue::TransferTo(BufferedTransformation &target, unsigned long transferMax)
00303 {
00304 unsigned long bytesLeft = transferMax;
00305 for (ByteQueueNode *current=m_head; bytesLeft && current; current=current->next)
00306 bytesLeft -= current->TransferTo(target, bytesLeft);
00307 CleanupUsedNodes();
00308
00309 unsigned int len = (unsigned int)STDMIN(bytesLeft, (unsigned long)m_lazyLength);
00310 if (len)
00311 {
00312 target.Put(m_lazyString, len);
00313 m_lazyString += len;
00314 m_lazyLength -= len;
00315 bytesLeft -= len;
00316 }
00317 return transferMax - bytesLeft;
00318 }
00319
00320 unsigned long ByteQueue::CopyTo(BufferedTransformation &target, unsigned long copyMax) const
00321 {
00322 unsigned long bytesLeft = copyMax;
00323 for (ByteQueueNode *current=m_head; bytesLeft && current; current=current->next)
00324 bytesLeft -= current->CopyTo(target, bytesLeft);
00325 if (bytesLeft && m_lazyLength)
00326 {
00327 unsigned int len = (unsigned int)STDMIN(bytesLeft, (unsigned long)m_lazyLength);
00328 target.Put(m_lazyString, len);
00329 bytesLeft -= len;
00330 }
00331 return copyMax - bytesLeft;
00332 }
00333
00334 void ByteQueue::Unget(byte inByte)
00335 {
00336 Unget(&inByte, 1);
00337 }
00338
00339 void ByteQueue::Unget(const byte *inString, unsigned int length)
00340 {
00341 ByteQueueNode *newHead = new ByteQueueNode(length);
00342 newHead->next = m_head;
00343 m_head = newHead;
00344 m_head->Put(inString, length);
00345 }
00346
00347
00348
00349
00350
00351
00352
00353 const byte * ByteQueue::Spy(unsigned int &contiguousSize) const
00354 {
00355 contiguousSize = m_head->m_tail - m_head->m_head;
00356 if (contiguousSize == 0 && m_lazyLength > 0)
00357 {
00358 contiguousSize = m_lazyLength;
00359 return m_lazyString;
00360 }
00361 else
00362 return m_head->buf + m_head->m_head;
00363 }
00364
00365 byte * ByteQueue::MakeNewSpace(unsigned int &contiguousSize)
00366 {
00367 if (m_lazyLength > 0)
00368 FinalizeLazyPut();
00369
00370 if (m_tail->m_tail == m_tail->MaxSize())
00371 {
00372 m_tail->next = new ByteQueueNode(m_nodeSize);
00373 m_tail = m_tail->next;
00374 }
00375
00376 contiguousSize = m_tail->MaxSize() - m_tail->m_tail;
00377 return m_tail->buf + m_tail->m_tail;
00378 }
00379
00380 void ByteQueue::OccupyNewSpace(unsigned int size)
00381 {
00382 m_tail->m_tail += size;
00383 assert(m_tail->m_tail <= m_tail->MaxSize());
00384 }
00385
00386 ByteQueue & ByteQueue::operator=(const ByteQueue &rhs)
00387 {
00388 Destroy();
00389 CopyFrom(rhs);
00390 return *this;
00391 }
00392
00393 bool ByteQueue::operator==(const ByteQueue &rhs) const
00394 {
00395 const unsigned long currentSize = CurrentSize();
00396
00397 if (currentSize != rhs.CurrentSize())
00398 return false;
00399
00400 Walker walker1(*this), walker2(rhs);
00401 byte b1, b2;
00402
00403 while (walker1.Get(b1) && walker2.Get(b2))
00404 if (b1 != b2)
00405 return false;
00406
00407 return true;
00408 }
00409
00410 byte ByteQueue::operator[](unsigned long i) const
00411 {
00412 for (ByteQueueNode *current=m_head; current; current=current->next)
00413 {
00414 if (i < current->CurrentSize())
00415 return (*current)[i];
00416
00417 i -= current->CurrentSize();
00418 }
00419
00420 assert(i < m_lazyLength);
00421 return m_lazyString[i];
00422 }
00423
00424 void ByteQueue::swap(ByteQueue &rhs)
00425 {
00426 std::swap(m_nodeSize, rhs.m_nodeSize);
00427 std::swap(m_head, rhs.m_head);
00428 std::swap(m_tail, rhs.m_tail);
00429 std::swap(m_lazyString, rhs.m_lazyString);
00430 std::swap(m_lazyLength, rhs.m_lazyLength);
00431 }
00432
00433
00434
00435 unsigned int ByteQueue::Walker::Get(byte &outByte)
00436 {
00437 ArraySink sink(&outByte, 1);
00438 return TransferTo(sink, 1);
00439 }
00440
00441 unsigned int ByteQueue::Walker::Get(byte *outString, unsigned int getMax)
00442 {
00443 ArraySink sink(outString, getMax);
00444 return TransferTo(sink, getMax);
00445 }
00446
00447 unsigned int ByteQueue::Walker::Peek(byte &outByte) const
00448 {
00449 ArraySink sink(&outByte, 1);
00450 return CopyTo(sink, 1);
00451 }
00452
00453 unsigned int ByteQueue::Walker::Peek(byte *outString, unsigned int peekMax) const
00454 {
00455 ArraySink sink(outString, peekMax);
00456 return CopyTo(sink, peekMax);
00457 }
00458
00459 unsigned long ByteQueue::Walker::TransferTo(BufferedTransformation &target, unsigned long transferMax)
00460 {
00461 unsigned long bytesLeft = transferMax;
00462 while (m_node)
00463 {
00464 unsigned int len = STDMIN(bytesLeft, (unsigned long)m_node->CurrentSize()-m_offset);
00465 target.Put(m_node->buf+m_node->m_head+m_offset, len);
00466 m_position += len;
00467 bytesLeft -= len;
00468
00469 if (!bytesLeft)
00470 {
00471 m_offset += len;
00472 break;
00473 }
00474
00475 m_node = m_node->next;
00476 m_offset = 0;
00477 }
00478
00479 unsigned int len = (unsigned int)STDMIN(bytesLeft, (unsigned long)m_lazyLength);
00480 if (len)
00481 {
00482 target.Put(m_lazyString, len);
00483 m_lazyString += len;
00484 m_lazyLength -= len;
00485 bytesLeft -= len;
00486 }
00487 return transferMax - bytesLeft;
00488 }
00489
00490 unsigned long ByteQueue::Walker::Skip(unsigned long skipMax)
00491 {
00492 return TransferTo(g_bitBucket, skipMax);
00493 }
00494
00495 unsigned long ByteQueue::Walker::CopyTo(BufferedTransformation &target, unsigned long copyMax) const
00496 {
00497 return Walker(*this).TransferTo(target, copyMax);
00498 }
00499
00500 NAMESPACE_END