1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol Buffers - Google's data interchange format 2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copyright 2008 Google Inc. All rights reserved. 3fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// http://code.google.com/p/protobuf/ 4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Redistribution and use in source and binary forms, with or without 6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// modification, are permitted provided that the following conditions are 7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// met: 8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Redistributions of source code must retain the above copyright 10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// notice, this list of conditions and the following disclaimer. 11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Redistributions in binary form must reproduce the above 12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// copyright notice, this list of conditions and the following disclaimer 13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in the documentation and/or other materials provided with the 14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// distribution. 15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Neither the name of Google Inc. nor the names of its 16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// contributors may be used to endorse or promote products derived from 17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// this software without specific prior written permission. 18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Authors: wink@google.com (Wink Saville), 32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// kenton@google.com (Kenton Varda) 33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Based on original Protocol Buffers design by 34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Sanjay Ghemawat, Jeff Dean, and others. 35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/message_lite.h> 37d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#include <string> 38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/common.h> 39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/coded_stream.h> 40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/zero_copy_stream_impl.h> 41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/stl_util-inl.h> 42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace google { 44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace protobuf { 45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleMessageLite::~MessageLite() {} 47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring MessageLite::InitializationErrorString() const { 49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return "(cannot determine missing fields for lite message)"; 50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace { 53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 54d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// When serializing, we first compute the byte size, then serialize the message. 55d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// If serialization produces a different number of bytes than expected, we 56d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// call this function, which crashes. The problem could be due to a bug in the 57d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// protobuf implementation but is more likely caused by concurrent modification 58d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// of the message. This function attempts to distinguish between the two and 59d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// provide a useful error message. 60d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillevoid ByteSizeConsistencyError(int byte_size_before_serialization, 61d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville int byte_size_after_serialization, 62d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville int bytes_produced_by_serialization) { 63d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville GOOGLE_CHECK_EQ(byte_size_before_serialization, byte_size_after_serialization) 64d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville << "Protocol message was modified concurrently during serialization."; 65d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville GOOGLE_CHECK_EQ(bytes_produced_by_serialization, byte_size_before_serialization) 66d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville << "Byte size calculation and serialization were inconsistent. This " 67d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "may indicate a bug in protocol buffers or it may be caused by " 68d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "concurrent modification of the message."; 69d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville GOOGLE_LOG(FATAL) << "This shouldn't be called if all the sizes are equal."; 70d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 71d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring InitializationErrorMessage(const char* action, 73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const MessageLite& message) { 74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Note: We want to avoid depending on strutil in the lite library, otherwise 75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // we'd use: 76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // 77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // return strings::Substitute( 78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // "Can't $0 message of type \"$1\" because it is missing required " 79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // "fields: $2", 80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // action, message.GetTypeName(), 81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // message.InitializationErrorString()); 82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string result; 84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result += "Can't "; 85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result += action; 86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result += " message of type \""; 87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result += message.GetTypeName(); 88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result += "\" because it is missing required fields: "; 89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result += message.InitializationErrorString(); 90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Several of the Parse methods below just do one thing and then call another 94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// method. In a naive implementation, we might have ParseFromString() call 95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ParseFromArray() which would call ParseFromZeroCopyStream() which would call 96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ParseFromCodedStream() which would call MergeFromCodedStream() which would 97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// call MergePartialFromCodedStream(). However, when parsing very small 98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// messages, every function call introduces significant overhead. To avoid 99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// this without reproducing code, we use these forced-inline helpers. 100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Note: GCC only allows GOOGLE_ATTRIBUTE_ALWAYS_INLINE on declarations, not 102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// definitions. 103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline bool InlineMergeFromCodedStream(io::CodedInputStream* input, 104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MessageLite* message) 105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_ATTRIBUTE_ALWAYS_INLINE; 106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline bool InlineParseFromCodedStream(io::CodedInputStream* input, 107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MessageLite* message) 108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_ATTRIBUTE_ALWAYS_INLINE; 109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline bool InlineParsePartialFromCodedStream(io::CodedInputStream* input, 110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MessageLite* message) 111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_ATTRIBUTE_ALWAYS_INLINE; 112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline bool InlineParseFromArray(const void* data, int size, 113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MessageLite* message) 114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_ATTRIBUTE_ALWAYS_INLINE; 115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline bool InlineParsePartialFromArray(const void* data, int size, 116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MessageLite* message) 117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_ATTRIBUTE_ALWAYS_INLINE; 118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool InlineMergeFromCodedStream(io::CodedInputStream* input, 120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MessageLite* message) { 121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!message->MergePartialFromCodedStream(input)) return false; 122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!message->IsInitialized()) { 123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_LOG(ERROR) << InitializationErrorMessage("parse", *message); 124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool InlineParseFromCodedStream(io::CodedInputStream* input, 130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MessageLite* message) { 131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville message->Clear(); 132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return InlineMergeFromCodedStream(input, message); 133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool InlineParsePartialFromCodedStream(io::CodedInputStream* input, 136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MessageLite* message) { 137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville message->Clear(); 138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return message->MergePartialFromCodedStream(input); 139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool InlineParseFromArray(const void* data, int size, MessageLite* message) { 142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::CodedInputStream input(reinterpret_cast<const uint8*>(data), size); 143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return InlineParseFromCodedStream(&input, message) && 144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville input.ConsumedEntireMessage(); 145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool InlineParsePartialFromArray(const void* data, int size, 148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MessageLite* message) { 149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::CodedInputStream input(reinterpret_cast<const uint8*>(data), size); 150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return InlineParsePartialFromCodedStream(&input, message) && 151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville input.ConsumedEntireMessage(); 152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace 155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool MessageLite::MergeFromCodedStream(io::CodedInputStream* input) { 157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return InlineMergeFromCodedStream(input, this); 158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool MessageLite::ParseFromCodedStream(io::CodedInputStream* input) { 161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return InlineParseFromCodedStream(input, this); 162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool MessageLite::ParsePartialFromCodedStream(io::CodedInputStream* input) { 165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return InlineParsePartialFromCodedStream(input, this); 166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool MessageLite::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) { 169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::CodedInputStream decoder(input); 170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return ParseFromCodedStream(&decoder) && decoder.ConsumedEntireMessage(); 171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool MessageLite::ParsePartialFromZeroCopyStream( 174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::ZeroCopyInputStream* input) { 175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::CodedInputStream decoder(input); 176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return ParsePartialFromCodedStream(&decoder) && 177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville decoder.ConsumedEntireMessage(); 178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool MessageLite::ParseFromBoundedZeroCopyStream( 181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::ZeroCopyInputStream* input, int size) { 182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::CodedInputStream decoder(input); 183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville decoder.PushLimit(size); 184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return ParseFromCodedStream(&decoder) && 185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville decoder.ConsumedEntireMessage() && 186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville decoder.BytesUntilLimit() == 0; 187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool MessageLite::ParsePartialFromBoundedZeroCopyStream( 190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::ZeroCopyInputStream* input, int size) { 191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::CodedInputStream decoder(input); 192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville decoder.PushLimit(size); 193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return ParsePartialFromCodedStream(&decoder) && 194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville decoder.ConsumedEntireMessage() && 195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville decoder.BytesUntilLimit() == 0; 196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool MessageLite::ParseFromString(const string& data) { 199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return InlineParseFromArray(data.data(), data.size(), this); 200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool MessageLite::ParsePartialFromString(const string& data) { 203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return InlineParsePartialFromArray(data.data(), data.size(), this); 204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool MessageLite::ParseFromArray(const void* data, int size) { 207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return InlineParseFromArray(data, size, this); 208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool MessageLite::ParsePartialFromArray(const void* data, int size) { 211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return InlineParsePartialFromArray(data, size, this); 212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// =================================================================== 216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleuint8* MessageLite::SerializeWithCachedSizesToArray(uint8* target) const { 218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We only optimize this when using optimize_for = SPEED. In other cases 219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // we just use the CodedOutputStream path. 220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int size = GetCachedSize(); 221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::ArrayOutputStream out(target, size); 222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::CodedOutputStream coded_out(&out); 223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SerializeWithCachedSizes(&coded_out); 224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(!coded_out.HadError()); 225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return target + size; 226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool MessageLite::SerializeToCodedStream(io::CodedOutputStream* output) const { 229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this); 230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return SerializePartialToCodedStream(output); 231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool MessageLite::SerializePartialToCodedStream( 234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::CodedOutputStream* output) const { 235d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const int size = ByteSize(); // Force size to be cached. 236d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville uint8* buffer = output->GetDirectBufferForNBytesAndAdvance(size); 237d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (buffer != NULL) { 238d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville uint8* end = SerializeWithCachedSizesToArray(buffer); 239d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (end - buffer != size) { 240d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ByteSizeConsistencyError(size, ByteSize(), end - buffer); 241d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 242d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return true; 243d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } else { 244d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville int original_byte_count = output->ByteCount(); 245d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville SerializeWithCachedSizes(output); 246d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (output->HadError()) { 247d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return false; 248d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 249d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville int final_byte_count = output->ByteCount(); 250d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 251d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (final_byte_count - original_byte_count != size) { 252d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ByteSizeConsistencyError(size, ByteSize(), 253d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville final_byte_count - original_byte_count); 254d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 255d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 256d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return true; 257d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool MessageLite::SerializeToZeroCopyStream( 261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::ZeroCopyOutputStream* output) const { 262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::CodedOutputStream encoder(output); 263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return SerializeToCodedStream(&encoder); 264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool MessageLite::SerializePartialToZeroCopyStream( 267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::ZeroCopyOutputStream* output) const { 268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::CodedOutputStream encoder(output); 269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return SerializePartialToCodedStream(&encoder); 270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool MessageLite::AppendToString(string* output) const { 273fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this); 274fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return AppendPartialToString(output); 275fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 276fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 277fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool MessageLite::AppendPartialToString(string* output) const { 278fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int old_size = output->size(); 279fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int byte_size = ByteSize(); 280fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville STLStringResizeUninitialized(output, old_size + byte_size); 281fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint8* start = reinterpret_cast<uint8*>(string_as_array(output) + old_size); 282fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint8* end = SerializeWithCachedSizesToArray(start); 283d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (end - start != byte_size) { 284d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ByteSizeConsistencyError(byte_size, ByteSize(), end - start); 285d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 286fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 287fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 288fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool MessageLite::SerializeToString(string* output) const { 290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville output->clear(); 291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return AppendToString(output); 292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool MessageLite::SerializePartialToString(string* output) const { 295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville output->clear(); 296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return AppendPartialToString(output); 297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool MessageLite::SerializeToArray(void* data, int size) const { 300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this); 301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return SerializePartialToArray(data, size); 302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 303fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool MessageLite::SerializePartialToArray(void* data, int size) const { 305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int byte_size = ByteSize(); 306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (size < byte_size) return false; 307d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville uint8* start = reinterpret_cast<uint8*>(data); 308d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville uint8* end = SerializeWithCachedSizesToArray(start); 309d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (end - start != byte_size) { 310d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ByteSizeConsistencyError(byte_size, ByteSize(), end - start); 311d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring MessageLite::SerializeAsString() const { 316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // If the compiler implements the (Named) Return Value Optimization, 317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // the local variable 'result' will not actually reside on the stack 318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // of this function, but will be overlaid with the object that the 319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // caller supplied for the return value to be constructed in. 320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string output; 321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!AppendToString(&output)) 322fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville output.clear(); 323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return output; 324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring MessageLite::SerializePartialAsString() const { 327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string output; 328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!AppendPartialToString(&output)) 329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville output.clear(); 330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return output; 331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace protobuf 334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace google 335