hbuf.h 4.4 KB

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