Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-15 08:38:58

0001 //
0002 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // Official repository: https://github.com/boostorg/json
0008 //
0009 
0010 #ifndef BOOST_JSON_IMPL_SERIALIZE_IPP
0011 #define BOOST_JSON_IMPL_SERIALIZE_IPP
0012 
0013 #include <boost/json/serialize.hpp>
0014 #include <boost/json/serializer.hpp>
0015 #include <ostream>
0016 
0017 namespace boost {
0018 namespace json {
0019 
0020 namespace {
0021 
0022 int serialize_xalloc = std::ios::xalloc();
0023 
0024 enum class serialize_stream_flags : long
0025 {
0026     allow_infinity_and_nan = 1,
0027 };
0028 
0029 std::underlying_type<serialize_stream_flags>::type
0030 to_bitmask( serialize_options const& opts )
0031 {
0032     using E = serialize_stream_flags;
0033     using I = std::underlying_type<E>::type;
0034     return (opts.allow_infinity_and_nan
0035         ? static_cast<I>(E::allow_infinity_and_nan) : 0);
0036 }
0037 
0038 serialize_options
0039 get_stream_flags( std::ostream& os )
0040 {
0041     auto const flags = os.iword(serialize_xalloc);
0042 
0043     serialize_options opts;
0044     using E = serialize_stream_flags;
0045     using I = std::underlying_type<E>::type;
0046     opts.allow_infinity_and_nan =
0047         flags & static_cast<I>(E::allow_infinity_and_nan);
0048     return opts;
0049 }
0050 
0051 } // namespace
0052 
0053 namespace detail {
0054 
0055 void
0056 serialize_impl(
0057     std::string& s,
0058     serializer& sr)
0059 {
0060     // serialize to a small buffer to avoid
0061     // the first few allocations in std::string
0062     char buf[BOOST_JSON_STACK_BUFFER_SIZE];
0063     string_view sv;
0064     sv = sr.read(buf);
0065     if(sr.done())
0066     {
0067         // fast path
0068         s.append(
0069             sv.data(), sv.size());
0070         return;
0071     }
0072     std::size_t len = sv.size();
0073     s.reserve(len * 2);
0074     s.resize(s.capacity());
0075     BOOST_ASSERT(
0076         s.size() >= len * 2);
0077     std::memcpy(&s[0],
0078         sv.data(), sv.size());
0079     auto const lim =
0080         s.max_size() / 2;
0081     for(;;)
0082     {
0083         sv = sr.read(
0084             &s[0] + len,
0085             s.size() - len);
0086         len += sv.size();
0087         if(sr.done())
0088             break;
0089         // growth factor 2x
0090         if(s.size() < lim)
0091             s.resize(s.size() * 2);
0092         else
0093             s.resize(2 * lim);
0094     }
0095     s.resize(len);
0096 }
0097 
0098 } // namespace detail
0099 
0100 std::string
0101 serialize(
0102     value const& jv,
0103     serialize_options const& opts)
0104 {
0105     unsigned char buf[256];
0106     serializer sr(
0107         storage_ptr(),
0108         buf,
0109         sizeof(buf),
0110         opts);
0111     sr.reset(&jv);
0112     std::string s;
0113     serialize_impl(s, sr);
0114     return s;
0115 }
0116 
0117 std::string
0118 serialize(
0119     array const& arr,
0120     serialize_options const& opts)
0121 {
0122     unsigned char buf[256];
0123     serializer sr(
0124         storage_ptr(),
0125         buf,
0126         sizeof(buf),
0127         opts);
0128     std::string s;
0129     sr.reset(&arr);
0130     serialize_impl(s, sr);
0131     return s;
0132 }
0133 
0134 std::string
0135 serialize(
0136     object const& obj,
0137     serialize_options const& opts)
0138 {
0139     unsigned char buf[256];
0140     serializer sr(
0141         storage_ptr(),
0142         buf,
0143         sizeof(buf),
0144         opts);
0145     std::string s;
0146     sr.reset(&obj);
0147     serialize_impl(s, sr);
0148     return s;
0149 }
0150 
0151 std::string
0152 serialize(
0153     string const& str,
0154     serialize_options const& opts)
0155 {
0156     return serialize( str.subview(), opts );
0157 }
0158 
0159 // this is here for key_value_pair::key()
0160 std::string
0161 serialize(
0162     string_view sv,
0163     serialize_options const& opts)
0164 {
0165     unsigned char buf[256];
0166     serializer sr(
0167         storage_ptr(),
0168         buf,
0169         sizeof(buf),
0170         opts);
0171     std::string s;
0172     sr.reset(sv);
0173     serialize_impl(s, sr);
0174     return s;
0175 }
0176 
0177 //----------------------------------------------------------
0178 
0179 //[example_operator_lt__lt_
0180 // Serialize a value into an output stream
0181 
0182 std::ostream&
0183 operator<<( std::ostream& os, value const& jv )
0184 {
0185     // Create a serializer
0186     serializer sr( get_stream_flags(os) );
0187 
0188     // Set the serializer up for our value
0189     sr.reset( &jv );
0190 
0191     // Loop until all output is produced.
0192     while( ! sr.done() )
0193     {
0194         // Use a local buffer to avoid allocation.
0195         char buf[ BOOST_JSON_STACK_BUFFER_SIZE ];
0196 
0197         // Fill our buffer with serialized characters and write it to the output stream.
0198         os << sr.read( buf );
0199     }
0200 
0201     return os;
0202 }
0203 //]
0204 
0205 static
0206 void
0207 to_ostream(
0208     std::ostream& os,
0209     serializer& sr)
0210 {
0211     while(! sr.done())
0212     {
0213         char buf[BOOST_JSON_STACK_BUFFER_SIZE];
0214         auto s = sr.read(buf);
0215         os.write(s.data(), s.size());
0216     }
0217 }
0218 
0219 std::ostream&
0220 operator<<(
0221     std::ostream& os,
0222     array const& arr)
0223 {
0224     serializer sr( get_stream_flags(os) );
0225     sr.reset(&arr);
0226     to_ostream(os, sr);
0227     return os;
0228 }
0229 
0230 std::ostream&
0231 operator<<(
0232     std::ostream& os,
0233     object const& obj)
0234 {
0235     serializer sr( get_stream_flags(os) );
0236     sr.reset(&obj);
0237     to_ostream(os, sr);
0238     return os;
0239 }
0240 
0241 std::ostream&
0242 operator<<(
0243     std::ostream& os,
0244     string const& str)
0245 {
0246     serializer sr( get_stream_flags(os) );
0247     sr.reset(&str);
0248     to_ostream(os, sr);
0249     return os;
0250 }
0251 
0252 std::ostream&
0253 operator<<( std::ostream& os, serialize_options const& opts )
0254 {
0255     os.iword(serialize_xalloc) = to_bitmask(opts);
0256     return os;
0257 }
0258 
0259 } // namespace json
0260 } // namespace boost
0261 
0262 #endif