JsonDom.cc 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  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. using boost::format;
  24. using std::string;
  25. namespace avro {
  26. namespace json {
  27. const char *typeToString(EntityType t) {
  28. switch (t) {
  29. case EntityType::Null: return "null";
  30. case EntityType::Bool: return "bool";
  31. case EntityType::Long: return "long";
  32. case EntityType::Double: return "double";
  33. case EntityType::String: return "string";
  34. case EntityType::Arr: return "array";
  35. case EntityType::Obj: return "object";
  36. default: return "unknown";
  37. }
  38. }
  39. Entity readEntity(JsonParser &p) {
  40. switch (p.peek()) {
  41. case JsonParser::Token::Null:
  42. p.advance();
  43. return Entity(p.line());
  44. case JsonParser::Token::Bool:
  45. p.advance();
  46. return Entity(p.boolValue(), p.line());
  47. case JsonParser::Token::Long:
  48. p.advance();
  49. return Entity(p.longValue(), p.line());
  50. case JsonParser::Token::Double:
  51. p.advance();
  52. return Entity(p.doubleValue(), p.line());
  53. case JsonParser::Token::String:
  54. p.advance();
  55. return Entity(std::make_shared<String>(p.rawString()), p.line());
  56. case JsonParser::Token::ArrayStart: {
  57. size_t l = p.line();
  58. p.advance();
  59. std::shared_ptr<Array> v = std::make_shared<Array>();
  60. while (p.peek() != JsonParser::Token::ArrayEnd) {
  61. v->push_back(readEntity(p));
  62. }
  63. p.advance();
  64. return Entity(v, l);
  65. }
  66. case JsonParser::Token::ObjectStart: {
  67. size_t l = p.line();
  68. p.advance();
  69. std::shared_ptr<Object> v = std::make_shared<Object>();
  70. while (p.peek() != JsonParser::Token::ObjectEnd) {
  71. p.advance();
  72. std::string k = p.stringValue();
  73. Entity n = readEntity(p);
  74. v->insert(std::make_pair(k, n));
  75. }
  76. p.advance();
  77. return Entity(v, l);
  78. }
  79. default:
  80. throw std::domain_error(JsonParser::toString(p.peek()));
  81. }
  82. }
  83. Entity loadEntity(const char *text) {
  84. return loadEntity(reinterpret_cast<const uint8_t *>(text), ::strlen(text));
  85. }
  86. Entity loadEntity(InputStream &in) {
  87. JsonParser p;
  88. p.init(in);
  89. return readEntity(p);
  90. }
  91. Entity loadEntity(const uint8_t *text, size_t len) {
  92. std::unique_ptr<InputStream> in = memoryInputStream(text, len);
  93. return loadEntity(*in);
  94. }
  95. void writeEntity(JsonGenerator<JsonNullFormatter> &g, const Entity &n) {
  96. switch (n.type()) {
  97. case EntityType::Null:
  98. g.encodeNull();
  99. break;
  100. case EntityType::Bool:
  101. g.encodeBool(n.boolValue());
  102. break;
  103. case EntityType::Long:
  104. g.encodeNumber(n.longValue());
  105. break;
  106. case EntityType::Double:
  107. g.encodeNumber(n.doubleValue());
  108. break;
  109. case EntityType::String:
  110. g.encodeString(n.stringValue());
  111. break;
  112. case EntityType::Arr: {
  113. g.arrayStart();
  114. const Array &v = n.arrayValue();
  115. for (const auto &it : v) {
  116. writeEntity(g, it);
  117. }
  118. g.arrayEnd();
  119. } break;
  120. case EntityType::Obj: {
  121. g.objectStart();
  122. const Object &v = n.objectValue();
  123. for (const auto &it : v) {
  124. g.encodeString(it.first);
  125. writeEntity(g, it.second);
  126. }
  127. g.objectEnd();
  128. } break;
  129. }
  130. }
  131. void Entity::ensureType(EntityType type) const {
  132. if (type_ != type) {
  133. format msg = format("Invalid type. Expected \"%1%\" actual %2%") % typeToString(type) % typeToString(type_);
  134. throw Exception(msg);
  135. }
  136. }
  137. String Entity::stringValue() const {
  138. ensureType(EntityType::String);
  139. return JsonParser::toStringValue(**boost::any_cast<std::shared_ptr<String>>(&value_));
  140. }
  141. String Entity::bytesValue() const {
  142. ensureType(EntityType::String);
  143. return JsonParser::toBytesValue(**boost::any_cast<std::shared_ptr<String>>(&value_));
  144. }
  145. std::string Entity::toString() const {
  146. std::unique_ptr<OutputStream> out = memoryOutputStream();
  147. JsonGenerator<JsonNullFormatter> g;
  148. g.init(*out);
  149. writeEntity(g, *this);
  150. g.flush();
  151. std::unique_ptr<InputStream> in = memoryInputStream(*out);
  152. const uint8_t *p = nullptr;
  153. size_t n = 0;
  154. size_t c = 0;
  155. while (in->next(&p, &n)) {
  156. c += n;
  157. }
  158. std::string result;
  159. result.resize(c);
  160. c = 0;
  161. std::unique_ptr<InputStream> in2 = memoryInputStream(*out);
  162. while (in2->next(&p, &n)) {
  163. ::memcpy(&result[c], p, n);
  164. c += n;
  165. }
  166. return result;
  167. }
  168. } // namespace json
  169. } // namespace avro