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 (at) google.com (Kenton Varda) 32 // wink (at) 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> 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> 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 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> 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> 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> 423 bool WireFormatLite::ReadPackedPrimitiveNoInline(io::CodedInputStream* input, 424 RepeatedField<CType>* values) { 425 return ReadPackedPrimitive<CType, DeclaredType>(input, values); 426 } 427 428 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 } 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> 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 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 501 inline void WireFormatLite::WriteTag(int field_number, WireType type, 502 io::CodedOutputStream* output) { 503 output->WriteTag(MakeTag(field_number, type)); 504 } 505 506 inline void WireFormatLite::WriteInt32NoTag(int32 value, 507 io::CodedOutputStream* output) { 508 output->WriteVarint32SignExtended(value); 509 } 510 inline void WireFormatLite::WriteInt64NoTag(int64 value, 511 io::CodedOutputStream* output) { 512 output->WriteVarint64(static_cast<uint64>(value)); 513 } 514 inline void WireFormatLite::WriteUInt32NoTag(uint32 value, 515 io::CodedOutputStream* output) { 516 output->WriteVarint32(value); 517 } 518 inline void WireFormatLite::WriteUInt64NoTag(uint64 value, 519 io::CodedOutputStream* output) { 520 output->WriteVarint64(value); 521 } 522 inline void WireFormatLite::WriteSInt32NoTag(int32 value, 523 io::CodedOutputStream* output) { 524 output->WriteVarint32(ZigZagEncode32(value)); 525 } 526 inline void WireFormatLite::WriteSInt64NoTag(int64 value, 527 io::CodedOutputStream* output) { 528 output->WriteVarint64(ZigZagEncode64(value)); 529 } 530 inline void WireFormatLite::WriteFixed32NoTag(uint32 value, 531 io::CodedOutputStream* output) { 532 output->WriteLittleEndian32(value); 533 } 534 inline void WireFormatLite::WriteFixed64NoTag(uint64 value, 535 io::CodedOutputStream* output) { 536 output->WriteLittleEndian64(value); 537 } 538 inline void WireFormatLite::WriteSFixed32NoTag(int32 value, 539 io::CodedOutputStream* output) { 540 output->WriteLittleEndian32(static_cast<uint32>(value)); 541 } 542 inline void WireFormatLite::WriteSFixed64NoTag(int64 value, 543 io::CodedOutputStream* output) { 544 output->WriteLittleEndian64(static_cast<uint64>(value)); 545 } 546 inline void WireFormatLite::WriteFloatNoTag(float value, 547 io::CodedOutputStream* output) { 548 output->WriteLittleEndian32(EncodeFloat(value)); 549 } 550 inline void WireFormatLite::WriteDoubleNoTag(double value, 551 io::CodedOutputStream* output) { 552 output->WriteLittleEndian64(EncodeDouble(value)); 553 } 554 inline void WireFormatLite::WriteBoolNoTag(bool value, 555 io::CodedOutputStream* output) { 556 output->WriteVarint32(value ? 1 : 0); 557 } 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> 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 return io::CodedOutputStream::WriteTagToArray(MakeTag(field_number, type), 589 target); 590 } 591 592 inline uint8* WireFormatLite::WriteInt32NoTagToArray(int32 value, 593 uint8* target) { 594 return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target); 595 } 596 inline uint8* WireFormatLite::WriteInt64NoTagToArray(int64 value, 597 uint8* target) { 598 return io::CodedOutputStream::WriteVarint64ToArray( 599 static_cast<uint64>(value), target); 600 } 601 inline uint8* WireFormatLite::WriteUInt32NoTagToArray(uint32 value, 602 uint8* target) { 603 return io::CodedOutputStream::WriteVarint32ToArray(value, target); 604 } 605 inline uint8* WireFormatLite::WriteUInt64NoTagToArray(uint64 value, 606 uint8* target) { 607 return io::CodedOutputStream::WriteVarint64ToArray(value, target); 608 } 609 inline uint8* WireFormatLite::WriteSInt32NoTagToArray(int32 value, 610 uint8* target) { 611 return io::CodedOutputStream::WriteVarint32ToArray(ZigZagEncode32(value), 612 target); 613 } 614 inline uint8* WireFormatLite::WriteSInt64NoTagToArray(int64 value, 615 uint8* target) { 616 return io::CodedOutputStream::WriteVarint64ToArray(ZigZagEncode64(value), 617 target); 618 } 619 inline uint8* WireFormatLite::WriteFixed32NoTagToArray(uint32 value, 620 uint8* target) { 621 return io::CodedOutputStream::WriteLittleEndian32ToArray(value, target); 622 } 623 inline uint8* WireFormatLite::WriteFixed64NoTagToArray(uint64 value, 624 uint8* target) { 625 return io::CodedOutputStream::WriteLittleEndian64ToArray(value, target); 626 } 627 inline uint8* WireFormatLite::WriteSFixed32NoTagToArray(int32 value, 628 uint8* target) { 629 return io::CodedOutputStream::WriteLittleEndian32ToArray( 630 static_cast<uint32>(value), target); 631 } 632 inline uint8* WireFormatLite::WriteSFixed64NoTagToArray(int64 value, 633 uint8* target) { 634 return io::CodedOutputStream::WriteLittleEndian64ToArray( 635 static_cast<uint64>(value), target); 636 } 637 inline uint8* WireFormatLite::WriteFloatNoTagToArray(float value, 638 uint8* target) { 639 return io::CodedOutputStream::WriteLittleEndian32ToArray(EncodeFloat(value), 640 target); 641 } 642 inline uint8* WireFormatLite::WriteDoubleNoTagToArray(double value, 643 uint8* target) { 644 return io::CodedOutputStream::WriteLittleEndian64ToArray(EncodeDouble(value), 645 target); 646 } 647 inline uint8* WireFormatLite::WriteBoolNoTagToArray(bool value, 648 uint8* target) { 649 return io::CodedOutputStream::WriteVarint32ToArray(value ? 1 : 0, target); 650 } 651 inline uint8* WireFormatLite::WriteEnumNoTagToArray(int value, 652 uint8* target) { 653 return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target); 654 } 655 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 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 } 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 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 } 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> 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 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 799 inline int WireFormatLite::Int32Size(int32 value) { 800 return io::CodedOutputStream::VarintSize32SignExtended(value); 801 } 802 inline int WireFormatLite::Int64Size(int64 value) { 803 return io::CodedOutputStream::VarintSize64(static_cast<uint64>(value)); 804 } 805 inline int WireFormatLite::UInt32Size(uint32 value) { 806 return io::CodedOutputStream::VarintSize32(value); 807 } 808 inline int WireFormatLite::UInt64Size(uint64 value) { 809 return io::CodedOutputStream::VarintSize64(value); 810 } 811 inline int WireFormatLite::SInt32Size(int32 value) { 812 return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value)); 813 } 814 inline int WireFormatLite::SInt64Size(int64 value) { 815 return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value)); 816 } 817 inline int WireFormatLite::EnumSize(int value) { 818 return io::CodedOutputStream::VarintSize32SignExtended(value); 819 } 820 821 inline int WireFormatLite::StringSize(const string& value) { 822 return io::CodedOutputStream::VarintSize32(value.size()) + 823 value.size(); 824 } 825 inline int WireFormatLite::BytesSize(const string& value) { 826 return io::CodedOutputStream::VarintSize32(value.size()) + 827 value.size(); 828 } 829 830 831 inline int WireFormatLite::GroupSize(const MessageLite& value) { 832 return value.ByteSize(); 833 } 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> 841 inline int WireFormatLite::GroupSizeNoVirtual( 842 const MessageType_WorkAroundCppLookupDefect& value) { 843 return value.MessageType_WorkAroundCppLookupDefect::ByteSize(); 844 } 845 template<typename MessageType_WorkAroundCppLookupDefect> 846 inline int WireFormatLite::MessageSizeNoVirtual( 847 const MessageType_WorkAroundCppLookupDefect& value) { 848 return LengthDelimitedSize( 849 value.MessageType_WorkAroundCppLookupDefect::ByteSize()); 850 } 851 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