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