json_writer.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #include "json_writer.h"
  2. #include <util/charset/utf8.h>
  3. #include <util/generic/algorithm.h>
  4. #include <util/string/cast.h>
  5. #include <util/system/yassert.h>
  6. namespace NJson {
  7. TJsonWriter::TJsonWriter(IOutputStream* out, bool formatOutput, bool sortkeys, bool validateUtf8)
  8. : Out(out)
  9. , Buf(NJsonWriter::HEM_UNSAFE)
  10. , DoubleNDigits(TJsonWriterConfig::DefaultDoubleNDigits)
  11. , FloatNDigits(TJsonWriterConfig::DefaultFloatNDigits)
  12. , FloatToStringMode(TJsonWriterConfig::DefaultFloatToStringMode)
  13. , SortKeys(sortkeys)
  14. , ValidateUtf8(validateUtf8)
  15. , DontEscapeStrings(false)
  16. , DontFlushInDestructor(false)
  17. {
  18. Buf.SetIndentSpaces(formatOutput ? 2 : 0);
  19. }
  20. TJsonWriter::TJsonWriter(IOutputStream* out, const TJsonWriterConfig& config, bool DFID)
  21. : Out(config.Unbuffered ? nullptr : out)
  22. , Buf(NJsonWriter::HEM_UNSAFE, config.Unbuffered ? out : nullptr)
  23. , DoubleNDigits(config.DoubleNDigits)
  24. , FloatNDigits(config.FloatNDigits)
  25. , FloatToStringMode(config.FloatToStringMode)
  26. , SortKeys(config.SortKeys)
  27. , ValidateUtf8(config.ValidateUtf8)
  28. , DontEscapeStrings(config.DontEscapeStrings)
  29. , DontFlushInDestructor(DFID)
  30. {
  31. Buf.SetIndentSpaces(config.FormatOutput ? 2 : 0);
  32. Buf.SetWriteNanAsString(config.WriteNanAsString);
  33. }
  34. TJsonWriter::~TJsonWriter() {
  35. // if we write to socket it's possible to get exception here
  36. // don't use exceptions in destructors
  37. if (!DontFlushInDestructor) {
  38. try {
  39. Flush();
  40. } catch (...) {
  41. }
  42. }
  43. }
  44. void TJsonWriter::Flush() {
  45. if (Out) {
  46. Buf.FlushTo(Out);
  47. }
  48. }
  49. void TJsonWriter::OpenMap() {
  50. Buf.BeginObject();
  51. }
  52. void TJsonWriter::CloseMap() {
  53. Buf.EndObject();
  54. }
  55. void TJsonWriter::OpenArray() {
  56. Buf.BeginList();
  57. }
  58. void TJsonWriter::CloseArray() {
  59. Buf.EndList();
  60. }
  61. void TJsonWriter::Write(const TStringBuf& value) {
  62. if (ValidateUtf8 && !IsUtf(value))
  63. throw yexception() << "JSON writer: invalid UTF-8";
  64. if (Buf.KeyExpected()) {
  65. Buf.WriteKey(value);
  66. } else {
  67. if (DontEscapeStrings) {
  68. Buf.UnsafeWriteValue(TString("\"") + value + '"');
  69. } else {
  70. Buf.WriteString(value);
  71. }
  72. }
  73. }
  74. void TJsonWriter::WriteNull() {
  75. Buf.WriteNull();
  76. }
  77. void TJsonWriter::Write(float value) {
  78. Buf.WriteFloat(value, FloatToStringMode, FloatNDigits);
  79. }
  80. void TJsonWriter::Write(double value) {
  81. Buf.WriteDouble(value, FloatToStringMode, DoubleNDigits);
  82. }
  83. void TJsonWriter::Write(long long value) {
  84. Buf.WriteLongLong(value);
  85. }
  86. void TJsonWriter::Write(unsigned long long value) {
  87. Buf.WriteULongLong(value);
  88. }
  89. void TJsonWriter::Write(bool value) {
  90. Buf.WriteBool(value);
  91. }
  92. namespace {
  93. struct TLessStrPtr {
  94. bool operator()(const TString* a, const TString* b) const {
  95. return *a < *b;
  96. }
  97. };
  98. }
  99. void TJsonWriter::Write(const TJsonValue* v) {
  100. Buf.WriteJsonValue(v, SortKeys, FloatToStringMode, DoubleNDigits);
  101. }
  102. void TJsonWriter::Write(const TJsonValue& v) {
  103. Buf.WriteJsonValue(&v, SortKeys, FloatToStringMode, DoubleNDigits);
  104. }
  105. TString WriteJson(const TJsonValue* value, bool formatOutput, bool sortkeys, bool validateUtf8) {
  106. TStringStream ss;
  107. WriteJson(&ss, value, formatOutput, sortkeys, validateUtf8);
  108. return ss.Str();
  109. }
  110. TString WriteJson(const TJsonValue& value, bool formatOutput, bool sortkeys, bool validateUtf8) {
  111. TStringStream ss;
  112. WriteJson(&ss, &value, formatOutput, sortkeys, validateUtf8);
  113. return ss.Str();
  114. }
  115. void WriteJson(IOutputStream* out, const TJsonValue* val, bool formatOutput, bool sortkeys, bool validateUtf8) {
  116. TJsonWriter w(out, formatOutput, sortkeys, validateUtf8);
  117. w.Write(val);
  118. w.Flush();
  119. }
  120. void WriteJson(IOutputStream* out, const TJsonValue* val, const TJsonWriterConfig& config) {
  121. TJsonWriter w(out, config, true);
  122. w.Write(val);
  123. w.Flush();
  124. }
  125. }