1
0

hbuf.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. #ifndef HW_BUF_H_
  2. #define HW_BUF_H_
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include "hdef.h"
  7. typedef struct hbuf_s {
  8. uint8_t* base;
  9. size_t len;
  10. #ifdef __cplusplus
  11. hbuf_s() {
  12. base = NULL;
  13. len = 0;
  14. }
  15. hbuf_s(void* data, size_t len) {
  16. this->base = (uint8_t*)data;
  17. this->len = len;
  18. }
  19. #endif
  20. } hbuf_t;
  21. class HBuf : public hbuf_t {
  22. public:
  23. HBuf() : hbuf_t() {
  24. cleanup_ = false;
  25. }
  26. HBuf(void* data, size_t len) : hbuf_t(data, len) {
  27. cleanup_ = false;
  28. }
  29. HBuf(size_t cap) { resize(cap); }
  30. virtual ~HBuf() {
  31. cleanup();
  32. }
  33. void* data() { return base; }
  34. size_t size() { return len; }
  35. bool isNull() {
  36. return base == NULL || len == 0;
  37. }
  38. void cleanup() {
  39. if (cleanup_) {
  40. if (base) {
  41. free(base);
  42. base = NULL;
  43. }
  44. len = 0;
  45. cleanup_ = false;
  46. }
  47. }
  48. void resize(size_t cap) {
  49. if (cap == len) return;
  50. if (base == NULL) {
  51. base = (uint8_t*)malloc(cap);
  52. memset(base, 0, cap);
  53. }
  54. else {
  55. base = (uint8_t*)realloc(base, cap);
  56. }
  57. len = cap;
  58. cleanup_ = true;
  59. }
  60. void copy(void* data, size_t len) {
  61. resize(len);
  62. memcpy(base, data, len);
  63. }
  64. void copy(hbuf_t* buf) {
  65. copy(buf->base, buf->len);
  66. }
  67. private:
  68. bool cleanup_;
  69. };
  70. // VL: Variable-Length
  71. class HVLBuf : public HBuf {
  72. public:
  73. HVLBuf() : HBuf() {_offset = _size = 0;}
  74. HVLBuf(void* data, size_t len) : HBuf(data, len) {_offset = 0; _size = len;}
  75. HVLBuf(size_t cap) : HBuf(cap) {_offset = _size = 0;}
  76. virtual ~HVLBuf() {}
  77. uint8_t* data() { return base+_offset; }
  78. size_t size() { return _size; }
  79. void push_front(void* ptr, size_t len) {
  80. if (len > this->len - _size) {
  81. this->len = MAX(this->len, len)*2;
  82. base = (uint8_t*)realloc(base, this->len);
  83. }
  84. if (_offset < len) {
  85. // move => end
  86. memmove(base+this->len-_size, data(), _size);
  87. _offset = this->len-_size;
  88. }
  89. memcpy(data()-len, ptr, len);
  90. _offset -= len;
  91. _size += len;
  92. }
  93. void push_back(void* ptr, size_t len) {
  94. if (len > this->len - _size) {
  95. this->len = MAX(this->len, len)*2;
  96. base = (uint8_t*)realloc(base, this->len);
  97. }
  98. else if (len > this->len - _offset - _size) {
  99. // move => start
  100. memmove(base, data(), _size);
  101. _offset = 0;
  102. }
  103. memcpy(data()+_size, ptr, len);
  104. _size += len;
  105. }
  106. void pop_front(void* ptr, size_t len) {
  107. if (len <= _size) {
  108. if (ptr) {
  109. memcpy(ptr, data(), len);
  110. }
  111. _offset += len;
  112. if (_offset >= len) _offset = 0;
  113. _size -= len;
  114. }
  115. }
  116. void pop_back(void* ptr, size_t len) {
  117. if (len <= _size) {
  118. if (ptr) {
  119. memcpy(ptr, data()+_size-len, len);
  120. }
  121. _size -= len;
  122. }
  123. }
  124. void clear() {
  125. _offset = _size = 0;
  126. }
  127. void prepend(void* ptr, size_t len) {
  128. push_front(ptr, len);
  129. }
  130. void append(void* ptr, size_t len) {
  131. push_back(ptr, len);
  132. }
  133. void insert(void* ptr, size_t len) {
  134. push_back(ptr, len);
  135. }
  136. void remove(size_t len) {
  137. pop_front(NULL, len);
  138. }
  139. private:
  140. size_t _offset;
  141. size_t _size;
  142. };
  143. class HRingBuf : public HBuf {
  144. public:
  145. HRingBuf() : HBuf() {_head = _tail = _size = 0;}
  146. HRingBuf(size_t cap) : HBuf(cap) {_head = _tail = _size = 0;}
  147. virtual ~HRingBuf() {}
  148. uint8_t* alloc(size_t len) {
  149. uint8_t* ret = NULL;
  150. if (_head < _tail || _size == 0) {
  151. // [_tail, this->len) && [0, _head)
  152. if (this->len - _tail >= len) {
  153. ret = base + _tail;
  154. _tail += len;
  155. if (_tail == this->len) _tail = 0;
  156. }
  157. else if (_head >= len) {
  158. ret = base;
  159. _tail = len;
  160. }
  161. }
  162. else {
  163. // [_tail, _head)
  164. if (_head - _tail >= len) {
  165. ret = base + _tail;
  166. _tail += len;
  167. }
  168. }
  169. _size += ret ? len : 0;
  170. return ret;
  171. }
  172. void free(size_t len) {
  173. _size -= len;
  174. if (len <= this->len - _head) {
  175. _head += len;
  176. if (_head == this->len) _head = 0;
  177. }
  178. else {
  179. _head = len;
  180. }
  181. }
  182. size_t size() {return _size;}
  183. private:
  184. size_t _head;
  185. size_t _tail;
  186. size_t _size;
  187. };
  188. #endif // HW_BUF_H_