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