ByteBuffer.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #ifndef _ByteBuffer_H_
  2. #define _ByteBuffer_H_
  3. // Default number of uint8_ts to allocate in the backing buffer if no size is provided
  4. #define BB_DEFAULT_SIZE 4096
  5. // If defined, utility functions within the class are enabled
  6. #define BB_UTILITY
  7. // If defined, places the class into a namespace called bb
  8. //#define BB_USE_NS
  9. #include <cstdlib>
  10. #include <cstdint>
  11. #include <cstring>
  12. #include <vector>
  13. #include <memory>
  14. #ifdef BB_UTILITY
  15. #include <iostream>
  16. #include <cstdio>
  17. #endif
  18. #ifdef BB_USE_NS
  19. namespace bb {
  20. #endif
  21. class ByteBuffer {
  22. public:
  23. ByteBuffer(uint32_t size = BB_DEFAULT_SIZE);
  24. ByteBuffer(uint8_t* arr, uint32_t size);
  25. ~ByteBuffer() {};
  26. uint32_t bytesRemaining(); // Number of uint8_ts from the current read position till the end of the buffer
  27. void clear(); // Clear our the vector and reset read and write positions
  28. ByteBuffer* clone(); // Return a new instance of a ByteBuffer with the exact same contents and the same state (rpos, wpos)
  29. //ByteBuffer compact(); // TODO?
  30. bool equals(ByteBuffer* other); // Compare if the contents are equivalent
  31. void resize(uint32_t newSize);
  32. uint32_t size(); // Size of internal vector
  33. // Basic Searching (Linear)
  34. template<typename T> int32_t find(T key, uint32_t start = 0) {
  35. int32_t ret = -1;
  36. uint32_t len = buf.size();
  37. for (uint32_t i = start; i < len; i++) {
  38. T data = read<T>(i);
  39. // Wasn't actually found, bounds of buffer were exceeded
  40. if ((key != 0) && (data == 0))
  41. break;
  42. // Key was found in array
  43. if (data == key) {
  44. ret = (int32_t) i;
  45. break;
  46. }
  47. }
  48. return ret;
  49. }
  50. // Replacement
  51. void replace(uint8_t key, uint8_t rep, uint32_t start = 0, bool firstOccuranceOnly = false);
  52. // Read
  53. uint8_t peek() const; // Relative peek. Reads and returns the next uint8_t in the buffer from the current position but does not increment the read position
  54. uint8_t get() const; // Relative get method. Reads the uint8_t at the buffers current position then increments the position
  55. uint8_t get(uint32_t index) const; // Absolute get method. Read uint8_t at index
  56. void getBytes(uint8_t* buf, uint32_t len) const; // Absolute read into array buf of length len
  57. char getChar() const; // Relative
  58. char getChar(uint32_t index) const; // Absolute
  59. double getDouble() const;
  60. double getDouble(uint32_t index) const;
  61. float getFloat() const;
  62. float getFloat(uint32_t index) const;
  63. uint32_t getInt() const;
  64. uint32_t getInt(uint32_t index) const;
  65. uint64_t getLong() const;
  66. uint64_t getLong(uint32_t index) const;
  67. uint16_t getShort() const;
  68. uint16_t getShort(uint32_t index) const;
  69. // Write
  70. void put(ByteBuffer* src); // Relative write of the entire contents of another ByteBuffer (src)
  71. void put(uint8_t b); // Relative write
  72. void put(uint8_t b, uint32_t index); // Absolute write at index
  73. void putBytes(uint8_t* b, uint32_t len); // Relative write
  74. void putBytes(uint8_t* b, uint32_t len, uint32_t index); // Absolute write starting at index
  75. void putChar(char value); // Relative
  76. void putChar(char value, uint32_t index); // Absolute
  77. void putDouble(double value);
  78. void putDouble(double value, uint32_t index);
  79. void putFloat(float value);
  80. void putFloat(float value, uint32_t index);
  81. void putInt(uint32_t value);
  82. void putInt(uint32_t value, uint32_t index);
  83. void putLong(uint64_t value);
  84. void putLong(uint64_t value, uint32_t index);
  85. void putShort(uint16_t value);
  86. void putShort(uint16_t value, uint32_t index);
  87. // Buffer Position Accessors & Mutators
  88. void setReadPos(uint32_t r) {
  89. rpos = r;
  90. }
  91. uint32_t getReadPos() const {
  92. return rpos;
  93. }
  94. void setWritePos(uint32_t w) {
  95. wpos = w;
  96. }
  97. uint32_t getWritePos() const {
  98. return wpos;
  99. }
  100. // Utility Functions
  101. #ifdef BB_UTILITY
  102. void setName(std::string n);
  103. std::string getName();
  104. void printInfo();
  105. void printAH();
  106. void printAscii();
  107. void printHex();
  108. void printPosition();
  109. #endif
  110. private:
  111. uint32_t wpos;
  112. mutable uint32_t rpos;
  113. std::vector<uint8_t> buf;
  114. #ifdef BB_UTILITY
  115. std::string name;
  116. #endif
  117. template<typename T> T read() const {
  118. T data = read<T>(rpos);
  119. rpos += sizeof(T);
  120. return data;
  121. }
  122. template<typename T> T read(uint32_t index) const {
  123. if (index + sizeof(T) <= buf.size())
  124. return *((T*) &buf[index]);
  125. return 0;
  126. }
  127. template<typename T> void append(T data) {
  128. uint32_t s = sizeof(data);
  129. if (size() < (wpos + s))
  130. buf.resize(wpos + s);
  131. memcpy(&buf[wpos], (uint8_t*) &data, s);
  132. //printf("writing %c to %i\n", (uint8_t)data, wpos);
  133. wpos += s;
  134. }
  135. template<typename T> void insert(T data, uint32_t index) {
  136. if ((index + sizeof(data)) > size())
  137. return;
  138. memcpy(&buf[index], (uint8_t*) &data, sizeof(data));
  139. wpos = index + sizeof(data);
  140. }
  141. };
  142. #ifdef BB_USE_NS
  143. }
  144. #endif
  145. #endif