1// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc.  All rights reserved.
3// https://developers.google.com/protocol-buffers/
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#ifdef _MSC_VER
40// This is required for min/max on VS2013 only.
41#include <algorithm>
42#endif
43
44#include <string>
45#include <google/protobuf/stubs/common.h>
46#include <google/protobuf/message_lite.h>
47#include <google/protobuf/repeated_field.h>
48#include <google/protobuf/wire_format_lite.h>
49#include <google/protobuf/io/coded_stream.h>
50
51
52namespace google {
53namespace protobuf {
54namespace internal {
55
56// Implementation details of ReadPrimitive.
57
58template <>
59inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>(
60    io::CodedInputStream* input,
61    int32* value) {
62  uint32 temp;
63  if (!input->ReadVarint32(&temp)) return false;
64  *value = static_cast<int32>(temp);
65  return true;
66}
67template <>
68inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_INT64>(
69    io::CodedInputStream* input,
70    int64* value) {
71  uint64 temp;
72  if (!input->ReadVarint64(&temp)) return false;
73  *value = static_cast<int64>(temp);
74  return true;
75}
76template <>
77inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_UINT32>(
78    io::CodedInputStream* input,
79    uint32* value) {
80  return input->ReadVarint32(value);
81}
82template <>
83inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_UINT64>(
84    io::CodedInputStream* input,
85    uint64* value) {
86  return input->ReadVarint64(value);
87}
88template <>
89inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>(
90    io::CodedInputStream* input,
91    int32* value) {
92  uint32 temp;
93  if (!input->ReadVarint32(&temp)) return false;
94  *value = ZigZagDecode32(temp);
95  return true;
96}
97template <>
98inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SINT64>(
99    io::CodedInputStream* input,
100    int64* value) {
101  uint64 temp;
102  if (!input->ReadVarint64(&temp)) return false;
103  *value = ZigZagDecode64(temp);
104  return true;
105}
106template <>
107inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_FIXED32>(
108    io::CodedInputStream* input,
109    uint32* value) {
110  return input->ReadLittleEndian32(value);
111}
112template <>
113inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_FIXED64>(
114    io::CodedInputStream* input,
115    uint64* value) {
116  return input->ReadLittleEndian64(value);
117}
118template <>
119inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SFIXED32>(
120    io::CodedInputStream* input,
121    int32* value) {
122  uint32 temp;
123  if (!input->ReadLittleEndian32(&temp)) return false;
124  *value = static_cast<int32>(temp);
125  return true;
126}
127template <>
128inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SFIXED64>(
129    io::CodedInputStream* input,
130    int64* value) {
131  uint64 temp;
132  if (!input->ReadLittleEndian64(&temp)) return false;
133  *value = static_cast<int64>(temp);
134  return true;
135}
136template <>
137inline bool WireFormatLite::ReadPrimitive<float, WireFormatLite::TYPE_FLOAT>(
138    io::CodedInputStream* input,
139    float* value) {
140  uint32 temp;
141  if (!input->ReadLittleEndian32(&temp)) return false;
142  *value = DecodeFloat(temp);
143  return true;
144}
145template <>
146inline bool WireFormatLite::ReadPrimitive<double, WireFormatLite::TYPE_DOUBLE>(
147    io::CodedInputStream* input,
148    double* value) {
149  uint64 temp;
150  if (!input->ReadLittleEndian64(&temp)) return false;
151  *value = DecodeDouble(temp);
152  return true;
153}
154template <>
155inline bool WireFormatLite::ReadPrimitive<bool, WireFormatLite::TYPE_BOOL>(
156    io::CodedInputStream* input,
157    bool* value) {
158  uint64 temp;
159  if (!input->ReadVarint64(&temp)) return false;
160  *value = temp != 0;
161  return true;
162}
163template <>
164inline bool WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
165    io::CodedInputStream* input,
166    int* value) {
167  uint32 temp;
168  if (!input->ReadVarint32(&temp)) return false;
169  *value = static_cast<int>(temp);
170  return true;
171}
172
173template <>
174inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
175  uint32, WireFormatLite::TYPE_FIXED32>(
176    const uint8* buffer,
177    uint32* value) {
178  return io::CodedInputStream::ReadLittleEndian32FromArray(buffer, value);
179}
180template <>
181inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
182  uint64, WireFormatLite::TYPE_FIXED64>(
183    const uint8* buffer,
184    uint64* value) {
185  return io::CodedInputStream::ReadLittleEndian64FromArray(buffer, value);
186}
187template <>
188inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
189  int32, WireFormatLite::TYPE_SFIXED32>(
190    const uint8* buffer,
191    int32* value) {
192  uint32 temp;
193  buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp);
194  *value = static_cast<int32>(temp);
195  return buffer;
196}
197template <>
198inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
199  int64, WireFormatLite::TYPE_SFIXED64>(
200    const uint8* buffer,
201    int64* value) {
202  uint64 temp;
203  buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp);
204  *value = static_cast<int64>(temp);
205  return buffer;
206}
207template <>
208inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
209  float, WireFormatLite::TYPE_FLOAT>(
210    const uint8* buffer,
211    float* value) {
212  uint32 temp;
213  buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp);
214  *value = DecodeFloat(temp);
215  return buffer;
216}
217template <>
218inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
219  double, WireFormatLite::TYPE_DOUBLE>(
220    const uint8* buffer,
221    double* value) {
222  uint64 temp;
223  buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp);
224  *value = DecodeDouble(temp);
225  return buffer;
226}
227
228template <typename CType, enum WireFormatLite::FieldType DeclaredType>
229inline bool WireFormatLite::ReadRepeatedPrimitive(
230    int,  // tag_size, unused.
231    uint32 tag,
232    io::CodedInputStream* input,
233    RepeatedField<CType>* values) {
234  CType value;
235  if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
236  values->Add(value);
237  int elements_already_reserved = values->Capacity() - values->size();
238  while (elements_already_reserved > 0 && input->ExpectTag(tag)) {
239    if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
240    values->AddAlreadyReserved(value);
241    elements_already_reserved--;
242  }
243  return true;
244}
245
246template <typename CType, enum WireFormatLite::FieldType DeclaredType>
247inline bool WireFormatLite::ReadRepeatedFixedSizePrimitive(
248    int tag_size,
249    uint32 tag,
250    io::CodedInputStream* input,
251    RepeatedField<CType>* values) {
252  GOOGLE_DCHECK_EQ(UInt32Size(tag), tag_size);
253  CType value;
254  if (!ReadPrimitive<CType, DeclaredType>(input, &value))
255    return false;
256  values->Add(value);
257
258  // For fixed size values, repeated values can be read more quickly by
259  // reading directly from a raw array.
260  //
261  // We can get a tight loop by only reading as many elements as can be
262  // added to the RepeatedField without having to do any resizing. Additionally,
263  // we only try to read as many elements as are available from the current
264  // buffer space. Doing so avoids having to perform boundary checks when
265  // reading the value: the maximum number of elements that can be read is
266  // known outside of the loop.
267  const void* void_pointer;
268  int size;
269  input->GetDirectBufferPointerInline(&void_pointer, &size);
270  if (size > 0) {
271    const uint8* buffer = reinterpret_cast<const uint8*>(void_pointer);
272    // The number of bytes each type occupies on the wire.
273    const int per_value_size = tag_size + sizeof(value);
274
275    int elements_available = min(values->Capacity() - values->size(),
276                                 size / per_value_size);
277    int num_read = 0;
278    while (num_read < elements_available &&
279           (buffer = io::CodedInputStream::ExpectTagFromArray(
280               buffer, tag)) != NULL) {
281      buffer = ReadPrimitiveFromArray<CType, DeclaredType>(buffer, &value);
282      values->AddAlreadyReserved(value);
283      ++num_read;
284    }
285    const int read_bytes = num_read * per_value_size;
286    if (read_bytes > 0) {
287      input->Skip(read_bytes);
288    }
289  }
290  return true;
291}
292
293// Specializations of ReadRepeatedPrimitive for the fixed size types, which use
294// the optimized code path.
295#define READ_REPEATED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE)             \
296template <>                                                                    \
297inline bool WireFormatLite::ReadRepeatedPrimitive<                             \
298  CPPTYPE, WireFormatLite::DECLARED_TYPE>(                                     \
299    int tag_size,                                                              \
300    uint32 tag,                                                                \
301    io::CodedInputStream* input,                                               \
302    RepeatedField<CPPTYPE>* values) {                                          \
303  return ReadRepeatedFixedSizePrimitive<                                       \
304    CPPTYPE, WireFormatLite::DECLARED_TYPE>(                                   \
305      tag_size, tag, input, values);                                           \
306}
307
308READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32)
309READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64)
310READ_REPEATED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32)
311READ_REPEATED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64)
312READ_REPEATED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT)
313READ_REPEATED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE)
314
315#undef READ_REPEATED_FIXED_SIZE_PRIMITIVE
316
317template <typename CType, enum WireFormatLite::FieldType DeclaredType>
318bool WireFormatLite::ReadRepeatedPrimitiveNoInline(
319    int tag_size,
320    uint32 tag,
321    io::CodedInputStream* input,
322    RepeatedField<CType>* value) {
323  return ReadRepeatedPrimitive<CType, DeclaredType>(
324      tag_size, tag, input, value);
325}
326
327template <typename CType, enum WireFormatLite::FieldType DeclaredType>
328inline bool WireFormatLite::ReadPackedPrimitive(io::CodedInputStream* input,
329                                                RepeatedField<CType>* values) {
330  uint32 length;
331  if (!input->ReadVarint32(&length)) return false;
332  io::CodedInputStream::Limit limit = input->PushLimit(length);
333  while (input->BytesUntilLimit() > 0) {
334    CType value;
335    if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
336    values->Add(value);
337  }
338  input->PopLimit(limit);
339  return true;
340}
341
342template <typename CType, enum WireFormatLite::FieldType DeclaredType>
343inline bool WireFormatLite::ReadPackedFixedSizePrimitive(
344    io::CodedInputStream* input, RepeatedField<CType>* values) {
345  uint32 length;
346  if (!input->ReadVarint32(&length)) return false;
347  const uint32 old_entries = values->size();
348  const uint32 new_entries = length / sizeof(CType);
349  const uint32 new_bytes = new_entries * sizeof(CType);
350  if (new_bytes != length) return false;
351  // We would *like* to pre-allocate the buffer to write into (for
352  // speed), but *must* avoid performing a very large allocation due
353  // to a malicious user-supplied "length" above.  So we have a fast
354  // path that pre-allocates when the "length" is less than a bound.
355  // We determine the bound by calling BytesUntilTotalBytesLimit() and
356  // BytesUntilLimit().  These return -1 to mean "no limit set".
357  // There are four cases:
358  // TotalBytesLimit  Limit
359  // -1               -1     Use slow path.
360  // -1               >= 0   Use fast path if length <= Limit.
361  // >= 0             -1     Use slow path.
362  // >= 0             >= 0   Use fast path if length <= min(both limits).
363  int64 bytes_limit = input->BytesUntilTotalBytesLimit();
364  if (bytes_limit == -1) {
365    bytes_limit = input->BytesUntilLimit();
366  } else {
367    bytes_limit =
368        min(bytes_limit, static_cast<int64>(input->BytesUntilLimit()));
369  }
370  if (bytes_limit >= new_bytes) {
371    // Fast-path that pre-allocates *values to the final size.
372#if defined(PROTOBUF_LITTLE_ENDIAN)
373    values->Resize(old_entries + new_entries, 0);
374    // values->mutable_data() may change after Resize(), so do this after:
375    void* dest = reinterpret_cast<void*>(values->mutable_data() + old_entries);
376    if (!input->ReadRaw(dest, new_bytes)) {
377      values->Truncate(old_entries);
378      return false;
379    }
380#else
381    values->Reserve(old_entries + new_entries);
382    CType value;
383    for (uint32 i = 0; i < new_entries; ++i) {
384      if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
385      values->AddAlreadyReserved(value);
386    }
387#endif
388  } else {
389    // This is the slow-path case where "length" may be too large to
390    // safely allocate.  We read as much as we can into *values
391    // without pre-allocating "length" bytes.
392    CType value;
393    for (uint32 i = 0; i < new_entries; ++i) {
394      if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
395      values->Add(value);
396    }
397  }
398  return true;
399}
400
401// Specializations of ReadPackedPrimitive for the fixed size types, which use
402// an optimized code path.
403#define READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE)      \
404template <>                                                                    \
405inline bool WireFormatLite::ReadPackedPrimitive<                               \
406  CPPTYPE, WireFormatLite::DECLARED_TYPE>(                                     \
407    io::CodedInputStream* input,                                               \
408    RepeatedField<CPPTYPE>* values) {                                          \
409  return ReadPackedFixedSizePrimitive<                                         \
410      CPPTYPE, WireFormatLite::DECLARED_TYPE>(input, values);                  \
411}
412
413READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32);
414READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64);
415READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32);
416READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64);
417READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT);
418READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE);
419
420#undef READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE
421
422template <typename CType, enum WireFormatLite::FieldType DeclaredType>
423bool WireFormatLite::ReadPackedPrimitiveNoInline(io::CodedInputStream* input,
424                                                 RepeatedField<CType>* values) {
425  return ReadPackedPrimitive<CType, DeclaredType>(input, values);
426}
427
428
429inline bool WireFormatLite::ReadGroup(int field_number,
430                                      io::CodedInputStream* input,
431                                      MessageLite* value) {
432  if (!input->IncrementRecursionDepth()) return false;
433  if (!value->MergePartialFromCodedStream(input)) return false;
434  input->DecrementRecursionDepth();
435  // Make sure the last thing read was an end tag for this group.
436  if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) {
437    return false;
438  }
439  return true;
440}
441inline bool WireFormatLite::ReadMessage(io::CodedInputStream* input,
442                                        MessageLite* value) {
443  uint32 length;
444  if (!input->ReadVarint32(&length)) return false;
445  if (!input->IncrementRecursionDepth()) return false;
446  io::CodedInputStream::Limit limit = input->PushLimit(length);
447  if (!value->MergePartialFromCodedStream(input)) return false;
448  // Make sure that parsing stopped when the limit was hit, not at an endgroup
449  // tag.
450  if (!input->ConsumedEntireMessage()) return false;
451  input->PopLimit(limit);
452  input->DecrementRecursionDepth();
453  return true;
454}
455
456// We name the template parameter something long and extremely unlikely to occur
457// elsewhere because a *qualified* member access expression designed to avoid
458// virtual dispatch, C++03 [basic.lookup.classref] 3.4.5/4 requires that the
459// name of the qualifying class to be looked up both in the context of the full
460// expression (finding the template parameter) and in the context of the object
461// whose member we are accessing. This could potentially find a nested type
462// within that object. The standard goes on to require these names to refer to
463// the same entity, which this collision would violate. The lack of a safe way
464// to avoid this collision appears to be a defect in the standard, but until it
465// is corrected, we choose the name to avoid accidental collisions.
466template<typename MessageType_WorkAroundCppLookupDefect>
467inline bool WireFormatLite::ReadGroupNoVirtual(
468    int field_number, io::CodedInputStream* input,
469    MessageType_WorkAroundCppLookupDefect* value) {
470  if (!input->IncrementRecursionDepth()) return false;
471  if (!value->
472      MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input))
473    return false;
474  input->DecrementRecursionDepth();
475  // Make sure the last thing read was an end tag for this group.
476  if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) {
477    return false;
478  }
479  return true;
480}
481template<typename MessageType_WorkAroundCppLookupDefect>
482inline bool WireFormatLite::ReadMessageNoVirtual(
483    io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) {
484  uint32 length;
485  if (!input->ReadVarint32(&length)) return false;
486  if (!input->IncrementRecursionDepth()) return false;
487  io::CodedInputStream::Limit limit = input->PushLimit(length);
488  if (!value->
489      MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input))
490    return false;
491  // Make sure that parsing stopped when the limit was hit, not at an endgroup
492  // tag.
493  if (!input->ConsumedEntireMessage()) return false;
494  input->PopLimit(limit);
495  input->DecrementRecursionDepth();
496  return true;
497}
498
499// ===================================================================
500
501inline void WireFormatLite::WriteTag(int field_number, WireType type,
502                                     io::CodedOutputStream* output) {
503  output->WriteTag(MakeTag(field_number, type));
504}
505
506inline void WireFormatLite::WriteInt32NoTag(int32 value,
507                                            io::CodedOutputStream* output) {
508  output->WriteVarint32SignExtended(value);
509}
510inline void WireFormatLite::WriteInt64NoTag(int64 value,
511                                            io::CodedOutputStream* output) {
512  output->WriteVarint64(static_cast<uint64>(value));
513}
514inline void WireFormatLite::WriteUInt32NoTag(uint32 value,
515                                             io::CodedOutputStream* output) {
516  output->WriteVarint32(value);
517}
518inline void WireFormatLite::WriteUInt64NoTag(uint64 value,
519                                             io::CodedOutputStream* output) {
520  output->WriteVarint64(value);
521}
522inline void WireFormatLite::WriteSInt32NoTag(int32 value,
523                                             io::CodedOutputStream* output) {
524  output->WriteVarint32(ZigZagEncode32(value));
525}
526inline void WireFormatLite::WriteSInt64NoTag(int64 value,
527                                             io::CodedOutputStream* output) {
528  output->WriteVarint64(ZigZagEncode64(value));
529}
530inline void WireFormatLite::WriteFixed32NoTag(uint32 value,
531                                              io::CodedOutputStream* output) {
532  output->WriteLittleEndian32(value);
533}
534inline void WireFormatLite::WriteFixed64NoTag(uint64 value,
535                                              io::CodedOutputStream* output) {
536  output->WriteLittleEndian64(value);
537}
538inline void WireFormatLite::WriteSFixed32NoTag(int32 value,
539                                               io::CodedOutputStream* output) {
540  output->WriteLittleEndian32(static_cast<uint32>(value));
541}
542inline void WireFormatLite::WriteSFixed64NoTag(int64 value,
543                                               io::CodedOutputStream* output) {
544  output->WriteLittleEndian64(static_cast<uint64>(value));
545}
546inline void WireFormatLite::WriteFloatNoTag(float value,
547                                            io::CodedOutputStream* output) {
548  output->WriteLittleEndian32(EncodeFloat(value));
549}
550inline void WireFormatLite::WriteDoubleNoTag(double value,
551                                             io::CodedOutputStream* output) {
552  output->WriteLittleEndian64(EncodeDouble(value));
553}
554inline void WireFormatLite::WriteBoolNoTag(bool value,
555                                           io::CodedOutputStream* output) {
556  output->WriteVarint32(value ? 1 : 0);
557}
558inline void WireFormatLite::WriteEnumNoTag(int value,
559                                           io::CodedOutputStream* output) {
560  output->WriteVarint32SignExtended(value);
561}
562
563// See comment on ReadGroupNoVirtual to understand the need for this template
564// parameter name.
565template<typename MessageType_WorkAroundCppLookupDefect>
566inline void WireFormatLite::WriteGroupNoVirtual(
567    int field_number, const MessageType_WorkAroundCppLookupDefect& value,
568    io::CodedOutputStream* output) {
569  WriteTag(field_number, WIRETYPE_START_GROUP, output);
570  value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output);
571  WriteTag(field_number, WIRETYPE_END_GROUP, output);
572}
573template<typename MessageType_WorkAroundCppLookupDefect>
574inline void WireFormatLite::WriteMessageNoVirtual(
575    int field_number, const MessageType_WorkAroundCppLookupDefect& value,
576    io::CodedOutputStream* output) {
577  WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
578  output->WriteVarint32(
579      value.MessageType_WorkAroundCppLookupDefect::GetCachedSize());
580  value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output);
581}
582
583// ===================================================================
584
585inline uint8* WireFormatLite::WriteTagToArray(int field_number,
586                                              WireType type,
587                                              uint8* target) {
588  return io::CodedOutputStream::WriteTagToArray(MakeTag(field_number, type),
589                                                target);
590}
591
592inline uint8* WireFormatLite::WriteInt32NoTagToArray(int32 value,
593                                                     uint8* target) {
594  return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
595}
596inline uint8* WireFormatLite::WriteInt64NoTagToArray(int64 value,
597                                                     uint8* target) {
598  return io::CodedOutputStream::WriteVarint64ToArray(
599      static_cast<uint64>(value), target);
600}
601inline uint8* WireFormatLite::WriteUInt32NoTagToArray(uint32 value,
602                                                      uint8* target) {
603  return io::CodedOutputStream::WriteVarint32ToArray(value, target);
604}
605inline uint8* WireFormatLite::WriteUInt64NoTagToArray(uint64 value,
606                                                      uint8* target) {
607  return io::CodedOutputStream::WriteVarint64ToArray(value, target);
608}
609inline uint8* WireFormatLite::WriteSInt32NoTagToArray(int32 value,
610                                                      uint8* target) {
611  return io::CodedOutputStream::WriteVarint32ToArray(ZigZagEncode32(value),
612                                                     target);
613}
614inline uint8* WireFormatLite::WriteSInt64NoTagToArray(int64 value,
615                                                      uint8* target) {
616  return io::CodedOutputStream::WriteVarint64ToArray(ZigZagEncode64(value),
617                                                     target);
618}
619inline uint8* WireFormatLite::WriteFixed32NoTagToArray(uint32 value,
620                                                       uint8* target) {
621  return io::CodedOutputStream::WriteLittleEndian32ToArray(value, target);
622}
623inline uint8* WireFormatLite::WriteFixed64NoTagToArray(uint64 value,
624                                                       uint8* target) {
625  return io::CodedOutputStream::WriteLittleEndian64ToArray(value, target);
626}
627inline uint8* WireFormatLite::WriteSFixed32NoTagToArray(int32 value,
628                                                        uint8* target) {
629  return io::CodedOutputStream::WriteLittleEndian32ToArray(
630      static_cast<uint32>(value), target);
631}
632inline uint8* WireFormatLite::WriteSFixed64NoTagToArray(int64 value,
633                                                        uint8* target) {
634  return io::CodedOutputStream::WriteLittleEndian64ToArray(
635      static_cast<uint64>(value), target);
636}
637inline uint8* WireFormatLite::WriteFloatNoTagToArray(float value,
638                                                     uint8* target) {
639  return io::CodedOutputStream::WriteLittleEndian32ToArray(EncodeFloat(value),
640                                                           target);
641}
642inline uint8* WireFormatLite::WriteDoubleNoTagToArray(double value,
643                                                      uint8* target) {
644  return io::CodedOutputStream::WriteLittleEndian64ToArray(EncodeDouble(value),
645                                                           target);
646}
647inline uint8* WireFormatLite::WriteBoolNoTagToArray(bool value,
648                                                    uint8* target) {
649  return io::CodedOutputStream::WriteVarint32ToArray(value ? 1 : 0, target);
650}
651inline uint8* WireFormatLite::WriteEnumNoTagToArray(int value,
652                                                    uint8* target) {
653  return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
654}
655
656inline uint8* WireFormatLite::WriteInt32ToArray(int field_number,
657                                                int32 value,
658                                                uint8* target) {
659  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
660  return WriteInt32NoTagToArray(value, target);
661}
662inline uint8* WireFormatLite::WriteInt64ToArray(int field_number,
663                                                int64 value,
664                                                uint8* target) {
665  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
666  return WriteInt64NoTagToArray(value, target);
667}
668inline uint8* WireFormatLite::WriteUInt32ToArray(int field_number,
669                                                 uint32 value,
670                                                 uint8* target) {
671  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
672  return WriteUInt32NoTagToArray(value, target);
673}
674inline uint8* WireFormatLite::WriteUInt64ToArray(int field_number,
675                                                 uint64 value,
676                                                 uint8* target) {
677  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
678  return WriteUInt64NoTagToArray(value, target);
679}
680inline uint8* WireFormatLite::WriteSInt32ToArray(int field_number,
681                                                 int32 value,
682                                                 uint8* target) {
683  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
684  return WriteSInt32NoTagToArray(value, target);
685}
686inline uint8* WireFormatLite::WriteSInt64ToArray(int field_number,
687                                                 int64 value,
688                                                 uint8* target) {
689  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
690  return WriteSInt64NoTagToArray(value, target);
691}
692inline uint8* WireFormatLite::WriteFixed32ToArray(int field_number,
693                                                  uint32 value,
694                                                  uint8* target) {
695  target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
696  return WriteFixed32NoTagToArray(value, target);
697}
698inline uint8* WireFormatLite::WriteFixed64ToArray(int field_number,
699                                                  uint64 value,
700                                                  uint8* target) {
701  target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
702  return WriteFixed64NoTagToArray(value, target);
703}
704inline uint8* WireFormatLite::WriteSFixed32ToArray(int field_number,
705                                                   int32 value,
706                                                   uint8* target) {
707  target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
708  return WriteSFixed32NoTagToArray(value, target);
709}
710inline uint8* WireFormatLite::WriteSFixed64ToArray(int field_number,
711                                                   int64 value,
712                                                   uint8* target) {
713  target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
714  return WriteSFixed64NoTagToArray(value, target);
715}
716inline uint8* WireFormatLite::WriteFloatToArray(int field_number,
717                                                float value,
718                                                uint8* target) {
719  target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
720  return WriteFloatNoTagToArray(value, target);
721}
722inline uint8* WireFormatLite::WriteDoubleToArray(int field_number,
723                                                 double value,
724                                                 uint8* target) {
725  target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
726  return WriteDoubleNoTagToArray(value, target);
727}
728inline uint8* WireFormatLite::WriteBoolToArray(int field_number,
729                                               bool value,
730                                               uint8* target) {
731  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
732  return WriteBoolNoTagToArray(value, target);
733}
734inline uint8* WireFormatLite::WriteEnumToArray(int field_number,
735                                               int value,
736                                               uint8* target) {
737  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
738  return WriteEnumNoTagToArray(value, target);
739}
740
741inline uint8* WireFormatLite::WriteStringToArray(int field_number,
742                                                 const string& value,
743                                                 uint8* target) {
744  // String is for UTF-8 text only
745  // WARNING:  In wire_format.cc, both strings and bytes are handled by
746  //   WriteString() to avoid code duplication.  If the implementations become
747  //   different, you will need to update that usage.
748  target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
749  return io::CodedOutputStream::WriteStringWithSizeToArray(value, target);
750}
751inline uint8* WireFormatLite::WriteBytesToArray(int field_number,
752                                                const string& value,
753                                                uint8* target) {
754  target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
755  return io::CodedOutputStream::WriteStringWithSizeToArray(value, target);
756}
757
758
759inline uint8* WireFormatLite::WriteGroupToArray(int field_number,
760                                                const MessageLite& value,
761                                                uint8* target) {
762  target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
763  target = value.SerializeWithCachedSizesToArray(target);
764  return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
765}
766inline uint8* WireFormatLite::WriteMessageToArray(int field_number,
767                                                  const MessageLite& value,
768                                                  uint8* target) {
769  target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
770  target = io::CodedOutputStream::WriteVarint32ToArray(
771    value.GetCachedSize(), target);
772  return value.SerializeWithCachedSizesToArray(target);
773}
774
775// See comment on ReadGroupNoVirtual to understand the need for this template
776// parameter name.
777template<typename MessageType_WorkAroundCppLookupDefect>
778inline uint8* WireFormatLite::WriteGroupNoVirtualToArray(
779    int field_number, const MessageType_WorkAroundCppLookupDefect& value,
780    uint8* target) {
781  target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
782  target = value.MessageType_WorkAroundCppLookupDefect
783      ::SerializeWithCachedSizesToArray(target);
784  return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
785}
786template<typename MessageType_WorkAroundCppLookupDefect>
787inline uint8* WireFormatLite::WriteMessageNoVirtualToArray(
788    int field_number, const MessageType_WorkAroundCppLookupDefect& value,
789    uint8* target) {
790  target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
791  target = io::CodedOutputStream::WriteVarint32ToArray(
792    value.MessageType_WorkAroundCppLookupDefect::GetCachedSize(), target);
793  return value.MessageType_WorkAroundCppLookupDefect
794      ::SerializeWithCachedSizesToArray(target);
795}
796
797// ===================================================================
798
799inline int WireFormatLite::Int32Size(int32 value) {
800  return io::CodedOutputStream::VarintSize32SignExtended(value);
801}
802inline int WireFormatLite::Int64Size(int64 value) {
803  return io::CodedOutputStream::VarintSize64(static_cast<uint64>(value));
804}
805inline int WireFormatLite::UInt32Size(uint32 value) {
806  return io::CodedOutputStream::VarintSize32(value);
807}
808inline int WireFormatLite::UInt64Size(uint64 value) {
809  return io::CodedOutputStream::VarintSize64(value);
810}
811inline int WireFormatLite::SInt32Size(int32 value) {
812  return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value));
813}
814inline int WireFormatLite::SInt64Size(int64 value) {
815  return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value));
816}
817inline int WireFormatLite::EnumSize(int value) {
818  return io::CodedOutputStream::VarintSize32SignExtended(value);
819}
820
821inline int WireFormatLite::StringSize(const string& value) {
822  return io::CodedOutputStream::VarintSize32(value.size()) +
823         value.size();
824}
825inline int WireFormatLite::BytesSize(const string& value) {
826  return io::CodedOutputStream::VarintSize32(value.size()) +
827         value.size();
828}
829
830
831inline int WireFormatLite::GroupSize(const MessageLite& value) {
832  return value.ByteSize();
833}
834inline int WireFormatLite::MessageSize(const MessageLite& value) {
835  return LengthDelimitedSize(value.ByteSize());
836}
837
838// See comment on ReadGroupNoVirtual to understand the need for this template
839// parameter name.
840template<typename MessageType_WorkAroundCppLookupDefect>
841inline int WireFormatLite::GroupSizeNoVirtual(
842    const MessageType_WorkAroundCppLookupDefect& value) {
843  return value.MessageType_WorkAroundCppLookupDefect::ByteSize();
844}
845template<typename MessageType_WorkAroundCppLookupDefect>
846inline int WireFormatLite::MessageSizeNoVirtual(
847    const MessageType_WorkAroundCppLookupDefect& value) {
848  return LengthDelimitedSize(
849      value.MessageType_WorkAroundCppLookupDefect::ByteSize());
850}
851
852inline int WireFormatLite::LengthDelimitedSize(int length) {
853  return io::CodedOutputStream::VarintSize32(length) + length;
854}
855
856}  // namespace internal
857}  // namespace protobuf
858
859}  // namespace google
860#endif  // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
861