mirror of
https://github.com/boostorg/json.git
synced 2025-05-11 13:44:06 +00:00
serializer work
This commit is contained in:
parent
b1e03f7326
commit
dd8dd9929f
117
bench/bench.cpp
117
bench/bench.cpp
@ -9,6 +9,7 @@
|
||||
|
||||
#include "lib/nlohmann/single_include/nlohmann/json.hpp"
|
||||
|
||||
#include "lib/rapidjson/include/rapidjson/rapidjson.h"
|
||||
#include "lib/rapidjson/include/rapidjson/document.h"
|
||||
#include "lib/rapidjson/include/rapidjson/writer.h"
|
||||
#include "lib/rapidjson/include/rapidjson/stringbuffer.h"
|
||||
@ -45,7 +46,7 @@ public:
|
||||
virtual ~any_impl() = default;
|
||||
|
||||
virtual boost::string_view name() const noexcept = 0;
|
||||
virtual void parse(boost::string_view s) = 0;
|
||||
virtual void work(boost::string_view s) = 0;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------
|
||||
@ -58,30 +59,46 @@ struct boost_impl : public any_impl
|
||||
return "Boost.JSON";
|
||||
}
|
||||
|
||||
void
|
||||
parse(boost::string_view s) override
|
||||
static
|
||||
std::string
|
||||
to_string(
|
||||
json::value const& jv,
|
||||
std::size_t size_hint)
|
||||
{
|
||||
json::parser p;
|
||||
boost::system::error_code ec;
|
||||
p.write(s.data(), s.size(), ec);
|
||||
}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
struct nlohmann_impl : public any_impl
|
||||
{
|
||||
boost::string_view
|
||||
name() const noexcept override
|
||||
{
|
||||
return "nlohmann";
|
||||
std::string s;
|
||||
std::size_t len = 0;
|
||||
s.resize(size_hint);
|
||||
json::serializer p(jv);
|
||||
for(;;)
|
||||
{
|
||||
auto const used = p.next(
|
||||
&s[len], s.size() - len);
|
||||
len += used;
|
||||
s.resize(len);
|
||||
if(p.is_done())
|
||||
break;
|
||||
s.resize((len * 3) / 2);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void
|
||||
parse(boost::string_view s) override
|
||||
work(boost::string_view s) override
|
||||
{
|
||||
auto jv = nlohmann::json::parse(
|
||||
s.begin(), s.end());
|
||||
std::string s2;
|
||||
{
|
||||
json::parser p;
|
||||
boost::system::error_code ec;
|
||||
p.write(s.data(), s.size(), ec);
|
||||
s2 = to_string(p.get(), s.size() * 2);
|
||||
dout << "s2.size() == " << s2.size() << std::endl;
|
||||
}
|
||||
{
|
||||
json::parser p;
|
||||
boost::system::error_code ec;
|
||||
p.write(s2.data(), s2.size(), ec);
|
||||
dout << "ec.message() == " << ec.message() << std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -96,10 +113,40 @@ struct rapidjson_impl : public any_impl
|
||||
}
|
||||
|
||||
void
|
||||
parse(boost::string_view s) override
|
||||
work(boost::string_view s) override
|
||||
{
|
||||
rapidjson::Document d;
|
||||
d.Parse(s.data(), s.size());
|
||||
rapidjson::StringBuffer s2;
|
||||
{
|
||||
rapidjson::Document d;
|
||||
d.Parse(s.data(), s.size());
|
||||
s2.Clear();
|
||||
rapidjson::Writer<
|
||||
rapidjson::StringBuffer> wr(s2);
|
||||
d.Accept(wr);
|
||||
dout << "s2.GetSize() == " << s2.GetSize() << std::endl;
|
||||
}
|
||||
{
|
||||
rapidjson::Document d;
|
||||
d.Parse(s2.GetString(), s2.GetSize());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
struct nlohmann_impl : public any_impl
|
||||
{
|
||||
boost::string_view
|
||||
name() const noexcept override
|
||||
{
|
||||
return "nlohmann";
|
||||
}
|
||||
|
||||
void
|
||||
work(boost::string_view s) override
|
||||
{
|
||||
auto jv = nlohmann::json::parse(
|
||||
s.begin(), s.end());
|
||||
}
|
||||
};
|
||||
|
||||
@ -334,7 +381,7 @@ benchParse(
|
||||
auto const when = clock_type::now();
|
||||
dout << impl.name();
|
||||
while(repeat--)
|
||||
impl.parse(doc);
|
||||
impl.work(doc);
|
||||
auto const elapsed =
|
||||
std::chrono::duration_cast<
|
||||
std::chrono::milliseconds>(
|
||||
@ -361,11 +408,16 @@ load_file(char const* path)
|
||||
return s;
|
||||
}
|
||||
|
||||
void
|
||||
study();
|
||||
|
||||
int
|
||||
main(
|
||||
int const argc,
|
||||
char const* const* const argv)
|
||||
{
|
||||
study();
|
||||
|
||||
if(argc > 1)
|
||||
{
|
||||
std::vector<std::string> vs;
|
||||
@ -381,9 +433,9 @@ main(
|
||||
{
|
||||
v.clear();
|
||||
#if 1
|
||||
v.emplace_back(new nlohmann_impl);
|
||||
v.emplace_back(new nlohmann_impl);
|
||||
v.emplace_back(new nlohmann_impl);
|
||||
//v.emplace_back(new nlohmann_impl);
|
||||
//v.emplace_back(new nlohmann_impl);
|
||||
//v.emplace_back(new nlohmann_impl);
|
||||
v.emplace_back(new rapidjson_impl);
|
||||
v.emplace_back(new rapidjson_impl);
|
||||
v.emplace_back(new rapidjson_impl);
|
||||
@ -394,7 +446,7 @@ main(
|
||||
|
||||
dout << "File: " << argv[i + 1] << std::endl;
|
||||
for(auto& impl : v)
|
||||
benchParse(vs[i], *impl, 100);
|
||||
benchParse(vs[i], *impl, 1);
|
||||
dout << std::endl;
|
||||
}
|
||||
}
|
||||
@ -432,3 +484,12 @@ main(
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
study()
|
||||
{
|
||||
json::string_view js = "[\"\xFF""\"]";
|
||||
rapidjson::Document d;
|
||||
d.Parse(js.data(), js.size());
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <boost/json/basic_parser.hpp>
|
||||
#include <boost/json/error.hpp>
|
||||
#include <boost/json/fixed_storage.hpp>
|
||||
#include <boost/json/ieee_decimal.hpp>
|
||||
#include <boost/json/kind.hpp>
|
||||
#include <boost/json/number.hpp>
|
||||
#include <boost/json/object.hpp>
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
#include <boost/json/detail/config.hpp>
|
||||
#include <boost/json/error.hpp>
|
||||
#include <boost/json/number.hpp>
|
||||
#include <boost/json/ieee_decimal.hpp>
|
||||
#include <boost/json/detail/basic_parser.hpp>
|
||||
#include <boost/json/detail/stack.hpp>
|
||||
#include <boost/json/detail/string.hpp>
|
||||
|
@ -70,6 +70,15 @@ public:
|
||||
buf_[size_++] = ch;
|
||||
}
|
||||
|
||||
// returns true if cp is a valid utf-32 code point
|
||||
static
|
||||
bool
|
||||
is_valid(unsigned long cp) noexcept
|
||||
{
|
||||
return cp <= 0x0010ffffu &&
|
||||
(cp < 0xd800u || cp > 0xdfffu);
|
||||
}
|
||||
|
||||
// append valid 32-bit code point as utf8
|
||||
void
|
||||
append_utf8(
|
||||
|
@ -7,8 +7,8 @@
|
||||
// Official repository: https://github.com/vinniefalco/json
|
||||
//
|
||||
|
||||
#ifndef BOOST_JSON_DETAIL_NUMBER_HPP
|
||||
#define BOOST_JSON_DETAIL_NUMBER_HPP
|
||||
#ifndef BOOST_JSON_DETAIL_MATH_HPP
|
||||
#define BOOST_JSON_DETAIL_MATH_HPP
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
36
include/boost/json/ieee_decimal.hpp
Normal file
36
include/boost/json/ieee_decimal.hpp
Normal file
@ -0,0 +1,36 @@
|
||||
//
|
||||
// Copyright (c) 2018-2019 Vinnie Falco (vinnie dot falco at gmail dot 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/vinniefalco/json
|
||||
//
|
||||
|
||||
#ifndef BOOST_JSON_IEEE_DECIMAL_HPP
|
||||
#define BOOST_JSON_IEEE_DECIMAL_HPP
|
||||
|
||||
#include <boost/json/detail/config.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
||||
|
||||
struct ieee_decimal
|
||||
{
|
||||
unsigned long long mantissa;
|
||||
short exponent;
|
||||
bool sign;
|
||||
};
|
||||
|
||||
BOOST_JSON_DECL
|
||||
double
|
||||
to_double(ieee_decimal const& dec) noexcept;
|
||||
|
||||
} // json
|
||||
} // boost
|
||||
|
||||
#ifdef BOOST_JSON_HEADER_ONLY
|
||||
#include <boost/json/impl/ieee_decimal.ipp>
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1303,7 +1303,6 @@ write_eof(error_code& ec)
|
||||
ec = {};
|
||||
}
|
||||
|
||||
|
||||
} // json
|
||||
} // boost
|
||||
|
||||
|
47
include/boost/json/impl/ieee_decimal.ipp
Normal file
47
include/boost/json/impl/ieee_decimal.ipp
Normal file
@ -0,0 +1,47 @@
|
||||
//
|
||||
// Copyright (c) 2018-2019 Vinnie Falco (vinnie dot falco at gmail dot 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/vinniefalco/json
|
||||
//
|
||||
|
||||
#ifndef BOOST_JSON_IMPL_IEEE_DECIMAL_IPP
|
||||
#define BOOST_JSON_IMPL_IEEE_DECIMAL_IPP
|
||||
|
||||
#include <boost/json/detail/config.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
||||
|
||||
namespace detail {
|
||||
|
||||
} // detail
|
||||
|
||||
/*
|
||||
struct ieee_decimal
|
||||
{
|
||||
unsigned long long mantissa;
|
||||
short exponent;
|
||||
bool sign;
|
||||
};
|
||||
*/
|
||||
|
||||
double
|
||||
to_double(
|
||||
ieee_decimal const& dec) noexcept
|
||||
{
|
||||
(void)dec;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
} // json
|
||||
} // boost
|
||||
|
||||
#ifdef BOOST_JSON_HEADER_ONLY
|
||||
#include <boost/json/impl/ieee_decimal.ipp>
|
||||
#endif
|
||||
|
||||
#endif
|
@ -11,7 +11,7 @@
|
||||
#define BOOST_JSON_IMPL_NUMBER_IPP
|
||||
|
||||
#include <boost/json/number.hpp>
|
||||
#include <boost/json/detail/number.hpp>
|
||||
#include <boost/json/detail/math.hpp>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
@ -32,6 +32,8 @@ namespace json {
|
||||
https://www.ampl.com/netlib/fp/dtoa.c
|
||||
|
||||
https://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/
|
||||
|
||||
https://kkimdev.github.io/posts/2018/06/15/IEEE-754-Floating-Point-Type-in-C++.html
|
||||
*/
|
||||
|
||||
//----------------------------------------------------------
|
||||
@ -44,7 +46,7 @@ number::
|
||||
number::
|
||||
number() noexcept
|
||||
: sp_(default_storage())
|
||||
, k_(kind::type_int64)
|
||||
, kind_(kind::type_int64)
|
||||
{
|
||||
int64_ = 0;
|
||||
}
|
||||
@ -52,7 +54,7 @@ number() noexcept
|
||||
number::
|
||||
number(storage_ptr sp) noexcept
|
||||
: sp_(std::move(sp))
|
||||
, k_(kind::type_int64)
|
||||
, kind_(kind::type_int64)
|
||||
{
|
||||
int64_ = 0;
|
||||
}
|
||||
@ -60,10 +62,10 @@ number(storage_ptr sp) noexcept
|
||||
number::
|
||||
number(pilfered<number> p) noexcept
|
||||
: sp_(std::move(p.get().sp_))
|
||||
, k_(p.get().k_)
|
||||
, kind_(p.get().kind_)
|
||||
{
|
||||
auto& other = p.get();
|
||||
switch(k_)
|
||||
switch(kind_)
|
||||
{
|
||||
default:
|
||||
case kind::type_double:
|
||||
@ -83,9 +85,9 @@ number(pilfered<number> p) noexcept
|
||||
number::
|
||||
number(number const& other)
|
||||
: sp_(other.sp_)
|
||||
, k_(other.k_)
|
||||
, kind_(other.kind_)
|
||||
{
|
||||
switch(k_)
|
||||
switch(kind_)
|
||||
{
|
||||
default:
|
||||
case kind::type_double:
|
||||
@ -107,9 +109,9 @@ number(
|
||||
number const& other,
|
||||
storage_ptr sp)
|
||||
: sp_(std::move(sp))
|
||||
, k_(other.k_)
|
||||
, kind_(other.kind_)
|
||||
{
|
||||
switch(k_)
|
||||
switch(kind_)
|
||||
{
|
||||
default:
|
||||
case kind::type_double:
|
||||
@ -129,9 +131,9 @@ number(
|
||||
number::
|
||||
number(number&& other)
|
||||
: sp_(other.sp_)
|
||||
, k_(other.k_)
|
||||
, kind_(other.kind_)
|
||||
{
|
||||
switch(k_)
|
||||
switch(kind_)
|
||||
{
|
||||
default:
|
||||
case kind::type_double:
|
||||
@ -153,9 +155,9 @@ number(
|
||||
number&& other,
|
||||
storage_ptr sp)
|
||||
: sp_(std::move(sp))
|
||||
, k_(other.k_)
|
||||
, kind_(other.kind_)
|
||||
{
|
||||
switch(k_)
|
||||
switch(kind_)
|
||||
{
|
||||
default:
|
||||
case kind::type_double:
|
||||
@ -176,8 +178,8 @@ number&
|
||||
number::
|
||||
operator=(number const& other)
|
||||
{
|
||||
k_ = other.k_;
|
||||
switch(k_)
|
||||
kind_ = other.kind_;
|
||||
switch(kind_)
|
||||
{
|
||||
default:
|
||||
case kind::type_double:
|
||||
@ -198,135 +200,71 @@ operator=(number const& other)
|
||||
//----------------------------------------------------------
|
||||
|
||||
number::
|
||||
number(
|
||||
mantissa_type mant,
|
||||
exponent_type exp,
|
||||
bool sign) noexcept
|
||||
number(ieee_decimal const& dec) noexcept
|
||||
{
|
||||
auto const as_double =
|
||||
[&]
|
||||
{
|
||||
double d = static_cast<
|
||||
double>(mant) * detail::pow10(exp);
|
||||
if(sign)
|
||||
double d;
|
||||
if(dec.exponent >= 0)
|
||||
d = static_cast<
|
||||
double>(dec.mantissa) *
|
||||
std::pow(10., dec.exponent);
|
||||
else
|
||||
d = static_cast<
|
||||
double>(dec.mantissa) /
|
||||
std::pow(10., -dec.exponent);
|
||||
if(dec.sign)
|
||||
d *= -1;
|
||||
return d;
|
||||
};
|
||||
|
||||
if(exp == 0)
|
||||
if(dec.exponent == 0)
|
||||
{
|
||||
if(! sign)
|
||||
if(! dec.sign)
|
||||
{
|
||||
assign_unsigned(mant);
|
||||
assign_impl(dec.mantissa);
|
||||
}
|
||||
else if(mant <= static_cast<unsigned long long>(
|
||||
else if(dec.mantissa <= static_cast<unsigned long long>(
|
||||
(std::numeric_limits<long long>::max)()) + 1)
|
||||
{
|
||||
assign_signed(static_cast<long long>(mant));
|
||||
assign_impl(static_cast<
|
||||
long long>(dec.mantissa));
|
||||
}
|
||||
else
|
||||
{
|
||||
assign_double(as_double());
|
||||
assign_impl(as_double());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto const d = as_double();
|
||||
if(! sign)
|
||||
if(! dec.sign)
|
||||
{
|
||||
auto v = static_cast<unsigned long long>(d);
|
||||
if(v == d)
|
||||
assign_unsigned(v);
|
||||
assign_impl(v);
|
||||
else
|
||||
assign_double(d);
|
||||
assign_impl(d);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto v = static_cast<long long>(d);
|
||||
if(v == d)
|
||||
assign_signed(v);
|
||||
assign_impl(v);
|
||||
else
|
||||
assign_double(d);
|
||||
assign_impl(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
number::
|
||||
number(short i) noexcept
|
||||
{
|
||||
assign_signed(i);
|
||||
}
|
||||
|
||||
number::
|
||||
number(int i) noexcept
|
||||
{
|
||||
assign_signed(i);
|
||||
}
|
||||
|
||||
number::
|
||||
number(long i) noexcept
|
||||
{
|
||||
assign_signed(i);
|
||||
}
|
||||
|
||||
number::
|
||||
number(long long i) noexcept
|
||||
{
|
||||
assign_signed(i);
|
||||
}
|
||||
|
||||
number::
|
||||
number(unsigned short i) noexcept
|
||||
{
|
||||
assign_unsigned(i);
|
||||
}
|
||||
|
||||
number::
|
||||
number(unsigned int i) noexcept
|
||||
{
|
||||
assign_unsigned(i);
|
||||
}
|
||||
|
||||
number::
|
||||
number(unsigned long i) noexcept
|
||||
{
|
||||
assign_unsigned(i);
|
||||
}
|
||||
|
||||
number::
|
||||
number(unsigned long long i) noexcept
|
||||
{
|
||||
assign_unsigned(i);
|
||||
}
|
||||
|
||||
number::
|
||||
number(float f) noexcept
|
||||
{
|
||||
assign_double(f);
|
||||
}
|
||||
|
||||
number::
|
||||
number(double f) noexcept
|
||||
{
|
||||
assign_double(f);
|
||||
}
|
||||
|
||||
number::
|
||||
number(long double f) noexcept
|
||||
{
|
||||
assign_double(static_cast<
|
||||
double>(f));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
bool
|
||||
number::
|
||||
is_int64() const noexcept
|
||||
{
|
||||
switch(k_)
|
||||
switch(kind_)
|
||||
{
|
||||
default:
|
||||
case kind::type_int64:
|
||||
@ -345,7 +283,7 @@ bool
|
||||
number::
|
||||
is_uint64() const noexcept
|
||||
{
|
||||
switch(k_)
|
||||
switch(kind_)
|
||||
{
|
||||
default:
|
||||
case kind::type_int64:
|
||||
@ -365,7 +303,7 @@ std::int_least64_t
|
||||
number::
|
||||
get_int64() const noexcept
|
||||
{
|
||||
switch(k_)
|
||||
switch(kind_)
|
||||
{
|
||||
default:
|
||||
case kind::type_int64:
|
||||
@ -385,7 +323,7 @@ std::uint_least64_t
|
||||
number::
|
||||
get_uint64() const noexcept
|
||||
{
|
||||
switch(k_)
|
||||
switch(kind_)
|
||||
{
|
||||
default:
|
||||
case kind::type_int64:
|
||||
@ -405,7 +343,7 @@ double
|
||||
number::
|
||||
get_double() const noexcept
|
||||
{
|
||||
switch(k_)
|
||||
switch(kind_)
|
||||
{
|
||||
default:
|
||||
case kind::type_int64:
|
||||
@ -426,7 +364,7 @@ print(
|
||||
std::size_t buf_size) const noexcept
|
||||
{
|
||||
int n;
|
||||
switch(k_)
|
||||
switch(kind_)
|
||||
{
|
||||
default:
|
||||
case kind::type_int64:
|
||||
@ -449,32 +387,6 @@ print(
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
void
|
||||
number::
|
||||
assign_signed(long long i) noexcept
|
||||
{
|
||||
k_ = kind::type_int64;
|
||||
int64_ = i;
|
||||
}
|
||||
|
||||
void
|
||||
number::
|
||||
assign_unsigned(unsigned long long i) noexcept
|
||||
{
|
||||
k_ = kind::type_uint64;
|
||||
uint64_ = i;
|
||||
}
|
||||
|
||||
void
|
||||
number::
|
||||
assign_double(double f) noexcept
|
||||
{
|
||||
k_ = kind::type_double;
|
||||
double_ = f;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, number const& n)
|
||||
{
|
||||
@ -488,7 +400,7 @@ operator==(
|
||||
number const& lhs,
|
||||
number const& rhs) noexcept
|
||||
{
|
||||
switch(lhs.k_)
|
||||
switch(lhs.kind_)
|
||||
{
|
||||
default:
|
||||
case number::kind::type_int64:
|
||||
|
@ -323,7 +323,7 @@ void
|
||||
parser::
|
||||
on_number(ieee_decimal dec, error_code&)
|
||||
{
|
||||
number n(dec.mantissa, dec.exponent, dec.sign);
|
||||
number n(dec);
|
||||
auto& jv = *stack_.front();
|
||||
BOOST_JSON_ASSERT(! jv.is_object());
|
||||
if(obj_)
|
||||
@ -359,6 +359,32 @@ on_null(error_code&)
|
||||
assign(nullptr);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
value
|
||||
parse(
|
||||
string_view s,
|
||||
storage_ptr sp,
|
||||
error_code& ec)
|
||||
{
|
||||
parser p(std::move(sp));
|
||||
p.write(s.data(), s.size(), ec);
|
||||
return p.release();
|
||||
}
|
||||
|
||||
value
|
||||
parse(
|
||||
string_view s,
|
||||
storage_ptr sp)
|
||||
{
|
||||
error_code ec;
|
||||
auto jv = parse(s, std::move(sp), ec);
|
||||
if(ec)
|
||||
BOOST_JSON_THROW(
|
||||
system_error(ec));
|
||||
return jv;
|
||||
}
|
||||
|
||||
} // json
|
||||
} // boost
|
||||
|
||||
|
@ -21,16 +21,10 @@ enum class serializer::state : char
|
||||
inc, // increment iterator
|
||||
val, // value
|
||||
|
||||
key1, // '"'
|
||||
key2, // escaped string
|
||||
key3, // '"'
|
||||
key4, // ':'
|
||||
key5, // literal (ctrl or utf16 escape)
|
||||
|
||||
str1, // '"'
|
||||
str2, // escaped string
|
||||
str3, // '"'
|
||||
str4, // ','
|
||||
str4, // ':' or ','
|
||||
str5, // literal (ctrl or utf16 escape)
|
||||
|
||||
lit, // literal string ({number}, true, false, null)
|
||||
@ -90,8 +84,9 @@ loop:
|
||||
}
|
||||
if(e.has_key)
|
||||
{
|
||||
key_ = it_->key;
|
||||
state_ = state::key1;
|
||||
key_ = true;
|
||||
str_ = it_->key;
|
||||
state_ = state::str1;
|
||||
goto loop;
|
||||
}
|
||||
BOOST_FALLTHROUGH;
|
||||
@ -118,6 +113,7 @@ loop:
|
||||
goto loop;
|
||||
|
||||
case kind::string:
|
||||
key_ = false;
|
||||
str_ = *e.value.if_string();
|
||||
state_ = state::str1;
|
||||
goto loop;
|
||||
@ -154,49 +150,6 @@ loop:
|
||||
|
||||
//---
|
||||
|
||||
case state::key1:
|
||||
if(p >= p1)
|
||||
goto finish;
|
||||
*p++ = '\"';
|
||||
state_ = state::key2;
|
||||
BOOST_FALLTHROUGH;
|
||||
|
||||
case state::key2:
|
||||
{
|
||||
auto const n =
|
||||
key_.copy(p, p1 - p);
|
||||
p += n;
|
||||
if(n < key_.size())
|
||||
{
|
||||
BOOST_JSON_ASSERT(p >= p1);
|
||||
key_ = key_.substr(n);
|
||||
goto finish;
|
||||
}
|
||||
state_ = state::key3;
|
||||
BOOST_FALLTHROUGH;
|
||||
}
|
||||
|
||||
case state::key3:
|
||||
if(p >= p1)
|
||||
goto finish;
|
||||
*p++ = '\"';
|
||||
state_ = state::key4;
|
||||
BOOST_FALLTHROUGH;
|
||||
|
||||
case state::key4:
|
||||
if(p >= p1)
|
||||
goto finish;
|
||||
*p++ = ':';
|
||||
state_ = state::val;
|
||||
goto loop;
|
||||
|
||||
case state::key5:
|
||||
if(p >= p1)
|
||||
goto finish;
|
||||
break;
|
||||
|
||||
//---
|
||||
|
||||
case state::str1:
|
||||
if(p >= p1)
|
||||
goto finish;
|
||||
@ -244,7 +197,8 @@ loop:
|
||||
state_ = state::str5;
|
||||
goto loop;
|
||||
}
|
||||
else if(ch >= 32)
|
||||
else if(static_cast<
|
||||
unsigned char>(ch) >= 32)
|
||||
{
|
||||
*p++ = ch;
|
||||
continue;
|
||||
@ -257,8 +211,12 @@ loop:
|
||||
buf_[4] = 'u';
|
||||
buf_[3] = '0';
|
||||
buf_[2] = '0';
|
||||
buf_[1] = "0123456789abcdef"[ch >> 4];
|
||||
buf_[0] = "0123456789abcdef"[ch & 15];
|
||||
static constexpr char hex[] =
|
||||
"0123456789abcdef";
|
||||
buf_[1] = hex[static_cast<
|
||||
unsigned char>(ch) >> 4];
|
||||
buf_[0] = hex[static_cast<
|
||||
unsigned char>(ch) & 15];
|
||||
nbuf_ = 6;
|
||||
state_ = state::str5;
|
||||
goto loop;
|
||||
@ -278,7 +236,7 @@ loop:
|
||||
if(p >= p1)
|
||||
goto finish;
|
||||
*p++ = '\"';
|
||||
if(it_->last)
|
||||
if(it_->last && ! key_)
|
||||
{
|
||||
state_ = state::inc;
|
||||
goto loop;
|
||||
@ -289,8 +247,16 @@ loop:
|
||||
case state::str4:
|
||||
if(p >= p1)
|
||||
goto finish;
|
||||
*p++ = ',';
|
||||
state_ = state::inc;
|
||||
if(key_)
|
||||
{
|
||||
*p++ = ':';
|
||||
state_ = state::val;
|
||||
}
|
||||
else
|
||||
{
|
||||
*p++ = ',';
|
||||
state_ = state::inc;
|
||||
}
|
||||
goto loop;
|
||||
|
||||
case state::str5:
|
||||
@ -329,6 +295,29 @@ finish:
|
||||
return p - p0;
|
||||
}
|
||||
|
||||
std::string
|
||||
to_string(
|
||||
json::value const& jv)
|
||||
{
|
||||
std::string s;
|
||||
std::size_t len = 0;
|
||||
s.resize(1024);
|
||||
json::serializer p(jv);
|
||||
for(;;)
|
||||
{
|
||||
auto const used = p.next(
|
||||
&s[len], s.size() - len);
|
||||
len += used;
|
||||
s.resize(len);
|
||||
if(p.is_done())
|
||||
break;
|
||||
s.resize((len * 3) / 2);
|
||||
}
|
||||
s.shrink_to_fit();
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, value const& jv)
|
||||
{
|
||||
|
@ -11,6 +11,7 @@
|
||||
#define BOOST_JSON_NUMBER_HPP
|
||||
|
||||
#include <boost/json/detail/config.hpp>
|
||||
#include <boost/json/ieee_decimal.hpp>
|
||||
#include <boost/json/storage.hpp>
|
||||
#include <boost/json/detail/string.hpp>
|
||||
#include <boost/pilfer.hpp>
|
||||
@ -21,12 +22,33 @@
|
||||
namespace boost {
|
||||
namespace json {
|
||||
|
||||
struct ieee_decimal
|
||||
{
|
||||
std::uint64_t mantissa;
|
||||
short exponent;
|
||||
bool sign;
|
||||
};
|
||||
namespace detail {
|
||||
|
||||
template<class T>
|
||||
using remove_cv_t = typename
|
||||
std::remove_cv<T>::type;
|
||||
|
||||
} // detail
|
||||
|
||||
/** Metafunction returning `true` if a `T` can be assigned to @ref number
|
||||
*/
|
||||
#ifdef GENERATING_DOCUMENTATION
|
||||
template<class T>
|
||||
using is_number = __see_below__;
|
||||
#else
|
||||
template<class T>
|
||||
using is_number =
|
||||
std::integral_constant<bool,
|
||||
std::is_arithmetic<T>::value &&
|
||||
! std::is_same<detail::remove_cv_t<T>,
|
||||
bool>::value &&
|
||||
! std::is_same<detail::remove_cv_t<T>,
|
||||
char>::value &&
|
||||
! std::is_same<detail::remove_cv_t<T>,
|
||||
wchar_t>::value &&
|
||||
! std::is_same<detail::remove_cv_t<T>,
|
||||
unsigned char>::value>;
|
||||
#endif
|
||||
|
||||
/** The representation of parsed numbers.
|
||||
*/
|
||||
@ -45,14 +67,13 @@ class number
|
||||
// The XSLT has problems with private anon unions
|
||||
union
|
||||
{
|
||||
unsigned
|
||||
long long uint64_;
|
||||
long long int64_;
|
||||
double double_;
|
||||
double double_;
|
||||
long long int64_;
|
||||
unsigned long long uint64_;
|
||||
};
|
||||
#endif
|
||||
|
||||
kind k_;
|
||||
kind kind_;
|
||||
|
||||
public:
|
||||
static std::size_t constexpr
|
||||
@ -68,12 +89,6 @@ public:
|
||||
#endif
|
||||
;
|
||||
|
||||
using mantissa_type =
|
||||
unsigned long long;
|
||||
|
||||
using exponent_type =
|
||||
short;
|
||||
|
||||
//------------------------------------------------------
|
||||
|
||||
BOOST_JSON_DECL
|
||||
@ -114,54 +129,19 @@ public:
|
||||
/** Construct a number from mantissa, exponent, and sign
|
||||
*/
|
||||
BOOST_JSON_DECL
|
||||
number(
|
||||
mantissa_type mant,
|
||||
exponent_type exp,
|
||||
bool sign) noexcept;
|
||||
explicit
|
||||
number(ieee_decimal const& dec) noexcept;
|
||||
|
||||
/// Construct a number from a signed integer
|
||||
BOOST_JSON_DECL
|
||||
number(short v) noexcept;
|
||||
|
||||
/// Construct a number from a signed integer
|
||||
BOOST_JSON_DECL
|
||||
number(int v) noexcept;
|
||||
|
||||
/// Construct a number from a signed integer
|
||||
BOOST_JSON_DECL
|
||||
number(long v) noexcept;
|
||||
|
||||
/// Construct a number from a signed integer
|
||||
BOOST_JSON_DECL
|
||||
number(long long v) noexcept;
|
||||
|
||||
/// Construct a number from an unsigned integer
|
||||
BOOST_JSON_DECL
|
||||
number(unsigned short v) noexcept;
|
||||
|
||||
/// Construct a number from an unsigned integer
|
||||
BOOST_JSON_DECL
|
||||
number(unsigned int v) noexcept;
|
||||
|
||||
/// Construct a number from an unsigned integer
|
||||
BOOST_JSON_DECL
|
||||
number(unsigned long v) noexcept;
|
||||
|
||||
/// Construct a number from an unsigned integer
|
||||
BOOST_JSON_DECL
|
||||
number(unsigned long long v) noexcept;
|
||||
|
||||
/// Construct a number from a floating point value
|
||||
BOOST_JSON_DECL
|
||||
number(float v) noexcept;
|
||||
|
||||
/// Construct a number from a floating point value
|
||||
BOOST_JSON_DECL
|
||||
number(double v) noexcept;
|
||||
|
||||
/// Construct a number from a floating point value
|
||||
BOOST_JSON_DECL
|
||||
number(long double v) noexcept;
|
||||
template<class T
|
||||
#ifndef GENERATING_DOCUMENTATION
|
||||
,class = typename std::enable_if<
|
||||
is_number<T>::value>::type
|
||||
#endif
|
||||
>
|
||||
number(T t) noexcept
|
||||
{
|
||||
assign_impl(t);
|
||||
}
|
||||
|
||||
storage_ptr const&
|
||||
get_storage() const noexcept
|
||||
@ -226,21 +206,41 @@ public:
|
||||
std::size_t buf_size) const noexcept;
|
||||
|
||||
private:
|
||||
struct pow10;
|
||||
|
||||
inline
|
||||
template<class T>
|
||||
void
|
||||
assign_signed(
|
||||
long long i) noexcept;
|
||||
assign_impl(T t,
|
||||
typename std::enable_if<
|
||||
std::is_unsigned<
|
||||
T>::value>::type* = 0) noexcept
|
||||
{
|
||||
kind_ = kind::type_uint64;
|
||||
uint64_ = t;
|
||||
}
|
||||
|
||||
inline
|
||||
template<class T>
|
||||
void
|
||||
assign_unsigned(
|
||||
unsigned long long i) noexcept;
|
||||
assign_impl(T t,
|
||||
typename std::enable_if<
|
||||
std::is_signed<T>::value &&
|
||||
std::is_integral<T>::value
|
||||
>::type* = 0) noexcept
|
||||
{
|
||||
kind_ = kind::type_int64;
|
||||
int64_ = t;
|
||||
}
|
||||
|
||||
inline
|
||||
template<class T>
|
||||
void
|
||||
assign_double(double f) noexcept;
|
||||
assign_impl(T t,
|
||||
typename std::enable_if<
|
||||
! std::is_integral<
|
||||
T>::value>::type* = 0) noexcept
|
||||
{
|
||||
kind_ = kind::type_double;
|
||||
// VFALCO silence warnings
|
||||
// when `T` is `long double`.
|
||||
double_ = static_cast<double>(t);
|
||||
}
|
||||
|
||||
BOOST_JSON_DECL
|
||||
friend
|
||||
@ -261,7 +261,6 @@ private:
|
||||
number const& lhs,
|
||||
number const& rhs) noexcept;
|
||||
|
||||
|
||||
inline
|
||||
storage_ptr
|
||||
release_storage() noexcept
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <boost/json/basic_parser.hpp>
|
||||
#include <boost/json/storage.hpp>
|
||||
#include <boost/json/value.hpp>
|
||||
#include <boost/json/storage.hpp>
|
||||
#include <boost/json/detail/string.hpp>
|
||||
#include <new>
|
||||
#include <string>
|
||||
@ -162,6 +163,39 @@ private:
|
||||
on_null(error_code&) override;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
BOOST_JSON_DECL
|
||||
value
|
||||
parse(
|
||||
string_view s,
|
||||
storage_ptr sp,
|
||||
error_code& ec);
|
||||
|
||||
inline
|
||||
value
|
||||
parse(
|
||||
string_view s,
|
||||
error_code& ec)
|
||||
{
|
||||
return parse(s,
|
||||
default_storage(), ec);
|
||||
}
|
||||
|
||||
BOOST_JSON_DECL
|
||||
value
|
||||
parse(
|
||||
string_view s,
|
||||
storage_ptr sp);
|
||||
|
||||
inline
|
||||
value
|
||||
parse(string_view s)
|
||||
{
|
||||
return parse(
|
||||
s, default_storage());
|
||||
}
|
||||
|
||||
} // json
|
||||
} // boost
|
||||
|
||||
|
@ -25,9 +25,9 @@ class serializer
|
||||
enum class state : char;
|
||||
|
||||
detail::const_iterator it_;
|
||||
string_view key_;
|
||||
string_view str_;
|
||||
unsigned char nbuf_;
|
||||
bool key_;
|
||||
char buf_[number::max_string_chars + 1];
|
||||
state state_;
|
||||
|
||||
@ -45,6 +45,10 @@ public:
|
||||
next(char* dest, std::size_t size);
|
||||
};
|
||||
|
||||
BOOST_JSON_DECL
|
||||
std::string
|
||||
to_string(value const& jv);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
std::ostream&
|
||||
operator<<(
|
||||
|
@ -26,6 +26,7 @@ the program, with the macro BOOST_BEAST_SPLIT_COMPILATION defined.
|
||||
#include <boost/json/impl/array.ipp>
|
||||
#include <boost/json/impl/basic_parser.ipp>
|
||||
#include <boost/json/impl/error.ipp>
|
||||
#include <boost/json/impl/ieee_decimal.ipp>
|
||||
#include <boost/json/impl/number.ipp>
|
||||
#include <boost/json/impl/object.ipp>
|
||||
#include <boost/json/impl/parser.ipp>
|
||||
|
@ -35,6 +35,7 @@ add_executable (json-tests
|
||||
assign_vector.cpp
|
||||
basic_parser.cpp
|
||||
error.cpp
|
||||
ieee_decimal.cpp
|
||||
json.cpp
|
||||
kind.cpp
|
||||
number.cpp
|
||||
|
@ -31,6 +31,7 @@ local SOURCES =
|
||||
assign_vector.cpp
|
||||
basic_parser.cpp
|
||||
error.cpp
|
||||
ieee_decimal.cpp
|
||||
json.cpp
|
||||
kind.cpp
|
||||
number.cpp
|
||||
|
31
test/ieee_decimal.cpp
Normal file
31
test/ieee_decimal.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
//
|
||||
// Copyright (c) 2018-2019 Vinnie Falco (vinnie dot falco at gmail dot 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/vinniefalco/json
|
||||
//
|
||||
|
||||
// Test that header file is self-contained.
|
||||
#include <boost/json/ieee_decimal.hpp>
|
||||
|
||||
#include <boost/beast/_experimental/unit_test/suite.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
||||
|
||||
class ieee_decimal_test : public beast::unit_test::suite
|
||||
{
|
||||
public:
|
||||
void run() override
|
||||
{
|
||||
pass();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(boost,json,ieee_decimal);
|
||||
|
||||
} // json
|
||||
} // boost
|
@ -19,7 +19,7 @@ def escape(c):
|
||||
n = ord(c);
|
||||
if n >= 32 and n <= 127:
|
||||
return c;
|
||||
return chex(c);
|
||||
return chex(c) + "\"\"";
|
||||
|
||||
def tocpp(s):
|
||||
v0 = ""
|
||||
|
@ -20,6 +20,23 @@ namespace json {
|
||||
class number_test : public beast::unit_test::suite
|
||||
{
|
||||
public:
|
||||
BOOST_JSON_STATIC_ASSERT(is_number<int>::value);
|
||||
BOOST_JSON_STATIC_ASSERT(is_number<short>::value);
|
||||
BOOST_JSON_STATIC_ASSERT(is_number<long>::value);
|
||||
BOOST_JSON_STATIC_ASSERT(is_number<long long>::value);
|
||||
BOOST_JSON_STATIC_ASSERT(is_number<unsigned int>::value);
|
||||
BOOST_JSON_STATIC_ASSERT(is_number<unsigned short>::value);
|
||||
BOOST_JSON_STATIC_ASSERT(is_number<unsigned long>::value);
|
||||
BOOST_JSON_STATIC_ASSERT(is_number<unsigned long long>::value);
|
||||
BOOST_JSON_STATIC_ASSERT(is_number<float>::value);
|
||||
BOOST_JSON_STATIC_ASSERT(is_number<double>::value);
|
||||
BOOST_JSON_STATIC_ASSERT(is_number<long double>::value);
|
||||
|
||||
BOOST_JSON_STATIC_ASSERT(! is_number<char>::value);
|
||||
BOOST_JSON_STATIC_ASSERT(! is_number<wchar_t>::value);
|
||||
BOOST_JSON_STATIC_ASSERT(! is_number<unsigned char>::value);
|
||||
BOOST_JSON_STATIC_ASSERT(! is_number<bool>::value);
|
||||
|
||||
template<class I>
|
||||
void
|
||||
check(I v
|
||||
@ -49,9 +66,11 @@ public:
|
||||
n2 = n;
|
||||
BEAST_EXPECT(n == n2);
|
||||
BEAST_EXPECT(n.is_uint64());
|
||||
#if 0
|
||||
BEAST_EXPECT(number(static_cast<
|
||||
number::mantissa_type>(v),
|
||||
decltype(ieee_decimal::mantissa)>(v),
|
||||
0, false) == n);
|
||||
#endif
|
||||
BEAST_EXPECT(n.get_uint64() == v);
|
||||
BEAST_EXPECT(n.get_double() == v);
|
||||
}
|
||||
|
@ -11,20 +11,17 @@
|
||||
#ifndef PARSE_VECTORS
|
||||
#define PARSE_VECTORS
|
||||
|
||||
#include <boost/json/detail/string.hpp>
|
||||
#include <boost/utility/string_view.hpp>
|
||||
#include <cstdlib>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
||||
|
||||
struct parse_vectors
|
||||
{
|
||||
struct item
|
||||
{
|
||||
char result;
|
||||
string_view name;
|
||||
string_view text;
|
||||
::boost::string_view name;
|
||||
::boost::string_view text;
|
||||
};
|
||||
|
||||
using iterator = item const*;
|
||||
@ -64,9 +61,6 @@ parse_vectors::
|
||||
parse_vectors() noexcept
|
||||
{
|
||||
static item const list[] = {
|
||||
{ 'i', "number_huge_exp", lit("[0.4e006699999999999999999999999999999999999999999999999999999999999999999999999"
|
||||
"99999999999999999999999999999999999999999999969999999006]") },
|
||||
|
||||
{ 'i', "number_double_huge_neg_exp", lit("[123.456e-789]") },
|
||||
{ 'i', "number_huge_exp", lit("[0.4e006699999999999999999999999999999999999999999999999999999999999999999999999"
|
||||
"99999999999999999999999999999999999999999999969999999006]") },
|
||||
@ -86,21 +80,21 @@ parse_vectors() noexcept
|
||||
{ 'i', "string_incomplete_surrogate_pair", lit("[\"\\uDd1ea\"]") },
|
||||
{ 'i', "string_invalid_lonely_surrogate", lit("[\"\\ud800\"]") },
|
||||
{ 'i', "string_invalid_surrogate", lit("[\"\\ud800abc\"]") },
|
||||
{ 'i', "string_invalid_utf-8", lit("[\"\xFF\"]") },
|
||||
{ 'i', "string_invalid_utf-8", lit("[\"\xFF""\"]") },
|
||||
{ 'i', "string_inverted_surrogates_U+1D11E", lit("[\"\\uDd1e\\uD834\"]") },
|
||||
{ 'i', "string_iso_latin_1", lit("[\"\xE9\"]") },
|
||||
{ 'i', "string_iso_latin_1", lit("[\"\xE9""\"]") },
|
||||
{ 'i', "string_lone_second_surrogate", lit("[\"\\uDFAA\"]") },
|
||||
{ 'i', "string_lone_utf8_continuation_byte", lit("[\"\x81\"]") },
|
||||
{ 'i', "string_not_in_unicode_range", lit("[\"\xF4\xBF\xBF\xBF\"]") },
|
||||
{ 'i', "string_overlong_sequence_2_bytes", lit("[\"\xC0\xAF\"]") },
|
||||
{ 'i', "string_overlong_sequence_6_bytes", lit("[\"\xFC\x83\xBF\xBF\xBF\xBF\"]") },
|
||||
{ 'i', "string_overlong_sequence_6_bytes_null", lit("[\"\xFC\x80\x80\x80\x80\x80\"]") },
|
||||
{ 'i', "string_truncated-utf-8", lit("[\"\xE0\xFF\"]") },
|
||||
{ 'i', "string_UTF-16LE_with_BOM", lit("\xFF\xFE[\x00\"\x00\xE9\x00\"\x00]\x00") },
|
||||
{ 'i', "string_UTF-8_invalid_sequence", lit("[\"\xE6\x97\xA5\xD1\x88\xFA\"]") },
|
||||
{ 'i', "string_utf16BE_no_BOM", lit("\x00[\x00\"\x00\xE9\x00\"\x00]") },
|
||||
{ 'i', "string_utf16LE_no_BOM", lit("[\x00\"\x00\xE9\x00\"\x00]\x00") },
|
||||
{ 'i', "string_UTF8_surrogate_U+D800", lit("[\"\xED\xA0\x80\"]") },
|
||||
{ 'i', "string_lone_utf8_continuation_byte", lit("[\"\x81""\"]") },
|
||||
{ 'i', "string_not_in_unicode_range", lit("[\"\xF4""\xBF""\xBF""\xBF""\"]") },
|
||||
{ 'i', "string_overlong_sequence_2_bytes", lit("[\"\xC0""\xAF""\"]") },
|
||||
{ 'i', "string_overlong_sequence_6_bytes", lit("[\"\xFC""\x83""\xBF""\xBF""\xBF""\xBF""\"]") },
|
||||
{ 'i', "string_overlong_sequence_6_bytes_null", lit("[\"\xFC""\x80""\x80""\x80""\x80""\x80""\"]") },
|
||||
{ 'i', "string_truncated-utf-8", lit("[\"\xE0""\xFF""\"]") },
|
||||
{ 'i', "string_UTF-16LE_with_BOM", lit("\xFF""\xFE""[\x00""\"\x00""\xE9""\x00""\"\x00""]\x00""") },
|
||||
{ 'i', "string_UTF-8_invalid_sequence", lit("[\"\xE6""\x97""\xA5""\xD1""\x88""\xFA""\"]") },
|
||||
{ 'i', "string_utf16BE_no_BOM", lit("\x00""[\x00""\"\x00""\xE9""\x00""\"\x00""]") },
|
||||
{ 'i', "string_utf16LE_no_BOM", lit("[\x00""\"\x00""\xE9""\x00""\"\x00""]\x00""") },
|
||||
{ 'i', "string_UTF8_surrogate_U+D800", lit("[\"\xED""\xA0""\x80""\"]") },
|
||||
{ 'i', "structure_500_nested_arrays", lit("[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
|
||||
"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
|
||||
"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
|
||||
@ -114,9 +108,9 @@ parse_vectors() noexcept
|
||||
"]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]"
|
||||
"]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]"
|
||||
"]]]]]]]]]]]]]]]]]]]]]]]]]]]]]") },
|
||||
{ 'i', "structure_UTF-8_BOM_empty_object", lit("\xEF\xBB\xBF{}") },
|
||||
{ 'i', "structure_UTF-8_BOM_empty_object", lit("\xEF""\xBB""\xBF""{}") },
|
||||
{ 'n', "array_1_true_without_comma", lit("[1 true]") },
|
||||
{ 'n', "array_a_invalid_utf8", lit("[a\xE5]") },
|
||||
{ 'n', "array_a_invalid_utf8", lit("[a\xE5""]") },
|
||||
{ 'n', "array_colon_instead_of_comma", lit("[\"\": 1]") },
|
||||
{ 'n', "array_comma_after_close", lit("[\"\"],") },
|
||||
{ 'n', "array_comma_and_number", lit("[,1]") },
|
||||
@ -127,24 +121,55 @@ parse_vectors() noexcept
|
||||
{ 'n', "array_incomplete", lit("[\"x\"") },
|
||||
{ 'n', "array_incomplete_invalid_value", lit("[x") },
|
||||
{ 'n', "array_inner_array_no_comma", lit("[3[4]]") },
|
||||
{ 'n', "array_invalid_utf8", lit("[\xFF]") },
|
||||
{ 'n', "array_invalid_utf8", lit("[\xFF""]") },
|
||||
{ 'n', "array_items_separated_by_semicolon", lit("[1:2]") },
|
||||
{ 'n', "array_just_comma", lit("[,]") },
|
||||
{ 'n', "array_just_minus", lit("[-]") },
|
||||
{ 'n', "array_missing_value", lit("[ , \"\"]") },
|
||||
{ 'n', "array_newlines_unclosed", lit("[\"a\",\x0A4\x0A,1,") },
|
||||
{ 'n', "array_newlines_unclosed", lit("[\"a\",\x0A""4\x0A"",1,") },
|
||||
{ 'n', "array_number_and_comma", lit("[1,]") },
|
||||
{ 'n', "array_number_and_several_commas", lit("[1,,]") },
|
||||
{ 'n', "array_spaces_vertical_tab_formfeed", lit("[\"\x0Ba\"\\f]") },
|
||||
{ 'n', "array_spaces_vertical_tab_formfeed", lit("[\"\x0B""a\"\\f]") },
|
||||
{ 'n', "array_star_inside", lit("[*]") },
|
||||
{ 'n', "array_unclosed", lit("[\"\"") },
|
||||
{ 'n', "array_unclosed_trailing_comma", lit("[1,") },
|
||||
{ 'n', "array_unclosed_with_new_lines", lit("[1,\x0A1\x0A,1") },
|
||||
{ 'n', "array_unclosed_with_new_lines", lit("[1,\x0A""1\x0A"",1") },
|
||||
{ 'n', "array_unclosed_with_object_inside", lit("[{}") },
|
||||
{ 'n', "fail01", lit("[\"mismatch\"}") },
|
||||
{ 'n', "fail02", lit("[\"Unclosed array\"") },
|
||||
{ 'n', "fail03", lit("{unquoted_key: \"keys must be quoted\"}") },
|
||||
{ 'n', "fail04", lit("[\"extra comma\",]") },
|
||||
{ 'n', "fail05", lit("[\"double extra comma\",,]") },
|
||||
{ 'n', "fail06", lit("[ , \"<-- missing value\"]") },
|
||||
{ 'n', "fail07", lit("[\"Comma after the close\"],") },
|
||||
{ 'n', "fail08", lit("[\"Extra close\"]]") },
|
||||
{ 'n', "fail09", lit("{\"Extra comma\": true,}") },
|
||||
{ 'n', "fail10", lit("{\"Extra value after close\": true} \"misplaced quoted value\"") },
|
||||
{ 'n', "fail11", lit("{\"Illegal expression\": 1 + 2}") },
|
||||
{ 'n', "fail12", lit("{\"Illegal invocation\": alert()}") },
|
||||
{ 'n', "fail13", lit("{\"Numbers cannot have leading zeroes\": 013}") },
|
||||
{ 'n', "fail14", lit("{\"Numbers cannot be hex\": 0x14}") },
|
||||
{ 'n', "fail15", lit("[\"Illegal backslash escape: \\x15\"]") },
|
||||
{ 'n', "fail16", lit("[\\naked]") },
|
||||
{ 'n', "fail17", lit("[\"Illegal backslash escape: \\017\"]") },
|
||||
{ 'n', "fail19", lit("{\"Missing colon\" null}") },
|
||||
{ 'n', "fail20", lit("{\"Double colon\":: null}") },
|
||||
{ 'n', "fail21", lit("{\"Comma instead of colon\", null}") },
|
||||
{ 'n', "fail22", lit("[\"Colon instead of comma\": false]") },
|
||||
{ 'n', "fail23", lit("[\"Bad value\", truth]") },
|
||||
{ 'n', "fail24", lit("['single quote']") },
|
||||
{ 'n', "fail25", lit("[\" tab character in string \"]") },
|
||||
{ 'n', "fail26", lit("[\"tab\\ character\\ in\\ string\\ \"]") },
|
||||
{ 'n', "fail27", lit("[\"line\x0A""break\"]") },
|
||||
{ 'n', "fail28", lit("[\"line\\\x0A""break\"]") },
|
||||
{ 'n', "fail29", lit("[0e]") },
|
||||
{ 'n', "fail30", lit("[0e+]") },
|
||||
{ 'n', "fail31", lit("[0e+-1]") },
|
||||
{ 'n', "fail32", lit("{\"Comma instead if closing brace\": true,") },
|
||||
{ 'n', "incomplete_false", lit("[fals]") },
|
||||
{ 'n', "incomplete_null", lit("[nul]") },
|
||||
{ 'n', "incomplete_true", lit("[tru]") },
|
||||
{ 'n', "multidigit_number_then_00", lit("123\x00") },
|
||||
{ 'n', "multidigit_number_then_00", lit("123\x00""") },
|
||||
{ 'n', "number_++", lit("[++1234]") },
|
||||
{ 'n', "number_+1", lit("[+1]") },
|
||||
{ 'n', "number_+Inf", lit("[+Inf]") },
|
||||
@ -178,9 +203,9 @@ parse_vectors() noexcept
|
||||
{ 'n', "number_infinity", lit("[Infinity]") },
|
||||
{ 'n', "number_invalid+-", lit("[0e+-1]") },
|
||||
{ 'n', "number_invalid-negative-real", lit("[-123.123foo]") },
|
||||
{ 'n', "number_invalid-utf-8-in-bigger-int", lit("[123\xE5]") },
|
||||
{ 'n', "number_invalid-utf-8-in-exponent", lit("[1e1\xE5]") },
|
||||
{ 'n', "number_invalid-utf-8-in-int", lit("[0\xE5]\x0A") },
|
||||
{ 'n', "number_invalid-utf-8-in-bigger-int", lit("[123\xE5""]") },
|
||||
{ 'n', "number_invalid-utf-8-in-exponent", lit("[1e1\xE5""]") },
|
||||
{ 'n', "number_invalid-utf-8-in-int", lit("[0\xE5""]\x0A""") },
|
||||
{ 'n', "number_minus_infinity", lit("[-Infinity]") },
|
||||
{ 'n', "number_minus_sign_with_trailing_garbage", lit("[-foo]") },
|
||||
{ 'n', "number_minus_space_1", lit("[- 1]") },
|
||||
@ -190,20 +215,20 @@ parse_vectors() noexcept
|
||||
{ 'n', "number_neg_with_garbage_at_end", lit("[-1x]") },
|
||||
{ 'n', "number_real_garbage_after_e", lit("[1ea]") },
|
||||
{ 'n', "number_real_without_fractional_part", lit("[1.]") },
|
||||
{ 'n', "number_real_with_invalid_utf8_after_e", lit("[1e\xE5]") },
|
||||
{ 'n', "number_real_with_invalid_utf8_after_e", lit("[1e\xE5""]") },
|
||||
{ 'n', "number_starting_with_dot", lit("[.123]") },
|
||||
{ 'n', "number_U+FF11_fullwidth_digit_one", lit("[\xEF\xBC\x91]") },
|
||||
{ 'n', "number_U+FF11_fullwidth_digit_one", lit("[\xEF""\xBC""\x91""]") },
|
||||
{ 'n', "number_with_alpha", lit("[1.2a-3]") },
|
||||
{ 'n', "number_with_alpha_char", lit("[1.8011670033376514H-308]") },
|
||||
{ 'n', "number_with_leading_zero", lit("[012]") },
|
||||
{ 'n', "object_bad_value", lit("[\"x\", truth]") },
|
||||
{ 'n', "object_bracket_key", lit("{[: \"x\"}\x0A") },
|
||||
{ 'n', "object_bracket_key", lit("{[: \"x\"}\x0A""") },
|
||||
{ 'n', "object_comma_instead_of_colon", lit("{\"x\", null}") },
|
||||
{ 'n', "object_double_colon", lit("{\"x\"::\"b\"}") },
|
||||
{ 'n', "object_emoji", lit("{\xF0\x9F\x87\xA8\xF0\x9F\x87\xAD}") },
|
||||
{ 'n', "object_emoji", lit("{\xF0""\x9F""\x87""\xA8""\xF0""\x9F""\x87""\xAD""}") },
|
||||
{ 'n', "object_garbage_at_end", lit("{\"a\":\"a\" 123}") },
|
||||
{ 'n', "object_key_with_single_quotes", lit("{key: 'value'}") },
|
||||
{ 'n', "object_lone_continuation_byte_in_key_and_trailing_comma", lit("{\"\xB9\":\"0\",}") },
|
||||
{ 'n', "object_lone_continuation_byte_in_key_and_trailing_comma", lit("{\"\xB9""\":\"0\",}") },
|
||||
{ 'n', "object_missing_colon", lit("{\"a\" b}") },
|
||||
{ 'n', "object_missing_key", lit("{:\"b\"}") },
|
||||
{ 'n', "object_missing_semicolon", lit("{\"a\" \"b\"}") },
|
||||
@ -229,28 +254,28 @@ parse_vectors() noexcept
|
||||
{ 'n', "string_1_surrogate_then_escape_u", lit("[\"\\uD800\\u\"]") },
|
||||
{ 'n', "string_1_surrogate_then_escape_u1", lit("[\"\\uD800\\u1\"]") },
|
||||
{ 'n', "string_1_surrogate_then_escape_u1x", lit("[\"\\uD800\\u1x\"]") },
|
||||
{ 'n', "string_accentuated_char_no_quotes", lit("[\xC3\xA9]") },
|
||||
{ 'n', "string_backslash_00", lit("[\"\\\x00\"]") },
|
||||
{ 'n', "string_accentuated_char_no_quotes", lit("[\xC3""\xA9""]") },
|
||||
{ 'n', "string_backslash_00", lit("[\"\\\x00""\"]") },
|
||||
{ 'n', "string_escaped_backslash_bad", lit("[\"\\\\\\\"]") },
|
||||
{ 'n', "string_escaped_ctrl_char_tab", lit("[\"\\ \"]") },
|
||||
{ 'n', "string_escaped_emoji", lit("[\"\\\xF0\x9F\x8C\x80\"]") },
|
||||
{ 'n', "string_escaped_emoji", lit("[\"\\\xF0""\x9F""\x8C""\x80""\"]") },
|
||||
{ 'n', "string_escape_x", lit("[\"\\x00\"]") },
|
||||
{ 'n', "string_incomplete_escape", lit("[\"\\\"]") },
|
||||
{ 'n', "string_incomplete_escaped_character", lit("[\"\\u00A\"]") },
|
||||
{ 'n', "string_incomplete_surrogate", lit("[\"\\uD834\\uDd\"]") },
|
||||
{ 'n', "string_incomplete_surrogate_escape_invalid", lit("[\"\\uD800\\uD800\\x\"]") },
|
||||
{ 'n', "string_invalid-utf-8-in-escape", lit("[\"\\u\xE5\"]") },
|
||||
{ 'n', "string_invalid-utf-8-in-escape", lit("[\"\\u\xE5""\"]") },
|
||||
{ 'n', "string_invalid_backslash_esc", lit("[\"\\a\"]") },
|
||||
{ 'n', "string_invalid_unicode_escape", lit("[\"\\uqqqq\"]") },
|
||||
{ 'n', "string_invalid_utf8_after_escape", lit("[\"\\\xE5\"]") },
|
||||
{ 'n', "string_invalid_utf8_after_escape", lit("[\"\\\xE5""\"]") },
|
||||
{ 'n', "string_leading_uescaped_thinspace", lit("[\\u0020\"asd\"]") },
|
||||
{ 'n', "string_no_quotes_with_bad_escape", lit("[\\n]") },
|
||||
{ 'n', "string_single_doublequote", lit("\"") },
|
||||
{ 'n', "string_single_quote", lit("['single quote']") },
|
||||
{ 'n', "string_single_string_no_double_quotes", lit("abc") },
|
||||
{ 'n', "string_start_escape_unclosed", lit("[\"\\") },
|
||||
{ 'n', "string_unescaped_crtl_char", lit("[\"a\x00a\"]") },
|
||||
{ 'n', "string_unescaped_newline", lit("[\"new\x0Aline\"]") },
|
||||
{ 'n', "string_unescaped_crtl_char", lit("[\"a\x00""a\"]") },
|
||||
{ 'n', "string_unescaped_newline", lit("[\"new\x0A""line\"]") },
|
||||
{ 'n', "string_unescaped_tab", lit("[\" \"]") },
|
||||
{ 'n', "string_unicode_CapitalU", lit("\"\\UA66D\"") },
|
||||
{ 'n', "string_with_trailing_garbage", lit("\"\"x") },
|
||||
@ -766,17 +791,17 @@ parse_vectors() noexcept
|
||||
{ 'n', "structure_array_trailing_garbage", lit("[1]x") },
|
||||
{ 'n', "structure_array_with_extra_array_close", lit("[1]]") },
|
||||
{ 'n', "structure_array_with_unclosed_string", lit("[\"asd]") },
|
||||
{ 'n', "structure_ascii-unicode-identifier", lit("a\xC3\xA5") },
|
||||
{ 'n', "structure_ascii-unicode-identifier", lit("a\xC3""\xA5""") },
|
||||
{ 'n', "structure_capitalized_True", lit("[True]") },
|
||||
{ 'n', "structure_close_unopened_array", lit("1]") },
|
||||
{ 'n', "structure_comma_instead_of_closing_brace", lit("{\"x\": true,") },
|
||||
{ 'n', "structure_double_array", lit("[][]") },
|
||||
{ 'n', "structure_end_array", lit("]") },
|
||||
{ 'n', "structure_incomplete_UTF8_BOM", lit("\xEF\xBB{}") },
|
||||
{ 'n', "structure_lone-invalid-utf-8", lit("\xE5") },
|
||||
{ 'n', "structure_incomplete_UTF8_BOM", lit("\xEF""\xBB""{}") },
|
||||
{ 'n', "structure_lone-invalid-utf-8", lit("\xE5""") },
|
||||
{ 'n', "structure_lone-open-bracket", lit("[") },
|
||||
{ 'n', "structure_no_data", lit("") },
|
||||
{ 'n', "structure_null-byte-outside-string", lit("[\x00]") },
|
||||
{ 'n', "structure_null-byte-outside-string", lit("[\x00""]") },
|
||||
{ 'n', "structure_number_with_trailing_garbage", lit("2@") },
|
||||
{ 'n', "structure_object_followed_by_closing_object", lit("{}}") },
|
||||
{ 'n', "structure_object_unclosed_no_value", lit("{\"\":") },
|
||||
@ -1297,20 +1322,20 @@ parse_vectors() noexcept
|
||||
{ 'n', "structure_open_object_open_string", lit("{\"a") },
|
||||
{ 'n', "structure_open_object_string_with_apostrophes", lit("{'a'") },
|
||||
{ 'n', "structure_open_open", lit("[\"\\{[\"\\{[\"\\{[\"\\{") },
|
||||
{ 'n', "structure_single_eacute", lit("\xE9") },
|
||||
{ 'n', "structure_single_eacute", lit("\xE9""") },
|
||||
{ 'n', "structure_single_star", lit("*") },
|
||||
{ 'n', "structure_trailing_#", lit("{\"a\":\"b\"}#{}") },
|
||||
{ 'n', "structure_U+2060_word_joined", lit("[\xE2\x81\xA0]") },
|
||||
{ 'n', "structure_U+2060_word_joined", lit("[\xE2""\x81""\xA0""]") },
|
||||
{ 'n', "structure_uescaped_LF_before_string", lit("[\\u000A\"\"]") },
|
||||
{ 'n', "structure_unclosed_array", lit("[1") },
|
||||
{ 'n', "structure_unclosed_array_partial_null", lit("[ false, nul") },
|
||||
{ 'n', "structure_unclosed_array_unfinished_false", lit("[ true, fals") },
|
||||
{ 'n', "structure_unclosed_array_unfinished_true", lit("[ false, tru") },
|
||||
{ 'n', "structure_unclosed_object", lit("{\"asd\":\"asd\"") },
|
||||
{ 'n', "structure_unicode-identifier", lit("\xC3\xA5") },
|
||||
{ 'n', "structure_UTF8_BOM_no_data", lit("\xEF\xBB\xBF") },
|
||||
{ 'n', "structure_whitespace_formfeed", lit("[\x0C]") },
|
||||
{ 'n', "structure_whitespace_U+2060_word_joiner", lit("[\xE2\x81\xA0]") },
|
||||
{ 'n', "structure_unicode-identifier", lit("\xC3""\xA5""") },
|
||||
{ 'n', "structure_UTF8_BOM_no_data", lit("\xEF""\xBB""\xBF""") },
|
||||
{ 'n', "structure_whitespace_formfeed", lit("[\x0C""]") },
|
||||
{ 'n', "structure_whitespace_U+2060_word_joiner", lit("[\xE2""\x81""\xA0""]") },
|
||||
{ 'y', "array_arraysWithSpaces", lit("[[] ]") },
|
||||
{ 'y', "array_empty-string", lit("[\"\"]") },
|
||||
{ 'y', "array_empty", lit("[]") },
|
||||
@ -1318,7 +1343,7 @@ parse_vectors() noexcept
|
||||
{ 'y', "array_false", lit("[false]") },
|
||||
{ 'y', "array_heterogeneous", lit("[null, 1, \"1\", {}]") },
|
||||
{ 'y', "array_null", lit("[null]") },
|
||||
{ 'y', "array_with_1_and_newline", lit("[1\x0A]") },
|
||||
{ 'y', "array_with_1_and_newline", lit("[1\x0A""]") },
|
||||
{ 'y', "array_with_leading_space", lit(" [1]") },
|
||||
{ 'y', "array_with_several_null", lit("[1,null,null,null,2]") },
|
||||
{ 'y', "array_with_trailing_space", lit("[2] ") },
|
||||
@ -1327,7 +1352,7 @@ parse_vectors() noexcept
|
||||
{ 'y', "number_0e1", lit("[0e1]") },
|
||||
{ 'y', "number_after_space", lit("[ 4]") },
|
||||
{ 'y', "number_double_close_to_zero", lit("[-0.0000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||
"01]\x0A") },
|
||||
"01]\x0A""") },
|
||||
{ 'y', "number_int_with_exp", lit("[20e1]") },
|
||||
{ 'y', "number_minus_zero", lit("[-0]") },
|
||||
{ 'y', "number_negative_int", lit("[-123]") },
|
||||
@ -1355,7 +1380,35 @@ parse_vectors() noexcept
|
||||
{ 'y', "object_simple", lit("{\"a\":[]}") },
|
||||
{ 'y', "object_string_unicode", lit("{\"title\":\"\\u041f\\u043e\\u043b\\u0442\\u043e\\u0440\\u0430 \\u0417\\u0435\\u"
|
||||
"043c\\u043b\\u0435\\u043a\\u043e\\u043f\\u0430\" }") },
|
||||
{ 'y', "object_with_newlines", lit("{\x0A\"a\": \"b\"\x0A}") },
|
||||
{ 'y', "object_with_newlines", lit("{\x0A""\"a\": \"b\"\x0A""}") },
|
||||
{ 'y', "pass01", lit("[\x0A"" \"JSON Test Pattern pass1\",\x0A"" {\"object with 1 member\":[\"ar"
|
||||
"ray with 1 element\"]},\x0A"" {},\x0A"" [],\x0A"" -42,\x0A"" true,\x0A"""
|
||||
" false,\x0A"" null,\x0A"" {\x0A"" \"integer\": 1234567890,\x0A"" "
|
||||
" \"real\": -9876.543210,\x0A"" \"e\": 0.123456789e-12,\x0A"" "
|
||||
"\"E\": 1.234567890E+34,\x0A"" \"\": 23456789012E66,\x0A"" \"zero\""
|
||||
": 0,\x0A"" \"one\": 1,\x0A"" \"space\": \" \",\x0A"" \"quote"
|
||||
"\": \"\\\"\",\x0A"" \"backslash\": \"\\\\\",\x0A"" \"controls\": \""
|
||||
"\\b\\f\\n\\r\\t\",\x0A"" \"slash\": \"/ & \\/\",\x0A"" \"alpha\": \""
|
||||
"abcdefghijklmnopqrstuvwyz\",\x0A"" \"ALPHA\": \"ABCDEFGHIJKLMNOPQRSTUVWYZ\""
|
||||
",\x0A"" \"digit\": \"0123456789\",\x0A"" \"0123456789\": \"digit\","
|
||||
"\x0A"" \"special\": \"`1~!@#$%^&*()_+-={':[,]}|;.</>?\",\x0A"" \"he"
|
||||
"x\": \"\\u0123\\u4567\\u89AB\\uCDEF\\uabcd\\uef4A\",\x0A"" \"true\": true,"
|
||||
"\x0A"" \"false\": false,\x0A"" \"null\": null,\x0A"" \"array"
|
||||
"\":[ ],\x0A"" \"object\":{ },\x0A"" \"address\": \"50 St. James S"
|
||||
"treet\",\x0A"" \"url\": \"http://www.JSON.org/\",\x0A"" \"comment\""
|
||||
": \"// /* <!-- --\",\x0A"" \"# -- --> */\": \" \",\x0A"" \" s p a c"
|
||||
" e d \" :[1,2 , 3\x0A""\x0A"",\x0A""\x0A""4 , 5 , 6 ,7 "
|
||||
" ],\"compact\":[1,2,3,4,5,6,7],\x0A"" \"jsontext\": \"{\\\"object wi"
|
||||
"th 1 member\\\":[\\\"array with 1 element\\\"]}\",\x0A"" \"quotes\": \""
|
||||
"4; \\u0022 %22 0x22 034 "\",\x0A"" \"\\/\\\\\\\"\\uCAFE\\uBABE\\uAB98"
|
||||
"\\uFCDE\\ubcda\\uef4A\\b\\f\\n\\r\\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?\"\x0A"": \"A "
|
||||
"key can be any string\"\x0A"" },\x0A"" 0.5 ,98.6\x0A"",\x0A""99.44\x0A"",\x0A"""
|
||||
"\x0A""1066,\x0A""1e1,\x0A""0.1e1,\x0A""1e-1,\x0A""1e00,2e+00,2e-00\x0A"",\"rosebu"
|
||||
"d\"]") },
|
||||
{ 'y', "pass02", lit("[[[[[[[[[[[[[[[[[[[\"Not too deep\"]]]]]]]]]]]]]]]]]]]") },
|
||||
{ 'y', "pass03", lit("{\x0A"" \"JSON Test Pattern pass3\": {\x0A"" \"The outermost value\": "
|
||||
"\"must be an object or array.\",\x0A"" \"In this test\": \"It is an object"
|
||||
".\"\x0A"" }\x0A""}\x0A""") },
|
||||
{ 'y', "string_1_2_3_bytes_UTF-8_sequences", lit("[\"\\u0060\\u012a\\u12AB\"]") },
|
||||
{ 'y', "string_accepted_surrogate_pair", lit("[\"\\uD801\\udc37\"]") },
|
||||
{ 'y', "string_accepted_surrogate_pairs", lit("[\"\\ud83d\\ude39\\ud83d\\udc8d\"]") },
|
||||
@ -1371,25 +1424,25 @@ parse_vectors() noexcept
|
||||
{ 'y', "string_in_array_with_leading_space", lit("[ \"asd\"]") },
|
||||
{ 'y', "string_last_surrogates_1_and_2", lit("[\"\\uDBFF\\uDFFF\"]") },
|
||||
{ 'y', "string_nbsp_uescaped", lit("[\"new\\u00A0line\"]") },
|
||||
{ 'y', "string_nonCharacterInUTF-8_U+10FFFF", lit("[\"\xF4\x8F\xBF\xBF\"]") },
|
||||
{ 'y', "string_nonCharacterInUTF-8_U+FFFF", lit("[\"\xEF\xBF\xBF\"]") },
|
||||
{ 'y', "string_nonCharacterInUTF-8_U+10FFFF", lit("[\"\xF4""\x8F""\xBF""\xBF""\"]") },
|
||||
{ 'y', "string_nonCharacterInUTF-8_U+FFFF", lit("[\"\xEF""\xBF""\xBF""\"]") },
|
||||
{ 'y', "string_null_escape", lit("[\"\\u0000\"]") },
|
||||
{ 'y', "string_one-byte-utf-8", lit("[\"\\u002c\"]") },
|
||||
{ 'y', "string_pi", lit("[\"\xCF\x80\"]") },
|
||||
{ 'y', "string_reservedCharacterInUTF-8_U+1BFFF", lit("[\"\xF0\x9B\xBF\xBF\"]") },
|
||||
{ 'y', "string_pi", lit("[\"\xCF""\x80""\"]") },
|
||||
{ 'y', "string_reservedCharacterInUTF-8_U+1BFFF", lit("[\"\xF0""\x9B""\xBF""\xBF""\"]") },
|
||||
{ 'y', "string_simple_ascii", lit("[\"asd \"]") },
|
||||
{ 'y', "string_space", lit("\" \"") },
|
||||
{ 'y', "string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF", lit("[\"\\uD834\\uDd1e\"]") },
|
||||
{ 'y', "string_three-byte-utf-8", lit("[\"\\u0821\"]") },
|
||||
{ 'y', "string_two-byte-utf-8", lit("[\"\\u0123\"]") },
|
||||
{ 'y', "string_u+2028_line_sep", lit("[\"\xE2\x80\xA8\"]") },
|
||||
{ 'y', "string_u+2029_par_sep", lit("[\"\xE2\x80\xA9\"]") },
|
||||
{ 'y', "string_u+2028_line_sep", lit("[\"\xE2""\x80""\xA8""\"]") },
|
||||
{ 'y', "string_u+2029_par_sep", lit("[\"\xE2""\x80""\xA9""\"]") },
|
||||
{ 'y', "string_uEscape", lit("[\"\\u0061\\u30af\\u30EA\\u30b9\"]") },
|
||||
{ 'y', "string_uescaped_newline", lit("[\"new\\u000Aline\"]") },
|
||||
{ 'y', "string_unescaped_char_delete", lit("[\"\"]") },
|
||||
{ 'y', "string_unicode", lit("[\"\\uA66D\"]") },
|
||||
{ 'y', "string_unicodeEscapedBackslash", lit("[\"\\u005C\"]") },
|
||||
{ 'y', "string_unicode_2", lit("[\"\xE2\x8D\x82\xE3\x88\xB4\xE2\x8D\x82\"]") },
|
||||
{ 'y', "string_unicode_2", lit("[\"\xE2""\x8D""\x82""\xE3""\x88""\xB4""\xE2""\x8D""\x82""\"]") },
|
||||
{ 'y', "string_unicode_escaped_double_quote", lit("[\"\\u0022\"]") },
|
||||
{ 'y', "string_unicode_U+10FFFE_nonchar", lit("[\"\\uDBFF\\uDFFE\"]") },
|
||||
{ 'y', "string_unicode_U+1FFFE_nonchar", lit("[\"\\uD83F\\uDFFE\"]") },
|
||||
@ -1397,7 +1450,7 @@ parse_vectors() noexcept
|
||||
{ 'y', "string_unicode_U+2064_invisible_plus", lit("[\"\\u2064\"]") },
|
||||
{ 'y', "string_unicode_U+FDD0_nonchar", lit("[\"\\uFDD0\"]") },
|
||||
{ 'y', "string_unicode_U+FFFE_nonchar", lit("[\"\\uFFFE\"]") },
|
||||
{ 'y', "string_utf8", lit("[\"\xE2\x82\xAC\xF0\x9D\x84\x9E\"]") },
|
||||
{ 'y', "string_utf8", lit("[\"\xE2""\x82""\xAC""\xF0""\x9D""\x84""\x9E""\"]") },
|
||||
{ 'y', "string_with_del_character", lit("[\"aa\"]") },
|
||||
{ 'y', "structure_lonely_false", lit("false") },
|
||||
{ 'y', "structure_lonely_int", lit("42") },
|
||||
@ -1406,7 +1459,7 @@ parse_vectors() noexcept
|
||||
{ 'y', "structure_lonely_string", lit("\"asd\"") },
|
||||
{ 'y', "structure_lonely_true", lit("true") },
|
||||
{ 'y', "structure_string_empty", lit("\"\"") },
|
||||
{ 'y', "structure_trailing_newline", lit("[\"a\"]\x0A") },
|
||||
{ 'y', "structure_trailing_newline", lit("[\"a\"]\x0A""") },
|
||||
{ 'y', "structure_true_in_array", lit("[true]") },
|
||||
{ 'y', "structure_whitespace_array", lit(" [] ") },
|
||||
{ ' ', "", "" }
|
||||
@ -1416,7 +1469,4 @@ parse_vectors() noexcept
|
||||
decltype(list)>::value - 1];
|
||||
}
|
||||
|
||||
} // json
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
|
1
test/parse-vectors/n_fail01.json
Normal file
1
test/parse-vectors/n_fail01.json
Normal file
@ -0,0 +1 @@
|
||||
["mismatch"}
|
1
test/parse-vectors/n_fail02.json
Normal file
1
test/parse-vectors/n_fail02.json
Normal file
@ -0,0 +1 @@
|
||||
["Unclosed array"
|
1
test/parse-vectors/n_fail03.json
Normal file
1
test/parse-vectors/n_fail03.json
Normal file
@ -0,0 +1 @@
|
||||
{unquoted_key: "keys must be quoted"}
|
1
test/parse-vectors/n_fail04.json
Normal file
1
test/parse-vectors/n_fail04.json
Normal file
@ -0,0 +1 @@
|
||||
["extra comma",]
|
1
test/parse-vectors/n_fail05.json
Normal file
1
test/parse-vectors/n_fail05.json
Normal file
@ -0,0 +1 @@
|
||||
["double extra comma",,]
|
1
test/parse-vectors/n_fail06.json
Normal file
1
test/parse-vectors/n_fail06.json
Normal file
@ -0,0 +1 @@
|
||||
[ , "<-- missing value"]
|
1
test/parse-vectors/n_fail07.json
Normal file
1
test/parse-vectors/n_fail07.json
Normal file
@ -0,0 +1 @@
|
||||
["Comma after the close"],
|
1
test/parse-vectors/n_fail08.json
Normal file
1
test/parse-vectors/n_fail08.json
Normal file
@ -0,0 +1 @@
|
||||
["Extra close"]]
|
1
test/parse-vectors/n_fail09.json
Normal file
1
test/parse-vectors/n_fail09.json
Normal file
@ -0,0 +1 @@
|
||||
{"Extra comma": true,}
|
1
test/parse-vectors/n_fail10.json
Normal file
1
test/parse-vectors/n_fail10.json
Normal file
@ -0,0 +1 @@
|
||||
{"Extra value after close": true} "misplaced quoted value"
|
1
test/parse-vectors/n_fail11.json
Normal file
1
test/parse-vectors/n_fail11.json
Normal file
@ -0,0 +1 @@
|
||||
{"Illegal expression": 1 + 2}
|
1
test/parse-vectors/n_fail12.json
Normal file
1
test/parse-vectors/n_fail12.json
Normal file
@ -0,0 +1 @@
|
||||
{"Illegal invocation": alert()}
|
1
test/parse-vectors/n_fail13.json
Normal file
1
test/parse-vectors/n_fail13.json
Normal file
@ -0,0 +1 @@
|
||||
{"Numbers cannot have leading zeroes": 013}
|
1
test/parse-vectors/n_fail14.json
Normal file
1
test/parse-vectors/n_fail14.json
Normal file
@ -0,0 +1 @@
|
||||
{"Numbers cannot be hex": 0x14}
|
1
test/parse-vectors/n_fail15.json
Normal file
1
test/parse-vectors/n_fail15.json
Normal file
@ -0,0 +1 @@
|
||||
["Illegal backslash escape: \x15"]
|
1
test/parse-vectors/n_fail16.json
Normal file
1
test/parse-vectors/n_fail16.json
Normal file
@ -0,0 +1 @@
|
||||
[\naked]
|
1
test/parse-vectors/n_fail17.json
Normal file
1
test/parse-vectors/n_fail17.json
Normal file
@ -0,0 +1 @@
|
||||
["Illegal backslash escape: \017"]
|
1
test/parse-vectors/n_fail19.json
Normal file
1
test/parse-vectors/n_fail19.json
Normal file
@ -0,0 +1 @@
|
||||
{"Missing colon" null}
|
1
test/parse-vectors/n_fail20.json
Normal file
1
test/parse-vectors/n_fail20.json
Normal file
@ -0,0 +1 @@
|
||||
{"Double colon":: null}
|
1
test/parse-vectors/n_fail21.json
Normal file
1
test/parse-vectors/n_fail21.json
Normal file
@ -0,0 +1 @@
|
||||
{"Comma instead of colon", null}
|
1
test/parse-vectors/n_fail22.json
Normal file
1
test/parse-vectors/n_fail22.json
Normal file
@ -0,0 +1 @@
|
||||
["Colon instead of comma": false]
|
1
test/parse-vectors/n_fail23.json
Normal file
1
test/parse-vectors/n_fail23.json
Normal file
@ -0,0 +1 @@
|
||||
["Bad value", truth]
|
1
test/parse-vectors/n_fail24.json
Normal file
1
test/parse-vectors/n_fail24.json
Normal file
@ -0,0 +1 @@
|
||||
['single quote']
|
1
test/parse-vectors/n_fail25.json
Normal file
1
test/parse-vectors/n_fail25.json
Normal file
@ -0,0 +1 @@
|
||||
[" tab character in string "]
|
1
test/parse-vectors/n_fail26.json
Normal file
1
test/parse-vectors/n_fail26.json
Normal file
@ -0,0 +1 @@
|
||||
["tab\ character\ in\ string\ "]
|
2
test/parse-vectors/n_fail27.json
Normal file
2
test/parse-vectors/n_fail27.json
Normal file
@ -0,0 +1,2 @@
|
||||
["line
|
||||
break"]
|
2
test/parse-vectors/n_fail28.json
Normal file
2
test/parse-vectors/n_fail28.json
Normal file
@ -0,0 +1,2 @@
|
||||
["line\
|
||||
break"]
|
1
test/parse-vectors/n_fail29.json
Normal file
1
test/parse-vectors/n_fail29.json
Normal file
@ -0,0 +1 @@
|
||||
[0e]
|
1
test/parse-vectors/n_fail30.json
Normal file
1
test/parse-vectors/n_fail30.json
Normal file
@ -0,0 +1 @@
|
||||
[0e+]
|
1
test/parse-vectors/n_fail31.json
Normal file
1
test/parse-vectors/n_fail31.json
Normal file
@ -0,0 +1 @@
|
||||
[0e+-1]
|
1
test/parse-vectors/n_fail32.json
Normal file
1
test/parse-vectors/n_fail32.json
Normal file
@ -0,0 +1 @@
|
||||
{"Comma instead if closing brace": true,
|
58
test/parse-vectors/y_pass01.json
Normal file
58
test/parse-vectors/y_pass01.json
Normal file
@ -0,0 +1,58 @@
|
||||
[
|
||||
"JSON Test Pattern pass1",
|
||||
{"object with 1 member":["array with 1 element"]},
|
||||
{},
|
||||
[],
|
||||
-42,
|
||||
true,
|
||||
false,
|
||||
null,
|
||||
{
|
||||
"integer": 1234567890,
|
||||
"real": -9876.543210,
|
||||
"e": 0.123456789e-12,
|
||||
"E": 1.234567890E+34,
|
||||
"": 23456789012E66,
|
||||
"zero": 0,
|
||||
"one": 1,
|
||||
"space": " ",
|
||||
"quote": "\"",
|
||||
"backslash": "\\",
|
||||
"controls": "\b\f\n\r\t",
|
||||
"slash": "/ & \/",
|
||||
"alpha": "abcdefghijklmnopqrstuvwyz",
|
||||
"ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ",
|
||||
"digit": "0123456789",
|
||||
"0123456789": "digit",
|
||||
"special": "`1~!@#$%^&*()_+-={':[,]}|;.</>?",
|
||||
"hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A",
|
||||
"true": true,
|
||||
"false": false,
|
||||
"null": null,
|
||||
"array":[ ],
|
||||
"object":{ },
|
||||
"address": "50 St. James Street",
|
||||
"url": "http://www.JSON.org/",
|
||||
"comment": "// /* <!-- --",
|
||||
"# -- --> */": " ",
|
||||
" s p a c e d " :[1,2 , 3
|
||||
|
||||
,
|
||||
|
||||
4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7],
|
||||
"jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}",
|
||||
"quotes": "" \u0022 %22 0x22 034 "",
|
||||
"\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?"
|
||||
: "A key can be any string"
|
||||
},
|
||||
0.5 ,98.6
|
||||
,
|
||||
99.44
|
||||
,
|
||||
|
||||
1066,
|
||||
1e1,
|
||||
0.1e1,
|
||||
1e-1,
|
||||
1e00,2e+00,2e-00
|
||||
,"rosebud"]
|
1
test/parse-vectors/y_pass02.json
Normal file
1
test/parse-vectors/y_pass02.json
Normal file
@ -0,0 +1 @@
|
||||
[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]
|
6
test/parse-vectors/y_pass03.json
Normal file
6
test/parse-vectors/y_pass03.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"JSON Test Pattern pass3": {
|
||||
"The outermost value": "must be an object or array.",
|
||||
"In this test": "It is an object."
|
||||
}
|
||||
}
|
@ -67,6 +67,51 @@ R"xx({
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testParse()
|
||||
{
|
||||
auto const check =
|
||||
[&](json::value const& jv)
|
||||
{
|
||||
BEAST_EXPECT(jv.is_object());
|
||||
BEAST_EXPECT(jv.as_object().find(
|
||||
"a")->second.is_bool());
|
||||
BEAST_EXPECT(jv.as_object().find(
|
||||
"b")->second.is_number());
|
||||
BEAST_EXPECT(jv.as_object().find(
|
||||
"c")->second.is_string());
|
||||
};
|
||||
|
||||
string_view js =
|
||||
"{\"a\":true,\"b\":1,\"c\":\"x\"}";
|
||||
|
||||
// parse(value)
|
||||
{
|
||||
check(parse(js));
|
||||
}
|
||||
|
||||
// parse(value, storage_ptr)
|
||||
{
|
||||
check(parse(js, default_storage()));
|
||||
}
|
||||
|
||||
// parse(value, error_code)
|
||||
{
|
||||
error_code ec;
|
||||
auto jv = parse(js, ec);
|
||||
BEAST_EXPECTS(! ec, ec.message());
|
||||
check(jv);
|
||||
}
|
||||
|
||||
// parse(value, storage_ptr, error_code)
|
||||
{
|
||||
error_code ec;
|
||||
auto jv = parse(js, default_storage(), ec);
|
||||
BEAST_EXPECTS(! ec, ec.message());
|
||||
check(jv);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
run()
|
||||
{
|
||||
@ -74,6 +119,7 @@ R"xx({
|
||||
"sizeof(parser) == " <<
|
||||
sizeof(parser) << "\n";
|
||||
testParser();
|
||||
testParse();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include <boost/beast/_experimental/unit_test/suite.hpp>
|
||||
#include "parse-vectors.hpp"
|
||||
|
||||
//#define SOFT_FAIL
|
||||
#define SOFT_FAIL
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
||||
@ -23,43 +23,32 @@ class serializer_test : public beast::unit_test::suite
|
||||
{
|
||||
public:
|
||||
static
|
||||
std::string
|
||||
to_string(value const& jv)
|
||||
unsigned
|
||||
common(
|
||||
string_view s1,
|
||||
string_view s2)
|
||||
{
|
||||
std::string s;
|
||||
unsigned long cap = 1024;
|
||||
for(;;)
|
||||
unsigned n = 0;
|
||||
auto p1 = s1.data();
|
||||
auto p2 = s2.data();
|
||||
auto end = s1.size() > s2.size() ?
|
||||
s2.end() : s1.end();
|
||||
while(p1 < end)
|
||||
{
|
||||
s.resize(cap);
|
||||
serializer p(jv);
|
||||
s.resize(p.next(
|
||||
&s[0], s.size()));
|
||||
if(p.is_done())
|
||||
++n;
|
||||
if(*p1++ != *p2++)
|
||||
break;
|
||||
cap *= 2;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
static
|
||||
value
|
||||
from_string(
|
||||
string_view s,
|
||||
error_code& ec)
|
||||
{
|
||||
parser p;
|
||||
p.write(
|
||||
s.data(),
|
||||
s.size(),
|
||||
ec);
|
||||
return p.release();
|
||||
return n;
|
||||
}
|
||||
|
||||
void
|
||||
round_trip(string_view s0)
|
||||
round_trip(
|
||||
string_view name,
|
||||
string_view s0)
|
||||
{
|
||||
error_code ec;
|
||||
auto jv0 = from_string(s0, ec);
|
||||
auto jv0 = parse(s0, ec);
|
||||
#ifdef SOFT_FAIL
|
||||
if(ec)
|
||||
return;
|
||||
@ -69,7 +58,10 @@ public:
|
||||
return;
|
||||
#endif
|
||||
auto s1 = to_string(jv0);
|
||||
auto jv1 = from_string(s1, ec);
|
||||
parser p;
|
||||
auto n = p.write(
|
||||
s1.data(), s1.size(), ec);
|
||||
auto jv1 = p.release();
|
||||
#ifdef SOFT_FAIL
|
||||
if(ec)
|
||||
#else
|
||||
@ -77,7 +69,15 @@ public:
|
||||
! ec, ec.message()))
|
||||
#endif
|
||||
{
|
||||
auto c1 = s1.data() + n;
|
||||
if( n > 60)
|
||||
n = 60;
|
||||
auto c0 = c1 - n;
|
||||
log <<
|
||||
"context\n"
|
||||
" " << string_view(c0, c1-c0) << std::endl;
|
||||
log <<
|
||||
name << "\n"
|
||||
" " << s0 << "\n"
|
||||
" " << s1 << std::endl << std::endl;
|
||||
return;
|
||||
@ -88,18 +88,24 @@ public:
|
||||
#else
|
||||
if(! BEAST_EXPECT(s1 == s2))
|
||||
#endif
|
||||
{
|
||||
auto c = common(s1, s2);
|
||||
log <<
|
||||
" " << s1 << "\n"
|
||||
" " << s2 << std::endl << std::endl;
|
||||
name << "\n"
|
||||
" " << s0 << "\n"
|
||||
" " << s1.substr(0, c) << "\n"
|
||||
" " << s2.substr(0, c) << std::endl << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
print_grind(
|
||||
string_view name,
|
||||
json::value const& jv)
|
||||
{
|
||||
auto const s0 = to_string(jv);
|
||||
log << s0 << std::endl;
|
||||
round_trip(s0);
|
||||
round_trip(name, s0);
|
||||
for(std::size_t i = 1;
|
||||
i < s0.size() - 1; ++i)
|
||||
{
|
||||
@ -120,6 +126,34 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testSerializer()
|
||||
{
|
||||
value jv;
|
||||
|
||||
// serializer(value)
|
||||
{
|
||||
serializer sr(jv);
|
||||
}
|
||||
|
||||
// is_done()
|
||||
{
|
||||
serializer sr(jv);
|
||||
BEAST_EXPECT(! sr.is_done());
|
||||
}
|
||||
|
||||
// next()
|
||||
{
|
||||
serializer sr(jv);
|
||||
char buf[1024];
|
||||
auto n = sr.next(
|
||||
buf, sizeof(buf));
|
||||
BEAST_EXPECT(sr.is_done());
|
||||
BEAST_EXPECT(string_view(
|
||||
buf, n) == "null");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testRoundTrips()
|
||||
{
|
||||
@ -129,41 +163,7 @@ public:
|
||||
if(e.result != 'y')
|
||||
continue;
|
||||
|
||||
round_trip(e.text);
|
||||
#if 0
|
||||
error_code ec;
|
||||
std::string s1, s2;
|
||||
{
|
||||
auto jv = from_string(
|
||||
e.text, ec);
|
||||
if(! BEAST_EXPECTS(
|
||||
! ec, ec.message()))
|
||||
continue;
|
||||
s1 = to_string(jv);
|
||||
}
|
||||
{
|
||||
auto jv =
|
||||
from_string(s1, ec);
|
||||
if(! BEAST_EXPECTS(
|
||||
! ec, ec.message()))
|
||||
{
|
||||
log <<
|
||||
" " << e.text << "\n" <<
|
||||
" " << s1 << "\n" <<
|
||||
std::endl << std::endl;
|
||||
continue;
|
||||
}
|
||||
s2 = to_string(jv);
|
||||
}
|
||||
if(! BEAST_EXPECT(s1 == s2))
|
||||
if(s1 != s2)
|
||||
{
|
||||
log <<
|
||||
" " << s1 << "\n" <<
|
||||
" " << s2 << "\n" <<
|
||||
std::endl << std::endl;
|
||||
}
|
||||
#endif
|
||||
round_trip(e.name, e.text);
|
||||
}
|
||||
}
|
||||
|
||||
@ -171,7 +171,7 @@ public:
|
||||
good(string_view s)
|
||||
{
|
||||
error_code ec;
|
||||
auto jv = from_string(s, ec);
|
||||
auto jv = parse(s, ec);
|
||||
return !ec;
|
||||
}
|
||||
|
||||
@ -179,11 +179,13 @@ public:
|
||||
void
|
||||
tv(char const (&s)[N])
|
||||
{
|
||||
round_trip(string_view(s, N - 1));
|
||||
round_trip(
|
||||
"",
|
||||
string_view(s, N - 1));
|
||||
}
|
||||
|
||||
void
|
||||
run()
|
||||
doTestStrings()
|
||||
{
|
||||
tv(R"("")");
|
||||
tv(R"("x")");
|
||||
@ -237,19 +239,34 @@ public:
|
||||
tv(R"(false)");
|
||||
|
||||
tv(R"(null)");
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
doTestVectors()
|
||||
{
|
||||
parse_vectors const pv;
|
||||
for(auto const e : pv)
|
||||
{
|
||||
if( e.result == 'y' ||
|
||||
good(e.text))
|
||||
{
|
||||
log << e.name << std::endl;
|
||||
round_trip(e.text);
|
||||
round_trip(e.name, e.text);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
run()
|
||||
{
|
||||
parse_vectors const pv;
|
||||
auto jv = parse(pv.begin()->text);
|
||||
auto s = to_string(jv);
|
||||
error_code ec;
|
||||
auto jv2 = parse(s, ec);
|
||||
BEAST_EXPECTS(! ec, ec.message());
|
||||
testSerializer();
|
||||
doTestStrings();
|
||||
doTestVectors();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -703,6 +703,7 @@ public:
|
||||
}
|
||||
|
||||
// kind::number
|
||||
#if 0
|
||||
{
|
||||
// VFALCO I'm not sure these should be numbers
|
||||
BEAST_EXPECT(value(tt<char>{}).is_number());
|
||||
@ -713,6 +714,7 @@ public:
|
||||
{ value jv; BEAST_EXPECT((jv = tt<unsigned char>{}).is_number()); }
|
||||
{ value jv; BEAST_EXPECT((jv = tt<wchar_t>{}).is_number()); }
|
||||
}
|
||||
#endif
|
||||
|
||||
// kind::number
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user