stream.hpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. //
  2. // Copyright (c) 2019 Vinnie Falco ([email protected])
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // Official repository: https://github.com/boostorg/json
  8. //
  9. #ifndef BOOST_JSON_DETAIL_STREAM_HPP
  10. #define BOOST_JSON_DETAIL_STREAM_HPP
  11. namespace boost {
  12. namespace json {
  13. namespace detail {
  14. class const_stream
  15. {
  16. friend class local_const_stream;
  17. char const* p_;
  18. char const* end_;
  19. public:
  20. const_stream() = default;
  21. const_stream(
  22. char const* data,
  23. std::size_t size) noexcept
  24. : p_(data)
  25. , end_(data + size)
  26. {
  27. }
  28. size_t
  29. used(char const* begin) const noexcept
  30. {
  31. return static_cast<
  32. size_t>(p_ - begin);
  33. }
  34. size_t
  35. remain() const noexcept
  36. {
  37. return end_ - p_;
  38. }
  39. char const*
  40. data() const noexcept
  41. {
  42. return p_;
  43. }
  44. operator bool() const noexcept
  45. {
  46. return p_ < end_;
  47. }
  48. // unchecked
  49. char
  50. operator*() const noexcept
  51. {
  52. BOOST_ASSERT(p_ < end_);
  53. return *p_;
  54. }
  55. // unchecked
  56. const_stream&
  57. operator++() noexcept
  58. {
  59. BOOST_ASSERT(p_ < end_);
  60. ++p_;
  61. return *this;
  62. }
  63. void
  64. skip(std::size_t n) noexcept
  65. {
  66. BOOST_ASSERT(n <= remain());
  67. p_ += n;
  68. }
  69. void
  70. skip_to(const char* p) noexcept
  71. {
  72. BOOST_ASSERT(p <= end_ && p >= p_);
  73. p_ = p;
  74. }
  75. };
  76. class local_const_stream
  77. : public const_stream
  78. {
  79. const_stream& src_;
  80. public:
  81. explicit
  82. local_const_stream(
  83. const_stream& src) noexcept
  84. : const_stream(src)
  85. , src_(src)
  86. {
  87. }
  88. ~local_const_stream()
  89. {
  90. src_.p_ = p_;
  91. }
  92. void
  93. clip(std::size_t n) noexcept
  94. {
  95. if(static_cast<std::size_t>(
  96. src_.end_ - p_) > n)
  97. end_ = p_ + n;
  98. else
  99. end_ = src_.end_;
  100. }
  101. };
  102. class const_stream_wrapper
  103. {
  104. const char*& p_;
  105. const char* const end_;
  106. friend class clipped_const_stream;
  107. public:
  108. const_stream_wrapper(
  109. const char*& p,
  110. const char* end)
  111. : p_(p)
  112. , end_(end)
  113. {
  114. }
  115. void operator++() noexcept
  116. {
  117. ++p_;
  118. }
  119. void operator+=(std::size_t n) noexcept
  120. {
  121. p_ += n;
  122. }
  123. void operator=(const char* p) noexcept
  124. {
  125. p_ = p;
  126. }
  127. char operator*() const noexcept
  128. {
  129. return *p_;
  130. }
  131. operator bool() const noexcept
  132. {
  133. return p_ < end_;
  134. }
  135. const char* begin() const noexcept
  136. {
  137. return p_;
  138. }
  139. const char* end() const noexcept
  140. {
  141. return end_;
  142. }
  143. std::size_t remain() const noexcept
  144. {
  145. return end_ - p_;
  146. }
  147. std::size_t remain(const char* p) const noexcept
  148. {
  149. return end_ - p;
  150. }
  151. std::size_t used(const char* p) const noexcept
  152. {
  153. return p_ - p;
  154. }
  155. };
  156. class clipped_const_stream
  157. : public const_stream_wrapper
  158. {
  159. const char* clip_;
  160. public:
  161. clipped_const_stream(
  162. const char*& p,
  163. const char* end)
  164. : const_stream_wrapper(p, end)
  165. , clip_(end)
  166. {
  167. }
  168. void operator=(const char* p)
  169. {
  170. p_ = p;
  171. }
  172. const char* end() const noexcept
  173. {
  174. return clip_;
  175. }
  176. operator bool() const noexcept
  177. {
  178. return p_ < clip_;
  179. }
  180. std::size_t remain() const noexcept
  181. {
  182. return clip_ - p_;
  183. }
  184. std::size_t remain(const char* p) const noexcept
  185. {
  186. return clip_ - p;
  187. }
  188. void
  189. clip(std::size_t n) noexcept
  190. {
  191. if(static_cast<std::size_t>(
  192. end_ - p_) > n)
  193. clip_ = p_ + n;
  194. else
  195. clip_ = end_;
  196. }
  197. };
  198. //--------------------------------------
  199. class stream
  200. {
  201. friend class local_stream;
  202. char* p_;
  203. char* end_;
  204. public:
  205. stream(
  206. char* data,
  207. std::size_t size) noexcept
  208. : p_(data)
  209. , end_(data + size)
  210. {
  211. }
  212. size_t
  213. used(char* begin) const noexcept
  214. {
  215. return static_cast<
  216. size_t>(p_ - begin);
  217. }
  218. size_t
  219. remain() const noexcept
  220. {
  221. return end_ - p_;
  222. }
  223. char*
  224. data() noexcept
  225. {
  226. return p_;
  227. }
  228. operator bool() const noexcept
  229. {
  230. return p_ < end_;
  231. }
  232. // unchecked
  233. char&
  234. operator*() noexcept
  235. {
  236. BOOST_ASSERT(p_ < end_);
  237. return *p_;
  238. }
  239. // unchecked
  240. stream&
  241. operator++() noexcept
  242. {
  243. BOOST_ASSERT(p_ < end_);
  244. ++p_;
  245. return *this;
  246. }
  247. // unchecked
  248. void
  249. append(
  250. char const* src,
  251. std::size_t n) noexcept
  252. {
  253. BOOST_ASSERT(remain() >= n);
  254. std::memcpy(p_, src, n);
  255. p_ += n;
  256. }
  257. // unchecked
  258. void
  259. append(char c) noexcept
  260. {
  261. BOOST_ASSERT(p_ < end_);
  262. *p_++ = c;
  263. }
  264. void
  265. advance(std::size_t n) noexcept
  266. {
  267. BOOST_ASSERT(remain() >= n);
  268. p_ += n;
  269. }
  270. };
  271. class local_stream
  272. : public stream
  273. {
  274. stream& src_;
  275. public:
  276. explicit
  277. local_stream(
  278. stream& src)
  279. : stream(src)
  280. , src_(src)
  281. {
  282. }
  283. ~local_stream()
  284. {
  285. src_.p_ = p_;
  286. }
  287. };
  288. } // detail
  289. } // namespace json
  290. } // namespace boost
  291. #endif