diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/json/json_reader.h | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/json/json_reader.h')
-rw-r--r-- | library/cpp/json/json_reader.h | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/library/cpp/json/json_reader.h b/library/cpp/json/json_reader.h new file mode 100644 index 0000000000..b673788330 --- /dev/null +++ b/library/cpp/json/json_reader.h @@ -0,0 +1,140 @@ +#pragma once + +#include "json_value.h" + +#include <library/cpp/json/common/defs.h> +#include <library/cpp/json/fast_sax/parser.h> + +#include <util/generic/yexception.h> + +#include <util/stream/input.h> +#include <util/stream/str.h> +#include <util/stream/mem.h> + +namespace NJson { + struct TJsonReaderConfig { + TJsonReaderConfig(); + + // js-style comments (both // and /**/) + bool AllowComments = false; + bool DontValidateUtf8 = false; + bool AllowEscapedApostrophe = false; + + void SetBufferSize(size_t bufferSize); + size_t GetBufferSize() const; + + private: + size_t BufferSize; + }; + + bool ReadJsonTree(TStringBuf in, TJsonValue* out, bool throwOnError = false); + bool ReadJsonTree(TStringBuf in, bool allowComments, TJsonValue* out, bool throwOnError = false); + bool ReadJsonTree(TStringBuf in, const TJsonReaderConfig* config, TJsonValue* out, bool throwOnError = false); + + bool ReadJsonTree(IInputStream* in, TJsonValue* out, bool throwOnError = false); + bool ReadJsonTree(IInputStream* in, bool allowComments, TJsonValue* out, bool throwOnError = false); + bool ReadJsonTree(IInputStream* in, const TJsonReaderConfig* config, TJsonValue* out, bool throwOnError = false); + + TJsonValue ReadJsonTree(IInputStream* in, bool throwOnError = false); + TJsonValue ReadJsonTree(IInputStream* in, bool allowComments, bool throwOnError); + TJsonValue ReadJsonTree(IInputStream* in, const TJsonReaderConfig* config, bool throwOnError = false); + + bool ReadJson(IInputStream* in, TJsonCallbacks* callbacks); + bool ReadJson(IInputStream* in, bool allowComments, TJsonCallbacks* callbacks); + bool ReadJson(IInputStream* in, bool allowComments, bool allowEscapedApostrophe, TJsonCallbacks* callbacks); + bool ReadJson(IInputStream* in, const TJsonReaderConfig* config, TJsonCallbacks* callbacks); + + enum ReaderConfigFlags { + COMMENTS = 0b100, + VALIDATE = 0b010, + ESCAPE = 0b001, + }; + + enum ReaderConfigToRapidJsonFlags { + COMMENTS_NOVALID_NOESCAPE = 0b100, + COMMENTS_VALID_NOESCAPE = 0b110, + COMMENTS_VALID_ESCAPE = 0b111, + COMMENTS_NOVALID_ESCAPE = 0b101, + NOCOMMENTS_VALID_NOESCAPE = 0b010, + NOCOMMENTS_VALID_ESCAPE = 0b011, + NOCOMMENTS_NOVALID_ESCAPE = 0b001, + }; + + inline bool ValidateJson(IInputStream* in, const TJsonReaderConfig* config, bool throwOnError = false) { + TJsonCallbacks c(throwOnError); + return ReadJson(in, config, &c); + } + + inline bool ValidateJson(TStringBuf in, const TJsonReaderConfig& config = TJsonReaderConfig(), bool throwOnError = false) { + TMemoryInput min(in.data(), in.size()); + return ValidateJson(&min, &config, throwOnError); + } + + inline bool ValidateJsonThrow(IInputStream* in, const TJsonReaderConfig* config) { + return ValidateJson(in, config, true); + } + + inline bool ValidateJsonThrow(TStringBuf in, const TJsonReaderConfig& config = TJsonReaderConfig()) { + return ValidateJson(in, config, true); + } + + class TParserCallbacks: public TJsonCallbacks { + public: + TParserCallbacks(TJsonValue& value, bool throwOnError = false, bool notClosedBracketIsError = false); + bool OnNull() override; + bool OnBoolean(bool val) override; + bool OnInteger(long long val) override; + bool OnUInteger(unsigned long long val) override; + bool OnString(const TStringBuf& val) override; + bool OnDouble(double val) override; + bool OnOpenArray() override; + bool OnCloseArray() override; + bool OnOpenMap() override; + bool OnCloseMap() override; + bool OnMapKey(const TStringBuf& val) override; + bool OnEnd() override; + + protected: + TJsonValue& Value; + TString Key; + TVector<TJsonValue*> ValuesStack; + bool NotClosedBracketIsError; + + enum { + START, + AFTER_MAP_KEY, + IN_MAP, + IN_ARRAY, + FINISH + } CurrentState; + + template <class T> + bool SetValue(const T& value) { + switch (CurrentState) { + case START: + Value.SetValue(value); + break; + case AFTER_MAP_KEY: + ValuesStack.back()->InsertValue(Key, value); + CurrentState = IN_MAP; + break; + case IN_ARRAY: + ValuesStack.back()->AppendValue(value); + break; + case IN_MAP: + case FINISH: + return false; + default: + ythrow yexception() << "TParserCallbacks::SetValue invalid enum"; + } + return true; + } + + bool OpenComplexValue(EJsonValueType type); + bool CloseComplexValue(); + }; + + //// relaxed json, used in library/cpp/scheme + bool ReadJsonFastTree(TStringBuf in, TJsonValue* out, bool throwOnError = false, bool notClosedBracketIsError = false); + TJsonValue ReadJsonFastTree(TStringBuf in, bool notClosedBracketIsError = false); +} |