stream.hpp 5.3 KB

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