hbuf.h 4.4 KB

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