mirror of
https://github.com/vdemydiuk/mtapi.git
synced 2026-08-04 22:47:46 +00:00
Added thirdparty: boost library
This commit is contained in:
+839
@@ -0,0 +1,839 @@
|
||||
//
|
||||
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/boostorg/json
|
||||
//
|
||||
|
||||
#ifndef BOOST_JSON_IMPL_SERIALIZER_IPP
|
||||
#define BOOST_JSON_IMPL_SERIALIZER_IPP
|
||||
|
||||
#include <boost/json/serializer.hpp>
|
||||
#include <boost/json/detail/format.hpp>
|
||||
#include <boost/json/detail/sse2.hpp>
|
||||
#include <ostream>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
||||
|
||||
enum class serializer::state : char
|
||||
{
|
||||
nul1, nul2, nul3, nul4,
|
||||
tru1, tru2, tru3, tru4,
|
||||
fal1, fal2, fal3, fal4, fal5,
|
||||
str1, str2, str3, str4, esc1,
|
||||
utf1, utf2, utf3, utf4, utf5,
|
||||
num,
|
||||
arr1, arr2, arr3, arr4,
|
||||
obj1, obj2, obj3, obj4, obj5, obj6
|
||||
};
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
serializer::
|
||||
serializer(
|
||||
storage_ptr sp,
|
||||
unsigned char* buf,
|
||||
std::size_t buf_size,
|
||||
serialize_options const& opts) noexcept
|
||||
: st_(
|
||||
std::move(sp),
|
||||
buf,
|
||||
buf_size)
|
||||
, opts_(opts)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
serializer::
|
||||
suspend(state st)
|
||||
{
|
||||
st_.push(st);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
serializer::
|
||||
suspend(
|
||||
state st,
|
||||
array::const_iterator it,
|
||||
array const* pa)
|
||||
{
|
||||
st_.push(pa);
|
||||
st_.push(it);
|
||||
st_.push(st);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
serializer::
|
||||
suspend(
|
||||
state st,
|
||||
object::const_iterator it,
|
||||
object const* po)
|
||||
{
|
||||
st_.push(po);
|
||||
st_.push(it);
|
||||
st_.push(st);
|
||||
return false;
|
||||
}
|
||||
|
||||
template<bool StackEmpty>
|
||||
bool
|
||||
serializer::
|
||||
write_null(stream& ss0)
|
||||
{
|
||||
local_stream ss(ss0);
|
||||
if(! StackEmpty && ! st_.empty())
|
||||
{
|
||||
state st;
|
||||
st_.pop(st);
|
||||
switch(st)
|
||||
{
|
||||
default:
|
||||
case state::nul1: goto do_nul1;
|
||||
case state::nul2: goto do_nul2;
|
||||
case state::nul3: goto do_nul3;
|
||||
case state::nul4: goto do_nul4;
|
||||
}
|
||||
}
|
||||
do_nul1:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append('n');
|
||||
else
|
||||
return suspend(state::nul1);
|
||||
do_nul2:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append('u');
|
||||
else
|
||||
return suspend(state::nul2);
|
||||
do_nul3:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append('l');
|
||||
else
|
||||
return suspend(state::nul3);
|
||||
do_nul4:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append('l');
|
||||
else
|
||||
return suspend(state::nul4);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<bool StackEmpty>
|
||||
bool
|
||||
serializer::
|
||||
write_true(stream& ss0)
|
||||
{
|
||||
local_stream ss(ss0);
|
||||
if(! StackEmpty && ! st_.empty())
|
||||
{
|
||||
state st;
|
||||
st_.pop(st);
|
||||
switch(st)
|
||||
{
|
||||
default:
|
||||
case state::tru1: goto do_tru1;
|
||||
case state::tru2: goto do_tru2;
|
||||
case state::tru3: goto do_tru3;
|
||||
case state::tru4: goto do_tru4;
|
||||
}
|
||||
}
|
||||
do_tru1:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append('t');
|
||||
else
|
||||
return suspend(state::tru1);
|
||||
do_tru2:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append('r');
|
||||
else
|
||||
return suspend(state::tru2);
|
||||
do_tru3:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append('u');
|
||||
else
|
||||
return suspend(state::tru3);
|
||||
do_tru4:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append('e');
|
||||
else
|
||||
return suspend(state::tru4);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<bool StackEmpty>
|
||||
bool
|
||||
serializer::
|
||||
write_false(stream& ss0)
|
||||
{
|
||||
local_stream ss(ss0);
|
||||
if(! StackEmpty && ! st_.empty())
|
||||
{
|
||||
state st;
|
||||
st_.pop(st);
|
||||
switch(st)
|
||||
{
|
||||
default:
|
||||
case state::fal1: goto do_fal1;
|
||||
case state::fal2: goto do_fal2;
|
||||
case state::fal3: goto do_fal3;
|
||||
case state::fal4: goto do_fal4;
|
||||
case state::fal5: goto do_fal5;
|
||||
}
|
||||
}
|
||||
do_fal1:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append('f');
|
||||
else
|
||||
return suspend(state::fal1);
|
||||
do_fal2:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append('a');
|
||||
else
|
||||
return suspend(state::fal2);
|
||||
do_fal3:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append('l');
|
||||
else
|
||||
return suspend(state::fal3);
|
||||
do_fal4:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append('s');
|
||||
else
|
||||
return suspend(state::fal4);
|
||||
do_fal5:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append('e');
|
||||
else
|
||||
return suspend(state::fal5);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<bool StackEmpty>
|
||||
bool
|
||||
serializer::
|
||||
write_string(stream& ss0)
|
||||
{
|
||||
local_stream ss(ss0);
|
||||
local_const_stream cs(cs0_);
|
||||
if(! StackEmpty && ! st_.empty())
|
||||
{
|
||||
state st;
|
||||
st_.pop(st);
|
||||
switch(st)
|
||||
{
|
||||
default:
|
||||
case state::str1: goto do_str1;
|
||||
case state::str2: goto do_str2;
|
||||
case state::str3: goto do_str3;
|
||||
case state::str4: goto do_str4;
|
||||
case state::esc1: goto do_esc1;
|
||||
case state::utf1: goto do_utf1;
|
||||
case state::utf2: goto do_utf2;
|
||||
case state::utf3: goto do_utf3;
|
||||
case state::utf4: goto do_utf4;
|
||||
case state::utf5: goto do_utf5;
|
||||
}
|
||||
}
|
||||
static constexpr char hex[] = "0123456789abcdef";
|
||||
static constexpr char esc[] =
|
||||
"uuuuuuuubtnufruuuuuuuuuuuuuuuuuu"
|
||||
"\0\0\"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
|
||||
|
||||
// opening quote
|
||||
do_str1:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append('\x22'); // '"'
|
||||
else
|
||||
return suspend(state::str1);
|
||||
|
||||
// fast loop,
|
||||
// copy unescaped
|
||||
do_str2:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
{
|
||||
std::size_t n = cs.remain();
|
||||
if(BOOST_JSON_LIKELY(n > 0))
|
||||
{
|
||||
if(ss.remain() > n)
|
||||
n = detail::count_unescaped(
|
||||
cs.data(), n);
|
||||
else
|
||||
n = detail::count_unescaped(
|
||||
cs.data(), ss.remain());
|
||||
if(n > 0)
|
||||
{
|
||||
ss.append(cs.data(), n);
|
||||
cs.skip(n);
|
||||
if(! ss)
|
||||
return suspend(state::str2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ss.append('\x22'); // '"'
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return suspend(state::str2);
|
||||
}
|
||||
|
||||
// slow loop,
|
||||
// handle escapes
|
||||
do_str3:
|
||||
while(BOOST_JSON_LIKELY(ss))
|
||||
{
|
||||
if(BOOST_JSON_LIKELY(cs))
|
||||
{
|
||||
auto const ch = *cs;
|
||||
auto const c = esc[static_cast<
|
||||
unsigned char>(ch)];
|
||||
++cs;
|
||||
if(! c)
|
||||
{
|
||||
ss.append(ch);
|
||||
}
|
||||
else if(c != 'u')
|
||||
{
|
||||
ss.append('\\');
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
{
|
||||
ss.append(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
buf_[0] = c;
|
||||
return suspend(
|
||||
state::esc1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(BOOST_JSON_LIKELY(
|
||||
ss.remain() >= 6))
|
||||
{
|
||||
ss.append("\\u00", 4);
|
||||
ss.append(hex[static_cast<
|
||||
unsigned char>(ch) >> 4]);
|
||||
ss.append(hex[static_cast<
|
||||
unsigned char>(ch) & 15]);
|
||||
}
|
||||
else
|
||||
{
|
||||
ss.append('\\');
|
||||
buf_[0] = hex[static_cast<
|
||||
unsigned char>(ch) >> 4];
|
||||
buf_[1] = hex[static_cast<
|
||||
unsigned char>(ch) & 15];
|
||||
goto do_utf1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ss.append('\x22'); // '"'
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return suspend(state::str3);
|
||||
|
||||
do_str4:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append('\x22'); // '"'
|
||||
else
|
||||
return suspend(state::str4);
|
||||
|
||||
do_esc1:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append(buf_[0]);
|
||||
else
|
||||
return suspend(state::esc1);
|
||||
goto do_str3;
|
||||
|
||||
do_utf1:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append('u');
|
||||
else
|
||||
return suspend(state::utf1);
|
||||
do_utf2:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append('0');
|
||||
else
|
||||
return suspend(state::utf2);
|
||||
do_utf3:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append('0');
|
||||
else
|
||||
return suspend(state::utf3);
|
||||
do_utf4:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append(buf_[0]);
|
||||
else
|
||||
return suspend(state::utf4);
|
||||
do_utf5:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append(buf_[1]);
|
||||
else
|
||||
return suspend(state::utf5);
|
||||
goto do_str3;
|
||||
}
|
||||
|
||||
template<bool StackEmpty>
|
||||
bool
|
||||
serializer::
|
||||
write_number(stream& ss0)
|
||||
{
|
||||
local_stream ss(ss0);
|
||||
if(StackEmpty || st_.empty())
|
||||
{
|
||||
switch(jv_->kind())
|
||||
{
|
||||
default:
|
||||
case kind::int64:
|
||||
if(BOOST_JSON_LIKELY(
|
||||
ss.remain() >=
|
||||
detail::max_number_chars))
|
||||
{
|
||||
ss.advance(detail::format_int64(
|
||||
ss.data(), jv_->get_int64()));
|
||||
return true;
|
||||
}
|
||||
cs0_ = { buf_, detail::format_int64(
|
||||
buf_, jv_->get_int64()) };
|
||||
break;
|
||||
|
||||
case kind::uint64:
|
||||
if(BOOST_JSON_LIKELY(
|
||||
ss.remain() >=
|
||||
detail::max_number_chars))
|
||||
{
|
||||
ss.advance(detail::format_uint64(
|
||||
ss.data(), jv_->get_uint64()));
|
||||
return true;
|
||||
}
|
||||
cs0_ = { buf_, detail::format_uint64(
|
||||
buf_, jv_->get_uint64()) };
|
||||
break;
|
||||
|
||||
case kind::double_:
|
||||
if(BOOST_JSON_LIKELY(
|
||||
ss.remain() >=
|
||||
detail::max_number_chars))
|
||||
{
|
||||
ss.advance(
|
||||
detail::format_double(
|
||||
ss.data(),
|
||||
jv_->get_double(),
|
||||
opts_.allow_infinity_and_nan));
|
||||
return true;
|
||||
}
|
||||
cs0_ = { buf_, detail::format_double(
|
||||
buf_, jv_->get_double(), opts_.allow_infinity_and_nan) };
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
state st;
|
||||
st_.pop(st);
|
||||
BOOST_ASSERT(
|
||||
st == state::num);
|
||||
}
|
||||
auto const n = ss.remain();
|
||||
if(n < cs0_.remain())
|
||||
{
|
||||
ss.append(cs0_.data(), n);
|
||||
cs0_.skip(n);
|
||||
return suspend(state::num);
|
||||
}
|
||||
ss.append(
|
||||
cs0_.data(), cs0_.remain());
|
||||
return true;
|
||||
}
|
||||
|
||||
template<bool StackEmpty>
|
||||
bool
|
||||
serializer::
|
||||
write_array(stream& ss0)
|
||||
{
|
||||
array const* pa;
|
||||
local_stream ss(ss0);
|
||||
array::const_iterator it;
|
||||
array::const_iterator end;
|
||||
if(StackEmpty || st_.empty())
|
||||
{
|
||||
pa = pa_;
|
||||
it = pa->begin();
|
||||
end = pa->end();
|
||||
}
|
||||
else
|
||||
{
|
||||
state st;
|
||||
st_.pop(st);
|
||||
st_.pop(it);
|
||||
st_.pop(pa);
|
||||
end = pa->end();
|
||||
switch(st)
|
||||
{
|
||||
default:
|
||||
case state::arr1: goto do_arr1;
|
||||
case state::arr2: goto do_arr2;
|
||||
case state::arr3: goto do_arr3;
|
||||
case state::arr4: goto do_arr4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
do_arr1:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append('[');
|
||||
else
|
||||
return suspend(
|
||||
state::arr1, it, pa);
|
||||
if(it == end)
|
||||
goto do_arr4;
|
||||
for(;;)
|
||||
{
|
||||
do_arr2:
|
||||
jv_ = &*it;
|
||||
if(! write_value<StackEmpty>(ss))
|
||||
return suspend(
|
||||
state::arr2, it, pa);
|
||||
if(BOOST_JSON_UNLIKELY(
|
||||
++it == end))
|
||||
break;
|
||||
do_arr3:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append(',');
|
||||
else
|
||||
return suspend(
|
||||
state::arr3, it, pa);
|
||||
}
|
||||
do_arr4:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append(']');
|
||||
else
|
||||
return suspend(
|
||||
state::arr4, it, pa);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<bool StackEmpty>
|
||||
bool
|
||||
serializer::
|
||||
write_object(stream& ss0)
|
||||
{
|
||||
object const* po;
|
||||
local_stream ss(ss0);
|
||||
object::const_iterator it;
|
||||
object::const_iterator end;
|
||||
if(StackEmpty || st_.empty())
|
||||
{
|
||||
po = po_;
|
||||
it = po->begin();
|
||||
end = po->end();
|
||||
}
|
||||
else
|
||||
{
|
||||
state st;
|
||||
st_.pop(st);
|
||||
st_.pop(it);
|
||||
st_.pop(po);
|
||||
end = po->end();
|
||||
switch(st)
|
||||
{
|
||||
default:
|
||||
case state::obj1: goto do_obj1;
|
||||
case state::obj2: goto do_obj2;
|
||||
case state::obj3: goto do_obj3;
|
||||
case state::obj4: goto do_obj4;
|
||||
case state::obj5: goto do_obj5;
|
||||
case state::obj6: goto do_obj6;
|
||||
break;
|
||||
}
|
||||
}
|
||||
do_obj1:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append('{');
|
||||
else
|
||||
return suspend(
|
||||
state::obj1, it, po);
|
||||
if(BOOST_JSON_UNLIKELY(
|
||||
it == end))
|
||||
goto do_obj6;
|
||||
for(;;)
|
||||
{
|
||||
cs0_ = {
|
||||
it->key().data(),
|
||||
it->key().size() };
|
||||
do_obj2:
|
||||
if(BOOST_JSON_UNLIKELY(
|
||||
! write_string<StackEmpty>(ss)))
|
||||
return suspend(
|
||||
state::obj2, it, po);
|
||||
do_obj3:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append(':');
|
||||
else
|
||||
return suspend(
|
||||
state::obj3, it, po);
|
||||
do_obj4:
|
||||
jv_ = &it->value();
|
||||
if(BOOST_JSON_UNLIKELY(
|
||||
! write_value<StackEmpty>(ss)))
|
||||
return suspend(
|
||||
state::obj4, it, po);
|
||||
++it;
|
||||
if(BOOST_JSON_UNLIKELY(it == end))
|
||||
break;
|
||||
do_obj5:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append(',');
|
||||
else
|
||||
return suspend(
|
||||
state::obj5, it, po);
|
||||
}
|
||||
do_obj6:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
{
|
||||
ss.append('}');
|
||||
return true;
|
||||
}
|
||||
return suspend(
|
||||
state::obj6, it, po);
|
||||
}
|
||||
|
||||
template<bool StackEmpty>
|
||||
bool
|
||||
serializer::
|
||||
write_value(stream& ss)
|
||||
{
|
||||
if(StackEmpty || st_.empty())
|
||||
{
|
||||
auto const& jv(*jv_);
|
||||
switch(jv.kind())
|
||||
{
|
||||
default:
|
||||
case kind::object:
|
||||
po_ = &jv.get_object();
|
||||
return write_object<true>(ss);
|
||||
|
||||
case kind::array:
|
||||
pa_ = &jv.get_array();
|
||||
return write_array<true>(ss);
|
||||
|
||||
case kind::string:
|
||||
{
|
||||
auto const& js = jv.get_string();
|
||||
cs0_ = { js.data(), js.size() };
|
||||
return write_string<true>(ss);
|
||||
}
|
||||
|
||||
case kind::int64:
|
||||
case kind::uint64:
|
||||
case kind::double_:
|
||||
return write_number<true>(ss);
|
||||
|
||||
case kind::bool_:
|
||||
if(jv.get_bool())
|
||||
{
|
||||
if(BOOST_JSON_LIKELY(
|
||||
ss.remain() >= 4))
|
||||
{
|
||||
ss.append("true", 4);
|
||||
return true;
|
||||
}
|
||||
return write_true<true>(ss);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(BOOST_JSON_LIKELY(
|
||||
ss.remain() >= 5))
|
||||
{
|
||||
ss.append("false", 5);
|
||||
return true;
|
||||
}
|
||||
return write_false<true>(ss);
|
||||
}
|
||||
|
||||
case kind::null:
|
||||
if(BOOST_JSON_LIKELY(
|
||||
ss.remain() >= 4))
|
||||
{
|
||||
ss.append("null", 4);
|
||||
return true;
|
||||
}
|
||||
return write_null<true>(ss);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
state st;
|
||||
st_.peek(st);
|
||||
switch(st)
|
||||
{
|
||||
default:
|
||||
case state::nul1: case state::nul2:
|
||||
case state::nul3: case state::nul4:
|
||||
return write_null<StackEmpty>(ss);
|
||||
|
||||
case state::tru1: case state::tru2:
|
||||
case state::tru3: case state::tru4:
|
||||
return write_true<StackEmpty>(ss);
|
||||
|
||||
case state::fal1: case state::fal2:
|
||||
case state::fal3: case state::fal4:
|
||||
case state::fal5:
|
||||
return write_false<StackEmpty>(ss);
|
||||
|
||||
case state::str1: case state::str2:
|
||||
case state::str3: case state::str4:
|
||||
case state::esc1:
|
||||
case state::utf1: case state::utf2:
|
||||
case state::utf3: case state::utf4:
|
||||
case state::utf5:
|
||||
return write_string<StackEmpty>(ss);
|
||||
|
||||
case state::num:
|
||||
return write_number<StackEmpty>(ss);
|
||||
|
||||
case state::arr1: case state::arr2:
|
||||
case state::arr3: case state::arr4:
|
||||
return write_array<StackEmpty>(ss);
|
||||
|
||||
case state::obj1: case state::obj2:
|
||||
case state::obj3: case state::obj4:
|
||||
case state::obj5: case state::obj6:
|
||||
return write_object<StackEmpty>(ss);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string_view
|
||||
serializer::
|
||||
read_some(
|
||||
char* dest, std::size_t size)
|
||||
{
|
||||
// If this goes off it means you forgot
|
||||
// to call reset() before seriailzing a
|
||||
// new value, or you never checked done()
|
||||
// to see if you should stop.
|
||||
BOOST_ASSERT(! done_);
|
||||
|
||||
stream ss(dest, size);
|
||||
if(st_.empty())
|
||||
(this->*fn0_)(ss);
|
||||
else
|
||||
(this->*fn1_)(ss);
|
||||
if(st_.empty())
|
||||
{
|
||||
done_ = true;
|
||||
jv_ = nullptr;
|
||||
}
|
||||
return string_view(
|
||||
dest, ss.used(dest));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
serializer::
|
||||
serializer( serialize_options const& opts ) noexcept
|
||||
: opts_(opts)
|
||||
{
|
||||
// ensure room for \uXXXX escape plus one
|
||||
BOOST_STATIC_ASSERT(
|
||||
sizeof(serializer::buf_) >= 7);
|
||||
}
|
||||
|
||||
void
|
||||
serializer::
|
||||
reset(value const* p) noexcept
|
||||
{
|
||||
pv_ = p;
|
||||
fn0_ = &serializer::write_value<true>;
|
||||
fn1_ = &serializer::write_value<false>;
|
||||
|
||||
jv_ = p;
|
||||
st_.clear();
|
||||
done_ = false;
|
||||
}
|
||||
|
||||
void
|
||||
serializer::
|
||||
reset(array const* p) noexcept
|
||||
{
|
||||
pa_ = p;
|
||||
fn0_ = &serializer::write_array<true>;
|
||||
fn1_ = &serializer::write_array<false>;
|
||||
st_.clear();
|
||||
done_ = false;
|
||||
}
|
||||
|
||||
void
|
||||
serializer::
|
||||
reset(object const* p) noexcept
|
||||
{
|
||||
po_ = p;
|
||||
fn0_ = &serializer::write_object<true>;
|
||||
fn1_ = &serializer::write_object<false>;
|
||||
st_.clear();
|
||||
done_ = false;
|
||||
}
|
||||
|
||||
void
|
||||
serializer::
|
||||
reset(string const* p) noexcept
|
||||
{
|
||||
cs0_ = { p->data(), p->size() };
|
||||
fn0_ = &serializer::write_string<true>;
|
||||
fn1_ = &serializer::write_string<false>;
|
||||
st_.clear();
|
||||
done_ = false;
|
||||
}
|
||||
|
||||
void
|
||||
serializer::
|
||||
reset(string_view sv) noexcept
|
||||
{
|
||||
cs0_ = { sv.data(), sv.size() };
|
||||
fn0_ = &serializer::write_string<true>;
|
||||
fn1_ = &serializer::write_string<false>;
|
||||
st_.clear();
|
||||
done_ = false;
|
||||
}
|
||||
|
||||
string_view
|
||||
serializer::
|
||||
read(char* dest, std::size_t size)
|
||||
{
|
||||
if(! jv_)
|
||||
{
|
||||
static value const null;
|
||||
jv_ = &null;
|
||||
}
|
||||
return read_some(dest, size);
|
||||
}
|
||||
|
||||
} // namespace json
|
||||
} // namespace boost
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user