1
0

io_buf.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. #ifndef _in_buff_hpp_
  2. #define _in_buff_hpp_
  3. #include <stdint.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include "clock.h"
  7. struct buff_t
  8. {
  9. private:
  10. char*ptr_;
  11. int len_;
  12. int owner_;
  13. public:
  14. buff_t(const buff_t&);
  15. buff_t() :ptr_(0) ,len_(0) ,owner_(0)
  16. {
  17. }
  18. buff_t(char*ptr,int len,bool owner=false)
  19. :ptr_(ptr) ,len_(len) ,owner_(owner?1:0)
  20. {
  21. }
  22. char*ptr()const
  23. {
  24. return ptr_;
  25. }
  26. bool empty()const
  27. {
  28. return len_==0;
  29. }
  30. int size()const
  31. {
  32. return len_;
  33. }
  34. int len()const
  35. {
  36. return len_;
  37. }
  38. void set(int len)
  39. {
  40. len_=len;
  41. }
  42. void reset(void*ptr,int len,bool owner)
  43. {
  44. if(owner_) ::free(ptr_);
  45. ptr_=(char*)ptr;
  46. len_=len;
  47. owner_=owner?1:0;
  48. }
  49. void clear()
  50. {
  51. reset(0,0,0);
  52. }
  53. ~buff_t()
  54. {
  55. if(owner_)
  56. {
  57. ::free(ptr_);
  58. }
  59. }
  60. };
  61. struct buf_base
  62. {
  63. private:
  64. buf_base(const buf_base&);
  65. protected:
  66. char*m_base;
  67. int m_mask,m_size;
  68. int64_t m_ppos,m_gpos;
  69. public:
  70. buf_base(int size)
  71. {
  72. m_size=256;
  73. while(m_size<size)
  74. m_size<<=1;
  75. m_base=(char*)::malloc(m_size);
  76. m_mask=m_size-1;
  77. m_ppos=m_gpos=0;
  78. }
  79. void grow(int add_size)
  80. {
  81. int size=m_size;
  82. while(size<m_size+add_size)
  83. size<<=1;
  84. m_gpos=pos(m_gpos);
  85. m_ppos=pos(m_ppos);
  86. if(m_ppos<m_gpos)
  87. m_ppos+=size;
  88. m_base=(char*)::realloc(m_base,size);
  89. m_size=size;
  90. m_mask=m_size-1;
  91. }
  92. ~buf_base()
  93. {
  94. ::free(m_base);
  95. }
  96. int size()const
  97. {
  98. return m_size;
  99. }
  100. inline int pos(int64_t p)const
  101. {
  102. return (int)p&m_mask;
  103. }
  104. int len_data() const
  105. {
  106. return m_ppos-m_gpos;
  107. }
  108. int len_free() const
  109. {
  110. return size()-len_data();
  111. }
  112. int operator[](int i)const
  113. {
  114. if(i>len_data())
  115. return -1;
  116. return (int)(uint8_t)m_base[pos(i+m_gpos)];
  117. }
  118. uint8_t& operator[](int i)
  119. {
  120. return *(uint8_t*)&m_base[pos(i+m_gpos)];
  121. }
  122. };
  123. struct in_buff:buf_base
  124. {
  125. in_buff(int size)
  126. :buf_base(size)
  127. {
  128. }
  129. ~in_buff()
  130. {
  131. }
  132. buff_t alloc()
  133. {
  134. const int ppos=pos(m_ppos);
  135. const int gpos=pos(m_gpos);
  136. int len=gpos<=ppos ?size()-ppos :gpos-ppos;
  137. return len==0?buff_t(0,0):buff_t(m_base+ppos,len);
  138. }
  139. void commit(int len)
  140. {
  141. m_ppos+=len;
  142. }
  143. void free(int len)
  144. {
  145. m_gpos+=len;
  146. }
  147. buff_t peek()
  148. {
  149. const int ppos=pos(m_ppos);
  150. const int gpos=pos(m_gpos);
  151. return buff_t(m_base+gpos,gpos<=ppos?ppos-gpos:size()-gpos);
  152. }
  153. /*
  154. char*peek(char*buf,int len)
  155. {
  156. if(len>len_data())
  157. return 0;
  158. buff_t b=peek();
  159. if(b.len()>=len)
  160. return b.ptr();
  161. memcpy(buf,b.ptr(),b.len());
  162. memcpy(buf+b.len(),m_base,len-b.len());
  163. return buf;
  164. }
  165. */
  166. buff_t get(int len)
  167. {
  168. if(len>len_data())
  169. return buff_t(0,0);
  170. buff_t b=peek();
  171. if(b.len()>=len)
  172. {
  173. free(len);
  174. return b;
  175. }
  176. else
  177. {
  178. buff_t r ((char*)malloc(len),len,1);
  179. memcpy(r.ptr(),b.ptr(),b.len());
  180. memcpy(r.ptr()+b.len(),m_base,len-b.len());
  181. free(len);
  182. return r;
  183. }
  184. }
  185. buff_t get(const char*chim)
  186. {
  187. int len=find(chim);
  188. if(len==0)
  189. return buff_t();
  190. return get(len);
  191. }
  192. char*get(char *buf,int len)
  193. {
  194. if(len>len_data())
  195. return 0;
  196. buff_t b=peek();
  197. if(b.len()>=len)
  198. {
  199. memcpy(buf,b.ptr(),len);
  200. }
  201. else
  202. {
  203. memcpy(buf,b.ptr(),b.len());
  204. memcpy(buf+b.len(),m_base,len-b.len());
  205. }
  206. free(len);
  207. return buf;
  208. }
  209. void skip(int len)
  210. {
  211. free(len);
  212. }
  213. int find(const char*chim)const
  214. {
  215. int slen=strlen(chim);
  216. for(int64_t p=m_gpos;p<m_ppos;)
  217. {
  218. if(m_base[this->pos(p++)]!=chim[0])
  219. continue;
  220. int j=1;
  221. for(;j<slen;j++)
  222. {
  223. if(m_base[pos(p++)]!=chim[j])
  224. break;
  225. }
  226. if(j==slen)
  227. return p-m_gpos;
  228. }
  229. return 0;
  230. }
  231. };
  232. /*
  233. struct out_buff:buf_base
  234. {
  235. out_buff(int size)
  236. :buf_base(size)
  237. {
  238. }
  239. ~out_buff()
  240. {
  241. }
  242. bool push(const char*d,int len,unsigned time_out_ms=-1)
  243. {
  244. int counter=10000;
  245. zclock c;
  246. for(;;)
  247. {
  248. int64_t ppos=ztomic::load(&m_ppos);
  249. int64_t gpos=ztomic::load(&m_gpos);
  250. if(ppos-gpos+len>size()|| !ztomic::cas(&m_ppos,&ppos,ppos+len))
  251. {
  252. if(c.count_ms()>=time_out_ms)
  253. return false;
  254. counter=yield(counter);
  255. continue;
  256. }
  257. int p=pos(ppos);
  258. int c=p+len-size();
  259. if(c<=0)
  260. {
  261. memcpy(m_base+p,d,len);
  262. }
  263. else
  264. {
  265. memcpy(m_base+p,d,len-c);
  266. memcpy(m_base,d+len-c,c);
  267. }
  268. break;
  269. }
  270. return true;
  271. }
  272. void free(int len)
  273. {
  274. ztomic::fetch_add(&m_gpos,len);
  275. }
  276. char*peek(int*len)
  277. {
  278. const int p=pos(m_ppos);
  279. const int g=pos(m_gpos);
  280. *len=g<=p?p-g:size()-g;
  281. return m_base+g;
  282. }
  283. };
  284. */
  285. #endif