诸暨麻将添加redis
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 
 
 
 
 

327 рядки
7.8 KiB

  1. // ***********************************************************************
  2. // Filename : ByteBuffer.h
  3. // Author : LIZHENG
  4. // Created : 2014-11-04
  5. // Description :
  6. //
  7. // Copyright (c) lizhenghn@gmail.com. All rights reserved.
  8. // ***********************************************************************
  9. #ifndef ZL_NETBUFFER_H
  10. #define ZL_NETBUFFER_H
  11. //#include "Define.h"
  12. //#include "zlreactor/NetUtil.h"
  13. #include <assert.h>
  14. #include <string>
  15. #include <vector>
  16. #include <algorithm>
  17. namespace zl
  18. {
  19. namespace net{
  20. /// A buffer class modeled after org.jboss.netty.buffer.ChannelBuffer
  21. /// see http://blog.csdn.net/solstice/article/details/6329080
  22. /// @code
  23. /// +-------------------+------------------+------------------+
  24. /// | prependable bytes | readable bytes | writable bytes |
  25. /// | | (CONTENT) | |
  26. /// +-------------------+------------------+------------------+
  27. /// | | | |
  28. /// 0 <= readerIndex <= writerIndex <= size
  29. /// @endcode
  30. class ByteBuffer
  31. {
  32. public:
  33. static const size_t kCheapPrepend = 8;
  34. static const size_t kInitialSize = 1024;
  35. public:
  36. ByteBuffer()
  37. : readerIndex_(kCheapPrepend)
  38. , writerIndex_(kCheapPrepend)
  39. , buffer_(kCheapPrepend + kInitialSize)
  40. {
  41. assert(readableBytes() == 0);
  42. assert(writableBytes() == kInitialSize);
  43. assert(prependableBytes() == kCheapPrepend);
  44. }
  45. size_t readableBytes() const
  46. {
  47. return writerIndex_ - readerIndex_;
  48. }
  49. size_t writableBytes() const
  50. {
  51. return buffer_.size() - writerIndex_;
  52. }
  53. size_t prependableBytes() const
  54. {
  55. return readerIndex_;
  56. }
  57. std::string toString() const
  58. {
  59. return std::string(peek(), static_cast<int>(readableBytes()));
  60. }
  61. public: // Data Write & Read
  62. void write(const std::string& str)
  63. {
  64. write(str.data(), str.size());
  65. }
  66. void write(const char* data)
  67. {
  68. write(data, strlen(data));
  69. }
  70. void write(const char* data, size_t len)
  71. {
  72. ensureWritableBytes(len);
  73. char* begin = beginWrite();
  74. for (size_t i = 0; i < len; i++)
  75. begin[i] = data[i];
  76. //std::copy(data, data+len, beginWrite());
  77. hasWritten(len);
  78. }
  79. void write(const void* data, size_t len)
  80. {
  81. write(static_cast<const char*>(data), len);
  82. }
  83. /// write Number using network endian
  84. /// Number == bool\int8_t\int16_t\int32_t\int64_t\float\double\....
  85. template <typename Number>
  86. void write(Number num)
  87. {
  88. Number nnum = NetUtil::host2Net(num);
  89. write(&nnum, sizeof(nnum));
  90. }
  91. /// return Number using host endian
  92. /// Number == bool\int8_t\int16_t\int32_t\int64_t\float\double\....
  93. /// Require: readableBytes() >= sizeof(Number)
  94. template <typename Number>
  95. Number read()
  96. {
  97. Number nnum = peek<Number>();
  98. retrieve(sizeof(nnum));
  99. return nnum;
  100. }
  101. /// peek number using host endian
  102. /// Number == bool\int8_t\int16_t\int32_t\int64_t\float\double\....
  103. /// Require: readableBytes() >= sizeof(Number)
  104. template <typename Number>
  105. Number peek() const
  106. {
  107. assert(readableBytes() >= sizeof(Number));
  108. Number nnum = 0;
  109. ::memcpy(&nnum, peek(), sizeof(nnum));
  110. return NetUtil::net2Host(nnum);
  111. }
  112. /// prepend number using network endian
  113. /// Number = int8_t\int16_t\int32_t\int64_t\...
  114. template <typename Number>
  115. void prepend(Number num)
  116. {
  117. Number nnum = NetUtil::host2Net(num);
  118. prepend(&nnum, sizeof(nnum));
  119. }
  120. //void prepend(const void* data, size_t len)
  121. //{
  122. // assert(len <= prependableBytes());
  123. // readerIndex_ -= len;
  124. // const char* d = static_cast<const char*>(data);
  125. // std::copy(d, d+len, begin()+readerIndex_);
  126. //}
  127. void retrieve(size_t len)
  128. {
  129. assert(len <= readableBytes());
  130. if (len < readableBytes())
  131. {
  132. readerIndex_ += len;
  133. }
  134. else
  135. {
  136. retrieveAll();
  137. }
  138. }
  139. template <typename Number>
  140. void retrieve()
  141. {
  142. retrieve(sizeof(Number));
  143. }
  144. void retrieveUntil(const char* end)
  145. {
  146. assert(peek() <= end);
  147. assert(end <= beginWrite());
  148. retrieve(end - peek());
  149. }
  150. void retrieveAll()
  151. {
  152. readerIndex_ = kCheapPrepend;
  153. writerIndex_ = kCheapPrepend;
  154. }
  155. std::string retrieveAllAsString()
  156. {
  157. return retrieveAsString(readableBytes());;
  158. }
  159. std::string retrieveAsString(size_t len)
  160. {
  161. assert(len <= readableBytes());
  162. std::string result(peek(), len);
  163. retrieve(len);
  164. return result;
  165. }
  166. public: // search
  167. const char* peek() const
  168. {
  169. return begin() + readerIndex_;
  170. }
  171. const char* findCRLF() const
  172. {
  173. const char* crlf = std::search(peek(), beginWrite(), kCRLF, kCRLF + 2);
  174. return crlf == beginWrite() ? NULL : crlf;
  175. }
  176. const char* findCRLF(const char* start) const
  177. {
  178. assert(peek() <= start);
  179. assert(start <= beginWrite());
  180. const char* crlf = std::search(start, beginWrite(), kCRLF, kCRLF + 2);
  181. return crlf == beginWrite() ? NULL : crlf;
  182. }
  183. const char* findDoubleCRLF() const
  184. {
  185. const char* crlf = std::search(peek(), beginWrite(), kDoubleCRLF, kDoubleCRLF + 4);
  186. return crlf == beginWrite() ? NULL : crlf;
  187. }
  188. const char* findEOL() const
  189. {
  190. const void* eol = memchr(peek(), '\n', readableBytes());
  191. return static_cast<const char*>(eol);
  192. }
  193. const char* findEOL(const char* start) const
  194. {
  195. assert(peek() <= start);
  196. assert(start <= beginWrite());
  197. const void* eol = memchr(start, '\n', beginWrite() - start);
  198. return static_cast<const char*>(eol);
  199. }
  200. public:
  201. void ensureWritableBytes(size_t len)
  202. {
  203. if (writableBytes() < len)
  204. {
  205. makeSpace(len);
  206. }
  207. assert(writableBytes() >= len);
  208. }
  209. char* beginWrite()
  210. {
  211. return begin() + writerIndex_;
  212. }
  213. const char* beginWrite() const
  214. {
  215. return begin() + writerIndex_;
  216. }
  217. void hasWritten(size_t len)
  218. {
  219. assert(len <= writableBytes());
  220. writerIndex_ += len;
  221. }
  222. void unwrite(size_t len)
  223. {
  224. assert(len <= readableBytes());
  225. writerIndex_ -= len;
  226. }
  227. void shrink(size_t reserve)
  228. {
  229. ByteBuffer other;
  230. other.ensureWritableBytes(readableBytes() + reserve);
  231. other.write(toString());
  232. swap(other);
  233. }
  234. size_t capacity() const
  235. {
  236. return buffer_.capacity();
  237. }
  238. void swap(ByteBuffer& rhs)
  239. {
  240. buffer_.swap(rhs.buffer_);
  241. std::swap(readerIndex_, rhs.readerIndex_);
  242. std::swap(writerIndex_, rhs.writerIndex_);
  243. }
  244. private:
  245. char* begin()
  246. {
  247. return &*buffer_.begin();
  248. }
  249. const char* begin() const
  250. {
  251. return &*buffer_.begin();
  252. }
  253. void makeSpace(size_t len)
  254. {
  255. if (writableBytes() + prependableBytes() < len + kCheapPrepend)
  256. {
  257. // FIXME: move readable data
  258. buffer_.resize(writerIndex_ + len);
  259. }
  260. else
  261. {
  262. // move readable data to the front, make space inside buffer
  263. assert(kCheapPrepend < readerIndex_);
  264. size_t readable = readableBytes();
  265. for (size_t i = 0; i < writerIndex_ - readerIndex_; i++)
  266. {
  267. (begin() + kCheapPrepend)[i] = (begin() + readerIndex_)[i];
  268. }
  269. //std::copy(begin() + readerIndex_, begin() + writerIndex_, begin() + kCheapPrepend);
  270. readerIndex_ = kCheapPrepend;
  271. writerIndex_ = readerIndex_ + readable;
  272. assert(readable == readableBytes());
  273. }
  274. }
  275. private:
  276. size_t readerIndex_;
  277. size_t writerIndex_;
  278. std::vector<char> buffer_; // save buffer of network endian
  279. static const char kCRLF[];
  280. static const char kDoubleCRLF[];
  281. };
  282. }
  283. }
  284. #endif /* ZL_BYTEBUFFER_H */