/src/Common/bytebuffer.cpp

https://github.com/brookerk/mmoserver · C++ · 388 lines · 324 code · 3 blank · 61 comment · 25 complexity · a2ec06cfe4c4357e7a5577f12cc96473 MD5 · raw file

  1. //
  2. //bytebuffer.CPP
  3. //
  4. //Copyright(C) 2006 Eric Dyoniziak
  5. //
  6. // This code is used to create a dynamic buffer for reading and writing binary
  7. // data. It has pre-built read and write functions for making specific operations
  8. // needed for packet creation in SWG, however it is easily expandable for
  9. // any generic data type and for any situation where data serialization is needed.
  10. //
  11. // This program is free software; you can redistribute it and/or modify
  12. // it freely. You must however leave this copyright notice in its original form.
  13. //
  14. // This program is distributed in the hope that it will be useful, but
  15. // WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17. //
  18. #include "bytebuffer.h"
  19. #include <iostream>
  20. #include <cstring>
  21. #include <cstdlib>
  22. //-------------------------------------------------------------------------------------------------------------------
  23. bytebuffer::bytebuffer()
  24. {
  25. _ReadPos = 0;
  26. _WritePos = 0;
  27. _bincount = 0;
  28. _buffer = new char[DATA_RESERVE];
  29. _ptrbin = new char*[PTR_BIN_SIZE];
  30. _bincapacity = PTR_BIN_SIZE;
  31. _capacity = DATA_RESERVE;
  32. }
  33. //-------------------------------------------------------------------------------------------------------------------
  34. bytebuffer::~bytebuffer()
  35. {
  36. cleanGarbage();
  37. delete [] _buffer;
  38. delete [] _ptrbin;
  39. }
  40. //-------------------------------------------------------------------------------------------------------------------
  41. unsigned int bytebuffer::getSize()
  42. {
  43. return _WritePos;
  44. }
  45. //-------------------------------------------------------------------------------------------------------------------
  46. char* bytebuffer::getBuffer()
  47. {
  48. char* ret = createArray(_WritePos);
  49. memcpy(ret,_buffer,_WritePos);
  50. return ret;
  51. }
  52. //-------------------------------------------------------------------------------------------------------------------
  53. unsigned char bytebuffer::readBYTE()
  54. {
  55. return read<unsigned char>();
  56. }
  57. //-------------------------------------------------------------------------------------------------------------------
  58. unsigned short bytebuffer::readSHORT()
  59. {
  60. return read<unsigned short>();
  61. }
  62. //-------------------------------------------------------------------------------------------------------------------
  63. unsigned int bytebuffer::readINT()
  64. {
  65. return read<unsigned int>();
  66. }
  67. //-------------------------------------------------------------------------------------------------------------------
  68. unsigned long long bytebuffer::readLONG()
  69. {
  70. return read<unsigned long long>();
  71. }
  72. //-------------------------------------------------------------------------------------------------------------------
  73. float bytebuffer::readFLOAT()
  74. {
  75. return read<float>();
  76. }
  77. //-------------------------------------------------------------------------------------------------------------------
  78. char* bytebuffer::readASTRING()
  79. {
  80. unsigned short size = readSHORT();
  81. char* ret = createArray(size+1);
  82. readDATA(ret,size);
  83. ret[size] = 0;
  84. return ret;
  85. }
  86. //-------------------------------------------------------------------------------------------------------------------
  87. wchar_t* bytebuffer::readASTRINGtoUNICODE()
  88. {
  89. unsigned short size = readSHORT();
  90. char* tempArray = new char[size];
  91. readDATA(tempArray,size);
  92. wchar_t* ret = (wchar_t*)createArray(size * 2 +2);
  93. ascii_to_unicode(ret,tempArray,size);
  94. delete [] tempArray;
  95. ret[size] = 0;
  96. return ret;
  97. }
  98. //-------------------------------------------------------------------------------------------------------------------
  99. char* bytebuffer::readUSTRINGtoASCII()
  100. {
  101. unsigned int size = readINT();
  102. wchar_t* tempArray = new wchar_t[size];
  103. readDATA((char*)tempArray,size * 2);
  104. char* ret = createArray(size + 1);
  105. unicode_to_ascii(ret,tempArray,size);
  106. delete [] tempArray;
  107. ret[size] = 0;
  108. return ret;
  109. }
  110. //-------------------------------------------------------------------------------------------------------------------
  111. wchar_t* bytebuffer::readUSTRING()
  112. {
  113. unsigned int size = readINT();
  114. wchar_t* ret = (wchar_t*)createArray(size * 2 + 2);
  115. readDATA((char*)ret,size * 2);
  116. ret[size] = 0;
  117. return ret;
  118. }
  119. //-------------------------------------------------------------------------------------------------------------------
  120. void bytebuffer::readDATA(char *data,unsigned int length)
  121. {
  122. if((_ReadPos + length) > _WritePos)
  123. {
  124. std::cout << "Fatal Error[0]: Read Beyond End of Buffer.\nPress Enter to Close Program...";
  125. std::cin.get();
  126. exit(1);
  127. }
  128. else
  129. {
  130. for(unsigned int i = 0;i < length;i++)
  131. {
  132. data[i] = _buffer[_ReadPos];
  133. _ReadPos++;
  134. }
  135. }
  136. }
  137. //-------------------------------------------------------------------------------------------------------------------
  138. void bytebuffer::writeBYTE(unsigned char data)
  139. {
  140. append<unsigned char>(data);
  141. }
  142. //-------------------------------------------------------------------------------------------------------------------
  143. void bytebuffer::writeSHORT(unsigned short data)
  144. {
  145. append<unsigned short>(data);
  146. }
  147. //-------------------------------------------------------------------------------------------------------------------
  148. void bytebuffer::writeINT(unsigned int data)
  149. {
  150. append<unsigned int>(data);
  151. }
  152. //-------------------------------------------------------------------------------------------------------------------
  153. void bytebuffer::writeLONG(unsigned long long data)
  154. {
  155. append<unsigned long long>(data);
  156. }
  157. //-------------------------------------------------------------------------------------------------------------------
  158. void bytebuffer::writeFLOAT(float data)
  159. {
  160. append<float>(data);
  161. }
  162. //-------------------------------------------------------------------------------------------------------------------
  163. void bytebuffer::writeASTRING(const char* string)
  164. {
  165. unsigned int size;
  166. for(size = 0;string[size] != '\0';size++)
  167. ;
  168. writeSHORT(size);
  169. writeDATA(string,size);
  170. }
  171. //-------------------------------------------------------------------------------------------------------------------
  172. void bytebuffer::writeASTRING(const wchar_t* string)
  173. {
  174. unsigned int size;
  175. for(size = 0;string[size] != 0;size++)
  176. ;
  177. char* new_string = new char[size];
  178. unicode_to_ascii(new_string,string,size);
  179. writeSHORT(size);
  180. writeDATA(new_string,size);
  181. delete [] new_string;
  182. }
  183. //-------------------------------------------------------------------------------------------------------------------
  184. void bytebuffer::writeUSTRING(const char* string)
  185. {
  186. unsigned int size;
  187. for(size = 0;string[size] != '\0';size++)
  188. ;
  189. wchar_t* new_string = new wchar_t[size];
  190. ascii_to_unicode(new_string,string,size);
  191. writeINT(size);
  192. writeDATA((char*)new_string,size *2);
  193. delete [] new_string;
  194. }
  195. //-------------------------------------------------------------------------------------------------------------------
  196. void bytebuffer::writeUSTRING(const wchar_t* string)
  197. {
  198. unsigned int size;
  199. for(size = 0;string[size] != 0;size++)
  200. ;
  201. writeINT(size);
  202. writeDATA((char*)string,size *2);
  203. }
  204. //-------------------------------------------------------------------------------------------------------------------
  205. void bytebuffer::writeDATA(const char *nData,unsigned int nLength)
  206. {
  207. while(_WritePos + nLength > _capacity)
  208. resize(_capacity * 3);
  209. for(unsigned int i = 0;i < nLength;i++)
  210. {
  211. _buffer[_WritePos] = nData[i];
  212. _WritePos++;
  213. }
  214. }
  215. //-------------------------------------------------------------------------------------------------------------------
  216. template <typename T>
  217. T bytebuffer::read()
  218. {
  219. unsigned int Tsize = sizeof(T);
  220. if(_ReadPos + Tsize > _WritePos)
  221. {
  222. std::cout << "Fatal Error[1]: Read Beyond End of Buffer.\nPress Enter to Close Program...";
  223. std::cin.get();
  224. exit(1);
  225. }
  226. else
  227. {
  228. T ret = *((T*)&_buffer[_ReadPos]);
  229. _ReadPos += Tsize;
  230. return ret;
  231. }
  232. }
  233. //-------------------------------------------------------------------------------------------------------------------
  234. template <typename T>
  235. void bytebuffer::append(T value)
  236. {
  237. unsigned int Tsize = sizeof(T);
  238. while(_WritePos + Tsize > _capacity)
  239. resize(_capacity * 3);
  240. *(T*)(&_buffer[_WritePos]) = value;
  241. _WritePos+= Tsize;
  242. }
  243. //-------------------------------------------------------------------------------------------------------------------
  244. template <typename T>
  245. T bytebuffer::peek()
  246. {
  247. unsigned int Tsize = sizeof(T);
  248. if(_ReadPos + Tsize > _WritePos)
  249. {
  250. std::cout << "Fatal Error: Read Beyond End of Buffer.\nPress Enter to Close Program...";
  251. std::cin.get();
  252. exit(1);
  253. }
  254. else
  255. {
  256. T ret = *((T*)&_buffer[_ReadPos]);
  257. return ret;
  258. }
  259. }
  260. //-------------------------------------------------------------------------------------------------------------------
  261. void bytebuffer::ascii_to_unicode(wchar_t *destination,const char *source, int length)
  262. {
  263. for(int i=0; i < length; i++)
  264. destination[i] = source[i];
  265. }
  266. //-------------------------------------------------------------------------------------------------------------------
  267. void bytebuffer::unicode_to_ascii(char *destination,const wchar_t *source, int length)
  268. {
  269. for(int i=0; i < length; i++)
  270. destination[i] = static_cast<char>(source[i]);
  271. }
  272. //-------------------------------------------------------------------------------------------------------------------
  273. void bytebuffer::writeBUFFER(bytebuffer &data)
  274. {
  275. writeDATA(data.getBuffer(),data.getSize());
  276. }
  277. //-------------------------------------------------------------------------------------------------------------------
  278. void bytebuffer::writeBUFFER(bytebuffer *data)
  279. {
  280. writeDATA(data->getBuffer(),data->getSize());
  281. }
  282. //-------------------------------------------------------------------------------------------------------------------
  283. void bytebuffer::cleanGarbage()
  284. {
  285. if(_bincount)
  286. {
  287. for(unsigned int i = 0;i < _bincount;i++)
  288. delete [] _ptrbin[i];
  289. _bincount = 0;
  290. }
  291. }
  292. //-------------------------------------------------------------------------------------------------------------------
  293. char* bytebuffer::createArray(unsigned int size)
  294. {
  295. if(_bincount == _bincapacity)
  296. {
  297. char **new_buffer = new char*[_bincapacity * 3];
  298. _bincapacity *= 3;
  299. for(unsigned int i=0;i < _bincount;i++)
  300. new_buffer[i] = _ptrbin[i];
  301. delete [] _ptrbin;
  302. _ptrbin= new_buffer;
  303. }
  304. _ptrbin[_bincount] = new char[size];
  305. _bincount++;
  306. return _ptrbin[_bincount-1];
  307. }
  308. //-------------------------------------------------------------------------------------------------------------------
  309. void bytebuffer::resize(unsigned int size)
  310. {
  311. if(size <= _capacity)
  312. {
  313. std::cout << "Error: Cannot resize bytebuffer when current buffer is greater than or equal to new size.\nPress Enter to Close Program...";
  314. std::cin.get();
  315. exit(1);
  316. }
  317. char *new_buffer = new char[size];
  318. _capacity = size;
  319. for(unsigned int i=0;i < _WritePos;i++)
  320. {
  321. new_buffer[i] = _buffer[i];
  322. }
  323. delete [] _buffer;
  324. _buffer = new_buffer;
  325. }
  326. //-------------------------------------------------------------------------------------------------------------------
  327. char bytebuffer::peekBYTE()
  328. {
  329. return peek<char>();
  330. }
  331. //-------------------------------------------------------------------------------------------------------------------
  332. unsigned short bytebuffer::peekSHORT()
  333. {
  334. return peek<unsigned short>();
  335. }
  336. //-------------------------------------------------------------------------------------------------------------------
  337. unsigned int bytebuffer::peekINT()
  338. {
  339. return peek<unsigned int>();
  340. }
  341. //-------------------------------------------------------------------------------------------------------------------
  342. unsigned long long bytebuffer::peekLONG()
  343. {
  344. return peek<unsigned long long>();
  345. }
  346. //-------------------------------------------------------------------------------------------------------------------
  347. char &bytebuffer::operator[](int index)
  348. {
  349. return _buffer[index];
  350. }
  351. //-------------------------------------------------------------------------------------------------------------------
  352. unsigned int bytebuffer::getBytesLeft()
  353. {
  354. return _WritePos - _ReadPos;
  355. }
  356. //-------------------------------------------------------------------------------------------------------------------
  357. void bytebuffer::popBytes(unsigned int size)
  358. {
  359. if(size <= _WritePos)
  360. _WritePos -= size;
  361. else
  362. {
  363. std::cout << "Error: Could not execute popBytes(). removal size was greater than current size.\n";
  364. std::cin.get();
  365. exit(1);
  366. }
  367. }
  368. //-------------------------------------------------------------------------------------------------------------------
  369. char* bytebuffer::getBufferLeft()
  370. {
  371. unsigned int size = _WritePos - _ReadPos;
  372. char* ret = createArray(size);
  373. memcpy(ret,_buffer+_ReadPos,size);
  374. return ret;
  375. }
  376. //-------------------------------------------------------------------------------------------------------------------
  377. void bytebuffer::clear()
  378. {
  379. delete [] _buffer;
  380. _ReadPos = 0;
  381. _WritePos = 0;
  382. _buffer = new char[DATA_RESERVE];
  383. _capacity = DATA_RESERVE;
  384. }
  385. //-------------------------------------------------------------------------------------------------------------------