serializer.hpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  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_SERIALIZER_HPP
  10. #define BOOST_JSON_SERIALIZER_HPP
  11. #include <boost/json/detail/config.hpp>
  12. #include <boost/json/value.hpp>
  13. #include <boost/json/detail/format.hpp>
  14. #include <boost/json/detail/stack.hpp>
  15. #include <boost/json/detail/stream.hpp>
  16. BOOST_JSON_NS_BEGIN
  17. /** A serializer for JSON.
  18. This class traverses an instance of a library
  19. type and emits serialized JSON text by filling
  20. in one or more caller-provided buffers. To use,
  21. declare a variable and call @ref reset with
  22. a pointer to the variable you want to serialize.
  23. Then call @ref read over and over until
  24. @ref done returns `true`.
  25. @par Example
  26. This demonstrates how the serializer may
  27. be used to print a JSON value to an output
  28. stream.
  29. @code
  30. void print( std::ostream& os, value const& jv)
  31. {
  32. serializer sr;
  33. sr.reset( &jv );
  34. while( ! sr.done() )
  35. {
  36. char buf[ 4000 ];
  37. os << sr.read( buf );
  38. }
  39. }
  40. @endcode
  41. @par Thread Safety
  42. The same instance may not be accessed concurrently.
  43. */
  44. class serializer
  45. {
  46. enum class state : char;
  47. // VFALCO Too many streams
  48. using stream = detail::stream;
  49. using const_stream = detail::const_stream;
  50. using local_stream = detail::local_stream;
  51. using local_const_stream =
  52. detail::local_const_stream;
  53. using fn_t = bool (serializer::*)(stream&);
  54. #ifndef BOOST_JSON_DOCS
  55. union
  56. {
  57. value const* pv_;
  58. array const* pa_;
  59. object const* po_;
  60. };
  61. #endif
  62. fn_t fn0_ = &serializer::write_null<true>;
  63. fn_t fn1_ = &serializer::write_null<false>;
  64. value const* jv_ = nullptr;
  65. detail::stack st_;
  66. const_stream cs0_;
  67. char buf_[detail::max_number_chars + 1];
  68. bool done_ = false;
  69. inline bool suspend(state st);
  70. inline bool suspend(
  71. state st, array::const_iterator it, array const* pa);
  72. inline bool suspend(
  73. state st, object::const_iterator it, object const* po);
  74. template<bool StackEmpty> bool write_null (stream& ss);
  75. template<bool StackEmpty> bool write_true (stream& ss);
  76. template<bool StackEmpty> bool write_false (stream& ss);
  77. template<bool StackEmpty> bool write_string (stream& ss);
  78. template<bool StackEmpty> bool write_number (stream& ss);
  79. template<bool StackEmpty> bool write_array (stream& ss);
  80. template<bool StackEmpty> bool write_object (stream& ss);
  81. template<bool StackEmpty> bool write_value (stream& ss);
  82. inline string_view read_some(char* dest, std::size_t size);
  83. public:
  84. /// Move constructor (deleted)
  85. serializer(serializer&&) = delete;
  86. /** Destructor
  87. All temporary storage is deallocated.
  88. @par Complexity
  89. Constant
  90. @par Exception Safety
  91. No-throw guarantee.
  92. */
  93. BOOST_JSON_DECL
  94. ~serializer() noexcept;
  95. /** Default constructor
  96. This constructs a serializer with no value.
  97. The value may be set later by calling @ref reset.
  98. If serialization is attempted with no value,
  99. the output is as if a null value is serialized.
  100. @par Complexity
  101. Constant.
  102. @par Exception Safety
  103. No-throw guarantee.
  104. */
  105. BOOST_JSON_DECL
  106. serializer() noexcept;
  107. /** Returns `true` if the serialization is complete
  108. This function returns `true` when all of the
  109. characters in the serialized representation of
  110. the value have been read.
  111. @par Complexity
  112. Constant.
  113. @par Exception Safety
  114. No-throw guarantee.
  115. */
  116. bool
  117. done() const noexcept
  118. {
  119. return done_;
  120. }
  121. /** Reset the serializer for a new element
  122. This function prepares the serializer to emit
  123. a new serialized JSON representing `*p`.
  124. Any internally allocated memory is
  125. preserved and re-used for the new output.
  126. @param p A pointer to the element to serialize.
  127. Ownership is not transferred; The caller is
  128. responsible for ensuring that the lifetime of
  129. `*p` extends until it is no longer needed.
  130. */
  131. /** @{ */
  132. BOOST_JSON_DECL
  133. void
  134. reset(value const* p) noexcept;
  135. BOOST_JSON_DECL
  136. void
  137. reset(array const* p) noexcept;
  138. BOOST_JSON_DECL
  139. void
  140. reset(object const* p) noexcept;
  141. BOOST_JSON_DECL
  142. void
  143. reset(string const* p) noexcept;
  144. /** @} */
  145. /** Reset the serializer for a new string
  146. This function prepares the serializer to emit
  147. a new serialized JSON representing the string.
  148. Any internally allocated memory is
  149. preserved and re-used for the new output.
  150. @param sv The characters representing the string.
  151. Ownership is not transferred; The caller is
  152. responsible for ensuring that the lifetime of
  153. the characters reference by `sv` extends
  154. until it is no longer needed.
  155. */
  156. BOOST_JSON_DECL
  157. void
  158. reset(string_view sv) noexcept;
  159. /** Read the next buffer of serialized JSON
  160. This function attempts to fill the caller
  161. provided buffer starting at `dest` with
  162. up to `size` characters of the serialized
  163. JSON that represents the value. If the
  164. buffer is not large enough, multiple calls
  165. may be required.
  166. \n
  167. If serialization completes during this call;
  168. that is, that all of the characters belonging
  169. to the serialized value have been written to
  170. caller-provided buffers, the function
  171. @ref done will return `true`.
  172. @par Preconditions
  173. `this->done() == true`
  174. @par Complexity
  175. Linear in `size`.
  176. @par Exception Safety
  177. Basic guarantee.
  178. Calls to `memory_resource::allocate` may throw.
  179. @return A @ref string_view containing the
  180. characters written, which may be less than
  181. `size`.
  182. @param dest A pointer to valid memory of at
  183. least `size` bytes.
  184. @param size The maximum number of characters
  185. to write to the memory pointed to by `dest`.
  186. */
  187. BOOST_JSON_DECL
  188. string_view
  189. read(char* dest, std::size_t size);
  190. /** Read the next buffer of serialized JSON
  191. This function allows reading into a
  192. character array, with a deduced maximum size.
  193. @par Preconditions
  194. `this->done() == true`
  195. @par Effects
  196. @code
  197. return this->read( dest, N );
  198. @endcode
  199. @par Complexity
  200. Linear in `N`.
  201. @par Exception Safety
  202. Basic guarantee.
  203. Calls to `memory_resource::allocate` may throw.
  204. @return A @ref string_view containing the
  205. characters written, which may be less than
  206. `size`.
  207. @param dest The character array to write to.
  208. */
  209. template<std::size_t N>
  210. string_view
  211. read(char(&dest)[N])
  212. {
  213. return read(dest, N);
  214. }
  215. #ifndef BOOST_JSON_DOCS
  216. // Safety net for accidental buffer overflows
  217. template<std::size_t N>
  218. string_view
  219. read(char(&dest)[N], std::size_t n)
  220. {
  221. // If this goes off, check your parameters
  222. // closely, chances are you passed an array
  223. // thinking it was a pointer.
  224. BOOST_ASSERT(n <= N);
  225. return read(dest, n);
  226. }
  227. #endif
  228. };
  229. BOOST_JSON_NS_END
  230. #endif