diff options
Diffstat (limited to 'src/google/protobuf/repeated_field.h')
-rw-r--r-- | src/google/protobuf/repeated_field.h | 85 |
1 files changed, 46 insertions, 39 deletions
diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h index 9c84ed98..b10e7a95 100644 --- a/src/google/protobuf/repeated_field.h +++ b/src/google/protobuf/repeated_field.h @@ -54,6 +54,7 @@ #include <string> #include <iterator> #include <google/protobuf/stubs/casts.h> +#include <google/protobuf/stubs/logging.h> #include <google/protobuf/stubs/common.h> #include <google/protobuf/stubs/type_traits.h> #include <google/protobuf/arena.h> @@ -361,7 +362,7 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase { // To parse directly into a proto2 generated class, the upb class GMR_Handlers // needs to be able to modify a RepeatedPtrFieldBase directly. - friend class LIBPROTOBUF_EXPORT upb::google_opensource::GMR_Handlers; + friend class upb::google_opensource::GMR_Handlers; RepeatedPtrFieldBase(); explicit RepeatedPtrFieldBase(::google::protobuf::Arena* arena); @@ -408,7 +409,7 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase { const typename TypeHandler::Type* const* data() const; template <typename TypeHandler> - inline void Swap(RepeatedPtrFieldBase* other) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; + GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Swap(RepeatedPtrFieldBase* other); void SwapElements(int index1, int index2); @@ -461,8 +462,7 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase { template <typename TypeHandler> GOOGLE_ATTRIBUTE_NOINLINE void AddAllocatedSlowWithCopy(typename TypeHandler::Type* value, Arena* value_arena, - Arena* my_arena) -; + Arena* my_arena); template <typename TypeHandler> GOOGLE_ATTRIBUTE_NOINLINE void AddAllocatedSlowWithoutCopy(typename TypeHandler::Type* value); @@ -472,7 +472,7 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase { typename TypeHandler::Type* ReleaseLastInternal(google::protobuf::internal::false_type); template<typename TypeHandler> GOOGLE_ATTRIBUTE_NOINLINE - inline void SwapFallback(RepeatedPtrFieldBase* other); + void SwapFallback(RepeatedPtrFieldBase* other); inline Arena* GetArenaNoVirtual() const { return arena_; @@ -541,20 +541,10 @@ class GenericTypeHandler { } // We force NewFromPrototype() and Delete() to be non-inline to reduce code // size: else, several other methods get inlined copies of message types' - // constructors and destructors. Note that the GOOGLE_ATTRIBUTE_NOINLINE macro - // requires the 'inline' storage class here, which is somewhat confusing, but - // the compiler does the right thing. - GOOGLE_ATTRIBUTE_NOINLINE - static inline GenericType* NewFromPrototype(const GenericType* prototype, - ::google::protobuf::Arena* arena = NULL) { - return New(arena); - } - GOOGLE_ATTRIBUTE_NOINLINE - static inline void Delete(GenericType* value, Arena* arena) { - if (arena == NULL) { - delete value; - } - } + // constructors and destructors. + GOOGLE_ATTRIBUTE_NOINLINE static GenericType* NewFromPrototype( + const GenericType* prototype, ::google::protobuf::Arena* arena = NULL); + GOOGLE_ATTRIBUTE_NOINLINE static void Delete(GenericType* value, Arena* arena); static inline ::google::protobuf::Arena* GetArena(GenericType* value) { return ::google::protobuf::Arena::GetArena<Type>(value); } @@ -563,11 +553,8 @@ class GenericTypeHandler { } static inline void Clear(GenericType* value) { value->Clear(); } - - GOOGLE_ATTRIBUTE_NOINLINE - static inline void Merge(const GenericType& from, GenericType* to) { - to->MergeFrom(from); - } + GOOGLE_ATTRIBUTE_NOINLINE static void Merge(const GenericType& from, + GenericType* to); static inline int SpaceUsed(const GenericType& value) { return value.SpaceUsed(); } @@ -576,11 +563,31 @@ class GenericTypeHandler { } }; -template<> -inline MessageLite* GenericTypeHandler<MessageLite>::NewFromPrototype( - const MessageLite* prototype, google::protobuf::Arena* arena) { - return prototype->New(arena); +template <typename GenericType> +GenericType* GenericTypeHandler<GenericType>::NewFromPrototype( + const GenericType* prototype, ::google::protobuf::Arena* arena) { + return New(arena); } +template <typename GenericType> +void GenericTypeHandler<GenericType>::Delete(GenericType* value, Arena* arena) { + if (arena == NULL) { + delete value; + } +} +template <typename GenericType> +void GenericTypeHandler<GenericType>::Merge(const GenericType& from, + GenericType* to) { + to->MergeFrom(from); +} + +// NewFromPrototype() and Merge() cannot be defined here; if they're declared +// inline the compiler will complain about not matching GOOGLE_ATTRIBUTE_NOINLINE +// above, and if not, compilation will result in multiple definitions. These +// are therefore declared as specializations here and defined in +// message_lite.cc. +template<> +MessageLite* GenericTypeHandler<MessageLite>::NewFromPrototype( + const MessageLite* prototype, google::protobuf::Arena* arena); template<> inline google::protobuf::Arena* GenericTypeHandler<MessageLite>::GetArena( MessageLite* value) { @@ -591,14 +598,9 @@ inline void* GenericTypeHandler<MessageLite>::GetMaybeArenaPointer( MessageLite* value) { return value->GetMaybeArenaPointer(); } - -// Implements GenericTypeHandler specialization required by RepeatedPtrFields -// to work with MessageLite type. template <> -inline void GenericTypeHandler<MessageLite>::Merge( - const MessageLite& from, MessageLite* to) { - to->CheckTypeAndMergeFrom(from); -} +void GenericTypeHandler<MessageLite>::Merge(const MessageLite& from, + MessageLite* to); // Declarations of the specialization as we cannot define them here, as the // header that defines ProtocolMessage depends on types defined in this header. @@ -647,7 +649,8 @@ inline const Message& GenericTypeHandler<Message>::default_instance() { // StringTypeHandler is exported. So, we factor out StringTypeHandlerBase, // export that, then make StringTypeHandler be a subclass which is NOT // exported. -// TODO(kenton): There has to be a better way. +// TODO(kenton): Now that StringSpaceUsedExcludingSelf() is in the lite
+// library, this can be cleaned up. class LIBPROTOBUF_EXPORT StringTypeHandlerBase { public: typedef string Type; @@ -1221,13 +1224,17 @@ void RepeatedField<Element>::Reserve(int new_size) { Arena* arena = GetArenaNoVirtual(); new_size = max(google::protobuf::internal::kMinRepeatedFieldAllocationSize, max(total_size_ * 2, new_size)); + GOOGLE_CHECK_LE(static_cast<size_t>(new_size), + (std::numeric_limits<size_t>::max() - kRepHeaderSize) / + sizeof(Element)) + << "Requested size is too large to fit into size_t."; if (arena == NULL) { rep_ = reinterpret_cast<Rep*>( - new char[kRepHeaderSize + sizeof(Element)*new_size]); + new char[kRepHeaderSize + sizeof(Element) * new_size]); } else { rep_ = reinterpret_cast<Rep*>( ::google::protobuf::Arena::CreateArray<char>(arena, - kRepHeaderSize + sizeof(Element)*new_size)); + kRepHeaderSize + sizeof(Element) * new_size)); } rep_->arena = arena; int old_total_size = total_size_; @@ -1342,7 +1349,7 @@ inline void RepeatedPtrFieldBase::Swap(RepeatedPtrFieldBase* other) { } template <typename TypeHandler> -inline void RepeatedPtrFieldBase::SwapFallback(RepeatedPtrFieldBase* other) { +void RepeatedPtrFieldBase::SwapFallback(RepeatedPtrFieldBase* other) { GOOGLE_DCHECK(other->GetArenaNoVirtual() != GetArenaNoVirtual()); // Copy semantics in this case. We try to improve efficiency by placing the |