Line data Source code
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 519 : if (!input->ReadVarint32(&temp)) return false;
64 519 : *value = static_cast<int32>(temp);
65 519 : 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 0 : if (!input->ReadVarint64(&temp)) return false;
73 0 : *value = static_cast<int64>(temp);
74 0 : return true;
75 : }
76 : template <>
77 : inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_UINT32>(
78 : io::CodedInputStream* input,
79 : uint32* value) {
80 0 : return input->ReadVarint32(value);
81 : }
82 : template <>
83 : inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_UINT64>(
84 : io::CodedInputStream* input,
85 : uint64* value) {
86 0 : 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 0 : if (!input->ReadVarint32(&temp)) return false;
94 0 : *value = ZigZagDecode32(temp);
95 0 : 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 0 : if (!input->ReadVarint64(&temp)) return false;
103 0 : *value = ZigZagDecode64(temp);
104 0 : return true;
105 : }
106 : template <>
107 : inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_FIXED32>(
108 : io::CodedInputStream* input,
109 : uint32* value) {
110 0 : return input->ReadLittleEndian32(value);
111 : }
112 : template <>
113 : inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_FIXED64>(
114 : io::CodedInputStream* input,
115 : uint64* value) {
116 0 : 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 0 : if (!input->ReadLittleEndian32(&temp)) return false;
124 0 : *value = static_cast<int32>(temp);
125 0 : 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 0 : if (!input->ReadLittleEndian64(&temp)) return false;
133 0 : *value = static_cast<int64>(temp);
134 0 : 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 0 : if (!input->ReadLittleEndian32(&temp)) return false;
142 0 : *value = DecodeFloat(temp);
143 0 : 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 0 : if (!input->ReadLittleEndian64(&temp)) return false;
151 0 : *value = DecodeDouble(temp);
152 0 : 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 6 : if (!input->ReadVarint64(&temp)) return false;
160 6 : *value = temp != 0;
161 6 : 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 711 : if (!input->ReadVarint32(&temp)) return false;
169 711 : *value = static_cast<int>(temp);
170 711 : 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 0 : buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp);
214 0 : *value = DecodeFloat(temp);
215 0 : 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>
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 0 : if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
236 0 : values->Add(value);
237 0 : int elements_already_reserved = values->Capacity() - values->size();
238 0 : while (elements_already_reserved > 0 && input->ExpectTag(tag)) {
239 0 : if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
240 0 : values->AddAlreadyReserved(value);
241 0 : elements_already_reserved--;
242 : }
243 0 : return true;
244 : }
245 :
246 : template <typename CType, enum WireFormatLite::FieldType DeclaredType>
247 : inline bool WireFormatLite::ReadRepeatedFixedSizePrimitive(
248 : int tag_size,
249 : uint32 tag,
250 : io::CodedInputStream* input,
251 : RepeatedField<CType>* values) {
252 0 : GOOGLE_DCHECK_EQ(UInt32Size(tag), tag_size);
253 : CType value;
254 0 : if (!ReadPrimitive<CType, DeclaredType>(input, &value))
255 0 : return false;
256 0 : 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 0 : if (size > 0) {
271 0 : const uint8* buffer = reinterpret_cast<const uint8*>(void_pointer);
272 : // The number of bytes each type occupies on the wire.
273 0 : const int per_value_size = tag_size + sizeof(value);
274 :
275 0 : int elements_available = min(values->Capacity() - values->size(),
276 0 : size / per_value_size);
277 0 : int num_read = 0;
278 0 : while (num_read < elements_available &&
279 : (buffer = io::CodedInputStream::ExpectTagFromArray(
280 : buffer, tag)) != NULL) {
281 0 : buffer = ReadPrimitiveFromArray<CType, DeclaredType>(buffer, &value);
282 0 : values->AddAlreadyReserved(value);
283 0 : ++num_read;
284 : }
285 0 : const int read_bytes = num_read * per_value_size;
286 0 : if (read_bytes > 0) {
287 0 : input->Skip(read_bytes);
288 : }
289 : }
290 0 : 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 :
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 0 : 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 0 : bool WireFormatLite::ReadRepeatedPrimitiveNoInline(
319 : int tag_size,
320 : uint32 tag,
321 : io::CodedInputStream* input,
322 : RepeatedField<CType>* value) {
323 : return ReadRepeatedPrimitive<CType, DeclaredType>(
324 0 : tag_size, tag, input, value);
325 : }
326 :
327 : template <typename CType, enum WireFormatLite::FieldType DeclaredType>
328 : inline bool WireFormatLite::ReadPackedPrimitive(io::CodedInputStream* input,
329 : RepeatedField<CType>* values) {
330 : uint32 length;
331 0 : if (!input->ReadVarint32(&length)) return false;
332 0 : io::CodedInputStream::Limit limit = input->PushLimit(length);
333 0 : while (input->BytesUntilLimit() > 0) {
334 : CType value;
335 0 : if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
336 0 : values->Add(value);
337 : }
338 0 : input->PopLimit(limit);
339 0 : return true;
340 : }
341 :
342 : template <typename CType, enum WireFormatLite::FieldType DeclaredType>
343 : inline bool WireFormatLite::ReadPackedFixedSizePrimitive(
344 : io::CodedInputStream* input, RepeatedField<CType>* values) {
345 : uint32 length;
346 0 : if (!input->ReadVarint32(&length)) return false;
347 0 : const uint32 old_entries = values->size();
348 0 : const uint32 new_entries = length / sizeof(CType);
349 0 : const uint32 new_bytes = new_entries * sizeof(CType);
350 0 : 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 0 : int64 bytes_limit = input->BytesUntilTotalBytesLimit();
364 0 : if (bytes_limit == -1) {
365 0 : bytes_limit = input->BytesUntilLimit();
366 : } else {
367 0 : bytes_limit =
368 0 : min(bytes_limit, static_cast<int64>(input->BytesUntilLimit()));
369 : }
370 0 : if (bytes_limit >= new_bytes) {
371 : // Fast-path that pre-allocates *values to the final size.
372 : #if defined(PROTOBUF_LITTLE_ENDIAN)
373 0 : values->Resize(old_entries + new_entries, 0);
374 : // values->mutable_data() may change after Resize(), so do this after:
375 0 : void* dest = reinterpret_cast<void*>(values->mutable_data() + old_entries);
376 0 : if (!input->ReadRaw(dest, new_bytes)) {
377 0 : values->Truncate(old_entries);
378 0 : 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 0 : for (uint32 i = 0; i < new_entries; ++i) {
394 0 : if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
395 0 : values->Add(value);
396 : }
397 : }
398 0 : 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 0 : 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>
423 0 : bool WireFormatLite::ReadPackedPrimitiveNoInline(io::CodedInputStream* input,
424 : RepeatedField<CType>* values) {
425 0 : return ReadPackedPrimitive<CType, DeclaredType>(input, values);
426 : }
427 :
428 :
429 0 : inline bool WireFormatLite::ReadGroup(int field_number,
430 : io::CodedInputStream* input,
431 : MessageLite* value) {
432 0 : if (!input->IncrementRecursionDepth()) return false;
433 0 : if (!value->MergePartialFromCodedStream(input)) return false;
434 0 : input->DecrementRecursionDepth();
435 : // Make sure the last thing read was an end tag for this group.
436 0 : if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) {
437 0 : return false;
438 : }
439 0 : return true;
440 : }
441 0 : inline bool WireFormatLite::ReadMessage(io::CodedInputStream* input,
442 : MessageLite* value) {
443 : uint32 length;
444 0 : if (!input->ReadVarint32(&length)) return false;
445 0 : if (!input->IncrementRecursionDepth()) return false;
446 0 : io::CodedInputStream::Limit limit = input->PushLimit(length);
447 0 : if (!value->MergePartialFromCodedStream(input)) return false;
448 : // Make sure that parsing stopped when the limit was hit, not at an endgroup
449 : // tag.
450 0 : if (!input->ConsumedEntireMessage()) return false;
451 0 : input->PopLimit(limit);
452 0 : input->DecrementRecursionDepth();
453 0 : 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>
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>
482 576 : inline bool WireFormatLite::ReadMessageNoVirtual(
483 : io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) {
484 : uint32 length;
485 576 : if (!input->ReadVarint32(&length)) return false;
486 576 : if (!input->IncrementRecursionDepth()) return false;
487 576 : io::CodedInputStream::Limit limit = input->PushLimit(length);
488 576 : if (!value->
489 : MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input))
490 0 : return false;
491 : // Make sure that parsing stopped when the limit was hit, not at an endgroup
492 : // tag.
493 576 : if (!input->ConsumedEntireMessage()) return false;
494 576 : input->PopLimit(limit);
495 576 : input->DecrementRecursionDepth();
496 576 : return true;
497 : }
498 :
499 : // ===================================================================
500 :
501 : inline void WireFormatLite::WriteTag(int field_number, WireType type,
502 : io::CodedOutputStream* output) {
503 0 : output->WriteTag(MakeTag(field_number, type));
504 : }
505 :
506 : inline void WireFormatLite::WriteInt32NoTag(int32 value,
507 : io::CodedOutputStream* output) {
508 0 : output->WriteVarint32SignExtended(value);
509 : }
510 : inline void WireFormatLite::WriteInt64NoTag(int64 value,
511 : io::CodedOutputStream* output) {
512 0 : output->WriteVarint64(static_cast<uint64>(value));
513 : }
514 : inline void WireFormatLite::WriteUInt32NoTag(uint32 value,
515 : io::CodedOutputStream* output) {
516 0 : output->WriteVarint32(value);
517 : }
518 : inline void WireFormatLite::WriteUInt64NoTag(uint64 value,
519 : io::CodedOutputStream* output) {
520 0 : output->WriteVarint64(value);
521 : }
522 : inline void WireFormatLite::WriteSInt32NoTag(int32 value,
523 : io::CodedOutputStream* output) {
524 0 : output->WriteVarint32(ZigZagEncode32(value));
525 : }
526 : inline void WireFormatLite::WriteSInt64NoTag(int64 value,
527 : io::CodedOutputStream* output) {
528 0 : output->WriteVarint64(ZigZagEncode64(value));
529 : }
530 : inline void WireFormatLite::WriteFixed32NoTag(uint32 value,
531 : io::CodedOutputStream* output) {
532 0 : output->WriteLittleEndian32(value);
533 : }
534 : inline void WireFormatLite::WriteFixed64NoTag(uint64 value,
535 : io::CodedOutputStream* output) {
536 0 : output->WriteLittleEndian64(value);
537 : }
538 : inline void WireFormatLite::WriteSFixed32NoTag(int32 value,
539 : io::CodedOutputStream* output) {
540 0 : output->WriteLittleEndian32(static_cast<uint32>(value));
541 : }
542 : inline void WireFormatLite::WriteSFixed64NoTag(int64 value,
543 : io::CodedOutputStream* output) {
544 0 : output->WriteLittleEndian64(static_cast<uint64>(value));
545 : }
546 : inline void WireFormatLite::WriteFloatNoTag(float value,
547 : io::CodedOutputStream* output) {
548 0 : output->WriteLittleEndian32(EncodeFloat(value));
549 : }
550 : inline void WireFormatLite::WriteDoubleNoTag(double value,
551 : io::CodedOutputStream* output) {
552 0 : output->WriteLittleEndian64(EncodeDouble(value));
553 : }
554 : inline void WireFormatLite::WriteBoolNoTag(bool value,
555 : io::CodedOutputStream* output) {
556 0 : output->WriteVarint32(value ? 1 : 0);
557 : }
558 : inline void WireFormatLite::WriteEnumNoTag(int value,
559 : io::CodedOutputStream* output) {
560 0 : 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>
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>
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 :
585 : inline uint8* WireFormatLite::WriteTagToArray(int field_number,
586 : WireType type,
587 : uint8* target) {
588 0 : return io::CodedOutputStream::WriteTagToArray(MakeTag(field_number, type),
589 0 : target);
590 : }
591 :
592 : inline uint8* WireFormatLite::WriteInt32NoTagToArray(int32 value,
593 : uint8* target) {
594 0 : return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
595 : }
596 : inline uint8* WireFormatLite::WriteInt64NoTagToArray(int64 value,
597 : uint8* target) {
598 0 : return io::CodedOutputStream::WriteVarint64ToArray(
599 0 : static_cast<uint64>(value), target);
600 : }
601 : inline uint8* WireFormatLite::WriteUInt32NoTagToArray(uint32 value,
602 : uint8* target) {
603 0 : return io::CodedOutputStream::WriteVarint32ToArray(value, target);
604 : }
605 : inline uint8* WireFormatLite::WriteUInt64NoTagToArray(uint64 value,
606 : uint8* target) {
607 0 : return io::CodedOutputStream::WriteVarint64ToArray(value, target);
608 : }
609 : inline uint8* WireFormatLite::WriteSInt32NoTagToArray(int32 value,
610 : uint8* target) {
611 0 : return io::CodedOutputStream::WriteVarint32ToArray(ZigZagEncode32(value),
612 0 : target);
613 : }
614 : inline uint8* WireFormatLite::WriteSInt64NoTagToArray(int64 value,
615 : uint8* target) {
616 0 : return io::CodedOutputStream::WriteVarint64ToArray(ZigZagEncode64(value),
617 0 : target);
618 : }
619 : inline uint8* WireFormatLite::WriteFixed32NoTagToArray(uint32 value,
620 : uint8* target) {
621 0 : return io::CodedOutputStream::WriteLittleEndian32ToArray(value, target);
622 : }
623 : inline uint8* WireFormatLite::WriteFixed64NoTagToArray(uint64 value,
624 : uint8* target) {
625 0 : return io::CodedOutputStream::WriteLittleEndian64ToArray(value, target);
626 : }
627 : inline uint8* WireFormatLite::WriteSFixed32NoTagToArray(int32 value,
628 : uint8* target) {
629 0 : return io::CodedOutputStream::WriteLittleEndian32ToArray(
630 0 : static_cast<uint32>(value), target);
631 : }
632 : inline uint8* WireFormatLite::WriteSFixed64NoTagToArray(int64 value,
633 : uint8* target) {
634 0 : return io::CodedOutputStream::WriteLittleEndian64ToArray(
635 0 : static_cast<uint64>(value), target);
636 : }
637 : inline uint8* WireFormatLite::WriteFloatNoTagToArray(float value,
638 : uint8* target) {
639 0 : return io::CodedOutputStream::WriteLittleEndian32ToArray(EncodeFloat(value),
640 0 : target);
641 : }
642 : inline uint8* WireFormatLite::WriteDoubleNoTagToArray(double value,
643 : uint8* target) {
644 0 : return io::CodedOutputStream::WriteLittleEndian64ToArray(EncodeDouble(value),
645 0 : target);
646 : }
647 : inline uint8* WireFormatLite::WriteBoolNoTagToArray(bool value,
648 : uint8* target) {
649 0 : return io::CodedOutputStream::WriteVarint32ToArray(value ? 1 : 0, target);
650 : }
651 : inline uint8* WireFormatLite::WriteEnumNoTagToArray(int value,
652 : uint8* target) {
653 0 : return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
654 : }
655 :
656 : inline uint8* WireFormatLite::WriteInt32ToArray(int field_number,
657 : int32 value,
658 : uint8* target) {
659 0 : target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
660 0 : return WriteInt32NoTagToArray(value, target);
661 : }
662 : inline uint8* WireFormatLite::WriteInt64ToArray(int field_number,
663 : int64 value,
664 : uint8* target) {
665 0 : target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
666 0 : return WriteInt64NoTagToArray(value, target);
667 : }
668 : inline uint8* WireFormatLite::WriteUInt32ToArray(int field_number,
669 : uint32 value,
670 : uint8* target) {
671 0 : target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
672 0 : return WriteUInt32NoTagToArray(value, target);
673 : }
674 : inline uint8* WireFormatLite::WriteUInt64ToArray(int field_number,
675 : uint64 value,
676 : uint8* target) {
677 0 : target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
678 0 : return WriteUInt64NoTagToArray(value, target);
679 : }
680 : inline uint8* WireFormatLite::WriteSInt32ToArray(int field_number,
681 : int32 value,
682 : uint8* target) {
683 0 : target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
684 0 : return WriteSInt32NoTagToArray(value, target);
685 : }
686 : inline uint8* WireFormatLite::WriteSInt64ToArray(int field_number,
687 : int64 value,
688 : uint8* target) {
689 0 : target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
690 0 : return WriteSInt64NoTagToArray(value, target);
691 : }
692 : inline uint8* WireFormatLite::WriteFixed32ToArray(int field_number,
693 : uint32 value,
694 : uint8* target) {
695 0 : target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
696 0 : return WriteFixed32NoTagToArray(value, target);
697 : }
698 : inline uint8* WireFormatLite::WriteFixed64ToArray(int field_number,
699 : uint64 value,
700 : uint8* target) {
701 0 : target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
702 0 : return WriteFixed64NoTagToArray(value, target);
703 : }
704 : inline uint8* WireFormatLite::WriteSFixed32ToArray(int field_number,
705 : int32 value,
706 : uint8* target) {
707 0 : target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
708 0 : return WriteSFixed32NoTagToArray(value, target);
709 : }
710 : inline uint8* WireFormatLite::WriteSFixed64ToArray(int field_number,
711 : int64 value,
712 : uint8* target) {
713 0 : target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
714 0 : return WriteSFixed64NoTagToArray(value, target);
715 : }
716 : inline uint8* WireFormatLite::WriteFloatToArray(int field_number,
717 : float value,
718 : uint8* target) {
719 0 : target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
720 0 : return WriteFloatNoTagToArray(value, target);
721 : }
722 : inline uint8* WireFormatLite::WriteDoubleToArray(int field_number,
723 : double value,
724 : uint8* target) {
725 0 : target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
726 0 : return WriteDoubleNoTagToArray(value, target);
727 : }
728 : inline uint8* WireFormatLite::WriteBoolToArray(int field_number,
729 : bool value,
730 : uint8* target) {
731 0 : target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
732 0 : return WriteBoolNoTagToArray(value, target);
733 : }
734 : inline uint8* WireFormatLite::WriteEnumToArray(int field_number,
735 : int value,
736 : uint8* target) {
737 0 : target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
738 0 : return WriteEnumNoTagToArray(value, target);
739 : }
740 :
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 0 : target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
749 0 : return io::CodedOutputStream::WriteStringWithSizeToArray(value, target);
750 : }
751 : inline uint8* WireFormatLite::WriteBytesToArray(int field_number,
752 : const string& value,
753 : uint8* target) {
754 0 : target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
755 0 : return io::CodedOutputStream::WriteStringWithSizeToArray(value, target);
756 : }
757 :
758 :
759 : inline uint8* WireFormatLite::WriteGroupToArray(int field_number,
760 : const MessageLite& value,
761 : uint8* target) {
762 0 : target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
763 0 : target = value.SerializeWithCachedSizesToArray(target);
764 0 : return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
765 : }
766 : inline uint8* WireFormatLite::WriteMessageToArray(int field_number,
767 : const MessageLite& value,
768 : uint8* target) {
769 0 : target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
770 0 : target = io::CodedOutputStream::WriteVarint32ToArray(
771 0 : value.GetCachedSize(), target);
772 0 : 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>
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>
787 : inline uint8* WireFormatLite::WriteMessageNoVirtualToArray(
788 : int field_number, const MessageType_WorkAroundCppLookupDefect& value,
789 : uint8* target) {
790 0 : target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
791 0 : target = io::CodedOutputStream::WriteVarint32ToArray(
792 : value.MessageType_WorkAroundCppLookupDefect::GetCachedSize(), target);
793 : return value.MessageType_WorkAroundCppLookupDefect
794 0 : ::SerializeWithCachedSizesToArray(target);
795 : }
796 :
797 : // ===================================================================
798 :
799 0 : inline int WireFormatLite::Int32Size(int32 value) {
800 0 : return io::CodedOutputStream::VarintSize32SignExtended(value);
801 : }
802 0 : inline int WireFormatLite::Int64Size(int64 value) {
803 0 : return io::CodedOutputStream::VarintSize64(static_cast<uint64>(value));
804 : }
805 0 : inline int WireFormatLite::UInt32Size(uint32 value) {
806 0 : return io::CodedOutputStream::VarintSize32(value);
807 : }
808 0 : inline int WireFormatLite::UInt64Size(uint64 value) {
809 0 : return io::CodedOutputStream::VarintSize64(value);
810 : }
811 0 : inline int WireFormatLite::SInt32Size(int32 value) {
812 0 : return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value));
813 : }
814 0 : inline int WireFormatLite::SInt64Size(int64 value) {
815 0 : return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value));
816 : }
817 0 : inline int WireFormatLite::EnumSize(int value) {
818 0 : return io::CodedOutputStream::VarintSize32SignExtended(value);
819 : }
820 :
821 0 : inline int WireFormatLite::StringSize(const string& value) {
822 0 : return io::CodedOutputStream::VarintSize32(value.size()) +
823 0 : value.size();
824 : }
825 0 : inline int WireFormatLite::BytesSize(const string& value) {
826 0 : return io::CodedOutputStream::VarintSize32(value.size()) +
827 0 : value.size();
828 : }
829 :
830 :
831 0 : inline int WireFormatLite::GroupSize(const MessageLite& value) {
832 0 : return value.ByteSize();
833 : }
834 0 : inline int WireFormatLite::MessageSize(const MessageLite& value) {
835 0 : 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>
841 : inline int WireFormatLite::GroupSizeNoVirtual(
842 : const MessageType_WorkAroundCppLookupDefect& value) {
843 : return value.MessageType_WorkAroundCppLookupDefect::ByteSize();
844 : }
845 : template<typename MessageType_WorkAroundCppLookupDefect>
846 0 : inline int WireFormatLite::MessageSizeNoVirtual(
847 : const MessageType_WorkAroundCppLookupDefect& value) {
848 0 : return LengthDelimitedSize(
849 0 : value.MessageType_WorkAroundCppLookupDefect::ByteSize());
850 : }
851 :
852 0 : inline int WireFormatLite::LengthDelimitedSize(int length) {
853 0 : 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__
|