diff options
Diffstat (limited to 'src/google/protobuf/wire_format.cc')
-rw-r--r-- | src/google/protobuf/wire_format.cc | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/src/google/protobuf/wire_format.cc b/src/google/protobuf/wire_format.cc index f4f02157..c5bbbf2e 100644 --- a/src/google/protobuf/wire_format.cc +++ b/src/google/protobuf/wire_format.cc @@ -141,7 +141,7 @@ bool WireFormat::SkipField(io::CodedInputStream* input, uint32 tag, bool WireFormat::SkipMessage(io::CodedInputStream* input, UnknownFieldSet* unknown_fields) { - while(true) { + while (true) { uint32 tag = input->ReadTag(); if (tag == 0) { // End of input. This is a valid place to end, so return true. @@ -159,6 +159,31 @@ bool WireFormat::SkipMessage(io::CodedInputStream* input, } } +bool WireFormat::ReadPackedEnumPreserveUnknowns(io::CodedInputStream* input, + uint32 field_number, + bool (*is_valid)(int), + UnknownFieldSet* unknown_fields, + RepeatedField<int>* values) { + uint32 length; + if (!input->ReadVarint32(&length)) return false; + io::CodedInputStream::Limit limit = input->PushLimit(length); + while (input->BytesUntilLimit() > 0) { + int value; + if (!google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, WireFormatLite::TYPE_ENUM>(input, &value)) { + return false; + } + if (is_valid == NULL || is_valid(value)) { + values->Add(value); + } else { + unknown_fields->AddVarint(field_number, value); + } + } + input->PopLimit(limit); + return true; +} + + void WireFormat::SerializeUnknownFields(const UnknownFieldSet& unknown_fields, io::CodedOutputStream* output) { for (int i = 0; i < unknown_fields.field_count(); i++) { @@ -520,6 +545,14 @@ bool WireFormat::ParseAndMergeField( field->enum_type()->FindValueByNumber(value); if (enum_value != NULL) { message_reflection->AddEnum(message, field, enum_value); + } else { + // The enum value is not one of the known values. Add it to the + // UnknownFieldSet. + int64 sign_extended_value = static_cast<int64>(value); + message_reflection->MutableUnknownFields(message) + ->AddVarint( + WireFormatLite::GetTagFieldNumber(tag), + sign_extended_value); } } } |