Backed out changeset 98b22b52150e (bug 812238) for breaking the build

This commit is contained in:
Ehsan Akhgari 2012-11-30 14:35:53 -05:00
parent 1601c817c6
commit e092247eaa
32 changed files with 0 additions and 11728 deletions

View File

@ -36,7 +36,6 @@ PARALLEL_DIRS += \
perf \
places \
prompts \
protobuf \
reflect \
social \
startup \

View File

@ -30,7 +30,6 @@ LOCAL_INCLUDES = \
-I$(srcdir)/../feeds \
-I$(srcdir)/../find \
-I$(srcdir)/../intl \
-I$(srcdir)/../protobuf \
-I$(srcdir)/../startup \
-I$(srcdir)/../statusfilter \
-I$(srcdir)/../typeaheadfind \
@ -45,7 +44,6 @@ SHARED_LIBRARY_LIBS = \
../startup/$(LIB_PREFIX)appstartup_s.$(LIB_SUFFIX) \
../statusfilter/$(LIB_PREFIX)mozbrwsr_s.$(LIB_SUFFIX) \
../downloads/$(LIB_PREFIX)download_s.$(LIB_SUFFIX) \
../protobuf/$(LIB_PREFIX)protobuf_s.$(LIB_SUFFIX) \
../intl/$(LIB_PREFIX)intl_s.$(LIB_SUFFIX) \
$(NULL)

View File

@ -1,33 +0,0 @@
Copyright 2008, Google Inc.
All rights reserved.
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.
Code generated by the Protocol Buffer compiler is owned by the owner
of the input file used when generating it. This code is not
standalone and requires a support library to be linked with it. This
support library is itself covered by the above license.

View File

@ -1,61 +0,0 @@
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
VPATH = \
@srcdir@ \
@srcdir@/google/protobuf \
@srcdir@/google/protobuf/io \
@srcdir@/google/protobuf/stubs \
$(NULL)
MODULE = protobuf
LIBRARY_NAME = protobuf_s
FORCE_STATIC_LIB = 1
LOCAL_INCLUDES = \
-I$(srcdir) \
-I$(srcdir)/google/protobuf \
-I$(srcdir)/google/protobuf/io \
-I$(srcdir)/google/protobuf/stubs \
$(NULL)
CPPSRCS = \
coded_stream.cc \
common.cc \
extension_set.cc \
generated_message_util.cc \
message_lite.cc \
once.cc \
repeated_field.cc \
wire_format_lite.cc \
zero_copy_stream.cc \
zero_copy_stream_impl_lite.cc \
$(NULL)
# These exports should only be included by source code automatically generated by
# the protocol compiler, protoc
EXPORTS_NAMESPACES = protobuf
EXPORTS_protobuf = \
common.h \
generated_message_util.h \
extension_set.h \
repeated_field.h \
once.h \
coded_stream.h \
wire_format_lite_inl.h \
$(NULL)
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/config/rules.mk
CXXFLAGS += $(TK_CFLAGS)

View File

@ -1,11 +0,0 @@
This library has been updated to protobuf-2.4.1 as of 11/30/12.
Protocol Buffers (protobuf) source is available (via svn) at:
svn checkout http://protobuf.googlecode.com/svn/trunk/ protobuf-read-only
This code is covered under the BSD license (see COPYING.txt). Documentation is
available at http://code.google.com/p/protobuf.
This import includes only files in protobuf-lite, a lighter-weight library that
does not support reflection or descriptors. Manual changes include removing all
tests, testdata, config.h, and all files not used in protobuf-lite.

File diff suppressed because it is too large Load Diff

View File

@ -1,904 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// 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
// 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.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// This header is logically internal, but is made public because it is used
// from protocol-compiler-generated code, which may reside in other components.
#ifndef GOOGLE_PROTOBUF_EXTENSION_SET_H__
#define GOOGLE_PROTOBUF_EXTENSION_SET_H__
#include <vector>
#include <map>
#include <utility>
#include <string>
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
class Descriptor; // descriptor.h
class FieldDescriptor; // descriptor.h
class DescriptorPool; // descriptor.h
class MessageLite; // message_lite.h
class Message; // message.h
class MessageFactory; // message.h
class UnknownFieldSet; // unknown_field_set.h
namespace io {
class CodedInputStream; // coded_stream.h
class CodedOutputStream; // coded_stream.h
}
namespace internal {
class FieldSkipper; // wire_format_lite.h
class RepeatedPtrFieldBase; // repeated_field.h
}
template <typename Element> class RepeatedField; // repeated_field.h
template <typename Element> class RepeatedPtrField; // repeated_field.h
}
namespace protobuf {
namespace internal {
// Used to store values of type WireFormatLite::FieldType without having to
// #include wire_format_lite.h. Also, ensures that we use only one byte to
// store these values, which is important to keep the layout of
// ExtensionSet::Extension small.
typedef uint8 FieldType;
// A function which, given an integer value, returns true if the number
// matches one of the defined values for the corresponding enum type. This
// is used with RegisterEnumExtension, below.
typedef bool EnumValidityFunc(int number);
// Version of the above which takes an argument. This is needed to deal with
// extensions that are not compiled in.
typedef bool EnumValidityFuncWithArg(const void* arg, int number);
// Information about a registered extension.
struct ExtensionInfo {
inline ExtensionInfo() {}
inline ExtensionInfo(FieldType type, bool is_repeated, bool is_packed)
: type(type), is_repeated(is_repeated), is_packed(is_packed),
descriptor(NULL) {}
FieldType type;
bool is_repeated;
bool is_packed;
struct EnumValidityCheck {
EnumValidityFuncWithArg* func;
const void* arg;
};
union {
EnumValidityCheck enum_validity_check;
const MessageLite* message_prototype;
};
// The descriptor for this extension, if one exists and is known. May be
// NULL. Must not be NULL if the descriptor for the extension does not
// live in the same pool as the descriptor for the containing type.
const FieldDescriptor* descriptor;
};
// Abstract interface for an object which looks up extension definitions. Used
// when parsing.
class LIBPROTOBUF_EXPORT ExtensionFinder {
public:
virtual ~ExtensionFinder();
// Find the extension with the given containing type and number.
virtual bool Find(int number, ExtensionInfo* output) = 0;
};
// Implementation of ExtensionFinder which finds extensions defined in .proto
// files which have been compiled into the binary.
class LIBPROTOBUF_EXPORT GeneratedExtensionFinder : public ExtensionFinder {
public:
GeneratedExtensionFinder(const MessageLite* containing_type)
: containing_type_(containing_type) {}
virtual ~GeneratedExtensionFinder() {}
// Returns true and fills in *output if found, otherwise returns false.
virtual bool Find(int number, ExtensionInfo* output);
private:
const MessageLite* containing_type_;
};
// Note: extension_set_heavy.cc defines DescriptorPoolExtensionFinder for
// finding extensions from a DescriptorPool.
// This is an internal helper class intended for use within the protocol buffer
// library and generated classes. Clients should not use it directly. Instead,
// use the generated accessors such as GetExtension() of the class being
// extended.
//
// This class manages extensions for a protocol message object. The
// message's HasExtension(), GetExtension(), MutableExtension(), and
// ClearExtension() methods are just thin wrappers around the embedded
// ExtensionSet. When parsing, if a tag number is encountered which is
// inside one of the message type's extension ranges, the tag is passed
// off to the ExtensionSet for parsing. Etc.
class LIBPROTOBUF_EXPORT ExtensionSet {
public:
ExtensionSet();
~ExtensionSet();
// These are called at startup by protocol-compiler-generated code to
// register known extensions. The registrations are used by ParseField()
// to look up extensions for parsed field numbers. Note that dynamic parsing
// does not use ParseField(); only protocol-compiler-generated parsing
// methods do.
static void RegisterExtension(const MessageLite* containing_type,
int number, FieldType type,
bool is_repeated, bool is_packed);
static void RegisterEnumExtension(const MessageLite* containing_type,
int number, FieldType type,
bool is_repeated, bool is_packed,
EnumValidityFunc* is_valid);
static void RegisterMessageExtension(const MessageLite* containing_type,
int number, FieldType type,
bool is_repeated, bool is_packed,
const MessageLite* prototype);
// =================================================================
// Add all fields which are currently present to the given vector. This
// is useful to implement Reflection::ListFields().
void AppendToList(const Descriptor* containing_type,
const DescriptorPool* pool,
vector<const FieldDescriptor*>* output) const;
// =================================================================
// Accessors
//
// Generated message classes include type-safe templated wrappers around
// these methods. Generally you should use those rather than call these
// directly, unless you are doing low-level memory management.
//
// When calling any of these accessors, the extension number requested
// MUST exist in the DescriptorPool provided to the constructor. Otheriwse,
// the method will fail an assert. Normally, though, you would not call
// these directly; you would either call the generated accessors of your
// message class (e.g. GetExtension()) or you would call the accessors
// of the reflection interface. In both cases, it is impossible to
// trigger this assert failure: the generated accessors only accept
// linked-in extension types as parameters, while the Reflection interface
// requires you to provide the FieldDescriptor describing the extension.
//
// When calling any of these accessors, a protocol-compiler-generated
// implementation of the extension corresponding to the number MUST
// be linked in, and the FieldDescriptor used to refer to it MUST be
// the one generated by that linked-in code. Otherwise, the method will
// die on an assert failure. The message objects returned by the message
// accessors are guaranteed to be of the correct linked-in type.
//
// These methods pretty much match Reflection except that:
// - They're not virtual.
// - They identify fields by number rather than FieldDescriptors.
// - They identify enum values using integers rather than descriptors.
// - Strings provide Mutable() in addition to Set() accessors.
bool Has(int number) const;
int ExtensionSize(int number) const; // Size of a repeated extension.
FieldType ExtensionType(int number) const;
void ClearExtension(int number);
// singular fields -------------------------------------------------
int32 GetInt32 (int number, int32 default_value) const;
int64 GetInt64 (int number, int64 default_value) const;
uint32 GetUInt32(int number, uint32 default_value) const;
uint64 GetUInt64(int number, uint64 default_value) const;
float GetFloat (int number, float default_value) const;
double GetDouble(int number, double default_value) const;
bool GetBool (int number, bool default_value) const;
int GetEnum (int number, int default_value) const;
const string & GetString (int number, const string& default_value) const;
const MessageLite& GetMessage(int number,
const MessageLite& default_value) const;
const MessageLite& GetMessage(int number, const Descriptor* message_type,
MessageFactory* factory) const;
// |descriptor| may be NULL so long as it is known that the descriptor for
// the extension lives in the same pool as the descriptor for the containing
// type.
#define desc const FieldDescriptor* descriptor // avoid line wrapping
void SetInt32 (int number, FieldType type, int32 value, desc);
void SetInt64 (int number, FieldType type, int64 value, desc);
void SetUInt32(int number, FieldType type, uint32 value, desc);
void SetUInt64(int number, FieldType type, uint64 value, desc);
void SetFloat (int number, FieldType type, float value, desc);
void SetDouble(int number, FieldType type, double value, desc);
void SetBool (int number, FieldType type, bool value, desc);
void SetEnum (int number, FieldType type, int value, desc);
void SetString(int number, FieldType type, const string& value, desc);
string * MutableString (int number, FieldType type, desc);
MessageLite* MutableMessage(int number, FieldType type,
const MessageLite& prototype, desc);
MessageLite* MutableMessage(const FieldDescriptor* decsriptor,
MessageFactory* factory);
#undef desc
// repeated fields -------------------------------------------------
int32 GetRepeatedInt32 (int number, int index) const;
int64 GetRepeatedInt64 (int number, int index) const;
uint32 GetRepeatedUInt32(int number, int index) const;
uint64 GetRepeatedUInt64(int number, int index) const;
float GetRepeatedFloat (int number, int index) const;
double GetRepeatedDouble(int number, int index) const;
bool GetRepeatedBool (int number, int index) const;
int GetRepeatedEnum (int number, int index) const;
const string & GetRepeatedString (int number, int index) const;
const MessageLite& GetRepeatedMessage(int number, int index) const;
void SetRepeatedInt32 (int number, int index, int32 value);
void SetRepeatedInt64 (int number, int index, int64 value);
void SetRepeatedUInt32(int number, int index, uint32 value);
void SetRepeatedUInt64(int number, int index, uint64 value);
void SetRepeatedFloat (int number, int index, float value);
void SetRepeatedDouble(int number, int index, double value);
void SetRepeatedBool (int number, int index, bool value);
void SetRepeatedEnum (int number, int index, int value);
void SetRepeatedString(int number, int index, const string& value);
string * MutableRepeatedString (int number, int index);
MessageLite* MutableRepeatedMessage(int number, int index);
#define desc const FieldDescriptor* descriptor // avoid line wrapping
void AddInt32 (int number, FieldType type, bool packed, int32 value, desc);
void AddInt64 (int number, FieldType type, bool packed, int64 value, desc);
void AddUInt32(int number, FieldType type, bool packed, uint32 value, desc);
void AddUInt64(int number, FieldType type, bool packed, uint64 value, desc);
void AddFloat (int number, FieldType type, bool packed, float value, desc);
void AddDouble(int number, FieldType type, bool packed, double value, desc);
void AddBool (int number, FieldType type, bool packed, bool value, desc);
void AddEnum (int number, FieldType type, bool packed, int value, desc);
void AddString(int number, FieldType type, const string& value, desc);
string * AddString (int number, FieldType type, desc);
MessageLite* AddMessage(int number, FieldType type,
const MessageLite& prototype, desc);
MessageLite* AddMessage(const FieldDescriptor* descriptor,
MessageFactory* factory);
#undef desc
void RemoveLast(int number);
void SwapElements(int number, int index1, int index2);
// -----------------------------------------------------------------
// TODO(kenton): Hardcore memory management accessors
// =================================================================
// convenience methods for implementing methods of Message
//
// These could all be implemented in terms of the other methods of this
// class, but providing them here helps keep the generated code size down.
void Clear();
void MergeFrom(const ExtensionSet& other);
void Swap(ExtensionSet* other);
bool IsInitialized() const;
// Parses a single extension from the input. The input should start out
// positioned immediately after the tag. |containing_type| is the default
// instance for the containing message; it is used only to look up the
// extension by number. See RegisterExtension(), above. Unlike the other
// methods of ExtensionSet, this only works for generated message types --
// it looks up extensions registered using RegisterExtension().
bool ParseField(uint32 tag, io::CodedInputStream* input,
ExtensionFinder* extension_finder,
FieldSkipper* field_skipper);
// Specific versions for lite or full messages (constructs the appropriate
// FieldSkipper automatically).
bool ParseField(uint32 tag, io::CodedInputStream* input,
const MessageLite* containing_type);
bool ParseField(uint32 tag, io::CodedInputStream* input,
const Message* containing_type,
UnknownFieldSet* unknown_fields);
// Parse an entire message in MessageSet format. Such messages have no
// fields, only extensions.
bool ParseMessageSet(io::CodedInputStream* input,
ExtensionFinder* extension_finder,
FieldSkipper* field_skipper);
// Specific versions for lite or full messages (constructs the appropriate
// FieldSkipper automatically).
bool ParseMessageSet(io::CodedInputStream* input,
const MessageLite* containing_type);
bool ParseMessageSet(io::CodedInputStream* input,
const Message* containing_type,
UnknownFieldSet* unknown_fields);
// Write all extension fields with field numbers in the range
// [start_field_number, end_field_number)
// to the output stream, using the cached sizes computed when ByteSize() was
// last called. Note that the range bounds are inclusive-exclusive.
void SerializeWithCachedSizes(int start_field_number,
int end_field_number,
io::CodedOutputStream* output) const;
// Same as SerializeWithCachedSizes, but without any bounds checking.
// The caller must ensure that target has sufficient capacity for the
// serialized extensions.
//
// Returns a pointer past the last written byte.
uint8* SerializeWithCachedSizesToArray(int start_field_number,
int end_field_number,
uint8* target) const;
// Like above but serializes in MessageSet format.
void SerializeMessageSetWithCachedSizes(io::CodedOutputStream* output) const;
uint8* SerializeMessageSetWithCachedSizesToArray(uint8* target) const;
// Returns the total serialized size of all the extensions.
int ByteSize() const;
// Like ByteSize() but uses MessageSet format.
int MessageSetByteSize() const;
// Returns (an estimate of) the total number of bytes used for storing the
// extensions in memory, excluding sizeof(*this). If the ExtensionSet is
// for a lite message (and thus possibly contains lite messages), the results
// are undefined (might work, might crash, might corrupt data, might not even
// be linked in). It's up to the protocol compiler to avoid calling this on
// such ExtensionSets (easy enough since lite messages don't implement
// SpaceUsed()).
int SpaceUsedExcludingSelf() const;
private:
struct Extension {
union {
int32 int32_value;
int64 int64_value;
uint32 uint32_value;
uint64 uint64_value;
float float_value;
double double_value;
bool bool_value;
int enum_value;
string* string_value;
MessageLite* message_value;
RepeatedField <int32 >* repeated_int32_value;
RepeatedField <int64 >* repeated_int64_value;
RepeatedField <uint32 >* repeated_uint32_value;
RepeatedField <uint64 >* repeated_uint64_value;
RepeatedField <float >* repeated_float_value;
RepeatedField <double >* repeated_double_value;
RepeatedField <bool >* repeated_bool_value;
RepeatedField <int >* repeated_enum_value;
RepeatedPtrField<string >* repeated_string_value;
RepeatedPtrField<MessageLite>* repeated_message_value;
};
FieldType type;
bool is_repeated;
// For singular types, indicates if the extension is "cleared". This
// happens when an extension is set and then later cleared by the caller.
// We want to keep the Extension object around for reuse, so instead of
// removing it from the map, we just set is_cleared = true. This has no
// meaning for repeated types; for those, the size of the RepeatedField
// simply becomes zero when cleared.
bool is_cleared;
// For repeated types, this indicates if the [packed=true] option is set.
bool is_packed;
// The descriptor for this extension, if one exists and is known. May be
// NULL. Must not be NULL if the descriptor for the extension does not
// live in the same pool as the descriptor for the containing type.
const FieldDescriptor* descriptor;
// For packed fields, the size of the packed data is recorded here when
// ByteSize() is called then used during serialization.
// TODO(kenton): Use atomic<int> when C++ supports it.
mutable int cached_size;
// Some helper methods for operations on a single Extension.
void SerializeFieldWithCachedSizes(
int number,
io::CodedOutputStream* output) const;
uint8* SerializeFieldWithCachedSizesToArray(
int number,
uint8* target) const;
void SerializeMessageSetItemWithCachedSizes(
int number,
io::CodedOutputStream* output) const;
uint8* SerializeMessageSetItemWithCachedSizesToArray(
int number,
uint8* target) const;
int ByteSize(int number) const;
int MessageSetItemByteSize(int number) const;
void Clear();
int GetSize() const;
void Free();
int SpaceUsedExcludingSelf() const;
};
// Gets the extension with the given number, creating it if it does not
// already exist. Returns true if the extension did not already exist.
bool MaybeNewExtension(int number, const FieldDescriptor* descriptor,
Extension** result);
// Parse a single MessageSet item -- called just after the item group start
// tag has been read.
bool ParseMessageSetItem(io::CodedInputStream* input,
ExtensionFinder* extension_finder,
FieldSkipper* field_skipper);
// Hack: RepeatedPtrFieldBase declares ExtensionSet as a friend. This
// friendship should automatically extend to ExtensionSet::Extension, but
// unfortunately some older compilers (e.g. GCC 3.4.4) do not implement this
// correctly. So, we must provide helpers for calling methods of that
// class.
// Defined in extension_set_heavy.cc.
static inline int RepeatedMessage_SpaceUsedExcludingSelf(
RepeatedPtrFieldBase* field);
// The Extension struct is small enough to be passed by value, so we use it
// directly as the value type in the map rather than use pointers. We use
// a map rather than hash_map here because we expect most ExtensionSets will
// only contain a small number of extensions whereas hash_map is optimized
// for 100 elements or more. Also, we want AppendToList() to order fields
// by field number.
map<int, Extension> extensions_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionSet);
};
// These are just for convenience...
inline void ExtensionSet::SetString(int number, FieldType type,
const string& value,
const FieldDescriptor* descriptor) {
MutableString(number, type, descriptor)->assign(value);
}
inline void ExtensionSet::SetRepeatedString(int number, int index,
const string& value) {
MutableRepeatedString(number, index)->assign(value);
}
inline void ExtensionSet::AddString(int number, FieldType type,
const string& value,
const FieldDescriptor* descriptor) {
AddString(number, type, descriptor)->assign(value);
}
// ===================================================================
// Glue for generated extension accessors
// -------------------------------------------------------------------
// Template magic
// First we have a set of classes representing "type traits" for different
// field types. A type traits class knows how to implement basic accessors
// for extensions of a particular type given an ExtensionSet. The signature
// for a type traits class looks like this:
//
// class TypeTraits {
// public:
// typedef ? ConstType;
// typedef ? MutableType;
//
// static inline ConstType Get(int number, const ExtensionSet& set);
// static inline void Set(int number, ConstType value, ExtensionSet* set);
// static inline MutableType Mutable(int number, ExtensionSet* set);
//
// // Variants for repeated fields.
// static inline ConstType Get(int number, const ExtensionSet& set,
// int index);
// static inline void Set(int number, int index,
// ConstType value, ExtensionSet* set);
// static inline MutableType Mutable(int number, int index,
// ExtensionSet* set);
// static inline void Add(int number, ConstType value, ExtensionSet* set);
// static inline MutableType Add(int number, ExtensionSet* set);
// };
//
// Not all of these methods make sense for all field types. For example, the
// "Mutable" methods only make sense for strings and messages, and the
// repeated methods only make sense for repeated types. So, each type
// traits class implements only the set of methods from this signature that it
// actually supports. This will cause a compiler error if the user tries to
// access an extension using a method that doesn't make sense for its type.
// For example, if "foo" is an extension of type "optional int32", then if you
// try to write code like:
// my_message.MutableExtension(foo)
// you will get a compile error because PrimitiveTypeTraits<int32> does not
// have a "Mutable()" method.
// -------------------------------------------------------------------
// PrimitiveTypeTraits
// Since the ExtensionSet has different methods for each primitive type,
// we must explicitly define the methods of the type traits class for each
// known type.
template <typename Type>
class PrimitiveTypeTraits {
public:
typedef Type ConstType;
static inline ConstType Get(int number, const ExtensionSet& set,
ConstType default_value);
static inline void Set(int number, FieldType field_type,
ConstType value, ExtensionSet* set);
};
template <typename Type>
class RepeatedPrimitiveTypeTraits {
public:
typedef Type ConstType;
static inline Type Get(int number, const ExtensionSet& set, int index);
static inline void Set(int number, int index, Type value, ExtensionSet* set);
static inline void Add(int number, FieldType field_type,
bool is_packed, Type value, ExtensionSet* set);
};
#define PROTOBUF_DEFINE_PRIMITIVE_TYPE(TYPE, METHOD) \
template<> inline TYPE PrimitiveTypeTraits<TYPE>::Get( \
int number, const ExtensionSet& set, TYPE default_value) { \
return set.Get##METHOD(number, default_value); \
} \
template<> inline void PrimitiveTypeTraits<TYPE>::Set( \
int number, FieldType field_type, TYPE value, ExtensionSet* set) { \
set->Set##METHOD(number, field_type, value, NULL); \
} \
\
template<> inline TYPE RepeatedPrimitiveTypeTraits<TYPE>::Get( \
int number, const ExtensionSet& set, int index) { \
return set.GetRepeated##METHOD(number, index); \
} \
template<> inline void RepeatedPrimitiveTypeTraits<TYPE>::Set( \
int number, int index, TYPE value, ExtensionSet* set) { \
set->SetRepeated##METHOD(number, index, value); \
} \
template<> inline void RepeatedPrimitiveTypeTraits<TYPE>::Add( \
int number, FieldType field_type, bool is_packed, \
TYPE value, ExtensionSet* set) { \
set->Add##METHOD(number, field_type, is_packed, value, NULL); \
}
PROTOBUF_DEFINE_PRIMITIVE_TYPE( int32, Int32)
PROTOBUF_DEFINE_PRIMITIVE_TYPE( int64, Int64)
PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint32, UInt32)
PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint64, UInt64)
PROTOBUF_DEFINE_PRIMITIVE_TYPE( float, Float)
PROTOBUF_DEFINE_PRIMITIVE_TYPE(double, Double)
PROTOBUF_DEFINE_PRIMITIVE_TYPE( bool, Bool)
#undef PROTOBUF_DEFINE_PRIMITIVE_TYPE
// -------------------------------------------------------------------
// StringTypeTraits
// Strings support both Set() and Mutable().
class LIBPROTOBUF_EXPORT StringTypeTraits {
public:
typedef const string& ConstType;
typedef string* MutableType;
static inline const string& Get(int number, const ExtensionSet& set,
ConstType default_value) {
return set.GetString(number, default_value);
}
static inline void Set(int number, FieldType field_type,
const string& value, ExtensionSet* set) {
set->SetString(number, field_type, value, NULL);
}
static inline string* Mutable(int number, FieldType field_type,
ExtensionSet* set) {
return set->MutableString(number, field_type, NULL);
}
};
class LIBPROTOBUF_EXPORT RepeatedStringTypeTraits {
public:
typedef const string& ConstType;
typedef string* MutableType;
static inline const string& Get(int number, const ExtensionSet& set,
int index) {
return set.GetRepeatedString(number, index);
}
static inline void Set(int number, int index,
const string& value, ExtensionSet* set) {
set->SetRepeatedString(number, index, value);
}
static inline string* Mutable(int number, int index, ExtensionSet* set) {
return set->MutableRepeatedString(number, index);
}
static inline void Add(int number, FieldType field_type,
bool /*is_packed*/, const string& value,
ExtensionSet* set) {
set->AddString(number, field_type, value, NULL);
}
static inline string* Add(int number, FieldType field_type,
ExtensionSet* set) {
return set->AddString(number, field_type, NULL);
}
};
// -------------------------------------------------------------------
// EnumTypeTraits
// ExtensionSet represents enums using integers internally, so we have to
// static_cast around.
template <typename Type, bool IsValid(int)>
class EnumTypeTraits {
public:
typedef Type ConstType;
static inline ConstType Get(int number, const ExtensionSet& set,
ConstType default_value) {
return static_cast<Type>(set.GetEnum(number, default_value));
}
static inline void Set(int number, FieldType field_type,
ConstType value, ExtensionSet* set) {
GOOGLE_DCHECK(IsValid(value));
set->SetEnum(number, field_type, value, NULL);
}
};
template <typename Type, bool IsValid(int)>
class RepeatedEnumTypeTraits {
public:
typedef Type ConstType;
static inline ConstType Get(int number, const ExtensionSet& set, int index) {
return static_cast<Type>(set.GetRepeatedEnum(number, index));
}
static inline void Set(int number, int index,
ConstType value, ExtensionSet* set) {
GOOGLE_DCHECK(IsValid(value));
set->SetRepeatedEnum(number, index, value);
}
static inline void Add(int number, FieldType field_type,
bool is_packed, ConstType value, ExtensionSet* set) {
GOOGLE_DCHECK(IsValid(value));
set->AddEnum(number, field_type, is_packed, value, NULL);
}
};
// -------------------------------------------------------------------
// MessageTypeTraits
// ExtensionSet guarantees that when manipulating extensions with message
// types, the implementation used will be the compiled-in class representing
// that type. So, we can static_cast down to the exact type we expect.
template <typename Type>
class MessageTypeTraits {
public:
typedef const Type& ConstType;
typedef Type* MutableType;
static inline ConstType Get(int number, const ExtensionSet& set,
ConstType default_value) {
return static_cast<const Type&>(
set.GetMessage(number, default_value));
}
static inline MutableType Mutable(int number, FieldType field_type,
ExtensionSet* set) {
return static_cast<Type*>(
set->MutableMessage(number, field_type, Type::default_instance(), NULL));
}
};
template <typename Type>
class RepeatedMessageTypeTraits {
public:
typedef const Type& ConstType;
typedef Type* MutableType;
static inline ConstType Get(int number, const ExtensionSet& set, int index) {
return static_cast<const Type&>(set.GetRepeatedMessage(number, index));
}
static inline MutableType Mutable(int number, int index, ExtensionSet* set) {
return static_cast<Type*>(set->MutableRepeatedMessage(number, index));
}
static inline MutableType Add(int number, FieldType field_type,
ExtensionSet* set) {
return static_cast<Type*>(
set->AddMessage(number, field_type, Type::default_instance(), NULL));
}
};
// -------------------------------------------------------------------
// ExtensionIdentifier
// This is the type of actual extension objects. E.g. if you have:
// extends Foo with optional int32 bar = 1234;
// then "bar" will be defined in C++ as:
// ExtensionIdentifier<Foo, PrimitiveTypeTraits<int32>, 1, false> bar(1234);
//
// Note that we could, in theory, supply the field number as a template
// parameter, and thus make an instance of ExtensionIdentifier have no
// actual contents. However, if we did that, then using at extension
// identifier would not necessarily cause the compiler to output any sort
// of reference to any simple defined in the extension's .pb.o file. Some
// linkers will actually drop object files that are not explicitly referenced,
// but that would be bad because it would cause this extension to not be
// registered at static initialization, and therefore using it would crash.
template <typename ExtendeeType, typename TypeTraitsType,
FieldType field_type, bool is_packed>
class ExtensionIdentifier {
public:
typedef TypeTraitsType TypeTraits;
typedef ExtendeeType Extendee;
ExtensionIdentifier(int number, typename TypeTraits::ConstType default_value)
: number_(number), default_value_(default_value) {}
inline int number() const { return number_; }
typename TypeTraits::ConstType default_value() const {
return default_value_;
}
private:
const int number_;
typename TypeTraits::ConstType default_value_;
};
// -------------------------------------------------------------------
// Generated accessors
// This macro should be expanded in the context of a generated type which
// has extensions.
//
// We use "_proto_TypeTraits" as a type name below because "TypeTraits"
// causes problems if the class has a nested message or enum type with that
// name and "_TypeTraits" is technically reserved for the C++ library since
// it starts with an underscore followed by a capital letter.
#define GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(CLASSNAME) \
/* Has, Size, Clear */ \
template <typename _proto_TypeTraits, \
::google::protobuf::internal::FieldType field_type, \
bool is_packed> \
inline bool HasExtension( \
const ::google::protobuf::internal::ExtensionIdentifier< \
CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) const { \
return _extensions_.Has(id.number()); \
} \
\
template <typename _proto_TypeTraits, \
::google::protobuf::internal::FieldType field_type, \
bool is_packed> \
inline void ClearExtension( \
const ::google::protobuf::internal::ExtensionIdentifier< \
CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) { \
_extensions_.ClearExtension(id.number()); \
} \
\
template <typename _proto_TypeTraits, \
::google::protobuf::internal::FieldType field_type, \
bool is_packed> \
inline int ExtensionSize( \
const ::google::protobuf::internal::ExtensionIdentifier< \
CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) const { \
return _extensions_.ExtensionSize(id.number()); \
} \
\
/* Singular accessors */ \
template <typename _proto_TypeTraits, \
::google::protobuf::internal::FieldType field_type, \
bool is_packed> \
inline typename _proto_TypeTraits::ConstType GetExtension( \
const ::google::protobuf::internal::ExtensionIdentifier< \
CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) const { \
return _proto_TypeTraits::Get(id.number(), _extensions_, \
id.default_value()); \
} \
\
template <typename _proto_TypeTraits, \
::google::protobuf::internal::FieldType field_type, \
bool is_packed> \
inline typename _proto_TypeTraits::MutableType MutableExtension( \
const ::google::protobuf::internal::ExtensionIdentifier< \
CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) { \
return _proto_TypeTraits::Mutable(id.number(), field_type, &_extensions_);\
} \
\
template <typename _proto_TypeTraits, \
::google::protobuf::internal::FieldType field_type, \
bool is_packed> \
inline void SetExtension( \
const ::google::protobuf::internal::ExtensionIdentifier< \
CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id, \
typename _proto_TypeTraits::ConstType value) { \
_proto_TypeTraits::Set(id.number(), field_type, value, &_extensions_); \
} \
\
/* Repeated accessors */ \
template <typename _proto_TypeTraits, \
::google::protobuf::internal::FieldType field_type, \
bool is_packed> \
inline typename _proto_TypeTraits::ConstType GetExtension( \
const ::google::protobuf::internal::ExtensionIdentifier< \
CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id, \
int index) const { \
return _proto_TypeTraits::Get(id.number(), _extensions_, index); \
} \
\
template <typename _proto_TypeTraits, \
::google::protobuf::internal::FieldType field_type, \
bool is_packed> \
inline typename _proto_TypeTraits::MutableType MutableExtension( \
const ::google::protobuf::internal::ExtensionIdentifier< \
CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id, \
int index) { \
return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); \
} \
\
template <typename _proto_TypeTraits, \
::google::protobuf::internal::FieldType field_type, \
bool is_packed> \
inline void SetExtension( \
const ::google::protobuf::internal::ExtensionIdentifier< \
CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id, \
int index, typename _proto_TypeTraits::ConstType value) { \
_proto_TypeTraits::Set(id.number(), index, value, &_extensions_); \
} \
\
template <typename _proto_TypeTraits, \
::google::protobuf::internal::FieldType field_type, \
bool is_packed> \
inline typename _proto_TypeTraits::MutableType AddExtension( \
const ::google::protobuf::internal::ExtensionIdentifier< \
CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) { \
return _proto_TypeTraits::Add(id.number(), field_type, &_extensions_); \
} \
\
template <typename _proto_TypeTraits, \
::google::protobuf::internal::FieldType field_type, \
bool is_packed> \
inline void AddExtension( \
const ::google::protobuf::internal::ExtensionIdentifier< \
CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id, \
typename _proto_TypeTraits::ConstType value) { \
_proto_TypeTraits::Add(id.number(), field_type, is_packed, \
value, &_extensions_); \
}
} // namespace internal
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_EXTENSION_SET_H__

View File

@ -1,55 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// 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
// 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.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/generated_message_util.h>
#include <limits>
namespace google {
namespace protobuf {
namespace internal {
double Infinity() {
return std::numeric_limits<double>::infinity();
}
double NaN() {
return std::numeric_limits<double>::quiet_NaN();
}
const ::std::string kEmptyString;
} // namespace internal
} // namespace protobuf
} // namespace google

View File

@ -1,82 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// 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
// 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.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// This file contains miscellaneous helper code used by generated code --
// including lite types -- but which should not be used directly by users.
#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
#include <string>
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
namespace io {
class CodedInputStream; // coded_stream.h
}
}
namespace protobuf {
namespace internal {
// Annotation for the compiler to emit a deprecation message if a field marked
// with option 'deprecated=true' is used in the code, or for other things in
// generated code which are deprecated.
//
// For internal use in the pb.cc files, deprecation warnings are suppressed
// there.
#undef DEPRECATED_PROTOBUF_FIELD
#if !defined(INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION)
# define PROTOBUF_DEPRECATED GOOGLE_ATTRIBUTE_DEPRECATED
#else
# define PROTOBUF_DEPRECATED
#endif
// Constants for special floating point values.
double Infinity();
double NaN();
// Constant used for empty default strings.
extern const ::std::string kEmptyString;
} // namespace internal
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__

View File

@ -1,839 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// 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
// 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.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// This implementation is heavily optimized to make reads and writes
// of small values (especially varints) as fast as possible. In
// particular, we optimize for the common case that a read or a write
// will not cross the end of the buffer, since we can avoid a lot
// of branching in this case.
#include <google/protobuf/io/coded_stream_inl.h>
#include <algorithm>
#include <limits.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/stl_util-inl.h>
namespace google {
namespace protobuf {
namespace io {
namespace {
static const int kMaxVarintBytes = 10;
static const int kMaxVarint32Bytes = 5;
inline bool NextNonEmpty(ZeroCopyInputStream* input,
const void** data, int* size) {
bool success;
do {
success = input->Next(data, size);
} while (success && *size == 0);
return success;
}
} // namespace
// CodedInputStream ==================================================
void CodedInputStream::BackUpInputToCurrentPosition() {
int backup_bytes = BufferSize() + buffer_size_after_limit_ + overflow_bytes_;
if (backup_bytes > 0) {
input_->BackUp(backup_bytes);
// total_bytes_read_ doesn't include overflow_bytes_.
total_bytes_read_ -= BufferSize() + buffer_size_after_limit_;
buffer_end_ = buffer_;
buffer_size_after_limit_ = 0;
overflow_bytes_ = 0;
}
}
inline void CodedInputStream::RecomputeBufferLimits() {
buffer_end_ += buffer_size_after_limit_;
int closest_limit = min(current_limit_, total_bytes_limit_);
if (closest_limit < total_bytes_read_) {
// The limit position is in the current buffer. We must adjust
// the buffer size accordingly.
buffer_size_after_limit_ = total_bytes_read_ - closest_limit;
buffer_end_ -= buffer_size_after_limit_;
} else {
buffer_size_after_limit_ = 0;
}
}
CodedInputStream::Limit CodedInputStream::PushLimit(int byte_limit) {
// Current position relative to the beginning of the stream.
int current_position = total_bytes_read_ -
(BufferSize() + buffer_size_after_limit_);
Limit old_limit = current_limit_;
// security: byte_limit is possibly evil, so check for negative values
// and overflow.
if (byte_limit >= 0 &&
byte_limit <= INT_MAX - current_position) {
current_limit_ = current_position + byte_limit;
} else {
// Negative or overflow.
current_limit_ = INT_MAX;
}
// We need to enforce all limits, not just the new one, so if the previous
// limit was before the new requested limit, we continue to enforce the
// previous limit.
current_limit_ = min(current_limit_, old_limit);
RecomputeBufferLimits();
return old_limit;
}
void CodedInputStream::PopLimit(Limit limit) {
// The limit passed in is actually the *old* limit, which we returned from
// PushLimit().
current_limit_ = limit;
RecomputeBufferLimits();
// We may no longer be at a legitimate message end. ReadTag() needs to be
// called again to find out.
legitimate_message_end_ = false;
}
int CodedInputStream::BytesUntilLimit() {
if (current_limit_ == INT_MAX) return -1;
int current_position = total_bytes_read_ -
(BufferSize() + buffer_size_after_limit_);
return current_limit_ - current_position;
}
void CodedInputStream::SetTotalBytesLimit(
int total_bytes_limit, int warning_threshold) {
// Make sure the limit isn't already past, since this could confuse other
// code.
int current_position = total_bytes_read_ -
(BufferSize() + buffer_size_after_limit_);
total_bytes_limit_ = max(current_position, total_bytes_limit);
total_bytes_warning_threshold_ = warning_threshold;
RecomputeBufferLimits();
}
void CodedInputStream::PrintTotalBytesLimitError() {
GOOGLE_LOG(ERROR) << "A protocol message was rejected because it was too "
"big (more than " << total_bytes_limit_
<< " bytes). To increase the limit (or to disable these "
"warnings), see CodedInputStream::SetTotalBytesLimit() "
"in google/protobuf/io/coded_stream.h.";
}
bool CodedInputStream::Skip(int count) {
if (count < 0) return false; // security: count is often user-supplied
const int original_buffer_size = BufferSize();
if (count <= original_buffer_size) {
// Just skipping within the current buffer. Easy.
Advance(count);
return true;
}
if (buffer_size_after_limit_ > 0) {
// We hit a limit inside this buffer. Advance to the limit and fail.
Advance(original_buffer_size);
return false;
}
count -= original_buffer_size;
buffer_ = NULL;
buffer_end_ = buffer_;
// Make sure this skip doesn't try to skip past the current limit.
int closest_limit = min(current_limit_, total_bytes_limit_);
int bytes_until_limit = closest_limit - total_bytes_read_;
if (bytes_until_limit < count) {
// We hit the limit. Skip up to it then fail.
if (bytes_until_limit > 0) {
total_bytes_read_ = closest_limit;
input_->Skip(bytes_until_limit);
}
return false;
}
total_bytes_read_ += count;
return input_->Skip(count);
}
bool CodedInputStream::GetDirectBufferPointer(const void** data, int* size) {
if (BufferSize() == 0 && !Refresh()) return false;
*data = buffer_;
*size = BufferSize();
return true;
}
bool CodedInputStream::ReadRaw(void* buffer, int size) {
int current_buffer_size;
while ((current_buffer_size = BufferSize()) < size) {
// Reading past end of buffer. Copy what we have, then refresh.
memcpy(buffer, buffer_, current_buffer_size);
buffer = reinterpret_cast<uint8*>(buffer) + current_buffer_size;
size -= current_buffer_size;
Advance(current_buffer_size);
if (!Refresh()) return false;
}
memcpy(buffer, buffer_, size);
Advance(size);
return true;
}
bool CodedInputStream::ReadString(string* buffer, int size) {
if (size < 0) return false; // security: size is often user-supplied
return InternalReadStringInline(buffer, size);
}
bool CodedInputStream::ReadStringFallback(string* buffer, int size) {
if (!buffer->empty()) {
buffer->clear();
}
int current_buffer_size;
while ((current_buffer_size = BufferSize()) < size) {
// Some STL implementations "helpfully" crash on buffer->append(NULL, 0).
if (current_buffer_size != 0) {
// Note: string1.append(string2) is O(string2.size()) (as opposed to
// O(string1.size() + string2.size()), which would be bad).
buffer->append(reinterpret_cast<const char*>(buffer_),
current_buffer_size);
}
size -= current_buffer_size;
Advance(current_buffer_size);
if (!Refresh()) return false;
}
buffer->append(reinterpret_cast<const char*>(buffer_), size);
Advance(size);
return true;
}
bool CodedInputStream::ReadLittleEndian32Fallback(uint32* value) {
uint8 bytes[sizeof(*value)];
const uint8* ptr;
if (BufferSize() >= sizeof(*value)) {
// Fast path: Enough bytes in the buffer to read directly.
ptr = buffer_;
Advance(sizeof(*value));
} else {
// Slow path: Had to read past the end of the buffer.
if (!ReadRaw(bytes, sizeof(*value))) return false;
ptr = bytes;
}
ReadLittleEndian32FromArray(ptr, value);
return true;
}
bool CodedInputStream::ReadLittleEndian64Fallback(uint64* value) {
uint8 bytes[sizeof(*value)];
const uint8* ptr;
if (BufferSize() >= sizeof(*value)) {
// Fast path: Enough bytes in the buffer to read directly.
ptr = buffer_;
Advance(sizeof(*value));
} else {
// Slow path: Had to read past the end of the buffer.
if (!ReadRaw(bytes, sizeof(*value))) return false;
ptr = bytes;
}
ReadLittleEndian64FromArray(ptr, value);
return true;
}
namespace {
inline const uint8* ReadVarint32FromArray(
const uint8* buffer, uint32* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
inline const uint8* ReadVarint32FromArray(const uint8* buffer, uint32* value) {
// Fast path: We have enough bytes left in the buffer to guarantee that
// this read won't cross the end, so we can skip the checks.
const uint8* ptr = buffer;
uint32 b;
uint32 result;
b = *(ptr++); result = (b & 0x7F) ; if (!(b & 0x80)) goto done;
b = *(ptr++); result |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done;
b = *(ptr++); result |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done;
b = *(ptr++); result |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done;
b = *(ptr++); result |= b << 28; if (!(b & 0x80)) goto done;
// If the input is larger than 32 bits, we still need to read it all
// and discard the high-order bits.
for (int i = 0; i < kMaxVarintBytes - kMaxVarint32Bytes; i++) {
b = *(ptr++); if (!(b & 0x80)) goto done;
}
// We have overrun the maximum size of a varint (10 bytes). Assume
// the data is corrupt.
return NULL;
done:
*value = result;
return ptr;
}
} // namespace
bool CodedInputStream::ReadVarint32Slow(uint32* value) {
uint64 result;
// Directly invoke ReadVarint64Fallback, since we already tried to optimize
// for one-byte varints.
if (!ReadVarint64Fallback(&result)) return false;
*value = (uint32)result;
return true;
}
bool CodedInputStream::ReadVarint32Fallback(uint32* value) {
if (BufferSize() >= kMaxVarintBytes ||
// Optimization: If the varint ends at exactly the end of the buffer,
// we can detect that and still use the fast path.
(buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) {
const uint8* end = ReadVarint32FromArray(buffer_, value);
if (end == NULL) return false;
buffer_ = end;
return true;
} else {
// Really slow case: we will incur the cost of an extra function call here,
// but moving this out of line reduces the size of this function, which
// improves the common case. In micro benchmarks, this is worth about 10-15%
return ReadVarint32Slow(value);
}
}
uint32 CodedInputStream::ReadTagSlow() {
if (buffer_ == buffer_end_) {
// Call refresh.
if (!Refresh()) {
// Refresh failed. Make sure that it failed due to EOF, not because
// we hit total_bytes_limit_, which, unlike normal limits, is not a
// valid place to end a message.
int current_position = total_bytes_read_ - buffer_size_after_limit_;
if (current_position >= total_bytes_limit_) {
// Hit total_bytes_limit_. But if we also hit the normal limit,
// we're still OK.
legitimate_message_end_ = current_limit_ == total_bytes_limit_;
} else {
legitimate_message_end_ = true;
}
return 0;
}
}
// For the slow path, just do a 64-bit read. Try to optimize for one-byte tags
// again, since we have now refreshed the buffer.
uint64 result;
if (!ReadVarint64(&result)) return 0;
return static_cast<uint32>(result);
}
uint32 CodedInputStream::ReadTagFallback() {
if (BufferSize() >= kMaxVarintBytes ||
// Optimization: If the varint ends at exactly the end of the buffer,
// we can detect that and still use the fast path.
(buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) {
uint32 tag;
const uint8* end = ReadVarint32FromArray(buffer_, &tag);
if (end == NULL) {
return 0;
}
buffer_ = end;
return tag;
} else {
// We are commonly at a limit when attempting to read tags. Try to quickly
// detect this case without making another function call.
if (buffer_ == buffer_end_ && buffer_size_after_limit_ > 0 &&
// Make sure that the limit we hit is not total_bytes_limit_, since
// in that case we still need to call Refresh() so that it prints an
// error.
total_bytes_read_ - buffer_size_after_limit_ < total_bytes_limit_) {
// We hit a byte limit.
legitimate_message_end_ = true;
return 0;
}
return ReadTagSlow();
}
}
bool CodedInputStream::ReadVarint64Slow(uint64* value) {
// Slow path: This read might cross the end of the buffer, so we
// need to check and refresh the buffer if and when it does.
uint64 result = 0;
int count = 0;
uint32 b;
do {
if (count == kMaxVarintBytes) return false;
while (buffer_ == buffer_end_) {
if (!Refresh()) return false;
}
b = *buffer_;
result |= static_cast<uint64>(b & 0x7F) << (7 * count);
Advance(1);
++count;
} while (b & 0x80);
*value = result;
return true;
}
bool CodedInputStream::ReadVarint64Fallback(uint64* value) {
if (BufferSize() >= kMaxVarintBytes ||
// Optimization: If the varint ends at exactly the end of the buffer,
// we can detect that and still use the fast path.
(buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) {
// Fast path: We have enough bytes left in the buffer to guarantee that
// this read won't cross the end, so we can skip the checks.
const uint8* ptr = buffer_;
uint32 b;
// Splitting into 32-bit pieces gives better performance on 32-bit
// processors.
uint32 part0 = 0, part1 = 0, part2 = 0;
b = *(ptr++); part0 = (b & 0x7F) ; if (!(b & 0x80)) goto done;
b = *(ptr++); part0 |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done;
b = *(ptr++); part0 |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done;
b = *(ptr++); part0 |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done;
b = *(ptr++); part1 = (b & 0x7F) ; if (!(b & 0x80)) goto done;
b = *(ptr++); part1 |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done;
b = *(ptr++); part1 |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done;
b = *(ptr++); part1 |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done;
b = *(ptr++); part2 = (b & 0x7F) ; if (!(b & 0x80)) goto done;
b = *(ptr++); part2 |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done;
// We have overrun the maximum size of a varint (10 bytes). The data
// must be corrupt.
return NULL;
done:
Advance(ptr - buffer_);
*value = (static_cast<uint64>(part0) ) |
(static_cast<uint64>(part1) << 28) |
(static_cast<uint64>(part2) << 56);
return true;
} else {
return ReadVarint64Slow(value);
}
}
bool CodedInputStream::Refresh() {
GOOGLE_DCHECK_EQ(0, BufferSize());
if (buffer_size_after_limit_ > 0 || overflow_bytes_ > 0 ||
total_bytes_read_ == current_limit_) {
// We've hit a limit. Stop.
int current_position = total_bytes_read_ - buffer_size_after_limit_;
if (current_position >= total_bytes_limit_ &&
total_bytes_limit_ != current_limit_) {
// Hit total_bytes_limit_.
PrintTotalBytesLimitError();
}
return false;
}
if (total_bytes_warning_threshold_ >= 0 &&
total_bytes_read_ >= total_bytes_warning_threshold_) {
GOOGLE_LOG(WARNING) << "Reading dangerously large protocol message. If the "
"message turns out to be larger than "
<< total_bytes_limit_ << " bytes, parsing will be halted "
"for security reasons. To increase the limit (or to "
"disable these warnings), see "
"CodedInputStream::SetTotalBytesLimit() in "
"google/protobuf/io/coded_stream.h.";
// Don't warn again for this stream.
total_bytes_warning_threshold_ = -1;
}
const void* void_buffer;
int buffer_size;
if (NextNonEmpty(input_, &void_buffer, &buffer_size)) {
buffer_ = reinterpret_cast<const uint8*>(void_buffer);
buffer_end_ = buffer_ + buffer_size;
GOOGLE_CHECK_GE(buffer_size, 0);
if (total_bytes_read_ <= INT_MAX - buffer_size) {
total_bytes_read_ += buffer_size;
} else {
// Overflow. Reset buffer_end_ to not include the bytes beyond INT_MAX.
// We can't get that far anyway, because total_bytes_limit_ is guaranteed
// to be less than it. We need to keep track of the number of bytes
// we discarded, though, so that we can call input_->BackUp() to back
// up over them on destruction.
// The following line is equivalent to:
// overflow_bytes_ = total_bytes_read_ + buffer_size - INT_MAX;
// except that it avoids overflows. Signed integer overflow has
// undefined results according to the C standard.
overflow_bytes_ = total_bytes_read_ - (INT_MAX - buffer_size);
buffer_end_ -= overflow_bytes_;
total_bytes_read_ = INT_MAX;
}
RecomputeBufferLimits();
return true;
} else {
buffer_ = NULL;
buffer_end_ = NULL;
return false;
}
}
// CodedOutputStream =================================================
CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output)
: output_(output),
buffer_(NULL),
buffer_size_(0),
total_bytes_(0),
had_error_(false) {
// Eagerly Refresh() so buffer space is immediately available.
Refresh();
// The Refresh() may have failed. If the client doesn't write any data,
// though, don't consider this an error. If the client does write data, then
// another Refresh() will be attempted and it will set the error once again.
had_error_ = false;
}
CodedOutputStream::~CodedOutputStream() {
if (buffer_size_ > 0) {
output_->BackUp(buffer_size_);
}
}
bool CodedOutputStream::Skip(int count) {
if (count < 0) return false;
while (count > buffer_size_) {
count -= buffer_size_;
if (!Refresh()) return false;
}
Advance(count);
return true;
}
bool CodedOutputStream::GetDirectBufferPointer(void** data, int* size) {
if (buffer_size_ == 0 && !Refresh()) return false;
*data = buffer_;
*size = buffer_size_;
return true;
}
void CodedOutputStream::WriteRaw(const void* data, int size) {
while (buffer_size_ < size) {
memcpy(buffer_, data, buffer_size_);
size -= buffer_size_;
data = reinterpret_cast<const uint8*>(data) + buffer_size_;
if (!Refresh()) return;
}
memcpy(buffer_, data, size);
Advance(size);
}
uint8* CodedOutputStream::WriteRawToArray(
const void* data, int size, uint8* target) {
memcpy(target, data, size);
return target + size;
}
void CodedOutputStream::WriteLittleEndian32(uint32 value) {
uint8 bytes[sizeof(value)];
bool use_fast = buffer_size_ >= sizeof(value);
uint8* ptr = use_fast ? buffer_ : bytes;
WriteLittleEndian32ToArray(value, ptr);
if (use_fast) {
Advance(sizeof(value));
} else {
WriteRaw(bytes, sizeof(value));
}
}
void CodedOutputStream::WriteLittleEndian64(uint64 value) {
uint8 bytes[sizeof(value)];
bool use_fast = buffer_size_ >= sizeof(value);
uint8* ptr = use_fast ? buffer_ : bytes;
WriteLittleEndian64ToArray(value, ptr);
if (use_fast) {
Advance(sizeof(value));
} else {
WriteRaw(bytes, sizeof(value));
}
}
inline uint8* CodedOutputStream::WriteVarint32FallbackToArrayInline(
uint32 value, uint8* target) {
target[0] = static_cast<uint8>(value | 0x80);
if (value >= (1 << 7)) {
target[1] = static_cast<uint8>((value >> 7) | 0x80);
if (value >= (1 << 14)) {
target[2] = static_cast<uint8>((value >> 14) | 0x80);
if (value >= (1 << 21)) {
target[3] = static_cast<uint8>((value >> 21) | 0x80);
if (value >= (1 << 28)) {
target[4] = static_cast<uint8>(value >> 28);
return target + 5;
} else {
target[3] &= 0x7F;
return target + 4;
}
} else {
target[2] &= 0x7F;
return target + 3;
}
} else {
target[1] &= 0x7F;
return target + 2;
}
} else {
target[0] &= 0x7F;
return target + 1;
}
}
void CodedOutputStream::WriteVarint32(uint32 value) {
if (buffer_size_ >= kMaxVarint32Bytes) {
// Fast path: We have enough bytes left in the buffer to guarantee that
// this write won't cross the end, so we can skip the checks.
uint8* target = buffer_;
uint8* end = WriteVarint32FallbackToArrayInline(value, target);
int size = end - target;
Advance(size);
} else {
// Slow path: This write might cross the end of the buffer, so we
// compose the bytes first then use WriteRaw().
uint8 bytes[kMaxVarint32Bytes];
int size = 0;
while (value > 0x7F) {
bytes[size++] = (static_cast<uint8>(value) & 0x7F) | 0x80;
value >>= 7;
}
bytes[size++] = static_cast<uint8>(value) & 0x7F;
WriteRaw(bytes, size);
}
}
uint8* CodedOutputStream::WriteVarint32FallbackToArray(
uint32 value, uint8* target) {
return WriteVarint32FallbackToArrayInline(value, target);
}
inline uint8* CodedOutputStream::WriteVarint64ToArrayInline(
uint64 value, uint8* target) {
// Splitting into 32-bit pieces gives better performance on 32-bit
// processors.
uint32 part0 = static_cast<uint32>(value );
uint32 part1 = static_cast<uint32>(value >> 28);
uint32 part2 = static_cast<uint32>(value >> 56);
int size;
// Here we can't really optimize for small numbers, since the value is
// split into three parts. Cheking for numbers < 128, for instance,
// would require three comparisons, since you'd have to make sure part1
// and part2 are zero. However, if the caller is using 64-bit integers,
// it is likely that they expect the numbers to often be very large, so
// we probably don't want to optimize for small numbers anyway. Thus,
// we end up with a hardcoded binary search tree...
if (part2 == 0) {
if (part1 == 0) {
if (part0 < (1 << 14)) {
if (part0 < (1 << 7)) {
size = 1; goto size1;
} else {
size = 2; goto size2;
}
} else {
if (part0 < (1 << 21)) {
size = 3; goto size3;
} else {
size = 4; goto size4;
}
}
} else {
if (part1 < (1 << 14)) {
if (part1 < (1 << 7)) {
size = 5; goto size5;
} else {
size = 6; goto size6;
}
} else {
if (part1 < (1 << 21)) {
size = 7; goto size7;
} else {
size = 8; goto size8;
}
}
}
} else {
if (part2 < (1 << 7)) {
size = 9; goto size9;
} else {
size = 10; goto size10;
}
}
GOOGLE_LOG(FATAL) << "Can't get here.";
size10: target[9] = static_cast<uint8>((part2 >> 7) | 0x80);
size9 : target[8] = static_cast<uint8>((part2 ) | 0x80);
size8 : target[7] = static_cast<uint8>((part1 >> 21) | 0x80);
size7 : target[6] = static_cast<uint8>((part1 >> 14) | 0x80);
size6 : target[5] = static_cast<uint8>((part1 >> 7) | 0x80);
size5 : target[4] = static_cast<uint8>((part1 ) | 0x80);
size4 : target[3] = static_cast<uint8>((part0 >> 21) | 0x80);
size3 : target[2] = static_cast<uint8>((part0 >> 14) | 0x80);
size2 : target[1] = static_cast<uint8>((part0 >> 7) | 0x80);
size1 : target[0] = static_cast<uint8>((part0 ) | 0x80);
target[size-1] &= 0x7F;
return target + size;
}
void CodedOutputStream::WriteVarint64(uint64 value) {
if (buffer_size_ >= kMaxVarintBytes) {
// Fast path: We have enough bytes left in the buffer to guarantee that
// this write won't cross the end, so we can skip the checks.
uint8* target = buffer_;
uint8* end = WriteVarint64ToArrayInline(value, target);
int size = end - target;
Advance(size);
} else {
// Slow path: This write might cross the end of the buffer, so we
// compose the bytes first then use WriteRaw().
uint8 bytes[kMaxVarintBytes];
int size = 0;
while (value > 0x7F) {
bytes[size++] = (static_cast<uint8>(value) & 0x7F) | 0x80;
value >>= 7;
}
bytes[size++] = static_cast<uint8>(value) & 0x7F;
WriteRaw(bytes, size);
}
}
uint8* CodedOutputStream::WriteVarint64ToArray(
uint64 value, uint8* target) {
return WriteVarint64ToArrayInline(value, target);
}
bool CodedOutputStream::Refresh() {
void* void_buffer;
if (output_->Next(&void_buffer, &buffer_size_)) {
buffer_ = reinterpret_cast<uint8*>(void_buffer);
total_bytes_ += buffer_size_;
return true;
} else {
buffer_ = NULL;
buffer_size_ = 0;
had_error_ = true;
return false;
}
}
int CodedOutputStream::VarintSize32Fallback(uint32 value) {
if (value < (1 << 7)) {
return 1;
} else if (value < (1 << 14)) {
return 2;
} else if (value < (1 << 21)) {
return 3;
} else if (value < (1 << 28)) {
return 4;
} else {
return 5;
}
}
int CodedOutputStream::VarintSize64(uint64 value) {
if (value < (1ull << 35)) {
if (value < (1ull << 7)) {
return 1;
} else if (value < (1ull << 14)) {
return 2;
} else if (value < (1ull << 21)) {
return 3;
} else if (value < (1ull << 28)) {
return 4;
} else {
return 5;
}
} else {
if (value < (1ull << 42)) {
return 6;
} else if (value < (1ull << 49)) {
return 7;
} else if (value < (1ull << 56)) {
return 8;
} else if (value < (1ull << 63)) {
return 9;
} else {
return 10;
}
}
}
} // namespace io
} // namespace protobuf
} // namespace google

File diff suppressed because it is too large Load Diff

View File

@ -1,64 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// 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
// 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.
// Author: jasonh@google.com (Jason Hsueh)
//
// Implements methods of coded_stream.h that need to be inlined for performance
// reasons, but should not be defined in a public header.
#ifndef GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__
#define GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__
#include <google/protobuf/io/coded_stream.h>
#include <string>
#include <google/protobuf/stubs/stl_util-inl.h>
namespace google {
namespace protobuf {
namespace io {
inline bool CodedInputStream::InternalReadStringInline(string* buffer,
int size) {
if (size < 0) return false; // security: size is often user-supplied
if (BufferSize() >= size) {
STLStringResizeUninitialized(buffer, size);
memcpy(string_as_array(buffer), buffer_, size);
Advance(size);
return true;
}
return ReadStringFallback(buffer, size);
}
} // namespace io
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__

View File

@ -1,54 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// 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
// 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.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// This file exists solely to document the google::protobuf::io namespace.
// It is not compiled into anything, but it may be read by an automated
// documentation generator.
namespace google {
namespace protobuf {
// Auxiliary classes used for I/O.
//
// The Protocol Buffer library uses the classes in this package to deal with
// I/O and encoding/decoding raw bytes. Most users will not need to
// deal with this package. However, users who want to adapt the system to
// work with their own I/O abstractions -- e.g., to allow Protocol Buffers
// to be read from a different kind of input stream without the need for a
// temporary buffer -- should take a closer look.
namespace io {}
} // namespace protobuf
} // namespace google

View File

@ -1,48 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// 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
// 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.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/io/zero_copy_stream.h>
namespace google {
namespace protobuf {
namespace io {
ZeroCopyInputStream::~ZeroCopyInputStream() {}
ZeroCopyOutputStream::~ZeroCopyOutputStream() {}
} // namespace io
} // namespace protobuf
} // namespace google

View File

@ -1,238 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// 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
// 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.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// This file contains the ZeroCopyInputStream and ZeroCopyOutputStream
// interfaces, which represent abstract I/O streams to and from which
// protocol buffers can be read and written. For a few simple
// implementations of these interfaces, see zero_copy_stream_impl.h.
//
// These interfaces are different from classic I/O streams in that they
// try to minimize the amount of data copying that needs to be done.
// To accomplish this, responsibility for allocating buffers is moved to
// the stream object, rather than being the responsibility of the caller.
// So, the stream can return a buffer which actually points directly into
// the final data structure where the bytes are to be stored, and the caller
// can interact directly with that buffer, eliminating an intermediate copy
// operation.
//
// As an example, consider the common case in which you are reading bytes
// from an array that is already in memory (or perhaps an mmap()ed file).
// With classic I/O streams, you would do something like:
// char buffer[BUFFER_SIZE];
// input->Read(buffer, BUFFER_SIZE);
// DoSomething(buffer, BUFFER_SIZE);
// Then, the stream basically just calls memcpy() to copy the data from
// the array into your buffer. With a ZeroCopyInputStream, you would do
// this instead:
// const void* buffer;
// int size;
// input->Next(&buffer, &size);
// DoSomething(buffer, size);
// Here, no copy is performed. The input stream returns a pointer directly
// into the backing array, and the caller ends up reading directly from it.
//
// If you want to be able to read the old-fashion way, you can create
// a CodedInputStream or CodedOutputStream wrapping these objects and use
// their ReadRaw()/WriteRaw() methods. These will, of course, add a copy
// step, but Coded*Stream will handle buffering so at least it will be
// reasonably efficient.
//
// ZeroCopyInputStream example:
// // Read in a file and print its contents to stdout.
// int fd = open("myfile", O_RDONLY);
// ZeroCopyInputStream* input = new FileInputStream(fd);
//
// const void* buffer;
// int size;
// while (input->Next(&buffer, &size)) {
// cout.write(buffer, size);
// }
//
// delete input;
// close(fd);
//
// ZeroCopyOutputStream example:
// // Copy the contents of "infile" to "outfile", using plain read() for
// // "infile" but a ZeroCopyOutputStream for "outfile".
// int infd = open("infile", O_RDONLY);
// int outfd = open("outfile", O_WRONLY);
// ZeroCopyOutputStream* output = new FileOutputStream(outfd);
//
// void* buffer;
// int size;
// while (output->Next(&buffer, &size)) {
// int bytes = read(infd, buffer, size);
// if (bytes < size) {
// // Reached EOF.
// output->BackUp(size - bytes);
// break;
// }
// }
//
// delete output;
// close(infd);
// close(outfd);
#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__
#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__
#include <string>
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
namespace io {
// Defined in this file.
class ZeroCopyInputStream;
class ZeroCopyOutputStream;
// Abstract interface similar to an input stream but designed to minimize
// copying.
class LIBPROTOBUF_EXPORT ZeroCopyInputStream {
public:
inline ZeroCopyInputStream() {}
virtual ~ZeroCopyInputStream();
// Obtains a chunk of data from the stream.
//
// Preconditions:
// * "size" and "data" are not NULL.
//
// Postconditions:
// * If the returned value is false, there is no more data to return or
// an error occurred. All errors are permanent.
// * Otherwise, "size" points to the actual number of bytes read and "data"
// points to a pointer to a buffer containing these bytes.
// * Ownership of this buffer remains with the stream, and the buffer
// remains valid only until some other method of the stream is called
// or the stream is destroyed.
// * It is legal for the returned buffer to have zero size, as long
// as repeatedly calling Next() eventually yields a buffer with non-zero
// size.
virtual bool Next(const void** data, int* size) = 0;
// Backs up a number of bytes, so that the next call to Next() returns
// data again that was already returned by the last call to Next(). This
// is useful when writing procedures that are only supposed to read up
// to a certain point in the input, then return. If Next() returns a
// buffer that goes beyond what you wanted to read, you can use BackUp()
// to return to the point where you intended to finish.
//
// Preconditions:
// * The last method called must have been Next().
// * count must be less than or equal to the size of the last buffer
// returned by Next().
//
// Postconditions:
// * The last "count" bytes of the last buffer returned by Next() will be
// pushed back into the stream. Subsequent calls to Next() will return
// the same data again before producing new data.
virtual void BackUp(int count) = 0;
// Skips a number of bytes. Returns false if the end of the stream is
// reached or some input error occurred. In the end-of-stream case, the
// stream is advanced to the end of the stream (so ByteCount() will return
// the total size of the stream).
virtual bool Skip(int count) = 0;
// Returns the total number of bytes read since this object was created.
virtual int64 ByteCount() const = 0;
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyInputStream);
};
// Abstract interface similar to an output stream but designed to minimize
// copying.
class LIBPROTOBUF_EXPORT ZeroCopyOutputStream {
public:
inline ZeroCopyOutputStream() {}
virtual ~ZeroCopyOutputStream();
// Obtains a buffer into which data can be written. Any data written
// into this buffer will eventually (maybe instantly, maybe later on)
// be written to the output.
//
// Preconditions:
// * "size" and "data" are not NULL.
//
// Postconditions:
// * If the returned value is false, an error occurred. All errors are
// permanent.
// * Otherwise, "size" points to the actual number of bytes in the buffer
// and "data" points to the buffer.
// * Ownership of this buffer remains with the stream, and the buffer
// remains valid only until some other method of the stream is called
// or the stream is destroyed.
// * Any data which the caller stores in this buffer will eventually be
// written to the output (unless BackUp() is called).
// * It is legal for the returned buffer to have zero size, as long
// as repeatedly calling Next() eventually yields a buffer with non-zero
// size.
virtual bool Next(void** data, int* size) = 0;
// Backs up a number of bytes, so that the end of the last buffer returned
// by Next() is not actually written. This is needed when you finish
// writing all the data you want to write, but the last buffer was bigger
// than you needed. You don't want to write a bunch of garbage after the
// end of your data, so you use BackUp() to back up.
//
// Preconditions:
// * The last method called must have been Next().
// * count must be less than or equal to the size of the last buffer
// returned by Next().
// * The caller must not have written anything to the last "count" bytes
// of that buffer.
//
// Postconditions:
// * The last "count" bytes of the last buffer returned by Next() will be
// ignored.
virtual void BackUp(int count) = 0;
// Returns the total number of bytes written since this object was created.
virtual int64 ByteCount() const = 0;
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyOutputStream);
};
} // namespace io
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__

View File

@ -1,393 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// 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
// 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.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/stl_util-inl.h>
namespace google {
namespace protobuf {
namespace io {
namespace {
// Default block size for Copying{In,Out}putStreamAdaptor.
static const int kDefaultBlockSize = 8192;
} // namespace
// ===================================================================
ArrayInputStream::ArrayInputStream(const void* data, int size,
int block_size)
: data_(reinterpret_cast<const uint8*>(data)),
size_(size),
block_size_(block_size > 0 ? block_size : size),
position_(0),
last_returned_size_(0) {
}
ArrayInputStream::~ArrayInputStream() {
}
bool ArrayInputStream::Next(const void** data, int* size) {
if (position_ < size_) {
last_returned_size_ = min(block_size_, size_ - position_);
*data = data_ + position_;
*size = last_returned_size_;
position_ += last_returned_size_;
return true;
} else {
// We're at the end of the array.
last_returned_size_ = 0; // Don't let caller back up.
return false;
}
}
void ArrayInputStream::BackUp(int count) {
GOOGLE_CHECK_GT(last_returned_size_, 0)
<< "BackUp() can only be called after a successful Next().";
GOOGLE_CHECK_LE(count, last_returned_size_);
GOOGLE_CHECK_GE(count, 0);
position_ -= count;
last_returned_size_ = 0; // Don't let caller back up further.
}
bool ArrayInputStream::Skip(int count) {
GOOGLE_CHECK_GE(count, 0);
last_returned_size_ = 0; // Don't let caller back up.
if (count > size_ - position_) {
position_ = size_;
return false;
} else {
position_ += count;
return true;
}
}
int64 ArrayInputStream::ByteCount() const {
return position_;
}
// ===================================================================
ArrayOutputStream::ArrayOutputStream(void* data, int size, int block_size)
: data_(reinterpret_cast<uint8*>(data)),
size_(size),
block_size_(block_size > 0 ? block_size : size),
position_(0),
last_returned_size_(0) {
}
ArrayOutputStream::~ArrayOutputStream() {
}
bool ArrayOutputStream::Next(void** data, int* size) {
if (position_ < size_) {
last_returned_size_ = min(block_size_, size_ - position_);
*data = data_ + position_;
*size = last_returned_size_;
position_ += last_returned_size_;
return true;
} else {
// We're at the end of the array.
last_returned_size_ = 0; // Don't let caller back up.
return false;
}
}
void ArrayOutputStream::BackUp(int count) {
GOOGLE_CHECK_GT(last_returned_size_, 0)
<< "BackUp() can only be called after a successful Next().";
GOOGLE_CHECK_LE(count, last_returned_size_);
GOOGLE_CHECK_GE(count, 0);
position_ -= count;
last_returned_size_ = 0; // Don't let caller back up further.
}
int64 ArrayOutputStream::ByteCount() const {
return position_;
}
// ===================================================================
StringOutputStream::StringOutputStream(string* target)
: target_(target) {
}
StringOutputStream::~StringOutputStream() {
}
bool StringOutputStream::Next(void** data, int* size) {
int old_size = target_->size();
// Grow the string.
if (old_size < target_->capacity()) {
// Resize the string to match its capacity, since we can get away
// without a memory allocation this way.
STLStringResizeUninitialized(target_, target_->capacity());
} else {
// Size has reached capacity, so double the size. Also make sure
// that the new size is at least kMinimumSize.
STLStringResizeUninitialized(
target_,
max(old_size * 2,
kMinimumSize + 0)); // "+ 0" works around GCC4 weirdness.
}
*data = string_as_array(target_) + old_size;
*size = target_->size() - old_size;
return true;
}
void StringOutputStream::BackUp(int count) {
GOOGLE_CHECK_GE(count, 0);
GOOGLE_CHECK_LE(count, target_->size());
target_->resize(target_->size() - count);
}
int64 StringOutputStream::ByteCount() const {
return target_->size();
}
// ===================================================================
CopyingInputStream::~CopyingInputStream() {}
int CopyingInputStream::Skip(int count) {
char junk[4096];
int skipped = 0;
while (skipped < count) {
int bytes = Read(junk, min(count - skipped,
implicit_cast<int>(sizeof(junk))));
if (bytes <= 0) {
// EOF or read error.
return skipped;
}
skipped += bytes;
}
return skipped;
}
CopyingInputStreamAdaptor::CopyingInputStreamAdaptor(
CopyingInputStream* copying_stream, int block_size)
: copying_stream_(copying_stream),
owns_copying_stream_(false),
failed_(false),
position_(0),
buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize),
buffer_used_(0),
backup_bytes_(0) {
}
CopyingInputStreamAdaptor::~CopyingInputStreamAdaptor() {
if (owns_copying_stream_) {
delete copying_stream_;
}
}
bool CopyingInputStreamAdaptor::Next(const void** data, int* size) {
if (failed_) {
// Already failed on a previous read.
return false;
}
AllocateBufferIfNeeded();
if (backup_bytes_ > 0) {
// We have data left over from a previous BackUp(), so just return that.
*data = buffer_.get() + buffer_used_ - backup_bytes_;
*size = backup_bytes_;
backup_bytes_ = 0;
return true;
}
// Read new data into the buffer.
buffer_used_ = copying_stream_->Read(buffer_.get(), buffer_size_);
if (buffer_used_ <= 0) {
// EOF or read error. We don't need the buffer anymore.
if (buffer_used_ < 0) {
// Read error (not EOF).
failed_ = true;
}
FreeBuffer();
return false;
}
position_ += buffer_used_;
*size = buffer_used_;
*data = buffer_.get();
return true;
}
void CopyingInputStreamAdaptor::BackUp(int count) {
GOOGLE_CHECK(backup_bytes_ == 0 && buffer_.get() != NULL)
<< " BackUp() can only be called after Next().";
GOOGLE_CHECK_LE(count, buffer_used_)
<< " Can't back up over more bytes than were returned by the last call"
" to Next().";
GOOGLE_CHECK_GE(count, 0)
<< " Parameter to BackUp() can't be negative.";
backup_bytes_ = count;
}
bool CopyingInputStreamAdaptor::Skip(int count) {
GOOGLE_CHECK_GE(count, 0);
if (failed_) {
// Already failed on a previous read.
return false;
}
// First skip any bytes left over from a previous BackUp().
if (backup_bytes_ >= count) {
// We have more data left over than we're trying to skip. Just chop it.
backup_bytes_ -= count;
return true;
}
count -= backup_bytes_;
backup_bytes_ = 0;
int skipped = copying_stream_->Skip(count);
position_ += skipped;
return skipped == count;
}
int64 CopyingInputStreamAdaptor::ByteCount() const {
return position_ - backup_bytes_;
}
void CopyingInputStreamAdaptor::AllocateBufferIfNeeded() {
if (buffer_.get() == NULL) {
buffer_.reset(new uint8[buffer_size_]);
}
}
void CopyingInputStreamAdaptor::FreeBuffer() {
GOOGLE_CHECK_EQ(backup_bytes_, 0);
buffer_used_ = 0;
buffer_.reset();
}
// ===================================================================
CopyingOutputStream::~CopyingOutputStream() {}
CopyingOutputStreamAdaptor::CopyingOutputStreamAdaptor(
CopyingOutputStream* copying_stream, int block_size)
: copying_stream_(copying_stream),
owns_copying_stream_(false),
failed_(false),
position_(0),
buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize),
buffer_used_(0) {
}
CopyingOutputStreamAdaptor::~CopyingOutputStreamAdaptor() {
WriteBuffer();
if (owns_copying_stream_) {
delete copying_stream_;
}
}
bool CopyingOutputStreamAdaptor::Flush() {
return WriteBuffer();
}
bool CopyingOutputStreamAdaptor::Next(void** data, int* size) {
if (buffer_used_ == buffer_size_) {
if (!WriteBuffer()) return false;
}
AllocateBufferIfNeeded();
*data = buffer_.get() + buffer_used_;
*size = buffer_size_ - buffer_used_;
buffer_used_ = buffer_size_;
return true;
}
void CopyingOutputStreamAdaptor::BackUp(int count) {
GOOGLE_CHECK_GE(count, 0);
GOOGLE_CHECK_EQ(buffer_used_, buffer_size_)
<< " BackUp() can only be called after Next().";
GOOGLE_CHECK_LE(count, buffer_used_)
<< " Can't back up over more bytes than were returned by the last call"
" to Next().";
buffer_used_ -= count;
}
int64 CopyingOutputStreamAdaptor::ByteCount() const {
return position_ + buffer_used_;
}
bool CopyingOutputStreamAdaptor::WriteBuffer() {
if (failed_) {
// Already failed on a previous write.
return false;
}
if (buffer_used_ == 0) return true;
if (copying_stream_->Write(buffer_.get(), buffer_used_)) {
position_ += buffer_used_;
buffer_used_ = 0;
return true;
} else {
failed_ = true;
FreeBuffer();
return false;
}
}
void CopyingOutputStreamAdaptor::AllocateBufferIfNeeded() {
if (buffer_ == NULL) {
buffer_.reset(new uint8[buffer_size_]);
}
}
void CopyingOutputStreamAdaptor::FreeBuffer() {
buffer_used_ = 0;
buffer_.reset();
}
// ===================================================================
} // namespace io
} // namespace protobuf
} // namespace google

View File

@ -1,340 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// 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
// 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.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// This file contains common implementations of the interfaces defined in
// zero_copy_stream.h which are included in the "lite" protobuf library.
// These implementations cover I/O on raw arrays and strings, as well as
// adaptors which make it easy to implement streams based on traditional
// streams. Of course, many users will probably want to write their own
// implementations of these interfaces specific to the particular I/O
// abstractions they prefer to use, but these should cover the most common
// cases.
#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__
#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__
#include <string>
#include <iosfwd>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
namespace io {
// ===================================================================
// A ZeroCopyInputStream backed by an in-memory array of bytes.
class LIBPROTOBUF_EXPORT ArrayInputStream : public ZeroCopyInputStream {
public:
// Create an InputStream that returns the bytes pointed to by "data".
// "data" remains the property of the caller but must remain valid until
// the stream is destroyed. If a block_size is given, calls to Next()
// will return data blocks no larger than the given size. Otherwise, the
// first call to Next() returns the entire array. block_size is mainly
// useful for testing; in production you would probably never want to set
// it.
ArrayInputStream(const void* data, int size, int block_size = -1);
~ArrayInputStream();
// implements ZeroCopyInputStream ----------------------------------
bool Next(const void** data, int* size);
void BackUp(int count);
bool Skip(int count);
int64 ByteCount() const;
private:
const uint8* const data_; // The byte array.
const int size_; // Total size of the array.
const int block_size_; // How many bytes to return at a time.
int position_;
int last_returned_size_; // How many bytes we returned last time Next()
// was called (used for error checking only).
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayInputStream);
};
// ===================================================================
// A ZeroCopyOutputStream backed by an in-memory array of bytes.
class LIBPROTOBUF_EXPORT ArrayOutputStream : public ZeroCopyOutputStream {
public:
// Create an OutputStream that writes to the bytes pointed to by "data".
// "data" remains the property of the caller but must remain valid until
// the stream is destroyed. If a block_size is given, calls to Next()
// will return data blocks no larger than the given size. Otherwise, the
// first call to Next() returns the entire array. block_size is mainly
// useful for testing; in production you would probably never want to set
// it.
ArrayOutputStream(void* data, int size, int block_size = -1);
~ArrayOutputStream();
// implements ZeroCopyOutputStream ---------------------------------
bool Next(void** data, int* size);
void BackUp(int count);
int64 ByteCount() const;
private:
uint8* const data_; // The byte array.
const int size_; // Total size of the array.
const int block_size_; // How many bytes to return at a time.
int position_;
int last_returned_size_; // How many bytes we returned last time Next()
// was called (used for error checking only).
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayOutputStream);
};
// ===================================================================
// A ZeroCopyOutputStream which appends bytes to a string.
class LIBPROTOBUF_EXPORT StringOutputStream : public ZeroCopyOutputStream {
public:
// Create a StringOutputStream which appends bytes to the given string.
// The string remains property of the caller, but it MUST NOT be accessed
// in any way until the stream is destroyed.
//
// Hint: If you call target->reserve(n) before creating the stream,
// the first call to Next() will return at least n bytes of buffer
// space.
explicit StringOutputStream(string* target);
~StringOutputStream();
// implements ZeroCopyOutputStream ---------------------------------
bool Next(void** data, int* size);
void BackUp(int count);
int64 ByteCount() const;
private:
static const int kMinimumSize = 16;
string* target_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringOutputStream);
};
// Note: There is no StringInputStream. Instead, just create an
// ArrayInputStream as follows:
// ArrayInputStream input(str.data(), str.size());
// ===================================================================
// A generic traditional input stream interface.
//
// Lots of traditional input streams (e.g. file descriptors, C stdio
// streams, and C++ iostreams) expose an interface where every read
// involves copying bytes into a buffer. If you want to take such an
// interface and make a ZeroCopyInputStream based on it, simply implement
// CopyingInputStream and then use CopyingInputStreamAdaptor.
//
// CopyingInputStream implementations should avoid buffering if possible.
// CopyingInputStreamAdaptor does its own buffering and will read data
// in large blocks.
class LIBPROTOBUF_EXPORT CopyingInputStream {
public:
virtual ~CopyingInputStream();
// Reads up to "size" bytes into the given buffer. Returns the number of
// bytes read. Read() waits until at least one byte is available, or
// returns zero if no bytes will ever become available (EOF), or -1 if a
// permanent read error occurred.
virtual int Read(void* buffer, int size) = 0;
// Skips the next "count" bytes of input. Returns the number of bytes
// actually skipped. This will always be exactly equal to "count" unless
// EOF was reached or a permanent read error occurred.
//
// The default implementation just repeatedly calls Read() into a scratch
// buffer.
virtual int Skip(int count);
};
// A ZeroCopyInputStream which reads from a CopyingInputStream. This is
// useful for implementing ZeroCopyInputStreams that read from traditional
// streams. Note that this class is not really zero-copy.
//
// If you want to read from file descriptors or C++ istreams, this is
// already implemented for you: use FileInputStream or IstreamInputStream
// respectively.
class LIBPROTOBUF_EXPORT CopyingInputStreamAdaptor : public ZeroCopyInputStream {
public:
// Creates a stream that reads from the given CopyingInputStream.
// If a block_size is given, it specifies the number of bytes that
// should be read and returned with each call to Next(). Otherwise,
// a reasonable default is used. The caller retains ownership of
// copying_stream unless SetOwnsCopyingStream(true) is called.
explicit CopyingInputStreamAdaptor(CopyingInputStream* copying_stream,
int block_size = -1);
~CopyingInputStreamAdaptor();
// Call SetOwnsCopyingStream(true) to tell the CopyingInputStreamAdaptor to
// delete the underlying CopyingInputStream when it is destroyed.
void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; }
// implements ZeroCopyInputStream ----------------------------------
bool Next(const void** data, int* size);
void BackUp(int count);
bool Skip(int count);
int64 ByteCount() const;
private:
// Insures that buffer_ is not NULL.
void AllocateBufferIfNeeded();
// Frees the buffer and resets buffer_used_.
void FreeBuffer();
// The underlying copying stream.
CopyingInputStream* copying_stream_;
bool owns_copying_stream_;
// True if we have seen a permenant error from the underlying stream.
bool failed_;
// The current position of copying_stream_, relative to the point where
// we started reading.
int64 position_;
// Data is read into this buffer. It may be NULL if no buffer is currently
// in use. Otherwise, it points to an array of size buffer_size_.
scoped_array<uint8> buffer_;
const int buffer_size_;
// Number of valid bytes currently in the buffer (i.e. the size last
// returned by Next()). 0 <= buffer_used_ <= buffer_size_.
int buffer_used_;
// Number of bytes in the buffer which were backed up over by a call to
// BackUp(). These need to be returned again.
// 0 <= backup_bytes_ <= buffer_used_
int backup_bytes_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingInputStreamAdaptor);
};
// ===================================================================
// A generic traditional output stream interface.
//
// Lots of traditional output streams (e.g. file descriptors, C stdio
// streams, and C++ iostreams) expose an interface where every write
// involves copying bytes from a buffer. If you want to take such an
// interface and make a ZeroCopyOutputStream based on it, simply implement
// CopyingOutputStream and then use CopyingOutputStreamAdaptor.
//
// CopyingOutputStream implementations should avoid buffering if possible.
// CopyingOutputStreamAdaptor does its own buffering and will write data
// in large blocks.
class LIBPROTOBUF_EXPORT CopyingOutputStream {
public:
virtual ~CopyingOutputStream();
// Writes "size" bytes from the given buffer to the output. Returns true
// if successful, false on a write error.
virtual bool Write(const void* buffer, int size) = 0;
};
// A ZeroCopyOutputStream which writes to a CopyingOutputStream. This is
// useful for implementing ZeroCopyOutputStreams that write to traditional
// streams. Note that this class is not really zero-copy.
//
// If you want to write to file descriptors or C++ ostreams, this is
// already implemented for you: use FileOutputStream or OstreamOutputStream
// respectively.
class LIBPROTOBUF_EXPORT CopyingOutputStreamAdaptor : public ZeroCopyOutputStream {
public:
// Creates a stream that writes to the given Unix file descriptor.
// If a block_size is given, it specifies the size of the buffers
// that should be returned by Next(). Otherwise, a reasonable default
// is used.
explicit CopyingOutputStreamAdaptor(CopyingOutputStream* copying_stream,
int block_size = -1);
~CopyingOutputStreamAdaptor();
// Writes all pending data to the underlying stream. Returns false if a
// write error occurred on the underlying stream. (The underlying
// stream itself is not necessarily flushed.)
bool Flush();
// Call SetOwnsCopyingStream(true) to tell the CopyingOutputStreamAdaptor to
// delete the underlying CopyingOutputStream when it is destroyed.
void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; }
// implements ZeroCopyOutputStream ---------------------------------
bool Next(void** data, int* size);
void BackUp(int count);
int64 ByteCount() const;
private:
// Write the current buffer, if it is present.
bool WriteBuffer();
// Insures that buffer_ is not NULL.
void AllocateBufferIfNeeded();
// Frees the buffer.
void FreeBuffer();
// The underlying copying stream.
CopyingOutputStream* copying_stream_;
bool owns_copying_stream_;
// True if we have seen a permenant error from the underlying stream.
bool failed_;
// The current position of copying_stream_, relative to the point where
// we started writing.
int64 position_;
// Data is written from this buffer. It may be NULL if no buffer is
// currently in use. Otherwise, it points to an array of size buffer_size_.
scoped_array<uint8> buffer_;
const int buffer_size_;
// Number of valid bytes currently in the buffer (i.e. the size last
// returned by Next()). When BackUp() is called, we just reduce this.
// 0 <= buffer_used_ <= buffer_size_.
int buffer_used_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOutputStreamAdaptor);
};
// ===================================================================
} // namespace io
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__

View File

@ -1,334 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// 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
// 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.
// Authors: wink@google.com (Wink Saville),
// kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/message_lite.h>
#include <string>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/stubs/stl_util-inl.h>
namespace google {
namespace protobuf {
MessageLite::~MessageLite() {}
string MessageLite::InitializationErrorString() const {
return "(cannot determine missing fields for lite message)";
}
namespace {
// When serializing, we first compute the byte size, then serialize the message.
// If serialization produces a different number of bytes than expected, we
// call this function, which crashes. The problem could be due to a bug in the
// protobuf implementation but is more likely caused by concurrent modification
// of the message. This function attempts to distinguish between the two and
// provide a useful error message.
void ByteSizeConsistencyError(int byte_size_before_serialization,
int byte_size_after_serialization,
int bytes_produced_by_serialization) {
GOOGLE_CHECK_EQ(byte_size_before_serialization, byte_size_after_serialization)
<< "Protocol message was modified concurrently during serialization.";
GOOGLE_CHECK_EQ(bytes_produced_by_serialization, byte_size_before_serialization)
<< "Byte size calculation and serialization were inconsistent. This "
"may indicate a bug in protocol buffers or it may be caused by "
"concurrent modification of the message.";
GOOGLE_LOG(FATAL) << "This shouldn't be called if all the sizes are equal.";
}
string InitializationErrorMessage(const char* action,
const MessageLite& message) {
// Note: We want to avoid depending on strutil in the lite library, otherwise
// we'd use:
//
// return strings::Substitute(
// "Can't $0 message of type \"$1\" because it is missing required "
// "fields: $2",
// action, message.GetTypeName(),
// message.InitializationErrorString());
string result;
result += "Can't ";
result += action;
result += " message of type \"";
result += message.GetTypeName();
result += "\" because it is missing required fields: ";
result += message.InitializationErrorString();
return result;
}
// Several of the Parse methods below just do one thing and then call another
// method. In a naive implementation, we might have ParseFromString() call
// ParseFromArray() which would call ParseFromZeroCopyStream() which would call
// ParseFromCodedStream() which would call MergeFromCodedStream() which would
// call MergePartialFromCodedStream(). However, when parsing very small
// messages, every function call introduces significant overhead. To avoid
// this without reproducing code, we use these forced-inline helpers.
//
// Note: GCC only allows GOOGLE_ATTRIBUTE_ALWAYS_INLINE on declarations, not
// definitions.
inline bool InlineMergeFromCodedStream(io::CodedInputStream* input,
MessageLite* message)
GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
inline bool InlineParseFromCodedStream(io::CodedInputStream* input,
MessageLite* message)
GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
inline bool InlineParsePartialFromCodedStream(io::CodedInputStream* input,
MessageLite* message)
GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
inline bool InlineParseFromArray(const void* data, int size,
MessageLite* message)
GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
inline bool InlineParsePartialFromArray(const void* data, int size,
MessageLite* message)
GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
bool InlineMergeFromCodedStream(io::CodedInputStream* input,
MessageLite* message) {
if (!message->MergePartialFromCodedStream(input)) return false;
if (!message->IsInitialized()) {
GOOGLE_LOG(ERROR) << InitializationErrorMessage("parse", *message);
return false;
}
return true;
}
bool InlineParseFromCodedStream(io::CodedInputStream* input,
MessageLite* message) {
message->Clear();
return InlineMergeFromCodedStream(input, message);
}
bool InlineParsePartialFromCodedStream(io::CodedInputStream* input,
MessageLite* message) {
message->Clear();
return message->MergePartialFromCodedStream(input);
}
bool InlineParseFromArray(const void* data, int size, MessageLite* message) {
io::CodedInputStream input(reinterpret_cast<const uint8*>(data), size);
return InlineParseFromCodedStream(&input, message) &&
input.ConsumedEntireMessage();
}
bool InlineParsePartialFromArray(const void* data, int size,
MessageLite* message) {
io::CodedInputStream input(reinterpret_cast<const uint8*>(data), size);
return InlineParsePartialFromCodedStream(&input, message) &&
input.ConsumedEntireMessage();
}
} // namespace
bool MessageLite::MergeFromCodedStream(io::CodedInputStream* input) {
return InlineMergeFromCodedStream(input, this);
}
bool MessageLite::ParseFromCodedStream(io::CodedInputStream* input) {
return InlineParseFromCodedStream(input, this);
}
bool MessageLite::ParsePartialFromCodedStream(io::CodedInputStream* input) {
return InlineParsePartialFromCodedStream(input, this);
}
bool MessageLite::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) {
io::CodedInputStream decoder(input);
return ParseFromCodedStream(&decoder) && decoder.ConsumedEntireMessage();
}
bool MessageLite::ParsePartialFromZeroCopyStream(
io::ZeroCopyInputStream* input) {
io::CodedInputStream decoder(input);
return ParsePartialFromCodedStream(&decoder) &&
decoder.ConsumedEntireMessage();
}
bool MessageLite::ParseFromBoundedZeroCopyStream(
io::ZeroCopyInputStream* input, int size) {
io::CodedInputStream decoder(input);
decoder.PushLimit(size);
return ParseFromCodedStream(&decoder) &&
decoder.ConsumedEntireMessage() &&
decoder.BytesUntilLimit() == 0;
}
bool MessageLite::ParsePartialFromBoundedZeroCopyStream(
io::ZeroCopyInputStream* input, int size) {
io::CodedInputStream decoder(input);
decoder.PushLimit(size);
return ParsePartialFromCodedStream(&decoder) &&
decoder.ConsumedEntireMessage() &&
decoder.BytesUntilLimit() == 0;
}
bool MessageLite::ParseFromString(const string& data) {
return InlineParseFromArray(data.data(), data.size(), this);
}
bool MessageLite::ParsePartialFromString(const string& data) {
return InlineParsePartialFromArray(data.data(), data.size(), this);
}
bool MessageLite::ParseFromArray(const void* data, int size) {
return InlineParseFromArray(data, size, this);
}
bool MessageLite::ParsePartialFromArray(const void* data, int size) {
return InlineParsePartialFromArray(data, size, this);
}
// ===================================================================
uint8* MessageLite::SerializeWithCachedSizesToArray(uint8* target) const {
// We only optimize this when using optimize_for = SPEED. In other cases
// we just use the CodedOutputStream path.
int size = GetCachedSize();
io::ArrayOutputStream out(target, size);
io::CodedOutputStream coded_out(&out);
SerializeWithCachedSizes(&coded_out);
GOOGLE_CHECK(!coded_out.HadError());
return target + size;
}
bool MessageLite::SerializeToCodedStream(io::CodedOutputStream* output) const {
GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this);
return SerializePartialToCodedStream(output);
}
bool MessageLite::SerializePartialToCodedStream(
io::CodedOutputStream* output) const {
const int size = ByteSize(); // Force size to be cached.
uint8* buffer = output->GetDirectBufferForNBytesAndAdvance(size);
if (buffer != NULL) {
uint8* end = SerializeWithCachedSizesToArray(buffer);
if (end - buffer != size) {
ByteSizeConsistencyError(size, ByteSize(), end - buffer);
}
return true;
} else {
int original_byte_count = output->ByteCount();
SerializeWithCachedSizes(output);
if (output->HadError()) {
return false;
}
int final_byte_count = output->ByteCount();
if (final_byte_count - original_byte_count != size) {
ByteSizeConsistencyError(size, ByteSize(),
final_byte_count - original_byte_count);
}
return true;
}
}
bool MessageLite::SerializeToZeroCopyStream(
io::ZeroCopyOutputStream* output) const {
io::CodedOutputStream encoder(output);
return SerializeToCodedStream(&encoder);
}
bool MessageLite::SerializePartialToZeroCopyStream(
io::ZeroCopyOutputStream* output) const {
io::CodedOutputStream encoder(output);
return SerializePartialToCodedStream(&encoder);
}
bool MessageLite::AppendToString(string* output) const {
GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this);
return AppendPartialToString(output);
}
bool MessageLite::AppendPartialToString(string* output) const {
int old_size = output->size();
int byte_size = ByteSize();
STLStringResizeUninitialized(output, old_size + byte_size);
uint8* start = reinterpret_cast<uint8*>(string_as_array(output) + old_size);
uint8* end = SerializeWithCachedSizesToArray(start);
if (end - start != byte_size) {
ByteSizeConsistencyError(byte_size, ByteSize(), end - start);
}
return true;
}
bool MessageLite::SerializeToString(string* output) const {
output->clear();
return AppendToString(output);
}
bool MessageLite::SerializePartialToString(string* output) const {
output->clear();
return AppendPartialToString(output);
}
bool MessageLite::SerializeToArray(void* data, int size) const {
GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this);
return SerializePartialToArray(data, size);
}
bool MessageLite::SerializePartialToArray(void* data, int size) const {
int byte_size = ByteSize();
if (size < byte_size) return false;
uint8* start = reinterpret_cast<uint8*>(data);
uint8* end = SerializeWithCachedSizesToArray(start);
if (end - start != byte_size) {
ByteSizeConsistencyError(byte_size, ByteSize(), end - start);
}
return true;
}
string MessageLite::SerializeAsString() const {
// If the compiler implements the (Named) Return Value Optimization,
// the local variable 'result' will not actually reside on the stack
// of this function, but will be overlaid with the object that the
// caller supplied for the return value to be constructed in.
string output;
if (!AppendToString(&output))
output.clear();
return output;
}
string MessageLite::SerializePartialAsString() const {
string output;
if (!AppendPartialToString(&output))
output.clear();
return output;
}
} // namespace protobuf
} // namespace google

View File

@ -1,239 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// 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
// 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.
// Authors: wink@google.com (Wink Saville),
// kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// Defines MessageLite, the abstract interface implemented by all (lite
// and non-lite) protocol message objects.
#ifndef GOOGLE_PROTOBUF_MESSAGE_LITE_H__
#define GOOGLE_PROTOBUF_MESSAGE_LITE_H__
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/io/coded_stream.h>
namespace google {
namespace protobuf {
// Interface to light weight protocol messages.
//
// This interface is implemented by all protocol message objects. Non-lite
// messages additionally implement the Message interface, which is a
// subclass of MessageLite. Use MessageLite instead when you only need
// the subset of features which it supports -- namely, nothing that uses
// descriptors or reflection. You can instruct the protocol compiler
// to generate classes which implement only MessageLite, not the full
// Message interface, by adding the following line to the .proto file:
//
// option optimize_for = LITE_RUNTIME;
//
// This is particularly useful on resource-constrained systems where
// the full protocol buffers runtime library is too big.
//
// Note that on non-constrained systems (e.g. servers) when you need
// to link in lots of protocol definitions, a better way to reduce
// total code footprint is to use optimize_for = CODE_SIZE. This
// will make the generated code smaller while still supporting all the
// same features (at the expense of speed). optimize_for = LITE_RUNTIME
// is best when you only have a small number of message types linked
// into your binary, in which case the size of the protocol buffers
// runtime itself is the biggest problem.
class LIBPROTOBUF_EXPORT MessageLite {
public:
inline MessageLite() {}
virtual ~MessageLite();
// Basic Operations ------------------------------------------------
// Get the name of this message type, e.g. "foo.bar.BazProto".
virtual string GetTypeName() const = 0;
// Construct a new instance of the same type. Ownership is passed to the
// caller.
virtual MessageLite* New() const = 0;
// Clear all fields of the message and set them to their default values.
// Clear() avoids freeing memory, assuming that any memory allocated
// to hold parts of the message will be needed again to hold the next
// message. If you actually want to free the memory used by a Message,
// you must delete it.
virtual void Clear() = 0;
// Quickly check if all required fields have values set.
virtual bool IsInitialized() const = 0;
// This is not implemented for Lite messages -- it just returns "(cannot
// determine missing fields for lite message)". However, it is implemented
// for full messages. See message.h.
virtual string InitializationErrorString() const;
// If |other| is the exact same class as this, calls MergeFrom(). Otherwise,
// results are undefined (probably crash).
virtual void CheckTypeAndMergeFrom(const MessageLite& other) = 0;
// Parsing ---------------------------------------------------------
// Methods for parsing in protocol buffer format. Most of these are
// just simple wrappers around MergeFromCodedStream().
// Fill the message with a protocol buffer parsed from the given input
// stream. Returns false on a read error or if the input is in the
// wrong format.
bool ParseFromCodedStream(io::CodedInputStream* input);
// Like ParseFromCodedStream(), but accepts messages that are missing
// required fields.
bool ParsePartialFromCodedStream(io::CodedInputStream* input);
// Read a protocol buffer from the given zero-copy input stream. If
// successful, the entire input will be consumed.
bool ParseFromZeroCopyStream(io::ZeroCopyInputStream* input);
// Like ParseFromZeroCopyStream(), but accepts messages that are missing
// required fields.
bool ParsePartialFromZeroCopyStream(io::ZeroCopyInputStream* input);
// Read a protocol buffer from the given zero-copy input stream, expecting
// the message to be exactly "size" bytes long. If successful, exactly
// this many bytes will have been consumed from the input.
bool ParseFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, int size);
// Like ParseFromBoundedZeroCopyStream(), but accepts messages that are
// missing required fields.
bool ParsePartialFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input,
int size);
// Parse a protocol buffer contained in a string.
bool ParseFromString(const string& data);
// Like ParseFromString(), but accepts messages that are missing
// required fields.
bool ParsePartialFromString(const string& data);
// Parse a protocol buffer contained in an array of bytes.
bool ParseFromArray(const void* data, int size);
// Like ParseFromArray(), but accepts messages that are missing
// required fields.
bool ParsePartialFromArray(const void* data, int size);
// Reads a protocol buffer from the stream and merges it into this
// Message. Singular fields read from the input overwrite what is
// already in the Message and repeated fields are appended to those
// already present.
//
// It is the responsibility of the caller to call input->LastTagWas()
// (for groups) or input->ConsumedEntireMessage() (for non-groups) after
// this returns to verify that the message's end was delimited correctly.
//
// ParsefromCodedStream() is implemented as Clear() followed by
// MergeFromCodedStream().
bool MergeFromCodedStream(io::CodedInputStream* input);
// Like MergeFromCodedStream(), but succeeds even if required fields are
// missing in the input.
//
// MergeFromCodedStream() is just implemented as MergePartialFromCodedStream()
// followed by IsInitialized().
virtual bool MergePartialFromCodedStream(io::CodedInputStream* input) = 0;
// Serialization ---------------------------------------------------
// Methods for serializing in protocol buffer format. Most of these
// are just simple wrappers around ByteSize() and SerializeWithCachedSizes().
// Write a protocol buffer of this message to the given output. Returns
// false on a write error. If the message is missing required fields,
// this may GOOGLE_CHECK-fail.
bool SerializeToCodedStream(io::CodedOutputStream* output) const;
// Like SerializeToCodedStream(), but allows missing required fields.
bool SerializePartialToCodedStream(io::CodedOutputStream* output) const;
// Write the message to the given zero-copy output stream. All required
// fields must be set.
bool SerializeToZeroCopyStream(io::ZeroCopyOutputStream* output) const;
// Like SerializeToZeroCopyStream(), but allows missing required fields.
bool SerializePartialToZeroCopyStream(io::ZeroCopyOutputStream* output) const;
// Serialize the message and store it in the given string. All required
// fields must be set.
bool SerializeToString(string* output) const;
// Like SerializeToString(), but allows missing required fields.
bool SerializePartialToString(string* output) const;
// Serialize the message and store it in the given byte array. All required
// fields must be set.
bool SerializeToArray(void* data, int size) const;
// Like SerializeToArray(), but allows missing required fields.
bool SerializePartialToArray(void* data, int size) const;
// Make a string encoding the message. Is equivalent to calling
// SerializeToString() on a string and using that. Returns the empty
// string if SerializeToString() would have returned an error.
// Note: If you intend to generate many such strings, you may
// reduce heap fragmentation by instead re-using the same string
// object with calls to SerializeToString().
string SerializeAsString() const;
// Like SerializeAsString(), but allows missing required fields.
string SerializePartialAsString() const;
// Like SerializeToString(), but appends to the data to the string's existing
// contents. All required fields must be set.
bool AppendToString(string* output) const;
// Like AppendToString(), but allows missing required fields.
bool AppendPartialToString(string* output) const;
// Computes the serialized size of the message. This recursively calls
// ByteSize() on all embedded messages. If a subclass does not override
// this, it MUST override SetCachedSize().
virtual int ByteSize() const = 0;
// Serializes the message without recomputing the size. The message must
// not have changed since the last call to ByteSize(); if it has, the results
// are undefined.
virtual void SerializeWithCachedSizes(
io::CodedOutputStream* output) const = 0;
// Like SerializeWithCachedSizes, but writes directly to *target, returning
// a pointer to the byte immediately after the last byte written. "target"
// must point at a byte array of at least ByteSize() bytes.
virtual uint8* SerializeWithCachedSizesToArray(uint8* target) const;
// Returns the result of the last call to ByteSize(). An embedded message's
// size is needed both to serialize it (because embedded messages are
// length-delimited) and to compute the outer message's size. Caching
// the size avoids computing it multiple times.
//
// ByteSize() does not automatically use the cached size when available
// because this would require invalidating it every time the message was
// modified, which would be too hard and expensive. (E.g. if a deeply-nested
// sub-message is changed, all of its parents' cached sizes would need to be
// invalidated, which is too much work for an otherwise inlined setter
// method.)
virtual int GetCachedSize() const = 0;
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageLite);
};
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_MESSAGE_LITE_H__

View File

@ -1,64 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// 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
// 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.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// This file exists solely to document the google::protobuf namespace.
// It is not compiled into anything, but it may be read by an automated
// documentation generator.
namespace google {
// Core components of the Protocol Buffers runtime library.
//
// The files in this package represent the core of the Protocol Buffer
// system. All of them are part of the libprotobuf library.
//
// A note on thread-safety:
//
// Thread-safety in the Protocol Buffer library follows a simple rule:
// unless explicitly noted otherwise, it is always safe to use an object
// from multiple threads simultaneously as long as the object is declared
// const in all threads (or, it is only used in ways that would be allowed
// if it were declared const). However, if an object is accessed in one
// thread in a way that would not be allowed if it were const, then it is
// not safe to access that object in any other thread simultaneously.
//
// Put simply, read-only access to an object can happen in multiple threads
// simultaneously, but write access can only happen in a single thread at
// a time.
//
// The implementation does contain some "const" methods which actually modify
// the object behind the scenes -- e.g., to cache results -- but in these cases
// mutex locking is used to make the access thread-safe.
namespace protobuf {}
} // namespace google

View File

@ -1,98 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// 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
// 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.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
#include <algorithm>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
namespace internal {
void RepeatedPtrFieldBase::Reserve(int new_size) {
if (total_size_ >= new_size) return;
void** old_elements = elements_;
total_size_ = max(total_size_ * 2, new_size);
elements_ = new void*[total_size_];
memcpy(elements_, old_elements, allocated_size_ * sizeof(elements_[0]));
if (old_elements != initial_space_) {
delete [] old_elements;
}
}
void RepeatedPtrFieldBase::Swap(RepeatedPtrFieldBase* other) {
void** swap_elements = elements_;
int swap_current_size = current_size_;
int swap_allocated_size = allocated_size_;
int swap_total_size = total_size_;
// We may not be using initial_space_ but it's not worth checking. Just
// copy it anyway.
void* swap_initial_space[kInitialSize];
memcpy(swap_initial_space, initial_space_, sizeof(initial_space_));
elements_ = other->elements_;
current_size_ = other->current_size_;
allocated_size_ = other->allocated_size_;
total_size_ = other->total_size_;
memcpy(initial_space_, other->initial_space_, sizeof(initial_space_));
other->elements_ = swap_elements;
other->current_size_ = swap_current_size;
other->allocated_size_ = swap_allocated_size;
other->total_size_ = swap_total_size;
memcpy(other->initial_space_, swap_initial_space, sizeof(swap_initial_space));
if (elements_ == other->initial_space_) {
elements_ = initial_space_;
}
if (other->elements_ == initial_space_) {
other->elements_ = other->initial_space_;
}
}
string* StringTypeHandlerBase::New() {
return new string;
}
void StringTypeHandlerBase::Delete(string* value) {
delete value;
}
} // namespace internal
} // namespace protobuf
} // namespace google

File diff suppressed because it is too large Load Diff

View File

@ -1,373 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// 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
// 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.
// Author: kenton@google.com (Kenton Varda)
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/once.h>
#include <stdio.h>
#include <errno.h>
#include <vector>
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN // We only need minimal includes
#include <windows.h>
#define snprintf _snprintf // see comment in strutil.cc
#else
#include <pthread.h>
#endif
namespace google {
namespace protobuf {
namespace internal {
void VerifyVersion(int headerVersion,
int minLibraryVersion,
const char* filename) {
if (GOOGLE_PROTOBUF_VERSION < minLibraryVersion) {
// Library is too old for headers.
GOOGLE_LOG(FATAL)
<< "This program requires version " << VersionString(minLibraryVersion)
<< " of the Protocol Buffer runtime library, but the installed version "
"is " << VersionString(GOOGLE_PROTOBUF_VERSION) << ". Please update "
"your library. If you compiled the program yourself, make sure that "
"your headers are from the same version of Protocol Buffers as your "
"link-time library. (Version verification failed in \""
<< filename << "\".)";
}
if (headerVersion < kMinHeaderVersionForLibrary) {
// Headers are too old for library.
GOOGLE_LOG(FATAL)
<< "This program was compiled against version "
<< VersionString(headerVersion) << " of the Protocol Buffer runtime "
"library, which is not compatible with the installed version ("
<< VersionString(GOOGLE_PROTOBUF_VERSION) << "). Contact the program "
"author for an update. If you compiled the program yourself, make "
"sure that your headers are from the same version of Protocol Buffers "
"as your link-time library. (Version verification failed in \""
<< filename << "\".)";
}
}
string VersionString(int version) {
int major = version / 1000000;
int minor = (version / 1000) % 1000;
int micro = version % 1000;
// 128 bytes should always be enough, but we use snprintf() anyway to be
// safe.
char buffer[128];
snprintf(buffer, sizeof(buffer), "%d.%d.%d", major, minor, micro);
// Guard against broken MSVC snprintf().
buffer[sizeof(buffer)-1] = '\0';
return buffer;
}
} // namespace internal
// ===================================================================
// emulates google3/base/logging.cc
namespace internal {
void DefaultLogHandler(LogLevel level, const char* filename, int line,
const string& message) {
static const char* level_names[] = { "INFO", "WARNING", "ERROR", "FATAL" };
// We use fprintf() instead of cerr because we want this to work at static
// initialization time.
fprintf(stderr, "libprotobuf %s %s:%d] %s\n",
level_names[level], filename, line, message.c_str());
fflush(stderr); // Needed on MSVC.
}
void NullLogHandler(LogLevel level, const char* filename, int line,
const string& message) {
// Nothing.
}
static LogHandler* log_handler_ = &DefaultLogHandler;
static int log_silencer_count_ = 0;
static Mutex* log_silencer_count_mutex_ = NULL;
GOOGLE_PROTOBUF_DECLARE_ONCE(log_silencer_count_init_);
void DeleteLogSilencerCount() {
delete log_silencer_count_mutex_;
log_silencer_count_mutex_ = NULL;
}
void InitLogSilencerCount() {
log_silencer_count_mutex_ = new Mutex;
OnShutdown(&DeleteLogSilencerCount);
}
void InitLogSilencerCountOnce() {
GoogleOnceInit(&log_silencer_count_init_, &InitLogSilencerCount);
}
LogMessage& LogMessage::operator<<(const string& value) {
message_ += value;
return *this;
}
LogMessage& LogMessage::operator<<(const char* value) {
message_ += value;
return *this;
}
// Since this is just for logging, we don't care if the current locale changes
// the results -- in fact, we probably prefer that. So we use snprintf()
// instead of Simple*toa().
#undef DECLARE_STREAM_OPERATOR
#define DECLARE_STREAM_OPERATOR(TYPE, FORMAT) \
LogMessage& LogMessage::operator<<(TYPE value) { \
/* 128 bytes should be big enough for any of the primitive */ \
/* values which we print with this, but well use snprintf() */ \
/* anyway to be extra safe. */ \
char buffer[128]; \
snprintf(buffer, sizeof(buffer), FORMAT, value); \
/* Guard against broken MSVC snprintf(). */ \
buffer[sizeof(buffer)-1] = '\0'; \
message_ += buffer; \
return *this; \
}
DECLARE_STREAM_OPERATOR(char , "%c" )
DECLARE_STREAM_OPERATOR(int , "%d" )
DECLARE_STREAM_OPERATOR(uint , "%u" )
DECLARE_STREAM_OPERATOR(long , "%ld")
DECLARE_STREAM_OPERATOR(unsigned long, "%lu")
DECLARE_STREAM_OPERATOR(double , "%g" )
#undef DECLARE_STREAM_OPERATOR
LogMessage::LogMessage(LogLevel level, const char* filename, int line)
: level_(level), filename_(filename), line_(line) {}
LogMessage::~LogMessage() {}
void LogMessage::Finish() {
bool suppress = false;
if (level_ != LOGLEVEL_FATAL) {
InitLogSilencerCountOnce();
MutexLock lock(log_silencer_count_mutex_);
suppress = internal::log_silencer_count_ > 0;
}
if (!suppress) {
internal::log_handler_(level_, filename_, line_, message_);
}
if (level_ == LOGLEVEL_FATAL) {
#ifdef PROTOBUF_USE_EXCEPTIONS
throw FatalException(filename_, line_, message_);
#else
abort();
#endif
}
}
void LogFinisher::operator=(LogMessage& other) {
other.Finish();
}
} // namespace internal
LogHandler* SetLogHandler(LogHandler* new_func) {
LogHandler* old = internal::log_handler_;
if (old == &internal::NullLogHandler) {
old = NULL;
}
if (new_func == NULL) {
internal::log_handler_ = &internal::NullLogHandler;
} else {
internal::log_handler_ = new_func;
}
return old;
}
LogSilencer::LogSilencer() {
internal::InitLogSilencerCountOnce();
MutexLock lock(internal::log_silencer_count_mutex_);
++internal::log_silencer_count_;
};
LogSilencer::~LogSilencer() {
internal::InitLogSilencerCountOnce();
MutexLock lock(internal::log_silencer_count_mutex_);
--internal::log_silencer_count_;
};
// ===================================================================
// emulates google3/base/callback.cc
Closure::~Closure() {}
namespace internal { FunctionClosure0::~FunctionClosure0() {} }
void DoNothing() {}
// ===================================================================
// emulates google3/base/mutex.cc
#ifdef WIN32
struct Mutex::Internal {
CRITICAL_SECTION mutex;
#ifndef NDEBUG
// Used only to implement AssertHeld().
DWORD thread_id;
#endif
};
Mutex::Mutex()
: mInternal(new Internal) {
InitializeCriticalSection(&mInternal->mutex);
}
Mutex::~Mutex() {
DeleteCriticalSection(&mInternal->mutex);
delete mInternal;
}
void Mutex::Lock() {
EnterCriticalSection(&mInternal->mutex);
#ifndef NDEBUG
mInternal->thread_id = GetCurrentThreadId();
#endif
}
void Mutex::Unlock() {
#ifndef NDEBUG
mInternal->thread_id = 0;
#endif
LeaveCriticalSection(&mInternal->mutex);
}
void Mutex::AssertHeld() {
#ifndef NDEBUG
GOOGLE_DCHECK_EQ(mInternal->thread_id, GetCurrentThreadId());
#endif
}
#else
struct Mutex::Internal {
pthread_mutex_t mutex;
};
Mutex::Mutex()
: mInternal(new Internal) {
pthread_mutex_init(&mInternal->mutex, NULL);
}
Mutex::~Mutex() {
pthread_mutex_destroy(&mInternal->mutex);
delete mInternal;
}
void Mutex::Lock() {
int result = pthread_mutex_lock(&mInternal->mutex);
if (result != 0) {
GOOGLE_LOG(FATAL) << "pthread_mutex_lock: " << strerror(result);
}
}
void Mutex::Unlock() {
int result = pthread_mutex_unlock(&mInternal->mutex);
if (result != 0) {
GOOGLE_LOG(FATAL) << "pthread_mutex_unlock: " << strerror(result);
}
}
void Mutex::AssertHeld() {
// pthreads dosn't provide a way to check which thread holds the mutex.
// TODO(kenton): Maybe keep track of locking thread ID like with WIN32?
}
#endif
// ===================================================================
// Shutdown support.
namespace internal {
typedef void OnShutdownFunc();
vector<void (*)()>* shutdown_functions = NULL;
Mutex* shutdown_functions_mutex = NULL;
GOOGLE_PROTOBUF_DECLARE_ONCE(shutdown_functions_init);
void InitShutdownFunctions() {
shutdown_functions = new vector<void (*)()>;
shutdown_functions_mutex = new Mutex;
}
inline void InitShutdownFunctionsOnce() {
GoogleOnceInit(&shutdown_functions_init, &InitShutdownFunctions);
}
void OnShutdown(void (*func)()) {
InitShutdownFunctionsOnce();
MutexLock lock(shutdown_functions_mutex);
shutdown_functions->push_back(func);
}
} // namespace internal
void ShutdownProtobufLibrary() {
internal::InitShutdownFunctionsOnce();
// We don't need to lock shutdown_functions_mutex because it's up to the
// caller to make sure that no one is using the library before this is
// called.
// Make it safe to call this multiple times.
if (internal::shutdown_functions == NULL) return;
for (int i = 0; i < internal::shutdown_functions->size(); i++) {
internal::shutdown_functions->at(i)();
}
delete internal::shutdown_functions;
internal::shutdown_functions = NULL;
delete internal::shutdown_functions_mutex;
internal::shutdown_functions_mutex = NULL;
}
#ifdef PROTOBUF_USE_EXCEPTIONS
FatalException::~FatalException() throw() {}
const char* FatalException::what() const throw() {
return message_.c_str();
}
#endif
} // namespace protobuf
} // namespace google

File diff suppressed because it is too large Load Diff

View File

@ -1,219 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// 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
// 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.
// Author: kenton@google.com (Kenton Varda)
//
// Deals with the fact that hash_map is not defined everywhere.
#ifndef GOOGLE_PROTOBUF_STUBS_HASH_H__
#define GOOGLE_PROTOBUF_STUBS_HASH_H__
#include <string.h>
#include <google/protobuf/stubs/common.h>
#if defined(HAVE_HASH_MAP) && defined(HAVE_HASH_SET)
#include HASH_MAP_H
#include HASH_SET_H
#else
#define MISSING_HASH
#include <map>
#include <set>
#endif
namespace google {
namespace protobuf {
#ifdef MISSING_HASH
// This system doesn't have hash_map or hash_set. Emulate them using map and
// set.
// Make hash<T> be the same as less<T>. Note that everywhere where custom
// hash functions are defined in the protobuf code, they are also defined such
// that they can be used as "less" functions, which is required by MSVC anyway.
template <typename Key>
struct hash {
// Dummy, just to make derivative hash functions compile.
int operator()(const Key& key) {
GOOGLE_LOG(FATAL) << "Should never be called.";
return 0;
}
inline bool operator()(const Key& a, const Key& b) const {
return a < b;
}
};
// Make sure char* is compared by value.
template <>
struct hash<const char*> {
// Dummy, just to make derivative hash functions compile.
int operator()(const char* key) {
GOOGLE_LOG(FATAL) << "Should never be called.";
return 0;
}
inline bool operator()(const char* a, const char* b) const {
return strcmp(a, b) < 0;
}
};
template <typename Key, typename Data,
typename HashFcn = hash<Key>,
typename EqualKey = int >
class hash_map : public std::map<Key, Data, HashFcn> {
};
template <typename Key,
typename HashFcn = hash<Key>,
typename EqualKey = int >
class hash_set : public std::set<Key, HashFcn> {
};
#elif defined(_MSC_VER) && !defined(_STLPORT_VERSION)
template <typename Key>
struct hash : public HASH_NAMESPACE::hash_compare<Key> {
};
// MSVC's hash_compare<const char*> hashes based on the string contents but
// compares based on the string pointer. WTF?
class CstringLess {
public:
inline bool operator()(const char* a, const char* b) const {
return strcmp(a, b) < 0;
}
};
template <>
struct hash<const char*>
: public HASH_NAMESPACE::hash_compare<const char*, CstringLess> {
};
template <typename Key, typename Data,
typename HashFcn = hash<Key>,
typename EqualKey = int >
class hash_map : public HASH_NAMESPACE::hash_map<
Key, Data, HashFcn> {
};
template <typename Key,
typename HashFcn = hash<Key>,
typename EqualKey = int >
class hash_set : public HASH_NAMESPACE::hash_set<
Key, HashFcn> {
};
#else
template <typename Key>
struct hash : public HASH_NAMESPACE::hash<Key> {
};
template <typename Key>
struct hash<const Key*> {
inline size_t operator()(const Key* key) const {
return reinterpret_cast<size_t>(key);
}
};
// Unlike the old SGI version, the TR1 "hash" does not special-case char*. So,
// we go ahead and provide our own implementation.
template <>
struct hash<const char*> {
inline size_t operator()(const char* str) const {
size_t result = 0;
for (; *str != '\0'; str++) {
result = 5 * result + *str;
}
return result;
}
};
template <typename Key, typename Data,
typename HashFcn = hash<Key>,
typename EqualKey = std::equal_to<Key> >
class hash_map : public HASH_NAMESPACE::HASH_MAP_CLASS<
Key, Data, HashFcn, EqualKey> {
};
template <typename Key,
typename HashFcn = hash<Key>,
typename EqualKey = std::equal_to<Key> >
class hash_set : public HASH_NAMESPACE::HASH_SET_CLASS<
Key, HashFcn, EqualKey> {
};
#endif
template <>
struct hash<string> {
inline size_t operator()(const string& key) const {
return hash<const char*>()(key.c_str());
}
static const size_t bucket_size = 4;
static const size_t min_buckets = 8;
inline size_t operator()(const string& a, const string& b) const {
return a < b;
}
};
template <typename First, typename Second>
struct hash<pair<First, Second> > {
inline size_t operator()(const pair<First, Second>& key) const {
size_t first_hash = hash<First>()(key.first);
size_t second_hash = hash<Second>()(key.second);
// FIXME(kenton): What is the best way to compute this hash? I have
// no idea! This seems a bit better than an XOR.
return first_hash * ((1 << 16) - 1) + second_hash;
}
static const size_t bucket_size = 4;
static const size_t min_buckets = 8;
inline size_t operator()(const pair<First, Second>& a,
const pair<First, Second>& b) const {
return a < b;
}
};
// Used by GCC/SGI STL only. (Why isn't this provided by the standard
// library? :( )
struct streq {
inline bool operator()(const char* a, const char* b) const {
return strcmp(a, b) == 0;
}
};
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_STUBS_HASH_H__

View File

@ -1,119 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// 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
// 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.
// from google3/util/gtl/map-util.h
// Author: Anton Carver
#ifndef GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__
#define GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
// Perform a lookup in a map or hash_map.
// If the key is present in the map then the value associated with that
// key is returned, otherwise the value passed as a default is returned.
template <class Collection>
const typename Collection::value_type::second_type&
FindWithDefault(const Collection& collection,
const typename Collection::value_type::first_type& key,
const typename Collection::value_type::second_type& value) {
typename Collection::const_iterator it = collection.find(key);
if (it == collection.end()) {
return value;
}
return it->second;
}
// Perform a lookup in a map or hash_map.
// If the key is present a const pointer to the associated value is returned,
// otherwise a NULL pointer is returned.
template <class Collection>
const typename Collection::value_type::second_type*
FindOrNull(const Collection& collection,
const typename Collection::value_type::first_type& key) {
typename Collection::const_iterator it = collection.find(key);
if (it == collection.end()) {
return 0;
}
return &it->second;
}
// Perform a lookup in a map or hash_map whose values are pointers.
// If the key is present a const pointer to the associated value is returned,
// otherwise a NULL pointer is returned.
// This function does not distinguish between a missing key and a key mapped
// to a NULL value.
template <class Collection>
const typename Collection::value_type::second_type
FindPtrOrNull(const Collection& collection,
const typename Collection::value_type::first_type& key) {
typename Collection::const_iterator it = collection.find(key);
if (it == collection.end()) {
return 0;
}
return it->second;
}
// Change the value associated with a particular key in a map or hash_map.
// If the key is not present in the map the key and value are inserted,
// otherwise the value is updated to be a copy of the value provided.
// True indicates that an insert took place, false indicates an update.
template <class Collection, class Key, class Value>
bool InsertOrUpdate(Collection * const collection,
const Key& key, const Value& value) {
pair<typename Collection::iterator, bool> ret =
collection->insert(typename Collection::value_type(key, value));
if (!ret.second) {
// update
ret.first->second = value;
return false;
}
return true;
}
// Insert a new key and value into a map or hash_map.
// If the key is not present in the map the key and value are
// inserted, otherwise nothing happens. True indicates that an insert
// took place, false indicates the key was already present.
template <class Collection, class Key, class Value>
bool InsertIfNotPresent(Collection * const collection,
const Key& key, const Value& value) {
pair<typename Collection::iterator, bool> ret =
collection->insert(typename Collection::value_type(key, value));
return ret.second;
}
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__

View File

@ -1,88 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// 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
// 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.
// Author: kenton@google.com (Kenton Varda)
//
// emulates google3/base/once.h
//
// This header is intended to be included only by internal .cc files and
// generated .pb.cc files. Users should not use this directly.
#ifdef _WIN32
#include <windows.h>
#endif
#include <google/protobuf/stubs/once.h>
namespace google {
namespace protobuf {
#ifdef _WIN32
struct ProtobufOnceInternal {
ProtobufOnceInternal() {
InitializeCriticalSection(&critical_section);
}
~ProtobufOnceInternal() {
DeleteCriticalSection(&critical_section);
}
CRITICAL_SECTION critical_section;
};
ProtobufOnceType::~ProtobufOnceType()
{
delete internal_;
internal_ = NULL;
}
ProtobufOnceType::ProtobufOnceType() {
// internal_ may be non-NULL if Init() was already called.
if (internal_ == NULL) internal_ = new ProtobufOnceInternal;
}
void ProtobufOnceType::Init(void (*init_func)()) {
// internal_ may be NULL if we're still in dynamic initialization and the
// constructor has not been called yet. As mentioned in once.h, we assume
// that the program is still single-threaded at this time, and therefore it
// should be safe to initialize internal_ like so.
if (internal_ == NULL) internal_ = new ProtobufOnceInternal;
EnterCriticalSection(&internal_->critical_section);
if (!initialized_) {
init_func();
initialized_ = true;
}
LeaveCriticalSection(&internal_->critical_section);
}
#endif
} // namespace protobuf
} // namespace google

View File

@ -1,123 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// 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
// 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.
// Author: kenton@google.com (Kenton Varda)
//
// emulates google3/base/once.h
//
// This header is intended to be included only by internal .cc files and
// generated .pb.cc files. Users should not use this directly.
//
// This is basically a portable version of pthread_once().
//
// This header declares three things:
// * A type called ProtobufOnceType.
// * A macro GOOGLE_PROTOBUF_DECLARE_ONCE() which declares a variable of type
// ProtobufOnceType. This is the only legal way to declare such a variable.
// The macro may only be used at the global scope (you cannot create local
// or class member variables of this type).
// * A function GogoleOnceInit(ProtobufOnceType* once, void (*init_func)()).
// This function, when invoked multiple times given the same ProtobufOnceType
// object, will invoke init_func on the first call only, and will make sure
// none of the calls return before that first call to init_func has finished.
//
// This implements a way to perform lazy initialization. It's more efficient
// than using mutexes as no lock is needed if initialization has already
// happened.
//
// Example usage:
// void Init();
// GOOGLE_PROTOBUF_DECLARE_ONCE(once_init);
//
// // Calls Init() exactly once.
// void InitOnce() {
// GoogleOnceInit(&once_init, &Init);
// }
//
// Note that if GoogleOnceInit() is called before main() has begun, it must
// only be called by the thread that will eventually call main() -- that is,
// the thread that performs dynamic initialization. In general this is a safe
// assumption since people don't usually construct threads before main() starts,
// but it is technically not guaranteed. Unfortunately, Win32 provides no way
// whatsoever to statically-initialize its synchronization primitives, so our
// only choice is to assume that dynamic initialization is single-threaded.
#ifndef GOOGLE_PROTOBUF_STUBS_ONCE_H__
#define GOOGLE_PROTOBUF_STUBS_ONCE_H__
#include <google/protobuf/stubs/common.h>
#ifndef _WIN32
#include <pthread.h>
#endif
namespace google {
namespace protobuf {
#ifdef _WIN32
struct ProtobufOnceInternal;
struct LIBPROTOBUF_EXPORT ProtobufOnceType {
ProtobufOnceType();
~ProtobufOnceType();
void Init(void (*init_func)());
volatile bool initialized_;
ProtobufOnceInternal* internal_;
};
#define GOOGLE_PROTOBUF_DECLARE_ONCE(NAME) \
::google::protobuf::ProtobufOnceType NAME
inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) {
// Note: Double-checked locking is safe on x86.
if (!once->initialized_) {
once->Init(init_func);
}
}
#else
typedef pthread_once_t ProtobufOnceType;
#define GOOGLE_PROTOBUF_DECLARE_ONCE(NAME) \
pthread_once_t NAME = PTHREAD_ONCE_INIT
inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) {
pthread_once(once, init_func);
}
#endif
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_STUBS_ONCE_H__

View File

@ -1,121 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// 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
// 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.
// from google3/util/gtl/stl_util-inl.h
#ifndef GOOGLE_PROTOBUF_STUBS_STL_UTIL_INL_H__
#define GOOGLE_PROTOBUF_STUBS_STL_UTIL_INL_H__
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
// STLDeleteContainerPointers()
// For a range within a container of pointers, calls delete
// (non-array version) on these pointers.
// NOTE: for these three functions, we could just implement a DeleteObject
// functor and then call for_each() on the range and functor, but this
// requires us to pull in all of algorithm.h, which seems expensive.
// For hash_[multi]set, it is important that this deletes behind the iterator
// because the hash_set may call the hash function on the iterator when it is
// advanced, which could result in the hash function trying to deference a
// stale pointer.
template <class ForwardIterator>
void STLDeleteContainerPointers(ForwardIterator begin,
ForwardIterator end) {
while (begin != end) {
ForwardIterator temp = begin;
++begin;
delete *temp;
}
}
// Inside Google, this function implements a horrible, disgusting hack in which
// we reach into the string's private implementation and resize it without
// initializing the new bytes. In some cases doing this can significantly
// improve performance. However, since it's totally non-portable it has no
// place in open source code. Feel free to fill this function in with your
// own disgusting hack if you want the perf boost.
inline void STLStringResizeUninitialized(string* s, size_t new_size) {
s->resize(new_size);
}
// Return a mutable char* pointing to a string's internal buffer,
// which may not be null-terminated. Writing through this pointer will
// modify the string.
//
// string_as_array(&str)[i] is valid for 0 <= i < str.size() until the
// next call to a string method that invalidates iterators.
//
// As of 2006-04, there is no standard-blessed way of getting a
// mutable reference to a string's internal buffer. However, issue 530
// (http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#530)
// proposes this as the method. According to Matt Austern, this should
// already work on all current implementations.
inline char* string_as_array(string* str) {
// DO NOT USE const_cast<char*>(str->data())! See the unittest for why.
return str->empty() ? NULL : &*str->begin();
}
// STLDeleteElements() deletes all the elements in an STL container and clears
// the container. This function is suitable for use with a vector, set,
// hash_set, or any other STL container which defines sensible begin(), end(),
// and clear() methods.
//
// If container is NULL, this function is a no-op.
//
// As an alternative to calling STLDeleteElements() directly, consider
// ElementDeleter (defined below), which ensures that your container's elements
// are deleted when the ElementDeleter goes out of scope.
template <class T>
void STLDeleteElements(T *container) {
if (!container) return;
STLDeleteContainerPointers(container->begin(), container->end());
container->clear();
}
// Given an STL container consisting of (key, value) pairs, STLDeleteValues
// deletes all the "value" components and clears the container. Does nothing
// in the case it's given a NULL pointer.
template <class T>
void STLDeleteValues(T *v) {
if (!v) return;
for (typename T::iterator i = v->begin(); i != v->end(); ++i) {
delete i->second;
}
v->clear();
}
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_STUBS_STL_UTIL_INL_H__

View File

@ -1,359 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// 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
// 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.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/wire_format_lite_inl.h>
#include <stack>
#include <string>
#include <vector>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/io/coded_stream_inl.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
namespace google {
namespace protobuf {
namespace internal {
#ifndef _MSC_VER // MSVC doesn't like definitions of inline constants, GCC
// requires them.
const int WireFormatLite::kMessageSetItemStartTag;
const int WireFormatLite::kMessageSetItemEndTag;
const int WireFormatLite::kMessageSetTypeIdTag;
const int WireFormatLite::kMessageSetMessageTag;
#endif
const int WireFormatLite::kMessageSetItemTagsSize =
io::CodedOutputStream::VarintSize32(kMessageSetItemStartTag) +
io::CodedOutputStream::VarintSize32(kMessageSetItemEndTag) +
io::CodedOutputStream::VarintSize32(kMessageSetTypeIdTag) +
io::CodedOutputStream::VarintSize32(kMessageSetMessageTag);
const WireFormatLite::CppType
WireFormatLite::kFieldTypeToCppTypeMap[MAX_FIELD_TYPE + 1] = {
static_cast<CppType>(0), // 0 is reserved for errors
CPPTYPE_DOUBLE, // TYPE_DOUBLE
CPPTYPE_FLOAT, // TYPE_FLOAT
CPPTYPE_INT64, // TYPE_INT64
CPPTYPE_UINT64, // TYPE_UINT64
CPPTYPE_INT32, // TYPE_INT32
CPPTYPE_UINT64, // TYPE_FIXED64
CPPTYPE_UINT32, // TYPE_FIXED32
CPPTYPE_BOOL, // TYPE_BOOL
CPPTYPE_STRING, // TYPE_STRING
CPPTYPE_MESSAGE, // TYPE_GROUP
CPPTYPE_MESSAGE, // TYPE_MESSAGE
CPPTYPE_STRING, // TYPE_BYTES
CPPTYPE_UINT32, // TYPE_UINT32
CPPTYPE_ENUM, // TYPE_ENUM
CPPTYPE_INT32, // TYPE_SFIXED32
CPPTYPE_INT64, // TYPE_SFIXED64
CPPTYPE_INT32, // TYPE_SINT32
CPPTYPE_INT64, // TYPE_SINT64
};
const WireFormatLite::WireType
WireFormatLite::kWireTypeForFieldType[MAX_FIELD_TYPE + 1] = {
static_cast<WireFormatLite::WireType>(-1), // invalid
WireFormatLite::WIRETYPE_FIXED64, // TYPE_DOUBLE
WireFormatLite::WIRETYPE_FIXED32, // TYPE_FLOAT
WireFormatLite::WIRETYPE_VARINT, // TYPE_INT64
WireFormatLite::WIRETYPE_VARINT, // TYPE_UINT64
WireFormatLite::WIRETYPE_VARINT, // TYPE_INT32
WireFormatLite::WIRETYPE_FIXED64, // TYPE_FIXED64
WireFormatLite::WIRETYPE_FIXED32, // TYPE_FIXED32
WireFormatLite::WIRETYPE_VARINT, // TYPE_BOOL
WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_STRING
WireFormatLite::WIRETYPE_START_GROUP, // TYPE_GROUP
WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_MESSAGE
WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_BYTES
WireFormatLite::WIRETYPE_VARINT, // TYPE_UINT32
WireFormatLite::WIRETYPE_VARINT, // TYPE_ENUM
WireFormatLite::WIRETYPE_FIXED32, // TYPE_SFIXED32
WireFormatLite::WIRETYPE_FIXED64, // TYPE_SFIXED64
WireFormatLite::WIRETYPE_VARINT, // TYPE_SINT32
WireFormatLite::WIRETYPE_VARINT, // TYPE_SINT64
};
bool WireFormatLite::SkipField(
io::CodedInputStream* input, uint32 tag) {
switch (WireFormatLite::GetTagWireType(tag)) {
case WireFormatLite::WIRETYPE_VARINT: {
uint64 value;
if (!input->ReadVarint64(&value)) return false;
return true;
}
case WireFormatLite::WIRETYPE_FIXED64: {
uint64 value;
if (!input->ReadLittleEndian64(&value)) return false;
return true;
}
case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
uint32 length;
if (!input->ReadVarint32(&length)) return false;
if (!input->Skip(length)) return false;
return true;
}
case WireFormatLite::WIRETYPE_START_GROUP: {
if (!input->IncrementRecursionDepth()) return false;
if (!SkipMessage(input)) return false;
input->DecrementRecursionDepth();
// Check that the ending tag matched the starting tag.
if (!input->LastTagWas(WireFormatLite::MakeTag(
WireFormatLite::GetTagFieldNumber(tag),
WireFormatLite::WIRETYPE_END_GROUP))) {
return false;
}
return true;
}
case WireFormatLite::WIRETYPE_END_GROUP: {
return false;
}
case WireFormatLite::WIRETYPE_FIXED32: {
uint32 value;
if (!input->ReadLittleEndian32(&value)) return false;
return true;
}
default: {
return false;
}
}
}
bool WireFormatLite::SkipMessage(io::CodedInputStream* input) {
while(true) {
uint32 tag = input->ReadTag();
if (tag == 0) {
// End of input. This is a valid place to end, so return true.
return true;
}
WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
// Must be the end of the message.
return true;
}
if (!SkipField(input, tag)) return false;
}
}
bool FieldSkipper::SkipField(
io::CodedInputStream* input, uint32 tag) {
return WireFormatLite::SkipField(input, tag);
}
bool FieldSkipper::SkipMessage(io::CodedInputStream* input) {
return WireFormatLite::SkipMessage(input);
}
void FieldSkipper::SkipUnknownEnum(
int field_number, int value) {
// Nothing.
}
bool WireFormatLite::ReadPackedEnumNoInline(io::CodedInputStream* input,
bool (*is_valid)(int),
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(value)) {
values->Add(value);
}
}
input->PopLimit(limit);
return true;
}
void WireFormatLite::WriteInt32(int field_number, int32 value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_VARINT, output);
WriteInt32NoTag(value, output);
}
void WireFormatLite::WriteInt64(int field_number, int64 value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_VARINT, output);
WriteInt64NoTag(value, output);
}
void WireFormatLite::WriteUInt32(int field_number, uint32 value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_VARINT, output);
WriteUInt32NoTag(value, output);
}
void WireFormatLite::WriteUInt64(int field_number, uint64 value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_VARINT, output);
WriteUInt64NoTag(value, output);
}
void WireFormatLite::WriteSInt32(int field_number, int32 value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_VARINT, output);
WriteSInt32NoTag(value, output);
}
void WireFormatLite::WriteSInt64(int field_number, int64 value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_VARINT, output);
WriteSInt64NoTag(value, output);
}
void WireFormatLite::WriteFixed32(int field_number, uint32 value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_FIXED32, output);
WriteFixed32NoTag(value, output);
}
void WireFormatLite::WriteFixed64(int field_number, uint64 value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_FIXED64, output);
WriteFixed64NoTag(value, output);
}
void WireFormatLite::WriteSFixed32(int field_number, int32 value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_FIXED32, output);
WriteSFixed32NoTag(value, output);
}
void WireFormatLite::WriteSFixed64(int field_number, int64 value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_FIXED64, output);
WriteSFixed64NoTag(value, output);
}
void WireFormatLite::WriteFloat(int field_number, float value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_FIXED32, output);
WriteFloatNoTag(value, output);
}
void WireFormatLite::WriteDouble(int field_number, double value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_FIXED64, output);
WriteDoubleNoTag(value, output);
}
void WireFormatLite::WriteBool(int field_number, bool value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_VARINT, output);
WriteBoolNoTag(value, output);
}
void WireFormatLite::WriteEnum(int field_number, int value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_VARINT, output);
WriteEnumNoTag(value, output);
}
void WireFormatLite::WriteString(int field_number, const string& value,
io::CodedOutputStream* output) {
// String is for UTF-8 text only
WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
output->WriteVarint32(value.size());
output->WriteString(value);
}
void WireFormatLite::WriteBytes(int field_number, const string& value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
output->WriteVarint32(value.size());
output->WriteString(value);
}
void WireFormatLite::WriteGroup(int field_number,
const MessageLite& value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_START_GROUP, output);
value.SerializeWithCachedSizes(output);
WriteTag(field_number, WIRETYPE_END_GROUP, output);
}
void WireFormatLite::WriteMessage(int field_number,
const MessageLite& value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
const int size = value.GetCachedSize();
output->WriteVarint32(size);
value.SerializeWithCachedSizes(output);
}
void WireFormatLite::WriteGroupMaybeToArray(int field_number,
const MessageLite& value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_START_GROUP, output);
const int size = value.GetCachedSize();
uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
if (target != NULL) {
uint8* end = value.SerializeWithCachedSizesToArray(target);
GOOGLE_DCHECK_EQ(end - target, size);
} else {
value.SerializeWithCachedSizes(output);
}
WriteTag(field_number, WIRETYPE_END_GROUP, output);
}
void WireFormatLite::WriteMessageMaybeToArray(int field_number,
const MessageLite& value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
const int size = value.GetCachedSize();
output->WriteVarint32(size);
uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
if (target != NULL) {
uint8* end = value.SerializeWithCachedSizesToArray(target);
GOOGLE_DCHECK_EQ(end - target, size);
} else {
value.SerializeWithCachedSizes(output);
}
}
bool WireFormatLite::ReadString(io::CodedInputStream* input,
string* value) {
// String is for UTF-8 text only
uint32 length;
if (!input->ReadVarint32(&length)) return false;
if (!input->InternalReadStringInline(value, length)) return false;
return true;
}
bool WireFormatLite::ReadBytes(io::CodedInputStream* input,
string* value) {
uint32 length;
if (!input->ReadVarint32(&length)) return false;
return input->InternalReadStringInline(value, length);
}
} // namespace internal
} // namespace protobuf
} // namespace google

View File

@ -1,620 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// 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
// 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.
// Author: kenton@google.com (Kenton Varda)
// atenasio@google.com (Chris Atenasio) (ZigZag transform)
// wink@google.com (Wink Saville) (refactored from wire_format.h)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// This header is logically internal, but is made public because it is used
// from protocol-compiler-generated code, which may reside in other components.
#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__
#define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__
#include <string>
#include <google/protobuf/message_lite.h>
namespace google {
namespace protobuf {
template <typename T> class RepeatedField; // repeated_field.h
namespace io {
class CodedInputStream; // coded_stream.h
class CodedOutputStream; // coded_stream.h
}
}
namespace protobuf {
namespace internal {
class StringPieceField;
// This class is for internal use by the protocol buffer library and by
// protocol-complier-generated message classes. It must not be called
// directly by clients.
//
// This class contains helpers for implementing the binary protocol buffer
// wire format without the need for reflection. Use WireFormat when using
// reflection.
//
// This class is really a namespace that contains only static methods.
class LIBPROTOBUF_EXPORT WireFormatLite {
public:
// -----------------------------------------------------------------
// Helper constants and functions related to the format. These are
// mostly meant for internal and generated code to use.
// The wire format is composed of a sequence of tag/value pairs, each
// of which contains the value of one field (or one element of a repeated
// field). Each tag is encoded as a varint. The lower bits of the tag
// identify its wire type, which specifies the format of the data to follow.
// The rest of the bits contain the field number. Each type of field (as
// declared by FieldDescriptor::Type, in descriptor.h) maps to one of
// these wire types. Immediately following each tag is the field's value,
// encoded in the format specified by the wire type. Because the tag
// identifies the encoding of this data, it is possible to skip
// unrecognized fields for forwards compatibility.
enum WireType {
WIRETYPE_VARINT = 0,
WIRETYPE_FIXED64 = 1,
WIRETYPE_LENGTH_DELIMITED = 2,
WIRETYPE_START_GROUP = 3,
WIRETYPE_END_GROUP = 4,
WIRETYPE_FIXED32 = 5,
};
// Lite alternative to FieldDescriptor::Type. Must be kept in sync.
enum FieldType {
TYPE_DOUBLE = 1,
TYPE_FLOAT = 2,
TYPE_INT64 = 3,
TYPE_UINT64 = 4,
TYPE_INT32 = 5,
TYPE_FIXED64 = 6,
TYPE_FIXED32 = 7,
TYPE_BOOL = 8,
TYPE_STRING = 9,
TYPE_GROUP = 10,
TYPE_MESSAGE = 11,
TYPE_BYTES = 12,
TYPE_UINT32 = 13,
TYPE_ENUM = 14,
TYPE_SFIXED32 = 15,
TYPE_SFIXED64 = 16,
TYPE_SINT32 = 17,
TYPE_SINT64 = 18,
MAX_FIELD_TYPE = 18,
};
// Lite alternative to FieldDescriptor::CppType. Must be kept in sync.
enum CppType {
CPPTYPE_INT32 = 1,
CPPTYPE_INT64 = 2,
CPPTYPE_UINT32 = 3,
CPPTYPE_UINT64 = 4,
CPPTYPE_DOUBLE = 5,
CPPTYPE_FLOAT = 6,
CPPTYPE_BOOL = 7,
CPPTYPE_ENUM = 8,
CPPTYPE_STRING = 9,
CPPTYPE_MESSAGE = 10,
MAX_CPPTYPE = 10,
};
// Helper method to get the CppType for a particular Type.
static CppType FieldTypeToCppType(FieldType type);
// Given a FieldSescriptor::Type return its WireType
static inline WireFormatLite::WireType WireTypeForFieldType(
WireFormatLite::FieldType type) {
return kWireTypeForFieldType[type];
}
// Number of bits in a tag which identify the wire type.
static const int kTagTypeBits = 3;
// Mask for those bits.
static const uint32 kTagTypeMask = (1 << kTagTypeBits) - 1;
// Helper functions for encoding and decoding tags. (Inlined below and in
// _inl.h)
//
// This is different from MakeTag(field->number(), field->type()) in the case
// of packed repeated fields.
static uint32 MakeTag(int field_number, WireType type);
static WireType GetTagWireType(uint32 tag);
static int GetTagFieldNumber(uint32 tag);
// Compute the byte size of a tag. For groups, this includes both the start
// and end tags.
static inline int TagSize(int field_number, WireFormatLite::FieldType type);
// Skips a field value with the given tag. The input should start
// positioned immediately after the tag. Skipped values are simply discarded,
// not recorded anywhere. See WireFormat::SkipField() for a version that
// records to an UnknownFieldSet.
static bool SkipField(io::CodedInputStream* input, uint32 tag);
// Reads and ignores a message from the input. Skipped values are simply
// discarded, not recorded anywhere. See WireFormat::SkipMessage() for a
// version that records to an UnknownFieldSet.
static bool SkipMessage(io::CodedInputStream* input);
// This macro does the same thing as WireFormatLite::MakeTag(), but the
// result is usable as a compile-time constant, which makes it usable
// as a switch case or a template input. WireFormatLite::MakeTag() is more
// type-safe, though, so prefer it if possible.
#define GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(FIELD_NUMBER, TYPE) \
static_cast<uint32>( \
((FIELD_NUMBER) << ::google::protobuf::internal::WireFormatLite::kTagTypeBits) \
| (TYPE))
// These are the tags for the old MessageSet format, which was defined as:
// message MessageSet {
// repeated group Item = 1 {
// required int32 type_id = 2;
// required string message = 3;
// }
// }
static const int kMessageSetItemNumber = 1;
static const int kMessageSetTypeIdNumber = 2;
static const int kMessageSetMessageNumber = 3;
static const int kMessageSetItemStartTag =
GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetItemNumber,
WireFormatLite::WIRETYPE_START_GROUP);
static const int kMessageSetItemEndTag =
GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetItemNumber,
WireFormatLite::WIRETYPE_END_GROUP);
static const int kMessageSetTypeIdTag =
GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetTypeIdNumber,
WireFormatLite::WIRETYPE_VARINT);
static const int kMessageSetMessageTag =
GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetMessageNumber,
WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
// Byte size of all tags of a MessageSet::Item combined.
static const int kMessageSetItemTagsSize;
// Helper functions for converting between floats/doubles and IEEE-754
// uint32s/uint64s so that they can be written. (Assumes your platform
// uses IEEE-754 floats.)
static uint32 EncodeFloat(float value);
static float DecodeFloat(uint32 value);
static uint64 EncodeDouble(double value);
static double DecodeDouble(uint64 value);
// Helper functions for mapping signed integers to unsigned integers in
// such a way that numbers with small magnitudes will encode to smaller
// varints. If you simply static_cast a negative number to an unsigned
// number and varint-encode it, it will always take 10 bytes, defeating
// the purpose of varint. So, for the "sint32" and "sint64" field types,
// we ZigZag-encode the values.
static uint32 ZigZagEncode32(int32 n);
static int32 ZigZagDecode32(uint32 n);
static uint64 ZigZagEncode64(int64 n);
static int64 ZigZagDecode64(uint64 n);
// =================================================================
// Methods for reading/writing individual field. The implementations
// of these methods are defined in wire_format_lite_inl.h; you must #include
// that file to use these.
// Avoid ugly line wrapping
#define input io::CodedInputStream* input
#define output io::CodedOutputStream* output
#define field_number int field_number
#define INL GOOGLE_ATTRIBUTE_ALWAYS_INLINE
// Read fields, not including tags. The assumption is that you already
// read the tag to determine what field to read.
// For primitive fields, we just use a templatized routine parameterized by
// the represented type and the FieldType. These are specialized with the
// appropriate definition for each declared type.
template <typename CType, enum FieldType DeclaredType>
static inline bool ReadPrimitive(input, CType* value) INL;
// Reads repeated primitive values, with optimizations for repeats.
// tag_size and tag should both be compile-time constants provided by the
// protocol compiler.
template <typename CType, enum FieldType DeclaredType>
static inline bool ReadRepeatedPrimitive(int tag_size,
uint32 tag,
input,
RepeatedField<CType>* value) INL;
// Identical to ReadRepeatedPrimitive, except will not inline the
// implementation.
template <typename CType, enum FieldType DeclaredType>
static bool ReadRepeatedPrimitiveNoInline(int tag_size,
uint32 tag,
input,
RepeatedField<CType>* value);
// Reads a primitive value directly from the provided buffer. It returns a
// pointer past the segment of data that was read.
//
// This is only implemented for the types with fixed wire size, e.g.
// float, double, and the (s)fixed* types.
template <typename CType, enum FieldType DeclaredType>
static inline const uint8* ReadPrimitiveFromArray(const uint8* buffer,
CType* value) INL;
// Reads a primitive packed field.
//
// This is only implemented for packable types.
template <typename CType, enum FieldType DeclaredType>
static inline bool ReadPackedPrimitive(input,
RepeatedField<CType>* value) INL;
// Identical to ReadPackedPrimitive, except will not inline the
// implementation.
template <typename CType, enum FieldType DeclaredType>
static bool ReadPackedPrimitiveNoInline(input, RepeatedField<CType>* value);
// Read a packed enum field. Values for which is_valid() returns false are
// dropped.
static bool ReadPackedEnumNoInline(input,
bool (*is_valid)(int),
RepeatedField<int>* value);
static bool ReadString(input, string* value);
static bool ReadBytes (input, string* value);
static inline bool ReadGroup (field_number, input, MessageLite* value);
static inline bool ReadMessage(input, MessageLite* value);
// Like above, but de-virtualize the call to MergePartialFromCodedStream().
// The pointer must point at an instance of MessageType, *not* a subclass (or
// the subclass must not override MergePartialFromCodedStream()).
template<typename MessageType>
static inline bool ReadGroupNoVirtual(field_number, input,
MessageType* value);
template<typename MessageType>
static inline bool ReadMessageNoVirtual(input, MessageType* value);
// Write a tag. The Write*() functions typically include the tag, so
// normally there's no need to call this unless using the Write*NoTag()
// variants.
static inline void WriteTag(field_number, WireType type, output) INL;
// Write fields, without tags.
static inline void WriteInt32NoTag (int32 value, output) INL;
static inline void WriteInt64NoTag (int64 value, output) INL;
static inline void WriteUInt32NoTag (uint32 value, output) INL;
static inline void WriteUInt64NoTag (uint64 value, output) INL;
static inline void WriteSInt32NoTag (int32 value, output) INL;
static inline void WriteSInt64NoTag (int64 value, output) INL;
static inline void WriteFixed32NoTag (uint32 value, output) INL;
static inline void WriteFixed64NoTag (uint64 value, output) INL;
static inline void WriteSFixed32NoTag(int32 value, output) INL;
static inline void WriteSFixed64NoTag(int64 value, output) INL;
static inline void WriteFloatNoTag (float value, output) INL;
static inline void WriteDoubleNoTag (double value, output) INL;
static inline void WriteBoolNoTag (bool value, output) INL;
static inline void WriteEnumNoTag (int value, output) INL;
// Write fields, including tags.
static void WriteInt32 (field_number, int32 value, output);
static void WriteInt64 (field_number, int64 value, output);
static void WriteUInt32 (field_number, uint32 value, output);
static void WriteUInt64 (field_number, uint64 value, output);
static void WriteSInt32 (field_number, int32 value, output);
static void WriteSInt64 (field_number, int64 value, output);
static void WriteFixed32 (field_number, uint32 value, output);
static void WriteFixed64 (field_number, uint64 value, output);
static void WriteSFixed32(field_number, int32 value, output);
static void WriteSFixed64(field_number, int64 value, output);
static void WriteFloat (field_number, float value, output);
static void WriteDouble (field_number, double value, output);
static void WriteBool (field_number, bool value, output);
static void WriteEnum (field_number, int value, output);
static void WriteString(field_number, const string& value, output);
static void WriteBytes (field_number, const string& value, output);
static void WriteGroup(
field_number, const MessageLite& value, output);
static void WriteMessage(
field_number, const MessageLite& value, output);
// Like above, but these will check if the output stream has enough
// space to write directly to a flat array.
static void WriteGroupMaybeToArray(
field_number, const MessageLite& value, output);
static void WriteMessageMaybeToArray(
field_number, const MessageLite& value, output);
// Like above, but de-virtualize the call to SerializeWithCachedSizes(). The
// pointer must point at an instance of MessageType, *not* a subclass (or
// the subclass must not override SerializeWithCachedSizes()).
template<typename MessageType>
static inline void WriteGroupNoVirtual(
field_number, const MessageType& value, output);
template<typename MessageType>
static inline void WriteMessageNoVirtual(
field_number, const MessageType& value, output);
#undef output
#define output uint8* target
// Like above, but use only *ToArray methods of CodedOutputStream.
static inline uint8* WriteTagToArray(field_number, WireType type, output) INL;
// Write fields, without tags.
static inline uint8* WriteInt32NoTagToArray (int32 value, output) INL;
static inline uint8* WriteInt64NoTagToArray (int64 value, output) INL;
static inline uint8* WriteUInt32NoTagToArray (uint32 value, output) INL;
static inline uint8* WriteUInt64NoTagToArray (uint64 value, output) INL;
static inline uint8* WriteSInt32NoTagToArray (int32 value, output) INL;
static inline uint8* WriteSInt64NoTagToArray (int64 value, output) INL;
static inline uint8* WriteFixed32NoTagToArray (uint32 value, output) INL;
static inline uint8* WriteFixed64NoTagToArray (uint64 value, output) INL;
static inline uint8* WriteSFixed32NoTagToArray(int32 value, output) INL;
static inline uint8* WriteSFixed64NoTagToArray(int64 value, output) INL;
static inline uint8* WriteFloatNoTagToArray (float value, output) INL;
static inline uint8* WriteDoubleNoTagToArray (double value, output) INL;
static inline uint8* WriteBoolNoTagToArray (bool value, output) INL;
static inline uint8* WriteEnumNoTagToArray (int value, output) INL;
// Write fields, including tags.
static inline uint8* WriteInt32ToArray(
field_number, int32 value, output) INL;
static inline uint8* WriteInt64ToArray(
field_number, int64 value, output) INL;
static inline uint8* WriteUInt32ToArray(
field_number, uint32 value, output) INL;
static inline uint8* WriteUInt64ToArray(
field_number, uint64 value, output) INL;
static inline uint8* WriteSInt32ToArray(
field_number, int32 value, output) INL;
static inline uint8* WriteSInt64ToArray(
field_number, int64 value, output) INL;
static inline uint8* WriteFixed32ToArray(
field_number, uint32 value, output) INL;
static inline uint8* WriteFixed64ToArray(
field_number, uint64 value, output) INL;
static inline uint8* WriteSFixed32ToArray(
field_number, int32 value, output) INL;
static inline uint8* WriteSFixed64ToArray(
field_number, int64 value, output) INL;
static inline uint8* WriteFloatToArray(
field_number, float value, output) INL;
static inline uint8* WriteDoubleToArray(
field_number, double value, output) INL;
static inline uint8* WriteBoolToArray(
field_number, bool value, output) INL;
static inline uint8* WriteEnumToArray(
field_number, int value, output) INL;
static inline uint8* WriteStringToArray(
field_number, const string& value, output) INL;
static inline uint8* WriteBytesToArray(
field_number, const string& value, output) INL;
static inline uint8* WriteGroupToArray(
field_number, const MessageLite& value, output) INL;
static inline uint8* WriteMessageToArray(
field_number, const MessageLite& value, output) INL;
// Like above, but de-virtualize the call to SerializeWithCachedSizes(). The
// pointer must point at an instance of MessageType, *not* a subclass (or
// the subclass must not override SerializeWithCachedSizes()).
template<typename MessageType>
static inline uint8* WriteGroupNoVirtualToArray(
field_number, const MessageType& value, output) INL;
template<typename MessageType>
static inline uint8* WriteMessageNoVirtualToArray(
field_number, const MessageType& value, output) INL;
#undef output
#undef input
#undef INL
#undef field_number
// Compute the byte size of a field. The XxSize() functions do NOT include
// the tag, so you must also call TagSize(). (This is because, for repeated
// fields, you should only call TagSize() once and multiply it by the element
// count, but you may have to call XxSize() for each individual element.)
static inline int Int32Size ( int32 value);
static inline int Int64Size ( int64 value);
static inline int UInt32Size (uint32 value);
static inline int UInt64Size (uint64 value);
static inline int SInt32Size ( int32 value);
static inline int SInt64Size ( int64 value);
static inline int EnumSize ( int value);
// These types always have the same size.
static const int kFixed32Size = 4;
static const int kFixed64Size = 8;
static const int kSFixed32Size = 4;
static const int kSFixed64Size = 8;
static const int kFloatSize = 4;
static const int kDoubleSize = 8;
static const int kBoolSize = 1;
static inline int StringSize(const string& value);
static inline int BytesSize (const string& value);
static inline int GroupSize (const MessageLite& value);
static inline int MessageSize(const MessageLite& value);
// Like above, but de-virtualize the call to ByteSize(). The
// pointer must point at an instance of MessageType, *not* a subclass (or
// the subclass must not override ByteSize()).
template<typename MessageType>
static inline int GroupSizeNoVirtual (const MessageType& value);
template<typename MessageType>
static inline int MessageSizeNoVirtual(const MessageType& value);
private:
// A helper method for the repeated primitive reader. This method has
// optimizations for primitive types that have fixed size on the wire, and
// can be read using potentially faster paths.
template <typename CType, enum FieldType DeclaredType>
static inline bool ReadRepeatedFixedSizePrimitive(
int tag_size,
uint32 tag,
google::protobuf::io::CodedInputStream* input,
RepeatedField<CType>* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
static const CppType kFieldTypeToCppTypeMap[];
static const WireFormatLite::WireType kWireTypeForFieldType[];
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormatLite);
};
// A class which deals with unknown values. The default implementation just
// discards them. WireFormat defines a subclass which writes to an
// UnknownFieldSet. This class is used by ExtensionSet::ParseField(), since
// ExtensionSet is part of the lite library but UnknownFieldSet is not.
class LIBPROTOBUF_EXPORT FieldSkipper {
public:
FieldSkipper() {}
virtual ~FieldSkipper() {}
// Skip a field whose tag has already been consumed.
virtual bool SkipField(io::CodedInputStream* input, uint32 tag);
// Skip an entire message or group, up to an end-group tag (which is consumed)
// or end-of-stream.
virtual bool SkipMessage(io::CodedInputStream* input);
// Deal with an already-parsed unrecognized enum value. The default
// implementation does nothing, but the UnknownFieldSet-based implementation
// saves it as an unknown varint.
virtual void SkipUnknownEnum(int field_number, int value);
};
// inline methods ====================================================
inline WireFormatLite::CppType
WireFormatLite::FieldTypeToCppType(FieldType type) {
return kFieldTypeToCppTypeMap[type];
}
inline uint32 WireFormatLite::MakeTag(int field_number, WireType type) {
return GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(field_number, type);
}
inline WireFormatLite::WireType WireFormatLite::GetTagWireType(uint32 tag) {
return static_cast<WireType>(tag & kTagTypeMask);
}
inline int WireFormatLite::GetTagFieldNumber(uint32 tag) {
return static_cast<int>(tag >> kTagTypeBits);
}
inline int WireFormatLite::TagSize(int field_number,
WireFormatLite::FieldType type) {
int result = io::CodedOutputStream::VarintSize32(
field_number << kTagTypeBits);
if (type == TYPE_GROUP) {
// Groups have both a start and an end tag.
return result * 2;
} else {
return result;
}
}
inline uint32 WireFormatLite::EncodeFloat(float value) {
union {float f; uint32 i;};
f = value;
return i;
}
inline float WireFormatLite::DecodeFloat(uint32 value) {
union {float f; uint32 i;};
i = value;
return f;
}
inline uint64 WireFormatLite::EncodeDouble(double value) {
union {double f; uint64 i;};
f = value;
return i;
}
inline double WireFormatLite::DecodeDouble(uint64 value) {
union {double f; uint64 i;};
i = value;
return f;
}
// ZigZag Transform: Encodes signed integers so that they can be
// effectively used with varint encoding.
//
// varint operates on unsigned integers, encoding smaller numbers into
// fewer bytes. If you try to use it on a signed integer, it will treat
// this number as a very large unsigned integer, which means that even
// small signed numbers like -1 will take the maximum number of bytes
// (10) to encode. ZigZagEncode() maps signed integers to unsigned
// in such a way that those with a small absolute value will have smaller
// encoded values, making them appropriate for encoding using varint.
//
// int32 -> uint32
// -------------------------
// 0 -> 0
// -1 -> 1
// 1 -> 2
// -2 -> 3
// ... -> ...
// 2147483647 -> 4294967294
// -2147483648 -> 4294967295
//
// >> encode >>
// << decode <<
inline uint32 WireFormatLite::ZigZagEncode32(int32 n) {
// Note: the right-shift must be arithmetic
return (n << 1) ^ (n >> 31);
}
inline int32 WireFormatLite::ZigZagDecode32(uint32 n) {
return (n >> 1) ^ -static_cast<int32>(n & 1);
}
inline uint64 WireFormatLite::ZigZagEncode64(int64 n) {
// Note: the right-shift must be arithmetic
return (n << 1) ^ (n >> 63);
}
inline int64 WireFormatLite::ZigZagDecode64(uint64 n) {
return (n >> 1) ^ -static_cast<int64>(n & 1);
}
} // namespace internal
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__

View File

@ -1,774 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// 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
// 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.
// Author: kenton@google.com (Kenton Varda)
// wink@google.com (Wink Saville) (refactored from wire_format.h)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
#define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
#include <string>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/wire_format_lite.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/io/coded_stream.h>
namespace google {
namespace protobuf {
namespace internal {
// Implementation details of ReadPrimitive.
template <>
inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>(
io::CodedInputStream* input,
int32* value) {
uint32 temp;
if (!input->ReadVarint32(&temp)) return false;
*value = static_cast<int32>(temp);
return true;
}
template <>
inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_INT64>(
io::CodedInputStream* input,
int64* value) {
uint64 temp;
if (!input->ReadVarint64(&temp)) return false;
*value = static_cast<int64>(temp);
return true;
}
template <>
inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_UINT32>(
io::CodedInputStream* input,
uint32* value) {
return input->ReadVarint32(value);
}
template <>
inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_UINT64>(
io::CodedInputStream* input,
uint64* value) {
return input->ReadVarint64(value);
}
template <>
inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>(
io::CodedInputStream* input,
int32* value) {
uint32 temp;
if (!input->ReadVarint32(&temp)) return false;
*value = ZigZagDecode32(temp);
return true;
}
template <>
inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SINT64>(
io::CodedInputStream* input,
int64* value) {
uint64 temp;
if (!input->ReadVarint64(&temp)) return false;
*value = ZigZagDecode64(temp);
return true;
}
template <>
inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_FIXED32>(
io::CodedInputStream* input,
uint32* value) {
return input->ReadLittleEndian32(value);
}
template <>
inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_FIXED64>(
io::CodedInputStream* input,
uint64* value) {
return input->ReadLittleEndian64(value);
}
template <>
inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SFIXED32>(
io::CodedInputStream* input,
int32* value) {
uint32 temp;
if (!input->ReadLittleEndian32(&temp)) return false;
*value = static_cast<int32>(temp);
return true;
}
template <>
inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SFIXED64>(
io::CodedInputStream* input,
int64* value) {
uint64 temp;
if (!input->ReadLittleEndian64(&temp)) return false;
*value = static_cast<int64>(temp);
return true;
}
template <>
inline bool WireFormatLite::ReadPrimitive<float, WireFormatLite::TYPE_FLOAT>(
io::CodedInputStream* input,
float* value) {
uint32 temp;
if (!input->ReadLittleEndian32(&temp)) return false;
*value = DecodeFloat(temp);
return true;
}
template <>
inline bool WireFormatLite::ReadPrimitive<double, WireFormatLite::TYPE_DOUBLE>(
io::CodedInputStream* input,
double* value) {
uint64 temp;
if (!input->ReadLittleEndian64(&temp)) return false;
*value = DecodeDouble(temp);
return true;
}
template <>
inline bool WireFormatLite::ReadPrimitive<bool, WireFormatLite::TYPE_BOOL>(
io::CodedInputStream* input,
bool* value) {
uint32 temp;
if (!input->ReadVarint32(&temp)) return false;
*value = temp != 0;
return true;
}
template <>
inline bool WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
io::CodedInputStream* input,
int* value) {
uint32 temp;
if (!input->ReadVarint32(&temp)) return false;
*value = static_cast<int>(temp);
return true;
}
template <>
inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
uint32, WireFormatLite::TYPE_FIXED32>(
const uint8* buffer,
uint32* value) {
return io::CodedInputStream::ReadLittleEndian32FromArray(buffer, value);
}
template <>
inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
uint64, WireFormatLite::TYPE_FIXED64>(
const uint8* buffer,
uint64* value) {
return io::CodedInputStream::ReadLittleEndian64FromArray(buffer, value);
}
template <>
inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
int32, WireFormatLite::TYPE_SFIXED32>(
const uint8* buffer,
int32* value) {
uint32 temp;
buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp);
*value = static_cast<int32>(temp);
return buffer;
}
template <>
inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
int64, WireFormatLite::TYPE_SFIXED64>(
const uint8* buffer,
int64* value) {
uint64 temp;
buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp);
*value = static_cast<int64>(temp);
return buffer;
}
template <>
inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
float, WireFormatLite::TYPE_FLOAT>(
const uint8* buffer,
float* value) {
uint32 temp;
buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp);
*value = DecodeFloat(temp);
return buffer;
}
template <>
inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
double, WireFormatLite::TYPE_DOUBLE>(
const uint8* buffer,
double* value) {
uint64 temp;
buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp);
*value = DecodeDouble(temp);
return buffer;
}
template <typename CType, enum WireFormatLite::FieldType DeclaredType>
inline bool WireFormatLite::ReadRepeatedPrimitive(int, // tag_size, unused.
uint32 tag,
io::CodedInputStream* input,
RepeatedField<CType>* values) {
CType value;
if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
values->Add(value);
int elements_already_reserved = values->Capacity() - values->size();
while (elements_already_reserved > 0 && input->ExpectTag(tag)) {
if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
values->AddAlreadyReserved(value);
elements_already_reserved--;
}
return true;
}
template <typename CType, enum WireFormatLite::FieldType DeclaredType>
inline bool WireFormatLite::ReadRepeatedFixedSizePrimitive(
int tag_size,
uint32 tag,
io::CodedInputStream* input,
RepeatedField<CType>* values) {
GOOGLE_DCHECK_EQ(UInt32Size(tag), tag_size);
CType value;
if (!ReadPrimitive<CType, DeclaredType>(input, &value))
return false;
values->Add(value);
// For fixed size values, repeated values can be read more quickly by
// reading directly from a raw array.
//
// We can get a tight loop by only reading as many elements as can be
// added to the RepeatedField without having to do any resizing. Additionally,
// we only try to read as many elements as are available from the current
// buffer space. Doing so avoids having to perform boundary checks when
// reading the value: the maximum number of elements that can be read is
// known outside of the loop.
const void* void_pointer;
int size;
input->GetDirectBufferPointerInline(&void_pointer, &size);
if (size > 0) {
const uint8* buffer = reinterpret_cast<const uint8*>(void_pointer);
// The number of bytes each type occupies on the wire.
const int per_value_size = tag_size + sizeof(value);
int elements_available = min(values->Capacity() - values->size(),
size / per_value_size);
int num_read = 0;
while (num_read < elements_available &&
(buffer = io::CodedInputStream::ExpectTagFromArray(
buffer, tag)) != NULL) {
buffer = ReadPrimitiveFromArray<CType, DeclaredType>(buffer, &value);
values->AddAlreadyReserved(value);
++num_read;
}
const int read_bytes = num_read * per_value_size;
if (read_bytes > 0) {
input->Skip(read_bytes);
}
}
return true;
}
// Specializations of ReadRepeatedPrimitive for the fixed size types, which use
// the optimized code path.
#define READ_REPEATED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE) \
template <> \
inline bool WireFormatLite::ReadRepeatedPrimitive< \
CPPTYPE, WireFormatLite::DECLARED_TYPE>( \
int tag_size, \
uint32 tag, \
io::CodedInputStream* input, \
RepeatedField<CPPTYPE>* values) { \
return ReadRepeatedFixedSizePrimitive< \
CPPTYPE, WireFormatLite::DECLARED_TYPE>( \
tag_size, tag, input, values); \
}
READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32);
READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64);
READ_REPEATED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32);
READ_REPEATED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64);
READ_REPEATED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT);
READ_REPEATED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE);
#undef READ_REPEATED_FIXED_SIZE_PRIMITIVE
template <typename CType, enum WireFormatLite::FieldType DeclaredType>
bool WireFormatLite::ReadRepeatedPrimitiveNoInline(
int tag_size,
uint32 tag,
io::CodedInputStream* input,
RepeatedField<CType>* value) {
return ReadRepeatedPrimitive<CType, DeclaredType>(
tag_size, tag, input, value);
}
template <typename CType, enum WireFormatLite::FieldType DeclaredType>
inline bool WireFormatLite::ReadPackedPrimitive(io::CodedInputStream* input,
RepeatedField<CType>* values) {
uint32 length;
if (!input->ReadVarint32(&length)) return false;
io::CodedInputStream::Limit limit = input->PushLimit(length);
while (input->BytesUntilLimit() > 0) {
CType value;
if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
values->Add(value);
}
input->PopLimit(limit);
return true;
}
template <typename CType, enum WireFormatLite::FieldType DeclaredType>
bool WireFormatLite::ReadPackedPrimitiveNoInline(io::CodedInputStream* input,
RepeatedField<CType>* values) {
return ReadPackedPrimitive<CType, DeclaredType>(input, values);
}
inline bool WireFormatLite::ReadGroup(int field_number,
io::CodedInputStream* input,
MessageLite* value) {
if (!input->IncrementRecursionDepth()) return false;
if (!value->MergePartialFromCodedStream(input)) return false;
input->DecrementRecursionDepth();
// Make sure the last thing read was an end tag for this group.
if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) {
return false;
}
return true;
}
inline bool WireFormatLite::ReadMessage(io::CodedInputStream* input,
MessageLite* value) {
uint32 length;
if (!input->ReadVarint32(&length)) return false;
if (!input->IncrementRecursionDepth()) return false;
io::CodedInputStream::Limit limit = input->PushLimit(length);
if (!value->MergePartialFromCodedStream(input)) return false;
// Make sure that parsing stopped when the limit was hit, not at an endgroup
// tag.
if (!input->ConsumedEntireMessage()) return false;
input->PopLimit(limit);
input->DecrementRecursionDepth();
return true;
}
// We name the template parameter something long and extremely unlikely to occur
// elsewhere because a *qualified* member access expression designed to avoid
// virtual dispatch, C++03 [basic.lookup.classref] 3.4.5/4 requires that the
// name of the qualifying class to be looked up both in the context of the full
// expression (finding the template parameter) and in the context of the object
// whose member we are accessing. This could potentially find a nested type
// within that object. The standard goes on to require these names to refer to
// the same entity, which this collision would violate. The lack of a safe way
// to avoid this collision appears to be a defect in the standard, but until it
// is corrected, we choose the name to avoid accidental collisions.
template<typename MessageType_WorkAroundCppLookupDefect>
inline bool WireFormatLite::ReadGroupNoVirtual(
int field_number, io::CodedInputStream* input,
MessageType_WorkAroundCppLookupDefect* value) {
if (!input->IncrementRecursionDepth()) return false;
if (!value->
MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input))
return false;
input->DecrementRecursionDepth();
// Make sure the last thing read was an end tag for this group.
if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) {
return false;
}
return true;
}
template<typename MessageType_WorkAroundCppLookupDefect>
inline bool WireFormatLite::ReadMessageNoVirtual(
io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) {
uint32 length;
if (!input->ReadVarint32(&length)) return false;
if (!input->IncrementRecursionDepth()) return false;
io::CodedInputStream::Limit limit = input->PushLimit(length);
if (!value->
MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input))
return false;
// Make sure that parsing stopped when the limit was hit, not at an endgroup
// tag.
if (!input->ConsumedEntireMessage()) return false;
input->PopLimit(limit);
input->DecrementRecursionDepth();
return true;
}
// ===================================================================
inline void WireFormatLite::WriteTag(int field_number, WireType type,
io::CodedOutputStream* output) {
output->WriteTag(MakeTag(field_number, type));
}
inline void WireFormatLite::WriteInt32NoTag(int32 value,
io::CodedOutputStream* output) {
output->WriteVarint32SignExtended(value);
}
inline void WireFormatLite::WriteInt64NoTag(int64 value,
io::CodedOutputStream* output) {
output->WriteVarint64(static_cast<uint64>(value));
}
inline void WireFormatLite::WriteUInt32NoTag(uint32 value,
io::CodedOutputStream* output) {
output->WriteVarint32(value);
}
inline void WireFormatLite::WriteUInt64NoTag(uint64 value,
io::CodedOutputStream* output) {
output->WriteVarint64(value);
}
inline void WireFormatLite::WriteSInt32NoTag(int32 value,
io::CodedOutputStream* output) {
output->WriteVarint32(ZigZagEncode32(value));
}
inline void WireFormatLite::WriteSInt64NoTag(int64 value,
io::CodedOutputStream* output) {
output->WriteVarint64(ZigZagEncode64(value));
}
inline void WireFormatLite::WriteFixed32NoTag(uint32 value,
io::CodedOutputStream* output) {
output->WriteLittleEndian32(value);
}
inline void WireFormatLite::WriteFixed64NoTag(uint64 value,
io::CodedOutputStream* output) {
output->WriteLittleEndian64(value);
}
inline void WireFormatLite::WriteSFixed32NoTag(int32 value,
io::CodedOutputStream* output) {
output->WriteLittleEndian32(static_cast<uint32>(value));
}
inline void WireFormatLite::WriteSFixed64NoTag(int64 value,
io::CodedOutputStream* output) {
output->WriteLittleEndian64(static_cast<uint64>(value));
}
inline void WireFormatLite::WriteFloatNoTag(float value,
io::CodedOutputStream* output) {
output->WriteLittleEndian32(EncodeFloat(value));
}
inline void WireFormatLite::WriteDoubleNoTag(double value,
io::CodedOutputStream* output) {
output->WriteLittleEndian64(EncodeDouble(value));
}
inline void WireFormatLite::WriteBoolNoTag(bool value,
io::CodedOutputStream* output) {
output->WriteVarint32(value ? 1 : 0);
}
inline void WireFormatLite::WriteEnumNoTag(int value,
io::CodedOutputStream* output) {
output->WriteVarint32SignExtended(value);
}
// See comment on ReadGroupNoVirtual to understand the need for this template
// parameter name.
template<typename MessageType_WorkAroundCppLookupDefect>
inline void WireFormatLite::WriteGroupNoVirtual(
int field_number, const MessageType_WorkAroundCppLookupDefect& value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_START_GROUP, output);
value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output);
WriteTag(field_number, WIRETYPE_END_GROUP, output);
}
template<typename MessageType_WorkAroundCppLookupDefect>
inline void WireFormatLite::WriteMessageNoVirtual(
int field_number, const MessageType_WorkAroundCppLookupDefect& value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
output->WriteVarint32(
value.MessageType_WorkAroundCppLookupDefect::GetCachedSize());
value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output);
}
// ===================================================================
inline uint8* WireFormatLite::WriteTagToArray(int field_number,
WireType type,
uint8* target) {
return io::CodedOutputStream::WriteTagToArray(MakeTag(field_number, type),
target);
}
inline uint8* WireFormatLite::WriteInt32NoTagToArray(int32 value,
uint8* target) {
return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
}
inline uint8* WireFormatLite::WriteInt64NoTagToArray(int64 value,
uint8* target) {
return io::CodedOutputStream::WriteVarint64ToArray(
static_cast<uint64>(value), target);
}
inline uint8* WireFormatLite::WriteUInt32NoTagToArray(uint32 value,
uint8* target) {
return io::CodedOutputStream::WriteVarint32ToArray(value, target);
}
inline uint8* WireFormatLite::WriteUInt64NoTagToArray(uint64 value,
uint8* target) {
return io::CodedOutputStream::WriteVarint64ToArray(value, target);
}
inline uint8* WireFormatLite::WriteSInt32NoTagToArray(int32 value,
uint8* target) {
return io::CodedOutputStream::WriteVarint32ToArray(ZigZagEncode32(value),
target);
}
inline uint8* WireFormatLite::WriteSInt64NoTagToArray(int64 value,
uint8* target) {
return io::CodedOutputStream::WriteVarint64ToArray(ZigZagEncode64(value),
target);
}
inline uint8* WireFormatLite::WriteFixed32NoTagToArray(uint32 value,
uint8* target) {
return io::CodedOutputStream::WriteLittleEndian32ToArray(value, target);
}
inline uint8* WireFormatLite::WriteFixed64NoTagToArray(uint64 value,
uint8* target) {
return io::CodedOutputStream::WriteLittleEndian64ToArray(value, target);
}
inline uint8* WireFormatLite::WriteSFixed32NoTagToArray(int32 value,
uint8* target) {
return io::CodedOutputStream::WriteLittleEndian32ToArray(
static_cast<uint32>(value), target);
}
inline uint8* WireFormatLite::WriteSFixed64NoTagToArray(int64 value,
uint8* target) {
return io::CodedOutputStream::WriteLittleEndian64ToArray(
static_cast<uint64>(value), target);
}
inline uint8* WireFormatLite::WriteFloatNoTagToArray(float value,
uint8* target) {
return io::CodedOutputStream::WriteLittleEndian32ToArray(EncodeFloat(value),
target);
}
inline uint8* WireFormatLite::WriteDoubleNoTagToArray(double value,
uint8* target) {
return io::CodedOutputStream::WriteLittleEndian64ToArray(EncodeDouble(value),
target);
}
inline uint8* WireFormatLite::WriteBoolNoTagToArray(bool value,
uint8* target) {
return io::CodedOutputStream::WriteVarint32ToArray(value ? 1 : 0, target);
}
inline uint8* WireFormatLite::WriteEnumNoTagToArray(int value,
uint8* target) {
return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
}
inline uint8* WireFormatLite::WriteInt32ToArray(int field_number,
int32 value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
return WriteInt32NoTagToArray(value, target);
}
inline uint8* WireFormatLite::WriteInt64ToArray(int field_number,
int64 value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
return WriteInt64NoTagToArray(value, target);
}
inline uint8* WireFormatLite::WriteUInt32ToArray(int field_number,
uint32 value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
return WriteUInt32NoTagToArray(value, target);
}
inline uint8* WireFormatLite::WriteUInt64ToArray(int field_number,
uint64 value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
return WriteUInt64NoTagToArray(value, target);
}
inline uint8* WireFormatLite::WriteSInt32ToArray(int field_number,
int32 value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
return WriteSInt32NoTagToArray(value, target);
}
inline uint8* WireFormatLite::WriteSInt64ToArray(int field_number,
int64 value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
return WriteSInt64NoTagToArray(value, target);
}
inline uint8* WireFormatLite::WriteFixed32ToArray(int field_number,
uint32 value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
return WriteFixed32NoTagToArray(value, target);
}
inline uint8* WireFormatLite::WriteFixed64ToArray(int field_number,
uint64 value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
return WriteFixed64NoTagToArray(value, target);
}
inline uint8* WireFormatLite::WriteSFixed32ToArray(int field_number,
int32 value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
return WriteSFixed32NoTagToArray(value, target);
}
inline uint8* WireFormatLite::WriteSFixed64ToArray(int field_number,
int64 value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
return WriteSFixed64NoTagToArray(value, target);
}
inline uint8* WireFormatLite::WriteFloatToArray(int field_number,
float value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
return WriteFloatNoTagToArray(value, target);
}
inline uint8* WireFormatLite::WriteDoubleToArray(int field_number,
double value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
return WriteDoubleNoTagToArray(value, target);
}
inline uint8* WireFormatLite::WriteBoolToArray(int field_number,
bool value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
return WriteBoolNoTagToArray(value, target);
}
inline uint8* WireFormatLite::WriteEnumToArray(int field_number,
int value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
return WriteEnumNoTagToArray(value, target);
}
inline uint8* WireFormatLite::WriteStringToArray(int field_number,
const string& value,
uint8* target) {
// String is for UTF-8 text only
// WARNING: In wire_format.cc, both strings and bytes are handled by
// WriteString() to avoid code duplication. If the implementations become
// different, you will need to update that usage.
target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
target = io::CodedOutputStream::WriteVarint32ToArray(value.size(), target);
return io::CodedOutputStream::WriteStringToArray(value, target);
}
inline uint8* WireFormatLite::WriteBytesToArray(int field_number,
const string& value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
target = io::CodedOutputStream::WriteVarint32ToArray(value.size(), target);
return io::CodedOutputStream::WriteStringToArray(value, target);
}
inline uint8* WireFormatLite::WriteGroupToArray(int field_number,
const MessageLite& value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
target = value.SerializeWithCachedSizesToArray(target);
return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
}
inline uint8* WireFormatLite::WriteMessageToArray(int field_number,
const MessageLite& value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
target = io::CodedOutputStream::WriteVarint32ToArray(
value.GetCachedSize(), target);
return value.SerializeWithCachedSizesToArray(target);
}
// See comment on ReadGroupNoVirtual to understand the need for this template
// parameter name.
template<typename MessageType_WorkAroundCppLookupDefect>
inline uint8* WireFormatLite::WriteGroupNoVirtualToArray(
int field_number, const MessageType_WorkAroundCppLookupDefect& value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
target = value.MessageType_WorkAroundCppLookupDefect
::SerializeWithCachedSizesToArray(target);
return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
}
template<typename MessageType_WorkAroundCppLookupDefect>
inline uint8* WireFormatLite::WriteMessageNoVirtualToArray(
int field_number, const MessageType_WorkAroundCppLookupDefect& value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
target = io::CodedOutputStream::WriteVarint32ToArray(
value.MessageType_WorkAroundCppLookupDefect::GetCachedSize(), target);
return value.MessageType_WorkAroundCppLookupDefect
::SerializeWithCachedSizesToArray(target);
}
// ===================================================================
inline int WireFormatLite::Int32Size(int32 value) {
return io::CodedOutputStream::VarintSize32SignExtended(value);
}
inline int WireFormatLite::Int64Size(int64 value) {
return io::CodedOutputStream::VarintSize64(static_cast<uint64>(value));
}
inline int WireFormatLite::UInt32Size(uint32 value) {
return io::CodedOutputStream::VarintSize32(value);
}
inline int WireFormatLite::UInt64Size(uint64 value) {
return io::CodedOutputStream::VarintSize64(value);
}
inline int WireFormatLite::SInt32Size(int32 value) {
return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value));
}
inline int WireFormatLite::SInt64Size(int64 value) {
return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value));
}
inline int WireFormatLite::EnumSize(int value) {
return io::CodedOutputStream::VarintSize32SignExtended(value);
}
inline int WireFormatLite::StringSize(const string& value) {
return io::CodedOutputStream::VarintSize32(value.size()) +
value.size();
}
inline int WireFormatLite::BytesSize(const string& value) {
return io::CodedOutputStream::VarintSize32(value.size()) +
value.size();
}
inline int WireFormatLite::GroupSize(const MessageLite& value) {
return value.ByteSize();
}
inline int WireFormatLite::MessageSize(const MessageLite& value) {
int size = value.ByteSize();
return io::CodedOutputStream::VarintSize32(size) + size;
}
// See comment on ReadGroupNoVirtual to understand the need for this template
// parameter name.
template<typename MessageType_WorkAroundCppLookupDefect>
inline int WireFormatLite::GroupSizeNoVirtual(
const MessageType_WorkAroundCppLookupDefect& value) {
return value.MessageType_WorkAroundCppLookupDefect::ByteSize();
}
template<typename MessageType_WorkAroundCppLookupDefect>
inline int WireFormatLite::MessageSizeNoVirtual(
const MessageType_WorkAroundCppLookupDefect& value) {
int size = value.MessageType_WorkAroundCppLookupDefect::ByteSize();
return io::CodedOutputStream::VarintSize32(size) + size;
}
} // namespace internal
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__