JsonDom.cc 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * https://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. #include "JsonDom.hh"
  19. #include <stdexcept>
  20. #include <cstring>
  21. #include "JsonIO.hh"
  22. #include "Stream.hh"
  23. namespace avro {
  24. namespace json {
  25. const char *typeToString(EntityType t) {
  26. switch (t) {
  27. case EntityType::Null: return "null";
  28. case EntityType::Bool: return "bool";
  29. case EntityType::Long: return "long";
  30. case EntityType::Double: return "double";
  31. case EntityType::String: return "string";
  32. case EntityType::Arr: return "array";
  33. case EntityType::Obj: return "object";
  34. default: return "unknown";
  35. }
  36. }
  37. Entity readEntity(JsonParser &p) {
  38. switch (p.peek()) {
  39. case JsonParser::Token::Null:
  40. p.advance();
  41. return Entity(p.line());
  42. case JsonParser::Token::Bool:
  43. p.advance();
  44. return Entity(p.boolValue(), p.line());
  45. case JsonParser::Token::Long:
  46. p.advance();
  47. return Entity(p.longValue(), p.line());
  48. case JsonParser::Token::Double:
  49. p.advance();
  50. return Entity(p.doubleValue(), p.line());
  51. case JsonParser::Token::String:
  52. p.advance();
  53. return Entity(std::make_shared<String>(p.rawString()), p.line());
  54. case JsonParser::Token::ArrayStart: {
  55. size_t l = p.line();
  56. p.advance();
  57. std::shared_ptr<Array> v = std::make_shared<Array>();
  58. while (p.peek() != JsonParser::Token::ArrayEnd) {
  59. v->push_back(readEntity(p));
  60. }
  61. p.advance();
  62. return Entity(v, l);
  63. }
  64. case JsonParser::Token::ObjectStart: {
  65. size_t l = p.line();
  66. p.advance();
  67. std::shared_ptr<Object> v = std::make_shared<Object>();
  68. while (p.peek() != JsonParser::Token::ObjectEnd) {
  69. p.advance();
  70. std::string k = p.stringValue();
  71. Entity n = readEntity(p);
  72. v->insert(std::make_pair(k, n));
  73. }
  74. p.advance();
  75. return Entity(v, l);
  76. }
  77. default:
  78. throw std::domain_error(JsonParser::toString(p.peek()));
  79. }
  80. }
  81. Entity loadEntity(const char *text) {
  82. return loadEntity(reinterpret_cast<const uint8_t *>(text), ::strlen(text));
  83. }
  84. Entity loadEntity(InputStream &in) {
  85. JsonParser p;
  86. p.init(in);
  87. return readEntity(p);
  88. }
  89. Entity loadEntity(const uint8_t *text, size_t len) {
  90. std::unique_ptr<InputStream> in = memoryInputStream(text, len);
  91. return loadEntity(*in);
  92. }
  93. void writeEntity(JsonGenerator<JsonNullFormatter> &g, const Entity &n) {
  94. switch (n.type()) {
  95. case EntityType::Null:
  96. g.encodeNull();
  97. break;
  98. case EntityType::Bool:
  99. g.encodeBool(n.boolValue());
  100. break;
  101. case EntityType::Long:
  102. g.encodeNumber(n.longValue());
  103. break;
  104. case EntityType::Double:
  105. g.encodeNumber(n.doubleValue());
  106. break;
  107. case EntityType::String:
  108. g.encodeString(n.stringValue());
  109. break;
  110. case EntityType::Arr: {
  111. g.arrayStart();
  112. const Array &v = n.arrayValue();
  113. for (const auto &it : v) {
  114. writeEntity(g, it);
  115. }
  116. g.arrayEnd();
  117. } break;
  118. case EntityType::Obj: {
  119. g.objectStart();
  120. const Object &v = n.objectValue();
  121. for (const auto &it : v) {
  122. g.encodeString(it.first);
  123. writeEntity(g, it.second);
  124. }
  125. g.objectEnd();
  126. } break;
  127. }
  128. }
  129. void Entity::ensureType(EntityType type) const {
  130. if (type_ != type) {
  131. throw Exception("Invalid type. Expected \"{}\" actual {}", typeToString(type), typeToString(type_));
  132. }
  133. }
  134. String Entity::stringValue() const {
  135. ensureType(EntityType::String);
  136. return JsonParser::toStringValue(**boost::any_cast<std::shared_ptr<String>>(&value_));
  137. }
  138. String Entity::bytesValue() const {
  139. ensureType(EntityType::String);
  140. return JsonParser::toBytesValue(**boost::any_cast<std::shared_ptr<String>>(&value_));
  141. }
  142. std::string Entity::toString() const {
  143. std::unique_ptr<OutputStream> out = memoryOutputStream();
  144. JsonGenerator<JsonNullFormatter> g;
  145. g.init(*out);
  146. writeEntity(g, *this);
  147. g.flush();
  148. std::unique_ptr<InputStream> in = memoryInputStream(*out);
  149. const uint8_t *p = nullptr;
  150. size_t n = 0;
  151. size_t c = 0;
  152. while (in->next(&p, &n)) {
  153. c += n;
  154. }
  155. std::string result;
  156. result.resize(c);
  157. c = 0;
  158. std::unique_ptr<InputStream> in2 = memoryInputStream(*out);
  159. while (in2->next(&p, &n)) {
  160. ::memcpy(&result[c], p, n);
  161. c += n;
  162. }
  163. return result;
  164. }
  165. } // namespace json
  166. } // namespace avro