2
0

ChunkedDataBuffer.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. #include "ChunkedDataBuffer.h"
  2. #include "DataStream.h"
  3. USING_NS_BF;
  4. int Beefy::ChunkedDataBuffer::sBlocksAllocated = 0;
  5. /*static void Log(const char* fmt ...)
  6. {
  7. static FILE* fp = fopen("chunked_dbg.txt", "wb");
  8. va_list argList;
  9. va_start(argList, fmt);
  10. String aResult = vformat(fmt, argList);
  11. va_end(argList);
  12. fwrite(aResult.c_str(), 1, aResult.length(), fp);
  13. fflush(fp);
  14. }*/
  15. ChunkedDataBuffer::ChunkedDataBuffer()
  16. {
  17. mWriteCurAlloc = NULL;
  18. mWriteCurPtr = (uint8*)(intptr)ALLOC_SIZE;
  19. mReadCurAlloc = NULL;
  20. mReadCurPtr = (uint8*)(intptr)ALLOC_SIZE;
  21. mReadNextAlloc = mReadCurPtr;
  22. mReadPoolIdx = -1;
  23. mSize = 0;
  24. }
  25. ChunkedDataBuffer::~ChunkedDataBuffer()
  26. {
  27. Clear();
  28. }
  29. void ChunkedDataBuffer::InitFlatRef(void* ptr, int size)
  30. {
  31. mReadPoolIdx = 0;
  32. mReadCurPtr = (uint8*)ptr;
  33. mReadCurAlloc = mReadCurPtr;
  34. mReadNextAlloc = mReadCurPtr + size;
  35. }
  36. void ChunkedDataBuffer::Clear()
  37. {
  38. mWriteCurAlloc = NULL;
  39. mWriteCurPtr = (uint8*)(intptr)ALLOC_SIZE;
  40. mReadCurAlloc = NULL;
  41. mReadCurPtr = (uint8*)(intptr)ALLOC_SIZE;
  42. mReadNextAlloc = mReadCurPtr;
  43. mReadPoolIdx = -1;
  44. mSize = 0;
  45. for (auto ptr : mPools)
  46. {
  47. //Log("Free %p\n", ptr);
  48. free(ptr);
  49. sBlocksAllocated--;
  50. }
  51. mPools.Clear();
  52. }
  53. int ChunkedDataBuffer::GetSize()
  54. {
  55. //int calcSize = (int)(((mPools.mSize - 1) * ALLOC_SIZE) + (mWriteCurPtr - mWriteCurAlloc));
  56. //BF_ASSERT(calcSize == mSize);
  57. return mSize;
  58. }
  59. void ChunkedDataBuffer::GrowPool()
  60. {
  61. int curSize = (int)(mWriteCurPtr - mWriteCurAlloc);
  62. mWriteCurAlloc = (uint8*)malloc(ALLOC_SIZE);
  63. //Log("Alloc %p\n", mWriteCurAlloc);
  64. sBlocksAllocated++;
  65. memset(mWriteCurAlloc, 0, ALLOC_SIZE);
  66. mPools.push_back(mWriteCurAlloc);
  67. mWriteCurPtr = mWriteCurAlloc;
  68. }
  69. void ChunkedDataBuffer::Write(const void* data, int size)
  70. {
  71. while (mWriteCurPtr + size >= mWriteCurAlloc + ALLOC_SIZE)
  72. {
  73. int curSize = (int)((mWriteCurAlloc + ALLOC_SIZE) - mWriteCurPtr);
  74. if (curSize > 0)
  75. memcpy(mWriteCurPtr, data, curSize);
  76. GrowPool();
  77. data = (uint8*)data + curSize;
  78. size -= curSize;
  79. mSize += curSize;
  80. if (size == 0)
  81. break;
  82. }
  83. memcpy(mWriteCurPtr, data, size);
  84. mWriteCurPtr += size;
  85. mSize += size;
  86. }
  87. void ChunkedDataBuffer::Write(uint8 byte)
  88. {
  89. while (mWriteCurPtr == mWriteCurAlloc + ALLOC_SIZE)
  90. GrowPool();
  91. *(mWriteCurPtr++) = byte;
  92. mSize++;
  93. }
  94. void ChunkedDataBuffer::Write_2(uint16 val)
  95. {
  96. while (mWriteCurPtr + 2 > mWriteCurAlloc + ALLOC_SIZE)
  97. {
  98. Write((uint8*)&val, 2);
  99. return;
  100. }
  101. *(uint16*)mWriteCurPtr = val;
  102. mWriteCurPtr += 2;
  103. mSize += 2;
  104. }
  105. void ChunkedDataBuffer::Write_3(uint32 val)
  106. {
  107. while (mWriteCurPtr + 3 > mWriteCurAlloc + ALLOC_SIZE)
  108. {
  109. Write((uint8*)&val, 3);
  110. return;
  111. }
  112. *(uint32*)mWriteCurPtr = val;
  113. mWriteCurPtr += 3;
  114. mSize += 3;
  115. }
  116. void ChunkedDataBuffer::Write_4(uint32 val)
  117. {
  118. while (mWriteCurPtr + 4 > mWriteCurAlloc + ALLOC_SIZE)
  119. {
  120. Write((uint8*)&val, 4);
  121. return;
  122. }
  123. *(uint32*)mWriteCurPtr = val;
  124. mWriteCurPtr += 4;
  125. mSize += 4;
  126. }
  127. int ChunkedDataBuffer::GetReadPos()
  128. {
  129. return mReadPoolIdx * ALLOC_SIZE + (int)(mReadCurPtr - mReadCurAlloc);
  130. }
  131. void ChunkedDataBuffer::SetReadPos(int pos)
  132. {
  133. mReadPoolIdx = pos / ALLOC_SIZE;
  134. if (mReadPoolIdx < mPools.mSize)
  135. {
  136. mReadCurAlloc = mPools[mReadPoolIdx];
  137. mReadCurPtr = mReadCurAlloc + pos % ALLOC_SIZE;
  138. mReadNextAlloc = mReadCurPtr + ALLOC_SIZE;
  139. }
  140. else
  141. {
  142. // Place at end of last pool
  143. mReadPoolIdx = mPools.mSize - 1;
  144. mReadCurAlloc = mPools[mReadPoolIdx];
  145. mReadCurPtr = mReadCurAlloc + ALLOC_SIZE;
  146. mReadNextAlloc = mReadCurPtr;
  147. }
  148. }
  149. void ChunkedDataBuffer::NextReadPool()
  150. {
  151. mReadCurAlloc = mPools[++mReadPoolIdx];
  152. mReadCurPtr = mReadCurAlloc;
  153. mReadNextAlloc = mReadCurPtr + ALLOC_SIZE;
  154. }
  155. void ChunkedDataBuffer::Read(void* data, int size)
  156. {
  157. while (mReadCurPtr + size > mReadNextAlloc)
  158. {
  159. int curSize = (int)(mReadNextAlloc - mReadCurPtr);
  160. if (curSize > 0)
  161. memcpy(data, mReadCurPtr, curSize);
  162. NextReadPool();
  163. data = (uint8*)data + curSize;
  164. size -= curSize;
  165. }
  166. memcpy(data, mReadCurPtr, size);
  167. mReadCurPtr += size;
  168. }
  169. void* ChunkedDataBuffer::FastRead(void * data, int size)
  170. {
  171. // Fast case- no crossing chunk boundary
  172. if (mReadCurPtr + size <= mReadNextAlloc)
  173. {
  174. void* retVal = mReadCurPtr;
  175. mReadCurPtr += size;
  176. return retVal;
  177. }
  178. void* dataHead = data;
  179. while (mReadCurPtr + size > mReadNextAlloc)
  180. {
  181. int curSize = (int)(mReadNextAlloc - mReadCurPtr);
  182. if (curSize > 0)
  183. memcpy(data, mReadCurPtr, curSize);
  184. NextReadPool();
  185. data = (uint8*)data + curSize;
  186. size -= curSize;
  187. }
  188. memcpy(data, mReadCurPtr, size);
  189. mReadCurPtr += size;
  190. return dataHead;
  191. }
  192. uint8 ChunkedDataBuffer::Read()
  193. {
  194. if (mReadCurPtr == mReadNextAlloc)
  195. NextReadPool();
  196. return *(mReadCurPtr++);
  197. }
  198. void ChunkedDataBuffer::Read(DataStream& stream, int size)
  199. {
  200. while (mReadCurPtr + size > mReadNextAlloc)
  201. {
  202. int curSize = (int)(mReadNextAlloc - mReadCurPtr);
  203. if (curSize > 0)
  204. stream.Write(mReadCurPtr, curSize);
  205. NextReadPool();
  206. size -= curSize;
  207. }
  208. stream.Write(mReadCurPtr, size);
  209. mReadCurPtr += size;
  210. }