🚧 add object and string parser for BON8

This commit is contained in:
Niels Lohmann 2021-09-11 23:28:16 +02:00
parent e27c127068
commit b932217c15
No known key found for this signature in database
GPG Key ID: 7F3CEA63AE251B69
3 changed files with 204 additions and 4 deletions

View File

@ -2434,11 +2434,17 @@ class binary_reader
case 0xFD:
return sax->number_float(1.0, "");
default: // anything else
case 0xFE:
{
auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bon8, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
}
default:
{
string_t s;
return get_bon8_string(s) && sax->string(s);
}
}
}
@ -2475,7 +2481,97 @@ class binary_reader
bool get_bon8_object(const std::size_t len)
{
return false;
if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
{
return false;
}
if (len != 0)
{
string_t key;
if (len != std::size_t(-1))
{
for (std::size_t i = 0; i < len; ++i)
{
get();
if (JSON_HEDLEY_UNLIKELY(!get_bon8_string(key) || !sax->key(key)))
{
return false;
}
if (JSON_HEDLEY_UNLIKELY(!parse_bon8_internal(false)))
{
return false;
}
key.clear();
}
}
else
{
while (get() != 0xFE)
{
if (JSON_HEDLEY_UNLIKELY(!get_bon8_string(key) || !sax->key(key)))
{
return false;
}
if (JSON_HEDLEY_UNLIKELY(!parse_bon8_internal(false)))
{
return false;
}
key.clear();
}
}
}
return sax->end_object();
}
bool get_bon8_string(string_t& result)
{
while (true)
{
if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bon8, "string")))
{
return false;
}
if ((current & 0x80) == 0x00)
{
result.push_back(static_cast<typename string_t::value_type>(current));
get();
}
else if ((current & 0xE0) == 0xC0)
{
result.push_back(static_cast<typename string_t::value_type>(current));
result.push_back(static_cast<typename string_t::value_type>(get()));
get();
}
else if ((current & 0xF0) == 0xE0)
{
result.push_back(static_cast<typename string_t::value_type>(current));
result.push_back(static_cast<typename string_t::value_type>(get()));
result.push_back(static_cast<typename string_t::value_type>(get()));
get();
}
else if ((current & 0xF8) == 0xF0)
{
result.push_back(static_cast<typename string_t::value_type>(current));
result.push_back(static_cast<typename string_t::value_type>(get()));
result.push_back(static_cast<typename string_t::value_type>(get()));
result.push_back(static_cast<typename string_t::value_type>(get()));
get();
}
else if (current == 0xFF)
{
get();
return true;
}
else
{
return true;
}
}
}
///////////////////////

View File

@ -10728,11 +10728,17 @@ class binary_reader
case 0xFD:
return sax->number_float(1.0, "");
default: // anything else
case 0xFE:
{
auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bon8, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
}
default:
{
string_t s;
return get_bon8_string(s) && sax->string(s);
}
}
}
@ -10769,7 +10775,97 @@ class binary_reader
bool get_bon8_object(const std::size_t len)
{
return false;
if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
{
return false;
}
if (len != 0)
{
string_t key;
if (len != std::size_t(-1))
{
for (std::size_t i = 0; i < len; ++i)
{
get();
if (JSON_HEDLEY_UNLIKELY(!get_bon8_string(key) || !sax->key(key)))
{
return false;
}
if (JSON_HEDLEY_UNLIKELY(!parse_bon8_internal(false)))
{
return false;
}
key.clear();
}
}
else
{
while (get() != 0xFE)
{
if (JSON_HEDLEY_UNLIKELY(!get_bon8_string(key) || !sax->key(key)))
{
return false;
}
if (JSON_HEDLEY_UNLIKELY(!parse_bon8_internal(false)))
{
return false;
}
key.clear();
}
}
}
return sax->end_object();
}
bool get_bon8_string(string_t& result)
{
while (true)
{
if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bon8, "string")))
{
return false;
}
if ((current & 0x80) == 0x00)
{
result.push_back(static_cast<typename string_t::value_type>(current));
get();
}
else if ((current & 0xE0) == 0xC0)
{
result.push_back(static_cast<typename string_t::value_type>(current));
result.push_back(static_cast<typename string_t::value_type>(get()));
get();
}
else if ((current & 0xF0) == 0xE0)
{
result.push_back(static_cast<typename string_t::value_type>(current));
result.push_back(static_cast<typename string_t::value_type>(get()));
result.push_back(static_cast<typename string_t::value_type>(get()));
get();
}
else if ((current & 0xF8) == 0xF0)
{
result.push_back(static_cast<typename string_t::value_type>(current));
result.push_back(static_cast<typename string_t::value_type>(get()));
result.push_back(static_cast<typename string_t::value_type>(get()));
result.push_back(static_cast<typename string_t::value_type>(get()));
get();
}
else if (current == 0xFF)
{
get();
return true;
}
else
{
return true;
}
}
}
///////////////////////

View File

@ -552,6 +552,7 @@ TEST_CASE("BON8")
std::vector<uint8_t> expected = {0xFF};
const auto result = json::to_bon8(j);
CHECK(result == expected);
CHECK(json::from_bon8(result) == j);
}
SECTION("other strings")
@ -560,6 +561,7 @@ TEST_CASE("BON8")
std::vector<uint8_t> expected = {'T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 's', 't', 'r', 'i', 'n', 'g', '.', 0xFF};
const auto result = json::to_bon8(j);
CHECK(result == expected);
CHECK(json::from_bon8(result) == j);
}
}
@ -634,6 +636,7 @@ TEST_CASE("BON8")
std::vector<uint8_t> expected = {0x81, 0x81, 0x81, 'f', 'o', 'o', 0xFF};
const auto result = json::to_bon8(j);
CHECK(result == expected);
CHECK(json::from_bon8(result) == j);
}
SECTION("[[[1]]]")
@ -651,6 +654,7 @@ TEST_CASE("BON8")
std::vector<uint8_t> expected = {0x81, 0x81, 0x81, 0xFF};
const auto result = json::to_bon8(j);
CHECK(result == expected);
CHECK(json::from_bon8(result) == j);
}
}
@ -677,6 +681,7 @@ TEST_CASE("BON8")
std::vector<uint8_t> expected = {0x86};
const auto result = json::to_bon8(j);
CHECK(result == expected);
CHECK(json::from_bon8(result) == j);
}
SECTION("{\"foo\": null}")
@ -685,6 +690,7 @@ TEST_CASE("BON8")
std::vector<uint8_t> expected = {0x87, 'f', 'o', 'o', 0xFA};
const auto result = json::to_bon8(j);
CHECK(result == expected);
CHECK(json::from_bon8(result) == j);
}
SECTION("{\"\": true, \"foo\": null}")
@ -693,6 +699,7 @@ TEST_CASE("BON8")
std::vector<uint8_t> expected = {0x88, 0xFF, 0xF9, 'f', 'o', 'o', 0xFA};
const auto result = json::to_bon8(j);
CHECK(result == expected);
CHECK(json::from_bon8(result) == j);
}
SECTION("{\"a\": \"\", \"c\": \"d\"}")
@ -720,6 +727,7 @@ TEST_CASE("BON8")
std::vector<uint8_t> expected = {0x8b, 'f', 'i', 'v', 'e', 0x95, 'f', 'o', 'u', 'r', 0x94, 'o', 'n', 'e', 0x91, 't', 'h', 'r', 'e', 'e', 0x93, 't', 'w', 'o', 0x92, 0xFE};
const auto result = json::to_bon8(j);
CHECK(result == expected);
CHECK(json::from_bon8(result) == j);
}
}
}