Commit df0b8333 authored by oqtvs's avatar oqtvs

Updated protobuf version to 3.5.1

parent 1255bd8d
...@@ -13,10 +13,11 @@ if(MSVC) ...@@ -13,10 +13,11 @@ if(MSVC)
/wd4702 /wd4456 /wd4457 /wd4065 /wd4310 /wd4661 /wd4506 /wd4702 /wd4456 /wd4457 /wd4065 /wd4310 /wd4661 /wd4506
) )
else() else()
#NOTE: -Wno-invalid-offsetof was used as solution for invalid offset warning on protobuf #3450
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wno-deprecated -Wmissing-prototypes -Wmissing-declarations -Wshadow ocv_warnings_disable(CMAKE_CXX_FLAGS -Wno-deprecated -Wmissing-prototypes -Wmissing-declarations -Wshadow
-Wunused-parameter -Wunused-local-typedefs -Wsign-compare -Wsign-promo -Wunused-parameter -Wunused-local-typedefs -Wsign-compare -Wsign-promo
-Wundef -Wtautological-undefined-compare -Wignored-qualifiers -Wextra -Wundef -Wtautological-undefined-compare -Wignored-qualifiers -Wextra
-Wunused-function -Wunused-const-variable -Wshorten-64-to-32 -Wunused-function -Wunused-const-variable -Wshorten-64-to-32 -Wno-invalid-offsetof
) )
endif() endif()
if(CV_ICC) if(CV_ICC)
...@@ -52,6 +53,7 @@ append_if_exist(Protobuf_SRCS ...@@ -52,6 +53,7 @@ append_if_exist(Protobuf_SRCS
${PROTOBUF_ROOT}/src/google/protobuf/arena.cc ${PROTOBUF_ROOT}/src/google/protobuf/arena.cc
${PROTOBUF_ROOT}/src/google/protobuf/arenastring.cc ${PROTOBUF_ROOT}/src/google/protobuf/arenastring.cc
${PROTOBUF_ROOT}/src/google/protobuf/extension_set.cc ${PROTOBUF_ROOT}/src/google/protobuf/extension_set.cc
${PROTOBUF_ROOT}/src/google/protobuf/generated_message_table_driven_lite.cc
${PROTOBUF_ROOT}/src/google/protobuf/generated_message_util.cc ${PROTOBUF_ROOT}/src/google/protobuf/generated_message_util.cc
${PROTOBUF_ROOT}/src/google/protobuf/io/coded_stream.cc ${PROTOBUF_ROOT}/src/google/protobuf/io/coded_stream.cc
${PROTOBUF_ROOT}/src/google/protobuf/io/zero_copy_stream.cc ${PROTOBUF_ROOT}/src/google/protobuf/io/zero_copy_stream.cc
...@@ -62,6 +64,7 @@ append_if_exist(Protobuf_SRCS ...@@ -62,6 +64,7 @@ append_if_exist(Protobuf_SRCS
${PROTOBUF_ROOT}/src/google/protobuf/stubs/bytestream.cc ${PROTOBUF_ROOT}/src/google/protobuf/stubs/bytestream.cc
${PROTOBUF_ROOT}/src/google/protobuf/stubs/common.cc ${PROTOBUF_ROOT}/src/google/protobuf/stubs/common.cc
${PROTOBUF_ROOT}/src/google/protobuf/stubs/int128.cc ${PROTOBUF_ROOT}/src/google/protobuf/stubs/int128.cc
${PROTOBUF_ROOT}/src/google/protobuf/stubs/io_win32.cc
${PROTOBUF_ROOT}/src/google/protobuf/stubs/once.cc ${PROTOBUF_ROOT}/src/google/protobuf/stubs/once.cc
${PROTOBUF_ROOT}/src/google/protobuf/stubs/status.cc ${PROTOBUF_ROOT}/src/google/protobuf/stubs/status.cc
${PROTOBUF_ROOT}/src/google/protobuf/stubs/statusor.cc ${PROTOBUF_ROOT}/src/google/protobuf/stubs/statusor.cc
...@@ -86,6 +89,7 @@ append_if_exist(Protobuf_SRCS ...@@ -86,6 +89,7 @@ append_if_exist(Protobuf_SRCS
${PROTOBUF_ROOT}/src/google/protobuf/extension_set_heavy.cc ${PROTOBUF_ROOT}/src/google/protobuf/extension_set_heavy.cc
${PROTOBUF_ROOT}/src/google/protobuf/field_mask.pb.cc ${PROTOBUF_ROOT}/src/google/protobuf/field_mask.pb.cc
${PROTOBUF_ROOT}/src/google/protobuf/generated_message_reflection.cc ${PROTOBUF_ROOT}/src/google/protobuf/generated_message_reflection.cc
${PROTOBUF_ROOT}/src/google/protobuf/generated_message_table_driven.cc
${PROTOBUF_ROOT}/src/google/protobuf/io/gzip_stream.cc ${PROTOBUF_ROOT}/src/google/protobuf/io/gzip_stream.cc
${PROTOBUF_ROOT}/src/google/protobuf/io/printer.cc ${PROTOBUF_ROOT}/src/google/protobuf/io/printer.cc
${PROTOBUF_ROOT}/src/google/protobuf/io/strtod.cc ${PROTOBUF_ROOT}/src/google/protobuf/io/strtod.cc
...@@ -103,6 +107,7 @@ append_if_exist(Protobuf_SRCS ...@@ -103,6 +107,7 @@ append_if_exist(Protobuf_SRCS
${PROTOBUF_ROOT}/src/google/protobuf/timestamp.pb.cc ${PROTOBUF_ROOT}/src/google/protobuf/timestamp.pb.cc
${PROTOBUF_ROOT}/src/google/protobuf/type.pb.cc ${PROTOBUF_ROOT}/src/google/protobuf/type.pb.cc
${PROTOBUF_ROOT}/src/google/protobuf/unknown_field_set.cc ${PROTOBUF_ROOT}/src/google/protobuf/unknown_field_set.cc
${PROTOBUF_ROOT}/src/google/protobuf/util/delimited_message_util.cc
${PROTOBUF_ROOT}/src/google/protobuf/util/field_comparator.cc ${PROTOBUF_ROOT}/src/google/protobuf/util/field_comparator.cc
${PROTOBUF_ROOT}/src/google/protobuf/util/field_mask_util.cc ${PROTOBUF_ROOT}/src/google/protobuf/util/field_mask_util.cc
${PROTOBUF_ROOT}/src/google/protobuf/util/internal/datapiece.cc ${PROTOBUF_ROOT}/src/google/protobuf/util/internal/datapiece.cc
......
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
#include <google/protobuf/any.h> #include <google/protobuf/any.h>
#include <google/protobuf/generated_message_util.h>
namespace google { namespace google {
namespace protobuf { namespace protobuf {
namespace internal { namespace internal {
...@@ -70,13 +72,11 @@ bool AnyMetadata::UnpackTo(Message* message) const { ...@@ -70,13 +72,11 @@ bool AnyMetadata::UnpackTo(Message* message) const {
if (!InternalIs(message->GetDescriptor())) { if (!InternalIs(message->GetDescriptor())) {
return false; return false;
} }
return message->ParseFromString( return message->ParseFromString(value_->GetNoArena());
value_->GetNoArena(&::google::protobuf::internal::GetEmptyString()));
} }
bool AnyMetadata::InternalIs(const Descriptor* descriptor) const { bool AnyMetadata::InternalIs(const Descriptor* descriptor) const {
const string type_url = type_url_->GetNoArena( const string type_url = type_url_->GetNoArena();
&::google::protobuf::internal::GetEmptyString());
string full_name; string full_name;
if (!ParseAnyTypeUrl(type_url, &full_name)) { if (!ParseAnyTypeUrl(type_url, &full_name)) {
return false; return false;
......
...@@ -63,7 +63,7 @@ class LIBPROTOBUF_EXPORT AnyMetadata { ...@@ -63,7 +63,7 @@ class LIBPROTOBUF_EXPORT AnyMetadata {
// Unpacks the payload into the given message. Returns false if the message's // Unpacks the payload into the given message. Returns false if the message's
// type doesn't match the type specified in the type URL (i.e., the full // type doesn't match the type specified in the type URL (i.e., the full
// name after the last "/" of the type URL doesn't match the message's actaul // name after the last "/" of the type URL doesn't match the message's actual
// full name) or parsing the payload has failed. // full name) or parsing the payload has failed.
bool UnpackTo(Message* message) const; bool UnpackTo(Message* message) const;
...@@ -90,8 +90,8 @@ extern const char kTypeGoogleProdComPrefix[]; // "type.googleprod.com/". ...@@ -90,8 +90,8 @@ extern const char kTypeGoogleProdComPrefix[]; // "type.googleprod.com/".
// Get the proto type name from Any::type_url value. For example, passing // Get the proto type name from Any::type_url value. For example, passing
// "type.googleapis.com/rpc.QueryOrigin" will return "rpc.QueryOrigin" in // "type.googleapis.com/rpc.QueryOrigin" will return "rpc.QueryOrigin" in
// *full_type_name. Returns false if type_url does not start with // *full_type_name. Returns false if the type_url does not have a "/"
// "type.googleapis.com" or "type.googleprod.com". // in the type url separating the full type name.
bool ParseAnyTypeUrl(const string& type_url, string* full_type_name); bool ParseAnyTypeUrl(const string& type_url, string* full_type_name);
// See if message is of type google.protobuf.Any, if so, return the descriptors // See if message is of type google.protobuf.Any, if so, return the descriptors
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This file defines an Arena allocator for better allocation performance.
#ifndef GOOGLE_PROTOBUF_ARENA_IMPL_H__
#define GOOGLE_PROTOBUF_ARENA_IMPL_H__
#include <limits>
#include <google/protobuf/stubs/atomic_sequence_num.h>
#include <google/protobuf/stubs/atomicops.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/mutex.h>
#include <google/protobuf/stubs/type_traits.h>
#include <google/protobuf/stubs/port.h>
namespace google {
namespace protobuf {
namespace internal {
inline size_t AlignUpTo8(size_t n) {
// Align n to next multiple of 8 (from Hacker's Delight, Chapter 3.)
return (n + 7) & -8;
}
// This class provides the core Arena memory allocation library. Different
// implementations only need to implement the public interface below.
// Arena is not a template type as that would only be useful if all protos
// in turn would be templates, which will/cannot happen. However separating
// the memory allocation part from the cruft of the API users expect we can
// use #ifdef the select the best implementation based on hardware / OS.
class LIBPROTOBUF_EXPORT ArenaImpl {
public:
struct Options {
size_t start_block_size;
size_t max_block_size;
char* initial_block;
size_t initial_block_size;
void* (*block_alloc)(size_t);
void (*block_dealloc)(void*, size_t);
template <typename O>
explicit Options(const O& options)
: start_block_size(options.start_block_size),
max_block_size(options.max_block_size),
initial_block(options.initial_block),
initial_block_size(options.initial_block_size),
block_alloc(options.block_alloc),
block_dealloc(options.block_dealloc) {}
};
template <typename O>
explicit ArenaImpl(const O& options) : options_(options) {
if (options_.initial_block != NULL && options_.initial_block_size > 0) {
GOOGLE_CHECK_GE(options_.initial_block_size, sizeof(Block))
<< ": Initial block size too small for header.";
initial_block_ = reinterpret_cast<Block*>(options_.initial_block);
} else {
initial_block_ = NULL;
}
Init();
}
// Destructor deletes all owned heap allocated objects, and destructs objects
// that have non-trivial destructors, except for proto2 message objects whose
// destructors can be skipped. Also, frees all blocks except the initial block
// if it was passed in.
~ArenaImpl();
uint64 Reset();
uint64 SpaceAllocated() const;
uint64 SpaceUsed() const;
void* AllocateAligned(size_t n);
void* AllocateAlignedAndAddCleanup(size_t n, void (*cleanup)(void*));
// Add object pointer and cleanup function pointer to the list.
void AddCleanup(void* elem, void (*cleanup)(void*));
private:
// Node contains the ptr of the object to be cleaned up and the associated
// cleanup function ptr.
struct CleanupNode {
void* elem; // Pointer to the object to be cleaned up.
void (*cleanup)(void*); // Function pointer to the destructor or deleter.
};
// Cleanup uses a chunked linked list, to reduce pointer chasing.
struct CleanupChunk {
static size_t SizeOf(size_t i) {
return sizeof(CleanupChunk) + (sizeof(CleanupNode) * (i - 1));
}
size_t len; // Number of elements currently present.
size_t size; // Total elements in the list.
CleanupChunk* next; // Next node in the list.
CleanupNode nodes[1]; // True length is |size|.
};
struct Block;
// Tracks per-thread info. ThreadInfos are kept in a linked list.
struct ThreadInfo {
void *owner; // &ThreadCache of this thread;
Block* head; // Head of linked list of blocks.
CleanupChunk* cleanup; // Head of cleanup list.
ThreadInfo* next; // Next ThreadInfo in this linked list.
};
// Blocks are variable length malloc-ed objects. The following structure
// describes the common header for all blocks.
struct Block {
void* owner; // &ThreadCache of thread that owns this block.
ThreadInfo* thread_info; // ThreadInfo of thread that owns this block.
Block* next; // Next block in arena (may have different owner)
// ((char*) &block) + pos is next available byte. It is always
// aligned at a multiple of 8 bytes.
size_t pos;
size_t size; // total size of the block.
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
size_t avail() const { return size - pos; }
// data follows
};
struct ThreadCache {
#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
// If we are using the ThreadLocalStorage class to store the ThreadCache,
// then the ThreadCache's default constructor has to be responsible for
// initializing it.
ThreadCache() : last_lifecycle_id_seen(-1), last_block_used_(NULL) {}
#endif
// The ThreadCache is considered valid as long as this matches the
// lifecycle_id of the arena being used.
int64 last_lifecycle_id_seen;
Block* last_block_used_;
};
static google::protobuf::internal::SequenceNumber lifecycle_id_generator_;
#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
// Android ndk does not support GOOGLE_THREAD_LOCAL keyword so we use a custom thread
// local storage class we implemented.
// iOS also does not support the GOOGLE_THREAD_LOCAL keyword.
static ThreadCache& thread_cache();
#elif defined(PROTOBUF_USE_DLLS)
// Thread local variables cannot be exposed through DLL interface but we can
// wrap them in static functions.
static ThreadCache& thread_cache();
#else
static GOOGLE_THREAD_LOCAL ThreadCache thread_cache_;
static ThreadCache& thread_cache() { return thread_cache_; }
#endif
void Init();
// Free all blocks and return the total space used which is the sums of sizes
// of the all the allocated blocks.
uint64 FreeBlocks();
void AddCleanupInBlock(Block* b, void* elem, void (*func)(void*));
CleanupChunk* ExpandCleanupList(CleanupChunk* cleanup, Block* b);
// Delete or Destruct all objects owned by the arena.
void CleanupList();
inline void CacheBlock(Block* block) {
thread_cache().last_block_used_ = block;
thread_cache().last_lifecycle_id_seen = lifecycle_id_;
// TODO(haberman): evaluate whether we would gain efficiency by getting rid
// of hint_. It's the only write we do to ArenaImpl in the allocation path,
// which will dirty the cache line.
google::protobuf::internal::Release_Store(&hint_, reinterpret_cast<google::protobuf::internal::AtomicWord>(block));
}
google::protobuf::internal::AtomicWord threads_; // Pointer to a linked list of ThreadInfo.
google::protobuf::internal::AtomicWord hint_; // Fast thread-local block access
google::protobuf::internal::AtomicWord space_allocated_; // Sum of sizes of all allocated blocks.
Block *initial_block_; // If non-NULL, points to the block that came from
// user data.
// Returns a block owned by this thread.
Block* GetBlock(size_t n);
Block* GetBlockSlow(void* me, Block* my_full_block, size_t n);
Block* NewBlock(void* me, Block* my_last_block, size_t min_bytes);
void InitBlock(Block* b, void *me, size_t size);
static void* AllocFromBlock(Block* b, size_t n);
ThreadInfo* NewThreadInfo(Block* b);
ThreadInfo* FindThreadInfo(void* me);
ThreadInfo* GetThreadInfo(void* me, size_t n);
int64 lifecycle_id_; // Unique for each arena. Changes on Reset().
Options options_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArenaImpl);
public:
// kHeaderSize is sizeof(Block), aligned up to the nearest multiple of 8 to
// protect the invariant that pos is always at a multiple of 8.
static const size_t kHeaderSize = (sizeof(Block) + 7) & -8;
#if LANG_CXX11
static_assert(kHeaderSize % 8 == 0, "kHeaderSize must be a multiple of 8.");
#endif
};
} // namespace internal
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_ARENA_IMPL_H__
...@@ -38,16 +38,6 @@ namespace protobuf { ...@@ -38,16 +38,6 @@ namespace protobuf {
namespace internal { namespace internal {
void ArenaStringPtr::AssignWithDefault(const ::std::string* default_value,
ArenaStringPtr value) {
const ::std::string* me = *UnsafeRawStringPointer();
const ::std::string* other = *value.UnsafeRawStringPointer();
// If the pointers are the same then do nothing.
if (me != other) {
SetNoArena(default_value, value.GetNoArena(default_value));
}
}
} // namespace internal } // namespace internal
} // namespace protobuf } // namespace protobuf
} // namespace google } // namespace google
...@@ -33,13 +33,11 @@ ...@@ -33,13 +33,11 @@
#include <string> #include <string>
#include <google/protobuf/stubs/logging.h> #include <google/protobuf/arena.h>
#include <google/protobuf/stubs/common.h> #include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/fastmem.h> #include <google/protobuf/stubs/fastmem.h>
#include <google/protobuf/arena.h> #include <google/protobuf/stubs/logging.h>
#include <google/protobuf/generated_message_util.h> #include <google/protobuf/stubs/port.h>
// This is the implementation of arena string fields written for the open-source // This is the implementation of arena string fields written for the open-source
// release. The ArenaStringPtr struct below is an internal implementation class // release. The ArenaStringPtr struct below is an internal implementation class
...@@ -63,11 +61,15 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr { ...@@ -63,11 +61,15 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
} }
} }
// Basic accessors. inline void SetLite(const ::std::string* default_value,
inline const ::std::string& Get(const ::std::string* /* default_value */) const { const ::std::string& value,
return *ptr_; ::google::protobuf::Arena* arena) {
Set(default_value, value, arena);
} }
// Basic accessors.
inline const ::std::string& Get() const { return *ptr_; }
inline ::std::string* Mutable(const ::std::string* default_value, inline ::std::string* Mutable(const ::std::string* default_value,
::google::protobuf::Arena* arena) { ::google::protobuf::Arena* arena) {
if (ptr_ == default_value) { if (ptr_ == default_value) {
...@@ -87,8 +89,9 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr { ...@@ -87,8 +89,9 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
} }
::std::string* released = NULL; ::std::string* released = NULL;
if (arena != NULL) { if (arena != NULL) {
// ptr_ is owned by the arena -- we need to return a copy. // ptr_ is owned by the arena.
released = new ::std::string(*ptr_); released = new ::std::string;
released->swap(*ptr_);
} else { } else {
released = ptr_; released = ptr_;
} }
...@@ -146,17 +149,16 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr { ...@@ -146,17 +149,16 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
// Swaps internal pointers. Arena-safety semantics: this is guarded by the // Swaps internal pointers. Arena-safety semantics: this is guarded by the
// logic in Swap()/UnsafeArenaSwap() at the message level, so this method is // logic in Swap()/UnsafeArenaSwap() at the message level, so this method is
// 'unsafe' if called directly. // 'unsafe' if called directly.
GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Swap(ArenaStringPtr* other) { GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE void Swap(ArenaStringPtr* other) {
std::swap(ptr_, other->ptr_); std::swap(ptr_, other->ptr_);
} }
// Frees storage (if not on an arena) and sets field to default value. // Frees storage (if not on an arena).
inline void Destroy(const ::std::string* default_value, inline void Destroy(const ::std::string* default_value,
::google::protobuf::Arena* arena) { ::google::protobuf::Arena* arena) {
if (arena == NULL && ptr_ != default_value) { if (arena == NULL && ptr_ != default_value) {
delete ptr_; delete ptr_;
} }
ptr_ = const_cast< ::std::string* >(default_value);
} }
// Clears content, but keeps allocated string if arena != NULL, to avoid the // Clears content, but keeps allocated string if arena != NULL, to avoid the
...@@ -214,11 +216,19 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr { ...@@ -214,11 +216,19 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
} }
} }
#if LANG_CXX11
void SetNoArena(const ::std::string* default_value, ::std::string&& value) {
if (IsDefault(default_value)) {
ptr_ = new ::std::string(std::move(value));
} else {
*ptr_ = std::move(value);
}
}
#endif
void AssignWithDefault(const ::std::string* default_value, ArenaStringPtr value); void AssignWithDefault(const ::std::string* default_value, ArenaStringPtr value);
inline const ::std::string& GetNoArena(const ::std::string* /* default_value */) const { inline const ::std::string& GetNoArena() const { return *ptr_; }
return *ptr_;
}
inline ::std::string* MutableNoArena(const ::std::string* default_value) { inline ::std::string* MutableNoArena(const ::std::string* default_value) {
if (ptr_ == default_value) { if (ptr_ == default_value) {
...@@ -253,7 +263,6 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr { ...@@ -253,7 +263,6 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
if (ptr_ != default_value) { if (ptr_ != default_value) {
delete ptr_; delete ptr_;
} }
ptr_ = NULL;
} }
inline void ClearToEmptyNoArena(const ::std::string* default_value) { inline void ClearToEmptyNoArena(const ::std::string* default_value) {
...@@ -281,27 +290,26 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr { ...@@ -281,27 +290,26 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
return &ptr_; return &ptr_;
} }
inline bool IsDefault(const ::std::string* default_value) const {
return ptr_ == default_value;
}
private: private:
::std::string* ptr_; ::std::string* ptr_;
GOOGLE_ATTRIBUTE_NOINLINE void CreateInstance(::google::protobuf::Arena* arena, GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE
const ::std::string* initial_value) { void CreateInstance(::google::protobuf::Arena* arena,
// Assumes ptr_ is not NULL. const ::std::string* initial_value) {
if (initial_value != NULL) { GOOGLE_DCHECK(initial_value != NULL);
ptr_ = new ::std::string(*initial_value); ptr_ = new ::std::string(*initial_value);
} else {
ptr_ = new ::std::string();
}
if (arena != NULL) { if (arena != NULL) {
arena->Own(ptr_); arena->Own(ptr_);
} }
} }
GOOGLE_ATTRIBUTE_NOINLINE void CreateInstanceNoArena(const ::std::string* initial_value) { GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE
if (initial_value != NULL) { void CreateInstanceNoArena(const ::std::string* initial_value) {
ptr_ = new ::std::string(*initial_value); GOOGLE_DCHECK(initial_value != NULL);
} else { ptr_ = new ::std::string(*initial_value);
ptr_ = new ::std::string();
}
} }
}; };
...@@ -310,5 +318,21 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr { ...@@ -310,5 +318,21 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
namespace protobuf {
namespace internal {
inline void ArenaStringPtr::AssignWithDefault(const ::std::string* default_value,
ArenaStringPtr value) {
const ::std::string* me = *UnsafeRawStringPointer();
const ::std::string* other = *value.UnsafeRawStringPointer();
// If the pointers are the same then do nothing.
if (me != other) {
SetNoArena(default_value, value.GetNoArena());
}
}
} // namespace internal
} // namespace protobuf
} // namespace google } // namespace google
#endif // GOOGLE_PROTOBUF_ARENASTRING_H__ #endif // GOOGLE_PROTOBUF_ARENASTRING_H__
...@@ -39,8 +39,9 @@ ...@@ -39,8 +39,9 @@
#include <google/protobuf/descriptor.pb.h> #include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/wire_format_lite_inl.h> #include <google/protobuf/wire_format_lite_inl.h>
#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/stl_util.h>
#include <google/protobuf/stubs/map_util.h> #include <google/protobuf/stubs/map_util.h>
#include <google/protobuf/stubs/stl_util.h>
namespace google { namespace google {
namespace protobuf { namespace protobuf {
...@@ -97,11 +98,12 @@ bool SimpleDescriptorDatabase::DescriptorIndex<Value>::AddSymbol( ...@@ -97,11 +98,12 @@ bool SimpleDescriptorDatabase::DescriptorIndex<Value>::AddSymbol(
// Try to look up the symbol to make sure a super-symbol doesn't already // Try to look up the symbol to make sure a super-symbol doesn't already
// exist. // exist.
typename map<string, Value>::iterator iter = FindLastLessOrEqual(name); typename std::map<string, Value>::iterator iter = FindLastLessOrEqual(name);
if (iter == by_symbol_.end()) { if (iter == by_symbol_.end()) {
// Apparently the map is currently empty. Just insert and be done with it. // Apparently the map is currently empty. Just insert and be done with it.
by_symbol_.insert(typename map<string, Value>::value_type(name, value)); by_symbol_.insert(
typename std::map<string, Value>::value_type(name, value));
return true; return true;
} }
...@@ -128,7 +130,8 @@ bool SimpleDescriptorDatabase::DescriptorIndex<Value>::AddSymbol( ...@@ -128,7 +130,8 @@ bool SimpleDescriptorDatabase::DescriptorIndex<Value>::AddSymbol(
// Insert the new symbol using the iterator as a hint, the new entry will // Insert the new symbol using the iterator as a hint, the new entry will
// appear immediately before the one the iterator is pointing at. // appear immediately before the one the iterator is pointing at.
by_symbol_.insert(iter, typename map<string, Value>::value_type(name, value)); by_symbol_.insert(iter,
typename std::map<string, Value>::value_type(name, value));
return true; return true;
} }
...@@ -179,7 +182,7 @@ Value SimpleDescriptorDatabase::DescriptorIndex<Value>::FindFile( ...@@ -179,7 +182,7 @@ Value SimpleDescriptorDatabase::DescriptorIndex<Value>::FindFile(
template <typename Value> template <typename Value>
Value SimpleDescriptorDatabase::DescriptorIndex<Value>::FindSymbol( Value SimpleDescriptorDatabase::DescriptorIndex<Value>::FindSymbol(
const string& name) { const string& name) {
typename map<string, Value>::iterator iter = FindLastLessOrEqual(name); typename std::map<string, Value>::iterator iter = FindLastLessOrEqual(name);
return (iter != by_symbol_.end() && IsSubSymbol(iter->first, name)) ? return (iter != by_symbol_.end() && IsSubSymbol(iter->first, name)) ?
iter->second : Value(); iter->second : Value();
...@@ -196,8 +199,8 @@ Value SimpleDescriptorDatabase::DescriptorIndex<Value>::FindExtension( ...@@ -196,8 +199,8 @@ Value SimpleDescriptorDatabase::DescriptorIndex<Value>::FindExtension(
template <typename Value> template <typename Value>
bool SimpleDescriptorDatabase::DescriptorIndex<Value>::FindAllExtensionNumbers( bool SimpleDescriptorDatabase::DescriptorIndex<Value>::FindAllExtensionNumbers(
const string& containing_type, const string& containing_type,
vector<int>* output) { std::vector<int>* output) {
typename map<pair<string, int>, Value>::const_iterator it = typename std::map<std::pair<string, int>, Value>::const_iterator it =
by_extension_.lower_bound(std::make_pair(containing_type, 0)); by_extension_.lower_bound(std::make_pair(containing_type, 0));
bool success = false; bool success = false;
...@@ -211,13 +214,14 @@ bool SimpleDescriptorDatabase::DescriptorIndex<Value>::FindAllExtensionNumbers( ...@@ -211,13 +214,14 @@ bool SimpleDescriptorDatabase::DescriptorIndex<Value>::FindAllExtensionNumbers(
} }
template <typename Value> template <typename Value>
typename map<string, Value>::iterator typename std::map<string, Value>::iterator
SimpleDescriptorDatabase::DescriptorIndex<Value>::FindLastLessOrEqual( SimpleDescriptorDatabase::DescriptorIndex<Value>::FindLastLessOrEqual(
const string& name) { const string& name) {
// Find the last key in the map which sorts less than or equal to the // Find the last key in the map which sorts less than or equal to the
// symbol name. Since upper_bound() returns the *first* key that sorts // symbol name. Since upper_bound() returns the *first* key that sorts
// *greater* than the input, we want the element immediately before that. // *greater* than the input, we want the element immediately before that.
typename map<string, Value>::iterator iter = by_symbol_.upper_bound(name); typename std::map<string, Value>::iterator iter =
by_symbol_.upper_bound(name);
if (iter != by_symbol_.begin()) --iter; if (iter != by_symbol_.begin()) --iter;
return iter; return iter;
} }
...@@ -227,7 +231,7 @@ bool SimpleDescriptorDatabase::DescriptorIndex<Value>::IsSubSymbol( ...@@ -227,7 +231,7 @@ bool SimpleDescriptorDatabase::DescriptorIndex<Value>::IsSubSymbol(
const string& sub_symbol, const string& super_symbol) { const string& sub_symbol, const string& super_symbol) {
return sub_symbol == super_symbol || return sub_symbol == super_symbol ||
(HasPrefixString(super_symbol, sub_symbol) && (HasPrefixString(super_symbol, sub_symbol) &&
super_symbol[sub_symbol.size()] == '.'); super_symbol[sub_symbol.size()] == '.');
} }
template <typename Value> template <typename Value>
...@@ -284,7 +288,7 @@ bool SimpleDescriptorDatabase::FindFileContainingExtension( ...@@ -284,7 +288,7 @@ bool SimpleDescriptorDatabase::FindFileContainingExtension(
bool SimpleDescriptorDatabase::FindAllExtensionNumbers( bool SimpleDescriptorDatabase::FindAllExtensionNumbers(
const string& extendee_type, const string& extendee_type,
vector<int>* output) { std::vector<int>* output) {
return index_.FindAllExtensionNumbers(extendee_type, output); return index_.FindAllExtensionNumbers(extendee_type, output);
} }
...@@ -340,7 +344,7 @@ bool EncodedDescriptorDatabase::FindFileContainingSymbol( ...@@ -340,7 +344,7 @@ bool EncodedDescriptorDatabase::FindFileContainingSymbol(
bool EncodedDescriptorDatabase::FindNameOfFileContainingSymbol( bool EncodedDescriptorDatabase::FindNameOfFileContainingSymbol(
const string& symbol_name, const string& symbol_name,
string* output) { string* output) {
pair<const void*, int> encoded_file = index_.FindSymbol(symbol_name); std::pair<const void*, int> encoded_file = index_.FindSymbol(symbol_name);
if (encoded_file.first == NULL) return false; if (encoded_file.first == NULL) return false;
// Optimization: The name should be the first field in the encoded message. // Optimization: The name should be the first field in the encoded message.
...@@ -352,7 +356,7 @@ bool EncodedDescriptorDatabase::FindNameOfFileContainingSymbol( ...@@ -352,7 +356,7 @@ bool EncodedDescriptorDatabase::FindNameOfFileContainingSymbol(
FileDescriptorProto::kNameFieldNumber, FileDescriptorProto::kNameFieldNumber,
internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED); internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
if (input.ReadTag() == kNameTag) { if (input.ReadTagNoLastTag() == kNameTag) {
// Success! // Success!
return internal::WireFormatLite::ReadString(&input, output); return internal::WireFormatLite::ReadString(&input, output);
} else { } else {
...@@ -376,12 +380,12 @@ bool EncodedDescriptorDatabase::FindFileContainingExtension( ...@@ -376,12 +380,12 @@ bool EncodedDescriptorDatabase::FindFileContainingExtension(
bool EncodedDescriptorDatabase::FindAllExtensionNumbers( bool EncodedDescriptorDatabase::FindAllExtensionNumbers(
const string& extendee_type, const string& extendee_type,
vector<int>* output) { std::vector<int>* output) {
return index_.FindAllExtensionNumbers(extendee_type, output); return index_.FindAllExtensionNumbers(extendee_type, output);
} }
bool EncodedDescriptorDatabase::MaybeParse( bool EncodedDescriptorDatabase::MaybeParse(
pair<const void*, int> encoded_file, std::pair<const void*, int> encoded_file,
FileDescriptorProto* output) { FileDescriptorProto* output) {
if (encoded_file.first == NULL) return false; if (encoded_file.first == NULL) return false;
return output->ParseFromArray(encoded_file.first, encoded_file.second); return output->ParseFromArray(encoded_file.first, encoded_file.second);
...@@ -431,11 +435,11 @@ bool DescriptorPoolDatabase::FindFileContainingExtension( ...@@ -431,11 +435,11 @@ bool DescriptorPoolDatabase::FindFileContainingExtension(
bool DescriptorPoolDatabase::FindAllExtensionNumbers( bool DescriptorPoolDatabase::FindAllExtensionNumbers(
const string& extendee_type, const string& extendee_type,
vector<int>* output) { std::vector<int>* output) {
const Descriptor* extendee = pool_.FindMessageTypeByName(extendee_type); const Descriptor* extendee = pool_.FindMessageTypeByName(extendee_type);
if (extendee == NULL) return false; if (extendee == NULL) return false;
vector<const FieldDescriptor*> extensions; std::vector<const FieldDescriptor*> extensions;
pool_.FindAllExtensions(extendee, &extensions); pool_.FindAllExtensions(extendee, &extensions);
for (int i = 0; i < extensions.size(); ++i) { for (int i = 0; i < extensions.size(); ++i) {
...@@ -454,7 +458,7 @@ MergedDescriptorDatabase::MergedDescriptorDatabase( ...@@ -454,7 +458,7 @@ MergedDescriptorDatabase::MergedDescriptorDatabase(
sources_.push_back(source2); sources_.push_back(source2);
} }
MergedDescriptorDatabase::MergedDescriptorDatabase( MergedDescriptorDatabase::MergedDescriptorDatabase(
const vector<DescriptorDatabase*>& sources) const std::vector<DescriptorDatabase*>& sources)
: sources_(sources) {} : sources_(sources) {}
MergedDescriptorDatabase::~MergedDescriptorDatabase() {} MergedDescriptorDatabase::~MergedDescriptorDatabase() {}
...@@ -517,23 +521,23 @@ bool MergedDescriptorDatabase::FindFileContainingExtension( ...@@ -517,23 +521,23 @@ bool MergedDescriptorDatabase::FindFileContainingExtension(
bool MergedDescriptorDatabase::FindAllExtensionNumbers( bool MergedDescriptorDatabase::FindAllExtensionNumbers(
const string& extendee_type, const string& extendee_type,
vector<int>* output) { std::vector<int>* output) {
set<int> merged_results; std::set<int> merged_results;
vector<int> results; std::vector<int> results;
bool success = false; bool success = false;
for (int i = 0; i < sources_.size(); i++) { for (int i = 0; i < sources_.size(); i++) {
if (sources_[i]->FindAllExtensionNumbers(extendee_type, &results)) { if (sources_[i]->FindAllExtensionNumbers(extendee_type, &results)) {
std::copy( std::copy(results.begin(), results.end(),
results.begin(), results.end(), std::insert_iterator<std::set<int> >(merged_results,
insert_iterator<set<int> >(merged_results, merged_results.begin())); merged_results.begin()));
success = true; success = true;
} }
results.clear(); results.clear();
} }
std::copy(merged_results.begin(), merged_results.end(), std::copy(merged_results.begin(), merged_results.end(),
insert_iterator<vector<int> >(*output, output->end())); std::insert_iterator<std::vector<int> >(*output, output->end()));
return success; return success;
} }
......
...@@ -97,11 +97,23 @@ class LIBPROTOBUF_EXPORT DescriptorDatabase { ...@@ -97,11 +97,23 @@ class LIBPROTOBUF_EXPORT DescriptorDatabase {
// This method has a default implementation that always returns // This method has a default implementation that always returns
// false. // false.
virtual bool FindAllExtensionNumbers(const string& /* extendee_type */, virtual bool FindAllExtensionNumbers(const string& /* extendee_type */,
vector<int>* /* output */) { std::vector<int>* /* output */) {
return false; return false;
} }
// Finds the file names and appends them to the output in an
// undefined order. This method is best-effort: it's not guaranteed that the
// database will find all files. Returns true if the database supports
// searching all file names, otherwise returns false and leaves output
// unchanged.
//
// This method has a default implementation that always returns
// false.
virtual bool FindAllFileNames(std::vector<string>* output) {
return false;
}
private: private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorDatabase); GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorDatabase);
}; };
...@@ -150,7 +162,7 @@ class LIBPROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase { ...@@ -150,7 +162,7 @@ class LIBPROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase {
int field_number, int field_number,
FileDescriptorProto* output); FileDescriptorProto* output);
bool FindAllExtensionNumbers(const string& extendee_type, bool FindAllExtensionNumbers(const string& extendee_type,
vector<int>* output); std::vector<int>* output);
private: private:
// So that it can use DescriptorIndex. // So that it can use DescriptorIndex.
...@@ -175,12 +187,12 @@ class LIBPROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase { ...@@ -175,12 +187,12 @@ class LIBPROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase {
Value FindSymbol(const string& name); Value FindSymbol(const string& name);
Value FindExtension(const string& containing_type, int field_number); Value FindExtension(const string& containing_type, int field_number);
bool FindAllExtensionNumbers(const string& containing_type, bool FindAllExtensionNumbers(const string& containing_type,
vector<int>* output); std::vector<int>* output);
private: private:
map<string, Value> by_name_; std::map<string, Value> by_name_;
map<string, Value> by_symbol_; std::map<string, Value> by_symbol_;
map<pair<string, int>, Value> by_extension_; std::map<std::pair<string, int>, Value> by_extension_;
// Invariant: The by_symbol_ map does not contain any symbols which are // Invariant: The by_symbol_ map does not contain any symbols which are
// prefixes of other symbols in the map. For example, "foo.bar" is a // prefixes of other symbols in the map. For example, "foo.bar" is a
...@@ -235,7 +247,7 @@ class LIBPROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase { ...@@ -235,7 +247,7 @@ class LIBPROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase {
// Find the last entry in the by_symbol_ map whose key is less than or // Find the last entry in the by_symbol_ map whose key is less than or
// equal to the given name. // equal to the given name.
typename map<string, Value>::iterator FindLastLessOrEqual( typename std::map<string, Value>::iterator FindLastLessOrEqual(
const string& name); const string& name);
// True if either the arguments are equal or super_symbol identifies a // True if either the arguments are equal or super_symbol identifies a
...@@ -250,7 +262,7 @@ class LIBPROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase { ...@@ -250,7 +262,7 @@ class LIBPROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase {
DescriptorIndex<const FileDescriptorProto*> index_; DescriptorIndex<const FileDescriptorProto*> index_;
vector<const FileDescriptorProto*> files_to_delete_; std::vector<const FileDescriptorProto*> files_to_delete_;
// If file is non-NULL, copy it into *output and return true, otherwise // If file is non-NULL, copy it into *output and return true, otherwise
// return false. // return false.
...@@ -295,15 +307,16 @@ class LIBPROTOBUF_EXPORT EncodedDescriptorDatabase : public DescriptorDatabase { ...@@ -295,15 +307,16 @@ class LIBPROTOBUF_EXPORT EncodedDescriptorDatabase : public DescriptorDatabase {
int field_number, int field_number,
FileDescriptorProto* output); FileDescriptorProto* output);
bool FindAllExtensionNumbers(const string& extendee_type, bool FindAllExtensionNumbers(const string& extendee_type,
vector<int>* output); std::vector<int>* output);
private: private:
SimpleDescriptorDatabase::DescriptorIndex<pair<const void*, int> > index_; SimpleDescriptorDatabase::DescriptorIndex<std::pair<const void*, int> >
vector<void*> files_to_delete_; index_;
std::vector<void*> files_to_delete_;
// If encoded_file.first is non-NULL, parse the data into *output and return // If encoded_file.first is non-NULL, parse the data into *output and return
// true, otherwise return false. // true, otherwise return false.
bool MaybeParse(pair<const void*, int> encoded_file, bool MaybeParse(std::pair<const void*, int> encoded_file,
FileDescriptorProto* output); FileDescriptorProto* output);
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EncodedDescriptorDatabase); GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EncodedDescriptorDatabase);
...@@ -324,7 +337,7 @@ class LIBPROTOBUF_EXPORT DescriptorPoolDatabase : public DescriptorDatabase { ...@@ -324,7 +337,7 @@ class LIBPROTOBUF_EXPORT DescriptorPoolDatabase : public DescriptorDatabase {
int field_number, int field_number,
FileDescriptorProto* output); FileDescriptorProto* output);
bool FindAllExtensionNumbers(const string& extendee_type, bool FindAllExtensionNumbers(const string& extendee_type,
vector<int>* output); std::vector<int>* output);
private: private:
const DescriptorPool& pool_; const DescriptorPool& pool_;
...@@ -341,7 +354,8 @@ class LIBPROTOBUF_EXPORT MergedDescriptorDatabase : public DescriptorDatabase { ...@@ -341,7 +354,8 @@ class LIBPROTOBUF_EXPORT MergedDescriptorDatabase : public DescriptorDatabase {
// Merge more than two databases. The sources remain property of the caller. // Merge more than two databases. The sources remain property of the caller.
// The vector may be deleted after the constructor returns but the // The vector may be deleted after the constructor returns but the
// DescriptorDatabases need to stick around. // DescriptorDatabases need to stick around.
explicit MergedDescriptorDatabase(const vector<DescriptorDatabase*>& sources); explicit MergedDescriptorDatabase(
const std::vector<DescriptorDatabase*>& sources);
~MergedDescriptorDatabase(); ~MergedDescriptorDatabase();
// implements DescriptorDatabase ----------------------------------- // implements DescriptorDatabase -----------------------------------
...@@ -355,11 +369,11 @@ class LIBPROTOBUF_EXPORT MergedDescriptorDatabase : public DescriptorDatabase { ...@@ -355,11 +369,11 @@ class LIBPROTOBUF_EXPORT MergedDescriptorDatabase : public DescriptorDatabase {
// Merges the results of calling all databases. Returns true iff any // Merges the results of calling all databases. Returns true iff any
// of the databases returned true. // of the databases returned true.
bool FindAllExtensionNumbers(const string& extendee_type, bool FindAllExtensionNumbers(const string& extendee_type,
vector<int>* output); std::vector<int>* output);
private: private:
vector<DescriptorDatabase*> sources_; std::vector<DescriptorDatabase*> sources_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MergedDescriptorDatabase); GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MergedDescriptorDatabase);
}; };
......
...@@ -38,12 +38,15 @@ ...@@ -38,12 +38,15 @@
#ifndef GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__ #ifndef GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__
#define GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__ #define GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__
#include <algorithm>
#include <memory> #include <memory>
#ifndef _SHARED_PTR_H #ifndef _SHARED_PTR_H
#include <google/protobuf/stubs/shared_ptr.h> #include <google/protobuf/stubs/shared_ptr.h>
#endif #endif
#include <vector>
#include <google/protobuf/message.h> #include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/stubs/common.h> #include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/mutex.h> #include <google/protobuf/stubs/mutex.h>
...@@ -136,16 +139,97 @@ class LIBPROTOBUF_EXPORT DynamicMessageFactory : public MessageFactory { ...@@ -136,16 +139,97 @@ class LIBPROTOBUF_EXPORT DynamicMessageFactory : public MessageFactory {
// Construct default oneof instance for reflection usage if oneof // Construct default oneof instance for reflection usage if oneof
// is defined. // is defined.
static void ConstructDefaultOneofInstance(const Descriptor* type, static void ConstructDefaultOneofInstance(const Descriptor* type,
const int offsets[], const uint32 offsets[],
void* default_oneof_instance); void* default_oneof_instance);
// Delete default oneof instance. Called by ~DynamicMessageFactory. // Delete default oneof instance. Called by ~DynamicMessageFactory.
static void DeleteDefaultOneofInstance(const Descriptor* type, static void DeleteDefaultOneofInstance(const Descriptor* type,
const int offsets[], const uint32 offsets[],
void* default_oneof_instance); const void* default_oneof_instance);
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessageFactory); GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessageFactory);
}; };
// Helper for computing a sorted list of map entries via reflection.
class LIBPROTOBUF_EXPORT DynamicMapSorter {
public:
static std::vector<const Message*> Sort(const Message& message,
int map_size,
const Reflection* reflection,
const FieldDescriptor* field) {
std::vector<const Message*> result(static_cast<size_t>(map_size));
const RepeatedPtrField<Message>& map_field =
reflection->GetRepeatedPtrField<Message>(message, field);
size_t i = 0;
for (RepeatedPtrField<Message>::const_pointer_iterator it =
map_field.pointer_begin(); it != map_field.pointer_end(); ) {
result[i++] = *it++;
}
GOOGLE_DCHECK_EQ(result.size(), i);
MapEntryMessageComparator comparator(field->message_type());
std::stable_sort(result.begin(), result.end(), comparator);
// Complain if the keys aren't in ascending order.
#ifndef NDEBUG
for (size_t j = 1; j < static_cast<size_t>(map_size); j++) {
if (!comparator(result[j - 1], result[j])) {
GOOGLE_LOG(ERROR) << (comparator(result[j], result[j - 1]) ?
"internal error in map key sorting" :
"map keys are not unique");
}
}
#endif
return result;
}
private:
class LIBPROTOBUF_EXPORT MapEntryMessageComparator {
public:
explicit MapEntryMessageComparator(const Descriptor* descriptor)
: field_(descriptor->field(0)) {}
bool operator()(const Message* a, const Message* b) {
const Reflection* reflection = a->GetReflection();
switch (field_->cpp_type()) {
case FieldDescriptor::CPPTYPE_BOOL: {
bool first = reflection->GetBool(*a, field_);
bool second = reflection->GetBool(*b, field_);
return first < second;
}
case FieldDescriptor::CPPTYPE_INT32: {
int32 first = reflection->GetInt32(*a, field_);
int32 second = reflection->GetInt32(*b, field_);
return first < second;
}
case FieldDescriptor::CPPTYPE_INT64: {
int64 first = reflection->GetInt64(*a, field_);
int64 second = reflection->GetInt64(*b, field_);
return first < second;
}
case FieldDescriptor::CPPTYPE_UINT32: {
uint32 first = reflection->GetUInt32(*a, field_);
uint32 second = reflection->GetUInt32(*b, field_);
return first < second;
}
case FieldDescriptor::CPPTYPE_UINT64: {
uint64 first = reflection->GetUInt64(*a, field_);
uint64 second = reflection->GetUInt64(*b, field_);
return first < second;
}
case FieldDescriptor::CPPTYPE_STRING: {
string first = reflection->GetString(*a, field_);
string second = reflection->GetString(*b, field_);
return first < second;
}
default:
GOOGLE_LOG(DFATAL) << "Invalid key for map field.";
return true;
}
}
private:
const FieldDescriptor* field_;
};
};
} // namespace protobuf } // namespace protobuf
} // namespace google } // namespace google
......
...@@ -76,7 +76,7 @@ inline bool is_packable(WireFormatLite::WireType type) { ...@@ -76,7 +76,7 @@ inline bool is_packable(WireFormatLite::WireType type) {
} }
// Registry stuff. // Registry stuff.
typedef hash_map<pair<const MessageLite*, int>, typedef hash_map<std::pair<const MessageLite*, int>,
ExtensionInfo> ExtensionRegistry; ExtensionInfo> ExtensionRegistry;
ExtensionRegistry* registry_ = NULL; ExtensionRegistry* registry_ = NULL;
GOOGLE_PROTOBUF_DECLARE_ONCE(registry_init_); GOOGLE_PROTOBUF_DECLARE_ONCE(registry_init_);
...@@ -221,7 +221,7 @@ int ExtensionSet::NumExtensions() const { ...@@ -221,7 +221,7 @@ int ExtensionSet::NumExtensions() const {
int ExtensionSet::ExtensionSize(int number) const { int ExtensionSet::ExtensionSize(int number) const {
ExtensionMap::const_iterator iter = extensions_.find(number); ExtensionMap::const_iterator iter = extensions_.find(number);
if (iter == extensions_.end()) return false; if (iter == extensions_.end()) return 0;
return iter->second.GetSize(); return iter->second.GetSize();
} }
...@@ -1371,7 +1371,7 @@ size_t ExtensionSet::ByteSize() const { ...@@ -1371,7 +1371,7 @@ size_t ExtensionSet::ByteSize() const {
bool ExtensionSet::MaybeNewExtension(int number, bool ExtensionSet::MaybeNewExtension(int number,
const FieldDescriptor* descriptor, const FieldDescriptor* descriptor,
Extension** result) { Extension** result) {
pair<ExtensionMap::iterator, bool> insert_result = std::pair<ExtensionMap::iterator, bool> insert_result =
extensions_.insert(std::make_pair(number, Extension())); extensions_.insert(std::make_pair(number, Extension()));
*result = &insert_result.first->second; *result = &insert_result.first->second;
(*result)->descriptor = descriptor; (*result)->descriptor = descriptor;
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#define GOOGLE_PROTOBUF_HAS_BITS_H__ #define GOOGLE_PROTOBUF_HAS_BITS_H__
#include <google/protobuf/stubs/common.h> #include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/port.h>
namespace google { namespace google {
namespace protobuf { namespace protobuf {
...@@ -40,17 +41,18 @@ namespace internal { ...@@ -40,17 +41,18 @@ namespace internal {
template<size_t doublewords> template<size_t doublewords>
class HasBits { class HasBits {
public: public:
HasBits() GOOGLE_ATTRIBUTE_ALWAYS_INLINE { Clear(); } HasBits() GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE { Clear(); }
void Clear() GOOGLE_ATTRIBUTE_ALWAYS_INLINE { void Clear() GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE {
memset(has_bits_, 0, sizeof(has_bits_)); memset(has_bits_, 0, sizeof(has_bits_));
} }
::google::protobuf::uint32& operator[](int index) GOOGLE_ATTRIBUTE_ALWAYS_INLINE { ::google::protobuf::uint32& operator[](int index) GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE {
return has_bits_[index]; return has_bits_[index];
} }
const ::google::protobuf::uint32& operator[](int index) const GOOGLE_ATTRIBUTE_ALWAYS_INLINE { const ::google::protobuf::uint32& operator[](int index) const
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE {
return has_bits_[index]; return has_bits_[index];
} }
...@@ -61,10 +63,41 @@ class HasBits { ...@@ -61,10 +63,41 @@ class HasBits {
bool operator!=(const HasBits<doublewords>& rhs) const { bool operator!=(const HasBits<doublewords>& rhs) const {
return !(*this == rhs); return !(*this == rhs);
} }
bool empty() const;
private: private:
::google::protobuf::uint32 has_bits_[doublewords]; ::google::protobuf::uint32 has_bits_[doublewords];
}; };
template <>
inline bool HasBits<1>::empty() const {
return !has_bits_[0];
}
template <>
inline bool HasBits<2>::empty() const {
return !(has_bits_[0] | has_bits_[1]);
}
template <>
inline bool HasBits<3>::empty() const {
return !(has_bits_[0] | has_bits_[1] | has_bits_[2]);
}
template <>
inline bool HasBits<4>::empty() const {
return !(has_bits_[0] | has_bits_[1] | has_bits_[2] | has_bits_[3]);
}
template <size_t doublewords>
inline bool HasBits<doublewords>::empty() const {
for (size_t i = 0; i < doublewords; ++i) {
if (has_bits_[i]) return false;
}
return true;
}
} // namespace internal } // namespace internal
} // namespace protobuf } // namespace protobuf
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment