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 
52 namespace google {
53 namespace protobuf {
54 namespace internal {
55 
56 // Implementation details of ReadPrimitive.
57 
58 template <>
59 inline 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 }
67 template <>
68 inline 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 }
76 template <>
77 inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_UINT32>(
78     io::CodedInputStream* input,
79     uint32* value) {
80   return input->ReadVarint32(value);
81 }
82 template <>
83 inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_UINT64>(
84     io::CodedInputStream* input,
85     uint64* value) {
86   return input->ReadVarint64(value);
87 }
88 template <>
89 inline 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 }
97 template <>
98 inline 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 }
106 template <>
107 inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_FIXED32>(
108     io::CodedInputStream* input,
109     uint32* value) {
110   return input->ReadLittleEndian32(value);
111 }
112 template <>
113 inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_FIXED64>(
114     io::CodedInputStream* input,
115     uint64* value) {
116   return input->ReadLittleEndian64(value);
117 }
118 template <>
119 inline 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 }
127 template <>
128 inline 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 }
136 template <>
137 inline 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 }
145 template <>
146 inline 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 }
154 template <>
155 inline 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 }
163 template <>
164 inline 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 
173 template <>
174 inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
175   uint32, WireFormatLite::TYPE_FIXED32>(
176     const uint8* buffer,
177     uint32* value) {
178   return io::CodedInputStream::ReadLittleEndian32FromArray(buffer, value);
179 }
180 template <>
181 inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
182   uint64, WireFormatLite::TYPE_FIXED64>(
183     const uint8* buffer,
184     uint64* value) {
185   return io::CodedInputStream::ReadLittleEndian64FromArray(buffer, value);
186 }
187 template <>
188 inline 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 }
197 template <>
198 inline 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 }
207 template <>
208 inline 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 }
217 template <>
218 inline 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 
228 template <typename CType, enum WireFormatLite::FieldType DeclaredType>
ReadRepeatedPrimitive(int,uint32 tag,io::CodedInputStream * input,RepeatedField<CType> * values)229 inline 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 
246 template <typename CType, enum WireFormatLite::FieldType DeclaredType>
ReadRepeatedFixedSizePrimitive(int tag_size,uint32 tag,io::CodedInputStream * input,RepeatedField<CType> * values)247 inline 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)             \
296 template <>                                                                    \
297 inline 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 
READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32,TYPE_FIXED32)308 READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32)
309 READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64)
310 READ_REPEATED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32)
311 READ_REPEATED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64)
312 READ_REPEATED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT)
313 READ_REPEATED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE)
314 
315 #undef READ_REPEATED_FIXED_SIZE_PRIMITIVE
316 
317 template <typename CType, enum WireFormatLite::FieldType DeclaredType>
318 bool 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 
327 template <typename CType, enum WireFormatLite::FieldType DeclaredType>
ReadPackedPrimitive(io::CodedInputStream * input,RepeatedField<CType> * values)328 inline 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 
342 template <typename CType, enum WireFormatLite::FieldType DeclaredType>
ReadPackedFixedSizePrimitive(io::CodedInputStream * input,RepeatedField<CType> * values)343 inline 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)      \
404 template <>                                                                    \
405 inline 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 
413 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32);
414 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64);
415 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32);
416 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64);
417 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT);
418 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE);
419 
420 #undef READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE
421 
422 template <typename CType, enum WireFormatLite::FieldType DeclaredType>
ReadPackedPrimitiveNoInline(io::CodedInputStream * input,RepeatedField<CType> * values)423 bool WireFormatLite::ReadPackedPrimitiveNoInline(io::CodedInputStream* input,
424                                                  RepeatedField<CType>* values) {
425   return ReadPackedPrimitive<CType, DeclaredType>(input, values);
426 }
427 
428 
ReadGroup(int field_number,io::CodedInputStream * input,MessageLite * value)429 inline 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 }
ReadMessage(io::CodedInputStream * input,MessageLite * value)441 inline 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.
466 template<typename MessageType_WorkAroundCppLookupDefect>
ReadGroupNoVirtual(int field_number,io::CodedInputStream * input,MessageType_WorkAroundCppLookupDefect * value)467 inline 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 }
481 template<typename MessageType_WorkAroundCppLookupDefect>
ReadMessageNoVirtual(io::CodedInputStream * input,MessageType_WorkAroundCppLookupDefect * value)482 inline 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 
WriteTag(int field_number,WireType type,io::CodedOutputStream * output)501 inline void WireFormatLite::WriteTag(int field_number, WireType type,
502                                      io::CodedOutputStream* output) {
503   output->WriteTag(MakeTag(field_number, type));
504 }
505 
WriteInt32NoTag(int32 value,io::CodedOutputStream * output)506 inline void WireFormatLite::WriteInt32NoTag(int32 value,
507                                             io::CodedOutputStream* output) {
508   output->WriteVarint32SignExtended(value);
509 }
WriteInt64NoTag(int64 value,io::CodedOutputStream * output)510 inline void WireFormatLite::WriteInt64NoTag(int64 value,
511                                             io::CodedOutputStream* output) {
512   output->WriteVarint64(static_cast<uint64>(value));
513 }
WriteUInt32NoTag(uint32 value,io::CodedOutputStream * output)514 inline void WireFormatLite::WriteUInt32NoTag(uint32 value,
515                                              io::CodedOutputStream* output) {
516   output->WriteVarint32(value);
517 }
WriteUInt64NoTag(uint64 value,io::CodedOutputStream * output)518 inline void WireFormatLite::WriteUInt64NoTag(uint64 value,
519                                              io::CodedOutputStream* output) {
520   output->WriteVarint64(value);
521 }
WriteSInt32NoTag(int32 value,io::CodedOutputStream * output)522 inline void WireFormatLite::WriteSInt32NoTag(int32 value,
523                                              io::CodedOutputStream* output) {
524   output->WriteVarint32(ZigZagEncode32(value));
525 }
WriteSInt64NoTag(int64 value,io::CodedOutputStream * output)526 inline void WireFormatLite::WriteSInt64NoTag(int64 value,
527                                              io::CodedOutputStream* output) {
528   output->WriteVarint64(ZigZagEncode64(value));
529 }
WriteFixed32NoTag(uint32 value,io::CodedOutputStream * output)530 inline void WireFormatLite::WriteFixed32NoTag(uint32 value,
531                                               io::CodedOutputStream* output) {
532   output->WriteLittleEndian32(value);
533 }
WriteFixed64NoTag(uint64 value,io::CodedOutputStream * output)534 inline void WireFormatLite::WriteFixed64NoTag(uint64 value,
535                                               io::CodedOutputStream* output) {
536   output->WriteLittleEndian64(value);
537 }
WriteSFixed32NoTag(int32 value,io::CodedOutputStream * output)538 inline void WireFormatLite::WriteSFixed32NoTag(int32 value,
539                                                io::CodedOutputStream* output) {
540   output->WriteLittleEndian32(static_cast<uint32>(value));
541 }
WriteSFixed64NoTag(int64 value,io::CodedOutputStream * output)542 inline void WireFormatLite::WriteSFixed64NoTag(int64 value,
543                                                io::CodedOutputStream* output) {
544   output->WriteLittleEndian64(static_cast<uint64>(value));
545 }
WriteFloatNoTag(float value,io::CodedOutputStream * output)546 inline void WireFormatLite::WriteFloatNoTag(float value,
547                                             io::CodedOutputStream* output) {
548   output->WriteLittleEndian32(EncodeFloat(value));
549 }
WriteDoubleNoTag(double value,io::CodedOutputStream * output)550 inline void WireFormatLite::WriteDoubleNoTag(double value,
551                                              io::CodedOutputStream* output) {
552   output->WriteLittleEndian64(EncodeDouble(value));
553 }
WriteBoolNoTag(bool value,io::CodedOutputStream * output)554 inline void WireFormatLite::WriteBoolNoTag(bool value,
555                                            io::CodedOutputStream* output) {
556   output->WriteVarint32(value ? 1 : 0);
557 }
WriteEnumNoTag(int value,io::CodedOutputStream * output)558 inline 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.
565 template<typename MessageType_WorkAroundCppLookupDefect>
WriteGroupNoVirtual(int field_number,const MessageType_WorkAroundCppLookupDefect & value,io::CodedOutputStream * output)566 inline 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 }
573 template<typename MessageType_WorkAroundCppLookupDefect>
WriteMessageNoVirtual(int field_number,const MessageType_WorkAroundCppLookupDefect & value,io::CodedOutputStream * output)574 inline 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 
WriteTagToArray(int field_number,WireType type,uint8 * target)585 inline 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 
WriteInt32NoTagToArray(int32 value,uint8 * target)592 inline uint8* WireFormatLite::WriteInt32NoTagToArray(int32 value,
593                                                      uint8* target) {
594   return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
595 }
WriteInt64NoTagToArray(int64 value,uint8 * target)596 inline uint8* WireFormatLite::WriteInt64NoTagToArray(int64 value,
597                                                      uint8* target) {
598   return io::CodedOutputStream::WriteVarint64ToArray(
599       static_cast<uint64>(value), target);
600 }
WriteUInt32NoTagToArray(uint32 value,uint8 * target)601 inline uint8* WireFormatLite::WriteUInt32NoTagToArray(uint32 value,
602                                                       uint8* target) {
603   return io::CodedOutputStream::WriteVarint32ToArray(value, target);
604 }
WriteUInt64NoTagToArray(uint64 value,uint8 * target)605 inline uint8* WireFormatLite::WriteUInt64NoTagToArray(uint64 value,
606                                                       uint8* target) {
607   return io::CodedOutputStream::WriteVarint64ToArray(value, target);
608 }
WriteSInt32NoTagToArray(int32 value,uint8 * target)609 inline uint8* WireFormatLite::WriteSInt32NoTagToArray(int32 value,
610                                                       uint8* target) {
611   return io::CodedOutputStream::WriteVarint32ToArray(ZigZagEncode32(value),
612                                                      target);
613 }
WriteSInt64NoTagToArray(int64 value,uint8 * target)614 inline uint8* WireFormatLite::WriteSInt64NoTagToArray(int64 value,
615                                                       uint8* target) {
616   return io::CodedOutputStream::WriteVarint64ToArray(ZigZagEncode64(value),
617                                                      target);
618 }
WriteFixed32NoTagToArray(uint32 value,uint8 * target)619 inline uint8* WireFormatLite::WriteFixed32NoTagToArray(uint32 value,
620                                                        uint8* target) {
621   return io::CodedOutputStream::WriteLittleEndian32ToArray(value, target);
622 }
WriteFixed64NoTagToArray(uint64 value,uint8 * target)623 inline uint8* WireFormatLite::WriteFixed64NoTagToArray(uint64 value,
624                                                        uint8* target) {
625   return io::CodedOutputStream::WriteLittleEndian64ToArray(value, target);
626 }
WriteSFixed32NoTagToArray(int32 value,uint8 * target)627 inline uint8* WireFormatLite::WriteSFixed32NoTagToArray(int32 value,
628                                                         uint8* target) {
629   return io::CodedOutputStream::WriteLittleEndian32ToArray(
630       static_cast<uint32>(value), target);
631 }
WriteSFixed64NoTagToArray(int64 value,uint8 * target)632 inline uint8* WireFormatLite::WriteSFixed64NoTagToArray(int64 value,
633                                                         uint8* target) {
634   return io::CodedOutputStream::WriteLittleEndian64ToArray(
635       static_cast<uint64>(value), target);
636 }
WriteFloatNoTagToArray(float value,uint8 * target)637 inline uint8* WireFormatLite::WriteFloatNoTagToArray(float value,
638                                                      uint8* target) {
639   return io::CodedOutputStream::WriteLittleEndian32ToArray(EncodeFloat(value),
640                                                            target);
641 }
WriteDoubleNoTagToArray(double value,uint8 * target)642 inline uint8* WireFormatLite::WriteDoubleNoTagToArray(double value,
643                                                       uint8* target) {
644   return io::CodedOutputStream::WriteLittleEndian64ToArray(EncodeDouble(value),
645                                                            target);
646 }
WriteBoolNoTagToArray(bool value,uint8 * target)647 inline uint8* WireFormatLite::WriteBoolNoTagToArray(bool value,
648                                                     uint8* target) {
649   return io::CodedOutputStream::WriteVarint32ToArray(value ? 1 : 0, target);
650 }
WriteEnumNoTagToArray(int value,uint8 * target)651 inline uint8* WireFormatLite::WriteEnumNoTagToArray(int value,
652                                                     uint8* target) {
653   return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
654 }
655 
WriteInt32ToArray(int field_number,int32 value,uint8 * target)656 inline 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 }
WriteInt64ToArray(int field_number,int64 value,uint8 * target)662 inline 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 }
WriteUInt32ToArray(int field_number,uint32 value,uint8 * target)668 inline 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 }
WriteUInt64ToArray(int field_number,uint64 value,uint8 * target)674 inline 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 }
WriteSInt32ToArray(int field_number,int32 value,uint8 * target)680 inline 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 }
WriteSInt64ToArray(int field_number,int64 value,uint8 * target)686 inline 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 }
WriteFixed32ToArray(int field_number,uint32 value,uint8 * target)692 inline 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 }
WriteFixed64ToArray(int field_number,uint64 value,uint8 * target)698 inline 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 }
WriteSFixed32ToArray(int field_number,int32 value,uint8 * target)704 inline 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 }
WriteSFixed64ToArray(int field_number,int64 value,uint8 * target)710 inline 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 }
WriteFloatToArray(int field_number,float value,uint8 * target)716 inline 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 }
WriteDoubleToArray(int field_number,double value,uint8 * target)722 inline 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 }
WriteBoolToArray(int field_number,bool value,uint8 * target)728 inline 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 }
WriteEnumToArray(int field_number,int value,uint8 * target)734 inline 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 
WriteStringToArray(int field_number,const string & value,uint8 * target)741 inline 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 }
WriteBytesToArray(int field_number,const string & value,uint8 * target)751 inline 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 
WriteGroupToArray(int field_number,const MessageLite & value,uint8 * target)759 inline 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 }
WriteMessageToArray(int field_number,const MessageLite & value,uint8 * target)766 inline 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.
777 template<typename MessageType_WorkAroundCppLookupDefect>
WriteGroupNoVirtualToArray(int field_number,const MessageType_WorkAroundCppLookupDefect & value,uint8 * target)778 inline 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 }
786 template<typename MessageType_WorkAroundCppLookupDefect>
WriteMessageNoVirtualToArray(int field_number,const MessageType_WorkAroundCppLookupDefect & value,uint8 * target)787 inline 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 
Int32Size(int32 value)799 inline int WireFormatLite::Int32Size(int32 value) {
800   return io::CodedOutputStream::VarintSize32SignExtended(value);
801 }
Int64Size(int64 value)802 inline int WireFormatLite::Int64Size(int64 value) {
803   return io::CodedOutputStream::VarintSize64(static_cast<uint64>(value));
804 }
UInt32Size(uint32 value)805 inline int WireFormatLite::UInt32Size(uint32 value) {
806   return io::CodedOutputStream::VarintSize32(value);
807 }
UInt64Size(uint64 value)808 inline int WireFormatLite::UInt64Size(uint64 value) {
809   return io::CodedOutputStream::VarintSize64(value);
810 }
SInt32Size(int32 value)811 inline int WireFormatLite::SInt32Size(int32 value) {
812   return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value));
813 }
SInt64Size(int64 value)814 inline int WireFormatLite::SInt64Size(int64 value) {
815   return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value));
816 }
EnumSize(int value)817 inline int WireFormatLite::EnumSize(int value) {
818   return io::CodedOutputStream::VarintSize32SignExtended(value);
819 }
820 
StringSize(const string & value)821 inline int WireFormatLite::StringSize(const string& value) {
822   return io::CodedOutputStream::VarintSize32(value.size()) +
823          value.size();
824 }
BytesSize(const string & value)825 inline int WireFormatLite::BytesSize(const string& value) {
826   return io::CodedOutputStream::VarintSize32(value.size()) +
827          value.size();
828 }
829 
830 
GroupSize(const MessageLite & value)831 inline int WireFormatLite::GroupSize(const MessageLite& value) {
832   return value.ByteSize();
833 }
MessageSize(const MessageLite & value)834 inline 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.
840 template<typename MessageType_WorkAroundCppLookupDefect>
GroupSizeNoVirtual(const MessageType_WorkAroundCppLookupDefect & value)841 inline int WireFormatLite::GroupSizeNoVirtual(
842     const MessageType_WorkAroundCppLookupDefect& value) {
843   return value.MessageType_WorkAroundCppLookupDefect::ByteSize();
844 }
845 template<typename MessageType_WorkAroundCppLookupDefect>
MessageSizeNoVirtual(const MessageType_WorkAroundCppLookupDefect & value)846 inline int WireFormatLite::MessageSizeNoVirtual(
847     const MessageType_WorkAroundCppLookupDefect& value) {
848   return LengthDelimitedSize(
849       value.MessageType_WorkAroundCppLookupDefect::ByteSize());
850 }
851 
LengthDelimitedSize(int length)852 inline 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