diff options
author | orivej <orivej@yandex-team.ru> | 2022-02-10 16:44:49 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:44:49 +0300 |
commit | 718c552901d703c502ccbefdfc3c9028d608b947 (patch) | |
tree | 46534a98bbefcd7b1f3faa5b52c138ab27db75b7 /contrib/libs/poco/JSON/src/ParserImpl.cpp | |
parent | e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (diff) | |
download | ydb-718c552901d703c502ccbefdfc3c9028d608b947.tar.gz |
Restoring authorship annotation for <orivej@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/poco/JSON/src/ParserImpl.cpp')
-rw-r--r-- | contrib/libs/poco/JSON/src/ParserImpl.cpp | 482 |
1 files changed, 241 insertions, 241 deletions
diff --git a/contrib/libs/poco/JSON/src/ParserImpl.cpp b/contrib/libs/poco/JSON/src/ParserImpl.cpp index ce455ea031..8cd24f9995 100644 --- a/contrib/libs/poco/JSON/src/ParserImpl.cpp +++ b/contrib/libs/poco/JSON/src/ParserImpl.cpp @@ -1,241 +1,241 @@ -// -// Parser.cpp -// -// Library: JSON -// Package: JSON -// Module: Parser -// -// Copyright (c) 2012, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// SPDX-License-Identifier: BSL-1.0 -// - - -#include "Poco/JSON/Parser.h" -#include "Poco/JSON/JSONException.h" -#include "Poco/Ascii.h" -#include "Poco/Token.h" -#include "Poco/UTF8Encoding.h" -#include "Poco/String.h" -#include "Poco/StreamCopier.h" -#undef min -#undef max -#include <limits> -#include <clocale> -#include <istream> -#include "pdjson.h" - - -typedef struct json_stream json_stream; - - -namespace Poco { -namespace JSON { - - -ParserImpl::ParserImpl(const Handler::Ptr& pHandler, std::size_t /*bufSize*/): - _pJSON(new json_stream), - _pHandler(pHandler), - _depth(JSON_UNLIMITED_DEPTH), - _decimalPoint('.'), - _allowNullByte(true), - _allowComments(false) -{ -} - - -ParserImpl::~ParserImpl() -{ - delete _pJSON; -} - - -void ParserImpl::handle(const std::string& json) -{ - if (!_allowNullByte && json.find("\\u0000") != json.npos) - throw JSONException("Null bytes in strings not allowed."); - - try - { - json_open_buffer(_pJSON, json.data(), json.size()); - checkError(); - ////////////////////////////////// - // Underlying parser is capable of parsing multiple consecutive JSONs; - // we do not currently support this feature; to force error on - // excessive characters past valid JSON end, this MUST be called - // AFTER opening the buffer - otherwise it is overwritten by - // json_open*() call, which calls internal init() - json_set_streaming(_pJSON, false); - ///////////////////////////////// - handle(); checkError(); - if (JSON_DONE != json_next(_pJSON)) - throw JSONException("Excess characters found after JSON end."); - json_close(_pJSON); - } - catch (std::exception&) - { - json_close(_pJSON); - throw; - } -} - - -Dynamic::Var ParserImpl::parseImpl(const std::string& json) -{ - if (_allowComments) - { - std::string str = json; - stripComments(str); - handle(str); - } - else handle(json); - - return asVarImpl(); -} - - -Dynamic::Var ParserImpl::parseImpl(std::istream& in) -{ - std::ostringstream os; - StreamCopier::copyStream(in, os); - return parseImpl(os.str()); -} - - -void ParserImpl::stripComments(std::string& json) -{ - if (_allowComments) - { - bool inString = false; - bool inComment = false; - char prevChar = 0; - std::string::iterator it = json.begin(); - for (; it != json.end();) - { - if (*it == '"' && !inString) inString = true; - else inString = false; - if (!inString) - { - if (*it == '/' && it + 1 != json.end() && *(it + 1) == '*') - inComment = true; - } - if (inComment) - { - char c = *it; - it = json.erase(it); - if (prevChar == '*' && c == '/') - { - inComment = false; - prevChar = 0; - } - else prevChar = c; - } - else ++it; - } - } -} - - -void ParserImpl::handleArray() -{ - json_type tok = json_peek(_pJSON); - while (tok != JSON_ARRAY_END && checkError()) - { - handle(); - tok = json_peek(_pJSON); - } - - if (tok == JSON_ARRAY_END) handle(); - else throw JSONException("JSON array end not found"); -} - - -void ParserImpl::handleObject() -{ - json_type tok = json_peek(_pJSON); - while (tok != JSON_OBJECT_END && checkError()) - { - json_next(_pJSON); - if (_pHandler) _pHandler->key(std::string(json_get_string(_pJSON, NULL))); - handle(); - tok = json_peek(_pJSON); - } - - if (tok == JSON_OBJECT_END) handle(); - else throw JSONException("JSON object end not found"); -} - - -void ParserImpl::handle() -{ - enum json_type type = json_next(_pJSON); - switch (type) - { - case JSON_DONE: - return; - case JSON_NULL: - _pHandler->null(); - break; - case JSON_TRUE: - if (_pHandler) _pHandler->value(true); - break; - case JSON_FALSE: - if (_pHandler) _pHandler->value(false); - break; - case JSON_NUMBER: - { - if (_pHandler) - { - std::string str(json_get_string(_pJSON, NULL)); - if (str.find(_decimalPoint) != str.npos || str.find('e') != str.npos || str.find('E') != str.npos) - { - _pHandler->value(NumberParser::parseFloat(str)); - } - else - { - Poco::Int64 val; - if (NumberParser::tryParse64(str, val)) - _pHandler->value(val); - else - _pHandler->value(NumberParser::parseUnsigned64(str)); - } - } - break; - } - case JSON_STRING: - if (_pHandler) _pHandler->value(std::string(json_get_string(_pJSON, NULL))); - break; - case JSON_OBJECT: - if (_pHandler) _pHandler->startObject(); - handleObject(); - break; - case JSON_OBJECT_END: - if (_pHandler) _pHandler->endObject(); - return; - case JSON_ARRAY: - if (_pHandler) _pHandler->startArray(); - handleArray(); - break; - case JSON_ARRAY_END: - if (_pHandler) _pHandler->endArray(); - return; - case JSON_ERROR: - { - const char* pErr = json_get_error(_pJSON); - std::string err(pErr ? pErr : "JSON parser error."); - throw JSONException(err); - } - } -} - - -bool ParserImpl::checkError() -{ - const char* err = json_get_error(_pJSON); - if (err) throw Poco::JSON::JSONException(err); - return true; -} - - -} } // namespace Poco::JSON +// +// Parser.cpp +// +// Library: JSON +// Package: JSON +// Module: Parser +// +// Copyright (c) 2012, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/JSON/Parser.h" +#include "Poco/JSON/JSONException.h" +#include "Poco/Ascii.h" +#include "Poco/Token.h" +#include "Poco/UTF8Encoding.h" +#include "Poco/String.h" +#include "Poco/StreamCopier.h" +#undef min +#undef max +#include <limits> +#include <clocale> +#include <istream> +#include "pdjson.h" + + +typedef struct json_stream json_stream; + + +namespace Poco { +namespace JSON { + + +ParserImpl::ParserImpl(const Handler::Ptr& pHandler, std::size_t /*bufSize*/): + _pJSON(new json_stream), + _pHandler(pHandler), + _depth(JSON_UNLIMITED_DEPTH), + _decimalPoint('.'), + _allowNullByte(true), + _allowComments(false) +{ +} + + +ParserImpl::~ParserImpl() +{ + delete _pJSON; +} + + +void ParserImpl::handle(const std::string& json) +{ + if (!_allowNullByte && json.find("\\u0000") != json.npos) + throw JSONException("Null bytes in strings not allowed."); + + try + { + json_open_buffer(_pJSON, json.data(), json.size()); + checkError(); + ////////////////////////////////// + // Underlying parser is capable of parsing multiple consecutive JSONs; + // we do not currently support this feature; to force error on + // excessive characters past valid JSON end, this MUST be called + // AFTER opening the buffer - otherwise it is overwritten by + // json_open*() call, which calls internal init() + json_set_streaming(_pJSON, false); + ///////////////////////////////// + handle(); checkError(); + if (JSON_DONE != json_next(_pJSON)) + throw JSONException("Excess characters found after JSON end."); + json_close(_pJSON); + } + catch (std::exception&) + { + json_close(_pJSON); + throw; + } +} + + +Dynamic::Var ParserImpl::parseImpl(const std::string& json) +{ + if (_allowComments) + { + std::string str = json; + stripComments(str); + handle(str); + } + else handle(json); + + return asVarImpl(); +} + + +Dynamic::Var ParserImpl::parseImpl(std::istream& in) +{ + std::ostringstream os; + StreamCopier::copyStream(in, os); + return parseImpl(os.str()); +} + + +void ParserImpl::stripComments(std::string& json) +{ + if (_allowComments) + { + bool inString = false; + bool inComment = false; + char prevChar = 0; + std::string::iterator it = json.begin(); + for (; it != json.end();) + { + if (*it == '"' && !inString) inString = true; + else inString = false; + if (!inString) + { + if (*it == '/' && it + 1 != json.end() && *(it + 1) == '*') + inComment = true; + } + if (inComment) + { + char c = *it; + it = json.erase(it); + if (prevChar == '*' && c == '/') + { + inComment = false; + prevChar = 0; + } + else prevChar = c; + } + else ++it; + } + } +} + + +void ParserImpl::handleArray() +{ + json_type tok = json_peek(_pJSON); + while (tok != JSON_ARRAY_END && checkError()) + { + handle(); + tok = json_peek(_pJSON); + } + + if (tok == JSON_ARRAY_END) handle(); + else throw JSONException("JSON array end not found"); +} + + +void ParserImpl::handleObject() +{ + json_type tok = json_peek(_pJSON); + while (tok != JSON_OBJECT_END && checkError()) + { + json_next(_pJSON); + if (_pHandler) _pHandler->key(std::string(json_get_string(_pJSON, NULL))); + handle(); + tok = json_peek(_pJSON); + } + + if (tok == JSON_OBJECT_END) handle(); + else throw JSONException("JSON object end not found"); +} + + +void ParserImpl::handle() +{ + enum json_type type = json_next(_pJSON); + switch (type) + { + case JSON_DONE: + return; + case JSON_NULL: + _pHandler->null(); + break; + case JSON_TRUE: + if (_pHandler) _pHandler->value(true); + break; + case JSON_FALSE: + if (_pHandler) _pHandler->value(false); + break; + case JSON_NUMBER: + { + if (_pHandler) + { + std::string str(json_get_string(_pJSON, NULL)); + if (str.find(_decimalPoint) != str.npos || str.find('e') != str.npos || str.find('E') != str.npos) + { + _pHandler->value(NumberParser::parseFloat(str)); + } + else + { + Poco::Int64 val; + if (NumberParser::tryParse64(str, val)) + _pHandler->value(val); + else + _pHandler->value(NumberParser::parseUnsigned64(str)); + } + } + break; + } + case JSON_STRING: + if (_pHandler) _pHandler->value(std::string(json_get_string(_pJSON, NULL))); + break; + case JSON_OBJECT: + if (_pHandler) _pHandler->startObject(); + handleObject(); + break; + case JSON_OBJECT_END: + if (_pHandler) _pHandler->endObject(); + return; + case JSON_ARRAY: + if (_pHandler) _pHandler->startArray(); + handleArray(); + break; + case JSON_ARRAY_END: + if (_pHandler) _pHandler->endArray(); + return; + case JSON_ERROR: + { + const char* pErr = json_get_error(_pJSON); + std::string err(pErr ? pErr : "JSON parser error."); + throw JSONException(err); + } + } +} + + +bool ParserImpl::checkError() +{ + const char* err = json_get_error(_pJSON); + if (err) throw Poco::JSON::JSONException(err); + return true; +} + + +} } // namespace Poco::JSON |