From e35a4e16efcdf66c4dd90efcf3117787effc1be5 Mon Sep 17 00:00:00 2001 From: status102 <102887808+status102@users.noreply.github.com> Date: Tue, 24 Jun 2025 19:33:30 +0800 Subject: [PATCH] chore: meojson update to v4.4.1 --- 3rdparty/include/meojson/parser/parser.hpp | 175 ++++++++++++++++----- 1 file changed, 137 insertions(+), 38 deletions(-) diff --git a/3rdparty/include/meojson/parser/parser.hpp b/3rdparty/include/meojson/parser/parser.hpp index 047c9c359c..f486abcaab 100644 --- a/3rdparty/include/meojson/parser/parser.hpp +++ b/3rdparty/include/meojson/parser/parser.hpp @@ -19,6 +19,7 @@ namespace json // **************************** template < + bool accept_jsonc = false, typename string_t = default_string_t, typename parsing_t = void, typename accel_traits = _packed_bytes::packed_bytes_trait_max> @@ -56,6 +57,7 @@ private: bool skip_string_literal_with_accel(); bool skip_whitespace() noexcept; + bool skip_comment() noexcept; bool skip_digit(); bool skip_unicode_escape(uint16_t& pair_high, string_t& result); @@ -74,14 +76,20 @@ auto parse(const parsing_t& content); template auto parse(char_t* content); +template +auto parsec(const parsing_t& content); + +template +auto parsec(char_t* content); + template < typename istream_t, typename = std::enable_if_t< std::is_base_of_v, istream_t>>> -auto parse(istream_t& istream, bool check_bom); +auto parse(istream_t& istream, bool check_bom = false, bool with_commets = false); template -auto open(const path_t& path, bool check_bom = false); +auto open(const path_t& path, bool check_bom = false, bool with_commets = false); namespace literals { @@ -105,15 +113,17 @@ const basic_value invalid_value(); // * parser impl * // ************************* -template +template inline std::optional> - parser::parse(const parsing_t& content) + parser::parse(const parsing_t& content) { - return parser(content.cbegin(), content.cend()).parse(); + return parser(content.cbegin(), content.cend()) + .parse(); } -template -inline std::optional> parser::parse() +template +inline std::optional> + parser::parse() { if (!skip_whitespace()) { return std::nullopt; @@ -135,8 +145,7 @@ inline std::optional> parser> parser -inline basic_value parser::parse_value() +template +inline basic_value parser::parse_value() { switch (*_cur) { case 'n': @@ -176,8 +185,8 @@ inline basic_value parser::parse_va } } -template -inline basic_value parser::parse_null() +template +inline basic_value parser::parse_null() { for (const auto& ch : _utils::null_string()) { if (_cur != _end && *_cur == ch) { @@ -191,8 +200,9 @@ inline basic_value parser::parse_nu return basic_value(); } -template -inline basic_value parser::parse_boolean() +template +inline basic_value + parser::parse_boolean() { switch (*_cur) { case 't': @@ -220,8 +230,8 @@ inline basic_value parser::parse_bo } } -template -inline basic_value parser::parse_number() +template +inline basic_value parser::parse_number() { const auto first = _cur; if (*_cur == '-') { @@ -259,8 +269,8 @@ inline basic_value parser::parse_nu return basic_value(basic_value::value_type::number, string_t(first, _cur)); } -template -inline basic_value parser::parse_string() +template +inline basic_value parser::parse_string() { auto string_opt = parse_stdstring(); if (!string_opt) { @@ -271,8 +281,8 @@ inline basic_value parser::parse_st std::move(string_opt).value()); } -template -inline basic_value parser::parse_array() +template +inline basic_value parser::parse_array() { if (*_cur == '[') { ++_cur; @@ -296,6 +306,12 @@ inline basic_value parser::parse_ar return invalid_value(); } + if constexpr (accept_jsonc) { + if (*_cur == ']') { + break; + } + } + basic_value val = parse_value(); if (!val.valid() || !skip_whitespace()) { @@ -322,8 +338,8 @@ inline basic_value parser::parse_ar return basic_array(std::move(result)); } -template -inline basic_value parser::parse_object() +template +inline basic_value parser::parse_object() { if (*_cur == '{') { ++_cur; @@ -347,6 +363,12 @@ inline basic_value parser::parse_ob return invalid_value(); } + if constexpr (accept_jsonc) { + if (*_cur == '}') { + break; + } + } + auto key_opt = parse_stdstring(); if (key_opt && skip_whitespace() && *_cur == ':') { @@ -389,8 +411,9 @@ inline basic_value parser::parse_ob return basic_object(std::move(result)); } -template -inline std::optional parser::parse_stdstring() +template +inline std::optional + parser::parse_stdstring() { if (*_cur == '"') { ++_cur; @@ -477,8 +500,8 @@ inline std::optional parser::parse_ return std::nullopt; } -template -inline bool parser::skip_unicode_escape( +template +inline bool parser::skip_unicode_escape( uint16_t& pair_high, string_t& result) { @@ -574,8 +597,9 @@ inline bool parser::skip_unicode_escape( return true; } -template -inline bool parser::skip_string_literal_with_accel() +template +inline bool + parser::skip_string_literal_with_accel() { if constexpr (sizeof(*_cur) != 1) { return false; @@ -602,8 +626,8 @@ inline bool parser::skip_string_literal_with_ return _cur != _end; } -template -inline bool parser::skip_whitespace() noexcept +template +inline bool parser::skip_whitespace() noexcept { while (_cur != _end) { switch (*_cur) { @@ -613,6 +637,17 @@ inline bool parser::skip_whitespace() noexcep case '\n': ++_cur; break; + case '/': + if constexpr (accept_jsonc) { + if (!skip_comment()) { + return false; + } + // else continue; + } + else { + return false; + } + break; case '\0': return false; default: @@ -622,8 +657,59 @@ inline bool parser::skip_whitespace() noexcep return false; } -template -inline bool parser::skip_digit() +template +bool json::parser::skip_comment() noexcept +{ + if (_cur == _end || *_cur != '/') { + return false; + } + + if (++_cur == _end) { + return false; + } + + enum class comment_type + { + invalid, + line, + block, + } t = comment_type::invalid; + + switch (*_cur++) { + case '/': + t = comment_type::line; + break; + case '*': + t = comment_type::block; + break; + default: + return false; + } + + while (_cur != _end) { + switch (*_cur++) { + case '\n': + if (t == comment_type::line) { + return true; + } + break; + case '*': + if (t == comment_type::block && _cur != _end && *_cur == '/') { + ++_cur; + return true; + } + break; + default: + break; + } + } + + // _cur == _end + return t == comment_type::line; +} + +template +inline bool parser::skip_digit() { // At least one digit if (_cur != _end && std::isdigit(*_cur)) { @@ -653,7 +739,7 @@ template auto parse(const parsing_t& content) { using string_t = std::basic_string; - return parser::parse(content); + return parser::parse(content); } template @@ -663,7 +749,7 @@ auto parse(char_t* content) } template -auto parse(istream_t& ifs, bool check_bom) +auto parse(istream_t& ifs, bool check_bom, bool with_commets) { using string_t = std::basic_string; @@ -686,11 +772,11 @@ auto parse(istream_t& ifs, bool check_bom) str.assign(str.begin() + 3, str.end()); } } - return parse(str); + return with_commets ? parsec(str) : parse(str); } template -auto open(const path_t& filepath, bool check_bom) +auto open(const path_t& filepath, bool check_bom, bool with_commets) { using char_t = typename ifstream_t::char_type; using string_t = std::basic_string; @@ -701,11 +787,24 @@ auto open(const path_t& filepath, bool check_bom) if (!ifs.is_open()) { return return_t(std::nullopt); } - auto opt = parse(ifs, check_bom); + auto opt = parse(ifs, check_bom, with_commets); ifs.close(); return opt; } +template +auto parsec(const parsing_t& content) +{ + using string_t = std::basic_string; + return parser::parse(content); +} + +template +auto parsec(char_t* content) +{ + return parsec(std::basic_string_view> { content }); +} + namespace literals { inline value operator""_json(const char* str, size_t len)