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 (int 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