123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- #include "json_writer.h"
- #include <util/charset/utf8.h>
- #include <util/generic/algorithm.h>
- #include <util/string/cast.h>
- #include <util/system/yassert.h>
- namespace NJson {
- 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)
- , 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);
- }
- }
- void TJsonWriter::OpenMap() {
- Buf.BeginObject();
- }
- void TJsonWriter::CloseMap() {
- Buf.EndObject();
- }
- void TJsonWriter::OpenArray() {
- Buf.BeginList();
- }
- 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);
- } else {
- if (DontEscapeStrings) {
- Buf.UnsafeWriteValue(TString("\"") + value + '"');
- } else {
- Buf.WriteString(value);
- }
- }
- }
- void TJsonWriter::WriteNull() {
- Buf.WriteNull();
- }
- void TJsonWriter::Write(float value) {
- Buf.WriteFloat(value, FloatToStringMode, FloatNDigits);
- }
- void TJsonWriter::Write(double value) {
- Buf.WriteDouble(value, FloatToStringMode, DoubleNDigits);
- }
- void TJsonWriter::Write(long long value) {
- Buf.WriteLongLong(value);
- }
- void TJsonWriter::Write(unsigned long long value) {
- Buf.WriteULongLong(value);
- }
- void TJsonWriter::Write(bool value) {
- Buf.WriteBool(value);
- }
- namespace {
- struct TLessStrPtr {
- bool operator()(const TString* a, const TString* b) const {
- return *a < *b;
- }
- };
- }
- 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();
- }
- }
|