OLD | NEW |
1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
3 // https://developers.google.com/protocol-buffers/ | 3 // http://code.google.com/p/protobuf/ |
4 // | 4 // |
5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
7 // met: | 7 // met: |
8 // | 8 // |
9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
11 // * Redistributions in binary form must reproduce the above | 11 // * Redistributions in binary form must reproduce the above |
12 // copyright notice, this list of conditions and the following disclaimer | 12 // copyright notice, this list of conditions and the following disclaimer |
13 // in the documentation and/or other materials provided with the | 13 // in the documentation and/or other materials provided with the |
(...skipping 15 matching lines...) Expand all Loading... |
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 | 30 |
31 // Author: kenton@google.com (Kenton Varda) | 31 // Author: kenton@google.com (Kenton Varda) |
32 // wink@google.com (Wink Saville) (refactored from wire_format.h) | 32 // wink@google.com (Wink Saville) (refactored from wire_format.h) |
33 // Based on original Protocol Buffers design by | 33 // Based on original Protocol Buffers design by |
34 // Sanjay Ghemawat, Jeff Dean, and others. | 34 // Sanjay Ghemawat, Jeff Dean, and others. |
35 | 35 |
36 #ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__ | 36 #ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__ |
37 #define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__ | 37 #define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__ |
38 | 38 |
39 #ifdef _MSC_VER | |
40 // This is required for min/max on VS2013 only. | |
41 #include <algorithm> | |
42 #endif | |
43 | |
44 #include <string> | 39 #include <string> |
45 #include <google/protobuf/stubs/common.h> | 40 #include <google/protobuf/stubs/common.h> |
46 #include <google/protobuf/message_lite.h> | 41 #include <google/protobuf/message_lite.h> |
47 #include <google/protobuf/repeated_field.h> | 42 #include <google/protobuf/repeated_field.h> |
48 #include <google/protobuf/wire_format_lite.h> | 43 #include <google/protobuf/wire_format_lite.h> |
49 #include <google/protobuf/io/coded_stream.h> | 44 #include <google/protobuf/io/coded_stream.h> |
50 #include <google/protobuf/arenastring.h> | |
51 | 45 |
52 | 46 |
53 namespace google { | 47 namespace google { |
54 namespace protobuf { | 48 namespace protobuf { |
55 namespace internal { | 49 namespace internal { |
56 | 50 |
57 // Implementation details of ReadPrimitive. | 51 // Implementation details of ReadPrimitive. |
58 | 52 |
59 template <> | 53 template <> |
60 inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>( | 54 inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>( |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 double* value) { | 143 double* value) { |
150 uint64 temp; | 144 uint64 temp; |
151 if (!input->ReadLittleEndian64(&temp)) return false; | 145 if (!input->ReadLittleEndian64(&temp)) return false; |
152 *value = DecodeDouble(temp); | 146 *value = DecodeDouble(temp); |
153 return true; | 147 return true; |
154 } | 148 } |
155 template <> | 149 template <> |
156 inline bool WireFormatLite::ReadPrimitive<bool, WireFormatLite::TYPE_BOOL>( | 150 inline bool WireFormatLite::ReadPrimitive<bool, WireFormatLite::TYPE_BOOL>( |
157 io::CodedInputStream* input, | 151 io::CodedInputStream* input, |
158 bool* value) { | 152 bool* value) { |
159 uint64 temp; | 153 uint32 temp; |
160 if (!input->ReadVarint64(&temp)) return false; | 154 if (!input->ReadVarint32(&temp)) return false; |
161 *value = temp != 0; | 155 *value = temp != 0; |
162 return true; | 156 return true; |
163 } | 157 } |
164 template <> | 158 template <> |
165 inline bool WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>( | 159 inline bool WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>( |
166 io::CodedInputStream* input, | 160 io::CodedInputStream* input, |
167 int* value) { | 161 int* value) { |
168 uint32 temp; | 162 uint32 temp; |
169 if (!input->ReadVarint32(&temp)) return false; | 163 if (!input->ReadVarint32(&temp)) return false; |
170 *value = static_cast<int>(temp); | 164 *value = static_cast<int>(temp); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 double, WireFormatLite::TYPE_DOUBLE>( | 214 double, WireFormatLite::TYPE_DOUBLE>( |
221 const uint8* buffer, | 215 const uint8* buffer, |
222 double* value) { | 216 double* value) { |
223 uint64 temp; | 217 uint64 temp; |
224 buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp); | 218 buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp); |
225 *value = DecodeDouble(temp); | 219 *value = DecodeDouble(temp); |
226 return buffer; | 220 return buffer; |
227 } | 221 } |
228 | 222 |
229 template <typename CType, enum WireFormatLite::FieldType DeclaredType> | 223 template <typename CType, enum WireFormatLite::FieldType DeclaredType> |
230 inline bool WireFormatLite::ReadRepeatedPrimitive( | 224 inline bool WireFormatLite::ReadRepeatedPrimitive(int, // tag_size, unused. |
231 int, // tag_size, unused. | 225 uint32 tag, |
232 uint32 tag, | 226 io::CodedInputStream* input, |
233 io::CodedInputStream* input, | 227 RepeatedField<CType>* values) { |
234 RepeatedField<CType>* values) { | |
235 CType value; | 228 CType value; |
236 if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; | 229 if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; |
237 values->Add(value); | 230 values->Add(value); |
238 int elements_already_reserved = values->Capacity() - values->size(); | 231 int elements_already_reserved = values->Capacity() - values->size(); |
239 while (elements_already_reserved > 0 && input->ExpectTag(tag)) { | 232 while (elements_already_reserved > 0 && input->ExpectTag(tag)) { |
240 if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; | 233 if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; |
241 values->AddAlreadyReserved(value); | 234 values->AddAlreadyReserved(value); |
242 elements_already_reserved--; | 235 elements_already_reserved--; |
243 } | 236 } |
244 return true; | 237 return true; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 ++num_read; | 277 ++num_read; |
285 } | 278 } |
286 const int read_bytes = num_read * per_value_size; | 279 const int read_bytes = num_read * per_value_size; |
287 if (read_bytes > 0) { | 280 if (read_bytes > 0) { |
288 input->Skip(read_bytes); | 281 input->Skip(read_bytes); |
289 } | 282 } |
290 } | 283 } |
291 return true; | 284 return true; |
292 } | 285 } |
293 | 286 |
294 // Specializations of ReadRepeatedPrimitive for the fixed size types, which use | 287 // Specializations of ReadRepeatedPrimitive for the fixed size types, which use |
295 // the optimized code path. | 288 // the optimized code path. |
296 #define READ_REPEATED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE) \ | 289 #define READ_REPEATED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE) \ |
297 template <> \ | 290 template <> \ |
298 inline bool WireFormatLite::ReadRepeatedPrimitive< \ | 291 inline bool WireFormatLite::ReadRepeatedPrimitive< \ |
299 CPPTYPE, WireFormatLite::DECLARED_TYPE>( \ | 292 CPPTYPE, WireFormatLite::DECLARED_TYPE>( \ |
300 int tag_size, \ | 293 int tag_size, \ |
301 uint32 tag, \ | 294 uint32 tag, \ |
302 io::CodedInputStream* input, \ | 295 io::CodedInputStream* input, \ |
303 RepeatedField<CPPTYPE>* values) { \ | 296 RepeatedField<CPPTYPE>* values) { \ |
304 return ReadRepeatedFixedSizePrimitive< \ | 297 return ReadRepeatedFixedSizePrimitive< \ |
(...skipping 29 matching lines...) Expand all Loading... |
334 while (input->BytesUntilLimit() > 0) { | 327 while (input->BytesUntilLimit() > 0) { |
335 CType value; | 328 CType value; |
336 if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; | 329 if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; |
337 values->Add(value); | 330 values->Add(value); |
338 } | 331 } |
339 input->PopLimit(limit); | 332 input->PopLimit(limit); |
340 return true; | 333 return true; |
341 } | 334 } |
342 | 335 |
343 template <typename CType, enum WireFormatLite::FieldType DeclaredType> | 336 template <typename CType, enum WireFormatLite::FieldType DeclaredType> |
344 inline bool WireFormatLite::ReadPackedFixedSizePrimitive( | |
345 io::CodedInputStream* input, RepeatedField<CType>* values) { | |
346 uint32 length; | |
347 if (!input->ReadVarint32(&length)) return false; | |
348 const uint32 old_entries = values->size(); | |
349 const uint32 new_entries = length / sizeof(CType); | |
350 const uint32 new_bytes = new_entries * sizeof(CType); | |
351 if (new_bytes != length) return false; | |
352 // We would *like* to pre-allocate the buffer to write into (for | |
353 // speed), but *must* avoid performing a very large allocation due | |
354 // to a malicious user-supplied "length" above. So we have a fast | |
355 // path that pre-allocates when the "length" is less than a bound. | |
356 // We determine the bound by calling BytesUntilTotalBytesLimit() and | |
357 // BytesUntilLimit(). These return -1 to mean "no limit set". | |
358 // There are four cases: | |
359 // TotalBytesLimit Limit | |
360 // -1 -1 Use slow path. | |
361 // -1 >= 0 Use fast path if length <= Limit. | |
362 // >= 0 -1 Use slow path. | |
363 // >= 0 >= 0 Use fast path if length <= min(both limits). | |
364 int64 bytes_limit = input->BytesUntilTotalBytesLimit(); | |
365 if (bytes_limit == -1) { | |
366 bytes_limit = input->BytesUntilLimit(); | |
367 } else { | |
368 bytes_limit = | |
369 min(bytes_limit, static_cast<int64>(input->BytesUntilLimit())); | |
370 } | |
371 if (bytes_limit >= new_bytes) { | |
372 // Fast-path that pre-allocates *values to the final size. | |
373 #if defined(PROTOBUF_LITTLE_ENDIAN) | |
374 values->Resize(old_entries + new_entries, 0); | |
375 // values->mutable_data() may change after Resize(), so do this after: | |
376 void* dest = reinterpret_cast<void*>(values->mutable_data() + old_entries); | |
377 if (!input->ReadRaw(dest, new_bytes)) { | |
378 values->Truncate(old_entries); | |
379 return false; | |
380 } | |
381 #else | |
382 values->Reserve(old_entries + new_entries); | |
383 CType value; | |
384 for (uint32 i = 0; i < new_entries; ++i) { | |
385 if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; | |
386 values->AddAlreadyReserved(value); | |
387 } | |
388 #endif | |
389 } else { | |
390 // This is the slow-path case where "length" may be too large to | |
391 // safely allocate. We read as much as we can into *values | |
392 // without pre-allocating "length" bytes. | |
393 CType value; | |
394 for (uint32 i = 0; i < new_entries; ++i) { | |
395 if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; | |
396 values->Add(value); | |
397 } | |
398 } | |
399 return true; | |
400 } | |
401 | |
402 // Specializations of ReadPackedPrimitive for the fixed size types, which use | |
403 // an optimized code path. | |
404 #define READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE) \ | |
405 template <> \ | |
406 inline bool WireFormatLite::ReadPackedPrimitive< \ | |
407 CPPTYPE, WireFormatLite::DECLARED_TYPE>( \ | |
408 io::CodedInputStream* input, \ | |
409 RepeatedField<CPPTYPE>* values) { \ | |
410 return ReadPackedFixedSizePrimitive< \ | |
411 CPPTYPE, WireFormatLite::DECLARED_TYPE>(input, values); \ | |
412 } | |
413 | |
414 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32); | |
415 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64); | |
416 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32); | |
417 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64); | |
418 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT); | |
419 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE); | |
420 | |
421 #undef READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE | |
422 | |
423 template <typename CType, enum WireFormatLite::FieldType DeclaredType> | |
424 bool WireFormatLite::ReadPackedPrimitiveNoInline(io::CodedInputStream* input, | 337 bool WireFormatLite::ReadPackedPrimitiveNoInline(io::CodedInputStream* input, |
425 RepeatedField<CType>* values) { | 338 RepeatedField<CType>* values) { |
426 return ReadPackedPrimitive<CType, DeclaredType>(input, values); | 339 return ReadPackedPrimitive<CType, DeclaredType>(input, values); |
427 } | 340 } |
428 | 341 |
429 | 342 |
430 | |
431 inline bool WireFormatLite::ReadGroup(int field_number, | 343 inline bool WireFormatLite::ReadGroup(int field_number, |
432 io::CodedInputStream* input, | 344 io::CodedInputStream* input, |
433 MessageLite* value) { | 345 MessageLite* value) { |
434 if (!input->IncrementRecursionDepth()) return false; | 346 if (!input->IncrementRecursionDepth()) return false; |
435 if (!value->MergePartialFromCodedStream(input)) return false; | 347 if (!value->MergePartialFromCodedStream(input)) return false; |
436 input->DecrementRecursionDepth(); | 348 input->DecrementRecursionDepth(); |
437 // Make sure the last thing read was an end tag for this group. | 349 // Make sure the last thing read was an end tag for this group. |
438 if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) { | 350 if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) { |
439 return false; | 351 return false; |
440 } | 352 } |
441 return true; | 353 return true; |
442 } | 354 } |
443 inline bool WireFormatLite::ReadMessage(io::CodedInputStream* input, | 355 inline bool WireFormatLite::ReadMessage(io::CodedInputStream* input, |
444 MessageLite* value) { | 356 MessageLite* value) { |
445 uint32 length; | 357 uint32 length; |
446 if (!input->ReadVarint32(&length)) return false; | 358 if (!input->ReadVarint32(&length)) return false; |
447 std::pair<io::CodedInputStream::Limit, int> p = | 359 if (!input->IncrementRecursionDepth()) return false; |
448 input->IncrementRecursionDepthAndPushLimit(length); | 360 io::CodedInputStream::Limit limit = input->PushLimit(length); |
449 if (p.second < 0 || !value->MergePartialFromCodedStream(input)) return false; | 361 if (!value->MergePartialFromCodedStream(input)) return false; |
450 // Make sure that parsing stopped when the limit was hit, not at an endgroup | 362 // Make sure that parsing stopped when the limit was hit, not at an endgroup |
451 // tag. | 363 // tag. |
452 return input->DecrementRecursionDepthAndPopLimit(p.first); | 364 if (!input->ConsumedEntireMessage()) return false; |
| 365 input->PopLimit(limit); |
| 366 input->DecrementRecursionDepth(); |
| 367 return true; |
453 } | 368 } |
454 | 369 |
455 // We name the template parameter something long and extremely unlikely to occur | 370 // We name the template parameter something long and extremely unlikely to occur |
456 // elsewhere because a *qualified* member access expression designed to avoid | 371 // elsewhere because a *qualified* member access expression designed to avoid |
457 // virtual dispatch, C++03 [basic.lookup.classref] 3.4.5/4 requires that the | 372 // virtual dispatch, C++03 [basic.lookup.classref] 3.4.5/4 requires that the |
458 // name of the qualifying class to be looked up both in the context of the full | 373 // name of the qualifying class to be looked up both in the context of the full |
459 // expression (finding the template parameter) and in the context of the object | 374 // expression (finding the template parameter) and in the context of the object |
460 // whose member we are accessing. This could potentially find a nested type | 375 // whose member we are accessing. This could potentially find a nested type |
461 // within that object. The standard goes on to require these names to refer to | 376 // within that object. The standard goes on to require these names to refer to |
462 // the same entity, which this collision would violate. The lack of a safe way | 377 // the same entity, which this collision would violate. The lack of a safe way |
463 // to avoid this collision appears to be a defect in the standard, but until it | 378 // to avoid this collision appears to be a defect in the standard, but until it |
464 // is corrected, we choose the name to avoid accidental collisions. | 379 // is corrected, we choose the name to avoid accidental collisions. |
465 template<typename MessageType_WorkAroundCppLookupDefect> | 380 template<typename MessageType_WorkAroundCppLookupDefect> |
466 inline bool WireFormatLite::ReadGroupNoVirtual( | 381 inline bool WireFormatLite::ReadGroupNoVirtual( |
467 int field_number, io::CodedInputStream* input, | 382 int field_number, io::CodedInputStream* input, |
468 MessageType_WorkAroundCppLookupDefect* value) { | 383 MessageType_WorkAroundCppLookupDefect* value) { |
469 if (!input->IncrementRecursionDepth()) return false; | 384 if (!input->IncrementRecursionDepth()) return false; |
470 if (!value-> | 385 if (!value-> |
471 MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input)) | 386 MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input)) |
472 return false; | 387 return false; |
473 input->UnsafeDecrementRecursionDepth(); | 388 input->DecrementRecursionDepth(); |
474 // Make sure the last thing read was an end tag for this group. | 389 // Make sure the last thing read was an end tag for this group. |
475 if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) { | 390 if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) { |
476 return false; | 391 return false; |
477 } | 392 } |
478 return true; | 393 return true; |
479 } | 394 } |
480 template<typename MessageType_WorkAroundCppLookupDefect> | 395 template<typename MessageType_WorkAroundCppLookupDefect> |
481 inline bool WireFormatLite::ReadGroupNoVirtualNoRecursionDepth( | |
482 int field_number, io::CodedInputStream* input, | |
483 MessageType_WorkAroundCppLookupDefect* value) { | |
484 return value->MessageType_WorkAroundCppLookupDefect:: | |
485 MergePartialFromCodedStream(input) && | |
486 input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP)); | |
487 } | |
488 template<typename MessageType_WorkAroundCppLookupDefect> | |
489 inline bool WireFormatLite::ReadMessageNoVirtual( | 396 inline bool WireFormatLite::ReadMessageNoVirtual( |
490 io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) { | 397 io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) { |
491 uint32 length; | 398 uint32 length; |
492 if (!input->ReadVarint32(&length)) return false; | 399 if (!input->ReadVarint32(&length)) return false; |
493 std::pair<io::CodedInputStream::Limit, int> p = | 400 if (!input->IncrementRecursionDepth()) return false; |
494 input->IncrementRecursionDepthAndPushLimit(length); | 401 io::CodedInputStream::Limit limit = input->PushLimit(length); |
495 if (p.second < 0 || !value-> | |
496 MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input)) | |
497 return false; | |
498 // Make sure that parsing stopped when the limit was hit, not at an endgroup | |
499 // tag. | |
500 return input->DecrementRecursionDepthAndPopLimit(p.first); | |
501 } | |
502 template<typename MessageType_WorkAroundCppLookupDefect> | |
503 inline bool WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( | |
504 io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) { | |
505 io::CodedInputStream::Limit old_limit = input->ReadLengthAndPushLimit(); | |
506 if (!value-> | 402 if (!value-> |
507 MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input)) | 403 MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input)) |
508 return false; | 404 return false; |
509 // Make sure that parsing stopped when the limit was hit, not at an endgroup | 405 // Make sure that parsing stopped when the limit was hit, not at an endgroup |
510 // tag. | 406 // tag. |
511 return input->CheckEntireMessageConsumedAndPopLimit(old_limit); | 407 if (!input->ConsumedEntireMessage()) return false; |
| 408 input->PopLimit(limit); |
| 409 input->DecrementRecursionDepth(); |
| 410 return true; |
512 } | 411 } |
513 | 412 |
514 // =================================================================== | 413 // =================================================================== |
515 | 414 |
516 inline void WireFormatLite::WriteTag(int field_number, WireType type, | 415 inline void WireFormatLite::WriteTag(int field_number, WireType type, |
517 io::CodedOutputStream* output) { | 416 io::CodedOutputStream* output) { |
518 output->WriteTag(MakeTag(field_number, type)); | 417 output->WriteTag(MakeTag(field_number, type)); |
519 } | 418 } |
520 | 419 |
521 inline void WireFormatLite::WriteInt32NoTag(int32 value, | 420 inline void WireFormatLite::WriteInt32NoTag(int32 value, |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
754 } | 653 } |
755 | 654 |
756 inline uint8* WireFormatLite::WriteStringToArray(int field_number, | 655 inline uint8* WireFormatLite::WriteStringToArray(int field_number, |
757 const string& value, | 656 const string& value, |
758 uint8* target) { | 657 uint8* target) { |
759 // String is for UTF-8 text only | 658 // String is for UTF-8 text only |
760 // WARNING: In wire_format.cc, both strings and bytes are handled by | 659 // WARNING: In wire_format.cc, both strings and bytes are handled by |
761 // WriteString() to avoid code duplication. If the implementations become | 660 // WriteString() to avoid code duplication. If the implementations become |
762 // different, you will need to update that usage. | 661 // different, you will need to update that usage. |
763 target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); | 662 target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); |
764 return io::CodedOutputStream::WriteStringWithSizeToArray(value, target); | 663 target = io::CodedOutputStream::WriteVarint32ToArray(value.size(), target); |
| 664 return io::CodedOutputStream::WriteStringToArray(value, target); |
765 } | 665 } |
766 inline uint8* WireFormatLite::WriteBytesToArray(int field_number, | 666 inline uint8* WireFormatLite::WriteBytesToArray(int field_number, |
767 const string& value, | 667 const string& value, |
768 uint8* target) { | 668 uint8* target) { |
769 target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); | 669 target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); |
770 return io::CodedOutputStream::WriteStringWithSizeToArray(value, target); | 670 target = io::CodedOutputStream::WriteVarint32ToArray(value.size(), target); |
| 671 return io::CodedOutputStream::WriteStringToArray(value, target); |
771 } | 672 } |
772 | 673 |
773 | 674 |
774 inline uint8* WireFormatLite::WriteGroupToArray(int field_number, | 675 inline uint8* WireFormatLite::WriteGroupToArray(int field_number, |
775 const MessageLite& value, | 676 const MessageLite& value, |
776 uint8* target) { | 677 uint8* target) { |
777 target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target); | 678 target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target); |
778 target = value.SerializeWithCachedSizesToArray(target); | 679 target = value.SerializeWithCachedSizesToArray(target); |
779 return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target); | 680 return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target); |
780 } | 681 } |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
866 | 767 |
867 inline int WireFormatLite::LengthDelimitedSize(int length) { | 768 inline int WireFormatLite::LengthDelimitedSize(int length) { |
868 return io::CodedOutputStream::VarintSize32(length) + length; | 769 return io::CodedOutputStream::VarintSize32(length) + length; |
869 } | 770 } |
870 | 771 |
871 } // namespace internal | 772 } // namespace internal |
872 } // namespace protobuf | 773 } // namespace protobuf |
873 | 774 |
874 } // namespace google | 775 } // namespace google |
875 #endif // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__ | 776 #endif // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__ |
OLD | NEW |