serialize.ipp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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_IMPL_SERIALIZE_IPP
  10. #define BOOST_JSON_IMPL_SERIALIZE_IPP
  11. #include <boost/json/serialize.hpp>
  12. #include <boost/json/serializer.hpp>
  13. #include <ostream>
  14. namespace boost {
  15. namespace json {
  16. static
  17. void
  18. serialize_impl(
  19. std::string& s,
  20. serializer& sr)
  21. {
  22. // serialize to a small buffer to avoid
  23. // the first few allocations in std::string
  24. char buf[BOOST_JSON_STACK_BUFFER_SIZE];
  25. string_view sv;
  26. sv = sr.read(buf);
  27. if(sr.done())
  28. {
  29. // fast path
  30. s.append(
  31. sv.data(), sv.size());
  32. return;
  33. }
  34. std::size_t len = sv.size();
  35. s.reserve(len * 2);
  36. s.resize(s.capacity());
  37. BOOST_ASSERT(
  38. s.size() >= len * 2);
  39. std::memcpy(&s[0],
  40. sv.data(), sv.size());
  41. auto const lim =
  42. s.max_size() / 2;
  43. for(;;)
  44. {
  45. sv = sr.read(
  46. &s[0] + len,
  47. s.size() - len);
  48. len += sv.size();
  49. if(sr.done())
  50. break;
  51. // growth factor 2x
  52. if(s.size() < lim)
  53. s.resize(s.size() * 2);
  54. else
  55. s.resize(2 * lim);
  56. }
  57. s.resize(len);
  58. }
  59. std::string
  60. serialize(
  61. value const& jv)
  62. {
  63. unsigned char buf[256];
  64. serializer sr(
  65. storage_ptr(),
  66. buf,
  67. sizeof(buf));
  68. sr.reset(&jv);
  69. std::string s;
  70. serialize_impl(s, sr);
  71. return s;
  72. }
  73. std::string
  74. serialize(
  75. array const& arr)
  76. {
  77. unsigned char buf[256];
  78. serializer sr(
  79. storage_ptr(),
  80. buf,
  81. sizeof(buf));
  82. std::string s;
  83. sr.reset(&arr);
  84. serialize_impl(s, sr);
  85. return s;
  86. }
  87. std::string
  88. serialize(
  89. object const& obj)
  90. {
  91. unsigned char buf[256];
  92. serializer sr(
  93. storage_ptr(),
  94. buf,
  95. sizeof(buf));
  96. std::string s;
  97. sr.reset(&obj);
  98. serialize_impl(s, sr);
  99. return s;
  100. }
  101. std::string
  102. serialize(
  103. string const& str)
  104. {
  105. return serialize( str.subview() );
  106. }
  107. // this is here for key_value_pair::key()
  108. std::string
  109. serialize(
  110. string_view sv)
  111. {
  112. unsigned char buf[256];
  113. serializer sr(
  114. storage_ptr(),
  115. buf,
  116. sizeof(buf));
  117. std::string s;
  118. sr.reset(sv);
  119. serialize_impl(s, sr);
  120. return s;
  121. }
  122. //----------------------------------------------------------
  123. //[example_operator_lt__lt_
  124. // Serialize a value into an output stream
  125. std::ostream&
  126. operator<<( std::ostream& os, value const& jv )
  127. {
  128. // Create a serializer
  129. serializer sr;
  130. // Set the serializer up for our value
  131. sr.reset( &jv );
  132. // Loop until all output is produced.
  133. while( ! sr.done() )
  134. {
  135. // Use a local buffer to avoid allocation.
  136. char buf[ BOOST_JSON_STACK_BUFFER_SIZE ];
  137. // Fill our buffer with serialized characters and write it to the output stream.
  138. os << sr.read( buf );
  139. }
  140. return os;
  141. }
  142. //]
  143. static
  144. void
  145. to_ostream(
  146. std::ostream& os,
  147. serializer& sr)
  148. {
  149. while(! sr.done())
  150. {
  151. char buf[BOOST_JSON_STACK_BUFFER_SIZE];
  152. auto s = sr.read(buf);
  153. os.write(s.data(), s.size());
  154. }
  155. }
  156. std::ostream&
  157. operator<<(
  158. std::ostream& os,
  159. array const& arr)
  160. {
  161. serializer sr;
  162. sr.reset(&arr);
  163. to_ostream(os, sr);
  164. return os;
  165. }
  166. std::ostream&
  167. operator<<(
  168. std::ostream& os,
  169. object const& obj)
  170. {
  171. serializer sr;
  172. sr.reset(&obj);
  173. to_ostream(os, sr);
  174. return os;
  175. }
  176. std::ostream&
  177. operator<<(
  178. std::ostream& os,
  179. string const& str)
  180. {
  181. serializer sr;
  182. sr.reset(&str);
  183. to_ostream(os, sr);
  184. return os;
  185. }
  186. } // namespace json
  187. } // namespace boost
  188. #endif