1// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc.  All rights reserved.
3// http://code.google.com/p/protobuf/
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
8//
9//     * Redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer.
11//     * Redistributions in binary form must reproduce the above
12// copyright notice, this list of conditions and the following disclaimer
13// in the documentation and/or other materials provided with the
14// distribution.
15//     * Neither the name of Google Inc. nor the names of its
16// contributors may be used to endorse or promote products derived from
17// this software without specific prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31// Author: kenton@google.com (Kenton Varda)
32//         wink@google.com (Wink Saville) (refactored from wire_format.h)
33//  Based on original Protocol Buffers design by
34//  Sanjay Ghemawat, Jeff Dean, and others.
35
36#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
37#define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
38
39#include <string>
40#include <google/protobuf/stubs/common.h>
41#include <google/protobuf/message_lite.h>
42#include <google/protobuf/repeated_field.h>
43#include <google/protobuf/wire_format_lite.h>
44#include <google/protobuf/io/coded_stream.h>
45
46
47namespace google {
48namespace protobuf {
49namespace internal {
50
51// Implementation details of ReadPrimitive.
52
53template <>
54inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>(
55    io::CodedInputStream* input,
56    int32* value) {
57  uint32 temp;
58  if (!input->ReadVarint32(&temp)) return false;
59  *value = static_cast<int32>(temp);
60  return true;
61}
62template <>
63inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_INT64>(
64    io::CodedInputStream* input,
65    int64* value) {
66  uint64 temp;
67  if (!input->ReadVarint64(&temp)) return false;
68  *value = static_cast<int64>(temp);
69  return true;
70}
71template <>
72inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_UINT32>(
73    io::CodedInputStream* input,
74    uint32* value) {
75  return input->ReadVarint32(value);
76}
77template <>
78inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_UINT64>(
79    io::CodedInputStream* input,
80    uint64* value) {
81  return input->ReadVarint64(value);
82}
83template <>
84inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>(
85    io::CodedInputStream* input,
86    int32* value) {
87  uint32 temp;
88  if (!input->ReadVarint32(&temp)) return false;
89  *value = ZigZagDecode32(temp);
90  return true;
91}
92template <>
93inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SINT64>(
94    io::CodedInputStream* input,
95    int64* value) {
96  uint64 temp;
97  if (!input->ReadVarint64(&temp)) return false;
98  *value = ZigZagDecode64(temp);
99  return true;
100}
101template <>
102inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_FIXED32>(
103    io::CodedInputStream* input,
104    uint32* value) {
105  return input->ReadLittleEndian32(value);
106}
107template <>
108inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_FIXED64>(
109    io::CodedInputStream* input,
110    uint64* value) {
111  return input->ReadLittleEndian64(value);
112}
113template <>
114inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SFIXED32>(
115    io::CodedInputStream* input,
116    int32* value) {
117  uint32 temp;
118  if (!input->ReadLittleEndian32(&temp)) return false;
119  *value = static_cast<int32>(temp);
120  return true;
121}
122template <>
123inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SFIXED64>(
124    io::CodedInputStream* input,
125    int64* value) {
126  uint64 temp;
127  if (!input->ReadLittleEndian64(&temp)) return false;
128  *value = static_cast<int64>(temp);
129  return true;
130}
131template <>
132inline bool WireFormatLite::ReadPrimitive<float, WireFormatLite::TYPE_FLOAT>(
133    io::CodedInputStream* input,
134    float* value) {
135  uint32 temp;
136  if (!input->ReadLittleEndian32(&temp)) return false;
137  *value = DecodeFloat(temp);
138  return true;
139}
140template <>
141inline bool WireFormatLite::ReadPrimitive<double, WireFormatLite::TYPE_DOUBLE>(
142    io::CodedInputStream* input,
143    double* value) {
144  uint64 temp;
145  if (!input->ReadLittleEndian64(&temp)) return false;
146  *value = DecodeDouble(temp);
147  return true;
148}
149template <>
150inline bool WireFormatLite::ReadPrimitive<bool, WireFormatLite::TYPE_BOOL>(
151    io::CodedInputStream* input,
152    bool* value) {
153  uint32 temp;
154  if (!input->ReadVarint32(&temp)) return false;
155  *value = temp != 0;
156  return true;
157}
158template <>
159inline bool WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
160    io::CodedInputStream* input,
161    int* value) {
162  uint32 temp;
163  if (!input->ReadVarint32(&temp)) return false;
164  *value = static_cast<int>(temp);
165  return true;
166}
167
168template <>
169inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
170  uint32, WireFormatLite::TYPE_FIXED32>(
171    const uint8* buffer,
172    uint32* value) {
173  return io::CodedInputStream::ReadLittleEndian32FromArray(buffer, value);
174}
175template <>
176inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
177  uint64, WireFormatLite::TYPE_FIXED64>(
178    const uint8* buffer,
179    uint64* value) {
180  return io::CodedInputStream::ReadLittleEndian64FromArray(buffer, value);
181}
182template <>
183inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
184  int32, WireFormatLite::TYPE_SFIXED32>(
185    const uint8* buffer,
186    int32* value) {
187  uint32 temp;
188  buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp);
189  *value = static_cast<int32>(temp);
190  return buffer;
191}
192template <>
193inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
194  int64, WireFormatLite::TYPE_SFIXED64>(
195    const uint8* buffer,
196    int64* value) {
197  uint64 temp;
198  buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp);
199  *value = static_cast<int64>(temp);
200  return buffer;
201}
202template <>
203inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
204  float, WireFormatLite::TYPE_FLOAT>(
205    const uint8* buffer,
206    float* value) {
207  uint32 temp;
208  buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp);
209  *value = DecodeFloat(temp);
210  return buffer;
211}
212template <>
213inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
214  double, WireFormatLite::TYPE_DOUBLE>(
215    const uint8* buffer,
216    double* value) {
217  uint64 temp;
218  buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp);
219  *value = DecodeDouble(temp);
220  return buffer;
221}
222
223template <typename CType, enum WireFormatLite::FieldType DeclaredType>
224inline bool WireFormatLite::ReadRepeatedPrimitive(int, // tag_size, unused.
225                                               uint32 tag,
226                                               io::CodedInputStream* input,
227                                               RepeatedField<CType>* values) {
228  CType value;
229  if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
230  values->Add(value);
231  int elements_already_reserved = values->Capacity() - values->size();
232  while (elements_already_reserved > 0 && input->ExpectTag(tag)) {
233    if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
234    values->AddAlreadyReserved(value);
235    elements_already_reserved--;
236  }
237  return true;
238}
239
240template <typename CType, enum WireFormatLite::FieldType DeclaredType>
241inline bool WireFormatLite::ReadRepeatedFixedSizePrimitive(
242    int tag_size,
243    uint32 tag,
244    io::CodedInputStream* input,
245    RepeatedField<CType>* values) {
246  GOOGLE_DCHECK_EQ(UInt32Size(tag), tag_size);
247  CType value;
248  if (!ReadPrimitive<CType, DeclaredType>(input, &value))
249    return false;
250  values->Add(value);
251
252  // For fixed size values, repeated values can be read more quickly by
253  // reading directly from a raw array.
254  //
255  // We can get a tight loop by only reading as many elements as can be
256  // added to the RepeatedField without having to do any resizing. Additionally,
257  // we only try to read as many elements as are available from the current
258  // buffer space. Doing so avoids having to perform boundary checks when
259  // reading the value: the maximum number of elements that can be read is
260  // known outside of the loop.
261  const void* void_pointer;
262  int size;
263  input->GetDirectBufferPointerInline(&void_pointer, &size);
264  if (size > 0) {
265    const uint8* buffer = reinterpret_cast<const uint8*>(void_pointer);
266    // The number of bytes each type occupies on the wire.
267    const int per_value_size = tag_size + sizeof(value);
268
269    int elements_available = min(values->Capacity() - values->size(),
270                                 size / per_value_size);
271    int num_read = 0;
272    while (num_read < elements_available &&
273           (buffer = io::CodedInputStream::ExpectTagFromArray(
274               buffer, tag)) != NULL) {
275      buffer = ReadPrimitiveFromArray<CType, DeclaredType>(buffer, &value);
276      values->AddAlreadyReserved(value);
277      ++num_read;
278    }
279    const int read_bytes = num_read * per_value_size;
280    if (read_bytes > 0) {
281      input->Skip(read_bytes);
282    }
283  }
284  return true;
285}
286
287// Specializations of ReadRepeatedPrimitive for the fixed size types, which use
288// the optimized code path.
289#define READ_REPEATED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE)             \
290template <>                                                                    \
291inline bool WireFormatLite::ReadRepeatedPrimitive<                             \
292  CPPTYPE, WireFormatLite::DECLARED_TYPE>(                                     \
293    int tag_size,                                                              \
294    uint32 tag,                                                                \
295    io::CodedInputStream* input,                                               \
296    RepeatedField<CPPTYPE>* values) {                                          \
297  return ReadRepeatedFixedSizePrimitive<                                       \
298    CPPTYPE, WireFormatLite::DECLARED_TYPE>(                                   \
299      tag_size, tag, input, values);                                           \
300}
301
302READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32)
303READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64)
304READ_REPEATED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32)
305READ_REPEATED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64)
306READ_REPEATED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT)
307READ_REPEATED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE)
308
309#undef READ_REPEATED_FIXED_SIZE_PRIMITIVE
310
311template <typename CType, enum WireFormatLite::FieldType DeclaredType>
312bool WireFormatLite::ReadRepeatedPrimitiveNoInline(
313    int tag_size,
314    uint32 tag,
315    io::CodedInputStream* input,
316    RepeatedField<CType>* value) {
317  return ReadRepeatedPrimitive<CType, DeclaredType>(
318      tag_size, tag, input, value);
319}
320
321template <typename CType, enum WireFormatLite::FieldType DeclaredType>
322inline bool WireFormatLite::ReadPackedPrimitive(io::CodedInputStream* input,
323                                                RepeatedField<CType>* values) {
324  uint32 length;
325  if (!input->ReadVarint32(&length)) return false;
326  io::CodedInputStream::Limit limit = input->PushLimit(length);
327  while (input->BytesUntilLimit() > 0) {
328    CType value;
329    if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
330    values->Add(value);
331  }
332  input->PopLimit(limit);
333  return true;
334}
335
336template <typename CType, enum WireFormatLite::FieldType DeclaredType>
337bool WireFormatLite::ReadPackedPrimitiveNoInline(io::CodedInputStream* input,
338                                                 RepeatedField<CType>* values) {
339  return ReadPackedPrimitive<CType, DeclaredType>(input, values);
340}
341
342
343inline bool WireFormatLite::ReadGroup(int field_number,
344                                      io::CodedInputStream* input,
345                                      MessageLite* value) {
346  if (!input->IncrementRecursionDepth()) return false;
347  if (!value->MergePartialFromCodedStream(input)) return false;
348  input->DecrementRecursionDepth();
349  // Make sure the last thing read was an end tag for this group.
350  if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) {
351    return false;
352  }
353  return true;
354}
355inline bool WireFormatLite::ReadMessage(io::CodedInputStream* input,
356                                        MessageLite* value) {
357  uint32 length;
358  if (!input->ReadVarint32(&length)) return false;
359  if (!input->IncrementRecursionDepth()) return false;
360  io::CodedInputStream::Limit limit = input->PushLimit(length);
361  if (!value->MergePartialFromCodedStream(input)) return false;
362  // Make sure that parsing stopped when the limit was hit, not at an endgroup
363  // tag.
364  if (!input->ConsumedEntireMessage()) return false;
365  input->PopLimit(limit);
366  input->DecrementRecursionDepth();
367  return true;
368}
369
370// We name the template parameter something long and extremely unlikely to occur
371// elsewhere because a *qualified* member access expression designed to avoid
372// virtual dispatch, C++03 [basic.lookup.classref] 3.4.5/4 requires that the
373// name of the qualifying class to be looked up both in the context of the full
374// expression (finding the template parameter) and in the context of the object
375// whose member we are accessing. This could potentially find a nested type
376// within that object. The standard goes on to require these names to refer to
377// the same entity, which this collision would violate. The lack of a safe way
378// to avoid this collision appears to be a defect in the standard, but until it
379// is corrected, we choose the name to avoid accidental collisions.
380template<typename MessageType_WorkAroundCppLookupDefect>
381inline bool WireFormatLite::ReadGroupNoVirtual(
382    int field_number, io::CodedInputStream* input,
383    MessageType_WorkAroundCppLookupDefect* value) {
384  if (!input->IncrementRecursionDepth()) return false;
385  if (!value->
386      MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input))
387    return false;
388  input->DecrementRecursionDepth();
389  // Make sure the last thing read was an end tag for this group.
390  if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) {
391    return false;
392  }
393  return true;
394}
395template<typename MessageType_WorkAroundCppLookupDefect>
396inline bool WireFormatLite::ReadMessageNoVirtual(
397    io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) {
398  uint32 length;
399  if (!input->ReadVarint32(&length)) return false;
400  if (!input->IncrementRecursionDepth()) return false;
401  io::CodedInputStream::Limit limit = input->PushLimit(length);
402  if (!value->
403      MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input))
404    return false;
405  // Make sure that parsing stopped when the limit was hit, not at an endgroup
406  // tag.
407  if (!input->ConsumedEntireMessage()) return false;
408  input->PopLimit(limit);
409  input->DecrementRecursionDepth();
410  return true;
411}
412
413// ===================================================================
414
415inline void WireFormatLite::WriteTag(int field_number, WireType type,
416                                     io::CodedOutputStream* output) {
417  output->WriteTag(MakeTag(field_number, type));
418}
419
420inline void WireFormatLite::WriteInt32NoTag(int32 value,
421                                            io::CodedOutputStream* output) {
422  output->WriteVarint32SignExtended(value);
423}
424inline void WireFormatLite::WriteInt64NoTag(int64 value,
425                                            io::CodedOutputStream* output) {
426  output->WriteVarint64(static_cast<uint64>(value));
427}
428inline void WireFormatLite::WriteUInt32NoTag(uint32 value,
429                                             io::CodedOutputStream* output) {
430  output->WriteVarint32(value);
431}
432inline void WireFormatLite::WriteUInt64NoTag(uint64 value,
433                                             io::CodedOutputStream* output) {
434  output->WriteVarint64(value);
435}
436inline void WireFormatLite::WriteSInt32NoTag(int32 value,
437                                             io::CodedOutputStream* output) {
438  output->WriteVarint32(ZigZagEncode32(value));
439}
440inline void WireFormatLite::WriteSInt64NoTag(int64 value,
441                                             io::CodedOutputStream* output) {
442  output->WriteVarint64(ZigZagEncode64(value));
443}
444inline void WireFormatLite::WriteFixed32NoTag(uint32 value,
445                                              io::CodedOutputStream* output) {
446  output->WriteLittleEndian32(value);
447}
448inline void WireFormatLite::WriteFixed64NoTag(uint64 value,
449                                              io::CodedOutputStream* output) {
450  output->WriteLittleEndian64(value);
451}
452inline void WireFormatLite::WriteSFixed32NoTag(int32 value,
453                                               io::CodedOutputStream* output) {
454  output->WriteLittleEndian32(static_cast<uint32>(value));
455}
456inline void WireFormatLite::WriteSFixed64NoTag(int64 value,
457                                               io::CodedOutputStream* output) {
458  output->WriteLittleEndian64(static_cast<uint64>(value));
459}
460inline void WireFormatLite::WriteFloatNoTag(float value,
461                                            io::CodedOutputStream* output) {
462  output->WriteLittleEndian32(EncodeFloat(value));
463}
464inline void WireFormatLite::WriteDoubleNoTag(double value,
465                                             io::CodedOutputStream* output) {
466  output->WriteLittleEndian64(EncodeDouble(value));
467}
468inline void WireFormatLite::WriteBoolNoTag(bool value,
469                                           io::CodedOutputStream* output) {
470  output->WriteVarint32(value ? 1 : 0);
471}
472inline void WireFormatLite::WriteEnumNoTag(int value,
473                                           io::CodedOutputStream* output) {
474  output->WriteVarint32SignExtended(value);
475}
476
477// See comment on ReadGroupNoVirtual to understand the need for this template
478// parameter name.
479template<typename MessageType_WorkAroundCppLookupDefect>
480inline void WireFormatLite::WriteGroupNoVirtual(
481    int field_number, const MessageType_WorkAroundCppLookupDefect& value,
482    io::CodedOutputStream* output) {
483  WriteTag(field_number, WIRETYPE_START_GROUP, output);
484  value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output);
485  WriteTag(field_number, WIRETYPE_END_GROUP, output);
486}
487template<typename MessageType_WorkAroundCppLookupDefect>
488inline void WireFormatLite::WriteMessageNoVirtual(
489    int field_number, const MessageType_WorkAroundCppLookupDefect& value,
490    io::CodedOutputStream* output) {
491  WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
492  output->WriteVarint32(
493      value.MessageType_WorkAroundCppLookupDefect::GetCachedSize());
494  value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output);
495}
496
497// ===================================================================
498
499inline uint8* WireFormatLite::WriteTagToArray(int field_number,
500                                              WireType type,
501                                              uint8* target) {
502  return io::CodedOutputStream::WriteTagToArray(MakeTag(field_number, type),
503                                                target);
504}
505
506inline uint8* WireFormatLite::WriteInt32NoTagToArray(int32 value,
507                                                     uint8* target) {
508  return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
509}
510inline uint8* WireFormatLite::WriteInt64NoTagToArray(int64 value,
511                                                     uint8* target) {
512  return io::CodedOutputStream::WriteVarint64ToArray(
513      static_cast<uint64>(value), target);
514}
515inline uint8* WireFormatLite::WriteUInt32NoTagToArray(uint32 value,
516                                                      uint8* target) {
517  return io::CodedOutputStream::WriteVarint32ToArray(value, target);
518}
519inline uint8* WireFormatLite::WriteUInt64NoTagToArray(uint64 value,
520                                                      uint8* target) {
521  return io::CodedOutputStream::WriteVarint64ToArray(value, target);
522}
523inline uint8* WireFormatLite::WriteSInt32NoTagToArray(int32 value,
524                                                      uint8* target) {
525  return io::CodedOutputStream::WriteVarint32ToArray(ZigZagEncode32(value),
526                                                     target);
527}
528inline uint8* WireFormatLite::WriteSInt64NoTagToArray(int64 value,
529                                                      uint8* target) {
530  return io::CodedOutputStream::WriteVarint64ToArray(ZigZagEncode64(value),
531                                                     target);
532}
533inline uint8* WireFormatLite::WriteFixed32NoTagToArray(uint32 value,
534                                                       uint8* target) {
535  return io::CodedOutputStream::WriteLittleEndian32ToArray(value, target);
536}
537inline uint8* WireFormatLite::WriteFixed64NoTagToArray(uint64 value,
538                                                       uint8* target) {
539  return io::CodedOutputStream::WriteLittleEndian64ToArray(value, target);
540}
541inline uint8* WireFormatLite::WriteSFixed32NoTagToArray(int32 value,
542                                                        uint8* target) {
543  return io::CodedOutputStream::WriteLittleEndian32ToArray(
544      static_cast<uint32>(value), target);
545}
546inline uint8* WireFormatLite::WriteSFixed64NoTagToArray(int64 value,
547                                                        uint8* target) {
548  return io::CodedOutputStream::WriteLittleEndian64ToArray(
549      static_cast<uint64>(value), target);
550}
551inline uint8* WireFormatLite::WriteFloatNoTagToArray(float value,
552                                                     uint8* target) {
553  return io::CodedOutputStream::WriteLittleEndian32ToArray(EncodeFloat(value),
554                                                           target);
555}
556inline uint8* WireFormatLite::WriteDoubleNoTagToArray(double value,
557                                                      uint8* target) {
558  return io::CodedOutputStream::WriteLittleEndian64ToArray(EncodeDouble(value),
559                                                           target);
560}
561inline uint8* WireFormatLite::WriteBoolNoTagToArray(bool value,
562                                                    uint8* target) {
563  return io::CodedOutputStream::WriteVarint32ToArray(value ? 1 : 0, target);
564}
565inline uint8* WireFormatLite::WriteEnumNoTagToArray(int value,
566                                                    uint8* target) {
567  return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
568}
569
570inline uint8* WireFormatLite::WriteInt32ToArray(int field_number,
571                                                int32 value,
572                                                uint8* target) {
573  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
574  return WriteInt32NoTagToArray(value, target);
575}
576inline uint8* WireFormatLite::WriteInt64ToArray(int field_number,
577                                                int64 value,
578                                                uint8* target) {
579  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
580  return WriteInt64NoTagToArray(value, target);
581}
582inline uint8* WireFormatLite::WriteUInt32ToArray(int field_number,
583                                                 uint32 value,
584                                                 uint8* target) {
585  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
586  return WriteUInt32NoTagToArray(value, target);
587}
588inline uint8* WireFormatLite::WriteUInt64ToArray(int field_number,
589                                                 uint64 value,
590                                                 uint8* target) {
591  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
592  return WriteUInt64NoTagToArray(value, target);
593}
594inline uint8* WireFormatLite::WriteSInt32ToArray(int field_number,
595                                                 int32 value,
596                                                 uint8* target) {
597  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
598  return WriteSInt32NoTagToArray(value, target);
599}
600inline uint8* WireFormatLite::WriteSInt64ToArray(int field_number,
601                                                 int64 value,
602                                                 uint8* target) {
603  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
604  return WriteSInt64NoTagToArray(value, target);
605}
606inline uint8* WireFormatLite::WriteFixed32ToArray(int field_number,
607                                                  uint32 value,
608                                                  uint8* target) {
609  target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
610  return WriteFixed32NoTagToArray(value, target);
611}
612inline uint8* WireFormatLite::WriteFixed64ToArray(int field_number,
613                                                  uint64 value,
614                                                  uint8* target) {
615  target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
616  return WriteFixed64NoTagToArray(value, target);
617}
618inline uint8* WireFormatLite::WriteSFixed32ToArray(int field_number,
619                                                   int32 value,
620                                                   uint8* target) {
621  target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
622  return WriteSFixed32NoTagToArray(value, target);
623}
624inline uint8* WireFormatLite::WriteSFixed64ToArray(int field_number,
625                                                   int64 value,
626                                                   uint8* target) {
627  target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
628  return WriteSFixed64NoTagToArray(value, target);
629}
630inline uint8* WireFormatLite::WriteFloatToArray(int field_number,
631                                                float value,
632                                                uint8* target) {
633  target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
634  return WriteFloatNoTagToArray(value, target);
635}
636inline uint8* WireFormatLite::WriteDoubleToArray(int field_number,
637                                                 double value,
638                                                 uint8* target) {
639  target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
640  return WriteDoubleNoTagToArray(value, target);
641}
642inline uint8* WireFormatLite::WriteBoolToArray(int field_number,
643                                               bool value,
644                                               uint8* target) {
645  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
646  return WriteBoolNoTagToArray(value, target);
647}
648inline uint8* WireFormatLite::WriteEnumToArray(int field_number,
649                                               int value,
650                                               uint8* target) {
651  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
652  return WriteEnumNoTagToArray(value, target);
653}
654
655inline uint8* WireFormatLite::WriteStringToArray(int field_number,
656                                                 const string& value,
657                                                 uint8* target) {
658  // String is for UTF-8 text only
659  // WARNING:  In wire_format.cc, both strings and bytes are handled by
660  //   WriteString() to avoid code duplication.  If the implementations become
661  //   different, you will need to update that usage.
662  target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
663  target = io::CodedOutputStream::WriteVarint32ToArray(value.size(), target);
664  return io::CodedOutputStream::WriteStringToArray(value, target);
665}
666inline uint8* WireFormatLite::WriteBytesToArray(int field_number,
667                                                const string& value,
668                                                uint8* target) {
669  target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
670  target = io::CodedOutputStream::WriteVarint32ToArray(value.size(), target);
671  return io::CodedOutputStream::WriteStringToArray(value, target);
672}
673
674
675inline uint8* WireFormatLite::WriteGroupToArray(int field_number,
676                                                const MessageLite& value,
677                                                uint8* target) {
678  target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
679  target = value.SerializeWithCachedSizesToArray(target);
680  return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
681}
682inline uint8* WireFormatLite::WriteMessageToArray(int field_number,
683                                                  const MessageLite& value,
684                                                  uint8* target) {
685  target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
686  target = io::CodedOutputStream::WriteVarint32ToArray(
687    value.GetCachedSize(), target);
688  return value.SerializeWithCachedSizesToArray(target);
689}
690
691// See comment on ReadGroupNoVirtual to understand the need for this template
692// parameter name.
693template<typename MessageType_WorkAroundCppLookupDefect>
694inline uint8* WireFormatLite::WriteGroupNoVirtualToArray(
695    int field_number, const MessageType_WorkAroundCppLookupDefect& value,
696    uint8* target) {
697  target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
698  target = value.MessageType_WorkAroundCppLookupDefect
699      ::SerializeWithCachedSizesToArray(target);
700  return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
701}
702template<typename MessageType_WorkAroundCppLookupDefect>
703inline uint8* WireFormatLite::WriteMessageNoVirtualToArray(
704    int field_number, const MessageType_WorkAroundCppLookupDefect& value,
705    uint8* target) {
706  target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
707  target = io::CodedOutputStream::WriteVarint32ToArray(
708    value.MessageType_WorkAroundCppLookupDefect::GetCachedSize(), target);
709  return value.MessageType_WorkAroundCppLookupDefect
710      ::SerializeWithCachedSizesToArray(target);
711}
712
713// ===================================================================
714
715inline int WireFormatLite::Int32Size(int32 value) {
716  return io::CodedOutputStream::VarintSize32SignExtended(value);
717}
718inline int WireFormatLite::Int64Size(int64 value) {
719  return io::CodedOutputStream::VarintSize64(static_cast<uint64>(value));
720}
721inline int WireFormatLite::UInt32Size(uint32 value) {
722  return io::CodedOutputStream::VarintSize32(value);
723}
724inline int WireFormatLite::UInt64Size(uint64 value) {
725  return io::CodedOutputStream::VarintSize64(value);
726}
727inline int WireFormatLite::SInt32Size(int32 value) {
728  return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value));
729}
730inline int WireFormatLite::SInt64Size(int64 value) {
731  return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value));
732}
733inline int WireFormatLite::EnumSize(int value) {
734  return io::CodedOutputStream::VarintSize32SignExtended(value);
735}
736
737inline int WireFormatLite::StringSize(const string& value) {
738  return io::CodedOutputStream::VarintSize32(value.size()) +
739         value.size();
740}
741inline int WireFormatLite::BytesSize(const string& value) {
742  return io::CodedOutputStream::VarintSize32(value.size()) +
743         value.size();
744}
745
746
747inline int WireFormatLite::GroupSize(const MessageLite& value) {
748  return value.ByteSize();
749}
750inline int WireFormatLite::MessageSize(const MessageLite& value) {
751  return LengthDelimitedSize(value.ByteSize());
752}
753
754// See comment on ReadGroupNoVirtual to understand the need for this template
755// parameter name.
756template<typename MessageType_WorkAroundCppLookupDefect>
757inline int WireFormatLite::GroupSizeNoVirtual(
758    const MessageType_WorkAroundCppLookupDefect& value) {
759  return value.MessageType_WorkAroundCppLookupDefect::ByteSize();
760}
761template<typename MessageType_WorkAroundCppLookupDefect>
762inline int WireFormatLite::MessageSizeNoVirtual(
763    const MessageType_WorkAroundCppLookupDefect& value) {
764  return LengthDelimitedSize(
765      value.MessageType_WorkAroundCppLookupDefect::ByteSize());
766}
767
768inline int WireFormatLite::LengthDelimitedSize(int length) {
769  return io::CodedOutputStream::VarintSize32(length) + length;
770}
771
772}  // namespace internal
773}  // namespace protobuf
774
775}  // namespace google
776#endif  // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
777