hbuf.h 5.0 KB

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