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