diff options
Diffstat (limited to 'src/google/protobuf/extension_set_heavy.cc')
-rw-r--r-- | src/google/protobuf/extension_set_heavy.cc | 303 |
1 files changed, 13 insertions, 290 deletions
diff --git a/src/google/protobuf/extension_set_heavy.cc b/src/google/protobuf/extension_set_heavy.cc index a50efac..2721f15 100644 --- a/src/google/protobuf/extension_set_heavy.cc +++ b/src/google/protobuf/extension_set_heavy.cc @@ -1,6 +1,6 @@ // Protocol Buffers - Google's data interchange format // Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ +// http://code.google.com/p/protobuf/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are @@ -35,43 +35,17 @@ // Contains methods defined in extension_set.h which cannot be part of the // lite library because they use descriptors or reflection. -#include <google/protobuf/io/zero_copy_stream_impl_lite.h> -#include <google/protobuf/descriptor.h> #include <google/protobuf/extension_set.h> +#include <google/protobuf/descriptor.h> #include <google/protobuf/message.h> #include <google/protobuf/repeated_field.h> #include <google/protobuf/wire_format.h> #include <google/protobuf/wire_format_lite_inl.h> namespace google { - namespace protobuf { namespace internal { -// A FieldSkipper used to store unknown MessageSet fields into UnknownFieldSet. -class MessageSetFieldSkipper - : public UnknownFieldSetFieldSkipper { - public: - explicit MessageSetFieldSkipper(UnknownFieldSet* unknown_fields) - : UnknownFieldSetFieldSkipper(unknown_fields) {} - virtual ~MessageSetFieldSkipper() {} - - virtual bool SkipMessageSetField(io::CodedInputStream* input, - int field_number); -}; -bool MessageSetFieldSkipper::SkipMessageSetField( - io::CodedInputStream* input, int field_number) { - uint32 length; - if (!input->ReadVarint32(&length)) return false; - if (unknown_fields_ == NULL) { - return input->Skip(length); - } else { - return input->ReadString( - unknown_fields_->AddLengthDelimited(field_number), length); - } -} - - // Implementation of ExtensionFinder which finds extensions in a given // DescriptorPool, using the given MessageFactory to construct sub-objects. // This class is implemented in extension_set_heavy.cc. @@ -93,7 +67,7 @@ class DescriptorPoolExtensionFinder : public ExtensionFinder { void ExtensionSet::AppendToList(const Descriptor* containing_type, const DescriptorPool* pool, - std::vector<const FieldDescriptor*>* output) const { + vector<const FieldDescriptor*>* output) const { for (map<int, Extension>::const_iterator iter = extensions_.begin(); iter != extensions_.end(); ++iter) { bool has = false; @@ -129,11 +103,6 @@ inline FieldDescriptor::CppType cpp_type(FieldType type) { static_cast<FieldDescriptor::Type>(type)); } -inline WireFormatLite::FieldType field_type(FieldType type) { - GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE); - return static_cast<WireFormatLite::FieldType>(type); -} - #define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \ GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? FieldDescriptor::LABEL_REPEATED \ : FieldDescriptor::LABEL_OPTIONAL, \ @@ -149,12 +118,7 @@ const MessageLite& ExtensionSet::GetMessage(int number, return *factory->GetPrototype(message_type); } else { GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE); - if (iter->second.is_lazy) { - return iter->second.lazymessage_value->GetMessage( - *factory->GetPrototype(message_type)); - } else { - return *iter->second.message_value; - } + return *iter->second.message_value; } } @@ -168,41 +132,13 @@ MessageLite* ExtensionSet::MutableMessage(const FieldDescriptor* descriptor, extension->is_packed = false; const MessageLite* prototype = factory->GetPrototype(descriptor->message_type()); - extension->is_lazy = false; + GOOGLE_CHECK(prototype != NULL); extension->message_value = prototype->New(); - extension->is_cleared = false; - return extension->message_value; } else { GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE); - extension->is_cleared = false; - if (extension->is_lazy) { - return extension->lazymessage_value->MutableMessage( - *factory->GetPrototype(descriptor->message_type())); - } else { - return extension->message_value; - } - } -} - -MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor, - MessageFactory* factory) { - map<int, Extension>::iterator iter = extensions_.find(descriptor->number()); - if (iter == extensions_.end()) { - // Not present. Return NULL. - return NULL; - } else { - GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE); - MessageLite* ret = NULL; - if (iter->second.is_lazy) { - ret = iter->second.lazymessage_value->ReleaseMessage( - *factory->GetPrototype(descriptor->message_type())); - delete iter->second.lazymessage_value; - } else { - ret = iter->second.message_value; - } - extensions_.erase(descriptor->number()); - return ret; } + extension->is_cleared = false; + return extension->message_value; } MessageLite* ExtensionSet::AddMessage(const FieldDescriptor* descriptor, @@ -221,7 +157,7 @@ MessageLite* ExtensionSet::AddMessage(const FieldDescriptor* descriptor, // RepeatedPtrField<Message> does not know how to Add() since it cannot // allocate an abstract object, so we have to be tricky. MessageLite* result = extension->repeated_message_value - ->AddFromCleared<GenericTypeHandler<MessageLite> >(); + ->AddFromCleared<internal::GenericTypeHandler<MessageLite> >(); if (result == NULL) { const MessageLite* prototype; if (extension->repeated_message_value->size() == 0) { @@ -284,7 +220,7 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, const Message* containing_type, UnknownFieldSet* unknown_fields) { - MessageSetFieldSkipper skipper(unknown_fields); + UnknownFieldSetFieldSkipper skipper(unknown_fields); if (input->GetExtensionPool() == NULL) { GeneratedExtensionFinder finder(containing_type); return ParseMessageSet(input, &finder, &skipper); @@ -350,11 +286,7 @@ int ExtensionSet::Extension::SpaceUsedExcludingSelf() const { StringSpaceUsedExcludingSelf(*string_value); break; case FieldDescriptor::CPPTYPE_MESSAGE: - if (is_lazy) { - total_size += lazymessage_value->SpaceUsed(); - } else { - total_size += down_cast<Message*>(message_value)->SpaceUsed(); - } + total_size += down_cast<Message*>(message_value)->SpaceUsed(); break; default: // No extra storage costs for primitive types. @@ -487,15 +419,8 @@ uint8* ExtensionSet::Extension::SerializeFieldWithCachedSizesToArray( HANDLE_TYPE( BYTES, Bytes, *string_value); HANDLE_TYPE( ENUM, Enum, enum_value); HANDLE_TYPE( GROUP, Group, *message_value); + HANDLE_TYPE( MESSAGE, Message, *message_value); #undef HANDLE_TYPE - case FieldDescriptor::TYPE_MESSAGE: - if (is_lazy) { - target = lazymessage_value->WriteMessageToArray(number, target); - } else { - target = WireFormatLite::WriteMessageToArray( - number, *message_value, target); - } - break; } } return target; @@ -519,216 +444,14 @@ uint8* ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizesToArray( target = WireFormatLite::WriteUInt32ToArray( WireFormatLite::kMessageSetTypeIdNumber, number, target); // Write message. - if (is_lazy) { - target = lazymessage_value->WriteMessageToArray( - WireFormatLite::kMessageSetMessageNumber, target); - } else { - target = WireFormatLite::WriteMessageToArray( - WireFormatLite::kMessageSetMessageNumber, *message_value, target); - } + target = WireFormatLite::WriteMessageToArray( + WireFormatLite::kMessageSetMessageNumber, *message_value, target); // End group. target = io::CodedOutputStream::WriteTagToArray( WireFormatLite::kMessageSetItemEndTag, target); return target; } - -bool ExtensionSet::ParseFieldMaybeLazily( - int wire_type, int field_number, io::CodedInputStream* input, - ExtensionFinder* extension_finder, - MessageSetFieldSkipper* field_skipper) { - return ParseField(WireFormatLite::MakeTag( - field_number, static_cast<WireFormatLite::WireType>(wire_type)), - input, extension_finder, field_skipper); -} - -bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, - ExtensionFinder* extension_finder, - MessageSetFieldSkipper* field_skipper) { - while (true) { - const uint32 tag = input->ReadTag(); - switch (tag) { - case 0: - return true; - case WireFormatLite::kMessageSetItemStartTag: - if (!ParseMessageSetItem(input, extension_finder, field_skipper)) { - return false; - } - break; - default: - if (!ParseField(tag, input, extension_finder, field_skipper)) { - return false; - } - break; - } - } -} - -bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, - const MessageLite* containing_type) { - MessageSetFieldSkipper skipper(NULL); - GeneratedExtensionFinder finder(containing_type); - return ParseMessageSet(input, &finder, &skipper); -} - -bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input, - ExtensionFinder* extension_finder, - MessageSetFieldSkipper* field_skipper) { - // TODO(kenton): It would be nice to share code between this and - // WireFormatLite::ParseAndMergeMessageSetItem(), but I think the - // differences would be hard to factor out. - - // This method parses a group which should contain two fields: - // required int32 type_id = 2; - // required data message = 3; - - uint32 last_type_id = 0; - - // If we see message data before the type_id, we'll append it to this so - // we can parse it later. - string message_data; - - while (true) { - const uint32 tag = input->ReadTag(); - if (tag == 0) return false; - - switch (tag) { - case WireFormatLite::kMessageSetTypeIdTag: { - uint32 type_id; - if (!input->ReadVarint32(&type_id)) return false; - last_type_id = type_id; - - if (!message_data.empty()) { - // We saw some message data before the type_id. Have to parse it - // now. - io::CodedInputStream sub_input( - reinterpret_cast<const uint8*>(message_data.data()), - message_data.size()); - if (!ParseFieldMaybeLazily(WireFormatLite::WIRETYPE_LENGTH_DELIMITED, - last_type_id, &sub_input, - extension_finder, field_skipper)) { - return false; - } - message_data.clear(); - } - - break; - } - - case WireFormatLite::kMessageSetMessageTag: { - if (last_type_id == 0) { - // We haven't seen a type_id yet. Append this data to message_data. - string temp; - uint32 length; - if (!input->ReadVarint32(&length)) return false; - if (!input->ReadString(&temp, length)) return false; - io::StringOutputStream output_stream(&message_data); - io::CodedOutputStream coded_output(&output_stream); - coded_output.WriteVarint32(length); - coded_output.WriteString(temp); - } else { - // Already saw type_id, so we can parse this directly. - if (!ParseFieldMaybeLazily(WireFormatLite::WIRETYPE_LENGTH_DELIMITED, - last_type_id, input, - extension_finder, field_skipper)) { - return false; - } - } - - break; - } - - case WireFormatLite::kMessageSetItemEndTag: { - return true; - } - - default: { - if (!field_skipper->SkipField(input, tag)) return false; - } - } - } -} - -void ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizes( - int number, - io::CodedOutputStream* output) const { - if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) { - // Not a valid MessageSet extension, but serialize it the normal way. - SerializeFieldWithCachedSizes(number, output); - return; - } - - if (is_cleared) return; - - // Start group. - output->WriteTag(WireFormatLite::kMessageSetItemStartTag); - - // Write type ID. - WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber, - number, - output); - // Write message. - if (is_lazy) { - lazymessage_value->WriteMessage( - WireFormatLite::kMessageSetMessageNumber, output); - } else { - WireFormatLite::WriteMessageMaybeToArray( - WireFormatLite::kMessageSetMessageNumber, - *message_value, - output); - } - - // End group. - output->WriteTag(WireFormatLite::kMessageSetItemEndTag); -} - -int ExtensionSet::Extension::MessageSetItemByteSize(int number) const { - if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) { - // Not a valid MessageSet extension, but compute the byte size for it the - // normal way. - return ByteSize(number); - } - - if (is_cleared) return 0; - - int our_size = WireFormatLite::kMessageSetItemTagsSize; - - // type_id - our_size += io::CodedOutputStream::VarintSize32(number); - - // message - int message_size = 0; - if (is_lazy) { - message_size = lazymessage_value->ByteSize(); - } else { - message_size = message_value->ByteSize(); - } - - our_size += io::CodedOutputStream::VarintSize32(message_size); - our_size += message_size; - - return our_size; -} - -void ExtensionSet::SerializeMessageSetWithCachedSizes( - io::CodedOutputStream* output) const { - for (map<int, Extension>::const_iterator iter = extensions_.begin(); - iter != extensions_.end(); ++iter) { - iter->second.SerializeMessageSetItemWithCachedSizes(iter->first, output); - } -} - -int ExtensionSet::MessageSetByteSize() const { - int total_size = 0; - - for (map<int, Extension>::const_iterator iter = extensions_.begin(); - iter != extensions_.end(); ++iter) { - total_size += iter->second.MessageSetItemByteSize(iter->first); - } - - return total_size; -} - } // namespace internal } // namespace protobuf } // namespace google |