diff options
Diffstat (limited to 'src/google/protobuf/wire_format_inl.h')
-rw-r--r-- | src/google/protobuf/wire_format_inl.h | 371 |
1 files changed, 371 insertions, 0 deletions
diff --git a/src/google/protobuf/wire_format_inl.h b/src/google/protobuf/wire_format_inl.h new file mode 100644 index 00000000..d8cdd8d6 --- /dev/null +++ b/src/google/protobuf/wire_format_inl.h @@ -0,0 +1,371 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. +// http://code.google.com/p/protobuf/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_INL_H__ +#define GOOGLE_PROTOBUF_WIRE_FORMAT_INL_H__ + +#include <string> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/io/coded_stream.h> + + +namespace google { +namespace protobuf { +namespace internal { + +inline bool WireFormat::ReadInt32(io::CodedInputStream* input, int32* value) { + uint32 temp; + if (!input->ReadVarint32(&temp)) return false; + *value = static_cast<int32>(temp); + return true; +} +inline bool WireFormat::ReadInt64(io::CodedInputStream* input, int64* value) { + uint64 temp; + if (!input->ReadVarint64(&temp)) return false; + *value = static_cast<int64>(temp); + return true; +} +inline bool WireFormat::ReadUInt32(io::CodedInputStream* input, uint32* value) { + return input->ReadVarint32(value); +} +inline bool WireFormat::ReadUInt64(io::CodedInputStream* input, uint64* value) { + return input->ReadVarint64(value); +} +inline bool WireFormat::ReadSInt32(io::CodedInputStream* input, int32* value) { + uint32 temp; + if (!input->ReadVarint32(&temp)) return false; + *value = ZigZagDecode32(temp); + return true; +} +inline bool WireFormat::ReadSInt64(io::CodedInputStream* input, int64* value) { + uint64 temp; + if (!input->ReadVarint64(&temp)) return false; + *value = ZigZagDecode64(temp); + return true; +} +inline bool WireFormat::ReadFixed32(io::CodedInputStream* input, + uint32* value) { + return input->ReadLittleEndian32(value); +} +inline bool WireFormat::ReadFixed64(io::CodedInputStream* input, + uint64* value) { + return input->ReadLittleEndian64(value); +} +inline bool WireFormat::ReadSFixed32(io::CodedInputStream* input, + int32* value) { + uint32 temp; + if (!input->ReadLittleEndian32(&temp)) return false; + *value = static_cast<int32>(temp); + return true; +} +inline bool WireFormat::ReadSFixed64(io::CodedInputStream* input, + int64* value) { + uint64 temp; + if (!input->ReadLittleEndian64(&temp)) return false; + *value = static_cast<int64>(temp); + return true; +} +inline bool WireFormat::ReadFloat(io::CodedInputStream* input, float* value) { + uint32 temp; + if (!input->ReadLittleEndian32(&temp)) return false; + *value = DecodeFloat(temp); + return true; +} +inline bool WireFormat::ReadDouble(io::CodedInputStream* input, double* value) { + uint64 temp; + if (!input->ReadLittleEndian64(&temp)) return false; + *value = DecodeDouble(temp); + return true; +} +inline bool WireFormat::ReadBool(io::CodedInputStream* input, bool* value) { + uint32 temp; + if (!input->ReadVarint32(&temp)) return false; + *value = temp != 0; + return true; +} +inline bool WireFormat::ReadEnum(io::CodedInputStream* input, int* value) { + uint32 temp; + if (!input->ReadVarint32(&temp)) return false; + *value = static_cast<int>(temp); + return true; +} + +inline bool WireFormat::ReadString(io::CodedInputStream* input, string* value) { + // WARNING: In wire_format.cc, both strings and bytes are handled by + // ReadString() to avoid code duplication. If the implementations become + // different, you will need to update that usage. + uint32 length; + if (!input->ReadVarint32(&length)) return false; + return input->ReadString(value, length); +} +inline bool WireFormat::ReadBytes(io::CodedInputStream* input, string* value) { + uint32 length; + if (!input->ReadVarint32(&length)) return false; + return input->ReadString(value, length); +} + + +inline bool WireFormat::ReadGroup(int field_number, io::CodedInputStream* input, + Message* 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 WireFormat::ReadMessage(io::CodedInputStream* input, Message* 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; +} + +template<typename MessageType> +inline bool WireFormat::ReadGroupNoVirtual(int field_number, + io::CodedInputStream* input, + MessageType* value) { + if (!input->IncrementRecursionDepth()) return false; + if (!value->MessageType::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> +inline bool WireFormat::ReadMessageNoVirtual(io::CodedInputStream* input, + MessageType* value) { + uint32 length; + if (!input->ReadVarint32(&length)) return false; + if (!input->IncrementRecursionDepth()) return false; + io::CodedInputStream::Limit limit = input->PushLimit(length); + if (!value->MessageType::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 bool WireFormat::WriteTag(int field_number, WireType type, + io::CodedOutputStream* output) { + return output->WriteTag(MakeTag(field_number, type)); +} + +inline bool WireFormat::WriteInt32(int field_number, int32 value, + io::CodedOutputStream* output) { + return WriteTag(field_number, WIRETYPE_VARINT, output) && + output->WriteVarint32SignExtended(value); +} +inline bool WireFormat::WriteInt64(int field_number, int64 value, + io::CodedOutputStream* output) { + return WriteTag(field_number, WIRETYPE_VARINT, output) && + output->WriteVarint64(static_cast<uint64>(value)); +} +inline bool WireFormat::WriteUInt32(int field_number, uint32 value, + io::CodedOutputStream* output) { + return WriteTag(field_number, WIRETYPE_VARINT, output) && + output->WriteVarint32(value); +} +inline bool WireFormat::WriteUInt64(int field_number, uint64 value, + io::CodedOutputStream* output) { + return WriteTag(field_number, WIRETYPE_VARINT, output) && + output->WriteVarint64(value); +} +inline bool WireFormat::WriteSInt32(int field_number, int32 value, + io::CodedOutputStream* output) { + return WriteTag(field_number, WIRETYPE_VARINT, output) && + output->WriteVarint32(ZigZagEncode32(value)); +} +inline bool WireFormat::WriteSInt64(int field_number, int64 value, + io::CodedOutputStream* output) { + return WriteTag(field_number, WIRETYPE_VARINT, output) && + output->WriteVarint64(ZigZagEncode64(value)); +} +inline bool WireFormat::WriteFixed32(int field_number, uint32 value, + io::CodedOutputStream* output) { + return WriteTag(field_number, WIRETYPE_FIXED32, output) && + output->WriteLittleEndian32(value); +} +inline bool WireFormat::WriteFixed64(int field_number, uint64 value, + io::CodedOutputStream* output) { + return WriteTag(field_number, WIRETYPE_FIXED64, output) && + output->WriteLittleEndian64(value); +} +inline bool WireFormat::WriteSFixed32(int field_number, int32 value, + io::CodedOutputStream* output) { + return WriteTag(field_number, WIRETYPE_FIXED32, output) && + output->WriteLittleEndian32(static_cast<uint32>(value)); +} +inline bool WireFormat::WriteSFixed64(int field_number, int64 value, + io::CodedOutputStream* output) { + return WriteTag(field_number, WIRETYPE_FIXED64, output) && + output->WriteLittleEndian64(static_cast<uint64>(value)); +} +inline bool WireFormat::WriteFloat(int field_number, float value, + io::CodedOutputStream* output) { + return WriteTag(field_number, WIRETYPE_FIXED32, output) && + output->WriteLittleEndian32(EncodeFloat(value)); +} +inline bool WireFormat::WriteDouble(int field_number, double value, + io::CodedOutputStream* output) { + return WriteTag(field_number, WIRETYPE_FIXED64, output) && + output->WriteLittleEndian64(EncodeDouble(value)); +} +inline bool WireFormat::WriteBool(int field_number, bool value, + io::CodedOutputStream* output) { + return WriteTag(field_number, WIRETYPE_VARINT, output) && + output->WriteVarint32(value ? 1 : 0); +} +inline bool WireFormat::WriteEnum(int field_number, int value, + io::CodedOutputStream* output) { + return WriteTag(field_number, WIRETYPE_VARINT, output) && + output->WriteVarint32SignExtended(value); +} + +inline bool WireFormat::WriteString(int field_number, const string& value, + io::CodedOutputStream* output) { + // 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. + return WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output) && + output->WriteVarint32(value.size()) && + output->WriteString(value); +} +inline bool WireFormat::WriteBytes(int field_number, const string& value, + io::CodedOutputStream* output) { + return WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output) && + output->WriteVarint32(value.size()) && + output->WriteString(value); +} + + +inline bool WireFormat::WriteGroup(int field_number, const Message& value, + io::CodedOutputStream* output) { + return WriteTag(field_number, WIRETYPE_START_GROUP, output) && + value.SerializeWithCachedSizes(output) && + WriteTag(field_number, WIRETYPE_END_GROUP, output); +} +inline bool WireFormat::WriteMessage(int field_number, const Message& value, + io::CodedOutputStream* output) { + return WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output) && + output->WriteVarint32(value.GetCachedSize()) && + value.SerializeWithCachedSizes(output); +} + +template<typename MessageType> +inline bool WireFormat::WriteGroupNoVirtual( + int field_number, const MessageType& value, + io::CodedOutputStream* output) { + return WriteTag(field_number, WIRETYPE_START_GROUP, output) && + value.MessageType::SerializeWithCachedSizes(output) && + WriteTag(field_number, WIRETYPE_END_GROUP, output); +} +template<typename MessageType> +inline bool WireFormat::WriteMessageNoVirtual( + int field_number, const MessageType& value, + io::CodedOutputStream* output) { + return WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output) && + output->WriteVarint32(value.MessageType::GetCachedSize()) && + value.MessageType::SerializeWithCachedSizes(output); +} + +// =================================================================== + +inline int WireFormat::TagSize(int field_number, FieldDescriptor::Type type) { + int result = io::CodedOutputStream::VarintSize32( + field_number << kTagTypeBits); + if (type == FieldDescriptor::TYPE_GROUP) { + // Groups have both a start and an end tag. + return result * 2; + } else { + return result; + } +} + +inline int WireFormat::Int32Size(int32 value) { + return io::CodedOutputStream::VarintSize32SignExtended(value); +} +inline int WireFormat::Int64Size(int64 value) { + return io::CodedOutputStream::VarintSize64(static_cast<uint64>(value)); +} +inline int WireFormat::UInt32Size(uint32 value) { + return io::CodedOutputStream::VarintSize32(value); +} +inline int WireFormat::UInt64Size(uint64 value) { + return io::CodedOutputStream::VarintSize64(value); +} +inline int WireFormat::SInt32Size(int32 value) { + return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value)); +} +inline int WireFormat::SInt64Size(int64 value) { + return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value)); +} +inline int WireFormat::EnumSize(int value) { + return io::CodedOutputStream::VarintSize32SignExtended(value); +} + +inline int WireFormat::StringSize(const string& value) { + return io::CodedOutputStream::VarintSize32(value.size()) + + value.size(); +} +inline int WireFormat::BytesSize(const string& value) { + return io::CodedOutputStream::VarintSize32(value.size()) + + value.size(); +} + + +inline int WireFormat::GroupSize(const Message& value) { + return value.ByteSize(); +} +inline int WireFormat::MessageSize(const Message& value) { + int size = value.ByteSize(); + return io::CodedOutputStream::VarintSize32(size) + size; +} + +template<typename MessageType> +inline int WireFormat::GroupSizeNoVirtual(const MessageType& value) { + return value.MessageType::ByteSize(); +} +template<typename MessageType> +inline int WireFormat::MessageSizeNoVirtual(const MessageType& value) { + int size = value.MessageType::ByteSize(); + return io::CodedOutputStream::VarintSize32(size) + size; +} + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_WIRE_FORMAT_INL_H__ |