diff options
Diffstat (limited to 'src/google/protobuf/wire_format.cc')
-rw-r--r-- | src/google/protobuf/wire_format.cc | 297 |
1 files changed, 169 insertions, 128 deletions
diff --git a/src/google/protobuf/wire_format.cc b/src/google/protobuf/wire_format.cc index aeea3ccb..dbd39b83 100644 --- a/src/google/protobuf/wire_format.cc +++ b/src/google/protobuf/wire_format.cc @@ -109,29 +109,29 @@ WireFormat::kWireTypeForFieldType[FieldDescriptor::MAX_TYPE + 1] = { bool WireFormat::SkipField(io::CodedInputStream* input, uint32 tag, UnknownFieldSet* unknown_fields) { - UnknownField* field = (unknown_fields == NULL) ? NULL : - unknown_fields->AddField(GetTagFieldNumber(tag)); + int number = GetTagFieldNumber(tag); switch (GetTagWireType(tag)) { case WIRETYPE_VARINT: { uint64 value; if (!input->ReadVarint64(&value)) return false; - if (field != NULL) field->add_varint(value); + if (unknown_fields != NULL) unknown_fields->AddVarint(number, value); return true; } case WIRETYPE_FIXED64: { uint64 value; if (!input->ReadLittleEndian64(&value)) return false; - if (field != NULL) field->add_fixed64(value); + if (unknown_fields != NULL) unknown_fields->AddFixed64(number, value); return true; } case WIRETYPE_LENGTH_DELIMITED: { uint32 length; if (!input->ReadVarint32(&length)) return false; - if (field == NULL) { + if (unknown_fields == NULL) { if (!input->Skip(length)) return false; } else { - if (!input->ReadString(field->add_length_delimited(), length)) { + if (!input->ReadString(unknown_fields->AddLengthDelimited(number), + length)) { return false; } } @@ -139,7 +139,8 @@ bool WireFormat::SkipField(io::CodedInputStream* input, uint32 tag, } case WIRETYPE_START_GROUP: { if (!input->IncrementRecursionDepth()) return false; - if (!SkipMessage(input, (field == NULL) ? NULL : field->add_group())) { + if (!SkipMessage(input, (unknown_fields == NULL) ? + NULL : unknown_fields->AddGroup(number))) { return false; } input->DecrementRecursionDepth(); @@ -156,7 +157,7 @@ bool WireFormat::SkipField(io::CodedInputStream* input, uint32 tag, case WIRETYPE_FIXED32: { uint32 value; if (!input->ReadLittleEndian32(&value)) return false; - if (field != NULL) field->add_fixed32(value); + if (unknown_fields != NULL) unknown_fields->AddFixed32(number, value); return true; } default: { @@ -185,72 +186,130 @@ bool WireFormat::SkipMessage(io::CodedInputStream* input, } } -bool WireFormat::SerializeUnknownFields(const UnknownFieldSet& unknown_fields, +void WireFormat::SerializeUnknownFields(const UnknownFieldSet& unknown_fields, io::CodedOutputStream* output) { for (int i = 0; i < unknown_fields.field_count(); i++) { const UnknownField& field = unknown_fields.field(i); - -#define DO(EXPRESSION) if (!(EXPRESSION)) return false - for (int j = 0; j < field.varint_size(); j++) { - DO(output->WriteVarint32(MakeTag(field.number(), WIRETYPE_VARINT))); - DO(output->WriteVarint64(field.varint(j))); - } - for (int j = 0; j < field.fixed32_size(); j++) { - DO(output->WriteVarint32(MakeTag(field.number(), WIRETYPE_FIXED32))); - DO(output->WriteLittleEndian32(field.fixed32(j))); - } - for (int j = 0; j < field.fixed64_size(); j++) { - DO(output->WriteVarint32(MakeTag(field.number(), WIRETYPE_FIXED64))); - DO(output->WriteLittleEndian64(field.fixed64(j))); - } - for (int j = 0; j < field.length_delimited_size(); j++) { - DO(output->WriteVarint32( - MakeTag(field.number(), WIRETYPE_LENGTH_DELIMITED))); - DO(output->WriteVarint32(field.length_delimited(j).size())); - DO(output->WriteString(field.length_delimited(j))); - } - for (int j = 0; j < field.group_size(); j++) { - DO(output->WriteVarint32(MakeTag(field.number(), WIRETYPE_START_GROUP))); - DO(SerializeUnknownFields(field.group(j), output)); - DO(output->WriteVarint32(MakeTag(field.number(), WIRETYPE_END_GROUP))); + switch (field.type()) { + case UnknownField::TYPE_VARINT: + output->WriteVarint32(MakeTag(field.number(), WIRETYPE_VARINT)); + output->WriteVarint64(field.varint()); + break; + case UnknownField::TYPE_FIXED32: + output->WriteVarint32(MakeTag(field.number(), WIRETYPE_FIXED32)); + output->WriteLittleEndian32(field.fixed32()); + break; + case UnknownField::TYPE_FIXED64: + output->WriteVarint32(MakeTag(field.number(), WIRETYPE_FIXED64)); + output->WriteLittleEndian64(field.fixed64()); + break; + case UnknownField::TYPE_LENGTH_DELIMITED: + output->WriteVarint32( + MakeTag(field.number(), WIRETYPE_LENGTH_DELIMITED)); + output->WriteVarint32(field.length_delimited().size()); + output->WriteString(field.length_delimited()); + break; + case UnknownField::TYPE_GROUP: + output->WriteVarint32(MakeTag(field.number(),WIRETYPE_START_GROUP)); + SerializeUnknownFields(field.group(), output); + output->WriteVarint32(MakeTag(field.number(), WIRETYPE_END_GROUP)); + break; } -#undef DO } +} - return true; +uint8* WireFormat::SerializeUnknownFieldsToArray( + const UnknownFieldSet& unknown_fields, + uint8* target) { + for (int i = 0; i < unknown_fields.field_count(); i++) { + const UnknownField& field = unknown_fields.field(i); + + switch (field.type()) { + case UnknownField::TYPE_VARINT: + target = WriteInt64ToArray(field.number(), field.varint(), target); + break; + case UnknownField::TYPE_FIXED32: + target = WriteFixed32ToArray(field.number(), field.fixed32(), target); + break; + case UnknownField::TYPE_FIXED64: + target = WriteFixed64ToArray(field.number(), field.fixed64(), target); + break; + case UnknownField::TYPE_LENGTH_DELIMITED: + target = + WriteBytesToArray(field.number(), field.length_delimited(), target); + break; + case UnknownField::TYPE_GROUP: + target = WriteTagToArray(field.number(), WIRETYPE_START_GROUP, target); + target = SerializeUnknownFieldsToArray(field.group(), target); + target = WriteTagToArray(field.number(), WIRETYPE_END_GROUP, target); + break; + } + } + return target; } -bool WireFormat::SerializeUnknownMessageSetItems( +void WireFormat::SerializeUnknownMessageSetItems( const UnknownFieldSet& unknown_fields, io::CodedOutputStream* output) { for (int i = 0; i < unknown_fields.field_count(); i++) { const UnknownField& field = unknown_fields.field(i); + // The only unknown fields that are allowed to exist in a MessageSet are + // messages, which are length-delimited. + if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) { + const string& data = field.length_delimited(); + + // Start group. + output->WriteVarint32(kMessageSetItemStartTag); + + // Write type ID. + output->WriteVarint32(kMessageSetTypeIdTag); + output->WriteVarint32(field.number()); + + // Write message. + output->WriteVarint32(kMessageSetMessageTag); + output->WriteVarint32(data.size()); + output->WriteString(data); + + // End group. + output->WriteVarint32(kMessageSetItemEndTag); + } + } +} + +uint8* WireFormat::SerializeUnknownMessageSetItemsToArray( + const UnknownFieldSet& unknown_fields, + uint8* target) { + for (int i = 0; i < unknown_fields.field_count(); i++) { + const UnknownField& field = unknown_fields.field(i); -#define DO(EXPRESSION) if (!(EXPRESSION)) return false // The only unknown fields that are allowed to exist in a MessageSet are // messages, which are length-delimited. - for (int j = 0; j < field.length_delimited_size(); j++) { - const string& data = field.length_delimited(j); + if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) { + const string& data = field.length_delimited(); // Start group. - DO(output->WriteVarint32(kMessageSetItemStartTag)); + target = + io::CodedOutputStream::WriteTagToArray(kMessageSetItemStartTag, target); // Write type ID. - DO(output->WriteVarint32(kMessageSetTypeIdTag)); - DO(output->WriteVarint32(field.number())); + target = + io::CodedOutputStream::WriteTagToArray(kMessageSetTypeIdTag, target); + target = + io::CodedOutputStream::WriteVarint32ToArray(field.number(), target); // Write message. - DO(output->WriteVarint32(kMessageSetMessageTag)); - DO(output->WriteVarint32(data.size())); - DO(output->WriteString(data)); + target = + io::CodedOutputStream::WriteTagToArray(kMessageSetMessageTag, target); + target = io::CodedOutputStream::WriteVarint32ToArray(data.size(), target); + target = io::CodedOutputStream::WriteStringToArray(data, target); // End group. - DO(output->WriteVarint32(kMessageSetItemEndTag)); + target = + io::CodedOutputStream::WriteTagToArray(kMessageSetItemEndTag, target); } -#undef DO } - return true; + return target; } int WireFormat::ComputeUnknownFieldsSize( @@ -259,34 +318,36 @@ int WireFormat::ComputeUnknownFieldsSize( for (int i = 0; i < unknown_fields.field_count(); i++) { const UnknownField& field = unknown_fields.field(i); - for (int j = 0; j < field.varint_size(); j++) { - size += io::CodedOutputStream::VarintSize32( - MakeTag(field.number(), WIRETYPE_VARINT)); - size += io::CodedOutputStream::VarintSize64(field.varint(j)); - } - for (int j = 0; j < field.fixed32_size(); j++) { - size += io::CodedOutputStream::VarintSize32( - MakeTag(field.number(), WIRETYPE_FIXED32)); - size += sizeof(int32); - } - for (int j = 0; j < field.fixed64_size(); j++) { - size += io::CodedOutputStream::VarintSize32( - MakeTag(field.number(), WIRETYPE_FIXED64)); - size += sizeof(int64); - } - for (int j = 0; j < field.length_delimited_size(); j++) { - size += io::CodedOutputStream::VarintSize32( - MakeTag(field.number(), WIRETYPE_LENGTH_DELIMITED)); - size += io::CodedOutputStream::VarintSize32( - field.length_delimited(j).size()); - size += field.length_delimited(j).size(); - } - for (int j = 0; j < field.group_size(); j++) { - size += io::CodedOutputStream::VarintSize32( - MakeTag(field.number(), WIRETYPE_START_GROUP)); - size += ComputeUnknownFieldsSize(field.group(j)); - size += io::CodedOutputStream::VarintSize32( - MakeTag(field.number(), WIRETYPE_END_GROUP)); + switch (field.type()) { + case UnknownField::TYPE_VARINT: + size += io::CodedOutputStream::VarintSize32( + MakeTag(field.number(), WIRETYPE_VARINT)); + size += io::CodedOutputStream::VarintSize64(field.varint()); + break; + case UnknownField::TYPE_FIXED32: + size += io::CodedOutputStream::VarintSize32( + MakeTag(field.number(), WIRETYPE_FIXED32)); + size += sizeof(int32); + break; + case UnknownField::TYPE_FIXED64: + size += io::CodedOutputStream::VarintSize32( + MakeTag(field.number(), WIRETYPE_FIXED64)); + size += sizeof(int64); + break; + case UnknownField::TYPE_LENGTH_DELIMITED: + size += io::CodedOutputStream::VarintSize32( + MakeTag(field.number(), WIRETYPE_LENGTH_DELIMITED)); + size += io::CodedOutputStream::VarintSize32( + field.length_delimited().size()); + size += field.length_delimited().size(); + break; + case UnknownField::TYPE_GROUP: + size += io::CodedOutputStream::VarintSize32( + MakeTag(field.number(), WIRETYPE_START_GROUP)); + size += ComputeUnknownFieldsSize(field.group()); + size += io::CodedOutputStream::VarintSize32( + MakeTag(field.number(), WIRETYPE_END_GROUP)); + break; } } @@ -301,12 +362,12 @@ int WireFormat::ComputeUnknownMessageSetItemsSize( // The only unknown fields that are allowed to exist in a MessageSet are // messages, which are length-delimited. - for (int j = 0; j < field.length_delimited_size(); j++) { + if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) { size += kMessageSetItemTagsSize; size += io::CodedOutputStream::VarintSize32(field.number()); size += io::CodedOutputStream::VarintSize32( - field.length_delimited(j).size()); - size += field.length_delimited(j).size(); + field.length_delimited().size()); + size += field.length_delimited().size(); } } @@ -487,8 +548,8 @@ bool WireFormat::ParseAndMergeField( // UnknownFieldSet. int64 sign_extended_value = static_cast<int64>(value); message_reflection->MutableUnknownFields(message) - ->AddField(GetTagFieldNumber(tag)) - ->add_varint(sign_extended_value); + ->AddVarint(GetTagFieldNumber(tag), + sign_extended_value); } break; } @@ -607,7 +668,7 @@ bool WireFormat::ParseAndMergeMessageSetItem( // =================================================================== -bool WireFormat::SerializeWithCachedSizes( +void WireFormat::SerializeWithCachedSizes( const Message& message, int size, io::CodedOutputStream* output) { const Descriptor* descriptor = message.GetDescriptor(); @@ -617,32 +678,24 @@ bool WireFormat::SerializeWithCachedSizes( vector<const FieldDescriptor*> fields; message_reflection->ListFields(message, &fields); for (int i = 0; i < fields.size(); i++) { - if (!SerializeFieldWithCachedSizes(fields[i], message, output)) { - return false; - } + SerializeFieldWithCachedSizes(fields[i], message, output); } if (descriptor->options().message_set_wire_format()) { - if (!SerializeUnknownMessageSetItems( - message_reflection->GetUnknownFields(message), output)) { - return false; - } + SerializeUnknownMessageSetItems( + message_reflection->GetUnknownFields(message), output); } else { - if (!SerializeUnknownFields( - message_reflection->GetUnknownFields(message), output)) { - return false; - } + SerializeUnknownFields( + message_reflection->GetUnknownFields(message), output); } GOOGLE_CHECK_EQ(output->ByteCount(), expected_endpoint) << ": Protocol message serialized to a size different from what was " "originally expected. Perhaps it was modified by another thread " "during serialization?"; - - return true; } -bool WireFormat::SerializeFieldWithCachedSizes( +void WireFormat::SerializeFieldWithCachedSizes( const FieldDescriptor* field, const Message& message, io::CodedOutputStream* output) { @@ -652,8 +705,8 @@ bool WireFormat::SerializeFieldWithCachedSizes( field->containing_type()->options().message_set_wire_format() && field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && !field->is_repeated()) { - return SerializeMessageSetItemWithCachedSizes( - field, message, output); + SerializeMessageSetItemWithCachedSizes(field, message, output); + return; } int count = 0; @@ -666,10 +719,9 @@ bool WireFormat::SerializeFieldWithCachedSizes( const bool is_packed = field->options().packed(); if (is_packed && count > 0) { - if (!WriteTag(field->number(), WIRETYPE_LENGTH_DELIMITED, output)) - return false; + WriteTag(field->number(), WIRETYPE_LENGTH_DELIMITED, output); const int data_size = FieldDataOnlyByteSize(field, message); - if (!output->WriteVarint32(data_size)) return false; + output->WriteVarint32(data_size); } for (int j = 0; j < count; j++) { @@ -682,13 +734,9 @@ bool WireFormat::SerializeFieldWithCachedSizes( message_reflection->Get##CPPTYPE_METHOD( \ message, field); \ if (is_packed) { \ - if (!Write##TYPE_METHOD##NoTag(value, output)) { \ - return false; \ - } \ + Write##TYPE_METHOD##NoTag(value, output); \ } else { \ - if (!Write##TYPE_METHOD(field->number(), value, output)) { \ - return false; \ - } \ + Write##TYPE_METHOD(field->number(), value, output); \ } \ break; \ } @@ -713,15 +761,13 @@ bool WireFormat::SerializeFieldWithCachedSizes( #define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD) \ case FieldDescriptor::TYPE_##TYPE: \ - if (!Write##TYPE_METHOD( \ + Write##TYPE_METHOD( \ field->number(), \ field->is_repeated() ? \ message_reflection->GetRepeated##CPPTYPE_METHOD( \ message, field, j) : \ message_reflection->Get##CPPTYPE_METHOD(message, field), \ - output)) { \ - return false; \ - } \ + output); \ break; HANDLE_TYPE(GROUP , Group , Message) @@ -733,10 +779,9 @@ bool WireFormat::SerializeFieldWithCachedSizes( message_reflection->GetRepeatedEnum(message, field, j) : message_reflection->GetEnum(message, field); if (is_packed) { - if (!WriteEnumNoTag(value->number(), output)) return false; + WriteEnumNoTag(value->number(), output); } else { - if (!WriteEnum(field->number(), value->number(), output)) - return false; + WriteEnum(field->number(), value->number(), output); } break; } @@ -749,7 +794,7 @@ bool WireFormat::SerializeFieldWithCachedSizes( message_reflection->GetRepeatedStringReference( message, field, j, &scratch) : message_reflection->GetStringReference(message, field, &scratch); - if (!WriteString(field->number(), value, output)) return false; + WriteString(field->number(), value, output); break; } @@ -759,39 +804,35 @@ bool WireFormat::SerializeFieldWithCachedSizes( message_reflection->GetRepeatedStringReference( message, field, j, &scratch) : message_reflection->GetStringReference(message, field, &scratch); - if (!WriteBytes(field->number(), value, output)) return false; + WriteBytes(field->number(), value, output); break; } } } - - return true; } -bool WireFormat::SerializeMessageSetItemWithCachedSizes( +void WireFormat::SerializeMessageSetItemWithCachedSizes( const FieldDescriptor* field, const Message& message, io::CodedOutputStream* output) { const Reflection* message_reflection = message.GetReflection(); // Start group. - if (!output->WriteVarint32(kMessageSetItemStartTag)) return false; + output->WriteVarint32(kMessageSetItemStartTag); // Write type ID. - if (!output->WriteVarint32(kMessageSetTypeIdTag)) return false; - if (!output->WriteVarint32(field->number())) return false; + output->WriteVarint32(kMessageSetTypeIdTag); + output->WriteVarint32(field->number()); // Write message. - if (!output->WriteVarint32(kMessageSetMessageTag)) return false; + output->WriteVarint32(kMessageSetMessageTag); const Message& sub_message = message_reflection->GetMessage(message, field); - if (!output->WriteVarint32(sub_message.GetCachedSize())) return false; - if (!sub_message.SerializeWithCachedSizes(output)) return false; + output->WriteVarint32(sub_message.GetCachedSize()); + sub_message.SerializeWithCachedSizes(output); // End group. - if (!output->WriteVarint32(kMessageSetItemEndTag)) return false; - - return true; + output->WriteVarint32(kMessageSetItemEndTag); } // =================================================================== |