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 JsonPrintOptions& options) { | 77 const JsonOptions& 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 JsonPrintOptions& options) { | 98 const JsonOptions& 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) { | |
146 google::protobuf::Type type; | 145 google::protobuf::Type type; |
147 RETURN_IF_ERROR(resolver->ResolveMessageType(type_url, &type)); | 146 RETURN_IF_ERROR(resolver->ResolveMessageType(type_url, &type)); |
148 internal::ZeroCopyStreamByteSink sink(binary_output); | 147 internal::ZeroCopyStreamByteSink sink(binary_output); |
149 StatusErrorListener listener; | 148 StatusErrorListener listener; |
150 converter::ProtoStreamObjectWriter::Options proto_writer_options; | |
151 proto_writer_options.ignore_unknown_fields = options.ignore_unknown_fields; | |
152 converter::ProtoStreamObjectWriter proto_writer(resolver, type, &sink, | 149 converter::ProtoStreamObjectWriter proto_writer(resolver, type, &sink, |
153 &listener, | 150 &listener); |
154 proto_writer_options); | |
155 | 151 |
156 converter::JsonStreamParser parser(&proto_writer); | 152 converter::JsonStreamParser parser(&proto_writer); |
157 const void* buffer; | 153 const void* buffer; |
158 int length; | 154 int length; |
159 while (json_input->Next(&buffer, &length)) { | 155 while (json_input->Next(&buffer, &length)) { |
160 if (length == 0) continue; | 156 if (length == 0) continue; |
161 RETURN_IF_ERROR( | 157 RETURN_IF_ERROR( |
162 parser.Parse(StringPiece(static_cast<const char*>(buffer), length))); | 158 parser.Parse(StringPiece(static_cast<const char*>(buffer), length))); |
163 } | 159 } |
164 RETURN_IF_ERROR(parser.FinishParse()); | 160 RETURN_IF_ERROR(parser.FinishParse()); |
165 | 161 |
166 return listener.GetStatus(); | 162 return listener.GetStatus(); |
167 } | 163 } |
168 | 164 |
169 util::Status JsonToBinaryString(TypeResolver* resolver, | 165 util::Status JsonToBinaryString(TypeResolver* resolver, |
170 const string& type_url, | 166 const string& type_url, |
171 const string& json_input, | 167 const string& json_input, |
172 string* binary_output, | 168 string* binary_output) { |
173 const JsonParseOptions& options) { | |
174 io::ArrayInputStream input_stream(json_input.data(), json_input.size()); | 169 io::ArrayInputStream input_stream(json_input.data(), json_input.size()); |
175 io::StringOutputStream output_stream(binary_output); | 170 io::StringOutputStream output_stream(binary_output); |
176 return JsonToBinaryStream( | 171 return JsonToBinaryStream(resolver, type_url, &input_stream, &output_stream); |
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; | |
238 } | 172 } |
239 | 173 |
240 } // namespace util | 174 } // namespace util |
241 } // namespace protobuf | 175 } // namespace protobuf |
242 } // namespace google | 176 } // namespace google |
OLD | NEW |