diff options
| author | Anton Samokhvalov <[email protected]> | 2022-02-10 16:45:17 +0300 | 
|---|---|---|
| committer | Daniil Cherednik <[email protected]> | 2022-02-10 16:45:17 +0300 | 
| commit | d3a398281c6fd1d3672036cb2d63f842d2cb28c5 (patch) | |
| tree | dd4bd3ca0f36b817e96812825ffaf10d645803f2 /library/cpp/json | |
| parent | 72cb13b4aff9bc9cf22e49251bc8fd143f82538f (diff) | |
Restoring authorship annotation for Anton Samokhvalov <[email protected]>. Commit 2 of 2.
Diffstat (limited to 'library/cpp/json')
39 files changed, 3585 insertions, 3585 deletions
diff --git a/library/cpp/json/common/defs.cpp b/library/cpp/json/common/defs.cpp index 7ae904ba543..da86da82e42 100644 --- a/library/cpp/json/common/defs.cpp +++ b/library/cpp/json/common/defs.cpp @@ -1,68 +1,68 @@ -#include "defs.h"  -  -using namespace NJson;  -  -TJsonCallbacks::~TJsonCallbacks() {  -}  -  -bool TJsonCallbacks::OnNull() {  -    return true;  -}  -  -bool TJsonCallbacks::OnBoolean(bool) {  -    return true;  -}  -  -bool TJsonCallbacks::OnInteger(long long) {  -    return true;  -}  -  -bool TJsonCallbacks::OnUInteger(unsigned long long) {  -    return true;  -}  -  -bool TJsonCallbacks::OnDouble(double) {  -    return true;  -}  -  -bool TJsonCallbacks::OnString(const TStringBuf&) {  -    return true;  -}  -  -bool TJsonCallbacks::OnOpenMap() {  -    return true;  -}  -  -bool TJsonCallbacks::OnMapKey(const TStringBuf&) {  -    return true;  -}  -  -bool TJsonCallbacks::OnCloseMap() {  -    return true;  -}  -  -bool TJsonCallbacks::OnOpenArray() {  -    return true;  -}  -  -bool TJsonCallbacks::OnCloseArray() {  -    return true;  -}  -  -bool TJsonCallbacks::OnStringNoCopy(const TStringBuf& s) {  -    return OnString(s);  -}  -  -bool TJsonCallbacks::OnMapKeyNoCopy(const TStringBuf& s) {  -    return OnMapKey(s);  -}  -  -bool TJsonCallbacks::OnEnd() {  -    return true;  -}  -  -void TJsonCallbacks::OnError(size_t off, TStringBuf reason) {  -    if (ThrowException) {  -        ythrow TJsonException() << "JSON error at offset " << off << " (" << reason << ")";  -    }  -}  +#include "defs.h" + +using namespace NJson; + +TJsonCallbacks::~TJsonCallbacks() { +} + +bool TJsonCallbacks::OnNull() { +    return true; +} + +bool TJsonCallbacks::OnBoolean(bool) { +    return true; +} + +bool TJsonCallbacks::OnInteger(long long) { +    return true; +} + +bool TJsonCallbacks::OnUInteger(unsigned long long) { +    return true; +} + +bool TJsonCallbacks::OnDouble(double) { +    return true; +} + +bool TJsonCallbacks::OnString(const TStringBuf&) { +    return true; +} + +bool TJsonCallbacks::OnOpenMap() { +    return true; +} + +bool TJsonCallbacks::OnMapKey(const TStringBuf&) { +    return true; +} + +bool TJsonCallbacks::OnCloseMap() { +    return true; +} + +bool TJsonCallbacks::OnOpenArray() { +    return true; +} + +bool TJsonCallbacks::OnCloseArray() { +    return true; +} + +bool TJsonCallbacks::OnStringNoCopy(const TStringBuf& s) { +    return OnString(s); +} + +bool TJsonCallbacks::OnMapKeyNoCopy(const TStringBuf& s) { +    return OnMapKey(s); +} + +bool TJsonCallbacks::OnEnd() { +    return true; +} + +void TJsonCallbacks::OnError(size_t off, TStringBuf reason) { +    if (ThrowException) { +        ythrow TJsonException() << "JSON error at offset " << off << " (" << reason << ")"; +    } +} diff --git a/library/cpp/json/common/defs.h b/library/cpp/json/common/defs.h index 8e0e6923fca..d3c8761bcc0 100644 --- a/library/cpp/json/common/defs.h +++ b/library/cpp/json/common/defs.h @@ -1,38 +1,38 @@ -#pragma once  -  -#include <util/generic/strbuf.h>  -#include <util/generic/yexception.h>  -  -namespace NJson {  -    class TJsonException: public yexception {  -    };  -  -    class TJsonCallbacks {  -    public:  -        explicit TJsonCallbacks(bool throwException = false)  -            : ThrowException(throwException)  -        {  -        }  -  -        virtual ~TJsonCallbacks();  -  -        virtual bool OnNull();  -        virtual bool OnBoolean(bool);  -        virtual bool OnInteger(long long);  -        virtual bool OnUInteger(unsigned long long);  -        virtual bool OnDouble(double);  -        virtual bool OnString(const TStringBuf&);  -        virtual bool OnOpenMap();  -        virtual bool OnMapKey(const TStringBuf&);  -        virtual bool OnCloseMap();  -        virtual bool OnOpenArray();  -        virtual bool OnCloseArray();  -        virtual bool OnStringNoCopy(const TStringBuf& s);  -        virtual bool OnMapKeyNoCopy(const TStringBuf& s);  -        virtual bool OnEnd();  -        virtual void OnError(size_t off, TStringBuf reason);  -  -    protected:  -        bool ThrowException;  -    };  -}  +#pragma once + +#include <util/generic/strbuf.h> +#include <util/generic/yexception.h> + +namespace NJson { +    class TJsonException: public yexception { +    }; + +    class TJsonCallbacks { +    public: +        explicit TJsonCallbacks(bool throwException = false) +            : ThrowException(throwException) +        { +        } + +        virtual ~TJsonCallbacks(); + +        virtual bool OnNull(); +        virtual bool OnBoolean(bool); +        virtual bool OnInteger(long long); +        virtual bool OnUInteger(unsigned long long); +        virtual bool OnDouble(double); +        virtual bool OnString(const TStringBuf&); +        virtual bool OnOpenMap(); +        virtual bool OnMapKey(const TStringBuf&); +        virtual bool OnCloseMap(); +        virtual bool OnOpenArray(); +        virtual bool OnCloseArray(); +        virtual bool OnStringNoCopy(const TStringBuf& s); +        virtual bool OnMapKeyNoCopy(const TStringBuf& s); +        virtual bool OnEnd(); +        virtual void OnError(size_t off, TStringBuf reason); + +    protected: +        bool ThrowException; +    }; +} diff --git a/library/cpp/json/common/ya.make b/library/cpp/json/common/ya.make index c64976ccd1b..5bbd3b0792a 100644 --- a/library/cpp/json/common/ya.make +++ b/library/cpp/json/common/ya.make @@ -1,9 +1,9 @@ -LIBRARY()  -  -OWNER(pg)  -  -SRCS(  -    defs.cpp  -)  -  -END()  +LIBRARY() + +OWNER(pg) + +SRCS( +    defs.cpp +) + +END() diff --git a/library/cpp/json/domscheme_traits.h b/library/cpp/json/domscheme_traits.h index 68b149a6906..a5a99cd8cfe 100644 --- a/library/cpp/json/domscheme_traits.h +++ b/library/cpp/json/domscheme_traits.h @@ -1,7 +1,7 @@  #pragma once -#include "json_value.h"  -#include "json_reader.h"  +#include "json_value.h" +#include "json_reader.h"  #include "json_writer.h"  #include <util/generic/algorithm.h> @@ -125,7 +125,7 @@ struct TJsonTraits {      // boolean ops      static inline void Get(TConstValueRef v, bool def, bool& b) {          b = -            v->GetType() == NJson::JSON_UNDEFINED ? def : v->IsNull() ? def : v->GetBooleanRobust();  +            v->GetType() == NJson::JSON_UNDEFINED ? def : v->IsNull() ? def : v->GetBooleanRobust();      }      static inline void Get(TConstValueRef v, bool& b) { @@ -136,14 +136,14 @@ struct TJsonTraits {          return v->IsBoolean();      } -#define INTEGER_OPS(type, checkOp, getOp)                                              \  -    static inline void Get(TConstValueRef v, type def, type& i) {                      \  -        i = v->checkOp() ? v->getOp() : def;                                           \  -    }                                                                                  \  -    static inline void Get(TConstValueRef v, type& i) {                                \  -        i = v->getOp();                                                                \  -    }                                                                                  \  -    static inline bool IsValidPrimitive(const type&, TConstValueRef v) {               \  +#define INTEGER_OPS(type, checkOp, getOp)                                              \ +    static inline void Get(TConstValueRef v, type def, type& i) {                      \ +        i = v->checkOp() ? v->getOp() : def;                                           \ +    }                                                                                  \ +    static inline void Get(TConstValueRef v, type& i) {                                \ +        i = v->getOp();                                                                \ +    }                                                                                  \ +    static inline bool IsValidPrimitive(const type&, TConstValueRef v) {               \          return v->checkOp() && v->getOp() >= Min<type>() && v->getOp() <= Max<type>(); \      } diff --git a/library/cpp/json/easy_parse/json_easy_parser.cpp b/library/cpp/json/easy_parse/json_easy_parser.cpp index 48567686356..3c781f544bc 100644 --- a/library/cpp/json/easy_parse/json_easy_parser.cpp +++ b/library/cpp/json/easy_parse/json_easy_parser.cpp @@ -5,232 +5,232 @@  #include <util/string/strip.h>  namespace NJson { -    static TString MAP_IDENTIFIER = "{}";  -    static TString ARRAY_IDENTIFIER = "[]";  -    static TString ANY_IDENTIFIER = "*";  - -    static void ParsePath(TString path, TVector<TPathElem>* res) {  -        TVector<const char*> parts;  -        Split(path.begin(), '/', &parts);  -        for (size_t n = 0; n < parts.size(); ++n) {  +    static TString MAP_IDENTIFIER = "{}"; +    static TString ARRAY_IDENTIFIER = "[]"; +    static TString ANY_IDENTIFIER = "*"; + +    static void ParsePath(TString path, TVector<TPathElem>* res) { +        TVector<const char*> parts; +        Split(path.begin(), '/', &parts); +        for (size_t n = 0; n < parts.size(); ++n) {              TString part = Strip(parts[n]); -            if (!part.empty()) {  -                if (part[0] != '[') {  -                    res->push_back(TPathElem(NImpl::MAP));  -                    res->push_back(TPathElem(part));  -                } else {  -                    int arrayCounter;  -                    try {  -                        arrayCounter = FromString<int>(part.substr(1, part.length() - 2));  -                    } catch (yexception&) {  -                        arrayCounter = -1;  -                    }  -                    res->push_back(TPathElem(arrayCounter));  +            if (!part.empty()) { +                if (part[0] != '[') { +                    res->push_back(TPathElem(NImpl::MAP)); +                    res->push_back(TPathElem(part)); +                } else { +                    int arrayCounter; +                    try { +                        arrayCounter = FromString<int>(part.substr(1, part.length() - 2)); +                    } catch (yexception&) { +                        arrayCounter = -1; +                    } +                    res->push_back(TPathElem(arrayCounter));                  }              }          }      } -    void TJsonParser::AddField(const TString& path, bool nonEmpty) {  -        Fields.emplace_back();  -        Fields.back().NonEmpty = nonEmpty;  -        ParsePath(path, &Fields.back().Path);  -    }  - -    TString TJsonParser::ConvertToTabDelimited(const TString& json) const {  -        TStringInput in(json);  -        TStringStream out;  -        ConvertToTabDelimited(in, out);  -        return out.Str();  -    }  - -    class TRewriteJsonImpl: public NJson::TJsonCallbacks {  -        const TJsonParser& Parent;  -        TVector<TString> FieldValues;  -        TVector<TPathElem> Stack;  -        bool ShouldUpdateOnArrayChange;  -        int CurrentFieldIdx;  -        bool HasFormatError;  - -    private:  -        static bool PathElementMatch(const TPathElem& templ, const TPathElem& real) {  -            if (templ.Type != real.Type)  -                return false;  -            if (templ.Type == NImpl::ARRAY)  -                return templ.ArrayCounter == -1 || templ.ArrayCounter == real.ArrayCounter;  -            if (templ.Type == NImpl::MAP_KEY)  -                return templ.Key == ANY_IDENTIFIER || templ.Key == real.Key;  -            return true;  -        }  - -        bool CheckFilter(const TVector<TPathElem>& path) const {  -            if (Stack.size() < path.size())  +    void TJsonParser::AddField(const TString& path, bool nonEmpty) { +        Fields.emplace_back(); +        Fields.back().NonEmpty = nonEmpty; +        ParsePath(path, &Fields.back().Path); +    } + +    TString TJsonParser::ConvertToTabDelimited(const TString& json) const { +        TStringInput in(json); +        TStringStream out; +        ConvertToTabDelimited(in, out); +        return out.Str(); +    } + +    class TRewriteJsonImpl: public NJson::TJsonCallbacks { +        const TJsonParser& Parent; +        TVector<TString> FieldValues; +        TVector<TPathElem> Stack; +        bool ShouldUpdateOnArrayChange; +        int CurrentFieldIdx; +        bool HasFormatError; + +    private: +        static bool PathElementMatch(const TPathElem& templ, const TPathElem& real) { +            if (templ.Type != real.Type) +                return false; +            if (templ.Type == NImpl::ARRAY) +                return templ.ArrayCounter == -1 || templ.ArrayCounter == real.ArrayCounter; +            if (templ.Type == NImpl::MAP_KEY) +                return templ.Key == ANY_IDENTIFIER || templ.Key == real.Key; +            return true; +        } + +        bool CheckFilter(const TVector<TPathElem>& path) const { +            if (Stack.size() < path.size())                  return false;              for (size_t n = 0; n < path.size(); ++n) { -                if (!PathElementMatch(path[n], Stack[n]))  -                    return false;  -            }  -            return true;  +                if (!PathElementMatch(path[n], Stack[n])) +                    return false; +            } +            return true;          } -        void UpdateRule() {  +        void UpdateRule() {              for (size_t n = 0; n < Parent.Fields.size(); ++n) { -                if (FieldValues[n].empty() && CheckFilter(Parent.Fields[n].Path)) {  -                    CurrentFieldIdx = n;  -                    return;  -                }  +                if (FieldValues[n].empty() && CheckFilter(Parent.Fields[n].Path)) { +                    CurrentFieldIdx = n; +                    return; +                } +            } +            CurrentFieldIdx = -1; +        } + +        void Pop() { +            Stack.pop_back(); +        } + +        void IncreaseArrayCounter() { +            if (!Stack.empty() && Stack.back().Type == NImpl::ARRAY) { +                ++Stack.back().ArrayCounter; +                if (ShouldUpdateOnArrayChange) +                    UpdateRule();              } -            CurrentFieldIdx = -1;  -        } - -        void Pop() {  -            Stack.pop_back();  -        }  - -        void IncreaseArrayCounter() {  -            if (!Stack.empty() && Stack.back().Type == NImpl::ARRAY) {  -                ++Stack.back().ArrayCounter;  -                if (ShouldUpdateOnArrayChange)  -                    UpdateRule();  -            }  -        }  -  -        template <class T>  -        bool OnValue(const T& val) {  -            IncreaseArrayCounter();  -            if (CurrentFieldIdx >= 0) {  -                FieldValues[CurrentFieldIdx] = ToString(val);  +        } + +        template <class T> +        bool OnValue(const T& val) { +            IncreaseArrayCounter(); +            if (CurrentFieldIdx >= 0) { +                FieldValues[CurrentFieldIdx] = ToString(val);                  UpdateRule(); -            }  -            return true;  -        } - -    public:  -        TRewriteJsonImpl(const TJsonParser& parent)  -            : Parent(parent)  -            , FieldValues(parent.Fields.size())  -            , ShouldUpdateOnArrayChange(false)  -            , CurrentFieldIdx(-1)  -            , HasFormatError(false)  -        {  +            } +            return true; +        } + +    public: +        TRewriteJsonImpl(const TJsonParser& parent) +            : Parent(parent) +            , FieldValues(parent.Fields.size()) +            , ShouldUpdateOnArrayChange(false) +            , CurrentFieldIdx(-1) +            , HasFormatError(false) +        {              for (size_t n = 0; n < Parent.Fields.size(); ++n) {                  if (!Parent.Fields[n].Path.empty() && Parent.Fields[n].Path.back().Type == NImpl::ARRAY) -                    ShouldUpdateOnArrayChange = true;  -            }  -        } - -        bool OnOpenMap() override {  -            IncreaseArrayCounter();  -            Stack.push_back(TPathElem(NImpl::MAP));  -            if (CurrentFieldIdx >= 0)  -                HasFormatError = true;  -            else  -                UpdateRule();  -            return true;  -        } - -        bool OnOpenArray() override {  -            IncreaseArrayCounter();  -            Stack.push_back(TPathElem(-1));  -            if (CurrentFieldIdx >= 0)  -                HasFormatError = true;  -            else  -                UpdateRule();  -            return true;  -        }  -  -        bool OnCloseMap() override {  -            while (!Stack.empty() && Stack.back().Type != NImpl::MAP)  -                Pop();  -            if (!Stack.empty())  -                Pop();  +                    ShouldUpdateOnArrayChange = true; +            } +        } + +        bool OnOpenMap() override { +            IncreaseArrayCounter(); +            Stack.push_back(TPathElem(NImpl::MAP)); +            if (CurrentFieldIdx >= 0) +                HasFormatError = true; +            else +                UpdateRule(); +            return true; +        } + +        bool OnOpenArray() override { +            IncreaseArrayCounter(); +            Stack.push_back(TPathElem(-1)); +            if (CurrentFieldIdx >= 0) +                HasFormatError = true; +            else +                UpdateRule(); +            return true; +        } + +        bool OnCloseMap() override { +            while (!Stack.empty() && Stack.back().Type != NImpl::MAP) +                Pop(); +            if (!Stack.empty()) +                Pop();              UpdateRule(); -            return true;  -        }  +            return true; +        } -        bool OnCloseArray() override {  -            if (!Stack.empty())  -                Pop();  +        bool OnCloseArray() override { +            if (!Stack.empty()) +                Pop();              UpdateRule(); -            return true;  -        }  - -        bool OnMapKey(const TStringBuf& key) override {  -            if (!Stack.empty() && Stack.back().Type == NImpl::MAP_KEY) {  -                Pop();  -                UpdateRule();  -            }  +            return true; +        } + +        bool OnMapKey(const TStringBuf& key) override { +            if (!Stack.empty() && Stack.back().Type == NImpl::MAP_KEY) { +                Pop(); +                UpdateRule(); +            }              Stack.push_back(TPathElem(TString{key})); -            if (CurrentFieldIdx >= 0)  -                HasFormatError = true;  -            else  -                UpdateRule();  -            return true;  -        }  +            if (CurrentFieldIdx >= 0) +                HasFormatError = true; +            else +                UpdateRule(); +            return true; +        } -        bool OnBoolean(bool b) override {  -            return OnValue(b);  -        }  +        bool OnBoolean(bool b) override { +            return OnValue(b); +        } -        bool OnInteger(long long i) override {  -            return OnValue(i);  +        bool OnInteger(long long i) override { +            return OnValue(i);          } -        bool OnDouble(double f) override {  -            return OnValue(f);  -        }  +        bool OnDouble(double f) override { +            return OnValue(f); +        } -        bool OnString(const TStringBuf& str) override {  -            return OnValue(str);  -        }  +        bool OnString(const TStringBuf& str) override { +            return OnValue(str); +        } -        bool IsOK() const {  -            if (HasFormatError)  -                return false;  +        bool IsOK() const { +            if (HasFormatError) +                return false;              for (size_t n = 0; n < FieldValues.size(); ++n) -                if (Parent.Fields[n].NonEmpty && FieldValues[n].empty())  -                    return false;  -            return true;  -        }  +                if (Parent.Fields[n].NonEmpty && FieldValues[n].empty()) +                    return false; +            return true; +        } -        void WriteTo(IOutputStream& out) const {  +        void WriteTo(IOutputStream& out) const {              for (size_t n = 0; n < FieldValues.size(); ++n) -                out << "\t" << FieldValues[n];  -        }  - -        void WriteTo(TVector<TString>* res) const {  -            *res = FieldValues;  -        }  -    };  - -    void TJsonParser::ConvertToTabDelimited(IInputStream& in, IOutputStream& out) const {  -        TRewriteJsonImpl impl(*this);  -        ReadJson(&in, &impl);  -        if (impl.IsOK()) {  -            out << Prefix;  -            impl.WriteTo(out);  -            out.Flush();  -        }  +                out << "\t" << FieldValues[n]; +        } + +        void WriteTo(TVector<TString>* res) const { +            *res = FieldValues; +        } +    }; + +    void TJsonParser::ConvertToTabDelimited(IInputStream& in, IOutputStream& out) const { +        TRewriteJsonImpl impl(*this); +        ReadJson(&in, &impl); +        if (impl.IsOK()) { +            out << Prefix; +            impl.WriteTo(out); +            out.Flush(); +        }      } -    bool TJsonParser::Parse(const TString& json, TVector<TString>* res) const {  -        TRewriteJsonImpl impl(*this);  -        TStringInput in(json);  -        ReadJson(&in, &impl);  -        if (impl.IsOK()) {  -            impl.WriteTo(res);  -            return true;  -        } else  -            return false;  +    bool TJsonParser::Parse(const TString& json, TVector<TString>* res) const { +        TRewriteJsonImpl impl(*this); +        TStringInput in(json); +        ReadJson(&in, &impl); +        if (impl.IsOK()) { +            impl.WriteTo(res); +            return true; +        } else +            return false;      } -    //struct TTestMe {  -    //    TTestMe() {  -    //        TJsonParser worker;  -    //        worker.AddField("/x/y/z", true);  -    //        TString ret1 = worker.ConvertToTabDelimited("{ \"x\" : { \"y\" : { \"w\" : 1, \"z\" : 2 } } }");  -    //        TString ret2 = worker.ConvertToTabDelimited(" [1, 2, 3, 4, 5] ");  -    //    }  -    //} testMe;  +    //struct TTestMe { +    //    TTestMe() { +    //        TJsonParser worker; +    //        worker.AddField("/x/y/z", true); +    //        TString ret1 = worker.ConvertToTabDelimited("{ \"x\" : { \"y\" : { \"w\" : 1, \"z\" : 2 } } }"); +    //        TString ret2 = worker.ConvertToTabDelimited(" [1, 2, 3, 4, 5] "); +    //    } +    //} testMe;  } diff --git a/library/cpp/json/easy_parse/json_easy_parser.h b/library/cpp/json/easy_parse/json_easy_parser.h index 310ec6f2ec4..59d7791ab14 100644 --- a/library/cpp/json/easy_parse/json_easy_parser.h +++ b/library/cpp/json/easy_parse/json_easy_parser.h @@ -1,5 +1,5 @@  #pragma once -  +  #include <util/generic/string.h>  #include <util/generic/vector.h>  #include <util/stream/input.h> @@ -33,14 +33,14 @@ namespace NJson {          friend class TRewriteJsonImpl; -        void ConvertToTabDelimited(IInputStream& in, IOutputStream& out) const;  -  +        void ConvertToTabDelimited(IInputStream& in, IOutputStream& out) const; +      public: -        void SetPrefix(const TString& prefix) {  +        void SetPrefix(const TString& prefix) {              Prefix = prefix;          } -        void AddField(const TString& path, bool mustExist);  -        TString ConvertToTabDelimited(const TString& json) const;  -        bool Parse(const TString& json, TVector<TString>* res) const;  +        void AddField(const TString& path, bool mustExist); +        TString ConvertToTabDelimited(const TString& json) const; +        bool Parse(const TString& json, TVector<TString>* res) const;      };  } diff --git a/library/cpp/json/easy_parse/json_easy_parser_impl.h b/library/cpp/json/easy_parse/json_easy_parser_impl.h index 4ac14e8a440..ec55d838b32 100644 --- a/library/cpp/json/easy_parse/json_easy_parser_impl.h +++ b/library/cpp/json/easy_parse/json_easy_parser_impl.h @@ -22,7 +22,7 @@ namespace NJson {          {          } -        TPathElemImpl(const TStringType& key)  +        TPathElemImpl(const TStringType& key)              : Type(NImpl::MAP_KEY)              , Key(key)              , ArrayCounter() @@ -31,8 +31,8 @@ namespace NJson {          TPathElemImpl(int arrayCounter)              : Type(NImpl::ARRAY) -            , ArrayCounter(arrayCounter)  -        {  +            , ArrayCounter(arrayCounter) +        {          }      }; diff --git a/library/cpp/json/fast_sax/parser.h b/library/cpp/json/fast_sax/parser.h index 31f5348da93..b5f031dd9eb 100644 --- a/library/cpp/json/fast_sax/parser.h +++ b/library/cpp/json/fast_sax/parser.h @@ -1,13 +1,13 @@ -#pragma once  -  +#pragma once +  #include <library/cpp/json/common/defs.h> -  -namespace NJson {  -    bool ReadJsonFast(TStringBuf in, TJsonCallbacks* callbacks);  -  -    inline bool ValidateJsonFast(TStringBuf in, bool throwOnError = false) {  + +namespace NJson { +    bool ReadJsonFast(TStringBuf in, TJsonCallbacks* callbacks); + +    inline bool ValidateJsonFast(TStringBuf in, bool throwOnError = false) {          Y_ASSERT(false); // this method is broken, see details in IGNIETFERRO-1243. Use NJson::ValidateJson instead, or fix this one before using -        TJsonCallbacks c(throwOnError);  -        return ReadJsonFast(in, &c);  -    }  -}  +        TJsonCallbacks c(throwOnError); +        return ReadJsonFast(in, &c); +    } +} diff --git a/library/cpp/json/fast_sax/parser.rl6 b/library/cpp/json/fast_sax/parser.rl6 index 0f1ad3b3b1b..edb4e9ee1b3 100644 --- a/library/cpp/json/fast_sax/parser.rl6 +++ b/library/cpp/json/fast_sax/parser.rl6 @@ -2,7 +2,7 @@  #include <library/cpp/json/fast_sax/parser.h>  #include <util/string/cast.h> -#include <util/generic/buffer.h>  +#include <util/generic/buffer.h>  #include <util/generic/strbuf.h>  #include <util/generic/ymath.h> @@ -15,7 +15,7 @@ enum EStoredStr {  struct TParserCtx {      TJsonCallbacks& Hndl; -    TBuffer Buffer;  +    TBuffer Buffer;      TStringBuf String;      EStoredStr Stored = SS_NONE;      bool ExpectValue = true; @@ -142,9 +142,9 @@ struct TParserCtx {      }      bool OnStrE() { -        Buffer.Clear();  -        Buffer.Reserve(2 * (te - ts));  -  +        Buffer.Clear(); +        Buffer.Reserve(2 * (te - ts)); +          return OnString(UnescapeJsonUnicode(TStringBuf(ts + 1, te - ts - 2), Buffer.data()), SS_MUSTCOPY);      } @@ -170,8 +170,8 @@ struct TParserCtx {          Stored = SS_NONE;          switch (stored) { -        default:  -            return false;  +        default: +            return false;          case SS_NOCOPY:              return Hndl.OnMapKeyNoCopy(String);          case SS_MUSTCOPY: diff --git a/library/cpp/json/fast_sax/unescape.cpp b/library/cpp/json/fast_sax/unescape.cpp index 772fe92a0db..72109b0b5e6 100644 --- a/library/cpp/json/fast_sax/unescape.cpp +++ b/library/cpp/json/fast_sax/unescape.cpp @@ -1,7 +1,7 @@ -#include "unescape.h"  -  -#include <util/string/escape.h>  -  -TStringBuf UnescapeJsonUnicode(TStringBuf data, char* scratch) {  +#include "unescape.h" + +#include <util/string/escape.h> + +TStringBuf UnescapeJsonUnicode(TStringBuf data, char* scratch) {      return TStringBuf(scratch, UnescapeC(data.data(), data.size(), scratch)); -}  +} diff --git a/library/cpp/json/fast_sax/unescape.h b/library/cpp/json/fast_sax/unescape.h index 55315548bc5..5e40e1e8660 100644 --- a/library/cpp/json/fast_sax/unescape.h +++ b/library/cpp/json/fast_sax/unescape.h @@ -1,5 +1,5 @@ -#pragma once  -  -#include <util/generic/strbuf.h>  -  -TStringBuf UnescapeJsonUnicode(TStringBuf data, char* scratch);  +#pragma once + +#include <util/generic/strbuf.h> + +TStringBuf UnescapeJsonUnicode(TStringBuf data, char* scratch); diff --git a/library/cpp/json/fast_sax/ya.make b/library/cpp/json/fast_sax/ya.make index 46e5c7c5d96..c6447ab6acc 100644 --- a/library/cpp/json/fast_sax/ya.make +++ b/library/cpp/json/fast_sax/ya.make @@ -1,17 +1,17 @@ -LIBRARY()  -  +LIBRARY() +  OWNER(      pg      velavokr  ) -  -PEERDIR(  + +PEERDIR(      library/cpp/json/common -)  -  -SRCS(  -    parser.rl6  -    unescape.cpp  -)  -  -END()  +) + +SRCS( +    parser.rl6 +    unescape.cpp +) + +END() diff --git a/library/cpp/json/flex_buffers/cvt.cpp b/library/cpp/json/flex_buffers/cvt.cpp index 9f7d6303737..fee0cea0b83 100644 --- a/library/cpp/json/flex_buffers/cvt.cpp +++ b/library/cpp/json/flex_buffers/cvt.cpp @@ -1,139 +1,139 @@ -#include "cvt.h"  -  -#include <flatbuffers/flexbuffers.h>  -  +#include "cvt.h" + +#include <flatbuffers/flexbuffers.h> +  #include <library/cpp/json/fast_sax/parser.h>  #include <library/cpp/json/json_reader.h> -  -#include <util/generic/vector.h>  -#include <util/stream/output.h>  -#include <util/stream/input.h>  -#include <util/memory/pool.h>  -  -using namespace NJson;  -  -namespace {  -    struct TJsonToFlexCallbacks: public TJsonCallbacks {  -        inline TJsonToFlexCallbacks()  -            : P(8192)  -        {  -        }  -  + +#include <util/generic/vector.h> +#include <util/stream/output.h> +#include <util/stream/input.h> +#include <util/memory/pool.h> + +using namespace NJson; + +namespace { +    struct TJsonToFlexCallbacks: public TJsonCallbacks { +        inline TJsonToFlexCallbacks() +            : P(8192) +        { +        } +          bool OnNull() override { -            B.Null();  -  -            return true;  -        }  -  +            B.Null(); + +            return true; +        } +          bool OnBoolean(bool v) override { -            B.Bool(v);  -  -            return true;  -        }  -  +            B.Bool(v); + +            return true; +        } +          bool OnInteger(long long v) override { -            B.Int(v);  -  -            return true;  -        }  -  +            B.Int(v); + +            return true; +        } +          bool OnUInteger(unsigned long long v) override { -            B.UInt(v);  -  -            return true;  -        }  -  +            B.UInt(v); + +            return true; +        } +          bool OnDouble(double v) override { -            B.Double(v);  -  -            return true;  -        }  -  +            B.Double(v); + +            return true; +        } +          bool OnString(const TStringBuf& v) override {              B.String(v.data(), v.size()); -  -            return true;  -        }  -  + +            return true; +        } +          bool OnOpenMap() override { -            S.push_back(B.StartMap());  -  -            return true;  -        }  -  +            S.push_back(B.StartMap()); + +            return true; +        } +          bool OnMapKey(const TStringBuf& v) override {              auto iv = P.AppendCString(v); -  +              B.Key(iv.data(), iv.size()); -  -            return true;  -        }  -  + +            return true; +        } +          bool OnCloseMap() override { -            B.EndMap(PopOffset());  -  -            return true;  -        }  -  +            B.EndMap(PopOffset()); + +            return true; +        } +          bool OnOpenArray() override { -            S.push_back(B.StartVector());  -  -            return true;  -        }  -  +            S.push_back(B.StartVector()); + +            return true; +        } +          bool OnCloseArray() override { -            B.EndVector(PopOffset(), false, false);  -  -            return true;  -        }  -  +            B.EndVector(PopOffset(), false, false); + +            return true; +        } +          bool OnStringNoCopy(const TStringBuf& s) override { -            return OnString(s);  -        }  -  +            return OnString(s); +        } +          bool OnMapKeyNoCopy(const TStringBuf& s) override { -            return OnMapKey(s);  -        }  -  +            return OnMapKey(s); +        } +          bool OnEnd() override { -            B.Finish();  -  -            Y_ENSURE(S.empty());  -  -            return true;  -        }  -  +            B.Finish(); + +            Y_ENSURE(S.empty()); + +            return true; +        } +          void OnError(size_t, TStringBuf reason) override { -            ythrow yexception() << reason;  -        }  -  -        inline size_t PopOffset() {  -            auto res = S.back();  -  -            S.pop_back();  -  -            return res;  -        }  -  -        inline auto& Buffer() {  -            return B.GetBuffer();  -        }  -  -        flexbuffers::Builder B;  -        TVector<size_t> S;  -        TMemoryPool P;  -    };  -}  -  -void NJson::ConvertJsonToFlexBuffers(TStringBuf input, TFlexBuffersData& result) {  -    TJsonToFlexCallbacks cb;  -  -    ReadJsonFast(input, &cb);  -    result.swap(const_cast<std::vector<ui8>&>(cb.Buffer()));  -}  -  -TString NJson::FlexToString(const TFlexBuffersData& v) {  +            ythrow yexception() << reason; +        } + +        inline size_t PopOffset() { +            auto res = S.back(); + +            S.pop_back(); + +            return res; +        } + +        inline auto& Buffer() { +            return B.GetBuffer(); +        } + +        flexbuffers::Builder B; +        TVector<size_t> S; +        TMemoryPool P; +    }; +} + +void NJson::ConvertJsonToFlexBuffers(TStringBuf input, TFlexBuffersData& result) { +    TJsonToFlexCallbacks cb; + +    ReadJsonFast(input, &cb); +    result.swap(const_cast<std::vector<ui8>&>(cb.Buffer())); +} + +TString NJson::FlexToString(const TFlexBuffersData& v) {      auto root = flexbuffers::GetRoot(v.data(), v.size()); -  -    return TString(root.ToString());  -}  + +    return TString(root.ToString()); +} diff --git a/library/cpp/json/flex_buffers/cvt.h b/library/cpp/json/flex_buffers/cvt.h index 489f2dad83b..82d2874268e 100644 --- a/library/cpp/json/flex_buffers/cvt.h +++ b/library/cpp/json/flex_buffers/cvt.h @@ -1,20 +1,20 @@ -#pragma once  -  -#include <util/generic/vector.h>  -#include <util/generic/strbuf.h>  -#include <util/generic/string.h>  -  -namespace NJson {  -    using TFlexBuffersData = TVector<ui8>;  -  -    TString FlexToString(const TFlexBuffersData& v);  -    void ConvertJsonToFlexBuffers(TStringBuf input, TFlexBuffersData& result);  -  -    inline TFlexBuffersData ConvertJsonToFlexBuffers(TStringBuf input) {  -        TFlexBuffersData result;  -  -        ConvertJsonToFlexBuffers(input, result);  -  -        return result;  -    }  -}  +#pragma once + +#include <util/generic/vector.h> +#include <util/generic/strbuf.h> +#include <util/generic/string.h> + +namespace NJson { +    using TFlexBuffersData = TVector<ui8>; + +    TString FlexToString(const TFlexBuffersData& v); +    void ConvertJsonToFlexBuffers(TStringBuf input, TFlexBuffersData& result); + +    inline TFlexBuffersData ConvertJsonToFlexBuffers(TStringBuf input) { +        TFlexBuffersData result; + +        ConvertJsonToFlexBuffers(input, result); + +        return result; +    } +} diff --git a/library/cpp/json/flex_buffers/ut/cvt_ut.cpp b/library/cpp/json/flex_buffers/ut/cvt_ut.cpp index de3eb0d520b..9fffef4d383 100644 --- a/library/cpp/json/flex_buffers/ut/cvt_ut.cpp +++ b/library/cpp/json/flex_buffers/ut/cvt_ut.cpp @@ -1,21 +1,21 @@  #include <library/cpp/testing/unittest/registar.h>  #include <library/cpp/json/flex_buffers/cvt.h> -  -using namespace NJson;  -  -static auto JSON = R"({  -    "a": {  -        "b": [1, 2, 3],  -        "c": ["x", "y", 3, "z"]  -    }  -})";  -  -static auto RES = R"({ a: { b: [ 1, 2, 3 ], c: [ "x", "y", 3, "z" ] } })";  -  -Y_UNIT_TEST_SUITE(JsonToFlex) {  -    Y_UNIT_TEST(Test1) {  -        auto buf = ConvertJsonToFlexBuffers(JSON);  -  -        UNIT_ASSERT_VALUES_EQUAL(FlexToString(buf), RES);  -    }  -}  + +using namespace NJson; + +static auto JSON = R"({ +    "a": { +        "b": [1, 2, 3], +        "c": ["x", "y", 3, "z"] +    } +})"; + +static auto RES = R"({ a: { b: [ 1, 2, 3 ], c: [ "x", "y", 3, "z" ] } })"; + +Y_UNIT_TEST_SUITE(JsonToFlex) { +    Y_UNIT_TEST(Test1) { +        auto buf = ConvertJsonToFlexBuffers(JSON); + +        UNIT_ASSERT_VALUES_EQUAL(FlexToString(buf), RES); +    } +} diff --git a/library/cpp/json/flex_buffers/ut/ya.make b/library/cpp/json/flex_buffers/ut/ya.make index 148ac138565..3fdc93f88ee 100644 --- a/library/cpp/json/flex_buffers/ut/ya.make +++ b/library/cpp/json/flex_buffers/ut/ya.make @@ -1,9 +1,9 @@  UNITTEST_FOR(library/cpp/json/flex_buffers) -  -OWNER(pg)  -  -SRCS(  -    cvt_ut.cpp  -)  -  -END()  + +OWNER(pg) + +SRCS( +    cvt_ut.cpp +) + +END() diff --git a/library/cpp/json/flex_buffers/ya.make b/library/cpp/json/flex_buffers/ya.make index 1b38b2f3d10..3ece5e3703d 100644 --- a/library/cpp/json/flex_buffers/ya.make +++ b/library/cpp/json/flex_buffers/ya.make @@ -1,16 +1,16 @@ -LIBRARY()  -  -OWNER(pg)  -  +LIBRARY() + +OWNER(pg) +  ADDINCL(contrib/libs/flatbuffers/include) -  -PEERDIR(  + +PEERDIR(      library/cpp/json -    contrib/libs/flatbuffers  -)  -  -SRCS(  -    cvt.cpp  -)  -  -END()  +    contrib/libs/flatbuffers +) + +SRCS( +    cvt.cpp +) + +END() diff --git a/library/cpp/json/fuzzy_test/main.cpp b/library/cpp/json/fuzzy_test/main.cpp index bdbf2679ffa..29a53aac142 100644 --- a/library/cpp/json/fuzzy_test/main.cpp +++ b/library/cpp/json/fuzzy_test/main.cpp @@ -1,30 +1,30 @@  #include <library/cpp/json/json_reader.h> -  -#include <util/random/random.h>  -#include <util/stream/str.h>  -  -extern "C" int LLVMFuzzerTestOneInput(const ui8* data, size_t size) {  + +#include <util/random/random.h> +#include <util/stream/str.h> + +extern "C" int LLVMFuzzerTestOneInput(const ui8* data, size_t size) {      const auto json = TString((const char*)data, size); -  -    try {  -        NJson::TJsonValue value;  -        NJson::ReadJsonFastTree(json, &value, true);  -    } catch (...) {  -        //Cout << json << " -> " << CurrentExceptionMessage() << Endl;  -    }  -  -    try {  -        NJson::TJsonCallbacks cb;  -        NJson::ReadJsonFast(json, &cb);  -    } catch (...) {  -        //Cout << json << " -> " << CurrentExceptionMessage() << Endl;  -    }  -  -    try {  -        NJson::ValidateJson(json);  -    } catch (...) {  -        //Cout << json << " -> " << CurrentExceptionMessage() << Endl;  -    }  -  -    return 0;  -}  + +    try { +        NJson::TJsonValue value; +        NJson::ReadJsonFastTree(json, &value, true); +    } catch (...) { +        //Cout << json << " -> " << CurrentExceptionMessage() << Endl; +    } + +    try { +        NJson::TJsonCallbacks cb; +        NJson::ReadJsonFast(json, &cb); +    } catch (...) { +        //Cout << json << " -> " << CurrentExceptionMessage() << Endl; +    } + +    try { +        NJson::ValidateJson(json); +    } catch (...) { +        //Cout << json << " -> " << CurrentExceptionMessage() << Endl; +    } + +    return 0; +} diff --git a/library/cpp/json/fuzzy_test/ya.make b/library/cpp/json/fuzzy_test/ya.make index 1ccd587546e..ff50bc1f622 100644 --- a/library/cpp/json/fuzzy_test/ya.make +++ b/library/cpp/json/fuzzy_test/ya.make @@ -1,13 +1,13 @@  FUZZ() -  -OWNER(pg)  -  -PEERDIR(  + +OWNER(pg) + +PEERDIR(      library/cpp/json -)  -  -SRCS(  -    main.cpp  -)  -  -END()  +) + +SRCS( +    main.cpp +) + +END() diff --git a/library/cpp/json/json_prettifier.cpp b/library/cpp/json/json_prettifier.cpp index cf36ae210db..bb16aab44e5 100644 --- a/library/cpp/json/json_prettifier.cpp +++ b/library/cpp/json/json_prettifier.cpp @@ -1,277 +1,277 @@  #include "json_prettifier.h"  #include <util/generic/deque.h> -#include <util/generic/algorithm.h>  +#include <util/generic/algorithm.h>  #include <util/memory/pool.h>  #include <util/string/util.h>  #include <library/cpp/string_utils/relaxed_escaper/relaxed_escaper.h>  namespace NJson { -    struct TRewritableOut {  -        IOutputStream& Slave;  - -        char Last = 0;  -        bool Dirty = false;  - -        TRewritableOut(IOutputStream& sl)  -            : Slave(sl)  -        {  -        }  - -        template <typename T>  -        void Write(const T& t) {  -            Flush();  -            Slave << t;  -        }  - -        void Hold(char c) {  -            if (Dirty)  -                Flush();  -            Last = c;  -            Dirty = true;  -        }  - -        void Flush() {  -            if (Dirty) {  -                Slave << Last;  -                Dirty = false;  -            }  -        }  - -        void Revert() {  +    struct TRewritableOut { +        IOutputStream& Slave; + +        char Last = 0; +        bool Dirty = false; + +        TRewritableOut(IOutputStream& sl) +            : Slave(sl) +        { +        } + +        template <typename T> +        void Write(const T& t) { +            Flush(); +            Slave << t; +        } + +        void Hold(char c) { +            if (Dirty) +                Flush(); +            Last = c; +            Dirty = true; +        } + +        void Flush() { +            if (Dirty) { +                Slave << Last; +                Dirty = false; +            } +        } + +        void Revert() {              Dirty = false;          } -    };  - -    struct TSpaces {  -        char S[256];  - -        TSpaces() {  -            memset(&S, ' ', sizeof(S));  -        }  - -        TStringBuf Get(ui8 sz) const {  -            return TStringBuf(S, sz);  -        }  -    };  - -    bool TJsonPrettifier::MayUnquoteNew(TStringBuf s) {  -        static str_spn alpha("a-zA-Z_@$", true);  -        static str_spn alnum("a-zA-Z_@$0-9.-", true);  -        static TStringBuf true0("true");  -        static TStringBuf false0("false");  -        static TStringBuf null0("null");  -  -        return !!s && alpha.chars_table[(ui8)s[0]] && alnum.cbrk(s.begin() + 1, s.end()) == s.end() && !EqualToOneOf(s, null0, true0, false0);  +    }; + +    struct TSpaces { +        char S[256]; + +        TSpaces() { +            memset(&S, ' ', sizeof(S)); +        } + +        TStringBuf Get(ui8 sz) const { +            return TStringBuf(S, sz); +        } +    }; + +    bool TJsonPrettifier::MayUnquoteNew(TStringBuf s) { +        static str_spn alpha("a-zA-Z_@$", true); +        static str_spn alnum("a-zA-Z_@$0-9.-", true); +        static TStringBuf true0("true"); +        static TStringBuf false0("false"); +        static TStringBuf null0("null"); + +        return !!s && alpha.chars_table[(ui8)s[0]] && alnum.cbrk(s.begin() + 1, s.end()) == s.end() && !EqualToOneOf(s, null0, true0, false0);      } -    // to keep arcadia tests happy  -    bool TJsonPrettifier::MayUnquoteOld(TStringBuf s) {  -        static str_spn alpha("a-zA-Z_@$", true);  -        static str_spn alnum("a-zA-Z_@$0-9", true);  -        static TStringBuf true0("true");  -        static TStringBuf false0("false");  -        static TStringBuf true1("on");  -        static TStringBuf false1("off");  -        static TStringBuf true2("da");  -        static TStringBuf false2("net");  -        static TStringBuf null0("null");  - -        return !!s && alpha.chars_table[(ui8)s[0]] && alnum.cbrk(s.begin() + 1, s.end()) == s.end() && !EqualToOneOf(s, null0, true0, false0, true1, false1, true2, false2);  -    }  - -    class TPrettifier: public TJsonCallbacks {  -        TRewritableOut Out;  -        TStringBuf Spaces;  -        TStringBuf Quote;  -        TStringBuf Unsafe;  -        TStringBuf Safe;  - -        ui32 Level = 0;  -        ui32 MaxPaddingLevel;  - -        bool Unquote = false;  -        bool Compactify = false;  -        bool NewUnquote = false;  - -    public:  -        TPrettifier(IOutputStream& out, const TJsonPrettifier& p)  -            : Out(out)  -            , MaxPaddingLevel(p.MaxPaddingLevel)  -            , Unquote(p.Unquote)  -            , Compactify(p.Compactify)  -            , NewUnquote(p.NewUnquote)  -        {  -            static TSpaces spaces;  -            Spaces = spaces.Get(p.Padding);  -            if (p.SingleQuotes) {  -                Quote = Unsafe = "'";  -                Safe = "\"";  -            } else {  -                Quote = Unsafe = "\"";  -                Safe = "'";  -            }  -        }  - -        void Pad(bool close = false) {  -            if (Compactify) {  -                Out.Flush();  -                return;  -            }  -            if (Level > MaxPaddingLevel || (Level == MaxPaddingLevel && close)) {  -                Out.Write(" ");  -                return;  -            }  -            if (Level || close) {  -                Out.Write(Spaces ? "\n" : " ");  -            }  -            for (ui32 i = 0; i < Level; ++i) {  -                Out.Write(Spaces);  -            }  -        }  - -        void WriteSpace(char sp) {  -            if (Compactify) {  -                Out.Flush();  -                return;  -            }  - -            Out.Write(sp);  +    // to keep arcadia tests happy +    bool TJsonPrettifier::MayUnquoteOld(TStringBuf s) { +        static str_spn alpha("a-zA-Z_@$", true); +        static str_spn alnum("a-zA-Z_@$0-9", true); +        static TStringBuf true0("true"); +        static TStringBuf false0("false"); +        static TStringBuf true1("on"); +        static TStringBuf false1("off"); +        static TStringBuf true2("da"); +        static TStringBuf false2("net"); +        static TStringBuf null0("null"); + +        return !!s && alpha.chars_table[(ui8)s[0]] && alnum.cbrk(s.begin() + 1, s.end()) == s.end() && !EqualToOneOf(s, null0, true0, false0, true1, false1, true2, false2); +    } + +    class TPrettifier: public TJsonCallbacks { +        TRewritableOut Out; +        TStringBuf Spaces; +        TStringBuf Quote; +        TStringBuf Unsafe; +        TStringBuf Safe; + +        ui32 Level = 0; +        ui32 MaxPaddingLevel; + +        bool Unquote = false; +        bool Compactify = false; +        bool NewUnquote = false; + +    public: +        TPrettifier(IOutputStream& out, const TJsonPrettifier& p) +            : Out(out) +            , MaxPaddingLevel(p.MaxPaddingLevel) +            , Unquote(p.Unquote) +            , Compactify(p.Compactify) +            , NewUnquote(p.NewUnquote) +        { +            static TSpaces spaces; +            Spaces = spaces.Get(p.Padding); +            if (p.SingleQuotes) { +                Quote = Unsafe = "'"; +                Safe = "\""; +            } else { +                Quote = Unsafe = "\""; +                Safe = "'"; +            }          } -        void OnVal() {  -            if (Out.Dirty && ':' == Out.Last) {  -                WriteSpace(' ');  -            } else {  -                Pad();  -            }  +        void Pad(bool close = false) { +            if (Compactify) { +                Out.Flush(); +                return; +            } +            if (Level > MaxPaddingLevel || (Level == MaxPaddingLevel && close)) { +                Out.Write(" "); +                return; +            } +            if (Level || close) { +                Out.Write(Spaces ? "\n" : " "); +            } +            for (ui32 i = 0; i < Level; ++i) { +                Out.Write(Spaces); +            }          } -  -        void AfterVal() {  -            Out.Hold(',');  + +        void WriteSpace(char sp) { +            if (Compactify) { +                Out.Flush(); +                return; +            } + +            Out.Write(sp); +        } + +        void OnVal() { +            if (Out.Dirty && ':' == Out.Last) { +                WriteSpace(' '); +            } else { +                Pad(); +            }          } -  -        template <typename T>  -        bool WriteVal(const T& t) {  -            OnVal();  -            Out.Write(t);  -            AfterVal();  -            return true;  + +        void AfterVal() { +            Out.Hold(','); +        } + +        template <typename T> +        bool WriteVal(const T& t) { +            OnVal(); +            Out.Write(t); +            AfterVal(); +            return true;          } -  -        bool OnNull() override {  + +        bool OnNull() override {              return WriteVal(TStringBuf("null"));          } -        bool OnBoolean(bool v) override {  +        bool OnBoolean(bool v) override {              return WriteVal(v ? TStringBuf("true") : TStringBuf("false"));          } -        bool OnInteger(long long i) override {  -            return WriteVal(i);  -        }  +        bool OnInteger(long long i) override { +            return WriteVal(i); +        } + +        bool OnUInteger(unsigned long long i) override { +            return WriteVal(i); +        } + +        bool OnDouble(double d) override { +            return WriteVal(d); +        } + +        void WriteString(TStringBuf s) { +            if (Unquote && (NewUnquote ? TJsonPrettifier::MayUnquoteNew(s) : TJsonPrettifier::MayUnquoteOld(s))) { +                Out.Slave << s; +            } else { +                Out.Slave << Quote; +                NEscJ::EscapeJ<false, true>(s, Out.Slave, Safe, Unsafe); +                Out.Slave << Quote; +            } +        } + +        bool OnString(const TStringBuf& s) override { +            OnVal(); +            WriteString(s); +            AfterVal(); +            return true; +        } + +        bool OnOpen(char c) { +            OnVal(); +            Level++; +            Out.Hold(c); +            return true; +        } + +        bool OnOpenMap() override { +            return OnOpen('{'); +        } + +        bool OnOpenArray() override { +            return OnOpen('['); +        } + +        bool OnMapKey(const TStringBuf& k) override { +            OnVal(); +            WriteString(k); +            WriteSpace(' '); +            Out.Hold(':'); +            return true; +        } + +        bool OnClose(char c) { +            if (!Level) +                return false; + +            Level--; + +            if (Out.Dirty && c == Out.Last) { +                WriteSpace(' '); +            } else { +                Out.Revert(); +                Pad(true); +            } + +            return true; +        } + +        bool OnCloseMap() override { +            if (!OnClose('{')) +                return false; +            Out.Write("}"); +            AfterVal(); +            return true; +        } -        bool OnUInteger(unsigned long long i) override {  -            return WriteVal(i);  +        bool OnCloseArray() override { +            if (!OnClose('[')) +                return false; +            Out.Write("]"); +            AfterVal(); +            return true;          } -        bool OnDouble(double d) override {  -            return WriteVal(d);  -        }  - -        void WriteString(TStringBuf s) {  -            if (Unquote && (NewUnquote ? TJsonPrettifier::MayUnquoteNew(s) : TJsonPrettifier::MayUnquoteOld(s))) {  -                Out.Slave << s;  -            } else {  -                Out.Slave << Quote;  -                NEscJ::EscapeJ<false, true>(s, Out.Slave, Safe, Unsafe);  -                Out.Slave << Quote;  -            }  -        }  - -        bool OnString(const TStringBuf& s) override {  -            OnVal();  -            WriteString(s);  -            AfterVal();  -            return true;  -        }  - -        bool OnOpen(char c) {  -            OnVal();  -            Level++;  -            Out.Hold(c);  -            return true;  -        }  - -        bool OnOpenMap() override {  -            return OnOpen('{');  -        }  - -        bool OnOpenArray() override {  -            return OnOpen('[');  -        }  - -        bool OnMapKey(const TStringBuf& k) override {  -            OnVal();  -            WriteString(k);  -            WriteSpace(' ');  -            Out.Hold(':');  -            return true;  +        bool OnEnd() override { +            return !Level;          } +    }; -        bool OnClose(char c) {  -            if (!Level)  -                return false;  - -            Level--;  - -            if (Out.Dirty && c == Out.Last) {  -                WriteSpace(' ');  -            } else {  -                Out.Revert();  -                Pad(true);  -            }  - -            return true;  -        }  - -        bool OnCloseMap() override {  -            if (!OnClose('{'))  -                return false;  -            Out.Write("}");  -            AfterVal();  -            return true;  -        }  - -        bool OnCloseArray() override {  -            if (!OnClose('['))  -                return false;  -            Out.Write("]");  -            AfterVal();  -            return true;  -        }  - -        bool OnEnd() override {  -            return !Level;  -        }  -    };  - -    bool TJsonPrettifier::Prettify(TStringBuf in, IOutputStream& out) const {  -        TPrettifier p(out, *this);  -        if (Strict) {  +    bool TJsonPrettifier::Prettify(TStringBuf in, IOutputStream& out) const { +        TPrettifier p(out, *this); +        if (Strict) {              TMemoryInput mIn(in.data(), in.size()); -            return ReadJson(&mIn, &p);  +            return ReadJson(&mIn, &p);          } else { -            return ReadJsonFast(in, &p);  +            return ReadJsonFast(in, &p);          }      } -    TString TJsonPrettifier::Prettify(TStringBuf in) const {  -        TStringStream s;  -        if (Prettify(in, s))  -            return s.Str();  -        return TString();  +    TString TJsonPrettifier::Prettify(TStringBuf in) const { +        TStringStream s; +        if (Prettify(in, s)) +            return s.Str(); +        return TString();      }  } diff --git a/library/cpp/json/json_prettifier.h b/library/cpp/json/json_prettifier.h index 873942f11a5..27d611b0b43 100644 --- a/library/cpp/json/json_prettifier.h +++ b/library/cpp/json/json_prettifier.h @@ -5,54 +5,54 @@  #include <util/generic/ylimits.h>  namespace NJson { -    struct TJsonPrettifier {  -        bool Unquote = false;  -        ui8 Padding = 4;  -        bool SingleQuotes = false;  -        bool Compactify = false;  -        bool Strict = false;  -        bool NewUnquote = false; // use new unquote, may break old tests  -        ui32 MaxPaddingLevel = Max<ui32>();  - -        static TJsonPrettifier Prettifier(bool unquote = false, ui8 padding = 4, bool singlequotes = false) {  -            TJsonPrettifier p;  -            p.Unquote = unquote;  -            p.Padding = padding;  -            p.SingleQuotes = singlequotes;  -            return p;  -        }  - -        static TJsonPrettifier Compactifier(bool unquote = false, bool singlequote = false) {  -            TJsonPrettifier p;  -            p.Unquote = unquote;  -            p.Padding = 0;  -            p.Compactify = true;  -            p.SingleQuotes = singlequote;  -            return p;  -        }  - -        bool Prettify(TStringBuf in, IOutputStream& out) const;  - -        TString Prettify(TStringBuf in) const;  - -        static bool MayUnquoteNew(TStringBuf in);  -        static bool MayUnquoteOld(TStringBuf in);  -    };  - -    inline TString PrettifyJson(TStringBuf in, bool unquote = false, ui8 padding = 4, bool sq = false) {  -        return TJsonPrettifier::Prettifier(unquote, padding, sq).Prettify(in);  -    }  - -    inline bool PrettifyJson(TStringBuf in, IOutputStream& out, bool unquote = false, ui8 padding = 4, bool sq = false) {  -        return TJsonPrettifier::Prettifier(unquote, padding, sq).Prettify(in, out);  -    }  - -    inline bool CompactifyJson(TStringBuf in, IOutputStream& out, bool unquote = false, bool sq = false) {  -        return TJsonPrettifier::Compactifier(unquote, sq).Prettify(in, out);  -    }  - -    inline TString CompactifyJson(TStringBuf in, bool unquote = false, bool sq = false) {  -        return TJsonPrettifier::Compactifier(unquote, sq).Prettify(in);  -    }  +    struct TJsonPrettifier { +        bool Unquote = false; +        ui8 Padding = 4; +        bool SingleQuotes = false; +        bool Compactify = false; +        bool Strict = false; +        bool NewUnquote = false; // use new unquote, may break old tests +        ui32 MaxPaddingLevel = Max<ui32>(); + +        static TJsonPrettifier Prettifier(bool unquote = false, ui8 padding = 4, bool singlequotes = false) { +            TJsonPrettifier p; +            p.Unquote = unquote; +            p.Padding = padding; +            p.SingleQuotes = singlequotes; +            return p; +        } + +        static TJsonPrettifier Compactifier(bool unquote = false, bool singlequote = false) { +            TJsonPrettifier p; +            p.Unquote = unquote; +            p.Padding = 0; +            p.Compactify = true; +            p.SingleQuotes = singlequote; +            return p; +        } + +        bool Prettify(TStringBuf in, IOutputStream& out) const; + +        TString Prettify(TStringBuf in) const; + +        static bool MayUnquoteNew(TStringBuf in); +        static bool MayUnquoteOld(TStringBuf in); +    }; + +    inline TString PrettifyJson(TStringBuf in, bool unquote = false, ui8 padding = 4, bool sq = false) { +        return TJsonPrettifier::Prettifier(unquote, padding, sq).Prettify(in); +    } + +    inline bool PrettifyJson(TStringBuf in, IOutputStream& out, bool unquote = false, ui8 padding = 4, bool sq = false) { +        return TJsonPrettifier::Prettifier(unquote, padding, sq).Prettify(in, out); +    } + +    inline bool CompactifyJson(TStringBuf in, IOutputStream& out, bool unquote = false, bool sq = false) { +        return TJsonPrettifier::Compactifier(unquote, sq).Prettify(in, out); +    } + +    inline TString CompactifyJson(TStringBuf in, bool unquote = false, bool sq = false) { +        return TJsonPrettifier::Compactifier(unquote, sq).Prettify(in); +    }  } diff --git a/library/cpp/json/json_reader.cpp b/library/cpp/json/json_reader.cpp index 87ec7d27426..072c8deafee 100644 --- a/library/cpp/json/json_reader.cpp +++ b/library/cpp/json/json_reader.cpp @@ -20,117 +20,117 @@ namespace NJson {          }      } -    static const size_t DEFAULT_BUFFER_LEN = 65536;  - -    bool TParserCallbacks::OpenComplexValue(EJsonValueType type) {  -        TJsonValue* pvalue;  -        switch (CurrentState) {  -            case START:  -                Value.SetType(type);  -                ValuesStack.push_back(&Value);  -                break;  -            case IN_ARRAY:  -                pvalue = &ValuesStack.back()->AppendValue(type);  -                ValuesStack.push_back(pvalue);  -                break;  -            case AFTER_MAP_KEY:  -                pvalue = &ValuesStack.back()->InsertValue(Key, type);  -                ValuesStack.push_back(pvalue);  -                CurrentState = IN_MAP;  -                break;  -            default:  -                return false;  -        }  -        return true;  -    } - -    bool TParserCallbacks::CloseComplexValue() {  -        if (ValuesStack.empty()) {  +    static const size_t DEFAULT_BUFFER_LEN = 65536; + +    bool TParserCallbacks::OpenComplexValue(EJsonValueType type) { +        TJsonValue* pvalue; +        switch (CurrentState) { +            case START: +                Value.SetType(type); +                ValuesStack.push_back(&Value); +                break; +            case IN_ARRAY: +                pvalue = &ValuesStack.back()->AppendValue(type); +                ValuesStack.push_back(pvalue); +                break; +            case AFTER_MAP_KEY: +                pvalue = &ValuesStack.back()->InsertValue(Key, type); +                ValuesStack.push_back(pvalue); +                CurrentState = IN_MAP; +                break; +            default: +                return false; +        } +        return true; +    } + +    bool TParserCallbacks::CloseComplexValue() { +        if (ValuesStack.empty()) {              return false;          } -  -        ValuesStack.pop_back();  -        if (!ValuesStack.empty()) {  -            switch (ValuesStack.back()->GetType()) {  -                case JSON_ARRAY:  -                    CurrentState = IN_ARRAY;  -                    break;  -                case JSON_MAP:  -                    CurrentState = IN_MAP;  -                    break;  -                default:  -                    return false;  -            }  -        } else {  -            CurrentState = FINISH;  -        }  -        return true;  + +        ValuesStack.pop_back(); +        if (!ValuesStack.empty()) { +            switch (ValuesStack.back()->GetType()) { +                case JSON_ARRAY: +                    CurrentState = IN_ARRAY; +                    break; +                case JSON_MAP: +                    CurrentState = IN_MAP; +                    break; +                default: +                    return false; +            } +        } else { +            CurrentState = FINISH; +        } +        return true;      }      TParserCallbacks::TParserCallbacks(TJsonValue& value, bool throwOnError, bool notClosedBracketIsError) -        : TJsonCallbacks(throwOnError)  -        , Value(value)  +        : TJsonCallbacks(throwOnError) +        , Value(value)          , NotClosedBracketIsError(notClosedBracketIsError) -        , CurrentState(START)  -    {  -    }  - -    bool TParserCallbacks::OnNull() {  -        return SetValue(JSON_NULL);  -    }  - -    bool TParserCallbacks::OnBoolean(bool val) {  -        return SetValue(val);  -    }  - -    bool TParserCallbacks::OnInteger(long long val) {  -        return SetValue(val);  -    }  - -    bool TParserCallbacks::OnUInteger(unsigned long long val) {  -        return SetValue(val);  -    }  - -    bool TParserCallbacks::OnString(const TStringBuf& val) {  -        return SetValue(val);  -    }  - -    bool TParserCallbacks::OnDouble(double val) {  -        return SetValue(val);  -    }  - -    bool TParserCallbacks::OnOpenArray() {  -        bool res = OpenComplexValue(JSON_ARRAY);  -        if (res)  -            CurrentState = IN_ARRAY;  -        return res;  -    }  - -    bool TParserCallbacks::OnCloseArray() {  -        return CloseComplexValue();  -    }  - -    bool TParserCallbacks::OnOpenMap() {  -        bool res = OpenComplexValue(JSON_MAP);  -        if (res)  -            CurrentState = IN_MAP;  -        return res;  -    }  - -    bool TParserCallbacks::OnCloseMap() {  -        return CloseComplexValue();  -    }  - -    bool TParserCallbacks::OnMapKey(const TStringBuf& val) {  -        switch (CurrentState) {  -            case IN_MAP:  -                Key = val;  -                CurrentState = AFTER_MAP_KEY;  -                break;  -            default:  -                return false;  -        }  -        return true;  +        , CurrentState(START) +    { +    } + +    bool TParserCallbacks::OnNull() { +        return SetValue(JSON_NULL); +    } + +    bool TParserCallbacks::OnBoolean(bool val) { +        return SetValue(val); +    } + +    bool TParserCallbacks::OnInteger(long long val) { +        return SetValue(val); +    } + +    bool TParserCallbacks::OnUInteger(unsigned long long val) { +        return SetValue(val); +    } + +    bool TParserCallbacks::OnString(const TStringBuf& val) { +        return SetValue(val); +    } + +    bool TParserCallbacks::OnDouble(double val) { +        return SetValue(val); +    } + +    bool TParserCallbacks::OnOpenArray() { +        bool res = OpenComplexValue(JSON_ARRAY); +        if (res) +            CurrentState = IN_ARRAY; +        return res; +    } + +    bool TParserCallbacks::OnCloseArray() { +        return CloseComplexValue(); +    } + +    bool TParserCallbacks::OnOpenMap() { +        bool res = OpenComplexValue(JSON_MAP); +        if (res) +            CurrentState = IN_MAP; +        return res; +    } + +    bool TParserCallbacks::OnCloseMap() { +        return CloseComplexValue(); +    } + +    bool TParserCallbacks::OnMapKey(const TStringBuf& val) { +        switch (CurrentState) { +            case IN_MAP: +                Key = val; +                CurrentState = AFTER_MAP_KEY; +                break; +            default: +                return false; +        } +        return true;      }      bool TParserCallbacks::OnEnd() { @@ -140,182 +140,182 @@ namespace NJson {          return true;      } -    TJsonReaderConfig::TJsonReaderConfig()  -        : BufferSize(DEFAULT_BUFFER_LEN)  -    {  -    }  +    TJsonReaderConfig::TJsonReaderConfig() +        : BufferSize(DEFAULT_BUFFER_LEN) +    { +    } -    void TJsonReaderConfig::SetBufferSize(size_t bufferSize) {  -        BufferSize = Max((size_t)1, Min(bufferSize, DEFAULT_BUFFER_LEN));  -    }  +    void TJsonReaderConfig::SetBufferSize(size_t bufferSize) { +        BufferSize = Max((size_t)1, Min(bufferSize, DEFAULT_BUFFER_LEN)); +    } -    size_t TJsonReaderConfig::GetBufferSize() const {  -        return BufferSize;  -    }  +    size_t TJsonReaderConfig::GetBufferSize() const { +        return BufferSize; +    } -    namespace {  -        struct TJsonValueBuilder {  +    namespace { +        struct TJsonValueBuilder {  #ifdef NDEBUG -            using TItem = TJsonValue*;  +            using TItem = TJsonValue*; -            inline TJsonValue& Access(TItem& item) const {  -                return *item;  -            }  +            inline TJsonValue& Access(TItem& item) const { +                return *item; +            }  #else -            struct TItem {  -                TJsonValue* V;  -                size_t DuplicateKeyCount;  - -                TItem(TJsonValue* v)  -                    : V(v)  -                    , DuplicateKeyCount(0)  -                {  -                }  -            };  -  -            inline TJsonValue& Access(TItem& item) const {  -                return *item.V;  +            struct TItem { +                TJsonValue* V; +                size_t DuplicateKeyCount; + +                TItem(TJsonValue* v) +                    : V(v) +                    , DuplicateKeyCount(0) +                { +                } +            }; + +            inline TJsonValue& Access(TItem& item) const { +                return *item.V;              }  #endif -            NJson::TJsonValue& V;  - -            TStack<TItem> S;  - -            TJsonValueBuilder(NJson::TJsonValue& v)  -                : V(v)  -            {  -                S.emplace(&V);  -            }  - -            template <class T>  -            void Set(const T& t) {  -                if (Access(S.top()).IsArray()) {  -                    Access(S.top()).AppendValue(t);  -                } else {  -                    Access(S.top()) = t;  -                    S.pop();  -                }  -            } - -            bool Null() {  -                Set(NJson::JSON_NULL);  -                return true;  -            }  - -            bool Bool(bool b) {  -                Set(b);  -                return true;  -            }  - -            bool Int(int i) {  -                Set(i);  -                return true;  -            }  - -            template <class U>  -            bool ProcessUint(U u) {  -                if (Y_LIKELY(u <= static_cast<ui64>(Max<i64>()))) {  -                    Set(i64(u));  -                } else {  -                    Set(u);  -                }  -                return true;  -            } - -            bool Uint(unsigned u) {  -                return ProcessUint(u);  -            }  - -            bool Int64(i64 i) {  -                Set(i);  -                return true;  -            }  - -            bool Uint64(ui64 u) {  -                return ProcessUint(u);  -            }  - -            bool Double(double d) {  -                Set(d);  -                return true;  -            }  - -            bool RawNumber(const char* str, rapidjson::SizeType length, bool copy) {  -                Y_ASSERT(false && "this method should never be called");  -                Y_UNUSED(str);  -                Y_UNUSED(length);  -                Y_UNUSED(copy);  -                return true;  -            }  - -            bool String(const char* str, rapidjson::SizeType length, bool copy) {  -                Y_ASSERT(copy);  -                Set(TStringBuf(str, length));  -                return true;  -            }  - -            bool StartObject() {  -                if (Access(S.top()).IsArray()) {  -                    S.emplace(&Access(S.top()).AppendValue(NJson::JSON_MAP));  -                } else {  -                    Access(S.top()).SetType(NJson::JSON_MAP);  -                }  -                return true;  -            } - -            bool Key(const char* str, rapidjson::SizeType length, bool copy) {  -                Y_ASSERT(copy);  -                auto& value = Access(S.top())[TStringBuf(str, length)];  +            NJson::TJsonValue& V; + +            TStack<TItem> S; + +            TJsonValueBuilder(NJson::TJsonValue& v) +                : V(v) +            { +                S.emplace(&V); +            } + +            template <class T> +            void Set(const T& t) { +                if (Access(S.top()).IsArray()) { +                    Access(S.top()).AppendValue(t); +                } else { +                    Access(S.top()) = t; +                    S.pop(); +                } +            } + +            bool Null() { +                Set(NJson::JSON_NULL); +                return true; +            } + +            bool Bool(bool b) { +                Set(b); +                return true; +            } + +            bool Int(int i) { +                Set(i); +                return true; +            } + +            template <class U> +            bool ProcessUint(U u) { +                if (Y_LIKELY(u <= static_cast<ui64>(Max<i64>()))) { +                    Set(i64(u)); +                } else { +                    Set(u); +                } +                return true; +            } + +            bool Uint(unsigned u) { +                return ProcessUint(u); +            } + +            bool Int64(i64 i) { +                Set(i); +                return true; +            } + +            bool Uint64(ui64 u) { +                return ProcessUint(u); +            } + +            bool Double(double d) { +                Set(d); +                return true; +            } + +            bool RawNumber(const char* str, rapidjson::SizeType length, bool copy) { +                Y_ASSERT(false && "this method should never be called"); +                Y_UNUSED(str); +                Y_UNUSED(length); +                Y_UNUSED(copy); +                return true; +            } + +            bool String(const char* str, rapidjson::SizeType length, bool copy) { +                Y_ASSERT(copy); +                Set(TStringBuf(str, length)); +                return true; +            } + +            bool StartObject() { +                if (Access(S.top()).IsArray()) { +                    S.emplace(&Access(S.top()).AppendValue(NJson::JSON_MAP)); +                } else { +                    Access(S.top()).SetType(NJson::JSON_MAP); +                } +                return true; +            } + +            bool Key(const char* str, rapidjson::SizeType length, bool copy) { +                Y_ASSERT(copy); +                auto& value = Access(S.top())[TStringBuf(str, length)];                  if (Y_UNLIKELY(value.GetType() != JSON_UNDEFINED)) {  #ifndef NDEBUG -                    ++S.top().DuplicateKeyCount;  +                    ++S.top().DuplicateKeyCount;  #endif -                    value.SetType(JSON_UNDEFINED);  -                }  -                S.emplace(&value);  -                return true;  +                    value.SetType(JSON_UNDEFINED); +                } +                S.emplace(&value); +                return true;              } -            inline int GetDuplicateKeyCount() const {  +            inline int GetDuplicateKeyCount() const {  #ifdef NDEBUG -                return 0;  +                return 0;  #else -                return S.top().DuplicateKeyCount;  +                return S.top().DuplicateKeyCount;  #endif -            }  - -            bool EndObject(rapidjson::SizeType memberCount) {  -                Y_ASSERT(memberCount == Access(S.top()).GetMap().size() + GetDuplicateKeyCount());  -                S.pop();  -                return true;  -            }  - -            bool StartArray() {  -                if (Access(S.top()).IsArray()) {  -                    S.emplace(&Access(S.top()).AppendValue(NJson::JSON_ARRAY));  -                } else {  -                    Access(S.top()).SetType(NJson::JSON_ARRAY);  -                }  -                return true;  -            }  -  -            bool EndArray(rapidjson::SizeType elementCount) {  -                Y_ASSERT(elementCount == Access(S.top()).GetArray().size());  -                S.pop();  -                return true;  -            }  -        };  -  -        template <class TRapidJsonCompliantInputStream, class THandler>  -        auto Read(const TJsonReaderConfig& config,  -                  rapidjson::Reader& reader,  -                  TRapidJsonCompliantInputStream& is,  -                  THandler& handler) {  +            } + +            bool EndObject(rapidjson::SizeType memberCount) { +                Y_ASSERT(memberCount == Access(S.top()).GetMap().size() + GetDuplicateKeyCount()); +                S.pop(); +                return true; +            } + +            bool StartArray() { +                if (Access(S.top()).IsArray()) { +                    S.emplace(&Access(S.top()).AppendValue(NJson::JSON_ARRAY)); +                } else { +                    Access(S.top()).SetType(NJson::JSON_ARRAY); +                } +                return true; +            } + +            bool EndArray(rapidjson::SizeType elementCount) { +                Y_ASSERT(elementCount == Access(S.top()).GetArray().size()); +                S.pop(); +                return true; +            } +        }; + +        template <class TRapidJsonCompliantInputStream, class THandler> +        auto Read(const TJsonReaderConfig& config, +                  rapidjson::Reader& reader, +                  TRapidJsonCompliantInputStream& is, +                  THandler& handler) {              ui8 flags = ReaderConfigToRapidJsonFlags::NOCOMMENTS_VALID_NOESCAPE; -            if (config.AllowComments) {  +            if (config.AllowComments) {                  flags |= ReaderConfigFlags::COMMENTS;              } @@ -329,9 +329,9 @@ namespace NJson {              switch (flags) {                  case ReaderConfigToRapidJsonFlags::COMMENTS_NOVALID_NOESCAPE: -                    return reader.Parse<rapidjson::kParseCommentsFlag>(is, handler);  +                    return reader.Parse<rapidjson::kParseCommentsFlag>(is, handler);                  case ReaderConfigToRapidJsonFlags::COMMENTS_VALID_NOESCAPE: -                    return reader.Parse<rapidjson::kParseCommentsFlag | rapidjson::kParseValidateEncodingFlag>(is, handler);  +                    return reader.Parse<rapidjson::kParseCommentsFlag | rapidjson::kParseValidateEncodingFlag>(is, handler);                  case ReaderConfigToRapidJsonFlags::COMMENTS_VALID_ESCAPE:                      return reader.Parse<rapidjson::kParseCommentsFlag | rapidjson::kParseValidateEncodingFlag | rapidjson::kParseEscapedApostropheFlag>(is, handler);                  case ReaderConfigToRapidJsonFlags::COMMENTS_NOVALID_ESCAPE: @@ -343,84 +343,84 @@ namespace NJson {                  case  ReaderConfigToRapidJsonFlags::NOCOMMENTS_NOVALID_ESCAPE:                      return reader.Parse<rapidjson::kParseEscapedApostropheFlag>(is, handler);                  default: -                    return reader.Parse<rapidjson::kParseNoFlags>(is, handler);  +                    return reader.Parse<rapidjson::kParseNoFlags>(is, handler);              }          } -        template <class TRapidJsonCompliantInputStream, class THandler>  -        bool ReadJson(TRapidJsonCompliantInputStream& is, const TJsonReaderConfig* config, THandler& handler, bool throwOnError) {  -            rapidjson::Reader reader;  -  -            auto result = Read(*config, reader, is, handler);  -  -            if (result.IsError()) {  -                if (throwOnError) {  +        template <class TRapidJsonCompliantInputStream, class THandler> +        bool ReadJson(TRapidJsonCompliantInputStream& is, const TJsonReaderConfig* config, THandler& handler, bool throwOnError) { +            rapidjson::Reader reader; + +            auto result = Read(*config, reader, is, handler); + +            if (result.IsError()) { +                if (throwOnError) {                      ythrow TJsonException() << PrintError(result); -                } else {  -                    return false;  -                }  -            }  -  +                } else { +                    return false; +                } +            } +              return true;          } -        template <class TRapidJsonCompliantInputStream>  -        bool ReadJsonTree(TRapidJsonCompliantInputStream& is, const TJsonReaderConfig* config, TJsonValue* out, bool throwOnError) {  -            out->SetType(NJson::JSON_NULL);  -  -            TJsonValueBuilder handler(*out);  -  -            return ReadJson(is, config, handler, throwOnError);  +        template <class TRapidJsonCompliantInputStream> +        bool ReadJsonTree(TRapidJsonCompliantInputStream& is, const TJsonReaderConfig* config, TJsonValue* out, bool throwOnError) { +            out->SetType(NJson::JSON_NULL); + +            TJsonValueBuilder handler(*out); + +            return ReadJson(is, config, handler, throwOnError); +        } + +        template <class TData> +        bool ReadJsonTreeImpl(TData* in, const TJsonReaderConfig* config, TJsonValue* out, bool throwOnError) { +            std::conditional_t<std::is_same<TData, TStringBuf>::value, TStringBufStreamWrapper, TInputStreamWrapper> is(*in); +            return ReadJsonTree(is, config, out, throwOnError); +        } + +        template <class TData> +        bool ReadJsonTreeImpl(TData* in, bool allowComments, TJsonValue* out, bool throwOnError) { +            TJsonReaderConfig config; +            config.AllowComments = allowComments; +            return ReadJsonTreeImpl(in, &config, out, throwOnError);          } -        template <class TData>  -        bool ReadJsonTreeImpl(TData* in, const TJsonReaderConfig* config, TJsonValue* out, bool throwOnError) {  -            std::conditional_t<std::is_same<TData, TStringBuf>::value, TStringBufStreamWrapper, TInputStreamWrapper> is(*in);  -            return ReadJsonTree(is, config, out, throwOnError);  -        }  - -        template <class TData>  -        bool ReadJsonTreeImpl(TData* in, bool allowComments, TJsonValue* out, bool throwOnError) {  -            TJsonReaderConfig config;  -            config.AllowComments = allowComments;  -            return ReadJsonTreeImpl(in, &config, out, throwOnError);  -        }  - -        template <class TData>  -        bool ReadJsonTreeImpl(TData* in, TJsonValue* out, bool throwOnError) {  -            return ReadJsonTreeImpl(in, false, out, throwOnError);  +        template <class TData> +        bool ReadJsonTreeImpl(TData* in, TJsonValue* out, bool throwOnError) { +            return ReadJsonTreeImpl(in, false, out, throwOnError);          } -    } //namespace  +    } //namespace -    bool ReadJsonTree(TStringBuf in, TJsonValue* out, bool throwOnError) {  -        return ReadJsonTreeImpl(&in, out, throwOnError);  +    bool ReadJsonTree(TStringBuf in, TJsonValue* out, bool throwOnError) { +        return ReadJsonTreeImpl(&in, out, throwOnError);      } -    bool ReadJsonTree(TStringBuf in, bool allowComments, TJsonValue* out, bool throwOnError) {  -        return ReadJsonTreeImpl(&in, allowComments, out, throwOnError);  -    }  +    bool ReadJsonTree(TStringBuf in, bool allowComments, TJsonValue* out, bool throwOnError) { +        return ReadJsonTreeImpl(&in, allowComments, out, throwOnError); +    } -    bool ReadJsonTree(TStringBuf in, const TJsonReaderConfig* config, TJsonValue* out, bool throwOnError) {  -        return ReadJsonTreeImpl(&in, config, out, throwOnError);  +    bool ReadJsonTree(TStringBuf in, const TJsonReaderConfig* config, TJsonValue* out, bool throwOnError) { +        return ReadJsonTreeImpl(&in, config, out, throwOnError);      } -    bool ReadJsonTree(IInputStream* in, TJsonValue* out, bool throwOnError) {  -        return ReadJsonTreeImpl(in, out, throwOnError);  +    bool ReadJsonTree(IInputStream* in, TJsonValue* out, bool throwOnError) { +        return ReadJsonTreeImpl(in, out, throwOnError);      } -    bool ReadJsonTree(IInputStream* in, bool allowComments, TJsonValue* out, bool throwOnError) {  -        return ReadJsonTreeImpl(in, allowComments, out, throwOnError);  +    bool ReadJsonTree(IInputStream* in, bool allowComments, TJsonValue* out, bool throwOnError) { +        return ReadJsonTreeImpl(in, allowComments, out, throwOnError);      } -    bool ReadJsonTree(IInputStream* in, const TJsonReaderConfig* config, TJsonValue* out, bool throwOnError) {  -        return ReadJsonTreeImpl(in, config, out, throwOnError);  +    bool ReadJsonTree(IInputStream* in, const TJsonReaderConfig* config, TJsonValue* out, bool throwOnError) { +        return ReadJsonTreeImpl(in, config, out, throwOnError);      }      bool ReadJsonFastTree(TStringBuf in, TJsonValue* out, bool throwOnError, bool notClosedBracketIsError) {          TParserCallbacks cb(*out, throwOnError, notClosedBracketIsError); -        return ReadJsonFast(in, &cb);  -    }  +        return ReadJsonFast(in, &cb); +    }      TJsonValue ReadJsonFastTree(TStringBuf in, bool notClosedBracketIsError) {          TJsonValue value; @@ -429,99 +429,99 @@ namespace NJson {          return value;      } -    namespace {  -        struct TJsonCallbacksWrapper {  -            TJsonCallbacks& Impl;  - -            TJsonCallbacksWrapper(TJsonCallbacks& impl)  -                : Impl(impl)  -            {  -            }  - -            bool Null() {  -                return Impl.OnNull();  -            }  - -            bool Bool(bool b) {  -                return Impl.OnBoolean(b);  -            }  - -            template <class U>  -            bool ProcessUint(U u) {  -                if (Y_LIKELY(u <= ui64(Max<i64>()))) {  -                    return Impl.OnInteger(i64(u));  -                } else {  -                    return Impl.OnUInteger(u);  -                }  -            }  -  -            bool Int(int i) {  -                return Impl.OnInteger(i);  -            }  -  -            bool Uint(unsigned u) {  -                return ProcessUint(u);  -            }  - -            bool Int64(i64 i) {  -                return Impl.OnInteger(i);  -            }  - -            bool Uint64(ui64 u) {  -                return ProcessUint(u);  -            }  - -            bool Double(double d) {  -                return Impl.OnDouble(d);  -            }  - -            bool RawNumber(const char* str, rapidjson::SizeType length, bool copy) {  -                Y_ASSERT(false && "this method should never be called");  -                Y_UNUSED(str);  -                Y_UNUSED(length);  -                Y_UNUSED(copy);  -                return true;  -            } - -            bool String(const char* str, rapidjson::SizeType length, bool copy) {  -                Y_ASSERT(copy);  -                return Impl.OnString(TStringBuf(str, length));  -            }  - -            bool StartObject() {  -                return Impl.OnOpenMap();  -            }  - -            bool Key(const char* str, rapidjson::SizeType length, bool copy) {  -                Y_ASSERT(copy);  -                return Impl.OnMapKey(TStringBuf(str, length));  -            }  - -            bool EndObject(rapidjson::SizeType memberCount) {  -                Y_UNUSED(memberCount);  -                return Impl.OnCloseMap();  -            }  - -            bool StartArray() {  -                return Impl.OnOpenArray();  -            }  - -            bool EndArray(rapidjson::SizeType elementCount) {  -                Y_UNUSED(elementCount);  -                return Impl.OnCloseArray();  -            }  -        };  -    }  - -    bool ReadJson(IInputStream* in, TJsonCallbacks* cbs) {  -        return ReadJson(in, false, cbs);  -    }  - -    bool ReadJson(IInputStream* in, bool allowComments, TJsonCallbacks* cbs) {  -        TJsonReaderConfig config;  -        config.AllowComments = allowComments;  -        return ReadJson(in, &config, cbs);  -    }  +    namespace { +        struct TJsonCallbacksWrapper { +            TJsonCallbacks& Impl; + +            TJsonCallbacksWrapper(TJsonCallbacks& impl) +                : Impl(impl) +            { +            } + +            bool Null() { +                return Impl.OnNull(); +            } + +            bool Bool(bool b) { +                return Impl.OnBoolean(b); +            } + +            template <class U> +            bool ProcessUint(U u) { +                if (Y_LIKELY(u <= ui64(Max<i64>()))) { +                    return Impl.OnInteger(i64(u)); +                } else { +                    return Impl.OnUInteger(u); +                } +            } + +            bool Int(int i) { +                return Impl.OnInteger(i); +            } + +            bool Uint(unsigned u) { +                return ProcessUint(u); +            } + +            bool Int64(i64 i) { +                return Impl.OnInteger(i); +            } + +            bool Uint64(ui64 u) { +                return ProcessUint(u); +            } + +            bool Double(double d) { +                return Impl.OnDouble(d); +            } + +            bool RawNumber(const char* str, rapidjson::SizeType length, bool copy) { +                Y_ASSERT(false && "this method should never be called"); +                Y_UNUSED(str); +                Y_UNUSED(length); +                Y_UNUSED(copy); +                return true; +            } + +            bool String(const char* str, rapidjson::SizeType length, bool copy) { +                Y_ASSERT(copy); +                return Impl.OnString(TStringBuf(str, length)); +            } + +            bool StartObject() { +                return Impl.OnOpenMap(); +            } + +            bool Key(const char* str, rapidjson::SizeType length, bool copy) { +                Y_ASSERT(copy); +                return Impl.OnMapKey(TStringBuf(str, length)); +            } + +            bool EndObject(rapidjson::SizeType memberCount) { +                Y_UNUSED(memberCount); +                return Impl.OnCloseMap(); +            } + +            bool StartArray() { +                return Impl.OnOpenArray(); +            } + +            bool EndArray(rapidjson::SizeType elementCount) { +                Y_UNUSED(elementCount); +                return Impl.OnCloseArray(); +            } +        }; +    } + +    bool ReadJson(IInputStream* in, TJsonCallbacks* cbs) { +        return ReadJson(in, false, cbs); +    } + +    bool ReadJson(IInputStream* in, bool allowComments, TJsonCallbacks* cbs) { +        TJsonReaderConfig config; +        config.AllowComments = allowComments; +        return ReadJson(in, &config, cbs); +    }      bool ReadJson(IInputStream* in, bool allowComments, bool allowEscapedApostrophe, TJsonCallbacks* cbs) {          TJsonReaderConfig config; @@ -530,38 +530,38 @@ namespace NJson {          return ReadJson(in, &config, cbs);      } -    bool ReadJson(IInputStream* in, const TJsonReaderConfig* config, TJsonCallbacks* cbs) {  -        TJsonCallbacksWrapper wrapper(*cbs);  -        TInputStreamWrapper is(*in);  +    bool ReadJson(IInputStream* in, const TJsonReaderConfig* config, TJsonCallbacks* cbs) { +        TJsonCallbacksWrapper wrapper(*cbs); +        TInputStreamWrapper is(*in); -        rapidjson::Reader reader;  -        auto result = Read(*config, reader, is, wrapper);  +        rapidjson::Reader reader; +        auto result = Read(*config, reader, is, wrapper); -        if (result.IsError()) {  +        if (result.IsError()) {              cbs->OnError(result.Offset(), PrintError(result)); -            return false;  +            return false;          } -        return cbs->OnEnd();  -    }  - -    TJsonValue ReadJsonTree(IInputStream* in, bool throwOnError) {  -        TJsonValue out;  -        ReadJsonTree(in, &out, throwOnError);  -        return out;  -    }  - -    TJsonValue ReadJsonTree(IInputStream* in, bool allowComments, bool throwOnError) {  -        TJsonValue out;  -        ReadJsonTree(in, allowComments, &out, throwOnError);  -        return out;  -    }  - -    TJsonValue ReadJsonTree(IInputStream* in, const TJsonReaderConfig* config, bool throwOnError) {  -        TJsonValue out;  -        ReadJsonTree(in, config, &out, throwOnError);  -        return out;  +        return cbs->OnEnd(); +    } + +    TJsonValue ReadJsonTree(IInputStream* in, bool throwOnError) { +        TJsonValue out; +        ReadJsonTree(in, &out, throwOnError); +        return out; +    } + +    TJsonValue ReadJsonTree(IInputStream* in, bool allowComments, bool throwOnError) { +        TJsonValue out; +        ReadJsonTree(in, allowComments, &out, throwOnError); +        return out; +    } + +    TJsonValue ReadJsonTree(IInputStream* in, const TJsonReaderConfig* config, bool throwOnError) { +        TJsonValue out; +        ReadJsonTree(in, config, &out, throwOnError); +        return out;      }  } diff --git a/library/cpp/json/json_reader.h b/library/cpp/json/json_reader.h index 674b3f6abf0..b6737883306 100644 --- a/library/cpp/json/json_reader.h +++ b/library/cpp/json/json_reader.h @@ -4,7 +4,7 @@  #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> @@ -12,37 +12,37 @@  #include <util/stream/mem.h>  namespace NJson { -    struct TJsonReaderConfig {  -        TJsonReaderConfig();  +    struct TJsonReaderConfig { +        TJsonReaderConfig(); -        // js-style comments (both // and /**/)  -        bool AllowComments = false;  -        bool DontValidateUtf8 = false;  +        // js-style comments (both // and /**/) +        bool AllowComments = false; +        bool DontValidateUtf8 = false;          bool AllowEscapedApostrophe = false; -        void SetBufferSize(size_t bufferSize);  -        size_t GetBufferSize() const;  +        void SetBufferSize(size_t bufferSize); +        size_t GetBufferSize() const; -    private:  -        size_t BufferSize;  -    };  +    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(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);  +    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);  +    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, 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);  +    bool ReadJson(IInputStream* in, const TJsonReaderConfig* config, TJsonCallbacks* callbacks);      enum ReaderConfigFlags {          COMMENTS = 0b100, @@ -60,79 +60,79 @@ namespace NJson {          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(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) {  +    inline bool ValidateJson(TStringBuf in, const TJsonReaderConfig& config = TJsonReaderConfig(), bool throwOnError = false) {          TMemoryInput min(in.data(), in.size()); -        return ValidateJson(&min, &config, throwOnError);  -    }  +        return ValidateJson(&min, &config, throwOnError); +    } -    inline bool ValidateJsonThrow(IInputStream* in, const TJsonReaderConfig* config) {  -        return ValidateJson(in, config, true);  -    }  +    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);  -    }  +    inline bool ValidateJsonThrow(TStringBuf in, const TJsonReaderConfig& config = TJsonReaderConfig()) { +        return ValidateJson(in, config, true); +    } -    class TParserCallbacks: public TJsonCallbacks {  -    public:  +    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 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;  +    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;  +        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();  -    };  +        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); diff --git a/library/cpp/json/json_writer.cpp b/library/cpp/json/json_writer.cpp index 140e1427d3f..3d058bae360 100644 --- a/library/cpp/json/json_writer.cpp +++ b/library/cpp/json/json_writer.cpp @@ -6,144 +6,144 @@  #include <util/system/yassert.h>  namespace NJson { -    TJsonWriter::TJsonWriter(IOutputStream* out, bool formatOutput, bool sortkeys, bool validateUtf8)  -        : Out(out)  -        , Buf(NJsonWriter::HEM_UNSAFE)  +    TJsonWriter::TJsonWriter(IOutputStream* out, bool formatOutput, bool sortkeys, bool validateUtf8) +        : Out(out) +        , Buf(NJsonWriter::HEM_UNSAFE)          , DoubleNDigits(TJsonWriterConfig::DefaultDoubleNDigits)          , FloatNDigits(TJsonWriterConfig::DefaultFloatNDigits)          , FloatToStringMode(TJsonWriterConfig::DefaultFloatToStringMode) -        , SortKeys(sortkeys)  -        , ValidateUtf8(validateUtf8)  -        , DontEscapeStrings(false)  -        , DontFlushInDestructor(false)  -    {  -        Buf.SetIndentSpaces(formatOutput ? 2 : 0);  -    }  - -    TJsonWriter::TJsonWriter(IOutputStream* out, const TJsonWriterConfig& config, bool DFID)  -        : Out(config.Unbuffered ? nullptr : out)  -        , Buf(NJsonWriter::HEM_UNSAFE, config.Unbuffered ? out : nullptr)  +        , SortKeys(sortkeys) +        , ValidateUtf8(validateUtf8) +        , DontEscapeStrings(false) +        , DontFlushInDestructor(false) +    { +        Buf.SetIndentSpaces(formatOutput ? 2 : 0); +    } + +    TJsonWriter::TJsonWriter(IOutputStream* out, const TJsonWriterConfig& config, bool DFID) +        : Out(config.Unbuffered ? nullptr : out) +        , Buf(NJsonWriter::HEM_UNSAFE, config.Unbuffered ? out : nullptr)          , DoubleNDigits(config.DoubleNDigits)          , FloatNDigits(config.FloatNDigits)          , FloatToStringMode(config.FloatToStringMode) -        , SortKeys(config.SortKeys)  -        , ValidateUtf8(config.ValidateUtf8)  -        , DontEscapeStrings(config.DontEscapeStrings)  -        , DontFlushInDestructor(DFID)  -    {  -        Buf.SetIndentSpaces(config.FormatOutput ? 2 : 0);  -        Buf.SetWriteNanAsString(config.WriteNanAsString);  -    }  - -    TJsonWriter::~TJsonWriter() {  -        // if we write to socket it's possible to get exception here  -        // don't use exceptions in destructors  -        if (!DontFlushInDestructor) {  -            try {  -                Flush();  -            } catch (...) {  -            }  -        }  -    }  - -    void TJsonWriter::Flush() {  -        if (Out) {  -            Buf.FlushTo(Out);  +        , SortKeys(config.SortKeys) +        , ValidateUtf8(config.ValidateUtf8) +        , DontEscapeStrings(config.DontEscapeStrings) +        , DontFlushInDestructor(DFID) +    { +        Buf.SetIndentSpaces(config.FormatOutput ? 2 : 0); +        Buf.SetWriteNanAsString(config.WriteNanAsString); +    } + +    TJsonWriter::~TJsonWriter() { +        // if we write to socket it's possible to get exception here +        // don't use exceptions in destructors +        if (!DontFlushInDestructor) { +            try { +                Flush(); +            } catch (...) { +            } +        } +    } + +    void TJsonWriter::Flush() { +        if (Out) { +            Buf.FlushTo(Out);          } -    }  +    } -    void TJsonWriter::OpenMap() {  -        Buf.BeginObject();  -    }  +    void TJsonWriter::OpenMap() { +        Buf.BeginObject(); +    } -    void TJsonWriter::CloseMap() {  -        Buf.EndObject();  -    }  +    void TJsonWriter::CloseMap() { +        Buf.EndObject(); +    } -    void TJsonWriter::OpenArray() {  -        Buf.BeginList();  -    }  +    void TJsonWriter::OpenArray() { +        Buf.BeginList(); +    } -    void TJsonWriter::CloseArray() {  -        Buf.EndList();  -    }  +    void TJsonWriter::CloseArray() { +        Buf.EndList(); +    } -    void TJsonWriter::Write(const TStringBuf& value) {  -        if (ValidateUtf8 && !IsUtf(value))  -            throw yexception() << "JSON writer: invalid UTF-8";  -        if (Buf.KeyExpected()) {  -            Buf.WriteKey(value);  +    void TJsonWriter::Write(const TStringBuf& value) { +        if (ValidateUtf8 && !IsUtf(value)) +            throw yexception() << "JSON writer: invalid UTF-8"; +        if (Buf.KeyExpected()) { +            Buf.WriteKey(value);          } else { -            if (DontEscapeStrings) {  -                Buf.UnsafeWriteValue(TString("\"") + value + '"');  -            } else {  -                Buf.WriteString(value);  -            }  +            if (DontEscapeStrings) { +                Buf.UnsafeWriteValue(TString("\"") + value + '"'); +            } else { +                Buf.WriteString(value); +            }          }      } -    void TJsonWriter::WriteNull() {  -        Buf.WriteNull();  -    }  +    void TJsonWriter::WriteNull() { +        Buf.WriteNull(); +    } -    void TJsonWriter::Write(float value) {  +    void TJsonWriter::Write(float value) {          Buf.WriteFloat(value, FloatToStringMode, FloatNDigits); -    }  +    } -    void TJsonWriter::Write(double value) {  +    void TJsonWriter::Write(double value) {          Buf.WriteDouble(value, FloatToStringMode, DoubleNDigits); -    }  +    } -    void TJsonWriter::Write(long long value) {  -        Buf.WriteLongLong(value);  -    }  +    void TJsonWriter::Write(long long value) { +        Buf.WriteLongLong(value); +    } -    void TJsonWriter::Write(unsigned long long value) {  -        Buf.WriteULongLong(value);  -    }  +    void TJsonWriter::Write(unsigned long long value) { +        Buf.WriteULongLong(value); +    } -    void TJsonWriter::Write(bool value) {  -        Buf.WriteBool(value);  -    }  +    void TJsonWriter::Write(bool value) { +        Buf.WriteBool(value); +    } -    namespace {  -        struct TLessStrPtr {  -            bool operator()(const TString* a, const TString* b) const {  -                return *a < *b;  -            }  -        };  -    }  +    namespace { +        struct TLessStrPtr { +            bool operator()(const TString* a, const TString* b) const { +                return *a < *b; +            } +        }; +    } -    void TJsonWriter::Write(const TJsonValue* v) {  +    void TJsonWriter::Write(const TJsonValue* v) {          Buf.WriteJsonValue(v, SortKeys, FloatToStringMode, DoubleNDigits); -    }  +    }      void TJsonWriter::Write(const TJsonValue& v) {          Buf.WriteJsonValue(&v, SortKeys, FloatToStringMode, DoubleNDigits);      } -    TString WriteJson(const TJsonValue* value, bool formatOutput, bool sortkeys, bool validateUtf8) {  -        TStringStream ss;  -        WriteJson(&ss, value, formatOutput, sortkeys, validateUtf8);  -        return ss.Str();  -    }  - -    TString WriteJson(const TJsonValue& value, bool formatOutput, bool sortkeys, bool validateUtf8) {  -        TStringStream ss;  -        WriteJson(&ss, &value, formatOutput, sortkeys, validateUtf8);  -        return ss.Str();  -    }  - -    void WriteJson(IOutputStream* out, const TJsonValue* val, bool formatOutput, bool sortkeys, bool validateUtf8) {  -        TJsonWriter w(out, formatOutput, sortkeys, validateUtf8);  -        w.Write(val);  -        w.Flush();  -    }  - -    void WriteJson(IOutputStream* out, const TJsonValue* val, const TJsonWriterConfig& config) {  -        TJsonWriter w(out, config, true);  -        w.Write(val);  -        w.Flush();  -    }  +    TString WriteJson(const TJsonValue* value, bool formatOutput, bool sortkeys, bool validateUtf8) { +        TStringStream ss; +        WriteJson(&ss, value, formatOutput, sortkeys, validateUtf8); +        return ss.Str(); +    } + +    TString WriteJson(const TJsonValue& value, bool formatOutput, bool sortkeys, bool validateUtf8) { +        TStringStream ss; +        WriteJson(&ss, &value, formatOutput, sortkeys, validateUtf8); +        return ss.Str(); +    } + +    void WriteJson(IOutputStream* out, const TJsonValue* val, bool formatOutput, bool sortkeys, bool validateUtf8) { +        TJsonWriter w(out, formatOutput, sortkeys, validateUtf8); +        w.Write(val); +        w.Flush(); +    } + +    void WriteJson(IOutputStream* out, const TJsonValue* val, const TJsonWriterConfig& config) { +        TJsonWriter w(out, config, true); +        w.Write(val); +        w.Flush(); +    }  } diff --git a/library/cpp/json/json_writer.h b/library/cpp/json/json_writer.h index b56ba5e8a79..c7f5c9499a4 100644 --- a/library/cpp/json/json_writer.h +++ b/library/cpp/json/json_writer.h @@ -12,148 +12,148 @@  #include <util/generic/strbuf.h>  namespace NJson { -    struct TJsonWriterConfig {  +    struct TJsonWriterConfig {          constexpr static ui32 DefaultDoubleNDigits = 10;          constexpr static ui32 DefaultFloatNDigits = 6;          constexpr static EFloatToStringMode DefaultFloatToStringMode = PREC_NDIGITS; -        inline TJsonWriterConfig& SetUnbuffered(bool v) noexcept {  -            Unbuffered = v;  - -            return *this;  -        }  -  -        inline TJsonWriterConfig& SetValidateUtf8(bool v) noexcept {  -            ValidateUtf8 = v;  -  -            return *this;  -        }  -  -        inline TJsonWriterConfig& SetFormatOutput(bool v) noexcept {  -            FormatOutput = v;  -  -            return *this;  -        }  -  +        inline TJsonWriterConfig& SetUnbuffered(bool v) noexcept { +            Unbuffered = v; + +            return *this; +        } + +        inline TJsonWriterConfig& SetValidateUtf8(bool v) noexcept { +            ValidateUtf8 = v; + +            return *this; +        } + +        inline TJsonWriterConfig& SetFormatOutput(bool v) noexcept { +            FormatOutput = v; + +            return *this; +        } +          ui32 DoubleNDigits = DefaultDoubleNDigits;          ui32 FloatNDigits = DefaultFloatNDigits;          EFloatToStringMode FloatToStringMode = DefaultFloatToStringMode; -        bool FormatOutput = false;  -        bool SortKeys = false;  -        bool ValidateUtf8 = true;  -        bool DontEscapeStrings = false;  -        bool Unbuffered = false;  -        bool WriteNanAsString = false; // NaN and Inf are not valid json values, so if WriteNanAsString is set, writer would write string intead of throwing exception (default case)  -    };  -  -    class TJsonWriter {  -        IOutputStream* Out;  -        NJsonWriter::TBuf Buf;  +        bool FormatOutput = false; +        bool SortKeys = false; +        bool ValidateUtf8 = true; +        bool DontEscapeStrings = false; +        bool Unbuffered = false; +        bool WriteNanAsString = false; // NaN and Inf are not valid json values, so if WriteNanAsString is set, writer would write string intead of throwing exception (default case) +    }; + +    class TJsonWriter { +        IOutputStream* Out; +        NJsonWriter::TBuf Buf;          const ui32 DoubleNDigits;          const ui32 FloatNDigits;          const EFloatToStringMode FloatToStringMode; -        const bool SortKeys;  -        const bool ValidateUtf8;  -        const bool DontEscapeStrings;  -        const bool DontFlushInDestructor;  - -    public:  -        TJsonWriter(IOutputStream* out, bool formatOutput, bool sortkeys = false, bool validateUtf8 = true);  -        TJsonWriter(IOutputStream* out, const TJsonWriterConfig& config, bool DontFlushInDestructor = false);  -        ~TJsonWriter();  - -        void Flush();  - -        void OpenMap();  -        void OpenMap(const TStringBuf& key) {  -            Buf.WriteKey(key);  -            OpenMap();  -        }  -        void CloseMap();  - -        void OpenArray();  -        void OpenArray(const TStringBuf& key) {  -            Buf.WriteKey(key);  -            OpenArray();  -        }  -        void CloseArray();  - -        void WriteNull();  - -        void Write(const TStringBuf& value);  -        void Write(float value);  -        void Write(double value);  -        void Write(bool value);  -        void Write(const TJsonValue* value);  +        const bool SortKeys; +        const bool ValidateUtf8; +        const bool DontEscapeStrings; +        const bool DontFlushInDestructor; + +    public: +        TJsonWriter(IOutputStream* out, bool formatOutput, bool sortkeys = false, bool validateUtf8 = true); +        TJsonWriter(IOutputStream* out, const TJsonWriterConfig& config, bool DontFlushInDestructor = false); +        ~TJsonWriter(); + +        void Flush(); + +        void OpenMap(); +        void OpenMap(const TStringBuf& key) { +            Buf.WriteKey(key); +            OpenMap(); +        } +        void CloseMap(); + +        void OpenArray(); +        void OpenArray(const TStringBuf& key) { +            Buf.WriteKey(key); +            OpenArray(); +        } +        void CloseArray(); + +        void WriteNull(); + +        void Write(const TStringBuf& value); +        void Write(float value); +        void Write(double value); +        void Write(bool value); +        void Write(const TJsonValue* value);          void Write(const TJsonValue& value); -        // must use all variations of integer types since long  -        // and long long are different types but with same size  -        void Write(long long value);  -        void Write(unsigned long long value);  -        void Write(long value) {  -            Write((long long)value);  -        }  -        void Write(unsigned long value) {  -            Write((unsigned long long)value);  -        }  -        void Write(int value) {  -            Write((long long)value);  -        }  -        void Write(unsigned int value) {  -            Write((unsigned long long)value);  -        }  -        void Write(short value) {  -            Write((long long)value);  -        }  -        void Write(unsigned short value) {  -            Write((unsigned long long)value);  -        }  - -        void Write(const unsigned char* value) {  -            Write((const char*)value);  -        }  -        void Write(const char* value) {  -            Write(TStringBuf(value));  -        }  -        void Write(const TString& value) {  -            Write(TStringBuf(value));  -        }  -        void Write(const std::string& value) {  -            Write(TStringBuf(value));  -        }  - -        // write raw json without checks  -        void UnsafeWrite(const TStringBuf& value) {  -            Buf.UnsafeWriteValue(value);  -        }  - -        template <typename T>  -        void Write(const TStringBuf& key, const T& value) {  -            Buf.WriteKey(key);  -            Write(value);  -        }  - -        // write raw json without checks  -        void UnsafeWrite(const TStringBuf& key, const TStringBuf& value) {  -            Buf.WriteKey(key);  -            UnsafeWrite(value);  -        }  - -        void WriteNull(const TStringBuf& key) {  -            Buf.WriteKey(key);  -            WriteNull();  -        }  - -        template <typename T>  -        void WriteOptional(const TStringBuf& key, const TMaybe<T>& value) {  -            if (value) {  -                Write(key, *value);  -            }  -        }  - -        void WriteOptional(const TStringBuf&, const TNothing&) {  -            // nothing to do  +        // must use all variations of integer types since long +        // and long long are different types but with same size +        void Write(long long value); +        void Write(unsigned long long value); +        void Write(long value) { +            Write((long long)value); +        } +        void Write(unsigned long value) { +            Write((unsigned long long)value); +        } +        void Write(int value) { +            Write((long long)value); +        } +        void Write(unsigned int value) { +            Write((unsigned long long)value); +        } +        void Write(short value) { +            Write((long long)value); +        } +        void Write(unsigned short value) { +            Write((unsigned long long)value); +        } + +        void Write(const unsigned char* value) { +            Write((const char*)value); +        } +        void Write(const char* value) { +            Write(TStringBuf(value)); +        } +        void Write(const TString& value) { +            Write(TStringBuf(value)); +        } +        void Write(const std::string& value) { +            Write(TStringBuf(value)); +        } + +        // write raw json without checks +        void UnsafeWrite(const TStringBuf& value) { +            Buf.UnsafeWriteValue(value); +        } + +        template <typename T> +        void Write(const TStringBuf& key, const T& value) { +            Buf.WriteKey(key); +            Write(value); +        } + +        // write raw json without checks +        void UnsafeWrite(const TStringBuf& key, const TStringBuf& value) { +            Buf.WriteKey(key); +            UnsafeWrite(value); +        } + +        void WriteNull(const TStringBuf& key) { +            Buf.WriteKey(key); +            WriteNull(); +        } + +        template <typename T> +        void WriteOptional(const TStringBuf& key, const TMaybe<T>& value) { +            if (value) { +                Write(key, *value); +            } +        } + +        void WriteOptional(const TStringBuf&, const TNothing&) { +            // nothing to do          }          void WriteKey(const TStringBuf key) { @@ -172,25 +172,25 @@ namespace NJson {              WriteKey(TStringBuf{key});          } -        void WriteKey(const std::string& key) {  -            WriteKey(TStringBuf{key});  -        }  -  -        NJsonWriter::TBufState State() const {  -            return Buf.State();  -        }  +        void WriteKey(const std::string& key) { +            WriteKey(TStringBuf{key}); +        } + +        NJsonWriter::TBufState State() const { +            return Buf.State(); +        } -        void Reset(const NJsonWriter::TBufState& from) {  -            return Buf.Reset(from);  -        }  +        void Reset(const NJsonWriter::TBufState& from) { +            return Buf.Reset(from); +        } -        void Reset(NJsonWriter::TBufState&& from) {  -            return Buf.Reset(std::move(from));  -        }  -    };  +        void Reset(NJsonWriter::TBufState&& from) { +            return Buf.Reset(std::move(from)); +        } +    }; -    void WriteJson(IOutputStream*, const TJsonValue*, bool formatOutput = false, bool sortkeys = false, bool validateUtf8 = true);  -    TString WriteJson(const TJsonValue*, bool formatOutput = true, bool sortkeys = false, bool validateUtf8 = false);  -    TString WriteJson(const TJsonValue&, bool formatOutput = true, bool sortkeys = false, bool validateUtf8 = false);  -    void WriteJson(IOutputStream*, const TJsonValue*, const TJsonWriterConfig& config);  +    void WriteJson(IOutputStream*, const TJsonValue*, bool formatOutput = false, bool sortkeys = false, bool validateUtf8 = true); +    TString WriteJson(const TJsonValue*, bool formatOutput = true, bool sortkeys = false, bool validateUtf8 = false); +    TString WriteJson(const TJsonValue&, bool formatOutput = true, bool sortkeys = false, bool validateUtf8 = false); +    void WriteJson(IOutputStream*, const TJsonValue*, const TJsonWriterConfig& config);  } diff --git a/library/cpp/json/rapidjson_helpers.h b/library/cpp/json/rapidjson_helpers.h index 6adad9b32fc..aeb96ff6703 100644 --- a/library/cpp/json/rapidjson_helpers.h +++ b/library/cpp/json/rapidjson_helpers.h @@ -26,7 +26,7 @@ namespace NJson {          }      }; -    struct TInputStreamWrapper : TReadOnlyStreamBase {  +    struct TInputStreamWrapper : TReadOnlyStreamBase {          Ch Peek() const {              if (!Eof) {                  if (Pos >= Sz) { @@ -77,7 +77,7 @@ namespace NJson {          size_t Count;      }; -    struct TStringBufStreamWrapper : TReadOnlyStreamBase {  +    struct TStringBufStreamWrapper : TReadOnlyStreamBase {          Ch Peek() const {              return Pos < Data.size() ? Data[Pos] : 0;          } diff --git a/library/cpp/json/ut/json_prettifier_ut.cpp b/library/cpp/json/ut/json_prettifier_ut.cpp index e2b51be062c..ae5f8dd81a4 100644 --- a/library/cpp/json/ut/json_prettifier_ut.cpp +++ b/library/cpp/json/ut/json_prettifier_ut.cpp @@ -36,78 +36,78 @@ Y_UNIT_TEST_SUITE(JsonPrettifier) {      Y_UNIT_TEST(PrettifyJsonLong) {          UNIT_ASSERT_STRINGS_EQUAL(NJson::PrettifyJson("[{k:v},{a:b}]", false, 2, true), -                                  "[\n"  -                                  "  {\n"  -                                  "    'k' : 'v'\n"  -                                  "  },\n"  -                                  "  {\n"  -                                  "    'a' : 'b'\n"  -                                  "  }\n"  -                                  "]");  +                                  "[\n" +                                  "  {\n" +                                  "    'k' : 'v'\n" +                                  "  },\n" +                                  "  {\n" +                                  "    'a' : 'b'\n" +                                  "  }\n" +                                  "]");          UNIT_ASSERT_STRINGS_EQUAL(NJson::PrettifyJson("{k:v,a:b,x:[1,2,3]}", false, 2, true), -                                  "{\n"  -                                  "  'k' : 'v',\n"  -                                  "  'a' : 'b',\n"  -                                  "  'x' : [\n"  -                                  "    1,\n"  -                                  "    2,\n"  -                                  "    3\n"  -                                  "  ]\n"  -                                  "}");  +                                  "{\n" +                                  "  'k' : 'v',\n" +                                  "  'a' : 'b',\n" +                                  "  'x' : [\n" +                                  "    1,\n" +                                  "    2,\n" +                                  "    3\n" +                                  "  ]\n" +                                  "}");          UNIT_ASSERT_STRINGS_EQUAL(NJson::PrettifyJson("{k:v,a:b,x:[1,{f:b},3],m:n}", false, 2, true), -                                  "{\n"  -                                  "  'k' : 'v',\n"  -                                  "  'a' : 'b',\n"  -                                  "  'x' : [\n"  -                                  "    1,\n"  -                                  "    {\n"  -                                  "      'f' : 'b'\n"  -                                  "    },\n"  -                                  "    3\n"  -                                  "  ],\n"  -                                  "  'm' : 'n'\n"  -                                  "}");  +                                  "{\n" +                                  "  'k' : 'v',\n" +                                  "  'a' : 'b',\n" +                                  "  'x' : [\n" +                                  "    1,\n" +                                  "    {\n" +                                  "      'f' : 'b'\n" +                                  "    },\n" +                                  "    3\n" +                                  "  ],\n" +                                  "  'm' : 'n'\n" +                                  "}");          NJson::TJsonPrettifier prettifierMaxLevel1 = NJson::TJsonPrettifier::Prettifier(false, 2, true);          prettifierMaxLevel1.MaxPaddingLevel = 1;          UNIT_ASSERT_STRINGS_EQUAL(prettifierMaxLevel1.Prettify("{k:v,a:b,x:[1,{f:b},3],m:n}"), -                                  "{\n"  -                                  "  'k' : 'v',\n"  -                                  "  'a' : 'b',\n"  -                                  "  'x' : [ 1, { 'f' : 'b' }, 3 ],\n"  -                                  "  'm' : 'n'\n"  -                                  "}");  +                                  "{\n" +                                  "  'k' : 'v',\n" +                                  "  'a' : 'b',\n" +                                  "  'x' : [ 1, { 'f' : 'b' }, 3 ],\n" +                                  "  'm' : 'n'\n" +                                  "}");          UNIT_ASSERT_STRINGS_EQUAL(NJson::PrettifyJson("{g:{x:{a:{b:c,e:f},q:{x:y}},y:fff}}", true, 2), -                                  "{\n"  -                                  "  g : {\n"  -                                  "    x : {\n"  -                                  "      a : {\n"  -                                  "        b : c,\n"  -                                  "        e : f\n"  -                                  "      },\n"  -                                  "      q : {\n"  -                                  "        x : y\n"  -                                  "      }\n"  -                                  "    },\n"  -                                  "    y : fff\n"  -                                  "  }\n"  -                                  "}");  +                                  "{\n" +                                  "  g : {\n" +                                  "    x : {\n" +                                  "      a : {\n" +                                  "        b : c,\n" +                                  "        e : f\n" +                                  "      },\n" +                                  "      q : {\n" +                                  "        x : y\n" +                                  "      }\n" +                                  "    },\n" +                                  "    y : fff\n" +                                  "  }\n" +                                  "}");          NJson::TJsonPrettifier prettifierMaxLevel3 = NJson::TJsonPrettifier::Prettifier(true, 2);          prettifierMaxLevel3.MaxPaddingLevel = 3;          UNIT_ASSERT_STRINGS_EQUAL(prettifierMaxLevel3.Prettify("{g:{x:{a:{b:c,e:f},q:{x:y}},y:fff}}"), -                                  "{\n"  -                                  "  g : {\n"  -                                  "    x : {\n"  -                                  "      a : { b : c, e : f },\n"  -                                  "      q : { x : y }\n"  -                                  "    },\n"  -                                  "    y : fff\n"  -                                  "  }\n"  -                                  "}");  +                                  "{\n" +                                  "  g : {\n" +                                  "    x : {\n" +                                  "      a : { b : c, e : f },\n" +                                  "      q : { x : y }\n" +                                  "    },\n" +                                  "    y : fff\n" +                                  "  }\n" +                                  "}");      }      Y_UNIT_TEST(PrettifyJsonInvalid) { @@ -144,61 +144,61 @@ Y_UNIT_TEST_SUITE(JsonPrettifier) {      Y_UNIT_TEST(CompactifyJsonLong) {          UNIT_ASSERT_STRINGS_EQUAL(NJson::CompactifyJson( -                                      "[\n"  -                                      "  {\n"  -                                      "    'k' : 'v'\n"  -                                      "  },\n"  -                                      "  {\n"  -                                      "    'a' : 'b'\n"  -                                      "  }\n"  -                                      "]",  -                                      true),  -                                  "[{k:v},{a:b}]");  +                                      "[\n" +                                      "  {\n" +                                      "    'k' : 'v'\n" +                                      "  },\n" +                                      "  {\n" +                                      "    'a' : 'b'\n" +                                      "  }\n" +                                      "]", +                                      true), +                                  "[{k:v},{a:b}]");          UNIT_ASSERT_STRINGS_EQUAL(NJson::CompactifyJson( -                                      "{\n"  -                                      "  'k' : 'v',\n"  -                                      "  'a' : 'b',\n"  -                                      "  'x' : [\n"  -                                      "    1,\n"  -                                      "    2,\n"  -                                      "    3\n"  -                                      "  ]\n"  -                                      "}",  -                                      true),  -                                  "{k:v,a:b,x:[1,2,3]}");  +                                      "{\n" +                                      "  'k' : 'v',\n" +                                      "  'a' : 'b',\n" +                                      "  'x' : [\n" +                                      "    1,\n" +                                      "    2,\n" +                                      "    3\n" +                                      "  ]\n" +                                      "}", +                                      true), +                                  "{k:v,a:b,x:[1,2,3]}");          UNIT_ASSERT_STRINGS_EQUAL(NJson::CompactifyJson( -                                      "{\n"  -                                      "  'k' : 'v',\n"  -                                      "  'a' : 'b',\n"  -                                      "  'x' : [\n"  -                                      "    1,\n"  -                                      "    {\n"  -                                      "      'f' : 'b'\n"  -                                      "    },\n"  -                                      "    3\n"  -                                      "  ],\n"  -                                      "  'm' : 'n'\n"  -                                      "}",  -                                      true),  -                                  "{k:v,a:b,x:[1,{f:b},3],m:n}");  +                                      "{\n" +                                      "  'k' : 'v',\n" +                                      "  'a' : 'b',\n" +                                      "  'x' : [\n" +                                      "    1,\n" +                                      "    {\n" +                                      "      'f' : 'b'\n" +                                      "    },\n" +                                      "    3\n" +                                      "  ],\n" +                                      "  'm' : 'n'\n" +                                      "}", +                                      true), +                                  "{k:v,a:b,x:[1,{f:b},3],m:n}");          UNIT_ASSERT_STRINGS_EQUAL(NJson::CompactifyJson( -                                      "{\n"  -                                      "  g : {\n"  -                                      "    x : {\n"  -                                      "      a : {\n"  -                                      "        b : c,\n"  -                                      "        e : f\n"  -                                      "      },\n"  -                                      "      q : {\n"  -                                      "        x : y\n"  -                                      "      }\n"  -                                      "    },\n"  -                                      "    y : fff\n"  -                                      "  }\n"  -                                      "}",  -                                      true),  -                                  "{g:{x:{a:{b:c,e:f},q:{x:y}},y:fff}}");  +                                      "{\n" +                                      "  g : {\n" +                                      "    x : {\n" +                                      "      a : {\n" +                                      "        b : c,\n" +                                      "        e : f\n" +                                      "      },\n" +                                      "      q : {\n" +                                      "        x : y\n" +                                      "      }\n" +                                      "    },\n" +                                      "    y : fff\n" +                                      "  }\n" +                                      "}", +                                      true), +                                  "{g:{x:{a:{b:c,e:f},q:{x:y}},y:fff}}");      }  } diff --git a/library/cpp/json/ut/json_reader_fast_ut.cpp b/library/cpp/json/ut/json_reader_fast_ut.cpp index 46709753568..60dffc91c73 100644 --- a/library/cpp/json/ut/json_reader_fast_ut.cpp +++ b/library/cpp/json/ut/json_reader_fast_ut.cpp @@ -7,176 +7,176 @@  #include <util/string/printf.h>  namespace NJson { -    namespace NTest {  -        enum ETestEvent {  -            E_NO_EVENT = 0,  -            E_ERROR = 1,  -            E_DICT_OPEN,  -            E_DICT_CLOSE,  -            E_ARR_OPEN,  -            E_ARR_CLOSE,  -            E_NULL,  -            E_BOOL,  -            E_FLT,  -            E_INT,  -            E_LONG_LONG,  -            E_STR,  -            E_KEY  -        };  - -        struct TEvent {  -            ETestEvent Type = E_NO_EVENT;  - -            i64 INum = 0;  -            double DNum = 0;  -            TString Str;  - -            TEvent(ETestEvent e = E_NO_EVENT)  -                : Type(e)  -            {  -            }  - -            TEvent(double v, ETestEvent e)  -                : Type(e)  -                , DNum(v)  -            {  -            }  - -            TEvent(i64 v, ETestEvent e)  -                : Type(e)  -                , INum(v)  -            {  -            }  - -            TEvent(TStringBuf t, ETestEvent e)  -                : Type(e)  -                , Str(NEscJ::EscapeJ<true, false>(t))  -            {  -            }  - -            TString ToString() const {  -                switch (Type) {  -                    default:  -                        return "YOUFAILED";  -                    case E_ERROR:  +    namespace NTest { +        enum ETestEvent { +            E_NO_EVENT = 0, +            E_ERROR = 1, +            E_DICT_OPEN, +            E_DICT_CLOSE, +            E_ARR_OPEN, +            E_ARR_CLOSE, +            E_NULL, +            E_BOOL, +            E_FLT, +            E_INT, +            E_LONG_LONG, +            E_STR, +            E_KEY +        }; + +        struct TEvent { +            ETestEvent Type = E_NO_EVENT; + +            i64 INum = 0; +            double DNum = 0; +            TString Str; + +            TEvent(ETestEvent e = E_NO_EVENT) +                : Type(e) +            { +            } + +            TEvent(double v, ETestEvent e) +                : Type(e) +                , DNum(v) +            { +            } + +            TEvent(i64 v, ETestEvent e) +                : Type(e) +                , INum(v) +            { +            } + +            TEvent(TStringBuf t, ETestEvent e) +                : Type(e) +                , Str(NEscJ::EscapeJ<true, false>(t)) +            { +            } + +            TString ToString() const { +                switch (Type) { +                    default: +                        return "YOUFAILED"; +                    case E_ERROR:                          return Sprintf("error: %s", Str.data()); -                    case E_DICT_OPEN:  -                        return "{";  -                    case E_DICT_CLOSE:  -                        return "}";  -                    case E_ARR_OPEN:  -                        return "[";  -                    case E_ARR_CLOSE:  -                        return "]";  -                    case E_NULL:  -                        return "null";  -                    case E_BOOL:  -                        return INum ? "true" : "false";  -                    case E_INT:  -                        return ::ToString(INum);  -                    case E_FLT:  -                        return ::ToString(DNum);  -                    case E_STR:  +                    case E_DICT_OPEN: +                        return "{"; +                    case E_DICT_CLOSE: +                        return "}"; +                    case E_ARR_OPEN: +                        return "["; +                    case E_ARR_CLOSE: +                        return "]"; +                    case E_NULL: +                        return "null"; +                    case E_BOOL: +                        return INum ? "true" : "false"; +                    case E_INT: +                        return ::ToString(INum); +                    case E_FLT: +                        return ::ToString(DNum); +                    case E_STR:                          return Sprintf("%s", Str.data()); -                    case E_KEY:  +                    case E_KEY:                          return Sprintf("key: %s", Str.data()); -                }  -            }  -        };  - -        using TEvents = TVector<TEvent>;  - -        struct TTestHandler : TJsonCallbacks {  -            TEvents Events;  - -            bool OnOpenMap() override {  -                Events.push_back(E_DICT_OPEN);  -                return true;  -            }  - -            bool OnCloseMap() override {  -                Events.push_back(E_DICT_CLOSE);  -                return true;  -            }  - -            bool OnOpenArray() override {  -                Events.push_back(E_ARR_OPEN);  -                return true;  -            }  - -            bool OnCloseArray() override {  -                Events.push_back(E_ARR_CLOSE);  -                return true;  -            }  - -            bool OnNull() override {  -                Events.push_back(E_NULL);  -                return true;  -            }  - -            bool OnBoolean(bool v) override {  -                Events.push_back(TEvent((i64)v, E_BOOL));  -                return true;  -            }  - -            bool OnInteger(long long v) override {  -                Events.push_back(TEvent((i64)v, E_INT));  -                return true;  -            }  - -            bool OnUInteger(unsigned long long v) override {  -                return OnInteger(v);  -            }  - -            bool OnDouble(double v) override {  -                Events.push_back(TEvent(v, E_FLT));  -                return true;  -            }  - -            bool OnString(const TStringBuf& v) override {  -                Events.push_back(TEvent(v, E_STR));  -                return true;  -            }  - -            bool OnMapKey(const TStringBuf& v) override {  -                Events.push_back(TEvent(v, E_KEY));  -                return true;  -            }  - -            void OnError(size_t, TStringBuf token) override {  -                Events.push_back(TEvent(token, E_ERROR));  -            }  - -            void Assert(const TEvents& e, TString str) {  -                try {  -                    UNIT_ASSERT_VALUES_EQUAL_C(e.size(), Events.size(), str);  - -                    for (ui32 i = 0, sz = e.size(); i < sz; ++i) {  +                } +            } +        }; + +        using TEvents = TVector<TEvent>; + +        struct TTestHandler : TJsonCallbacks { +            TEvents Events; + +            bool OnOpenMap() override { +                Events.push_back(E_DICT_OPEN); +                return true; +            } + +            bool OnCloseMap() override { +                Events.push_back(E_DICT_CLOSE); +                return true; +            } + +            bool OnOpenArray() override { +                Events.push_back(E_ARR_OPEN); +                return true; +            } + +            bool OnCloseArray() override { +                Events.push_back(E_ARR_CLOSE); +                return true; +            } + +            bool OnNull() override { +                Events.push_back(E_NULL); +                return true; +            } + +            bool OnBoolean(bool v) override { +                Events.push_back(TEvent((i64)v, E_BOOL)); +                return true; +            } + +            bool OnInteger(long long v) override { +                Events.push_back(TEvent((i64)v, E_INT)); +                return true; +            } + +            bool OnUInteger(unsigned long long v) override { +                return OnInteger(v); +            } + +            bool OnDouble(double v) override { +                Events.push_back(TEvent(v, E_FLT)); +                return true; +            } + +            bool OnString(const TStringBuf& v) override { +                Events.push_back(TEvent(v, E_STR)); +                return true; +            } + +            bool OnMapKey(const TStringBuf& v) override { +                Events.push_back(TEvent(v, E_KEY)); +                return true; +            } + +            void OnError(size_t, TStringBuf token) override { +                Events.push_back(TEvent(token, E_ERROR)); +            } + +            void Assert(const TEvents& e, TString str) { +                try { +                    UNIT_ASSERT_VALUES_EQUAL_C(e.size(), Events.size(), str); + +                    for (ui32 i = 0, sz = e.size(); i < sz; ++i) {                          UNIT_ASSERT_VALUES_EQUAL_C((int)e[i].Type, (int)Events[i].Type, Sprintf("'%s' %u", str.data(), i));                          UNIT_ASSERT_VALUES_EQUAL_C(e[i].INum, Events[i].INum, Sprintf("'%s' %u", str.data(), i));                          UNIT_ASSERT_VALUES_EQUAL_C(e[i].DNum, Events[i].DNum, Sprintf("'%s' %u", str.data(), i));                          UNIT_ASSERT_VALUES_EQUAL_C(e[i].Str, Events[i].Str, Sprintf("'%s' %u", str.data(), i)); -                    }  -                } catch (const yexception&) {  -                    Clog << "Exception at '" << str << "'" << Endl;  -                    for (const auto& event : Events) {  -                        Clog << event.ToString() << Endl;  -                    }  - -                    throw;  -                }  +                    } +                } catch (const yexception&) { +                    Clog << "Exception at '" << str << "'" << Endl; +                    for (const auto& event : Events) { +                        Clog << event.ToString() << Endl; +                    } + +                    throw; +                }              } -        };  +        };      }  } -class TFastJsonTest: public TTestBase {  -    UNIT_TEST_SUITE(TFastJsonTest)  +class TFastJsonTest: public TTestBase { +    UNIT_TEST_SUITE(TFastJsonTest)      UNIT_TEST(TestParse)      UNIT_TEST(TestReadJsonFastTree)      UNIT_TEST(TestNoInlineComment) -    UNIT_TEST_SUITE_END();  -  +    UNIT_TEST_SUITE_END(); +  public:      template <bool accept>      void DoTestParse(TStringBuf json, ui32 amount, ...) { @@ -188,45 +188,45 @@ public:              ETestEvent e = (ETestEvent)va_arg(vl, int);              switch ((int)e) { -                case E_NO_EVENT:  -                case E_DICT_OPEN:  -                case E_DICT_CLOSE:  -                case E_ARR_OPEN:  -                case E_ARR_CLOSE:  -                case E_NULL:  -                    evs.push_back(e);  -                    break;  -                case E_BOOL: {  -                    bool v = va_arg(vl, int);  -                    evs.push_back(TEvent((i64)v, E_BOOL));  -                    break;  -                }  -                case E_INT: {  -                    i64 i = va_arg(vl, int);  -                    evs.push_back(TEvent(i, E_INT));  -                    break;  -                }  -                case E_LONG_LONG: {  -                    i64 i = va_arg(vl, long long);  -                    evs.push_back(TEvent(i, E_INT));  -                    break;  -                }  -                case E_FLT: {  -                    double f = va_arg(vl, double);  -                    evs.push_back(TEvent(f, E_FLT));  -                    break;  -                }  -                case E_STR: {  -                    const char* s = va_arg(vl, const char*);  -                    evs.push_back(TEvent(TStringBuf(s), E_STR));  -                    break;  -                }  -                case E_KEY:  -                case E_ERROR: {  -                    const char* s = va_arg(vl, const char*);  -                    evs.push_back(TEvent(TStringBuf(s), e));  -                    break;  -                }  +                case E_NO_EVENT: +                case E_DICT_OPEN: +                case E_DICT_CLOSE: +                case E_ARR_OPEN: +                case E_ARR_CLOSE: +                case E_NULL: +                    evs.push_back(e); +                    break; +                case E_BOOL: { +                    bool v = va_arg(vl, int); +                    evs.push_back(TEvent((i64)v, E_BOOL)); +                    break; +                } +                case E_INT: { +                    i64 i = va_arg(vl, int); +                    evs.push_back(TEvent(i, E_INT)); +                    break; +                } +                case E_LONG_LONG: { +                    i64 i = va_arg(vl, long long); +                    evs.push_back(TEvent(i, E_INT)); +                    break; +                } +                case E_FLT: { +                    double f = va_arg(vl, double); +                    evs.push_back(TEvent(f, E_FLT)); +                    break; +                } +                case E_STR: { +                    const char* s = va_arg(vl, const char*); +                    evs.push_back(TEvent(TStringBuf(s), E_STR)); +                    break; +                } +                case E_KEY: +                case E_ERROR: { +                    const char* s = va_arg(vl, const char*); +                    evs.push_back(TEvent(TStringBuf(s), e)); +                    break; +                }              }          }          va_end(vl); @@ -258,25 +258,25 @@ public:          DoTestParse<false>("[a,,b]", 3, E_ARR_OPEN, E_STR, "a", E_ERROR, "invalid syntax at token: ','");          DoTestParse<true>("{ k : v }", 4, E_DICT_OPEN, E_KEY, "k", E_STR, "v", E_DICT_CLOSE);          DoTestParse<true>("{a:'\\b'/*comment*/, k /*comment*/\n : v }", 6, E_DICT_OPEN, E_KEY, "a", E_STR, "\b", E_KEY, "k", E_STR, "v", E_DICT_CLOSE); -        DoTestParse<true>("{a:.15, k : v }", 6, E_DICT_OPEN, E_KEY, "a", E_FLT, .15, E_KEY, "k", E_STR, "v", E_DICT_CLOSE);  -        DoTestParse<true>("[ a, -.1e+5, 1E-7]", 5, E_ARR_OPEN, E_STR, "a", E_FLT, -.1e+5, E_FLT, 1e-7, E_ARR_CLOSE);  +        DoTestParse<true>("{a:.15, k : v }", 6, E_DICT_OPEN, E_KEY, "a", E_FLT, .15, E_KEY, "k", E_STR, "v", E_DICT_CLOSE); +        DoTestParse<true>("[ a, -.1e+5, 1E-7]", 5, E_ARR_OPEN, E_STR, "a", E_FLT, -.1e+5, E_FLT, 1e-7, E_ARR_CLOSE);          DoTestParse<true>("{}", 2, E_DICT_OPEN, E_DICT_CLOSE); -        DoTestParse<true>("{ a : x, b : [ c, d, ] }", 9, E_DICT_OPEN, E_KEY, "a", E_STR, "x", E_KEY, "b", E_ARR_OPEN, E_STR, "c", E_STR, "d", E_ARR_CLOSE, E_DICT_CLOSE);  -        DoTestParse<false>("{ a : x, b : [ c, d,, ] }", 8, E_DICT_OPEN, E_KEY, "a", E_STR, "x", E_KEY, "b", E_ARR_OPEN, E_STR, "c", E_STR, "d", E_ERROR, "invalid syntax at token: ','");  -        //        DoTestParse<false>("{ a : x : y }", 4, E_DICT_OPEN  -        //                    , E_KEY, "a", E_STR, "x"  -        //                    , E_ERROR  -        //                    , ":");  -        //        DoTestParse<false>("{queries:{ref:[]},{nonref:[]}}", 8, E_DICT_OPEN  -        //                           , E_KEY, "queries", E_DICT_OPEN  -        //                               , E_KEY, "ref", E_ARR_OPEN, E_ARR_CLOSE  -        //                               , E_DICT_CLOSE, E_ERROR, "");  +        DoTestParse<true>("{ a : x, b : [ c, d, ] }", 9, E_DICT_OPEN, E_KEY, "a", E_STR, "x", E_KEY, "b", E_ARR_OPEN, E_STR, "c", E_STR, "d", E_ARR_CLOSE, E_DICT_CLOSE); +        DoTestParse<false>("{ a : x, b : [ c, d,, ] }", 8, E_DICT_OPEN, E_KEY, "a", E_STR, "x", E_KEY, "b", E_ARR_OPEN, E_STR, "c", E_STR, "d", E_ERROR, "invalid syntax at token: ','"); +        //        DoTestParse<false>("{ a : x : y }", 4, E_DICT_OPEN +        //                    , E_KEY, "a", E_STR, "x" +        //                    , E_ERROR +        //                    , ":"); +        //        DoTestParse<false>("{queries:{ref:[]},{nonref:[]}}", 8, E_DICT_OPEN +        //                           , E_KEY, "queries", E_DICT_OPEN +        //                               , E_KEY, "ref", E_ARR_OPEN, E_ARR_CLOSE +        //                               , E_DICT_CLOSE, E_ERROR, "");          DoTestParse<true>("'100x00'", 1, E_STR, "100x00");          DoTestParse<true>("-1", 1, E_INT, -1);          DoTestParse<true>("-9223372036854775808", 1, E_LONG_LONG, (long long)Min<i64>());          DoTestParse<false>("100x00", 1, E_ERROR, "invalid syntax at token: '100x'");          DoTestParse<false>("100 200", 2, E_INT, 100, E_ERROR, "invalid syntax at token: '200'"); -        DoTestParse<true>("{g:{x:{a:{b:c,e:f},q:{x:y}},y:fff}}", 22, E_DICT_OPEN, E_KEY, "g", E_DICT_OPEN, E_KEY, "x", E_DICT_OPEN, E_KEY, "a", E_DICT_OPEN, E_KEY, "b", E_STR, "c", E_KEY, "e", E_STR, "f", E_DICT_CLOSE, E_KEY, "q", E_DICT_OPEN, E_KEY, "x", E_STR, "y", E_DICT_CLOSE, E_DICT_CLOSE, E_KEY, "y", E_STR, "fff", E_DICT_CLOSE, E_DICT_CLOSE);  +        DoTestParse<true>("{g:{x:{a:{b:c,e:f},q:{x:y}},y:fff}}", 22, E_DICT_OPEN, E_KEY, "g", E_DICT_OPEN, E_KEY, "x", E_DICT_OPEN, E_KEY, "a", E_DICT_OPEN, E_KEY, "b", E_STR, "c", E_KEY, "e", E_STR, "f", E_DICT_CLOSE, E_KEY, "q", E_DICT_OPEN, E_KEY, "x", E_STR, "y", E_DICT_CLOSE, E_DICT_CLOSE, E_KEY, "y", E_STR, "fff", E_DICT_CLOSE, E_DICT_CLOSE);      }      void TestReadJsonFastTree() { diff --git a/library/cpp/json/ut/json_reader_ut.cpp b/library/cpp/json/ut/json_reader_ut.cpp index 958ed197301..cd31afa0b8b 100644 --- a/library/cpp/json/ut/json_reader_ut.cpp +++ b/library/cpp/json/ut/json_reader_ut.cpp @@ -7,12 +7,12 @@  using namespace NJson;  class TReformatCallbacks: public TJsonCallbacks { -    TJsonWriter& Writer;  -  +    TJsonWriter& Writer; +  public: -    TReformatCallbacks(TJsonWriter& writer)  -        : Writer(writer)  -    {  +    TReformatCallbacks(TJsonWriter& writer) +        : Writer(writer) +    {      }      bool OnBoolean(bool val) override { @@ -30,7 +30,7 @@ public:          return true;      } -    bool OnString(const TStringBuf& val) override {  +    bool OnString(const TStringBuf& val) override {          Writer.Write(val);          return true;      } @@ -60,7 +60,7 @@ public:          return true;      } -    bool OnMapKey(const TStringBuf& val) override {  +    bool OnMapKey(const TStringBuf& val) override {          Writer.Write(val);          return true;      } @@ -145,7 +145,7 @@ Y_UNIT_TEST_SUITE(TJsonReaderTest) {          UNIT_ASSERT_VALUES_EQUAL(value["array"].GetStringRobust(), "[1,2,3,\"TString\"]");          UNIT_ASSERT_VALUES_EQUAL(value["null value"].GetStringRobust(), "null"); -        const TJsonValue::TArray* array;  +        const TJsonValue::TArray* array;          UNIT_ASSERT(GetArrayPointer(value, "array", &array));          UNIT_ASSERT_VALUES_EQUAL(value["array"].GetArray().size(), array->size());          UNIT_ASSERT_VALUES_EQUAL(value["array"][0].GetInteger(), (*array)[0].GetInteger()); @@ -353,7 +353,7 @@ Y_UNIT_TEST_SUITE(TJsonReaderTest) {              UNIT_ASSERT_EQUAL(value["test"].GetDouble(), 0.0);              UNIT_ASSERT_EQUAL(value["test"].GetDoubleRobust(), static_cast<double>(Max<ui64>()));          } // Max<ui64>() -    }     // TJsonDoubleTest  +    }     // TJsonDoubleTest      Y_UNIT_TEST(TJsonInvalidTest) {          { @@ -397,34 +397,34 @@ Y_UNIT_TEST_SUITE(TJsonReaderTest) {          UNIT_ASSERT_VALUES_EQUAL("", v.GetMap().begin()->second.GetString());      }  } -  -  -static const TString YANDEX_STREAMING_JSON("{\"a\":1}//d{\"b\":2}");  -  -  -Y_UNIT_TEST_SUITE(TCompareReadJsonFast) {  -    Y_UNIT_TEST(NoEndl) {  -        NJson::TJsonValue parsed;  -  -        bool success = NJson::ReadJsonTree(YANDEX_STREAMING_JSON, &parsed, false);  -        bool fast_success = NJson::ReadJsonFastTree(YANDEX_STREAMING_JSON, &parsed, false);  -        UNIT_ASSERT(success == fast_success);  -    }  -    Y_UNIT_TEST(WithEndl) {  -        NJson::TJsonValue parsed1;  -        NJson::TJsonValue parsed2;  -  -        bool success = NJson::ReadJsonTree(YANDEX_STREAMING_JSON + "\n", &parsed1, false);  -        bool fast_success = NJson::ReadJsonFastTree(YANDEX_STREAMING_JSON + "\n", &parsed2, false);  -  -        UNIT_ASSERT_VALUES_EQUAL(success, fast_success);  -    }  -    Y_UNIT_TEST(NoQuotes) {  -        TString streamingJson = "{a:1}";  -        NJson::TJsonValue parsed;  -  -        bool success = NJson::ReadJsonTree(streamingJson, &parsed, false);  -        bool fast_success = NJson::ReadJsonFastTree(streamingJson, &parsed, false);  -        UNIT_ASSERT(success != fast_success);  -    }  -}  + + +static const TString YANDEX_STREAMING_JSON("{\"a\":1}//d{\"b\":2}"); + + +Y_UNIT_TEST_SUITE(TCompareReadJsonFast) { +    Y_UNIT_TEST(NoEndl) { +        NJson::TJsonValue parsed; + +        bool success = NJson::ReadJsonTree(YANDEX_STREAMING_JSON, &parsed, false); +        bool fast_success = NJson::ReadJsonFastTree(YANDEX_STREAMING_JSON, &parsed, false); +        UNIT_ASSERT(success == fast_success); +    } +    Y_UNIT_TEST(WithEndl) { +        NJson::TJsonValue parsed1; +        NJson::TJsonValue parsed2; + +        bool success = NJson::ReadJsonTree(YANDEX_STREAMING_JSON + "\n", &parsed1, false); +        bool fast_success = NJson::ReadJsonFastTree(YANDEX_STREAMING_JSON + "\n", &parsed2, false); + +        UNIT_ASSERT_VALUES_EQUAL(success, fast_success); +    } +    Y_UNIT_TEST(NoQuotes) { +        TString streamingJson = "{a:1}"; +        NJson::TJsonValue parsed; + +        bool success = NJson::ReadJsonTree(streamingJson, &parsed, false); +        bool fast_success = NJson::ReadJsonFastTree(streamingJson, &parsed, false); +        UNIT_ASSERT(success != fast_success); +    } +} diff --git a/library/cpp/json/ut/json_writer_ut.cpp b/library/cpp/json/ut/json_writer_ut.cpp index 0fe747d704e..ca11d34dad9 100644 --- a/library/cpp/json/ut/json_writer_ut.cpp +++ b/library/cpp/json/ut/json_writer_ut.cpp @@ -8,7 +8,7 @@ using namespace NJson;  Y_UNIT_TEST_SUITE(TJsonWriterTest) {      Y_UNIT_TEST(SimpleWriteTest) {          TString expected1 = "{\"key1\":1,\"key2\":2,\"key3\":3"; -        TString expected2 = expected1 + ",\"array\":[\"stroka\",false]";  +        TString expected2 = expected1 + ",\"array\":[\"stroka\",false]";          TString expected3 = expected2 + "}";          TStringStream out; @@ -120,7 +120,7 @@ Y_UNIT_TEST_SUITE(TJsonWriterTest) {              WriteJson(&out, &v);              UNIT_ASSERT_VALUES_EQUAL(out.Str(), expected);          } // 18446744073709551615 -    }     // SimpleUnsignedIntegerWriteTest  +    }     // SimpleUnsignedIntegerWriteTest      Y_UNIT_TEST(WriteOptionalTest) {          { diff --git a/library/cpp/json/ut/ya.make b/library/cpp/json/ut/ya.make index 5f3a2d85102..8e0362d84b2 100644 --- a/library/cpp/json/ut/ya.make +++ b/library/cpp/json/ut/ya.make @@ -2,10 +2,10 @@ OWNER(velavokr)  UNITTEST_FOR(library/cpp/json) -PEERDIR(  +PEERDIR(      library/cpp/string_utils/relaxed_escaper -)  -  +) +  SRCS(      json_reader_fast_ut.cpp      json_reader_ut.cpp diff --git a/library/cpp/json/writer/json.cpp b/library/cpp/json/writer/json.cpp index 6bad7cf3a9e..02370c2d79e 100644 --- a/library/cpp/json/writer/json.cpp +++ b/library/cpp/json/writer/json.cpp @@ -1,94 +1,94 @@  #include "json.h" -  +  #include <library/cpp/json/json_value.h> -  +  #include <util/string/cast.h> -#include <util/string/strspn.h>  +#include <util/string/strspn.h>  #include <util/generic/algorithm.h>  #include <util/generic/ymath.h> -#include <util/generic/singleton.h>  +#include <util/generic/singleton.h>  namespace NJsonWriter { -    TBuf::TBuf(EHtmlEscapeMode mode, IOutputStream* stream)  -        : Stream(stream)  -        , NeedComma(false)  -        , NeedNewline(false)  -        , EscapeMode(mode)  -        , IndentSpaces(0)  -        , WriteNanAsString(false)  -    {  -        Y_ASSERT(mode == HEM_DONT_ESCAPE_HTML ||  -                 mode == HEM_ESCAPE_HTML ||  -                 mode == HEM_RELAXED ||  -                 mode == HEM_UNSAFE);  -        if (!Stream) {  -            StringStream.Reset(new TStringStream);  -            Stream = StringStream.Get();  -        }  - -        Stack.reserve(64); // should be enough for most cases  -        StackPush(JE_OUTER_SPACE);  -    } - -    static const char* EntityToStr(EJsonEntity e) {  -        switch (e) {  -            case JE_OUTER_SPACE:  -                return "JE_OUTER_SPACE";  -            case JE_LIST:  -                return "JE_LIST";  -            case JE_OBJECT:  -                return "JE_OBJECT";  -            case JE_PAIR:  -                return "JE_PAIR";  -            default:  -                return "JE_unknown";  -        }  -    }  - -    inline void TBuf::StackPush(EJsonEntity e) {  -        Stack.push_back(e);  -    } - -    inline EJsonEntity TBuf::StackTop() const {  -        return Stack.back();  -    }  - -    inline void TBuf::StackPop() {  -        Y_ASSERT(!Stack.empty());  -        const EJsonEntity current = StackTop();  -        Stack.pop_back();  -        switch (current) {  -            case JE_OUTER_SPACE:  -                ythrow TError() << "JSON writer: stack empty";  -            case JE_LIST:  -                PrintIndentation(true);  -                RawWriteChar(']');  -                break;  -            case JE_OBJECT:  -                PrintIndentation(true);  -                RawWriteChar('}');  -                break;  -            case JE_PAIR:  -                break;  -        }  -        NeedComma = true;  -        NeedNewline = true;  -    }  - -    inline void TBuf::CheckAndPop(EJsonEntity e) {  -        if (Y_UNLIKELY(StackTop() != e)) {  -            ythrow TError() << "JSON writer: unexpected value "  -                            << EntityToStr(StackTop()) << " on the stack";  -        }  -        StackPop();  -    } - -    void TBuf::PrintIndentation(bool closing) {  -        if (!IndentSpaces)  -            return;  -        const int indentation = IndentSpaces * (Stack.size() - 1);  -        if (!indentation && !closing)  -            return;  +    TBuf::TBuf(EHtmlEscapeMode mode, IOutputStream* stream) +        : Stream(stream) +        , NeedComma(false) +        , NeedNewline(false) +        , EscapeMode(mode) +        , IndentSpaces(0) +        , WriteNanAsString(false) +    { +        Y_ASSERT(mode == HEM_DONT_ESCAPE_HTML || +                 mode == HEM_ESCAPE_HTML || +                 mode == HEM_RELAXED || +                 mode == HEM_UNSAFE); +        if (!Stream) { +            StringStream.Reset(new TStringStream); +            Stream = StringStream.Get(); +        } + +        Stack.reserve(64); // should be enough for most cases +        StackPush(JE_OUTER_SPACE); +    } + +    static const char* EntityToStr(EJsonEntity e) { +        switch (e) { +            case JE_OUTER_SPACE: +                return "JE_OUTER_SPACE"; +            case JE_LIST: +                return "JE_LIST"; +            case JE_OBJECT: +                return "JE_OBJECT"; +            case JE_PAIR: +                return "JE_PAIR"; +            default: +                return "JE_unknown"; +        } +    } + +    inline void TBuf::StackPush(EJsonEntity e) { +        Stack.push_back(e); +    } + +    inline EJsonEntity TBuf::StackTop() const { +        return Stack.back(); +    } + +    inline void TBuf::StackPop() { +        Y_ASSERT(!Stack.empty()); +        const EJsonEntity current = StackTop(); +        Stack.pop_back(); +        switch (current) { +            case JE_OUTER_SPACE: +                ythrow TError() << "JSON writer: stack empty"; +            case JE_LIST: +                PrintIndentation(true); +                RawWriteChar(']'); +                break; +            case JE_OBJECT: +                PrintIndentation(true); +                RawWriteChar('}'); +                break; +            case JE_PAIR: +                break; +        } +        NeedComma = true; +        NeedNewline = true; +    } + +    inline void TBuf::CheckAndPop(EJsonEntity e) { +        if (Y_UNLIKELY(StackTop() != e)) { +            ythrow TError() << "JSON writer: unexpected value " +                            << EntityToStr(StackTop()) << " on the stack"; +        } +        StackPop(); +    } + +    void TBuf::PrintIndentation(bool closing) { +        if (!IndentSpaces) +            return; +        const int indentation = IndentSpaces * (Stack.size() - 1); +        if (!indentation && !closing) +            return;          PrintWhitespaces(Max(0, indentation), true);      } @@ -107,258 +107,258 @@ namespace NJsonWriter {          } while (count > 0);      } -    inline void TBuf::WriteComma() {  -        if (NeedComma) {  -            RawWriteChar(',');  -        }  -        NeedComma = true;  - -        if (NeedNewline) {  -            PrintIndentation(false);  -        }  -        NeedNewline = true;  -    }  - -    inline void TBuf::BeginValue() {  -        if (Y_UNLIKELY(KeyExpected())) {  -            ythrow TError() << "JSON writer: value written, "  -                               "but expected a key:value pair";  -        }  -        WriteComma();  -    }  - -    inline void TBuf::BeginKey() {  -        if (Y_UNLIKELY(!KeyExpected())) {  -            ythrow TError() << "JSON writer: key written outside of an object";  -        }  -        WriteComma();  -        StackPush(JE_PAIR);  -        NeedComma = false;  -        NeedNewline = false;  -    } - -    inline void TBuf::EndValue() {  -        if (StackTop() == JE_PAIR) {  -            StackPop();  -        }  -    } - -    TValueContext TBuf::BeginList() {  -        NeedNewline = true;  -        BeginValue();  -        RawWriteChar('[');  -        StackPush(JE_LIST);  -        NeedComma = false;  -        return TValueContext(*this);  -    } - -    TPairContext TBuf::BeginObject() {  -        NeedNewline = true;  -        BeginValue();  -        RawWriteChar('{');  -        StackPush(JE_OBJECT);  -        NeedComma = false;  -        return TPairContext(*this);  -    } - -    TAfterColonContext TBuf::UnsafeWriteKey(const TStringBuf& s) {  -        BeginKey();  -        RawWriteChar('"');  -        UnsafeWriteRawBytes(s);  -        UnsafeWriteRawBytes("\":", 2);  -        return TAfterColonContext(*this);  -    } - -    TAfterColonContext TBuf::WriteKey(const TStringBuf& s) {  -        // use the default escaping mode for this object  -        return WriteKey(s, EscapeMode);  -    }  - -    TAfterColonContext TBuf::WriteKey(const TStringBuf& s, EHtmlEscapeMode hem) {  -        BeginKey();  -        WriteBareString(s, hem);  -        RawWriteChar(':');  -        return TAfterColonContext(*this);  -    }  - -    TAfterColonContext TBuf::CompatWriteKeyWithoutQuotes(const TStringBuf& s) {  -        BeginKey();  -        Y_ASSERT(AllOf(s, [](char x) { return 'a' <= x && x <= 'z'; }));  -        UnsafeWriteRawBytes(s);  -        RawWriteChar(':');  -        return TAfterColonContext(*this);  -    }  - -    TBuf& TBuf::EndList() {  -        CheckAndPop(JE_LIST);  -        EndValue();  -        return *this;  -    }  - -    TBuf& TBuf::EndObject() {  -        CheckAndPop(JE_OBJECT);  -        EndValue();  -        return *this;  -    }  - -    TValueContext TBuf::WriteString(const TStringBuf& s) {  -        // use the default escaping mode for this object  -        return WriteString(s, EscapeMode);  -    }  - -    TValueContext TBuf::WriteString(const TStringBuf& s, EHtmlEscapeMode hem) {  -        BeginValue();  -        WriteBareString(s, hem);  -        EndValue();  -        return TValueContext(*this);  -    }  - -    TValueContext TBuf::WriteNull() {  +    inline void TBuf::WriteComma() { +        if (NeedComma) { +            RawWriteChar(','); +        } +        NeedComma = true; + +        if (NeedNewline) { +            PrintIndentation(false); +        } +        NeedNewline = true; +    } + +    inline void TBuf::BeginValue() { +        if (Y_UNLIKELY(KeyExpected())) { +            ythrow TError() << "JSON writer: value written, " +                               "but expected a key:value pair"; +        } +        WriteComma(); +    } + +    inline void TBuf::BeginKey() { +        if (Y_UNLIKELY(!KeyExpected())) { +            ythrow TError() << "JSON writer: key written outside of an object"; +        } +        WriteComma(); +        StackPush(JE_PAIR); +        NeedComma = false; +        NeedNewline = false; +    } + +    inline void TBuf::EndValue() { +        if (StackTop() == JE_PAIR) { +            StackPop(); +        } +    } + +    TValueContext TBuf::BeginList() { +        NeedNewline = true; +        BeginValue(); +        RawWriteChar('['); +        StackPush(JE_LIST); +        NeedComma = false; +        return TValueContext(*this); +    } + +    TPairContext TBuf::BeginObject() { +        NeedNewline = true; +        BeginValue(); +        RawWriteChar('{'); +        StackPush(JE_OBJECT); +        NeedComma = false; +        return TPairContext(*this); +    } + +    TAfterColonContext TBuf::UnsafeWriteKey(const TStringBuf& s) { +        BeginKey(); +        RawWriteChar('"'); +        UnsafeWriteRawBytes(s); +        UnsafeWriteRawBytes("\":", 2); +        return TAfterColonContext(*this); +    } + +    TAfterColonContext TBuf::WriteKey(const TStringBuf& s) { +        // use the default escaping mode for this object +        return WriteKey(s, EscapeMode); +    } + +    TAfterColonContext TBuf::WriteKey(const TStringBuf& s, EHtmlEscapeMode hem) { +        BeginKey(); +        WriteBareString(s, hem); +        RawWriteChar(':'); +        return TAfterColonContext(*this); +    } + +    TAfterColonContext TBuf::CompatWriteKeyWithoutQuotes(const TStringBuf& s) { +        BeginKey(); +        Y_ASSERT(AllOf(s, [](char x) { return 'a' <= x && x <= 'z'; })); +        UnsafeWriteRawBytes(s); +        RawWriteChar(':'); +        return TAfterColonContext(*this); +    } + +    TBuf& TBuf::EndList() { +        CheckAndPop(JE_LIST); +        EndValue(); +        return *this; +    } + +    TBuf& TBuf::EndObject() { +        CheckAndPop(JE_OBJECT); +        EndValue(); +        return *this; +    } + +    TValueContext TBuf::WriteString(const TStringBuf& s) { +        // use the default escaping mode for this object +        return WriteString(s, EscapeMode); +    } + +    TValueContext TBuf::WriteString(const TStringBuf& s, EHtmlEscapeMode hem) { +        BeginValue(); +        WriteBareString(s, hem); +        EndValue(); +        return TValueContext(*this); +    } + +    TValueContext TBuf::WriteNull() {          UnsafeWriteValue(TStringBuf("null")); -        return TValueContext(*this);  -    }  +        return TValueContext(*this); +    } -    TValueContext TBuf::WriteBool(bool b) {  +    TValueContext TBuf::WriteBool(bool b) {          constexpr TStringBuf trueVal = "true";          constexpr TStringBuf falseVal = "false";          UnsafeWriteValue(b ? trueVal : falseVal); -        return TValueContext(*this);  -    }  - -    TValueContext TBuf::WriteInt(int i) {  -        char buf[22]; // enough to hold any 64-bit number  -        size_t len = ToString(i, buf, sizeof(buf));  -        UnsafeWriteValue(buf, len);  -        return TValueContext(*this);  -    }  - -    TValueContext TBuf::WriteLongLong(long long i) {  -        static_assert(sizeof(long long) <= 8, "expect sizeof(long long) <= 8");  -        char buf[22]; // enough to hold any 64-bit number  -        size_t len = ToString(i, buf, sizeof(buf));  -        UnsafeWriteValue(buf, len);  -        return TValueContext(*this);  -    }  - -    TValueContext TBuf::WriteULongLong(unsigned long long i) {  -        char buf[22]; // enough to hold any 64-bit number  -        size_t len = ToString(i, buf, sizeof(buf));  -        UnsafeWriteValue(buf, len);  -        return TValueContext(*this);  -    }  - -    template <class TFloat>  -    TValueContext TBuf::WriteFloatImpl(TFloat f, EFloatToStringMode mode, int ndigits) {  -        char buf[512]; // enough to hold most floats, the same buffer is used in FloatToString implementation  -        if (Y_UNLIKELY(!IsValidFloat(f))) {  -            if (WriteNanAsString) {  -                const size_t size = FloatToString(f, buf, Y_ARRAY_SIZE(buf));  -                WriteString(TStringBuf(buf, size));  -                return TValueContext(*this);  -            } else {  -                ythrow TError() << "JSON writer: invalid float value: " << FloatToString(f);  -            }  +        return TValueContext(*this); +    } + +    TValueContext TBuf::WriteInt(int i) { +        char buf[22]; // enough to hold any 64-bit number +        size_t len = ToString(i, buf, sizeof(buf)); +        UnsafeWriteValue(buf, len); +        return TValueContext(*this); +    } + +    TValueContext TBuf::WriteLongLong(long long i) { +        static_assert(sizeof(long long) <= 8, "expect sizeof(long long) <= 8"); +        char buf[22]; // enough to hold any 64-bit number +        size_t len = ToString(i, buf, sizeof(buf)); +        UnsafeWriteValue(buf, len); +        return TValueContext(*this); +    } + +    TValueContext TBuf::WriteULongLong(unsigned long long i) { +        char buf[22]; // enough to hold any 64-bit number +        size_t len = ToString(i, buf, sizeof(buf)); +        UnsafeWriteValue(buf, len); +        return TValueContext(*this); +    } + +    template <class TFloat> +    TValueContext TBuf::WriteFloatImpl(TFloat f, EFloatToStringMode mode, int ndigits) { +        char buf[512]; // enough to hold most floats, the same buffer is used in FloatToString implementation +        if (Y_UNLIKELY(!IsValidFloat(f))) { +            if (WriteNanAsString) { +                const size_t size = FloatToString(f, buf, Y_ARRAY_SIZE(buf)); +                WriteString(TStringBuf(buf, size)); +                return TValueContext(*this); +            } else { +                ythrow TError() << "JSON writer: invalid float value: " << FloatToString(f); +            }          } -        size_t len = FloatToString(f, buf, Y_ARRAY_SIZE(buf), mode, ndigits);  -        UnsafeWriteValue(buf, len);  -        return TValueContext(*this);  -    } - -    TValueContext TBuf::WriteFloat(float f, EFloatToStringMode mode, int ndigits) {  -        return WriteFloatImpl(f, mode, ndigits);  -    }  - -    TValueContext TBuf::WriteDouble(double f, EFloatToStringMode mode, int ndigits) {  -        return WriteFloatImpl(f, mode, ndigits);  -    }  - -    namespace {  -        struct TFinder: public TCompactStrSpn {  -            inline TFinder()  -                : TCompactStrSpn("\xe2\\\"\b\n\f\r\t<>&\'/")  -            {  -                for (ui8 ch = 0; ch < 0x20; ++ch) {  -                    Set(ch);  -                }  -            }  -        };  -    }  -  -    inline void TBuf::WriteBareString(const TStringBuf s, EHtmlEscapeMode hem) {  -        RawWriteChar('"');  -        const auto& specialChars = *Singleton<TFinder>();  -        const char* b = s.begin();  -        const char* e = s.end();  -        const char* i = b;  -        while ((i = specialChars.FindFirstOf(i, e)) != e) {  -            // U+2028 (line separator) and U+2029 (paragraph separator) are valid string  -            // contents in JSON, but are treated as line breaks in JavaScript, breaking JSONP.  -            // In UTF-8, U+2028 is "\xe2\x80\xa8" and U+2029 is "\xe2\x80\xa9".  -            if (Y_UNLIKELY(e - i >= 3 && i[0] == '\xe2' && i[1] == '\x80' && (i[2] | 1) == '\xa9')) {  -                UnsafeWriteRawBytes(b, i - b);  -                UnsafeWriteRawBytes(i[2] == '\xa9' ? "\\u2029" : "\\u2028", 6);  -                b = i = i + 3;  -            } else if (EscapedWriteChar(b, i, hem)) {  -                b = ++i;  -            } else {  -                ++i;  -            }  -        }  -        UnsafeWriteRawBytes(b, e - b);  -        RawWriteChar('"');  -    } - -    inline void TBuf::RawWriteChar(char c) {  -        Stream->Write(c);  -    }  - -    void TBuf::WriteHexEscape(unsigned char c) {  -        Y_ASSERT(c < 0x80);  -        UnsafeWriteRawBytes("\\u00", 4);  -        static const char hexDigits[] = "0123456789ABCDEF";  -        RawWriteChar(hexDigits[(c & 0xf0) >> 4]);  -        RawWriteChar(hexDigits[(c & 0x0f)]);  -    }  - -#define MATCH(sym, string)                        \  -    case sym:                                     \  -        UnsafeWriteRawBytes(beg, cur - beg);      \  +        size_t len = FloatToString(f, buf, Y_ARRAY_SIZE(buf), mode, ndigits); +        UnsafeWriteValue(buf, len); +        return TValueContext(*this); +    } + +    TValueContext TBuf::WriteFloat(float f, EFloatToStringMode mode, int ndigits) { +        return WriteFloatImpl(f, mode, ndigits); +    } + +    TValueContext TBuf::WriteDouble(double f, EFloatToStringMode mode, int ndigits) { +        return WriteFloatImpl(f, mode, ndigits); +    } + +    namespace { +        struct TFinder: public TCompactStrSpn { +            inline TFinder() +                : TCompactStrSpn("\xe2\\\"\b\n\f\r\t<>&\'/") +            { +                for (ui8 ch = 0; ch < 0x20; ++ch) { +                    Set(ch); +                } +            } +        }; +    } + +    inline void TBuf::WriteBareString(const TStringBuf s, EHtmlEscapeMode hem) { +        RawWriteChar('"'); +        const auto& specialChars = *Singleton<TFinder>(); +        const char* b = s.begin(); +        const char* e = s.end(); +        const char* i = b; +        while ((i = specialChars.FindFirstOf(i, e)) != e) { +            // U+2028 (line separator) and U+2029 (paragraph separator) are valid string +            // contents in JSON, but are treated as line breaks in JavaScript, breaking JSONP. +            // In UTF-8, U+2028 is "\xe2\x80\xa8" and U+2029 is "\xe2\x80\xa9". +            if (Y_UNLIKELY(e - i >= 3 && i[0] == '\xe2' && i[1] == '\x80' && (i[2] | 1) == '\xa9')) { +                UnsafeWriteRawBytes(b, i - b); +                UnsafeWriteRawBytes(i[2] == '\xa9' ? "\\u2029" : "\\u2028", 6); +                b = i = i + 3; +            } else if (EscapedWriteChar(b, i, hem)) { +                b = ++i; +            } else { +                ++i; +            } +        } +        UnsafeWriteRawBytes(b, e - b); +        RawWriteChar('"'); +    } + +    inline void TBuf::RawWriteChar(char c) { +        Stream->Write(c); +    } + +    void TBuf::WriteHexEscape(unsigned char c) { +        Y_ASSERT(c < 0x80); +        UnsafeWriteRawBytes("\\u00", 4); +        static const char hexDigits[] = "0123456789ABCDEF"; +        RawWriteChar(hexDigits[(c & 0xf0) >> 4]); +        RawWriteChar(hexDigits[(c & 0x0f)]); +    } + +#define MATCH(sym, string)                        \ +    case sym:                                     \ +        UnsafeWriteRawBytes(beg, cur - beg);      \          UnsafeWriteRawBytes(TStringBuf(string));  \ -        return true  - -    inline bool TBuf::EscapedWriteChar(const char* beg, const char* cur, EHtmlEscapeMode hem) {  -        unsigned char c = *cur;  -        if (hem == HEM_ESCAPE_HTML) {  -            switch (c) {  -                MATCH('"', """);  -                MATCH('\'', "'");  -                MATCH('<', "<");  -                MATCH('>', ">");  -                MATCH('&', "&");  -            }  -            //for other characters, we fall through to the non-HTML-escaped part  +        return true + +    inline bool TBuf::EscapedWriteChar(const char* beg, const char* cur, EHtmlEscapeMode hem) { +        unsigned char c = *cur; +        if (hem == HEM_ESCAPE_HTML) { +            switch (c) { +                MATCH('"', """); +                MATCH('\'', "'"); +                MATCH('<', "<"); +                MATCH('>', ">"); +                MATCH('&', "&"); +            } +            //for other characters, we fall through to the non-HTML-escaped part          } -        if (hem == HEM_RELAXED && c == '/')  -            return false;  - -        if (hem != HEM_UNSAFE) {  -            switch (c) {  -                case '/':  -                    UnsafeWriteRawBytes(beg, cur - beg);  -                    UnsafeWriteRawBytes("\\/", 2);  -                    return true;  -                case '<':  -                case '>':  -                case '\'':  -                    UnsafeWriteRawBytes(beg, cur - beg);  -                    WriteHexEscape(c);  -                    return true;  -            }  -            // for other characters, fall through to the non-escaped part  +        if (hem == HEM_RELAXED && c == '/') +            return false; + +        if (hem != HEM_UNSAFE) { +            switch (c) { +                case '/': +                    UnsafeWriteRawBytes(beg, cur - beg); +                    UnsafeWriteRawBytes("\\/", 2); +                    return true; +                case '<': +                case '>': +                case '\'': +                    UnsafeWriteRawBytes(beg, cur - beg); +                    WriteHexEscape(c); +                    return true; +            } +            // for other characters, fall through to the non-escaped part          } -        switch (c) {  +        switch (c) {              MATCH('"', "\\\"");              MATCH('\\', "\\\\");              MATCH('\b', "\\b"); @@ -366,152 +366,152 @@ namespace NJsonWriter {              MATCH('\n', "\\n");              MATCH('\r', "\\r");              MATCH('\t', "\\t"); -        }  -        if (c < 0x20) {  -            UnsafeWriteRawBytes(beg, cur - beg);  -            WriteHexEscape(c);  -            return true;  -        }  -  -        return false;  +        } +        if (c < 0x20) { +            UnsafeWriteRawBytes(beg, cur - beg); +            WriteHexEscape(c); +            return true; +        } + +        return false;      }  #undef MATCH -    static bool LessStrPtr(const TString* a, const TString* b) {  -        return *a < *b;  -    }  +    static bool LessStrPtr(const TString* a, const TString* b) { +        return *a < *b; +    }      TValueContext TBuf::WriteJsonValue(const NJson::TJsonValue* v, bool sortKeys, EFloatToStringMode mode, int ndigits) { -        using namespace NJson;  -        switch (v->GetType()) {  -            default:  -            case JSON_NULL:  -                WriteNull();  -                break;  -            case JSON_BOOLEAN:  -                WriteBool(v->GetBoolean());  -                break;  -            case JSON_DOUBLE:  +        using namespace NJson; +        switch (v->GetType()) { +            default: +            case JSON_NULL: +                WriteNull(); +                break; +            case JSON_BOOLEAN: +                WriteBool(v->GetBoolean()); +                break; +            case JSON_DOUBLE:                  WriteDouble(v->GetDouble(), mode, ndigits); -                break;  -            case JSON_INTEGER:  -                WriteLongLong(v->GetInteger());  -                break;  -            case JSON_UINTEGER:  -                WriteULongLong(v->GetUInteger());  -                break;  -            case JSON_STRING:  -                WriteString(v->GetString());  -                break;  -            case JSON_ARRAY: {  -                BeginList();  -                const TJsonValue::TArray& arr = v->GetArray();  -                for (const auto& it : arr)  +                break; +            case JSON_INTEGER: +                WriteLongLong(v->GetInteger()); +                break; +            case JSON_UINTEGER: +                WriteULongLong(v->GetUInteger()); +                break; +            case JSON_STRING: +                WriteString(v->GetString()); +                break; +            case JSON_ARRAY: { +                BeginList(); +                const TJsonValue::TArray& arr = v->GetArray(); +                for (const auto& it : arr)                      WriteJsonValue(&it, sortKeys, mode, ndigits); -                EndList();  -                break;  +                EndList(); +                break;              } -            case JSON_MAP: {  -                BeginObject();  -                const TJsonValue::TMapType& map = v->GetMap();  -                if (sortKeys) {  -                    const size_t oldsz = Keys.size();  -                    Keys.reserve(map.size() + oldsz);  -                    for (const auto& it : map) {  -                        Keys.push_back(&(it.first));  -                    }  -                    Sort(Keys.begin() + oldsz, Keys.end(), LessStrPtr);  -                    for (size_t i = oldsz, sz = Keys.size(); i < sz; ++i) {  -                        TJsonValue::TMapType::const_iterator kv = map.find(*Keys[i]);  -                        WriteKey(kv->first);  +            case JSON_MAP: { +                BeginObject(); +                const TJsonValue::TMapType& map = v->GetMap(); +                if (sortKeys) { +                    const size_t oldsz = Keys.size(); +                    Keys.reserve(map.size() + oldsz); +                    for (const auto& it : map) { +                        Keys.push_back(&(it.first)); +                    } +                    Sort(Keys.begin() + oldsz, Keys.end(), LessStrPtr); +                    for (size_t i = oldsz, sz = Keys.size(); i < sz; ++i) { +                        TJsonValue::TMapType::const_iterator kv = map.find(*Keys[i]); +                        WriteKey(kv->first);                          WriteJsonValue(&kv->second, sortKeys, mode, ndigits); -                    }  -                    Keys.resize(oldsz);  -                } else {  -                    for (const auto& it : map) {  -                        WriteKey(it.first);  +                    } +                    Keys.resize(oldsz); +                } else { +                    for (const auto& it : map) { +                        WriteKey(it.first);                          WriteJsonValue(&it.second, sortKeys, mode, ndigits); -                    }  -                }  -                EndObject();  -                break;  +                    } +                } +                EndObject(); +                break;              }          } -        return TValueContext(*this);  +        return TValueContext(*this);      } -  -    TPairContext TBuf::UnsafeWritePair(const TStringBuf& s) {  -        if (Y_UNLIKELY(StackTop() != JE_OBJECT)) {  -            ythrow TError() << "JSON writer: key:value pair written outside of an object";  -        }  -        WriteComma();  -        UnsafeWriteRawBytes(s);  -        return TPairContext(*this);  + +    TPairContext TBuf::UnsafeWritePair(const TStringBuf& s) { +        if (Y_UNLIKELY(StackTop() != JE_OBJECT)) { +            ythrow TError() << "JSON writer: key:value pair written outside of an object"; +        } +        WriteComma(); +        UnsafeWriteRawBytes(s); +        return TPairContext(*this);      } -    void TBuf::UnsafeWriteValue(const TStringBuf& s) {  -        BeginValue();  -        UnsafeWriteRawBytes(s);  -        EndValue();  +    void TBuf::UnsafeWriteValue(const TStringBuf& s) { +        BeginValue(); +        UnsafeWriteRawBytes(s); +        EndValue();      } -    void TBuf::UnsafeWriteValue(const char* s, size_t len) {  -        BeginValue();  -        UnsafeWriteRawBytes(s, len);  -        EndValue();  -    }  +    void TBuf::UnsafeWriteValue(const char* s, size_t len) { +        BeginValue(); +        UnsafeWriteRawBytes(s, len); +        EndValue(); +    } -    void TBuf::UnsafeWriteRawBytes(const char* src, size_t len) {  -        Stream->Write(src, len);  -    }  +    void TBuf::UnsafeWriteRawBytes(const char* src, size_t len) { +        Stream->Write(src, len); +    } -    void TBuf::UnsafeWriteRawBytes(const TStringBuf& s) {  +    void TBuf::UnsafeWriteRawBytes(const TStringBuf& s) {          UnsafeWriteRawBytes(s.data(), s.size()); -    }  - -    const TString& TBuf::Str() const {  -        if (!StringStream) {  -            ythrow TError() << "JSON writer: Str() called "  -                               "but writing to an external stream";  -        }  -        if (!(Stack.size() == 1 && StackTop() == JE_OUTER_SPACE)) {  -            ythrow TError() << "JSON writer: incomplete object converted to string";  -        }  -        return StringStream->Str();  -    }  - -    void TBuf::FlushTo(IOutputStream* stream) {  -        if (!StringStream) {  -            ythrow TError() << "JSON writer: FlushTo() called "  -                               "but writing to an external stream";  -        }  -        stream->Write(StringStream->Str());  -        StringStream->Clear();  -    } -  -    TString WrapJsonToCallback(const TBuf& buf, TStringBuf callback) {  -        if (!callback) {  -            return buf.Str();  -        } else {  -            return TString::Join(callback, "(", buf.Str(), ")");  -        }  -    } - -    TBufState TBuf::State() const {  -        return TBufState{NeedComma, NeedNewline, Stack};  -    } - -    void TBuf::Reset(const TBufState& from) {  -        NeedComma = from.NeedComma;  -        NeedNewline = from.NeedNewline;  -        Stack = from.Stack;  -    } - -    void TBuf::Reset(TBufState&& from) {  -        NeedComma = from.NeedComma;  -        NeedNewline = from.NeedNewline;  -        Stack.swap(from.Stack);  -    }  +    } + +    const TString& TBuf::Str() const { +        if (!StringStream) { +            ythrow TError() << "JSON writer: Str() called " +                               "but writing to an external stream"; +        } +        if (!(Stack.size() == 1 && StackTop() == JE_OUTER_SPACE)) { +            ythrow TError() << "JSON writer: incomplete object converted to string"; +        } +        return StringStream->Str(); +    } + +    void TBuf::FlushTo(IOutputStream* stream) { +        if (!StringStream) { +            ythrow TError() << "JSON writer: FlushTo() called " +                               "but writing to an external stream"; +        } +        stream->Write(StringStream->Str()); +        StringStream->Clear(); +    } + +    TString WrapJsonToCallback(const TBuf& buf, TStringBuf callback) { +        if (!callback) { +            return buf.Str(); +        } else { +            return TString::Join(callback, "(", buf.Str(), ")"); +        } +    } + +    TBufState TBuf::State() const { +        return TBufState{NeedComma, NeedNewline, Stack}; +    } + +    void TBuf::Reset(const TBufState& from) { +        NeedComma = from.NeedComma; +        NeedNewline = from.NeedNewline; +        Stack = from.Stack; +    } + +    void TBuf::Reset(TBufState&& from) { +        NeedComma = from.NeedComma; +        NeedNewline = from.NeedNewline; +        Stack.swap(from.Stack); +    }  } diff --git a/library/cpp/json/writer/json.h b/library/cpp/json/writer/json.h index eca04a510a4..0aae2531b94 100644 --- a/library/cpp/json/writer/json.h +++ b/library/cpp/json/writer/json.h @@ -39,7 +39,7 @@ namespace NJsonWriter {          TVector<EJsonEntity> Stack;      }; -    class TBuf : TNonCopyable {  +    class TBuf : TNonCopyable {      public:          TBuf(EHtmlEscapeMode mode = HEM_DONT_ESCAPE_HTML, IOutputStream* stream = nullptr); @@ -183,8 +183,8 @@ namespace NJsonWriter {      protected:          TValueWriter(TBuf& buf)              : Buf(buf) -        {  -        }  +        { +        }          friend class TBuf;      protected: @@ -196,25 +196,25 @@ namespace NJsonWriter {          TBuf& EndList() {              return Buf.EndList();          } -        TString Str() const {  -            return Buf.Str();  -        }  -  +        TString Str() const { +            return Buf.Str(); +        } +      private:          TValueContext(TBuf& buf)              : TValueWriter<TValueContext>(buf) -        {  -        }  +        { +        }          friend class TBuf;          friend class TValueWriter<TValueContext>;      };      class TAfterColonContext: public TValueWriter<TPairContext> {      private: -        TAfterColonContext(TBuf& iBuf)  -            : TValueWriter<TPairContext>(iBuf)  -        {  -        }  +        TAfterColonContext(TBuf& iBuf) +            : TValueWriter<TPairContext>(iBuf) +        { +        }          friend class TBuf;          friend class TPairContext;      }; @@ -275,15 +275,15 @@ namespace NJsonWriter {      JSON_VALUE_WRITER_WRAP(UnsafeWriteValue, (const TStringBuf& arg), (arg))  #undef JSON_VALUE_WRITER_WRAP -    template <typename TOutContext>  -    TValueContext TValueWriter<TOutContext>::BeginList() {  +    template <typename TOutContext> +    TValueContext TValueWriter<TOutContext>::BeginList() {          return Buf.BeginList();      } -    template <typename TOutContext>  -    TPairContext TValueWriter<TOutContext>::BeginObject() {  +    template <typename TOutContext> +    TPairContext TValueWriter<TOutContext>::BeginObject() {          return Buf.BeginObject();      } -    TString WrapJsonToCallback(const TBuf& buf, TStringBuf callback);  +    TString WrapJsonToCallback(const TBuf& buf, TStringBuf callback);  } diff --git a/library/cpp/json/writer/json_ut.cpp b/library/cpp/json/writer/json_ut.cpp index e8d0be35660..9980555683f 100644 --- a/library/cpp/json/writer/json_ut.cpp +++ b/library/cpp/json/writer/json_ut.cpp @@ -16,12 +16,12 @@ Y_UNIT_TEST_SUITE(JsonWriter) {              .UnsafeWritePair("\"xk\":13")              .WriteKey("key2")              .BeginList() -            .BeginObject()  -            .EndObject()  -            .BeginObject()  -            .EndObject()  +            .BeginObject() +            .EndObject() +            .BeginObject() +            .EndObject()              .EndList() -            .EndObject();  +            .EndObject();          w.WriteInt(43);          w.UnsafeWriteValue("\"x\"");          w.WriteString("..."); @@ -75,11 +75,11 @@ Y_UNIT_TEST_SUITE(JsonWriter) {      Y_UNIT_TEST(BareKey) {          NJsonWriter::TBuf w;          w.BeginObject() -            .CompatWriteKeyWithoutQuotes("p")  -            .WriteInt(1)  -            .CompatWriteKeyWithoutQuotes("n")  -            .WriteInt(0)  -            .EndObject();  +            .CompatWriteKeyWithoutQuotes("p") +            .WriteInt(1) +            .CompatWriteKeyWithoutQuotes("n") +            .WriteInt(0) +            .EndObject();          TString ws = w.Str();          const char* exp = "{p:1,n:0}";          UNIT_ASSERT_STRINGS_EQUAL(ws.c_str(), exp); @@ -108,12 +108,12 @@ Y_UNIT_TEST_SUITE(JsonWriter) {              .WriteInt(1)              .WriteString("hello")              .BeginObject() -            .WriteKey("abc")  -            .WriteInt(3)  -            .WriteKey("def")  -            .WriteInt(4)  +            .WriteKey("abc") +            .WriteInt(3) +            .WriteKey("def") +            .WriteInt(4)              .EndObject() -            .EndList();  +            .EndList();          const char* exp = "[\n"                            "  1,\n"                            "  \"hello\",\n" @@ -196,12 +196,12 @@ Y_UNIT_TEST_SUITE(JsonWriter) {              .WriteFloat(244.13854, PREC_NDIGITS, 4)              .WriteFloat(10385.8324, PREC_POINT_DIGITS, 2)              .BeginObject() -            .WriteKey("1")  -            .WriteDouble(1111.71, PREC_POINT_DIGITS, 0)  -            .WriteKey("2")  -            .WriteDouble(1111.71, PREC_NDIGITS, 1)  +            .WriteKey("1") +            .WriteDouble(1111.71, PREC_POINT_DIGITS, 0) +            .WriteKey("2") +            .WriteDouble(1111.71, PREC_NDIGITS, 1)              .EndObject() -            .EndList();  +            .EndList();          const char exp[] = "[0.123457,0.1234567899,0.316,244.1,10385.83,{\"1\":1112,\"2\":1e+03}]";          UNIT_ASSERT_STRINGS_EQUAL(exp, buf.Str());      } @@ -238,17 +238,17 @@ Y_UNIT_TEST_SUITE(JsonWriter) {              buf.SetWriteNanAsString();              buf.BeginObject() -                .WriteKey("nanvalue")  -                .WriteFloat(std::numeric_limits<double>::quiet_NaN())  -                .WriteKey("infvalue")  -                .WriteFloat(std::numeric_limits<double>::infinity())  -                .WriteKey("minus_infvalue")  -                .WriteFloat(-std::numeric_limits<float>::infinity())  +                .WriteKey("nanvalue") +                .WriteFloat(std::numeric_limits<double>::quiet_NaN()) +                .WriteKey("infvalue") +                .WriteFloat(std::numeric_limits<double>::infinity()) +                .WriteKey("minus_infvalue") +                .WriteFloat(-std::numeric_limits<float>::infinity())                  .WriteKey("l") -                .BeginList()  -                .WriteFloat(std::numeric_limits<float>::quiet_NaN())  -                .EndList()  -                .EndObject();  +                .BeginList() +                .WriteFloat(std::numeric_limits<float>::quiet_NaN()) +                .EndList() +                .EndObject();              UNIT_ASSERT_STRINGS_EQUAL(buf.Str(), R"raw_json({"nanvalue":"nan","infvalue":"inf","minus_infvalue":"-inf","l":["nan"]})raw_json");          } @@ -256,11 +256,11 @@ Y_UNIT_TEST_SUITE(JsonWriter) {          {              NJsonWriter::TBuf buf;              buf.BeginObject() -                .WriteKey("<>&")  -                .WriteString("Ololo")  -                .UnsafeWriteKey("<>&")  -                .WriteString("Ololo2")  -                .EndObject();  +                .WriteKey("<>&") +                .WriteString("Ololo") +                .UnsafeWriteKey("<>&") +                .WriteString("Ololo2") +                .EndObject();              UNIT_ASSERT_STRINGS_EQUAL(buf.Str(), R"({"\u003C\u003E&":"Ololo","<>&":"Ololo2"})");          } diff --git a/library/cpp/json/writer/json_value.cpp b/library/cpp/json/writer/json_value.cpp index 4e85a6bc08f..c61e8d1dc43 100644 --- a/library/cpp/json/writer/json_value.cpp +++ b/library/cpp/json/writer/json_value.cpp @@ -1,12 +1,12 @@  #include "json_value.h"  #include "json.h" -#include <util/generic/ymath.h>  +#include <util/generic/ymath.h>  #include <util/generic/ylimits.h>  #include <util/generic/utility.h> -#include <util/generic/singleton.h>  +#include <util/generic/singleton.h>  #include <util/stream/str.h> -#include <util/stream/output.h>  +#include <util/stream/output.h>  #include <util/string/cast.h>  #include <util/string/type.h>  #include <util/string/vector.h> @@ -59,7 +59,7 @@ AreJsonArraysEqual(const NJson::TJsonValue& lhs, const NJson::TJsonValue& rhs) {          return false;      for (TArray::const_iterator lhsIt = lhsArray.begin(), rhsIt = rhsArray.begin(); -         lhsIt != lhsArray.end(); ++lhsIt, ++rhsIt) {  +         lhsIt != lhsArray.end(); ++lhsIt, ++rhsIt) {          if (*lhsIt != *rhsIt)              return false;      } @@ -68,926 +68,926 @@ AreJsonArraysEqual(const NJson::TJsonValue& lhs, const NJson::TJsonValue& rhs) {  }  namespace NJson { -    const TJsonValue TJsonValue::UNDEFINED{};  - -    TJsonValue::TJsonValue(const EJsonValueType type) {  -        SetType(type);  -    }  - -    TJsonValue::TJsonValue(TJsonValue&& vval) noexcept  -        : Type(JSON_UNDEFINED)  -    {  -        vval.SwapWithUndefined(*this);  -        Zero(vval.Value);  -    }  - -    TJsonValue::TJsonValue(const TJsonValue& val)  -        : Type(val.Type)  -    {  -        switch (Type) {  -            case JSON_STRING:  -                new (&Value.String) TString(val.GetString());  -                break;  -            case JSON_MAP:  -                Value.Map = new TMapType(val.GetMap());  -                break;  -            case JSON_ARRAY:  -                Value.Array = new TArray(val.GetArray());  -                break;  -            case JSON_UNDEFINED:  -            case JSON_NULL:  -            case JSON_BOOLEAN:  -            case JSON_INTEGER:  -            case JSON_UINTEGER:  -            case JSON_DOUBLE:  -                std::memcpy(&Value, &val.Value, sizeof(Value));  -                break;  -        }  -    } - -    TJsonValue& TJsonValue::operator=(const TJsonValue& val) {  -        if (this == &val)  -            return *this;  -        TJsonValue tmp(val);  -        tmp.Swap(*this);  +    const TJsonValue TJsonValue::UNDEFINED{}; + +    TJsonValue::TJsonValue(const EJsonValueType type) { +        SetType(type); +    } + +    TJsonValue::TJsonValue(TJsonValue&& vval) noexcept +        : Type(JSON_UNDEFINED) +    { +        vval.SwapWithUndefined(*this); +        Zero(vval.Value); +    } + +    TJsonValue::TJsonValue(const TJsonValue& val) +        : Type(val.Type) +    { +        switch (Type) { +            case JSON_STRING: +                new (&Value.String) TString(val.GetString()); +                break; +            case JSON_MAP: +                Value.Map = new TMapType(val.GetMap()); +                break; +            case JSON_ARRAY: +                Value.Array = new TArray(val.GetArray()); +                break; +            case JSON_UNDEFINED: +            case JSON_NULL: +            case JSON_BOOLEAN: +            case JSON_INTEGER: +            case JSON_UINTEGER: +            case JSON_DOUBLE: +                std::memcpy(&Value, &val.Value, sizeof(Value)); +                break; +        } +    } + +    TJsonValue& TJsonValue::operator=(const TJsonValue& val) { +        if (this == &val) +            return *this; +        TJsonValue tmp(val); +        tmp.Swap(*this);          return *this; -    }  +    } -    TJsonValue& TJsonValue::operator=(TJsonValue&& val) noexcept {  -        if (this == &val)  -            return *this;  -        TJsonValue tmp(std::move(val));  -        tmp.Swap(*this);  +    TJsonValue& TJsonValue::operator=(TJsonValue&& val) noexcept { +        if (this == &val) +            return *this; +        TJsonValue tmp(std::move(val)); +        tmp.Swap(*this);          return *this; -    }  - -    TJsonValue::TJsonValue(const bool value) noexcept {  -        SetType(JSON_BOOLEAN);  -        Value.Boolean = value;  -    }  - -    TJsonValue::TJsonValue(const long long value) noexcept {  -        SetType(JSON_INTEGER);  -        Value.Integer = value;  -    }  - -    TJsonValue::TJsonValue(const unsigned long long value) noexcept {  -        SetType(JSON_UINTEGER);  -        Value.UInteger = value;  -    }  - -    TJsonValue::TJsonValue(const int value) noexcept {  -        SetType(JSON_INTEGER);  -        Value.Integer = value;  -    }  - -    TJsonValue::TJsonValue(const unsigned int value) noexcept {  -        SetType(JSON_UINTEGER);  -        Value.UInteger = value;  -    }  - -    TJsonValue::TJsonValue(const long value) noexcept {  -        SetType(JSON_INTEGER);  -        Value.Integer = value;  -    }  - -    TJsonValue::TJsonValue(const unsigned long value) noexcept {  -        SetType(JSON_UINTEGER);  -        Value.UInteger = value;  -    }  - -    TJsonValue::TJsonValue(const double value) noexcept {  -        SetType(JSON_DOUBLE);  -        Value.Double = value;  -    }  +    } + +    TJsonValue::TJsonValue(const bool value) noexcept { +        SetType(JSON_BOOLEAN); +        Value.Boolean = value; +    } + +    TJsonValue::TJsonValue(const long long value) noexcept { +        SetType(JSON_INTEGER); +        Value.Integer = value; +    } + +    TJsonValue::TJsonValue(const unsigned long long value) noexcept { +        SetType(JSON_UINTEGER); +        Value.UInteger = value; +    } + +    TJsonValue::TJsonValue(const int value) noexcept { +        SetType(JSON_INTEGER); +        Value.Integer = value; +    } + +    TJsonValue::TJsonValue(const unsigned int value) noexcept { +        SetType(JSON_UINTEGER); +        Value.UInteger = value; +    } + +    TJsonValue::TJsonValue(const long value) noexcept { +        SetType(JSON_INTEGER); +        Value.Integer = value; +    } + +    TJsonValue::TJsonValue(const unsigned long value) noexcept { +        SetType(JSON_UINTEGER); +        Value.UInteger = value; +    } + +    TJsonValue::TJsonValue(const double value) noexcept { +        SetType(JSON_DOUBLE); +        Value.Double = value; +    }      TJsonValue::TJsonValue(TString value) { -        SetType(JSON_STRING);  -        Value.String = std::move(value);  -    }  - -    TJsonValue::TJsonValue(const TStringBuf value) {  -        SetType(JSON_STRING);  -        Value.String = value;  -    }  - -    TJsonValue::TJsonValue(const char* value) {  -        SetType(JSON_STRING);  -        Value.String = value;  -    }  - -    EJsonValueType TJsonValue::GetType() const noexcept {  -        return Type;  -    }  - -    TJsonValue& TJsonValue::SetType(const EJsonValueType type) {  -        if (Type == type)  -            return *this;  - -        Clear();  -        Type = type;  - -        switch (Type) {  -            case JSON_STRING:  -                new (&Value.String) TString();  -                break;  -            case JSON_MAP:  -                Value.Map = new TMapType();  -                break;  -            case JSON_ARRAY:  -                Value.Array = new TArray();  -                break;  -            case JSON_UNDEFINED:  -            case JSON_NULL:  -            case JSON_BOOLEAN:  -            case JSON_INTEGER:  -            case JSON_UINTEGER:  -            case JSON_DOUBLE:  -                break;  -        }  -  -        return *this;  -    } - -    TJsonValue& TJsonValue::SetValue(const TJsonValue& value) {  -        return *this = value;  -    }  - -    TJsonValue& TJsonValue::SetValue(TJsonValue&& value) {  -        *this = std::move(value);  -        return *this;  -    }  - -    TJsonValue& TJsonValue::InsertValue(const TString& key, const TJsonValue& value) {  -        SetType(JSON_MAP);  -        return (*Value.Map)[key] = value;  -    }  - -    TJsonValue& TJsonValue::InsertValue(const TStringBuf key, const TJsonValue& value) {  -        SetType(JSON_MAP);  -        return (*Value.Map)[key] = value;  -    }  - -    TJsonValue& TJsonValue::InsertValue(const char* key, const TJsonValue& value) {  -        SetType(JSON_MAP);  -        return (*Value.Map)[key] = value;  -    }  - -    TJsonValue& TJsonValue::InsertValue(const TString& key, TJsonValue&& value) {  -        SetType(JSON_MAP);  -        return (*Value.Map)[key] = std::move(value);  -    }  - -    TJsonValue& TJsonValue::InsertValue(const TStringBuf key, TJsonValue&& value) {  -        SetType(JSON_MAP);  -        return (*Value.Map)[key] = std::move(value);  -    }  - -    TJsonValue& TJsonValue::InsertValue(const char* key, TJsonValue&& value) {  -        SetType(JSON_MAP);  -        return (*Value.Map)[key] = std::move(value);  -    }  - -    TJsonValue& TJsonValue::Back() {  +        SetType(JSON_STRING); +        Value.String = std::move(value); +    } + +    TJsonValue::TJsonValue(const TStringBuf value) { +        SetType(JSON_STRING); +        Value.String = value; +    } + +    TJsonValue::TJsonValue(const char* value) { +        SetType(JSON_STRING); +        Value.String = value; +    } + +    EJsonValueType TJsonValue::GetType() const noexcept { +        return Type; +    } + +    TJsonValue& TJsonValue::SetType(const EJsonValueType type) { +        if (Type == type) +            return *this; + +        Clear(); +        Type = type; + +        switch (Type) { +            case JSON_STRING: +                new (&Value.String) TString(); +                break; +            case JSON_MAP: +                Value.Map = new TMapType(); +                break; +            case JSON_ARRAY: +                Value.Array = new TArray(); +                break; +            case JSON_UNDEFINED: +            case JSON_NULL: +            case JSON_BOOLEAN: +            case JSON_INTEGER: +            case JSON_UINTEGER: +            case JSON_DOUBLE: +                break; +        } + +        return *this; +    } + +    TJsonValue& TJsonValue::SetValue(const TJsonValue& value) { +        return *this = value; +    } + +    TJsonValue& TJsonValue::SetValue(TJsonValue&& value) { +        *this = std::move(value); +        return *this; +    } + +    TJsonValue& TJsonValue::InsertValue(const TString& key, const TJsonValue& value) { +        SetType(JSON_MAP); +        return (*Value.Map)[key] = value; +    } + +    TJsonValue& TJsonValue::InsertValue(const TStringBuf key, const TJsonValue& value) { +        SetType(JSON_MAP); +        return (*Value.Map)[key] = value; +    } + +    TJsonValue& TJsonValue::InsertValue(const char* key, const TJsonValue& value) { +        SetType(JSON_MAP); +        return (*Value.Map)[key] = value; +    } + +    TJsonValue& TJsonValue::InsertValue(const TString& key, TJsonValue&& value) { +        SetType(JSON_MAP); +        return (*Value.Map)[key] = std::move(value); +    } + +    TJsonValue& TJsonValue::InsertValue(const TStringBuf key, TJsonValue&& value) { +        SetType(JSON_MAP); +        return (*Value.Map)[key] = std::move(value); +    } + +    TJsonValue& TJsonValue::InsertValue(const char* key, TJsonValue&& value) { +        SetType(JSON_MAP); +        return (*Value.Map)[key] = std::move(value); +    } + +    TJsonValue& TJsonValue::Back() {          BackChecks();          return Value.Array->back();      }      const TJsonValue& TJsonValue::Back() const {          BackChecks(); -        return Value.Array->back();  -    }  - -    TJsonValue& TJsonValue::AppendValue(const TJsonValue& value) {  -        SetType(JSON_ARRAY);  -        Value.Array->push_back(value);  -        return Value.Array->back();  -    }  - -    TJsonValue& TJsonValue::AppendValue(TJsonValue&& value) {  -        SetType(JSON_ARRAY);  -        Value.Array->push_back(std::move(value));  -        return Value.Array->back();  -    }  - -    void TJsonValue::EraseValue(const TStringBuf key) {  -        if (IsMap()) {  -            TMapType::iterator it = Value.Map->find(key);  -            if (it != Value.Map->end())  -                Value.Map->erase(it);  -        }  -    }  - -    void TJsonValue::EraseValue(const size_t index) {  -        if (IsArray()) {  -            if (index >= Value.Array->size()) {  -                return;  -            }  -            TArray::iterator it = Value.Array->begin() + index;  -            Value.Array->erase(it);  -        }  -    } - -    void TJsonValue::Clear() noexcept {  -        switch (Type) {  -            case JSON_STRING:  -                Value.String.~TString();  -                break;  -            case JSON_MAP:  -                delete Value.Map;  -                break;  -            case JSON_ARRAY:  -                delete Value.Array;  -                break;  -            case JSON_UNDEFINED:  -            case JSON_NULL:  -            case JSON_BOOLEAN:  -            case JSON_INTEGER:  -            case JSON_UINTEGER:  -            case JSON_DOUBLE:  -                break;  +        return Value.Array->back(); +    } + +    TJsonValue& TJsonValue::AppendValue(const TJsonValue& value) { +        SetType(JSON_ARRAY); +        Value.Array->push_back(value); +        return Value.Array->back(); +    } + +    TJsonValue& TJsonValue::AppendValue(TJsonValue&& value) { +        SetType(JSON_ARRAY); +        Value.Array->push_back(std::move(value)); +        return Value.Array->back(); +    } + +    void TJsonValue::EraseValue(const TStringBuf key) { +        if (IsMap()) { +            TMapType::iterator it = Value.Map->find(key); +            if (it != Value.Map->end()) +                Value.Map->erase(it);          } -        Zero(Value);  -        Type = JSON_UNDEFINED;       } -    TJsonValue& TJsonValue::operator[](const size_t idx) {  -        SetType(JSON_ARRAY);  -        if (Value.Array->size() <= idx)  -            Value.Array->resize(idx + 1);  -        return (*Value.Array)[idx];  -    }  +    void TJsonValue::EraseValue(const size_t index) { +        if (IsArray()) { +            if (index >= Value.Array->size()) { +                return; +            } +            TArray::iterator it = Value.Array->begin() + index; +            Value.Array->erase(it); +        } +    } -    TJsonValue& TJsonValue::operator[](const TStringBuf& key) {  -        SetType(JSON_MAP);  -        return (*Value.Map)[key];  +    void TJsonValue::Clear() noexcept { +        switch (Type) { +            case JSON_STRING: +                Value.String.~TString(); +                break; +            case JSON_MAP: +                delete Value.Map; +                break; +            case JSON_ARRAY: +                delete Value.Array; +                break; +            case JSON_UNDEFINED: +            case JSON_NULL: +            case JSON_BOOLEAN: +            case JSON_INTEGER: +            case JSON_UINTEGER: +            case JSON_DOUBLE: +                break; +        } +        Zero(Value); +        Type = JSON_UNDEFINED;      } -    namespace {  -        struct TDefaultsHolder {  -            const TString String{};  -            const TJsonValue::TMapType Map{};  -            const TJsonValue::TArray Array{};  -            const TJsonValue Value{};  -        };  -    }  +    TJsonValue& TJsonValue::operator[](const size_t idx) { +        SetType(JSON_ARRAY); +        if (Value.Array->size() <= idx) +            Value.Array->resize(idx + 1); +        return (*Value.Array)[idx]; +    } -    const TJsonValue& TJsonValue::operator[](const size_t idx) const noexcept {  -        const TJsonValue* ret = nullptr;  -        if (GetValuePointer(idx, &ret))  -            return *ret;  +    TJsonValue& TJsonValue::operator[](const TStringBuf& key) { +        SetType(JSON_MAP); +        return (*Value.Map)[key]; +    } -        return Singleton<TDefaultsHolder>()->Value;  -    }  +    namespace { +        struct TDefaultsHolder { +            const TString String{}; +            const TJsonValue::TMapType Map{}; +            const TJsonValue::TArray Array{}; +            const TJsonValue Value{}; +        }; +    } -    const TJsonValue& TJsonValue::operator[](const TStringBuf& key) const noexcept {  -        const TJsonValue* ret = nullptr;  -        if (GetValuePointer(key, &ret))  -            return *ret;  +    const TJsonValue& TJsonValue::operator[](const size_t idx) const noexcept { +        const TJsonValue* ret = nullptr; +        if (GetValuePointer(idx, &ret)) +            return *ret; -        return Singleton<TDefaultsHolder>()->Value;  -    }  +        return Singleton<TDefaultsHolder>()->Value; +    } -    bool TJsonValue::GetBoolean() const {  -        return Type != JSON_BOOLEAN ? false : Value.Boolean;  -    }  +    const TJsonValue& TJsonValue::operator[](const TStringBuf& key) const noexcept { +        const TJsonValue* ret = nullptr; +        if (GetValuePointer(key, &ret)) +            return *ret; -    long long TJsonValue::GetInteger() const {  -        if (!IsInteger())  -            return 0;  +        return Singleton<TDefaultsHolder>()->Value; +    } -        switch (Type) {  -            case JSON_INTEGER:  -                return Value.Integer;  +    bool TJsonValue::GetBoolean() const { +        return Type != JSON_BOOLEAN ? false : Value.Boolean; +    } -            case JSON_UINTEGER:  -                return Value.UInteger;  +    long long TJsonValue::GetInteger() const { +        if (!IsInteger()) +            return 0; -            case JSON_DOUBLE:  -                return Value.Double;  +        switch (Type) { +            case JSON_INTEGER: +                return Value.Integer; + +            case JSON_UINTEGER: +                return Value.UInteger; + +            case JSON_DOUBLE: +                return Value.Double; -            default:  -                Y_ASSERT(false && "Unexpected type.");  -                return 0;  -        }  +            default: +                Y_ASSERT(false && "Unexpected type."); +                return 0; +        }      } -    unsigned long long TJsonValue::GetUInteger() const {  -        if (!IsUInteger())  -            return 0;  +    unsigned long long TJsonValue::GetUInteger() const { +        if (!IsUInteger()) +            return 0; -        switch (Type) {  -            case JSON_UINTEGER:  -                return Value.UInteger;  +        switch (Type) { +            case JSON_UINTEGER: +                return Value.UInteger; -            case JSON_INTEGER:  -                return Value.Integer;  +            case JSON_INTEGER: +                return Value.Integer; -            case JSON_DOUBLE:  -                return Value.Double;  +            case JSON_DOUBLE: +                return Value.Double; -            default:  -                Y_ASSERT(false && "Unexpected type.");  -                return 0;  -        }  +            default: +                Y_ASSERT(false && "Unexpected type."); +                return 0; +        }      } -    double TJsonValue::GetDouble() const {  -        if (!IsDouble())  -            return 0.0;  +    double TJsonValue::GetDouble() const { +        if (!IsDouble()) +            return 0.0; -        switch (Type) {  -            case JSON_DOUBLE:  -                return Value.Double;  +        switch (Type) { +            case JSON_DOUBLE: +                return Value.Double; -            case JSON_INTEGER:  -                return Value.Integer;  +            case JSON_INTEGER: +                return Value.Integer; -            case JSON_UINTEGER:  -                return Value.UInteger;  +            case JSON_UINTEGER: +                return Value.UInteger; -            default:  -                Y_ASSERT(false && "Unexpected type.");  -                return 0.0;  -        }  +            default: +                Y_ASSERT(false && "Unexpected type."); +                return 0.0; +        }      } -    const TString& TJsonValue::GetString() const {  -        return Type != JSON_STRING ? Singleton<TDefaultsHolder>()->String : Value.String;  -    }  +    const TString& TJsonValue::GetString() const { +        return Type != JSON_STRING ? Singleton<TDefaultsHolder>()->String : Value.String; +    } -    const TJsonValue::TMapType& TJsonValue::GetMap() const {  -        return Type != JSON_MAP ? Singleton<TDefaultsHolder>()->Map : *Value.Map;  -    }  +    const TJsonValue::TMapType& TJsonValue::GetMap() const { +        return Type != JSON_MAP ? Singleton<TDefaultsHolder>()->Map : *Value.Map; +    } -    const TJsonValue::TArray& TJsonValue::GetArray() const {  -        return (Type != JSON_ARRAY) ? Singleton<TDefaultsHolder>()->Array : *Value.Array;  -    }  +    const TJsonValue::TArray& TJsonValue::GetArray() const { +        return (Type != JSON_ARRAY) ? Singleton<TDefaultsHolder>()->Array : *Value.Array; +    } -    bool TJsonValue::GetBooleanSafe() const {  -        if (Type != JSON_BOOLEAN)  -            ythrow TJsonException() << "Not a boolean";  +    bool TJsonValue::GetBooleanSafe() const { +        if (Type != JSON_BOOLEAN) +            ythrow TJsonException() << "Not a boolean"; -        return Value.Boolean;  -    }  +        return Value.Boolean; +    } -    long long TJsonValue::GetIntegerSafe() const {  -        if (!IsInteger())  -            ythrow TJsonException() << "Not an integer";  +    long long TJsonValue::GetIntegerSafe() const { +        if (!IsInteger()) +            ythrow TJsonException() << "Not an integer"; -        return GetInteger();  -    }  +        return GetInteger(); +    } -    unsigned long long TJsonValue::GetUIntegerSafe() const {  -        if (!IsUInteger())  -            ythrow TJsonException() << "Not an unsigned integer";  +    unsigned long long TJsonValue::GetUIntegerSafe() const { +        if (!IsUInteger()) +            ythrow TJsonException() << "Not an unsigned integer"; -        return GetUInteger();  -    }  +        return GetUInteger(); +    } -    double TJsonValue::GetDoubleSafe() const {  -        if (!IsDouble())  -            ythrow TJsonException() << "Not a double";  +    double TJsonValue::GetDoubleSafe() const { +        if (!IsDouble()) +            ythrow TJsonException() << "Not a double"; -        return GetDouble();  -    }  +        return GetDouble(); +    } -    const TString& TJsonValue::GetStringSafe() const {  -        if (Type != JSON_STRING)  -            ythrow TJsonException() << "Not a string";  +    const TString& TJsonValue::GetStringSafe() const { +        if (Type != JSON_STRING) +            ythrow TJsonException() << "Not a string"; -        return Value.String;  -    }  +        return Value.String; +    } -    bool TJsonValue::GetBooleanSafe(const bool defaultValue) const {  -        if (Type == JSON_UNDEFINED)  -            return defaultValue;  +    bool TJsonValue::GetBooleanSafe(const bool defaultValue) const { +        if (Type == JSON_UNDEFINED) +            return defaultValue; -        return GetBooleanSafe();  -    }  +        return GetBooleanSafe(); +    } -    long long TJsonValue::GetIntegerSafe(const long long defaultValue) const {  -        if (Type == JSON_UNDEFINED)  -            return defaultValue;  +    long long TJsonValue::GetIntegerSafe(const long long defaultValue) const { +        if (Type == JSON_UNDEFINED) +            return defaultValue; -        return GetIntegerSafe();  -    }  +        return GetIntegerSafe(); +    } -    unsigned long long TJsonValue::GetUIntegerSafe(const unsigned long long defaultValue) const {  -        if (Type == JSON_UNDEFINED)  -            return defaultValue;  +    unsigned long long TJsonValue::GetUIntegerSafe(const unsigned long long defaultValue) const { +        if (Type == JSON_UNDEFINED) +            return defaultValue; -        return GetUIntegerSafe();  -    }  +        return GetUIntegerSafe(); +    } -    double TJsonValue::GetDoubleSafe(const double defaultValue) const {  -        if (Type == JSON_UNDEFINED)  -            return defaultValue;  +    double TJsonValue::GetDoubleSafe(const double defaultValue) const { +        if (Type == JSON_UNDEFINED) +            return defaultValue; -        return GetDoubleSafe();  -    }  +        return GetDoubleSafe(); +    } -    TString TJsonValue::GetStringSafe(const TString& defaultValue) const {  -        if (Type == JSON_UNDEFINED)  -            return defaultValue;  +    TString TJsonValue::GetStringSafe(const TString& defaultValue) const { +        if (Type == JSON_UNDEFINED) +            return defaultValue; -        return GetStringSafe();  -    }  +        return GetStringSafe(); +    } -    const TJsonValue::TMapType& TJsonValue::GetMapSafe() const {  -        if (Type != JSON_MAP)  -            ythrow TJsonException() << "Not a map";  +    const TJsonValue::TMapType& TJsonValue::GetMapSafe() const { +        if (Type != JSON_MAP) +            ythrow TJsonException() << "Not a map"; -        return *Value.Map;  -    }  +        return *Value.Map; +    } -    TJsonValue::TMapType& TJsonValue::GetMapSafe() {  -        return const_cast<TJsonValue::TMapType&>(const_cast<const TJsonValue*>(this)->GetMapSafe());  -    }  +    TJsonValue::TMapType& TJsonValue::GetMapSafe() { +        return const_cast<TJsonValue::TMapType&>(const_cast<const TJsonValue*>(this)->GetMapSafe()); +    } -    const TJsonValue::TArray& TJsonValue::GetArraySafe() const {  -        if (Type != JSON_ARRAY)  -            ythrow TJsonException() << "Not an array";  +    const TJsonValue::TArray& TJsonValue::GetArraySafe() const { +        if (Type != JSON_ARRAY) +            ythrow TJsonException() << "Not an array"; -        return *Value.Array;  -    }  +        return *Value.Array; +    } -    TJsonValue::TArray& TJsonValue::GetArraySafe() {  -        return const_cast<TJsonValue::TArray&>(const_cast<const TJsonValue*>(this)->GetArraySafe());  -    }  +    TJsonValue::TArray& TJsonValue::GetArraySafe() { +        return const_cast<TJsonValue::TArray&>(const_cast<const TJsonValue*>(this)->GetArraySafe()); +    } -    bool TJsonValue::GetBooleanRobust() const noexcept {  -        switch (Type) {  -            case JSON_ARRAY:  -                return !Value.Array->empty();  -            case JSON_MAP:  -                return !Value.Map->empty();  -            case JSON_INTEGER:  -            case JSON_UINTEGER:  -            case JSON_DOUBLE:  -                return GetIntegerRobust();  -            case JSON_STRING:  -                return GetIntegerRobust() || IsTrue(Value.String);  -            case JSON_NULL:  -            case JSON_UNDEFINED:  -            default:  +    bool TJsonValue::GetBooleanRobust() const noexcept { +        switch (Type) { +            case JSON_ARRAY: +                return !Value.Array->empty(); +            case JSON_MAP: +                return !Value.Map->empty(); +            case JSON_INTEGER: +            case JSON_UINTEGER: +            case JSON_DOUBLE: +                return GetIntegerRobust(); +            case JSON_STRING: +                return GetIntegerRobust() || IsTrue(Value.String); +            case JSON_NULL: +            case JSON_UNDEFINED: +            default:                  return false; -            case JSON_BOOLEAN:  -                return Value.Boolean;  -        }  -    } - -    long long TJsonValue::GetIntegerRobust() const noexcept {  -        switch (Type) {  -            case JSON_ARRAY:  -                return Value.Array->size();  -            case JSON_MAP:  -                return Value.Map->size();  -            case JSON_BOOLEAN:  -                return Value.Boolean;  -            case JSON_DOUBLE:  -                return GetDoubleRobust();  -            case JSON_STRING:  -                try {  -                    i64 res = 0;  -                    if (Value.String && TryFromString(Value.String, res)) {  -                        return res;  -                    }  -                } catch (const yexception&) {  -                }  -                return 0;  -            case JSON_NULL:  -            case JSON_UNDEFINED:  -            default:  -                return 0;  -            case JSON_INTEGER:  -            case JSON_UINTEGER:  -                return Value.Integer;  -        }  -    } - -    unsigned long long TJsonValue::GetUIntegerRobust() const noexcept {  -        switch (Type) {  -            case JSON_ARRAY:  -                return Value.Array->size();  -            case JSON_MAP:  -                return Value.Map->size();  -            case JSON_BOOLEAN:  -                return Value.Boolean;  -            case JSON_DOUBLE:  -                return GetDoubleRobust();  -            case JSON_STRING:  -                try {  -                    ui64 res = 0;  -                    if (Value.String && TryFromString(Value.String, res)) {  -                        return res;  -                    }  -                } catch (const yexception&) {  -                }  -                return 0;  -            case JSON_NULL:  -            case JSON_UNDEFINED:  -            default:  -                return 0;  -            case JSON_INTEGER:  -            case JSON_UINTEGER:  -                return Value.UInteger;  -        }  -    } - -    double TJsonValue::GetDoubleRobust() const noexcept {  -        switch (Type) {  -            case JSON_ARRAY:  -                return Value.Array->size();  -            case JSON_MAP:  -                return Value.Map->size();  -            case JSON_BOOLEAN:  -                return Value.Boolean;  -            case JSON_INTEGER:  -                return Value.Integer;  -            case JSON_UINTEGER:  -                return Value.UInteger;  -            case JSON_STRING:  -                try {  -                    double res = 0;  -                    if (Value.String && TryFromString(Value.String, res)) {  -                        return res;  -                    }  -                } catch (const yexception&) {  -                }  -                return 0;  -            case JSON_NULL:  -            case JSON_UNDEFINED:  -            default:  -                return 0;  -            case JSON_DOUBLE:  -                return Value.Double;  -        }  -    } - -    TString TJsonValue::GetStringRobust() const {  -        switch (Type) {  -            case JSON_ARRAY:  -            case JSON_MAP:  -            case JSON_BOOLEAN:  -            case JSON_DOUBLE:  -            case JSON_INTEGER:  -            case JSON_UINTEGER:  -            case JSON_NULL:  -            case JSON_UNDEFINED:  -            default: {  -                NJsonWriter::TBuf sout;  -                sout.WriteJsonValue(this);  -                return sout.Str();  -            }  -            case JSON_STRING:  -                return Value.String;  -        }  -    } - -    bool TJsonValue::GetBoolean(bool* value) const noexcept {  -        if (Type != JSON_BOOLEAN)  -            return false;  - -        *value = Value.Boolean;  -        return true;  -    }  - -    bool TJsonValue::GetInteger(long long* value) const noexcept {  -        if (!IsInteger())  -            return false;  - -        *value = GetInteger();  -        return true;  -    }  - -    bool TJsonValue::GetUInteger(unsigned long long* value) const noexcept {  -        if (!IsUInteger())  -            return false;  - -        *value = GetUInteger();  -        return true;  -    }  - -    bool TJsonValue::GetDouble(double* value) const noexcept {  -        if (!IsDouble())  -            return false;  - -        *value = GetDouble();  -        return true;  -    }  - -    bool TJsonValue::GetString(TString* value) const {  -        if (Type != JSON_STRING)  -            return false;  - -        *value = Value.String;  -        return true;  -    }  - -    bool TJsonValue::GetMap(TJsonValue::TMapType* value) const {  -        if (Type != JSON_MAP)  -            return false;  - -        *value = *Value.Map;  -        return true;  -    }  - -    bool TJsonValue::GetArray(TJsonValue::TArray* value) const {  -        if (Type != JSON_ARRAY)  -            return false;  - -        *value = *Value.Array;  -        return true;  -    }  - -    bool TJsonValue::GetMapPointer(const TJsonValue::TMapType** value) const noexcept {  -        if (Type != JSON_MAP)  -            return false;  - -        *value = Value.Map;  -        return true;  -    }  - -    bool TJsonValue::GetArrayPointer(const TJsonValue::TArray** value) const noexcept {  -        if (Type != JSON_ARRAY)  -            return false;  - -        *value = Value.Array;  +            case JSON_BOOLEAN: +                return Value.Boolean; +        } +    } + +    long long TJsonValue::GetIntegerRobust() const noexcept { +        switch (Type) { +            case JSON_ARRAY: +                return Value.Array->size(); +            case JSON_MAP: +                return Value.Map->size(); +            case JSON_BOOLEAN: +                return Value.Boolean; +            case JSON_DOUBLE: +                return GetDoubleRobust(); +            case JSON_STRING: +                try { +                    i64 res = 0; +                    if (Value.String && TryFromString(Value.String, res)) { +                        return res; +                    } +                } catch (const yexception&) { +                } +                return 0; +            case JSON_NULL: +            case JSON_UNDEFINED: +            default: +                return 0; +            case JSON_INTEGER: +            case JSON_UINTEGER: +                return Value.Integer; +        } +    } + +    unsigned long long TJsonValue::GetUIntegerRobust() const noexcept { +        switch (Type) { +            case JSON_ARRAY: +                return Value.Array->size(); +            case JSON_MAP: +                return Value.Map->size(); +            case JSON_BOOLEAN: +                return Value.Boolean; +            case JSON_DOUBLE: +                return GetDoubleRobust(); +            case JSON_STRING: +                try { +                    ui64 res = 0; +                    if (Value.String && TryFromString(Value.String, res)) { +                        return res; +                    } +                } catch (const yexception&) { +                } +                return 0; +            case JSON_NULL: +            case JSON_UNDEFINED: +            default: +                return 0; +            case JSON_INTEGER: +            case JSON_UINTEGER: +                return Value.UInteger; +        } +    } + +    double TJsonValue::GetDoubleRobust() const noexcept { +        switch (Type) { +            case JSON_ARRAY: +                return Value.Array->size(); +            case JSON_MAP: +                return Value.Map->size(); +            case JSON_BOOLEAN: +                return Value.Boolean; +            case JSON_INTEGER: +                return Value.Integer; +            case JSON_UINTEGER: +                return Value.UInteger; +            case JSON_STRING: +                try { +                    double res = 0; +                    if (Value.String && TryFromString(Value.String, res)) { +                        return res; +                    } +                } catch (const yexception&) { +                } +                return 0; +            case JSON_NULL: +            case JSON_UNDEFINED: +            default: +                return 0; +            case JSON_DOUBLE: +                return Value.Double; +        } +    } + +    TString TJsonValue::GetStringRobust() const { +        switch (Type) { +            case JSON_ARRAY: +            case JSON_MAP: +            case JSON_BOOLEAN: +            case JSON_DOUBLE: +            case JSON_INTEGER: +            case JSON_UINTEGER: +            case JSON_NULL: +            case JSON_UNDEFINED: +            default: { +                NJsonWriter::TBuf sout; +                sout.WriteJsonValue(this); +                return sout.Str(); +            } +            case JSON_STRING: +                return Value.String; +        } +    } + +    bool TJsonValue::GetBoolean(bool* value) const noexcept { +        if (Type != JSON_BOOLEAN) +            return false; + +        *value = Value.Boolean; +        return true; +    } + +    bool TJsonValue::GetInteger(long long* value) const noexcept { +        if (!IsInteger()) +            return false; + +        *value = GetInteger(); +        return true; +    } + +    bool TJsonValue::GetUInteger(unsigned long long* value) const noexcept { +        if (!IsUInteger()) +            return false; + +        *value = GetUInteger(); +        return true; +    } + +    bool TJsonValue::GetDouble(double* value) const noexcept { +        if (!IsDouble()) +            return false; + +        *value = GetDouble(); +        return true; +    } + +    bool TJsonValue::GetString(TString* value) const { +        if (Type != JSON_STRING) +            return false; + +        *value = Value.String;          return true;      } -    bool TJsonValue::GetValue(const size_t index, TJsonValue* value) const {  -        const TJsonValue* tmp = nullptr;  -        if (GetValuePointer(index, &tmp)) {  -            *value = *tmp;  -            return true;  -        }  -        return false;  +    bool TJsonValue::GetMap(TJsonValue::TMapType* value) const { +        if (Type != JSON_MAP) +            return false; + +        *value = *Value.Map; +        return true;      } -    bool TJsonValue::GetValue(const TStringBuf key, TJsonValue* value) const {  -        const TJsonValue* tmp = nullptr;  -        if (GetValuePointer(key, &tmp)) {  -            *value = *tmp;  -            return true;  -        }  -        return false;  +    bool TJsonValue::GetArray(TJsonValue::TArray* value) const { +        if (Type != JSON_ARRAY) +            return false; + +        *value = *Value.Array; +        return true;      } -    bool TJsonValue::GetValuePointer(const size_t index, const TJsonValue** value) const noexcept {  -        if (Type == JSON_ARRAY && index < Value.Array->size()) {  -            *value = &(*Value.Array)[index];  +    bool TJsonValue::GetMapPointer(const TJsonValue::TMapType** value) const noexcept { +        if (Type != JSON_MAP) +            return false; + +        *value = Value.Map; +        return true; +    } + +    bool TJsonValue::GetArrayPointer(const TJsonValue::TArray** value) const noexcept { +        if (Type != JSON_ARRAY) +            return false; + +        *value = Value.Array; +        return true; +    } + +    bool TJsonValue::GetValue(const size_t index, TJsonValue* value) const { +        const TJsonValue* tmp = nullptr; +        if (GetValuePointer(index, &tmp)) { +            *value = *tmp;              return true;          } -        return false;  +        return false;      } -    bool TJsonValue::GetValuePointer(const TStringBuf key, const TJsonValue** value) const noexcept {  -        if (Type == JSON_MAP) {  -            const TMapType::const_iterator it = Value.Map->find(key);  -            if (it != Value.Map->end()) {  -                *value = &(it->second);  -                return true;  -            }  -        }  -        return false;  -    }  +    bool TJsonValue::GetValue(const TStringBuf key, TJsonValue* value) const { +        const TJsonValue* tmp = nullptr; +        if (GetValuePointer(key, &tmp)) { +            *value = *tmp; +            return true; +        } +        return false; +    } -    bool TJsonValue::GetValuePointer(const TStringBuf key, TJsonValue** value) noexcept {  -        return static_cast<const TJsonValue*>(this)->GetValuePointer(key, const_cast<const TJsonValue**>(value));  -    }  +    bool TJsonValue::GetValuePointer(const size_t index, const TJsonValue** value) const noexcept { +        if (Type == JSON_ARRAY && index < Value.Array->size()) { +            *value = &(*Value.Array)[index]; +            return true; +        } +        return false; +    } -    bool TJsonValue::IsNull() const noexcept {  -        return Type == JSON_NULL;  -    }  +    bool TJsonValue::GetValuePointer(const TStringBuf key, const TJsonValue** value) const noexcept { +        if (Type == JSON_MAP) { +            const TMapType::const_iterator it = Value.Map->find(key); +            if (it != Value.Map->end()) { +                *value = &(it->second); +                return true; +            } +        } +        return false; +    } -    bool TJsonValue::IsBoolean() const noexcept {  -        return Type == JSON_BOOLEAN;  -    }  +    bool TJsonValue::GetValuePointer(const TStringBuf key, TJsonValue** value) noexcept { +        return static_cast<const TJsonValue*>(this)->GetValuePointer(key, const_cast<const TJsonValue**>(value)); +    } + +    bool TJsonValue::IsNull() const noexcept { +        return Type == JSON_NULL; +    } -    bool TJsonValue::IsInteger() const noexcept {  -        switch (Type) {  -            case JSON_INTEGER:  -                return true;  +    bool TJsonValue::IsBoolean() const noexcept { +        return Type == JSON_BOOLEAN; +    } -            case JSON_UINTEGER:  -                return (Value.UInteger <= static_cast<unsigned long long>(Max<long long>()));  +    bool TJsonValue::IsInteger() const noexcept { +        switch (Type) { +            case JSON_INTEGER: +                return true; -            case JSON_DOUBLE:  -                return ((long long)Value.Double == Value.Double);  -  -            default:  -                return false;  -        }  +            case JSON_UINTEGER: +                return (Value.UInteger <= static_cast<unsigned long long>(Max<long long>())); + +            case JSON_DOUBLE: +                return ((long long)Value.Double == Value.Double); + +            default: +                return false; +        }      } -    bool TJsonValue::IsUInteger() const noexcept {  -        switch (Type) {  -            case JSON_UINTEGER:  -                return true;  +    bool TJsonValue::IsUInteger() const noexcept { +        switch (Type) { +            case JSON_UINTEGER: +                return true; -            case JSON_INTEGER:  -                return (Value.Integer >= 0);  +            case JSON_INTEGER: +                return (Value.Integer >= 0); -            case JSON_DOUBLE:  -                return ((unsigned long long)Value.Double == Value.Double);  +            case JSON_DOUBLE: +                return ((unsigned long long)Value.Double == Value.Double); -            default:  -                return false;  -        }  +            default: +                return false; +        }      } -    bool TJsonValue::IsDouble() const noexcept {  -        // Check whether we can convert integer to floating-point  -        // without precision loss.  -        switch (Type) {  -            case JSON_DOUBLE:  -                return true;  +    bool TJsonValue::IsDouble() const noexcept { +        // Check whether we can convert integer to floating-point +        // without precision loss. +        switch (Type) { +            case JSON_DOUBLE: +                return true; -            case JSON_INTEGER:  +            case JSON_INTEGER:                  return (1ll << std::numeric_limits<double>::digits) >= Abs(Value.Integer); -            case JSON_UINTEGER:  +            case JSON_UINTEGER:                  return (1ull << std::numeric_limits<double>::digits) >= Value.UInteger; -            default:  -                return false;  -        }  -    } - -    namespace {  -        template <class TPtr, class T>  -        TPtr* CreateOrNullptr(TPtr* p, T key, std::true_type /*create*/) {  -            return &(*p)[key];  -        }  - -        template <class TPtr, class T>  -        TPtr* CreateOrNullptr(const TPtr* p, T key, std::false_type /*create*/) noexcept {  -            const TPtr* const next = &(*p)[key];  -            return next->IsDefined() ? const_cast<TPtr*>(next) : nullptr;  -        }  - -        template <bool Create, class TJsonPtr>  -        TJsonPtr GetValuePtrByPath(TJsonPtr currentJson, TStringBuf path, char delimiter) noexcept(!Create) {  -            static_assert(  -                !(Create && std::is_const<std::remove_pointer_t<TJsonPtr>>::value),  -                "TJsonPtr must be a `TJsonValue*` if `Create` is true");  -            constexpr std::integral_constant<bool, Create> create_tag{};  - -            while (!path.empty()) {  -                size_t index = 0;  -                const TStringBuf step = path.NextTok(delimiter);  -                if (step.size() > 2 && *step.begin() == '[' && step.back() == ']' && TryFromString(step.substr(1, step.size() - 2), index)) {  -                    currentJson = CreateOrNullptr(currentJson, index, create_tag);  -                } else {  -                    currentJson = CreateOrNullptr(currentJson, step, create_tag);  -                }  -  -                if (!currentJson) {  -                    return nullptr;  -                }  +            default: +                return false; +        } +    } + +    namespace { +        template <class TPtr, class T> +        TPtr* CreateOrNullptr(TPtr* p, T key, std::true_type /*create*/) { +            return &(*p)[key]; +        } + +        template <class TPtr, class T> +        TPtr* CreateOrNullptr(const TPtr* p, T key, std::false_type /*create*/) noexcept { +            const TPtr* const next = &(*p)[key]; +            return next->IsDefined() ? const_cast<TPtr*>(next) : nullptr; +        } + +        template <bool Create, class TJsonPtr> +        TJsonPtr GetValuePtrByPath(TJsonPtr currentJson, TStringBuf path, char delimiter) noexcept(!Create) { +            static_assert( +                !(Create && std::is_const<std::remove_pointer_t<TJsonPtr>>::value), +                "TJsonPtr must be a `TJsonValue*` if `Create` is true"); +            constexpr std::integral_constant<bool, Create> create_tag{}; + +            while (!path.empty()) { +                size_t index = 0; +                const TStringBuf step = path.NextTok(delimiter); +                if (step.size() > 2 && *step.begin() == '[' && step.back() == ']' && TryFromString(step.substr(1, step.size() - 2), index)) { +                    currentJson = CreateOrNullptr(currentJson, index, create_tag); +                } else { +                    currentJson = CreateOrNullptr(currentJson, step, create_tag); +                } + +                if (!currentJson) { +                    return nullptr; +                }              } -            return currentJson;  +            return currentJson;          } -    } // anonymous namespace  +    } // anonymous namespace -    bool TJsonValue::GetValueByPath(const TStringBuf path, TJsonValue& result, char delimiter) const {  -        const TJsonValue* const ptr = GetValuePtrByPath<false>(this, path, delimiter);  -        if (ptr) {  -            result = *ptr;  -            return true;  -        }  -        return false;  +    bool TJsonValue::GetValueByPath(const TStringBuf path, TJsonValue& result, char delimiter) const { +        const TJsonValue* const ptr = GetValuePtrByPath<false>(this, path, delimiter); +        if (ptr) { +            result = *ptr; +            return true; +        } +        return false;      } -    bool TJsonValue::SetValueByPath(const TStringBuf path, const TJsonValue& value, char delimiter) {  -        TJsonValue* const ptr = GetValuePtrByPath<true>(this, path, delimiter);  -        if (ptr) {  -            *ptr = value;  -            return true;  -        }  -        return false;  +    bool TJsonValue::SetValueByPath(const TStringBuf path, const TJsonValue& value, char delimiter) { +        TJsonValue* const ptr = GetValuePtrByPath<true>(this, path, delimiter); +        if (ptr) { +            *ptr = value; +            return true; +        } +        return false;      } -    bool TJsonValue::SetValueByPath(const TStringBuf path, TJsonValue&& value, char delimiter) {  -        TJsonValue* const ptr = GetValuePtrByPath<true>(this, path, delimiter);  -        if (ptr) {  -            *ptr = std::move(value);  -            return true;  -        }  -        return false;  +    bool TJsonValue::SetValueByPath(const TStringBuf path, TJsonValue&& value, char delimiter) { +        TJsonValue* const ptr = GetValuePtrByPath<true>(this, path, delimiter); +        if (ptr) { +            *ptr = std::move(value); +            return true; +        } +        return false;      } -    const TJsonValue* TJsonValue::GetValueByPath(const TStringBuf key, char delim) const noexcept {  -        return GetValuePtrByPath<false>(this, key, delim);  +    const TJsonValue* TJsonValue::GetValueByPath(const TStringBuf key, char delim) const noexcept { +        return GetValuePtrByPath<false>(this, key, delim);      } -    TJsonValue* TJsonValue::GetValueByPath(const TStringBuf key, char delim) noexcept {  -        return GetValuePtrByPath<false>(this, key, delim);  +    TJsonValue* TJsonValue::GetValueByPath(const TStringBuf key, char delim) noexcept { +        return GetValuePtrByPath<false>(this, key, delim);      } -    void TJsonValue::DoScan(const TString& path, TJsonValue* parent, IScanCallback& callback) {  -        if (!callback.Do(path, parent, *this)) {  -            return;  +    void TJsonValue::DoScan(const TString& path, TJsonValue* parent, IScanCallback& callback) { +        if (!callback.Do(path, parent, *this)) { +            return;          } -  -        if (Type == JSON_MAP) {  -            for (auto&& i : *Value.Map) {  + +        if (Type == JSON_MAP) { +            for (auto&& i : *Value.Map) {                  i.second.DoScan(!!path ? TString::Join(path, ".", i.first) : i.first, this, callback); -            }  -        } else if (Type == JSON_ARRAY) {  -            for (ui32 i = 0; i < Value.Array->size(); ++i) {  +            } +        } else if (Type == JSON_ARRAY) { +            for (ui32 i = 0; i < Value.Array->size(); ++i) {                  (*Value.Array)[i].DoScan(TString::Join(path, "[", ToString(i), "]"), this, callback); -            }  +            }          }      } -    void TJsonValue::Scan(IScanCallback& callback) {  -        DoScan("", nullptr, callback);  +    void TJsonValue::Scan(IScanCallback& callback) { +        DoScan("", nullptr, callback);      } -    bool TJsonValue::IsString() const noexcept {  -        return Type == JSON_STRING;  +    bool TJsonValue::IsString() const noexcept { +        return Type == JSON_STRING;      } -    bool TJsonValue::IsMap() const noexcept {  -        return Type == JSON_MAP;  +    bool TJsonValue::IsMap() const noexcept { +        return Type == JSON_MAP;      } -    bool TJsonValue::IsArray() const noexcept {  -        return Type == JSON_ARRAY;  +    bool TJsonValue::IsArray() const noexcept { +        return Type == JSON_ARRAY;      } -    bool TJsonValue::Has(const TStringBuf& key) const noexcept {  +    bool TJsonValue::Has(const TStringBuf& key) const noexcept {          return Type == JSON_MAP && Value.Map->contains(key);      } -    bool TJsonValue::Has(size_t key) const noexcept {  -        return Type == JSON_ARRAY && Value.Array->size() > key;  -    } - -    bool TJsonValue::operator==(const TJsonValue& rhs) const {  -        switch (Type) {  -            case JSON_UNDEFINED: {  -                return (rhs.GetType() == JSON_UNDEFINED);  -            }  - -            case JSON_NULL: {  -                return rhs.IsNull();  -            }  - -            case JSON_BOOLEAN: {  -                return (rhs.IsBoolean() && Value.Boolean == rhs.Value.Boolean);  -            }  - -            case JSON_INTEGER: {  -                return (rhs.IsInteger() && GetInteger() == rhs.GetInteger());  -            }  - -            case JSON_UINTEGER: {  -                return (rhs.IsUInteger() && GetUInteger() == rhs.GetUInteger());  -            }  - -            case JSON_STRING: {  -                return (rhs.IsString() && Value.String == rhs.Value.String);  -            }  -  -            case JSON_DOUBLE: {  -                return (rhs.IsDouble() && fabs(GetDouble() - rhs.GetDouble()) <= FLT_EPSILON);  -            }  -  -            case JSON_MAP:  -                return AreJsonMapsEqual(*this, rhs);  -  -            case JSON_ARRAY:  -                return AreJsonArraysEqual(*this, rhs);  -  -            default:  -                Y_ASSERT(false && "Unknown type.");  -                return false;  -        }  -    } - -    void TJsonValue::SwapWithUndefined(TJsonValue& output) noexcept {  -        if (Type == JSON_STRING) {  -            static_assert(std::is_nothrow_move_constructible<TString>::value, "noexcept violation! Add some try {} catch (...) logic");  -            new (&output.Value.String) TString(std::move(Value.String));  -            Value.String.~TString();  -        } else {  -            std::memcpy(&output.Value, &Value, sizeof(Value));  -        }  - -        output.Type = Type;  -        Type = JSON_UNDEFINED;  -    }  - -    void TJsonValue::Swap(TJsonValue& rhs) noexcept {  -        TJsonValue tmp(std::move(*this));  -        rhs.SwapWithUndefined(*this);  -        tmp.SwapWithUndefined(rhs);  -    }  +    bool TJsonValue::Has(size_t key) const noexcept { +        return Type == JSON_ARRAY && Value.Array->size() > key; +    } + +    bool TJsonValue::operator==(const TJsonValue& rhs) const { +        switch (Type) { +            case JSON_UNDEFINED: { +                return (rhs.GetType() == JSON_UNDEFINED); +            } + +            case JSON_NULL: { +                return rhs.IsNull(); +            } + +            case JSON_BOOLEAN: { +                return (rhs.IsBoolean() && Value.Boolean == rhs.Value.Boolean); +            } + +            case JSON_INTEGER: { +                return (rhs.IsInteger() && GetInteger() == rhs.GetInteger()); +            } + +            case JSON_UINTEGER: { +                return (rhs.IsUInteger() && GetUInteger() == rhs.GetUInteger()); +            } + +            case JSON_STRING: { +                return (rhs.IsString() && Value.String == rhs.Value.String); +            } + +            case JSON_DOUBLE: { +                return (rhs.IsDouble() && fabs(GetDouble() - rhs.GetDouble()) <= FLT_EPSILON); +            } + +            case JSON_MAP: +                return AreJsonMapsEqual(*this, rhs); + +            case JSON_ARRAY: +                return AreJsonArraysEqual(*this, rhs); + +            default: +                Y_ASSERT(false && "Unknown type."); +                return false; +        } +    } + +    void TJsonValue::SwapWithUndefined(TJsonValue& output) noexcept { +        if (Type == JSON_STRING) { +            static_assert(std::is_nothrow_move_constructible<TString>::value, "noexcept violation! Add some try {} catch (...) logic"); +            new (&output.Value.String) TString(std::move(Value.String)); +            Value.String.~TString(); +        } else { +            std::memcpy(&output.Value, &Value, sizeof(Value)); +        } + +        output.Type = Type; +        Type = JSON_UNDEFINED; +    } + +    void TJsonValue::Swap(TJsonValue& rhs) noexcept { +        TJsonValue tmp(std::move(*this)); +        rhs.SwapWithUndefined(*this); +        tmp.SwapWithUndefined(rhs); +    }      void TJsonValue::Save(IOutputStream* s) const {          ::Save(s, static_cast<ui8>(Type)); @@ -1051,43 +1051,43 @@ namespace NJson {          }      } -    //****************************************************************  +    //**************************************************************** -    bool GetMapPointer(const TJsonValue& jv, const size_t index, const TJsonValue::TMapType** value) {  -        const TJsonValue* v;  -        if (!jv.GetValuePointer(index, &v) || !v->IsMap())  -            return false;  +    bool GetMapPointer(const TJsonValue& jv, const size_t index, const TJsonValue::TMapType** value) { +        const TJsonValue* v; +        if (!jv.GetValuePointer(index, &v) || !v->IsMap()) +            return false; -        *value = &v->GetMap();  -        return true;  -    }  +        *value = &v->GetMap(); +        return true; +    } -    bool GetArrayPointer(const TJsonValue& jv, const size_t index, const TJsonValue::TArray** value) {  -        const TJsonValue* v;  -        if (!jv.GetValuePointer(index, &v) || !v->IsArray())  -            return false;  +    bool GetArrayPointer(const TJsonValue& jv, const size_t index, const TJsonValue::TArray** value) { +        const TJsonValue* v; +        if (!jv.GetValuePointer(index, &v) || !v->IsArray()) +            return false; -        *value = &v->GetArray();  -        return true;  -    }  +        *value = &v->GetArray(); +        return true; +    } -    bool GetMapPointer(const TJsonValue& jv, const TStringBuf key, const TJsonValue::TMapType** value) {  -        const TJsonValue* v;  -        if (!jv.GetValuePointer(key, &v) || !v->IsMap())  -            return false;  +    bool GetMapPointer(const TJsonValue& jv, const TStringBuf key, const TJsonValue::TMapType** value) { +        const TJsonValue* v; +        if (!jv.GetValuePointer(key, &v) || !v->IsMap()) +            return false; -        *value = &v->GetMap();  -        return true;  -    }  +        *value = &v->GetMap(); +        return true; +    } -    bool GetArrayPointer(const TJsonValue& jv, const TStringBuf key, const TJsonValue::TArray** value) {  -        const TJsonValue* v;  -        if (!jv.GetValuePointer(key, &v) || !v->IsArray())  -            return false;  +    bool GetArrayPointer(const TJsonValue& jv, const TStringBuf key, const TJsonValue::TArray** value) { +        const TJsonValue* v; +        if (!jv.GetValuePointer(key, &v) || !v->IsArray()) +            return false; -        *value = &v->GetArray();  -        return true;  -    }  +        *value = &v->GetArray(); +        return true; +    }      void TJsonValue::BackChecks() const {          if (Type != JSON_ARRAY) @@ -1098,8 +1098,8 @@ namespace NJson {      }  } -template <>  +template <>  void Out<NJson::TJsonValue>(IOutputStream& out, const NJson::TJsonValue& v) {      NJsonWriter::TBuf buf(NJsonWriter::HEM_DONT_ESCAPE_HTML, &out);      buf.WriteJsonValue(&v); -}  +} diff --git a/library/cpp/json/writer/json_value.h b/library/cpp/json/writer/json_value.h index 721453f001d..3f0f50bc4c8 100644 --- a/library/cpp/json/writer/json_value.h +++ b/library/cpp/json/writer/json_value.h @@ -1,189 +1,189 @@  #pragma once  #include <library/cpp/json/common/defs.h> -  +  #include <util/generic/string.h>  #include <util/generic/hash.h>  #include <util/generic/vector.h> -#include <util/generic/deque.h>  +#include <util/generic/deque.h>  #include <util/generic/utility.h>  #include <util/generic/yexception.h>  namespace NJson { -    enum EJsonValueType {  -        JSON_UNDEFINED /* "Undefined" */,  -        JSON_NULL /* "Null" */,  -        JSON_BOOLEAN /* "Boolean" */,  -        JSON_INTEGER /* "Integer" */,  -        JSON_DOUBLE /* "Double" */,  -        JSON_STRING /* "String" */,  -        JSON_MAP /* "Map" */,  -        JSON_ARRAY /* "Array" */,  -        JSON_UINTEGER /* "UInteger" */  -    };  - -    class TJsonValue;  - -    class IScanCallback {  -    public:  +    enum EJsonValueType { +        JSON_UNDEFINED /* "Undefined" */, +        JSON_NULL /* "Null" */, +        JSON_BOOLEAN /* "Boolean" */, +        JSON_INTEGER /* "Integer" */, +        JSON_DOUBLE /* "Double" */, +        JSON_STRING /* "String" */, +        JSON_MAP /* "Map" */, +        JSON_ARRAY /* "Array" */, +        JSON_UINTEGER /* "UInteger" */ +    }; + +    class TJsonValue; + +    class IScanCallback { +    public:          virtual ~IScanCallback() = default; -        virtual bool Do(const TString& path, TJsonValue* parent, TJsonValue& value) = 0;  -    };  - -    class TJsonValue {  -        void Clear() noexcept;  - -    public:  -        typedef THashMap<TString, TJsonValue> TMapType;  -        typedef TDeque<TJsonValue> TArray;  - -        TJsonValue() noexcept = default;  -        TJsonValue(EJsonValueType type);  -        TJsonValue(bool value) noexcept;  -        TJsonValue(int value) noexcept;  -        TJsonValue(unsigned int value) noexcept;  -        TJsonValue(long value) noexcept;  -        TJsonValue(unsigned long value) noexcept;  -        TJsonValue(long long value) noexcept;  -        TJsonValue(unsigned long long value) noexcept;  -        TJsonValue(double value) noexcept;  +        virtual bool Do(const TString& path, TJsonValue* parent, TJsonValue& value) = 0; +    }; + +    class TJsonValue { +        void Clear() noexcept; + +    public: +        typedef THashMap<TString, TJsonValue> TMapType; +        typedef TDeque<TJsonValue> TArray; + +        TJsonValue() noexcept = default; +        TJsonValue(EJsonValueType type); +        TJsonValue(bool value) noexcept; +        TJsonValue(int value) noexcept; +        TJsonValue(unsigned int value) noexcept; +        TJsonValue(long value) noexcept; +        TJsonValue(unsigned long value) noexcept; +        TJsonValue(long long value) noexcept; +        TJsonValue(unsigned long long value) noexcept; +        TJsonValue(double value) noexcept;          TJsonValue(TString value); -        TJsonValue(const char* value);  -        template <class T>  -        TJsonValue(const T*) = delete;  -        TJsonValue(TStringBuf value);  -  -        TJsonValue(const std::string& s)  -            : TJsonValue(TStringBuf(s))  -        {  -        }  -  -        TJsonValue(const TJsonValue& vval);  -        TJsonValue(TJsonValue&& vval) noexcept;  - -        TJsonValue& operator=(const TJsonValue& val);  -        TJsonValue& operator=(TJsonValue&& val) noexcept;  - -        ~TJsonValue() {  -            Clear();  -        }  - -        EJsonValueType GetType() const noexcept;  -        TJsonValue& SetType(EJsonValueType type);  - -        TJsonValue& SetValue(const TJsonValue& value);  -        TJsonValue& SetValue(TJsonValue&& value);  - -        // for Map  -        TJsonValue& InsertValue(const TString& key, const TJsonValue& value);  -        TJsonValue& InsertValue(TStringBuf key, const TJsonValue& value);  -        TJsonValue& InsertValue(const char* key, const TJsonValue& value);  -        TJsonValue& InsertValue(const TString& key, TJsonValue&& value);  -        TJsonValue& InsertValue(TStringBuf key, TJsonValue&& value);  -        TJsonValue& InsertValue(const char* key, TJsonValue&& value);  - -        // for Array  -        TJsonValue& AppendValue(const TJsonValue& value);  -        TJsonValue& AppendValue(TJsonValue&& value);  -        TJsonValue& Back();  +        TJsonValue(const char* value); +        template <class T> +        TJsonValue(const T*) = delete; +        TJsonValue(TStringBuf value); + +        TJsonValue(const std::string& s) +            : TJsonValue(TStringBuf(s)) +        { +        } + +        TJsonValue(const TJsonValue& vval); +        TJsonValue(TJsonValue&& vval) noexcept; + +        TJsonValue& operator=(const TJsonValue& val); +        TJsonValue& operator=(TJsonValue&& val) noexcept; + +        ~TJsonValue() { +            Clear(); +        } + +        EJsonValueType GetType() const noexcept; +        TJsonValue& SetType(EJsonValueType type); + +        TJsonValue& SetValue(const TJsonValue& value); +        TJsonValue& SetValue(TJsonValue&& value); + +        // for Map +        TJsonValue& InsertValue(const TString& key, const TJsonValue& value); +        TJsonValue& InsertValue(TStringBuf key, const TJsonValue& value); +        TJsonValue& InsertValue(const char* key, const TJsonValue& value); +        TJsonValue& InsertValue(const TString& key, TJsonValue&& value); +        TJsonValue& InsertValue(TStringBuf key, TJsonValue&& value); +        TJsonValue& InsertValue(const char* key, TJsonValue&& value); + +        // for Array +        TJsonValue& AppendValue(const TJsonValue& value); +        TJsonValue& AppendValue(TJsonValue&& value); +        TJsonValue& Back();          const TJsonValue& Back() const; -        bool GetValueByPath(TStringBuf path, TJsonValue& result, char delimiter = '.') const;  -        bool SetValueByPath(TStringBuf path, const TJsonValue& value, char delimiter = '.');  -        bool SetValueByPath(TStringBuf path, TJsonValue&& value, char delimiter = '.');  - -        // returns NULL on failure  -        const TJsonValue* GetValueByPath(TStringBuf path, char delimiter = '.') const noexcept;  -        TJsonValue* GetValueByPath(TStringBuf path, char delimiter = '.') noexcept;  - -        void EraseValue(TStringBuf key);  -        void EraseValue(size_t index);  - -        TJsonValue& operator[](size_t idx);  -        TJsonValue& operator[](const TStringBuf& key);  -        const TJsonValue& operator[](size_t idx) const noexcept;  -        const TJsonValue& operator[](const TStringBuf& key) const noexcept;  - -        bool GetBoolean() const;  -        long long GetInteger() const;  -        unsigned long long GetUInteger() const;  -        double GetDouble() const;  -        const TString& GetString() const;  -        const TMapType& GetMap() const;  -        const TArray& GetArray() const;  - -        //throwing TJsonException possible  -        bool GetBooleanSafe() const;  -        long long GetIntegerSafe() const;  -        unsigned long long GetUIntegerSafe() const;  -        double GetDoubleSafe() const;  -        const TString& GetStringSafe() const;  -        const TMapType& GetMapSafe() const;  -        TMapType& GetMapSafe();  -        const TArray& GetArraySafe() const;  -        TArray& GetArraySafe();  - -        bool GetBooleanSafe(bool defaultValue) const;  -        long long GetIntegerSafe(long long defaultValue) const;  -        unsigned long long GetUIntegerSafe(unsigned long long defaultValue) const;  -        double GetDoubleSafe(double defaultValue) const;  -        TString GetStringSafe(const TString& defaultValue) const;  - -        bool GetBooleanRobust() const noexcept;  -        long long GetIntegerRobust() const noexcept;  -        unsigned long long GetUIntegerRobust() const noexcept;  -        double GetDoubleRobust() const noexcept;  -        TString GetStringRobust() const;  - -        // Exception-free accessors  -        bool GetBoolean(bool* value) const noexcept;  -        bool GetInteger(long long* value) const noexcept;  -        bool GetUInteger(unsigned long long* value) const noexcept;  -        bool GetDouble(double* value) const noexcept;  -        bool GetMapPointer(const TMapType** value) const noexcept;  -        bool GetArrayPointer(const TArray** value) const noexcept;  - -        bool GetString(TString* value) const;  -        bool GetMap(TMapType* value) const;  -        bool GetArray(TArray* value) const;  -        bool GetValue(size_t index, TJsonValue* value) const;  -        bool GetValue(TStringBuf key, TJsonValue* value) const;  -        bool GetValuePointer(size_t index, const TJsonValue** value) const noexcept;  -        bool GetValuePointer(TStringBuf key, const TJsonValue** value) const noexcept;  -        bool GetValuePointer(TStringBuf key, TJsonValue** value) noexcept;  - -        // Checking for defined non-null value  -        bool IsDefined() const noexcept {  -            return Type != JSON_UNDEFINED && Type != JSON_NULL;  -        }  - -        bool IsNull() const noexcept;  -        bool IsBoolean() const noexcept;  -        bool IsDouble() const noexcept;  -        bool IsString() const noexcept;  -        bool IsMap() const noexcept;  -        bool IsArray() const noexcept;  - -        /// @return true if JSON_INTEGER or (JSON_UINTEGER and Value <= Max<long long>)  -        bool IsInteger() const noexcept;  - -        /// @return true if JSON_UINTEGER or (JSON_INTEGER and Value >= 0)  -        bool IsUInteger() const noexcept;  - -        bool Has(const TStringBuf& key) const noexcept;  -        bool Has(size_t key) const noexcept;  - -        void Scan(IScanCallback& callback);  - -        /// Non-robust comparison.  -        bool operator==(const TJsonValue& rhs) const;  - -        bool operator!=(const TJsonValue& rhs) const {  -            return !(*this == rhs);  -        }  - -        void Swap(TJsonValue& rhs) noexcept;  +        bool GetValueByPath(TStringBuf path, TJsonValue& result, char delimiter = '.') const; +        bool SetValueByPath(TStringBuf path, const TJsonValue& value, char delimiter = '.'); +        bool SetValueByPath(TStringBuf path, TJsonValue&& value, char delimiter = '.'); + +        // returns NULL on failure +        const TJsonValue* GetValueByPath(TStringBuf path, char delimiter = '.') const noexcept; +        TJsonValue* GetValueByPath(TStringBuf path, char delimiter = '.') noexcept; + +        void EraseValue(TStringBuf key); +        void EraseValue(size_t index); + +        TJsonValue& operator[](size_t idx); +        TJsonValue& operator[](const TStringBuf& key); +        const TJsonValue& operator[](size_t idx) const noexcept; +        const TJsonValue& operator[](const TStringBuf& key) const noexcept; + +        bool GetBoolean() const; +        long long GetInteger() const; +        unsigned long long GetUInteger() const; +        double GetDouble() const; +        const TString& GetString() const; +        const TMapType& GetMap() const; +        const TArray& GetArray() const; + +        //throwing TJsonException possible +        bool GetBooleanSafe() const; +        long long GetIntegerSafe() const; +        unsigned long long GetUIntegerSafe() const; +        double GetDoubleSafe() const; +        const TString& GetStringSafe() const; +        const TMapType& GetMapSafe() const; +        TMapType& GetMapSafe(); +        const TArray& GetArraySafe() const; +        TArray& GetArraySafe(); + +        bool GetBooleanSafe(bool defaultValue) const; +        long long GetIntegerSafe(long long defaultValue) const; +        unsigned long long GetUIntegerSafe(unsigned long long defaultValue) const; +        double GetDoubleSafe(double defaultValue) const; +        TString GetStringSafe(const TString& defaultValue) const; + +        bool GetBooleanRobust() const noexcept; +        long long GetIntegerRobust() const noexcept; +        unsigned long long GetUIntegerRobust() const noexcept; +        double GetDoubleRobust() const noexcept; +        TString GetStringRobust() const; + +        // Exception-free accessors +        bool GetBoolean(bool* value) const noexcept; +        bool GetInteger(long long* value) const noexcept; +        bool GetUInteger(unsigned long long* value) const noexcept; +        bool GetDouble(double* value) const noexcept; +        bool GetMapPointer(const TMapType** value) const noexcept; +        bool GetArrayPointer(const TArray** value) const noexcept; + +        bool GetString(TString* value) const; +        bool GetMap(TMapType* value) const; +        bool GetArray(TArray* value) const; +        bool GetValue(size_t index, TJsonValue* value) const; +        bool GetValue(TStringBuf key, TJsonValue* value) const; +        bool GetValuePointer(size_t index, const TJsonValue** value) const noexcept; +        bool GetValuePointer(TStringBuf key, const TJsonValue** value) const noexcept; +        bool GetValuePointer(TStringBuf key, TJsonValue** value) noexcept; + +        // Checking for defined non-null value +        bool IsDefined() const noexcept { +            return Type != JSON_UNDEFINED && Type != JSON_NULL; +        } + +        bool IsNull() const noexcept; +        bool IsBoolean() const noexcept; +        bool IsDouble() const noexcept; +        bool IsString() const noexcept; +        bool IsMap() const noexcept; +        bool IsArray() const noexcept; + +        /// @return true if JSON_INTEGER or (JSON_UINTEGER and Value <= Max<long long>) +        bool IsInteger() const noexcept; + +        /// @return true if JSON_UINTEGER or (JSON_INTEGER and Value >= 0) +        bool IsUInteger() const noexcept; + +        bool Has(const TStringBuf& key) const noexcept; +        bool Has(size_t key) const noexcept; + +        void Scan(IScanCallback& callback); + +        /// Non-robust comparison. +        bool operator==(const TJsonValue& rhs) const; + +        bool operator!=(const TJsonValue& rhs) const { +            return !(*this == rhs); +        } + +        void Swap(TJsonValue& rhs) noexcept;          // save using util/ysaveload.h serialization (not to JSON stream)          void Save(IOutputStream* s) const; @@ -191,28 +191,28 @@ namespace NJson {          // load using util/ysaveload.h serialization (not as JSON stream)          void Load(IInputStream* s); -        static const TJsonValue UNDEFINED;  +        static const TJsonValue UNDEFINED; -    private:  -        EJsonValueType Type = JSON_UNDEFINED;  -        union TValueUnion {  -            bool Boolean;  -            long long Integer;  -            unsigned long long UInteger;  -            double Double;  -            TString String;  -            TMapType* Map;  -            TArray* Array;  +    private: +        EJsonValueType Type = JSON_UNDEFINED; +        union TValueUnion { +            bool Boolean; +            long long Integer; +            unsigned long long UInteger; +            double Double; +            TString String; +            TMapType* Map; +            TArray* Array; -            TValueUnion() noexcept {  +            TValueUnion() noexcept {                  Zero(*this); -            }  -            ~TValueUnion() noexcept {  -            }  -        };  -        TValueUnion Value;  -        void DoScan(const TString& path, TJsonValue* parent, IScanCallback& callback);  -        void SwapWithUndefined(TJsonValue& output) noexcept;  +            } +            ~TValueUnion() noexcept { +            } +        }; +        TValueUnion Value; +        void DoScan(const TString& path, TJsonValue* parent, IScanCallback& callback); +        void SwapWithUndefined(TJsonValue& output) noexcept;          /**              @throw yexception if Back shouldn't be called on the object. @@ -220,51 +220,51 @@ namespace NJson {          void BackChecks() const;      }; -    inline bool GetBoolean(const TJsonValue& jv, size_t index, bool* value) noexcept {  -        return jv[index].GetBoolean(value);  -    }  +    inline bool GetBoolean(const TJsonValue& jv, size_t index, bool* value) noexcept { +        return jv[index].GetBoolean(value); +    } -    inline bool GetInteger(const TJsonValue& jv, size_t index, long long* value) noexcept {  -        return jv[index].GetInteger(value);  -    }  +    inline bool GetInteger(const TJsonValue& jv, size_t index, long long* value) noexcept { +        return jv[index].GetInteger(value); +    } -    inline bool GetUInteger(const TJsonValue& jv, size_t index, unsigned long long* value) noexcept {  -        return jv[index].GetUInteger(value);  -    }  +    inline bool GetUInteger(const TJsonValue& jv, size_t index, unsigned long long* value) noexcept { +        return jv[index].GetUInteger(value); +    } -    inline bool GetDouble(const TJsonValue& jv, size_t index, double* value) noexcept {  -        return jv[index].GetDouble(value);  -    }  +    inline bool GetDouble(const TJsonValue& jv, size_t index, double* value) noexcept { +        return jv[index].GetDouble(value); +    } -    inline bool GetString(const TJsonValue& jv, size_t index, TString* value) {  -        return jv[index].GetString(value);  -    }  +    inline bool GetString(const TJsonValue& jv, size_t index, TString* value) { +        return jv[index].GetString(value); +    } -    bool GetMapPointer(const TJsonValue& jv, size_t index, const TJsonValue::TMapType** value);  -    bool GetArrayPointer(const TJsonValue& jv, size_t index, const TJsonValue::TArray** value);  +    bool GetMapPointer(const TJsonValue& jv, size_t index, const TJsonValue::TMapType** value); +    bool GetArrayPointer(const TJsonValue& jv, size_t index, const TJsonValue::TArray** value); -    inline bool GetBoolean(const TJsonValue& jv, TStringBuf key, bool* value) noexcept {  -        return jv[key].GetBoolean(value);  -    }  +    inline bool GetBoolean(const TJsonValue& jv, TStringBuf key, bool* value) noexcept { +        return jv[key].GetBoolean(value); +    } -    inline bool GetInteger(const TJsonValue& jv, TStringBuf key, long long* value) noexcept {  -        return jv[key].GetInteger(value);  -    }  +    inline bool GetInteger(const TJsonValue& jv, TStringBuf key, long long* value) noexcept { +        return jv[key].GetInteger(value); +    } -    inline bool GetUInteger(const TJsonValue& jv, TStringBuf key, unsigned long long* value) noexcept {  -        return jv[key].GetUInteger(value);  -    }  +    inline bool GetUInteger(const TJsonValue& jv, TStringBuf key, unsigned long long* value) noexcept { +        return jv[key].GetUInteger(value); +    } -    inline bool GetDouble(const TJsonValue& jv, TStringBuf key, double* value) noexcept {  -        return jv[key].GetDouble(value);  -    }  +    inline bool GetDouble(const TJsonValue& jv, TStringBuf key, double* value) noexcept { +        return jv[key].GetDouble(value); +    } -    inline bool GetString(const TJsonValue& jv, TStringBuf key, TString* value) {  -        return jv[key].GetString(value);  -    }  +    inline bool GetString(const TJsonValue& jv, TStringBuf key, TString* value) { +        return jv[key].GetString(value); +    } -    bool GetMapPointer(const TJsonValue& jv, const TStringBuf key, const TJsonValue::TMapType** value);  -    bool GetArrayPointer(const TJsonValue& jv, const TStringBuf key, const TJsonValue::TArray** value);  +    bool GetMapPointer(const TJsonValue& jv, const TStringBuf key, const TJsonValue::TMapType** value); +    bool GetArrayPointer(const TJsonValue& jv, const TStringBuf key, const TJsonValue::TArray** value);      class TJsonMap: public TJsonValue {      public: diff --git a/library/cpp/json/writer/json_value_ut.cpp b/library/cpp/json/writer/json_value_ut.cpp index d3f3c42bea1..dc7f6affdff 100644 --- a/library/cpp/json/writer/json_value_ut.cpp +++ b/library/cpp/json/writer/json_value_ut.cpp @@ -18,7 +18,7 @@ Y_UNIT_TEST_SUITE(TJsonValueTest) {          TJsonValue emptyMap(JSON_MAP);          UNIT_ASSERT(!undef.IsDefined()); -        UNIT_ASSERT(!null.IsDefined()); // json NULL is undefined too!  +        UNIT_ASSERT(!null.IsDefined()); // json NULL is undefined too!          UNIT_ASSERT(_false.IsDefined());          UNIT_ASSERT(zeroInt.IsDefined());          UNIT_ASSERT(zeroDouble.IsDefined()); @@ -259,7 +259,7 @@ Y_UNIT_TEST_SUITE(TJsonValueTest) {              UNIT_ASSERT_EQUAL(lhs.GetValueByPath("l/a/c/e/x", '/'), NULL);              UNIT_ASSERT_EQUAL(lhs.GetValueByPath("a/c/e/x", '/'), NULL);              UNIT_ASSERT_EQUAL(lhs.GetValueByPath("nokey", '/'), NULL); -            UNIT_ASSERT_EQUAL(*lhs.GetValueByPath("", '/'), lhs); // itself  +            UNIT_ASSERT_EQUAL(*lhs.GetValueByPath("", '/'), lhs); // itself              TJsonValue array;              TJsonValue third; @@ -325,7 +325,7 @@ Y_UNIT_TEST_SUITE(TJsonValueTest) {          }          {              const TJsonValue* result = lhs.GetValueByPath("", '/'); -            UNIT_ASSERT_EQUAL(*result, lhs); // itself  +            UNIT_ASSERT_EQUAL(*result, lhs); // itself          }          TJsonValue array; @@ -335,8 +335,8 @@ Y_UNIT_TEST_SUITE(TJsonValueTest) {          third["t"] = array;          UNIT_ASSERT(array.GetValueByPath("[0].e", '.')->GetStringRobust() == "f"); -        UNIT_ASSERT(third.GetValueByPath("t.[0].e", '.')->GetStringRobust() == "f");  -        UNIT_ASSERT(third.GetValueByPath("t.[1].c.e", '.')->GetStringRobust() == "f");  +        UNIT_ASSERT(third.GetValueByPath("t.[0].e", '.')->GetStringRobust() == "f"); +        UNIT_ASSERT(third.GetValueByPath("t.[1].c.e", '.')->GetStringRobust() == "f");      }      Y_UNIT_TEST(EraseValueFromArray) { @@ -385,7 +385,7 @@ Y_UNIT_TEST_SUITE(TJsonValueTest) {              value1.AppendValue(1);              value1.AppendValue(2);              src.InsertValue("key", value1); -            src.InsertValue("key1", "HI!");  +            src.InsertValue("key1", "HI!");              TJsonValue dst;              TJsonValue value2; @@ -426,7 +426,7 @@ Y_UNIT_TEST_SUITE(TJsonValueTest) {              dst.InsertValue("arr", arr2);              src["arr"].AppendValue(value1); -            for (auto& node : src["arr"].GetArraySafe()) {  +            for (auto& node : src["arr"].GetArraySafe()) {                  node.InsertValue("yek", "eulav");              }              UNIT_ASSERT(src == dst); @@ -550,7 +550,7 @@ Y_UNIT_TEST_SUITE(TJsonValueTest) {              outer.AppendValue(json);          } -        const TJsonValue::TArray* array = nullptr;  +        const TJsonValue::TArray* array = nullptr;          GetArrayPointer(outer, 0, &array);          UNIT_ASSERT_VALUES_EQUAL((*array)[1], 2);      } @@ -565,7 +565,7 @@ Y_UNIT_TEST_SUITE(TJsonValueTest) {              outer.InsertValue("x", json);          } -        const TJsonValue::TArray* array = nullptr;  +        const TJsonValue::TArray* array = nullptr;          GetArrayPointer(outer, "x", &array);          UNIT_ASSERT_VALUES_EQUAL((*array)[1], 2);      } @@ -580,7 +580,7 @@ Y_UNIT_TEST_SUITE(TJsonValueTest) {              outer.AppendValue(json);          } -        const TJsonValue::TMapType* map = nullptr;  +        const TJsonValue::TMapType* map = nullptr;          GetMapPointer(outer, 0, &map);          UNIT_ASSERT_VALUES_EQUAL((*map).at("b"), 2);      } @@ -595,7 +595,7 @@ Y_UNIT_TEST_SUITE(TJsonValueTest) {              outer.InsertValue("x", json);          } -        const TJsonValue::TMapType* map = nullptr;  +        const TJsonValue::TMapType* map = nullptr;          GetMapPointer(outer, "x", &map);          UNIT_ASSERT_VALUES_EQUAL((*map).at("b"), 2);      } @@ -617,7 +617,7 @@ Y_UNIT_TEST_SUITE(TJsonValueTest) {          const char* longTestString =              "Testing TJsonValue& operator=(TJsonValue&&) subpart self moving " -            "after TJsonValue was constrcuted from TString&&.";  +            "after TJsonValue was constrcuted from TString&&.";          json["hello"] = TString{longTestString};          json = std::move(json["hello"]); diff --git a/library/cpp/json/writer/ya.make b/library/cpp/json/writer/ya.make index 1f1e2df08e1..3989ff35043 100644 --- a/library/cpp/json/writer/ya.make +++ b/library/cpp/json/writer/ya.make @@ -5,8 +5,8 @@ OWNER(      myltsev      pg  ) -  -PEERDIR(  + +PEERDIR(      library/cpp/json/common  ) diff --git a/library/cpp/json/ya.make b/library/cpp/json/ya.make index d46147f2690..d58eead8ec4 100644 --- a/library/cpp/json/ya.make +++ b/library/cpp/json/ya.make @@ -8,7 +8,7 @@ OWNER(  SRCS(      json_writer.cpp      json_reader.cpp -    json_prettifier.cpp  +    json_prettifier.cpp      rapidjson_helpers.cpp  )  | 
