hbuf.h 4.4 KB

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