诸暨麻将添加redis
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

282 lines
11 KiB

  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // https://developers.google.com/protocol-buffers/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. #include <google/protobuf/util/json_util.h>
  31. #include <google/protobuf/stubs/common.h>
  32. #include <google/protobuf/io/coded_stream.h>
  33. #include <google/protobuf/io/zero_copy_stream.h>
  34. #include <google/protobuf/stubs/once.h>
  35. #include <google/protobuf/util/internal/default_value_objectwriter.h>
  36. #include <google/protobuf/util/internal/error_listener.h>
  37. #include <google/protobuf/util/internal/json_objectwriter.h>
  38. #include <google/protobuf/util/internal/json_stream_parser.h>
  39. #include <google/protobuf/util/internal/protostream_objectsource.h>
  40. #include <google/protobuf/util/internal/protostream_objectwriter.h>
  41. #include <google/protobuf/util/type_resolver.h>
  42. #include <google/protobuf/util/type_resolver_util.h>
  43. #include <google/protobuf/stubs/bytestream.h>
  44. #include <google/protobuf/stubs/strutil.h>
  45. #include <google/protobuf/stubs/status_macros.h>
  46. #include <google/protobuf/port_def.inc>
  47. namespace google {
  48. namespace protobuf {
  49. namespace util {
  50. namespace internal {
  51. ZeroCopyStreamByteSink::~ZeroCopyStreamByteSink() {
  52. if (buffer_size_ > 0) {
  53. stream_->BackUp(buffer_size_);
  54. }
  55. }
  56. void ZeroCopyStreamByteSink::Append(const char* bytes, size_t len) {
  57. while (true) {
  58. if (len <= buffer_size_) {
  59. memcpy(buffer_, bytes, len);
  60. buffer_ = static_cast<char*>(buffer_) + len;
  61. buffer_size_ -= len;
  62. return;
  63. }
  64. if (buffer_size_ > 0) {
  65. memcpy(buffer_, bytes, buffer_size_);
  66. bytes += buffer_size_;
  67. len -= buffer_size_;
  68. }
  69. if (!stream_->Next(&buffer_, &buffer_size_)) {
  70. // There isn't a way for ByteSink to report errors.
  71. buffer_size_ = 0;
  72. return;
  73. }
  74. }
  75. }
  76. } // namespace internal
  77. util::Status BinaryToJsonStream(TypeResolver* resolver,
  78. const std::string& type_url,
  79. io::ZeroCopyInputStream* binary_input,
  80. io::ZeroCopyOutputStream* json_output,
  81. const JsonPrintOptions& options) {
  82. io::CodedInputStream in_stream(binary_input);
  83. google::protobuf::Type type;
  84. RETURN_IF_ERROR(resolver->ResolveMessageType(type_url, &type));
  85. converter::ProtoStreamObjectSource proto_source(&in_stream, resolver, type);
  86. proto_source.set_use_ints_for_enums(options.always_print_enums_as_ints);
  87. proto_source.set_preserve_proto_field_names(
  88. options.preserve_proto_field_names);
  89. io::CodedOutputStream out_stream(json_output);
  90. converter::JsonObjectWriter json_writer(options.add_whitespace ? " " : "",
  91. &out_stream);
  92. if (options.always_print_primitive_fields) {
  93. converter::DefaultValueObjectWriter default_value_writer(resolver, type,
  94. &json_writer);
  95. default_value_writer.set_preserve_proto_field_names(
  96. options.preserve_proto_field_names);
  97. default_value_writer.set_print_enums_as_ints(
  98. options.always_print_enums_as_ints);
  99. return proto_source.WriteTo(&default_value_writer);
  100. } else {
  101. return proto_source.WriteTo(&json_writer);
  102. }
  103. }
  104. util::Status BinaryToJsonString(TypeResolver* resolver,
  105. const std::string& type_url,
  106. const std::string& binary_input,
  107. std::string* json_output,
  108. const JsonPrintOptions& options) {
  109. io::ArrayInputStream input_stream(binary_input.data(), binary_input.size());
  110. io::StringOutputStream output_stream(json_output);
  111. return BinaryToJsonStream(resolver, type_url, &input_stream, &output_stream,
  112. options);
  113. }
  114. namespace {
  115. class StatusErrorListener : public converter::ErrorListener {
  116. public:
  117. StatusErrorListener() {}
  118. ~StatusErrorListener() override {}
  119. util::Status GetStatus() { return status_; }
  120. void InvalidName(const converter::LocationTrackerInterface& loc,
  121. StringPiece unknown_name,
  122. StringPiece message) override {
  123. std::string loc_string = GetLocString(loc);
  124. if (!loc_string.empty()) {
  125. loc_string.append(" ");
  126. }
  127. status_ =
  128. util::Status(util::error::INVALID_ARGUMENT,
  129. StrCat(loc_string, unknown_name, ": ", message));
  130. }
  131. void InvalidValue(const converter::LocationTrackerInterface& loc,
  132. StringPiece type_name,
  133. StringPiece value) override {
  134. status_ = util::Status(
  135. util::error::INVALID_ARGUMENT,
  136. StrCat(GetLocString(loc), ": invalid value ", string(value),
  137. " for type ", string(type_name)));
  138. }
  139. void MissingField(const converter::LocationTrackerInterface& loc,
  140. StringPiece missing_name) override {
  141. status_ = util::Status(util::error::INVALID_ARGUMENT,
  142. StrCat(GetLocString(loc), ": missing field ",
  143. std::string(missing_name)));
  144. }
  145. private:
  146. util::Status status_;
  147. std::string GetLocString(const converter::LocationTrackerInterface& loc) {
  148. std::string loc_string = loc.ToString();
  149. StripWhitespace(&loc_string);
  150. if (!loc_string.empty()) {
  151. loc_string = StrCat("(", loc_string, ")");
  152. }
  153. return loc_string;
  154. }
  155. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StatusErrorListener);
  156. };
  157. } // namespace
  158. util::Status JsonToBinaryStream(TypeResolver* resolver,
  159. const std::string& type_url,
  160. io::ZeroCopyInputStream* json_input,
  161. io::ZeroCopyOutputStream* binary_output,
  162. const JsonParseOptions& options) {
  163. google::protobuf::Type type;
  164. RETURN_IF_ERROR(resolver->ResolveMessageType(type_url, &type));
  165. internal::ZeroCopyStreamByteSink sink(binary_output);
  166. StatusErrorListener listener;
  167. converter::ProtoStreamObjectWriter::Options proto_writer_options;
  168. proto_writer_options.ignore_unknown_fields = options.ignore_unknown_fields;
  169. proto_writer_options.ignore_unknown_enum_values =
  170. options.ignore_unknown_fields;
  171. proto_writer_options.case_insensitive_enum_parsing =
  172. options.case_insensitive_enum_parsing;
  173. converter::ProtoStreamObjectWriter proto_writer(
  174. resolver, type, &sink, &listener, proto_writer_options);
  175. converter::JsonStreamParser parser(&proto_writer);
  176. const void* buffer;
  177. int length;
  178. while (json_input->Next(&buffer, &length)) {
  179. if (length == 0) continue;
  180. RETURN_IF_ERROR(parser.Parse(
  181. StringPiece(static_cast<const char*>(buffer), length)));
  182. }
  183. RETURN_IF_ERROR(parser.FinishParse());
  184. return listener.GetStatus();
  185. }
  186. util::Status JsonToBinaryString(TypeResolver* resolver,
  187. const std::string& type_url,
  188. StringPiece json_input,
  189. std::string* binary_output,
  190. const JsonParseOptions& options) {
  191. io::ArrayInputStream input_stream(json_input.data(), json_input.size());
  192. io::StringOutputStream output_stream(binary_output);
  193. return JsonToBinaryStream(resolver, type_url, &input_stream, &output_stream,
  194. options);
  195. }
  196. namespace {
  197. const char* kTypeUrlPrefix = "type.googleapis.com";
  198. TypeResolver* generated_type_resolver_ = NULL;
  199. PROTOBUF_NAMESPACE_ID::internal::once_flag generated_type_resolver_init_;
  200. std::string GetTypeUrl(const Message& message) {
  201. return std::string(kTypeUrlPrefix) + "/" +
  202. message.GetDescriptor()->full_name();
  203. }
  204. void DeleteGeneratedTypeResolver() { delete generated_type_resolver_; }
  205. void InitGeneratedTypeResolver() {
  206. generated_type_resolver_ = NewTypeResolverForDescriptorPool(
  207. kTypeUrlPrefix, DescriptorPool::generated_pool());
  208. ::google::protobuf::internal::OnShutdown(&DeleteGeneratedTypeResolver);
  209. }
  210. TypeResolver* GetGeneratedTypeResolver() {
  211. PROTOBUF_NAMESPACE_ID::internal::call_once(generated_type_resolver_init_,
  212. InitGeneratedTypeResolver);
  213. return generated_type_resolver_;
  214. }
  215. } // namespace
  216. util::Status MessageToJsonString(const Message& message, std::string* output,
  217. const JsonOptions& options) {
  218. const DescriptorPool* pool = message.GetDescriptor()->file()->pool();
  219. TypeResolver* resolver =
  220. pool == DescriptorPool::generated_pool()
  221. ? GetGeneratedTypeResolver()
  222. : NewTypeResolverForDescriptorPool(kTypeUrlPrefix, pool);
  223. util::Status result =
  224. BinaryToJsonString(resolver, GetTypeUrl(message),
  225. message.SerializeAsString(), output, options);
  226. if (pool != DescriptorPool::generated_pool()) {
  227. delete resolver;
  228. }
  229. return result;
  230. }
  231. util::Status JsonStringToMessage(StringPiece input, Message* message,
  232. const JsonParseOptions& options) {
  233. const DescriptorPool* pool = message->GetDescriptor()->file()->pool();
  234. TypeResolver* resolver =
  235. pool == DescriptorPool::generated_pool()
  236. ? GetGeneratedTypeResolver()
  237. : NewTypeResolverForDescriptorPool(kTypeUrlPrefix, pool);
  238. std::string binary;
  239. util::Status result = JsonToBinaryString(resolver, GetTypeUrl(*message),
  240. input, &binary, options);
  241. if (result.ok() && !message->ParseFromString(binary)) {
  242. result =
  243. util::Status(util::error::INVALID_ARGUMENT,
  244. "JSON transcoder produced invalid protobuf output.");
  245. }
  246. if (pool != DescriptorPool::generated_pool()) {
  247. delete resolver;
  248. }
  249. return result;
  250. }
  251. } // namespace util
  252. } // namespace protobuf
  253. } // namespace google