DS_ByteQueue.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*
  2. * Copyright (c) 2014, Oculus VR, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. #include "DS_ByteQueue.h"
  11. #include <string.h> // Memmove
  12. #include <stdlib.h> // realloc
  13. #include <stdio.h>
  14. using namespace DataStructures;
  15. ByteQueue::ByteQueue()
  16. {
  17. readOffset=writeOffset=lengthAllocated=0;
  18. data=0;
  19. }
  20. ByteQueue::~ByteQueue()
  21. {
  22. Clear(_FILE_AND_LINE_);
  23. }
  24. void ByteQueue::WriteBytes(const char *in, unsigned length, const char *file, unsigned int line)
  25. {
  26. unsigned bytesWritten;
  27. bytesWritten=GetBytesWritten();
  28. if (lengthAllocated==0 || length > lengthAllocated-bytesWritten-1)
  29. {
  30. unsigned oldLengthAllocated=lengthAllocated;
  31. // Always need to waste 1 byte for the math to work, else writeoffset==readoffset
  32. unsigned newAmountToAllocate=length+oldLengthAllocated+1;
  33. if (newAmountToAllocate<256)
  34. newAmountToAllocate=256;
  35. lengthAllocated=lengthAllocated + newAmountToAllocate;
  36. data=(char*)rakRealloc_Ex(data, lengthAllocated, file, line);
  37. if (writeOffset < readOffset)
  38. {
  39. if (writeOffset <= newAmountToAllocate)
  40. {
  41. memcpy(data + oldLengthAllocated, data, writeOffset);
  42. writeOffset=readOffset+bytesWritten;
  43. }
  44. else
  45. {
  46. memcpy(data + oldLengthAllocated, data, newAmountToAllocate);
  47. memmove(data, data+newAmountToAllocate, writeOffset-newAmountToAllocate);
  48. writeOffset-=newAmountToAllocate;
  49. }
  50. }
  51. }
  52. if (length <= lengthAllocated-writeOffset)
  53. memcpy(data+writeOffset, in, length);
  54. else
  55. {
  56. // Wrap
  57. memcpy(data+writeOffset, in, lengthAllocated-writeOffset);
  58. memcpy(data, in+(lengthAllocated-writeOffset), length-(lengthAllocated-writeOffset));
  59. }
  60. writeOffset=(writeOffset+length) % lengthAllocated;
  61. }
  62. bool ByteQueue::ReadBytes(char *out, unsigned maxLengthToRead, bool peek)
  63. {
  64. unsigned bytesWritten = GetBytesWritten();
  65. unsigned bytesToRead = bytesWritten < maxLengthToRead ? bytesWritten : maxLengthToRead;
  66. if (bytesToRead==0)
  67. return false;
  68. if (writeOffset>=readOffset)
  69. {
  70. memcpy(out, data+readOffset, bytesToRead);
  71. }
  72. else
  73. {
  74. unsigned availableUntilWrap = lengthAllocated-readOffset;
  75. if (bytesToRead <= availableUntilWrap)
  76. {
  77. memcpy(out, data+readOffset, bytesToRead);
  78. }
  79. else
  80. {
  81. memcpy(out, data+readOffset, availableUntilWrap);
  82. memcpy(out+availableUntilWrap, data, bytesToRead-availableUntilWrap);
  83. }
  84. }
  85. if (peek==false)
  86. IncrementReadOffset(bytesToRead);
  87. return true;
  88. }
  89. char* ByteQueue::PeekContiguousBytes(unsigned int *outLength) const
  90. {
  91. if (writeOffset>=readOffset)
  92. *outLength=writeOffset-readOffset;
  93. else
  94. *outLength=lengthAllocated-readOffset;
  95. return data+readOffset;
  96. }
  97. void ByteQueue::Clear(const char *file, unsigned int line)
  98. {
  99. if (lengthAllocated)
  100. rakFree_Ex(data, file, line );
  101. readOffset=writeOffset=lengthAllocated=0;
  102. data=0;
  103. }
  104. unsigned ByteQueue::GetBytesWritten(void) const
  105. {
  106. if (writeOffset>=readOffset)
  107. return writeOffset-readOffset;
  108. else
  109. return writeOffset+(lengthAllocated-readOffset);
  110. }
  111. void ByteQueue::IncrementReadOffset(unsigned length)
  112. {
  113. readOffset=(readOffset+length) % lengthAllocated;
  114. }
  115. void ByteQueue::DecrementReadOffset(unsigned length)
  116. {
  117. if (length>readOffset)
  118. readOffset=lengthAllocated-(length-readOffset);
  119. else
  120. readOffset-=length;
  121. }
  122. void ByteQueue::Print(void)
  123. {
  124. unsigned i;
  125. for (i=readOffset; i!=writeOffset; i++)
  126. RAKNET_DEBUG_PRINTF("%i ", data[i]);
  127. RAKNET_DEBUG_PRINTF("\n");
  128. }
粤ICP备19079148号