scimpl_json_read.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. #include "scimpl.h"
  2. #include <library/cpp/json/json_reader.h>
  3. #include <util/stream/output.h>
  4. #include <util/generic/maybe.h>
  5. namespace NSc {
  6. struct TJsonError {
  7. size_t Offset = 0;
  8. TMaybe<TString> Reason;
  9. };
  10. struct TJsonDeserializer : NJson::TJsonCallbacks {
  11. struct TContainer {
  12. TValue* Container = nullptr;
  13. TValue* LastValue = nullptr;
  14. bool ExpectKey = false;
  15. TContainer(TValue& v)
  16. : Container(&v)
  17. , ExpectKey(v.IsDict())
  18. {
  19. }
  20. bool Add(TStringBuf v, bool allowDuplicated) {
  21. if (!ExpectKey || Y_UNLIKELY(!Container->IsDict()))
  22. return false;
  23. if (!allowDuplicated && Y_UNLIKELY(Container->Has(v)))
  24. return false;
  25. LastValue = &Container->GetOrAdd(v);
  26. ExpectKey = false;
  27. return true;
  28. }
  29. void Push() {
  30. LastValue = &Container->Push();
  31. }
  32. TValue& NextValue() {
  33. if (Container->IsArray()) {
  34. Push();
  35. } else if (Container->IsDict()) {
  36. ExpectKey = true;
  37. }
  38. return *(LastValue ? LastValue : Container);
  39. }
  40. bool IsArray() const {
  41. return !!Container && Container->IsArray();
  42. }
  43. bool IsDict() const {
  44. return !!Container && Container->IsDict();
  45. }
  46. };
  47. typedef TVector<TContainer> TStackType;
  48. public:
  49. TValue& Root;
  50. TJsonError& Error;
  51. const TJsonOpts& Cfg;
  52. TStackType Stack;
  53. bool Virgin = true;
  54. public:
  55. TJsonDeserializer(TValue& root, TJsonError& err, const TJsonOpts& cfg)
  56. : Root(root)
  57. , Error(err)
  58. , Cfg(cfg)
  59. {
  60. Root.SetNull();
  61. Stack.reserve(10);
  62. }
  63. bool HasNextValue() const {
  64. return Virgin | !Stack.empty();
  65. }
  66. TValue& NextValue() {
  67. Virgin = false;
  68. return Stack.empty() ? Root : Stack.back().NextValue();
  69. }
  70. bool OnNull() override {
  71. if (Y_UNLIKELY(!HasNextValue()))
  72. return false;
  73. NextValue().SetNull();
  74. return true;
  75. }
  76. bool OnEnd() override {
  77. return Stack.empty();
  78. }
  79. template <typename T>
  80. bool OnValue(T v) {
  81. if (Y_UNLIKELY(!HasNextValue()))
  82. return false;
  83. NextValue() = v;
  84. return true;
  85. }
  86. template <typename T>
  87. bool OnIntValue(T v) {
  88. if (Y_UNLIKELY(!HasNextValue()))
  89. return false;
  90. NextValue().SetIntNumber(v);
  91. return true;
  92. }
  93. bool OnBoolean(bool v) override {
  94. if (Y_UNLIKELY(!HasNextValue()))
  95. return false;
  96. NextValue().SetBool(v);
  97. return true;
  98. }
  99. bool OnInteger(long long v) override {
  100. return OnIntValue(v);
  101. }
  102. bool OnUInteger(unsigned long long v) override {
  103. return OnIntValue(v);
  104. }
  105. bool OnDouble(double v) override {
  106. return OnValue(v);
  107. }
  108. bool OnString(const TStringBuf& v) override {
  109. return OnValue(v);
  110. }
  111. bool OnMapKey(const TStringBuf& k) override {
  112. if (Y_UNLIKELY(Stack.empty()))
  113. return false;
  114. return Stack.back().Add(k, !(Cfg.Opts & TJsonOpts::JO_PARSER_DISALLOW_DUPLICATE_KEYS));
  115. }
  116. bool OnOpenMap() override {
  117. if (Y_UNLIKELY(!HasNextValue()))
  118. return false;
  119. Stack.push_back(TContainer(NextValue().SetDict()));
  120. return true;
  121. }
  122. bool OnCloseMap() override {
  123. if (Y_UNLIKELY(Stack.empty() || !Stack.back().IsDict()))
  124. return false;
  125. Stack.pop_back();
  126. return true;
  127. }
  128. bool OnOpenArray() override {
  129. if (Y_UNLIKELY(!HasNextValue()))
  130. return false;
  131. Stack.push_back(TContainer(NextValue().SetArray()));
  132. return true;
  133. }
  134. bool OnCloseArray() override {
  135. if (Y_UNLIKELY(Stack.empty() || !Stack.back().IsArray()))
  136. return false;
  137. Stack.pop_back();
  138. return true;
  139. }
  140. void OnError(size_t off, TStringBuf reason) override {
  141. Error.Offset = off;
  142. Error.Reason = reason;
  143. }
  144. };
  145. static bool DoParseFromJson(TValue& res, TJsonError& err, TStringBuf json, const TJsonOpts& cfg) {
  146. TJsonDeserializer d(res, err, cfg);
  147. if (cfg.RelaxedJson) {
  148. return NJson::ReadJsonFast(json, &d);
  149. } else {
  150. TMemoryInput min(json.data(), json.size());
  151. return NJson::ReadJson(&min, &cfg, &d);
  152. }
  153. }
  154. static bool DoParseFromJson(TValue& res, TStringBuf json, const TJsonOpts& cfg) {
  155. TJsonError err;
  156. return DoParseFromJson(res, err, json, cfg);
  157. }
  158. TValue TValue::FromJson(TStringBuf v, const TJsonOpts& cfg) {
  159. TValue res;
  160. if (FromJson(res, v, cfg)) {
  161. return res;
  162. } else {
  163. return DefaultValue();
  164. }
  165. }
  166. TValue TValue::FromJsonThrow(TStringBuf json, const TJsonOpts& cfg) {
  167. TValue res;
  168. TJsonError err;
  169. if (DoParseFromJson(res, err, json, cfg)) {
  170. return res;
  171. }
  172. TString reason = err.Reason.Empty() ? "NULL" : *err.Reason;
  173. ythrow TSchemeParseException(err.Offset, reason) << "JSON error at offset " << err.Offset << " (" << reason << ")";
  174. }
  175. bool TValue::FromJson(TValue& res, TStringBuf json, const TJsonOpts& cfg) {
  176. if (DoParseFromJson(res, json, cfg)) {
  177. return true;
  178. }
  179. res.SetNull();
  180. return false;
  181. }
  182. }