diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/yson/json/json_writer.cpp | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/yson/json/json_writer.cpp')
-rw-r--r-- | library/cpp/yson/json/json_writer.cpp | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/library/cpp/yson/json/json_writer.cpp b/library/cpp/yson/json/json_writer.cpp new file mode 100644 index 0000000000..87481256ec --- /dev/null +++ b/library/cpp/yson/json/json_writer.cpp @@ -0,0 +1,220 @@ +#include "json_writer.h" + +#include <library/cpp/json/json_writer.h> + +namespace NYT { + //////////////////////////////////////////////////////////////////////////////// + + static bool IsSpecialJsonKey(const TStringBuf& key) { + return key.size() > 0 && key[0] == '$'; + } + + //////////////////////////////////////////////////////////////////////////////// + + TJsonWriter::TJsonWriter( + IOutputStream* output, + ::NYson::EYsonType type, + EJsonFormat format, + EJsonAttributesMode attributesMode, + ESerializedBoolFormat booleanFormat) + : TJsonWriter( + output, + NJson::TJsonWriterConfig{}.SetFormatOutput(format == JF_PRETTY), + type, + attributesMode, + booleanFormat + ) + {} + + TJsonWriter::TJsonWriter( + IOutputStream* output, + NJson::TJsonWriterConfig config, + ::NYson::EYsonType type, + EJsonAttributesMode attributesMode, + ESerializedBoolFormat booleanFormat) + : Output(output) + , Type(type) + , AttributesMode(attributesMode) + , BooleanFormat(booleanFormat) + , Depth(0) + { + if (Type == ::NYson::EYsonType::MapFragment) { + ythrow ::NYson::TYsonException() << ("Map fragments are not supported by Json"); + } + + UnderlyingJsonWriter.Reset(new NJson::TJsonWriter( + output, + config)); + JsonWriter = UnderlyingJsonWriter.Get(); + HasAttributes = false; + InAttributesBalance = 0; + } + + void TJsonWriter::EnterNode() { + if (AttributesMode == JAM_NEVER) { + HasAttributes = false; + } else if (AttributesMode == JAM_ON_DEMAND) { + // Do nothing + } else if (AttributesMode == JAM_ALWAYS) { + if (!HasAttributes) { + JsonWriter->OpenMap(); + JsonWriter->Write("$attributes"); + JsonWriter->OpenMap(); + JsonWriter->CloseMap(); + } + HasAttributes = true; + } + HasUnfoldedStructureStack.push_back(HasAttributes); + + if (HasAttributes) { + JsonWriter->Write("$value"); + HasAttributes = false; + } + + Depth += 1; + } + + void TJsonWriter::LeaveNode() { + Y_ASSERT(!HasUnfoldedStructureStack.empty()); + if (HasUnfoldedStructureStack.back()) { + // Close map of the {$attributes, $value} + JsonWriter->CloseMap(); + } + HasUnfoldedStructureStack.pop_back(); + + Depth -= 1; + + if (Depth == 0 && Type == ::NYson::EYsonType::ListFragment && InAttributesBalance == 0) { + JsonWriter->Flush(); + Output->Write("\n"); + } + } + + bool TJsonWriter::IsWriteAllowed() { + if (AttributesMode == JAM_NEVER) { + return InAttributesBalance == 0; + } + return true; + } + + void TJsonWriter::OnStringScalar(TStringBuf value) { + if (IsWriteAllowed()) { + EnterNode(); + WriteStringScalar(value); + LeaveNode(); + } + } + + void TJsonWriter::OnInt64Scalar(i64 value) { + if (IsWriteAllowed()) { + EnterNode(); + JsonWriter->Write(value); + LeaveNode(); + } + } + + void TJsonWriter::OnUint64Scalar(ui64 value) { + if (IsWriteAllowed()) { + EnterNode(); + JsonWriter->Write(value); + LeaveNode(); + } + } + + void TJsonWriter::OnDoubleScalar(double value) { + if (IsWriteAllowed()) { + EnterNode(); + JsonWriter->Write(value); + LeaveNode(); + } + } + + void TJsonWriter::OnBooleanScalar(bool value) { + if (IsWriteAllowed()) { + if (BooleanFormat == SBF_STRING) { + OnStringScalar(value ? "true" : "false"); + } else { + EnterNode(); + JsonWriter->Write(value); + LeaveNode(); + } + } + } + + void TJsonWriter::OnEntity() { + if (IsWriteAllowed()) { + EnterNode(); + JsonWriter->WriteNull(); + LeaveNode(); + } + } + + void TJsonWriter::OnBeginList() { + if (IsWriteAllowed()) { + EnterNode(); + JsonWriter->OpenArray(); + } + } + + void TJsonWriter::OnListItem() { + } + + void TJsonWriter::OnEndList() { + if (IsWriteAllowed()) { + JsonWriter->CloseArray(); + LeaveNode(); + } + } + + void TJsonWriter::OnBeginMap() { + if (IsWriteAllowed()) { + EnterNode(); + JsonWriter->OpenMap(); + } + } + + void TJsonWriter::OnKeyedItem(TStringBuf name) { + if (IsWriteAllowed()) { + if (IsSpecialJsonKey(name)) { + WriteStringScalar(TString("$") + name); + } else { + WriteStringScalar(name); + } + } + } + + void TJsonWriter::OnEndMap() { + if (IsWriteAllowed()) { + JsonWriter->CloseMap(); + LeaveNode(); + } + } + + void TJsonWriter::OnBeginAttributes() { + InAttributesBalance += 1; + if (AttributesMode != JAM_NEVER) { + JsonWriter->OpenMap(); + JsonWriter->Write("$attributes"); + JsonWriter->OpenMap(); + } + } + + void TJsonWriter::OnEndAttributes() { + InAttributesBalance -= 1; + if (AttributesMode != JAM_NEVER) { + HasAttributes = true; + JsonWriter->CloseMap(); + } + } + + void TJsonWriter::WriteStringScalar(const TStringBuf& value) { + JsonWriter->Write(value); + } + + void TJsonWriter::Flush() { + JsonWriter->Flush(); + } + + //////////////////////////////////////////////////////////////////////////////// + +} |