diff options
Diffstat (limited to 'src/google/protobuf/util/internal/protostream_objectwriter.cc')
-rw-r--r-- | src/google/protobuf/util/internal/protostream_objectwriter.cc | 54 |
1 files changed, 44 insertions, 10 deletions
diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.cc b/src/google/protobuf/util/internal/protostream_objectwriter.cc index 786bf0be..94ddb428 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter.cc +++ b/src/google/protobuf/util/internal/protostream_objectwriter.cc @@ -58,17 +58,20 @@ using util::StatusOr; ProtoStreamObjectWriter::ProtoStreamObjectWriter( TypeResolver* type_resolver, const google::protobuf::Type& type, - strings::ByteSink* output, ErrorListener* listener) + strings::ByteSink* output, ErrorListener* listener, + const ProtoStreamObjectWriter::Options& options) : ProtoWriter(type_resolver, type, output, listener), master_type_(type), - current_(NULL) {} + current_(NULL), + options_(options) {} ProtoStreamObjectWriter::ProtoStreamObjectWriter( const TypeInfo* typeinfo, const google::protobuf::Type& type, strings::ByteSink* output, ErrorListener* listener) : ProtoWriter(typeinfo, type, output, listener), master_type_(type), - current_(NULL) {} + current_(NULL), + options_(ProtoStreamObjectWriter::Options::Defaults()) {} ProtoStreamObjectWriter::~ProtoStreamObjectWriter() { if (current_ == NULL) return; @@ -439,7 +442,8 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartObject( // name): // { "key": "<name>", "value": { Push("", Item::MESSAGE, false, false); - ProtoWriter::RenderDataPiece("key", DataPiece(name)); + ProtoWriter::RenderDataPiece("key", + DataPiece(name, use_strict_base64_decoding())); Push("value", Item::MESSAGE, true, false); // Make sure we are valid so far after starting map fields. @@ -604,7 +608,8 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartList(StringPiece name) { // Render // { "key": "<name>", "value": { Push("", Item::MESSAGE, false, false); - ProtoWriter::RenderDataPiece("key", DataPiece(name)); + ProtoWriter::RenderDataPiece("key", + DataPiece(name, use_strict_base64_decoding())); Push("value", Item::MESSAGE, true, false); // Make sure we are valid after pushing all above items. @@ -758,8 +763,36 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow, string struct_field_name; switch (data.type()) { // Our JSON parser parses numbers as either int64, uint64, or double. - case DataPiece::TYPE_INT64: - case DataPiece::TYPE_UINT64: + case DataPiece::TYPE_INT64: { + // If the option to treat integers as strings is set, then render them as + // strings. Otherwise, fallback to rendering them as double. + if (ow->options_.struct_integers_as_strings) { + StatusOr<int64> int_value = data.ToInt64(); + if (int_value.ok()) { + ow->ProtoWriter::RenderDataPiece( + "string_value", + DataPiece(SimpleItoa(int_value.ValueOrDie()), true)); + return Status::OK; + } + } + struct_field_name = "number_value"; + break; + } + case DataPiece::TYPE_UINT64: { + // If the option to treat integers as strings is set, then render them as + // strings. Otherwise, fallback to rendering them as double. + if (ow->options_.struct_integers_as_strings) { + StatusOr<uint64> int_value = data.ToUint64(); + if (int_value.ok()) { + ow->ProtoWriter::RenderDataPiece( + "string_value", + DataPiece(SimpleItoa(int_value.ValueOrDie()), true)); + return Status::OK; + } + } + struct_field_name = "number_value"; + break; + } case DataPiece::TYPE_DOUBLE: { struct_field_name = "number_value"; break; @@ -812,7 +845,7 @@ Status ProtoStreamObjectWriter::RenderTimestamp(ProtoStreamObjectWriter* ow, static inline util::Status RenderOneFieldPath(ProtoStreamObjectWriter* ow, StringPiece path) { ow->ProtoWriter::RenderDataPiece( - "paths", DataPiece(ConvertFieldMaskPath(path, &ToSnakeCase))); + "paths", DataPiece(ConvertFieldMaskPath(path, &ToSnakeCase), true)); return Status::OK; } @@ -871,7 +904,7 @@ Status ProtoStreamObjectWriter::RenderDuration(ProtoStreamObjectWriter* ow, nanos = sign * nanos; int64 seconds = sign * unsigned_seconds; - if (seconds > kMaxSeconds || seconds < kMinSeconds || + if (seconds > kDurationMaxSeconds || seconds < kDurationMinSeconds || nanos <= -kNanosPerSecond || nanos >= kNanosPerSecond) { return Status(INVALID_ARGUMENT, "Duration value exceeds limits"); } @@ -925,7 +958,8 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::RenderDataPiece( // Render an item in repeated map list. // { "key": "<name>", "value": Push("", Item::MESSAGE, false, false); - ProtoWriter::RenderDataPiece("key", DataPiece(name)); + ProtoWriter::RenderDataPiece("key", + DataPiece(name, use_strict_base64_decoding())); field = Lookup("value"); if (field == NULL) { GOOGLE_LOG(DFATAL) << "Map does not have a value field."; |