diff options
author | myltsev <myltsev@yandex-team.ru> | 2022-02-10 16:46:03 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:46:03 +0300 |
commit | 9166d66c30c23c9e85a7c88185a068987148d23f (patch) | |
tree | 421bdcec5755d9e441c485560aab5ab8d74c7475 /library/cpp/json | |
parent | 8d3a5ed3a188a34167eaee54f1691ce5c9edf2f3 (diff) | |
download | ydb-9166d66c30c23c9e85a7c88185a068987148d23f.tar.gz |
Restoring authorship annotation for <myltsev@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'library/cpp/json')
-rw-r--r-- | library/cpp/json/easy_parse/json_easy_parser_impl.h | 14 | ||||
-rw-r--r-- | library/cpp/json/json_value.h | 4 | ||||
-rw-r--r-- | library/cpp/json/json_writer.cpp | 6 | ||||
-rw-r--r-- | library/cpp/json/json_writer.h | 2 | ||||
-rw-r--r-- | library/cpp/json/ut/json_writer_ut.cpp | 22 | ||||
-rw-r--r-- | library/cpp/json/writer/README | 44 | ||||
-rw-r--r-- | library/cpp/json/writer/json.cpp | 136 | ||||
-rw-r--r-- | library/cpp/json/writer/json.h | 330 | ||||
-rw-r--r-- | library/cpp/json/writer/json_ut.cpp | 280 | ||||
-rw-r--r-- | library/cpp/json/writer/json_value.cpp | 8 | ||||
-rw-r--r-- | library/cpp/json/writer/json_value.h | 2 | ||||
-rw-r--r-- | library/cpp/json/writer/ya.make | 16 |
12 files changed, 432 insertions, 432 deletions
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 ec55d838b3..9f9486c6f5 100644 --- a/library/cpp/json/easy_parse/json_easy_parser_impl.h +++ b/library/cpp/json/easy_parse/json_easy_parser_impl.h @@ -3,34 +3,34 @@ #include <util/generic/string.h> namespace NJson { - namespace NImpl { + namespace NImpl { enum EType { ARRAY, MAP, MAP_KEY }; - } + } template <class TStringType> - struct TPathElemImpl { - NImpl::EType Type; + struct TPathElemImpl { + NImpl::EType Type; TStringType Key; int ArrayCounter; - TPathElemImpl(NImpl::EType type) + TPathElemImpl(NImpl::EType type) : Type(type) , ArrayCounter() { } TPathElemImpl(const TStringType& key) - : Type(NImpl::MAP_KEY) + : Type(NImpl::MAP_KEY) , Key(key) , ArrayCounter() { } TPathElemImpl(int arrayCounter) - : Type(NImpl::ARRAY) + : Type(NImpl::ARRAY) , ArrayCounter(arrayCounter) { } diff --git a/library/cpp/json/json_value.h b/library/cpp/json/json_value.h index f70f4d2ee8..9109377521 100644 --- a/library/cpp/json/json_value.h +++ b/library/cpp/json/json_value.h @@ -1,3 +1,3 @@ -#pragma once - +#pragma once + #include <library/cpp/json/writer/json_value.h> diff --git a/library/cpp/json/json_writer.cpp b/library/cpp/json/json_writer.cpp index 3d058bae36..c9fc529135 100644 --- a/library/cpp/json/json_writer.cpp +++ b/library/cpp/json/json_writer.cpp @@ -73,14 +73,14 @@ namespace NJson { throw yexception() << "JSON writer: invalid UTF-8"; if (Buf.KeyExpected()) { Buf.WriteKey(value); - } else { + } else { if (DontEscapeStrings) { Buf.UnsafeWriteValue(TString("\"") + value + '"'); } else { Buf.WriteString(value); } - } - } + } + } void TJsonWriter::WriteNull() { Buf.WriteNull(); diff --git a/library/cpp/json/json_writer.h b/library/cpp/json/json_writer.h index c7f5c9499a..471ff3ed71 100644 --- a/library/cpp/json/json_writer.h +++ b/library/cpp/json/json_writer.h @@ -1,7 +1,7 @@ #pragma once // Deprecated. Use library/cpp/json/writer in new code. - + #include "json_value.h" #include <library/cpp/json/writer/json.h> diff --git a/library/cpp/json/ut/json_writer_ut.cpp b/library/cpp/json/ut/json_writer_ut.cpp index ca11d34dad..f4d9cde0e8 100644 --- a/library/cpp/json/ut/json_writer_ut.cpp +++ b/library/cpp/json/ut/json_writer_ut.cpp @@ -71,17 +71,17 @@ Y_UNIT_TEST_SUITE(TJsonWriterTest) { Y_UNIT_TEST(SortKeys) { TString expected = "{\"a\":null,\"j\":null,\"n\":null,\"y\":null,\"z\":null}"; - TJsonValue v; - v["z"] = JSON_NULL; - v["n"] = JSON_NULL; - v["a"] = JSON_NULL; - v["y"] = JSON_NULL; - v["j"] = JSON_NULL; - TStringStream out; - WriteJson(&out, &v, false, true); - UNIT_ASSERT_STRINGS_EQUAL(out.Str(), expected); - } - + TJsonValue v; + v["z"] = JSON_NULL; + v["n"] = JSON_NULL; + v["a"] = JSON_NULL; + v["y"] = JSON_NULL; + v["j"] = JSON_NULL; + TStringStream out; + WriteJson(&out, &v, false, true); + UNIT_ASSERT_STRINGS_EQUAL(out.Str(), expected); + } + Y_UNIT_TEST(SimpleUnsignedIntegerWriteTest) { { TString expected = "{\"test\":1}"; diff --git a/library/cpp/json/writer/README b/library/cpp/json/writer/README index a20489f32e..6e6f754658 100644 --- a/library/cpp/json/writer/README +++ b/library/cpp/json/writer/README @@ -1,23 +1,23 @@ -JSON writer with no external dependencies, producing output -where HTML special characters are always escaped. - -Use it like this: - +JSON writer with no external dependencies, producing output +where HTML special characters are always escaped. + +Use it like this: + #include <library/cpp/json/writer/json.h> - ... - - NJsonWriter::TBuf json; - json.BeginList() - .WriteString("<script>") - .EndList(); - Cout << json.Str(); // output: ["\u003Cscript\u003E"] - -For compatibility with legacy formats where object keys -are not quoted, use CompatWriteKeyWithoutQuotes: - - NJsonWriter::TBuf json; - json.BeginObject() - .CompatWriteKeyWithoutQuotes("r").WriteInt(1) - .CompatWriteKeyWithoutQuotes("n").WriteInt(0) - .EndObject(); - Cout << json.Str(); // output: {r:1,n:0} + ... + + NJsonWriter::TBuf json; + json.BeginList() + .WriteString("<script>") + .EndList(); + Cout << json.Str(); // output: ["\u003Cscript\u003E"] + +For compatibility with legacy formats where object keys +are not quoted, use CompatWriteKeyWithoutQuotes: + + NJsonWriter::TBuf json; + json.BeginObject() + .CompatWriteKeyWithoutQuotes("r").WriteInt(1) + .CompatWriteKeyWithoutQuotes("n").WriteInt(0) + .EndObject(); + Cout << json.Str(); // output: {r:1,n:0} diff --git a/library/cpp/json/writer/json.cpp b/library/cpp/json/writer/json.cpp index 02370c2d79..50523bf754 100644 --- a/library/cpp/json/writer/json.cpp +++ b/library/cpp/json/writer/json.cpp @@ -1,14 +1,14 @@ -#include "json.h" +#include "json.h" #include <library/cpp/json/json_value.h> #include <util/string/cast.h> #include <util/string/strspn.h> -#include <util/generic/algorithm.h> -#include <util/generic/ymath.h> +#include <util/generic/algorithm.h> +#include <util/generic/ymath.h> #include <util/generic/singleton.h> - -namespace NJsonWriter { + +namespace NJsonWriter { TBuf::TBuf(EHtmlEscapeMode mode, IOutputStream* stream) : Stream(stream) , NeedComma(false) @@ -25,7 +25,7 @@ namespace NJsonWriter { StringStream.Reset(new TStringStream); Stream = StringStream.Get(); } - + Stack.reserve(64); // should be enough for most cases StackPush(JE_OUTER_SPACE); } @@ -47,12 +47,12 @@ namespace NJsonWriter { 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(); @@ -81,8 +81,8 @@ namespace NJsonWriter { << EntityToStr(StackTop()) << " on the stack"; } StackPop(); - } - + } + void TBuf::PrintIndentation(bool closing) { if (!IndentSpaces) return; @@ -126,7 +126,7 @@ namespace NJsonWriter { } WriteComma(); } - + inline void TBuf::BeginKey() { if (Y_UNLIKELY(!KeyExpected())) { ythrow TError() << "JSON writer: key written outside of an object"; @@ -135,14 +135,14 @@ namespace NJsonWriter { StackPush(JE_PAIR); NeedComma = false; NeedNewline = false; - } + } inline void TBuf::EndValue() { if (StackTop() == JE_PAIR) { StackPop(); } } - + TValueContext TBuf::BeginList() { NeedNewline = true; BeginValue(); @@ -150,8 +150,8 @@ namespace NJsonWriter { StackPush(JE_LIST); NeedComma = false; return TValueContext(*this); - } - + } + TPairContext TBuf::BeginObject() { NeedNewline = true; BeginValue(); @@ -159,28 +159,28 @@ namespace NJsonWriter { 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'; })); @@ -194,44 +194,44 @@ namespace NJsonWriter { 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); } - + 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 @@ -239,14 +239,14 @@ namespace NJsonWriter { 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 @@ -271,7 +271,7 @@ namespace NJsonWriter { TValueContext TBuf::WriteDouble(double f, EFloatToStringMode mode, int ndigits) { return WriteFloatImpl(f, mode, ndigits); } - + namespace { struct TFinder: public TCompactStrSpn { inline TFinder() @@ -306,12 +306,12 @@ namespace NJsonWriter { } 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); @@ -319,13 +319,13 @@ namespace NJsonWriter { 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) { @@ -337,11 +337,11 @@ namespace NJsonWriter { 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 '/': @@ -356,16 +356,16 @@ namespace NJsonWriter { return true; } // for other characters, fall through to the non-escaped part - } - + } + switch (c) { - MATCH('"', "\\\""); - MATCH('\\', "\\\\"); - MATCH('\b', "\\b"); - MATCH('\f', "\\f"); - MATCH('\n', "\\n"); - MATCH('\r', "\\r"); - MATCH('\t', "\\t"); + MATCH('"', "\\\""); + MATCH('\\', "\\\\"); + MATCH('\b', "\\b"); + MATCH('\f', "\\f"); + MATCH('\n', "\\n"); + MATCH('\r', "\\r"); + MATCH('\t', "\\t"); } if (c < 0x20) { UnsafeWriteRawBytes(beg, cur - beg); @@ -374,14 +374,14 @@ namespace NJsonWriter { } return false; - } + } #undef MATCH 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()) { @@ -411,7 +411,7 @@ namespace NJsonWriter { WriteJsonValue(&it, sortKeys, mode, ndigits); EndList(); break; - } + } case JSON_MAP: { BeginObject(); const TJsonValue::TMapType& map = v->GetMap(); @@ -436,10 +436,10 @@ namespace NJsonWriter { } EndObject(); break; - } - } + } + } return TValueContext(*this); - } + } TPairContext TBuf::UnsafeWritePair(const TStringBuf& s) { if (Y_UNLIKELY(StackTop() != JE_OBJECT)) { @@ -448,28 +448,28 @@ namespace NJsonWriter { WriteComma(); UnsafeWriteRawBytes(s); return TPairContext(*this); - } - + } + 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::UnsafeWriteRawBytes(const char* src, size_t len) { Stream->Write(src, len); } - + void TBuf::UnsafeWriteRawBytes(const TStringBuf& s) { UnsafeWriteRawBytes(s.data(), s.size()); } - + const TString& TBuf::Str() const { if (!StringStream) { ythrow TError() << "JSON writer: Str() called " @@ -480,7 +480,7 @@ namespace NJsonWriter { } return StringStream->Str(); } - + void TBuf::FlushTo(IOutputStream* stream) { if (!StringStream) { ythrow TError() << "JSON writer: FlushTo() called " @@ -488,7 +488,7 @@ namespace NJsonWriter { } stream->Write(StringStream->Str()); StringStream->Clear(); - } + } TString WrapJsonToCallback(const TBuf& buf, TStringBuf callback) { if (!callback) { @@ -496,12 +496,12 @@ namespace NJsonWriter { } 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; diff --git a/library/cpp/json/writer/json.h b/library/cpp/json/writer/json.h index 0aae2531b9..f8e0783574 100644 --- a/library/cpp/json/writer/json.h +++ b/library/cpp/json/writer/json.h @@ -1,38 +1,38 @@ -#pragma once - -#include <util/generic/noncopyable.h> -#include <util/generic/ptr.h> +#pragma once + +#include <util/generic/noncopyable.h> +#include <util/generic/ptr.h> #include <util/generic/string.h> -#include <util/generic/vector.h> -#include <util/generic/yexception.h> -#include <util/stream/str.h> +#include <util/generic/vector.h> +#include <util/generic/yexception.h> +#include <util/stream/str.h> #include <util/string/cast.h> - -namespace NJson { - class TJsonValue; -} - -namespace NJsonWriter { + +namespace NJson { + class TJsonValue; +} + +namespace NJsonWriter { enum EJsonEntity : ui8 { - JE_OUTER_SPACE = 1, - JE_LIST, - JE_OBJECT, - JE_PAIR, - }; - - enum EHtmlEscapeMode { - HEM_ESCAPE_HTML = 1, // Use HTML escaping: < > & \/ - HEM_DONT_ESCAPE_HTML, // Use JSON escaping: \u003C \u003E \u0026 \/ - HEM_RELAXED, // Use JSON escaping: \u003C \u003E \u0026 / - HEM_UNSAFE, // Turn escaping off: < > & / - }; - - class TError: public yexception {}; - - class TValueContext; - class TPairContext; - class TAfterColonContext; - + JE_OUTER_SPACE = 1, + JE_LIST, + JE_OBJECT, + JE_PAIR, + }; + + enum EHtmlEscapeMode { + HEM_ESCAPE_HTML = 1, // Use HTML escaping: < > & \/ + HEM_DONT_ESCAPE_HTML, // Use JSON escaping: \u003C \u003E \u0026 \/ + HEM_RELAXED, // Use JSON escaping: \u003C \u003E \u0026 / + HEM_UNSAFE, // Turn escaping off: < > & / + }; + + class TError: public yexception {}; + + class TValueContext; + class TPairContext; + class TAfterColonContext; + struct TBufState { bool NeedComma; bool NeedNewline; @@ -40,102 +40,102 @@ namespace NJsonWriter { }; class TBuf : TNonCopyable { - public: + public: TBuf(EHtmlEscapeMode mode = HEM_DONT_ESCAPE_HTML, IOutputStream* stream = nullptr); - + TValueContext WriteString(const TStringBuf& s, EHtmlEscapeMode hem); TValueContext WriteString(const TStringBuf& s); - TValueContext WriteInt(int i); + TValueContext WriteInt(int i); TValueContext WriteLongLong(long long i); TValueContext WriteULongLong(unsigned long long i); TValueContext WriteFloat(float f, EFloatToStringMode mode = PREC_NDIGITS, int ndigits = 6); TValueContext WriteDouble(double f, EFloatToStringMode mode = PREC_NDIGITS, int ndigits = 10); - TValueContext WriteBool(bool b); - TValueContext WriteNull(); + TValueContext WriteBool(bool b); + TValueContext WriteNull(); TValueContext WriteJsonValue(const NJson::TJsonValue* value, bool sortKeys = false, EFloatToStringMode mode = PREC_NDIGITS, int ndigits = 10); - - TValueContext BeginList(); - TBuf& EndList(); - - TPairContext BeginObject(); + + TValueContext BeginList(); + TBuf& EndList(); + + TPairContext BeginObject(); TAfterColonContext WriteKey(const TStringBuf& key, EHtmlEscapeMode hem); TAfterColonContext WriteKey(const TStringBuf& key); TAfterColonContext UnsafeWriteKey(const TStringBuf& key); bool KeyExpected() const { return Stack.back() == JE_OBJECT; } - - //! deprecated, do not use in new code + + //! deprecated, do not use in new code TAfterColonContext CompatWriteKeyWithoutQuotes(const TStringBuf& key); - - TBuf& EndObject(); - - /*** Indent the resulting JSON with spaces. - * By default (spaces==0) no formatting is done. */ - TBuf& SetIndentSpaces(int spaces) { - IndentSpaces = spaces; - return *this; - } - + + TBuf& EndObject(); + + /*** Indent the resulting JSON with spaces. + * By default (spaces==0) no formatting is done. */ + TBuf& SetIndentSpaces(int spaces) { + IndentSpaces = spaces; + return *this; + } + /*** NaN and Inf are not valid json values, * so if WriteNanAsString is set, writer would write string * intead of throwing exception (default case) */ - TBuf& SetWriteNanAsString(bool writeNanAsString = true) { + TBuf& SetWriteNanAsString(bool writeNanAsString = true) { WriteNanAsString = writeNanAsString; - return *this; + return *this; } - /*** Return the string formed in the internal TStringStream. - * You may only call it if the `stream' parameter was NULL - * at construction time. */ + /*** Return the string formed in the internal TStringStream. + * You may only call it if the `stream' parameter was NULL + * at construction time. */ const TString& Str() const; - - /*** Dump and forget the string constructed so far. - * You may only call it if the `stream' parameter was NULL - * at construction time. */ + + /*** Dump and forget the string constructed so far. + * You may only call it if the `stream' parameter was NULL + * at construction time. */ void FlushTo(IOutputStream* stream); - - /*** Write a literal string that represents a JSON value - * (string, number, object, array, bool, or null). - * - * Example: - * j.UnsafeWriteValue("[1, 2, 3, \"o'clock\", 4, \"o'clock rock\"]"); - * - * As in all of the Unsafe* functions, no escaping is done. */ + + /*** Write a literal string that represents a JSON value + * (string, number, object, array, bool, or null). + * + * Example: + * j.UnsafeWriteValue("[1, 2, 3, \"o'clock\", 4, \"o'clock rock\"]"); + * + * As in all of the Unsafe* functions, no escaping is done. */ void UnsafeWriteValue(const TStringBuf& s); - void UnsafeWriteValue(const char* s, size_t len); - - /*** When in the context of an object, write a literal string - * that represents a key:value pair (or several pairs). - * - * Example: - * j.BeginObject(); - * j.UnsafeWritePair("\"adam\": \"male\", \"eve\": \"female\""); - * j.EndObject(); - * - * As in all of the Unsafe* functions, no escaping is done. */ + void UnsafeWriteValue(const char* s, size_t len); + + /*** When in the context of an object, write a literal string + * that represents a key:value pair (or several pairs). + * + * Example: + * j.BeginObject(); + * j.UnsafeWritePair("\"adam\": \"male\", \"eve\": \"female\""); + * j.EndObject(); + * + * As in all of the Unsafe* functions, no escaping is done. */ TPairContext UnsafeWritePair(const TStringBuf& s); - - /*** Copy the supplied string directly into the output stream. */ + + /*** Copy the supplied string directly into the output stream. */ void UnsafeWriteRawBytes(const TStringBuf& s); - void UnsafeWriteRawBytes(const char* c, size_t len); - + void UnsafeWriteRawBytes(const char* c, size_t len); + TBufState State() const; void Reset(const TBufState& from); void Reset(TBufState&& from); - private: - void BeginValue(); - void EndValue(); - void BeginKey(); - void RawWriteChar(char c); + private: + void BeginValue(); + void EndValue(); + void BeginKey(); + void RawWriteChar(char c); bool EscapedWriteChar(const char* b, const char* c, EHtmlEscapeMode hem); void WriteBareString(const TStringBuf s, EHtmlEscapeMode hem); - void WriteComma(); - void PrintIndentation(bool closing); + void WriteComma(); + void PrintIndentation(bool closing); void PrintWhitespaces(size_t count, bool prependWithNewLine); - void WriteHexEscape(unsigned char c); - + void WriteHexEscape(unsigned char c); + void StackPush(EJsonEntity e); void StackPop(); void CheckAndPop(EJsonEntity e); @@ -146,23 +146,23 @@ namespace NJsonWriter { private: IOutputStream* Stream; - THolder<TStringStream> StringStream; + THolder<TStringStream> StringStream; typedef TVector<const TString*> TKeys; TKeys Keys; TVector<EJsonEntity> Stack; - bool NeedComma; + bool NeedComma; bool NeedNewline; - const EHtmlEscapeMode EscapeMode; - int IndentSpaces; + const EHtmlEscapeMode EscapeMode; + int IndentSpaces; bool WriteNanAsString; - }; - - // Please don't try to instantiate the classes declared below this point. - + }; + + // Please don't try to instantiate the classes declared below this point. + template <typename TOutContext> class TValueWriter { - public: + public: TOutContext WriteNull(); TOutContext WriteString(const TStringBuf&); TOutContext WriteString(const TStringBuf& s, EHtmlEscapeMode hem); @@ -177,82 +177,82 @@ namespace NJsonWriter { TOutContext WriteJsonValue(const NJson::TJsonValue* value, bool sortKeys = false); TOutContext UnsafeWriteValue(const TStringBuf&); - TValueContext BeginList(); - TPairContext BeginObject(); - - protected: - TValueWriter(TBuf& buf) - : Buf(buf) + TValueContext BeginList(); + TPairContext BeginObject(); + + protected: + TValueWriter(TBuf& buf) + : Buf(buf) { } - friend class TBuf; - - protected: - TBuf& Buf; - }; - - class TValueContext: public TValueWriter<TValueContext> { - public: - TBuf& EndList() { - return Buf.EndList(); - } + friend class TBuf; + + protected: + TBuf& Buf; + }; + + class TValueContext: public TValueWriter<TValueContext> { + public: + TBuf& EndList() { + return Buf.EndList(); + } TString Str() const { return Buf.Str(); } - private: - TValueContext(TBuf& buf) - : TValueWriter<TValueContext>(buf) + private: + TValueContext(TBuf& buf) + : TValueWriter<TValueContext>(buf) { } - friend class TBuf; - friend class TValueWriter<TValueContext>; - }; - - class TAfterColonContext: public TValueWriter<TPairContext> { - private: + friend class TBuf; + friend class TValueWriter<TValueContext>; + }; + + class TAfterColonContext: public TValueWriter<TPairContext> { + private: TAfterColonContext(TBuf& iBuf) : TValueWriter<TPairContext>(iBuf) { } - friend class TBuf; - friend class TPairContext; - }; - - class TPairContext { - public: + friend class TBuf; + friend class TPairContext; + }; + + class TPairContext { + public: TAfterColonContext WriteKey(const TStringBuf& s, EHtmlEscapeMode hem) { - return Buf.WriteKey(s, hem); - } + return Buf.WriteKey(s, hem); + } TAfterColonContext WriteKey(const TStringBuf& s) { - return Buf.WriteKey(s); - } + return Buf.WriteKey(s); + } TAfterColonContext UnsafeWriteKey(const TStringBuf& s) { return Buf.UnsafeWriteKey(s); } TAfterColonContext CompatWriteKeyWithoutQuotes(const TStringBuf& s) { - return Buf.CompatWriteKeyWithoutQuotes(s); - } + return Buf.CompatWriteKeyWithoutQuotes(s); + } TPairContext UnsafeWritePair(const TStringBuf& s) { - return Buf.UnsafeWritePair(s); - } - TBuf& EndObject() { - return Buf.EndObject(); - } - - private: - TPairContext(TBuf& buf) - : Buf(buf) + return Buf.UnsafeWritePair(s); + } + TBuf& EndObject() { + return Buf.EndObject(); + } + + private: + TPairContext(TBuf& buf) + : Buf(buf) { } - - friend class TBuf; - friend class TValueWriter<TPairContext>; - - private: - TBuf& Buf; - }; - + + friend class TBuf; + friend class TValueWriter<TPairContext>; + + private: + TBuf& Buf; + }; + #define JSON_VALUE_WRITER_WRAP(function, params, args) \ template <typename TOutContext> \ TOutContext TValueWriter<TOutContext>::function params { \ @@ -277,13 +277,13 @@ namespace NJsonWriter { template <typename TOutContext> TValueContext TValueWriter<TOutContext>::BeginList() { - return Buf.BeginList(); - } - + return Buf.BeginList(); + } + template <typename TOutContext> TPairContext TValueWriter<TOutContext>::BeginObject() { - return Buf.BeginObject(); - } + return Buf.BeginObject(); + } 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 9980555683..d6842bcc6d 100644 --- a/library/cpp/json/writer/json_ut.cpp +++ b/library/cpp/json/writer/json_ut.cpp @@ -1,191 +1,191 @@ #include <library/cpp/testing/unittest/registar.h> #include <util/system/sanitizers.h> - -#include "json.h" + +#include "json.h" #include <library/cpp/json/json_value.h> - + #include <limits> Y_UNIT_TEST_SUITE(JsonWriter) { Y_UNIT_TEST(Struct) { - NJsonWriter::TBuf w; - w.BeginList(); - w.BeginObject() - .WriteKey("key") - .WriteString("value") - .UnsafeWritePair("\"xk\":13") - .WriteKey("key2") - .BeginList() + NJsonWriter::TBuf w; + w.BeginList(); + w.BeginObject() + .WriteKey("key") + .WriteString("value") + .UnsafeWritePair("\"xk\":13") + .WriteKey("key2") + .BeginList() .BeginObject() .EndObject() .BeginObject() .EndObject() - .EndList() + .EndList() .EndObject(); - w.WriteInt(43); - w.UnsafeWriteValue("\"x\""); - w.WriteString("..."); - w.EndList(); - const char* exp = "[{\"key\":\"value\",\"xk\":13,\"key2\":[{},{}]},43,\"x\",\"...\"]"; - UNIT_ASSERT_EQUAL(w.Str(), exp); - } + w.WriteInt(43); + w.UnsafeWriteValue("\"x\""); + w.WriteString("..."); + w.EndList(); + const char* exp = "[{\"key\":\"value\",\"xk\":13,\"key2\":[{},{}]},43,\"x\",\"...\"]"; + UNIT_ASSERT_EQUAL(w.Str(), exp); + } Y_UNIT_TEST(EscapedString) { - NJsonWriter::TBuf w(NJsonWriter::HEM_ESCAPE_HTML); - w.WriteString(" \n \r \t \007 \b \f ' <tag> &ent; \"txt\" "); + NJsonWriter::TBuf w(NJsonWriter::HEM_ESCAPE_HTML); + w.WriteString(" \n \r \t \007 \b \f ' <tag> &ent; \"txt\" "); TString ws = w.Str(); - const char* exp = "\" \\n \\r \\t \\u0007 \\b \\f ' <tag> &ent; "txt" \""; - UNIT_ASSERT_STRINGS_EQUAL(ws.c_str(), exp); - } + const char* exp = "\" \\n \\r \\t \\u0007 \\b \\f ' <tag> &ent; "txt" \""; + UNIT_ASSERT_STRINGS_EQUAL(ws.c_str(), exp); + } Y_UNIT_TEST(UnescapedString) { - NJsonWriter::TBuf w; - w.WriteString(" \n \r \t \b \f '; -- <tag> &ent; \"txt\"", NJsonWriter::HEM_DONT_ESCAPE_HTML); + NJsonWriter::TBuf w; + w.WriteString(" \n \r \t \b \f '; -- <tag> &ent; \"txt\"", NJsonWriter::HEM_DONT_ESCAPE_HTML); TString ws = w.Str(); - const char* exp = "\" \\n \\r \\t \\b \\f \\u0027; -- \\u003Ctag\\u003E &ent; \\\"txt\\\"\""; - UNIT_ASSERT_STRINGS_EQUAL(ws.c_str(), exp); - } + const char* exp = "\" \\n \\r \\t \\b \\f \\u0027; -- \\u003Ctag\\u003E &ent; \\\"txt\\\"\""; + UNIT_ASSERT_STRINGS_EQUAL(ws.c_str(), exp); + } Y_UNIT_TEST(UnescapedChaining) { - NJsonWriter::TBuf w(NJsonWriter::HEM_DONT_ESCAPE_HTML); - w.UnsafeWriteRawBytes("(", 1); - w.BeginList().WriteString("<>&'\\").BeginList(); - w.EndList().EndList(); + NJsonWriter::TBuf w(NJsonWriter::HEM_DONT_ESCAPE_HTML); + w.UnsafeWriteRawBytes("(", 1); + w.BeginList().WriteString("<>&'\\").BeginList(); + w.EndList().EndList(); TString ws = w.Str(); - const char* exp = "([\"\\u003C\\u003E&\\u0027\\\\\",[]]"; - UNIT_ASSERT_STRINGS_EQUAL(ws.c_str(), exp); - } + const char* exp = "([\"\\u003C\\u003E&\\u0027\\\\\",[]]"; + UNIT_ASSERT_STRINGS_EQUAL(ws.c_str(), exp); + } Y_UNIT_TEST(Utf8) { TString ws = NJsonWriter::TBuf().WriteString("яЯ σΣ ש א").Str(); - const char* exp = "\"яЯ σΣ ש א\""; - UNIT_ASSERT_STRINGS_EQUAL(ws.c_str(), exp); - } + const char* exp = "\"яЯ σΣ ש א\""; + UNIT_ASSERT_STRINGS_EQUAL(ws.c_str(), exp); + } Y_UNIT_TEST(WrongObject) { - NJsonWriter::TBuf w; - w.BeginObject(); - UNIT_ASSERT_EXCEPTION(w.WriteString("hehe"), NJsonWriter::TError); - } + NJsonWriter::TBuf w; + w.BeginObject(); + UNIT_ASSERT_EXCEPTION(w.WriteString("hehe"), NJsonWriter::TError); + } Y_UNIT_TEST(WrongList) { - NJsonWriter::TBuf w; - w.BeginList(); - UNIT_ASSERT_EXCEPTION(w.WriteKey("hehe"), NJsonWriter::TError); - } + NJsonWriter::TBuf w; + w.BeginList(); + UNIT_ASSERT_EXCEPTION(w.WriteKey("hehe"), NJsonWriter::TError); + } Y_UNIT_TEST(Incomplete) { - NJsonWriter::TBuf w; - w.BeginList(); - UNIT_ASSERT_EXCEPTION(w.Str(), NJsonWriter::TError); - } + NJsonWriter::TBuf w; + w.BeginList(); + UNIT_ASSERT_EXCEPTION(w.Str(), NJsonWriter::TError); + } Y_UNIT_TEST(BareKey) { - NJsonWriter::TBuf w; - w.BeginObject() + NJsonWriter::TBuf w; + w.BeginObject() .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); - } + const char* exp = "{p:1,n:0}"; + UNIT_ASSERT_STRINGS_EQUAL(ws.c_str(), exp); + } Y_UNIT_TEST(UnescapedStringInObject) { - NJsonWriter::TBuf w(NJsonWriter::HEM_DONT_ESCAPE_HTML); - w.BeginObject().WriteKey("key").WriteString("</&>'").EndObject(); + NJsonWriter::TBuf w(NJsonWriter::HEM_DONT_ESCAPE_HTML); + w.BeginObject().WriteKey("key").WriteString("</&>'").EndObject(); TString ws = w.Str(); - const char* exp = "{\"key\":\"\\u003C\\/&\\u003E\\u0027\"}"; - UNIT_ASSERT_STRINGS_EQUAL(ws.c_str(), exp); - } + const char* exp = "{\"key\":\"\\u003C\\/&\\u003E\\u0027\"}"; + UNIT_ASSERT_STRINGS_EQUAL(ws.c_str(), exp); + } Y_UNIT_TEST(ForeignStreamStr) { - NJsonWriter::TBuf w(NJsonWriter::HEM_DONT_ESCAPE_HTML, &Cerr); - UNIT_ASSERT_EXCEPTION(w.Str(), NJsonWriter::TError); - } + NJsonWriter::TBuf w(NJsonWriter::HEM_DONT_ESCAPE_HTML, &Cerr); + UNIT_ASSERT_EXCEPTION(w.Str(), NJsonWriter::TError); + } Y_UNIT_TEST(ForeignStreamValue) { - TStringStream ss; - NJsonWriter::TBuf w(NJsonWriter::HEM_DONT_ESCAPE_HTML, &ss); - w.WriteInt(1543); - UNIT_ASSERT_STRINGS_EQUAL(ss.Str(), "1543"); - } + TStringStream ss; + NJsonWriter::TBuf w(NJsonWriter::HEM_DONT_ESCAPE_HTML, &ss); + w.WriteInt(1543); + UNIT_ASSERT_STRINGS_EQUAL(ss.Str(), "1543"); + } Y_UNIT_TEST(Indentation) { - NJsonWriter::TBuf w(NJsonWriter::HEM_DONT_ESCAPE_HTML); - w.SetIndentSpaces(2); - w.BeginList() - .WriteInt(1) - .WriteString("hello") - .BeginObject() + NJsonWriter::TBuf w(NJsonWriter::HEM_DONT_ESCAPE_HTML); + w.SetIndentSpaces(2); + w.BeginList() + .WriteInt(1) + .WriteString("hello") + .BeginObject() .WriteKey("abc") .WriteInt(3) .WriteKey("def") .WriteInt(4) - .EndObject() + .EndObject() .EndList(); - const char* exp = "[\n" - " 1,\n" - " \"hello\",\n" - " {\n" + const char* exp = "[\n" + " 1,\n" + " \"hello\",\n" + " {\n" " \"abc\":3,\n" " \"def\":4\n" - " }\n" - "]"; - UNIT_ASSERT_STRINGS_EQUAL(exp, w.Str()); - } + " }\n" + "]"; + UNIT_ASSERT_STRINGS_EQUAL(exp, w.Str()); + } Y_UNIT_TEST(WriteJsonValue) { - using namespace NJson; - TJsonValue val; - val.AppendValue(1); - val.AppendValue("2"); - val.AppendValue(3.5); - TJsonValue obj; - obj.InsertValue("key", TJsonValue("value")); - - val.AppendValue(obj); - val.AppendValue(TJsonValue(JSON_NULL)); - - NJsonWriter::TBuf w(NJsonWriter::HEM_DONT_ESCAPE_HTML); - w.WriteJsonValue(&val); - - const char exp[] = "[1,\"2\",3.5,{\"key\":\"value\"},null]"; - UNIT_ASSERT_STRINGS_EQUAL(exp, w.Str()); - } + using namespace NJson; + TJsonValue val; + val.AppendValue(1); + val.AppendValue("2"); + val.AppendValue(3.5); + TJsonValue obj; + obj.InsertValue("key", TJsonValue("value")); + + val.AppendValue(obj); + val.AppendValue(TJsonValue(JSON_NULL)); + + NJsonWriter::TBuf w(NJsonWriter::HEM_DONT_ESCAPE_HTML); + w.WriteJsonValue(&val); + + const char exp[] = "[1,\"2\",3.5,{\"key\":\"value\"},null]"; + UNIT_ASSERT_STRINGS_EQUAL(exp, w.Str()); + } Y_UNIT_TEST(WriteJsonValueSorted) { - using namespace NJson; - TJsonValue val; - val.InsertValue("1", TJsonValue(1)); - val.InsertValue("2", TJsonValue(2)); - - TJsonValue obj; - obj.InsertValue("zero", TJsonValue(0)); - obj.InsertValue("succ", TJsonValue(1)); - val.InsertValue("0", obj); - - NJsonWriter::TBuf w(NJsonWriter::HEM_DONT_ESCAPE_HTML); - w.WriteJsonValue(&val, true); - - const char exp[] = "{\"0\":{\"succ\":1,\"zero\":0},\"1\":1,\"2\":2}"; - UNIT_ASSERT_STRINGS_EQUAL(exp, w.Str()); - } + using namespace NJson; + TJsonValue val; + val.InsertValue("1", TJsonValue(1)); + val.InsertValue("2", TJsonValue(2)); + + TJsonValue obj; + obj.InsertValue("zero", TJsonValue(0)); + obj.InsertValue("succ", TJsonValue(1)); + val.InsertValue("0", obj); + + NJsonWriter::TBuf w(NJsonWriter::HEM_DONT_ESCAPE_HTML); + w.WriteJsonValue(&val, true); + + const char exp[] = "{\"0\":{\"succ\":1,\"zero\":0},\"1\":1,\"2\":2}"; + UNIT_ASSERT_STRINGS_EQUAL(exp, w.Str()); + } Y_UNIT_TEST(Unescaped) { - NJsonWriter::TBuf buf(NJsonWriter::HEM_UNSAFE); - buf.WriteString("</security>'"); - UNIT_ASSERT_STRINGS_EQUAL("\"</security>'\"", buf.Str()); - } + NJsonWriter::TBuf buf(NJsonWriter::HEM_UNSAFE); + buf.WriteString("</security>'"); + UNIT_ASSERT_STRINGS_EQUAL("\"</security>'\"", buf.Str()); + } Y_UNIT_TEST(LittleBobbyJsonp) { - NJsonWriter::TBuf buf; - buf.WriteString("hello\xe2\x80\xa8\xe2\x80\xa9stranger"); - UNIT_ASSERT_STRINGS_EQUAL("\"hello\\u2028\\u2029stranger\"", buf.Str()); - } + NJsonWriter::TBuf buf; + buf.WriteString("hello\xe2\x80\xa8\xe2\x80\xa9stranger"); + UNIT_ASSERT_STRINGS_EQUAL("\"hello\\u2028\\u2029stranger\"", buf.Str()); + } Y_UNIT_TEST(LittleBobbyInvalid) { - NJsonWriter::TBuf buf; - TStringBuf incomplete("\xe2\x80\xa8", 2); - buf.WriteString(incomplete); - // garbage in - garbage out - UNIT_ASSERT_STRINGS_EQUAL("\"\xe2\x80\"", buf.Str()); - } + NJsonWriter::TBuf buf; + TStringBuf incomplete("\xe2\x80\xa8", 2); + buf.WriteString(incomplete); + // garbage in - garbage out + UNIT_ASSERT_STRINGS_EQUAL("\"\xe2\x80\"", buf.Str()); + } Y_UNIT_TEST(OverlyZealous) { - NJsonWriter::TBuf buf; - buf.WriteString("—"); - UNIT_ASSERT_STRINGS_EQUAL("\"—\"", buf.Str()); - } + NJsonWriter::TBuf buf; + buf.WriteString("—"); + UNIT_ASSERT_STRINGS_EQUAL("\"—\"", buf.Str()); + } Y_UNIT_TEST(RelaxedEscaping) { - NJsonWriter::TBuf buf(NJsonWriter::HEM_RELAXED); - buf.WriteString("</>"); - UNIT_ASSERT_STRINGS_EQUAL("\"\\u003C/\\u003E\"", buf.Str()); - } + NJsonWriter::TBuf buf(NJsonWriter::HEM_RELAXED); + buf.WriteString("</>"); + UNIT_ASSERT_STRINGS_EQUAL("\"\\u003C/\\u003E\"", buf.Str()); + } Y_UNIT_TEST(FloatFormatting) { NJsonWriter::TBuf buf(NJsonWriter::HEM_DONT_ESCAPE_HTML); @@ -304,4 +304,4 @@ Y_UNIT_TEST_SUITE(JsonWriter) { // doesn't really matter UNIT_ASSERT(!p.empty()); } -} +} diff --git a/library/cpp/json/writer/json_value.cpp b/library/cpp/json/writer/json_value.cpp index c61e8d1dc4..26fa35eed3 100644 --- a/library/cpp/json/writer/json_value.cpp +++ b/library/cpp/json/writer/json_value.cpp @@ -1,5 +1,5 @@ #include "json_value.h" -#include "json.h" +#include "json.h" #include <util/generic/ymath.h> #include <util/generic/ylimits.h> @@ -161,7 +161,7 @@ namespace NJson { Value.Double = value; } - TJsonValue::TJsonValue(TString value) { + TJsonValue::TJsonValue(TString value) { SetType(JSON_STRING); Value.String = std::move(value); } @@ -1100,6 +1100,6 @@ namespace NJson { template <> void Out<NJson::TJsonValue>(IOutputStream& out, const NJson::TJsonValue& v) { - NJsonWriter::TBuf buf(NJsonWriter::HEM_DONT_ESCAPE_HTML, &out); - buf.WriteJsonValue(&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 3f0f50bc4c..b24029b8bb 100644 --- a/library/cpp/json/writer/json_value.h +++ b/library/cpp/json/writer/json_value.h @@ -48,7 +48,7 @@ namespace NJson { TJsonValue(long long value) noexcept; TJsonValue(unsigned long long value) noexcept; TJsonValue(double value) noexcept; - TJsonValue(TString value); + TJsonValue(TString value); TJsonValue(const char* value); template <class T> TJsonValue(const T*) = delete; diff --git a/library/cpp/json/writer/ya.make b/library/cpp/json/writer/ya.make index 3989ff3504..cfbab3c818 100644 --- a/library/cpp/json/writer/ya.make +++ b/library/cpp/json/writer/ya.make @@ -1,4 +1,4 @@ -LIBRARY() +LIBRARY() OWNER( mvel @@ -9,12 +9,12 @@ OWNER( PEERDIR( library/cpp/json/common ) - -SRCS( - json_value.cpp - json.cpp -) - + +SRCS( + json_value.cpp + json.cpp +) + GENERATE_ENUM_SERIALIZATION(json_value.h) -END() +END() |