hbuf.h 5.1 KB

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