hbuf.h 5.3 KB

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