OLD | NEW |
1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
3 // https://developers.google.com/protocol-buffers/ | 3 // https://developers.google.com/protocol-buffers/ |
4 // | 4 // |
5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
7 // met: | 7 // met: |
8 // | 8 // |
9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 len -= length; | 67 len -= length; |
68 } | 68 } |
69 } | 69 } |
70 } | 70 } |
71 } // namespace internal | 71 } // namespace internal |
72 | 72 |
73 util::Status BinaryToJsonStream(TypeResolver* resolver, | 73 util::Status BinaryToJsonStream(TypeResolver* resolver, |
74 const string& type_url, | 74 const string& type_url, |
75 io::ZeroCopyInputStream* binary_input, | 75 io::ZeroCopyInputStream* binary_input, |
76 io::ZeroCopyOutputStream* json_output, | 76 io::ZeroCopyOutputStream* json_output, |
77 const JsonOptions& options) { | 77 const JsonPrintOptions& options) { |
78 io::CodedInputStream in_stream(binary_input); | 78 io::CodedInputStream in_stream(binary_input); |
79 google::protobuf::Type type; | 79 google::protobuf::Type type; |
80 RETURN_IF_ERROR(resolver->ResolveMessageType(type_url, &type)); | 80 RETURN_IF_ERROR(resolver->ResolveMessageType(type_url, &type)); |
81 converter::ProtoStreamObjectSource proto_source(&in_stream, resolver, type); | 81 converter::ProtoStreamObjectSource proto_source(&in_stream, resolver, type); |
82 io::CodedOutputStream out_stream(json_output); | 82 io::CodedOutputStream out_stream(json_output); |
83 converter::JsonObjectWriter json_writer(options.add_whitespace ? " " : "", | 83 converter::JsonObjectWriter json_writer(options.add_whitespace ? " " : "", |
84 &out_stream); | 84 &out_stream); |
85 if (options.always_print_primitive_fields) { | 85 if (options.always_print_primitive_fields) { |
86 converter::DefaultValueObjectWriter default_value_writer( | 86 converter::DefaultValueObjectWriter default_value_writer( |
87 resolver, type, &json_writer); | 87 resolver, type, &json_writer); |
88 return proto_source.WriteTo(&default_value_writer); | 88 return proto_source.WriteTo(&default_value_writer); |
89 } else { | 89 } else { |
90 return proto_source.WriteTo(&json_writer); | 90 return proto_source.WriteTo(&json_writer); |
91 } | 91 } |
92 } | 92 } |
93 | 93 |
94 util::Status BinaryToJsonString(TypeResolver* resolver, | 94 util::Status BinaryToJsonString(TypeResolver* resolver, |
95 const string& type_url, | 95 const string& type_url, |
96 const string& binary_input, | 96 const string& binary_input, |
97 string* json_output, | 97 string* json_output, |
98 const JsonOptions& options) { | 98 const JsonPrintOptions& options) { |
99 io::ArrayInputStream input_stream(binary_input.data(), binary_input.size()); | 99 io::ArrayInputStream input_stream(binary_input.data(), binary_input.size()); |
100 io::StringOutputStream output_stream(json_output); | 100 io::StringOutputStream output_stream(json_output); |
101 return BinaryToJsonStream(resolver, type_url, &input_stream, &output_stream, | 101 return BinaryToJsonStream(resolver, type_url, &input_stream, &output_stream, |
102 options); | 102 options); |
103 } | 103 } |
104 | 104 |
105 namespace { | 105 namespace { |
106 class StatusErrorListener : public converter::ErrorListener { | 106 class StatusErrorListener : public converter::ErrorListener { |
107 public: | 107 public: |
108 StatusErrorListener() : status_(util::Status::OK) {} | 108 StatusErrorListener() : status_(util::Status::OK) {} |
(...skipping 25 matching lines...) Expand all Loading... |
134 private: | 134 private: |
135 util::Status status_; | 135 util::Status status_; |
136 | 136 |
137 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StatusErrorListener); | 137 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StatusErrorListener); |
138 }; | 138 }; |
139 } // namespace | 139 } // namespace |
140 | 140 |
141 util::Status JsonToBinaryStream(TypeResolver* resolver, | 141 util::Status JsonToBinaryStream(TypeResolver* resolver, |
142 const string& type_url, | 142 const string& type_url, |
143 io::ZeroCopyInputStream* json_input, | 143 io::ZeroCopyInputStream* json_input, |
144 io::ZeroCopyOutputStream* binary_output) { | 144 io::ZeroCopyOutputStream* binary_output, |
| 145 const JsonParseOptions& options) { |
145 google::protobuf::Type type; | 146 google::protobuf::Type type; |
146 RETURN_IF_ERROR(resolver->ResolveMessageType(type_url, &type)); | 147 RETURN_IF_ERROR(resolver->ResolveMessageType(type_url, &type)); |
147 internal::ZeroCopyStreamByteSink sink(binary_output); | 148 internal::ZeroCopyStreamByteSink sink(binary_output); |
148 StatusErrorListener listener; | 149 StatusErrorListener listener; |
| 150 converter::ProtoStreamObjectWriter::Options proto_writer_options; |
| 151 proto_writer_options.ignore_unknown_fields = options.ignore_unknown_fields; |
149 converter::ProtoStreamObjectWriter proto_writer(resolver, type, &sink, | 152 converter::ProtoStreamObjectWriter proto_writer(resolver, type, &sink, |
150 &listener); | 153 &listener, |
| 154 proto_writer_options); |
151 | 155 |
152 converter::JsonStreamParser parser(&proto_writer); | 156 converter::JsonStreamParser parser(&proto_writer); |
153 const void* buffer; | 157 const void* buffer; |
154 int length; | 158 int length; |
155 while (json_input->Next(&buffer, &length)) { | 159 while (json_input->Next(&buffer, &length)) { |
156 if (length == 0) continue; | 160 if (length == 0) continue; |
157 RETURN_IF_ERROR( | 161 RETURN_IF_ERROR( |
158 parser.Parse(StringPiece(static_cast<const char*>(buffer), length))); | 162 parser.Parse(StringPiece(static_cast<const char*>(buffer), length))); |
159 } | 163 } |
160 RETURN_IF_ERROR(parser.FinishParse()); | 164 RETURN_IF_ERROR(parser.FinishParse()); |
161 | 165 |
162 return listener.GetStatus(); | 166 return listener.GetStatus(); |
163 } | 167 } |
164 | 168 |
165 util::Status JsonToBinaryString(TypeResolver* resolver, | 169 util::Status JsonToBinaryString(TypeResolver* resolver, |
166 const string& type_url, | 170 const string& type_url, |
167 const string& json_input, | 171 const string& json_input, |
168 string* binary_output) { | 172 string* binary_output, |
| 173 const JsonParseOptions& options) { |
169 io::ArrayInputStream input_stream(json_input.data(), json_input.size()); | 174 io::ArrayInputStream input_stream(json_input.data(), json_input.size()); |
170 io::StringOutputStream output_stream(binary_output); | 175 io::StringOutputStream output_stream(binary_output); |
171 return JsonToBinaryStream(resolver, type_url, &input_stream, &output_stream); | 176 return JsonToBinaryStream( |
| 177 resolver, type_url, &input_stream, &output_stream, options); |
| 178 } |
| 179 |
| 180 namespace { |
| 181 const char* kTypeUrlPrefix = "type.googleapis.com"; |
| 182 TypeResolver* generated_type_resolver_ = NULL; |
| 183 GOOGLE_PROTOBUF_DECLARE_ONCE(generated_type_resolver_init_); |
| 184 |
| 185 string GetTypeUrl(const Message& message) { |
| 186 return string(kTypeUrlPrefix) + "/" + message.GetDescriptor()->full_name(); |
| 187 } |
| 188 |
| 189 void DeleteGeneratedTypeResolver() { delete generated_type_resolver_; } |
| 190 |
| 191 void InitGeneratedTypeResolver() { |
| 192 generated_type_resolver_ = NewTypeResolverForDescriptorPool( |
| 193 kTypeUrlPrefix, DescriptorPool::generated_pool()); |
| 194 ::google::protobuf::internal::OnShutdown(&DeleteGeneratedTypeResolver); |
| 195 } |
| 196 |
| 197 TypeResolver* GetGeneratedTypeResolver() { |
| 198 ::google::protobuf::GoogleOnceInit(&generated_type_resolver_init_, &InitGenera
tedTypeResolver); |
| 199 return generated_type_resolver_; |
| 200 } |
| 201 } // namespace |
| 202 |
| 203 util::Status MessageToJsonString(const Message& message, string* output, |
| 204 const JsonOptions& options) { |
| 205 const DescriptorPool* pool = message.GetDescriptor()->file()->pool(); |
| 206 TypeResolver* resolver = |
| 207 pool == DescriptorPool::generated_pool() |
| 208 ? GetGeneratedTypeResolver() |
| 209 : NewTypeResolverForDescriptorPool(kTypeUrlPrefix, pool); |
| 210 util::Status result = |
| 211 BinaryToJsonString(resolver, GetTypeUrl(message), |
| 212 message.SerializeAsString(), output, options); |
| 213 if (pool != DescriptorPool::generated_pool()) { |
| 214 delete resolver; |
| 215 } |
| 216 return result; |
| 217 } |
| 218 |
| 219 util::Status JsonStringToMessage(const string& input, Message* message, |
| 220 const JsonParseOptions& options) { |
| 221 const DescriptorPool* pool = message->GetDescriptor()->file()->pool(); |
| 222 TypeResolver* resolver = |
| 223 pool == DescriptorPool::generated_pool() |
| 224 ? GetGeneratedTypeResolver() |
| 225 : NewTypeResolverForDescriptorPool(kTypeUrlPrefix, pool); |
| 226 string binary; |
| 227 util::Status result = JsonToBinaryString( |
| 228 resolver, GetTypeUrl(*message), input, &binary, options); |
| 229 if (result.ok() && !message->ParseFromString(binary)) { |
| 230 result = |
| 231 util::Status(util::error::INVALID_ARGUMENT, |
| 232 "JSON transcoder produced invalid protobuf output."); |
| 233 } |
| 234 if (pool != DescriptorPool::generated_pool()) { |
| 235 delete resolver; |
| 236 } |
| 237 return result; |
172 } | 238 } |
173 | 239 |
174 } // namespace util | 240 } // namespace util |
175 } // namespace protobuf | 241 } // namespace protobuf |
176 } // namespace google | 242 } // namespace google |
OLD | NEW |