1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // http://code.google.com/p/protobuf/ 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 #include <string> 40 #include <google/protobuf/stubs/common.h> 41 #include <google/protobuf/message_lite.h> 42 #include <google/protobuf/repeated_field.h> 43 #include <google/protobuf/wire_format_lite.h> 44 #include <google/protobuf/io/coded_stream.h> 45 46 47 namespace google { 48 namespace protobuf { 49 namespace internal { 50 51 // Implementation details of ReadPrimitive. 52 53 template <> 54 inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>( 55 io::CodedInputStream* input, 56 int32* value) { 57 uint32 temp; 58 if (!input->ReadVarint32(&temp)) return false; 59 *value = static_cast<int32>(temp); 60 return true; 61 } 62 template <> 63 inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_INT64>( 64 io::CodedInputStream* input, 65 int64* value) { 66 uint64 temp; 67 if (!input->ReadVarint64(&temp)) return false; 68 *value = static_cast<int64>(temp); 69 return true; 70 } 71 template <> 72 inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_UINT32>( 73 io::CodedInputStream* input, 74 uint32* value) { 75 return input->ReadVarint32(value); 76 } 77 template <> 78 inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_UINT64>( 79 io::CodedInputStream* input, 80 uint64* value) { 81 return input->ReadVarint64(value); 82 } 83 template <> 84 inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>( 85 io::CodedInputStream* input, 86 int32* value) { 87 uint32 temp; 88 if (!input->ReadVarint32(&temp)) return false; 89 *value = ZigZagDecode32(temp); 90 return true; 91 } 92 template <> 93 inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SINT64>( 94 io::CodedInputStream* input, 95 int64* value) { 96 uint64 temp; 97 if (!input->ReadVarint64(&temp)) return false; 98 *value = ZigZagDecode64(temp); 99 return true; 100 } 101 template <> 102 inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_FIXED32>( 103 io::CodedInputStream* input, 104 uint32* value) { 105 return input->ReadLittleEndian32(value); 106 } 107 template <> 108 inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_FIXED64>( 109 io::CodedInputStream* input, 110 uint64* value) { 111 return input->ReadLittleEndian64(value); 112 } 113 template <> 114 inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SFIXED32>( 115 io::CodedInputStream* input, 116 int32* value) { 117 uint32 temp; 118 if (!input->ReadLittleEndian32(&temp)) return false; 119 *value = static_cast<int32>(temp); 120 return true; 121 } 122 template <> 123 inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SFIXED64>( 124 io::CodedInputStream* input, 125 int64* value) { 126 uint64 temp; 127 if (!input->ReadLittleEndian64(&temp)) return false; 128 *value = static_cast<int64>(temp); 129 return true; 130 } 131 template <> 132 inline bool WireFormatLite::ReadPrimitive<float, WireFormatLite::TYPE_FLOAT>( 133 io::CodedInputStream* input, 134 float* value) { 135 uint32 temp; 136 if (!input->ReadLittleEndian32(&temp)) return false; 137 *value = DecodeFloat(temp); 138 return true; 139 } 140 template <> 141 inline bool WireFormatLite::ReadPrimitive<double, WireFormatLite::TYPE_DOUBLE>( 142 io::CodedInputStream* input, 143 double* value) { 144 uint64 temp; 145 if (!input->ReadLittleEndian64(&temp)) return false; 146 *value = DecodeDouble(temp); 147 return true; 148 } 149 template <> 150 inline bool WireFormatLite::ReadPrimitive<bool, WireFormatLite::TYPE_BOOL>( 151 io::CodedInputStream* input, 152 bool* value) { 153 uint32 temp; 154 if (!input->ReadVarint32(&temp)) return false; 155 *value = temp != 0; 156 return true; 157 } 158 template <> 159 inline bool WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>( 160 io::CodedInputStream* input, 161 int* value) { 162 uint32 temp; 163 if (!input->ReadVarint32(&temp)) return false; 164 *value = static_cast<int>(temp); 165 return true; 166 } 167 168 template <> 169 inline const uint8* WireFormatLite::ReadPrimitiveFromArray< 170 uint32, WireFormatLite::TYPE_FIXED32>( 171 const uint8* buffer, 172 uint32* value) { 173 return io::CodedInputStream::ReadLittleEndian32FromArray(buffer, value); 174 } 175 template <> 176 inline const uint8* WireFormatLite::ReadPrimitiveFromArray< 177 uint64, WireFormatLite::TYPE_FIXED64>( 178 const uint8* buffer, 179 uint64* value) { 180 return io::CodedInputStream::ReadLittleEndian64FromArray(buffer, value); 181 } 182 template <> 183 inline const uint8* WireFormatLite::ReadPrimitiveFromArray< 184 int32, WireFormatLite::TYPE_SFIXED32>( 185 const uint8* buffer, 186 int32* value) { 187 uint32 temp; 188 buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp); 189 *value = static_cast<int32>(temp); 190 return buffer; 191 } 192 template <> 193 inline const uint8* WireFormatLite::ReadPrimitiveFromArray< 194 int64, WireFormatLite::TYPE_SFIXED64>( 195 const uint8* buffer, 196 int64* value) { 197 uint64 temp; 198 buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp); 199 *value = static_cast<int64>(temp); 200 return buffer; 201 } 202 template <> 203 inline const uint8* WireFormatLite::ReadPrimitiveFromArray< 204 float, WireFormatLite::TYPE_FLOAT>( 205 const uint8* buffer, 206 float* value) { 207 uint32 temp; 208 buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp); 209 *value = DecodeFloat(temp); 210 return buffer; 211 } 212 template <> 213 inline const uint8* WireFormatLite::ReadPrimitiveFromArray< 214 double, WireFormatLite::TYPE_DOUBLE>( 215 const uint8* buffer, 216 double* value) { 217 uint64 temp; 218 buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp); 219 *value = DecodeDouble(temp); 220 return buffer; 221 } 222 223 template <typename CType, enum WireFormatLite::FieldType DeclaredType> 224 inline bool WireFormatLite::ReadRepeatedPrimitive(int, // tag_size, unused. 225 uint32 tag, 226 io::CodedInputStream* input, 227 RepeatedField<CType>* values) { 228 CType value; 229 if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; 230 values->Add(value); 231 int elements_already_reserved = values->Capacity() - values->size(); 232 while (elements_already_reserved > 0 && input->ExpectTag(tag)) { 233 if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; 234 values->AddAlreadyReserved(value); 235 elements_already_reserved--; 236 } 237 return true; 238 } 239 240 template <typename CType, enum WireFormatLite::FieldType DeclaredType> 241 inline bool WireFormatLite::ReadRepeatedFixedSizePrimitive( 242 int tag_size, 243 uint32 tag, 244 io::CodedInputStream* input, 245 RepeatedField<CType>* values) { 246 GOOGLE_DCHECK_EQ(UInt32Size(tag), tag_size); 247 CType value; 248 if (!ReadPrimitive<CType, DeclaredType>(input, &value)) 249 return false; 250 values->Add(value); 251 252 // For fixed size values, repeated values can be read more quickly by 253 // reading directly from a raw array. 254 // 255 // We can get a tight loop by only reading as many elements as can be 256 // added to the RepeatedField without having to do any resizing. Additionally, 257 // we only try to read as many elements as are available from the current 258 // buffer space. Doing so avoids having to perform boundary checks when 259 // reading the value: the maximum number of elements that can be read is 260 // known outside of the loop. 261 const void* void_pointer; 262 int size; 263 input->GetDirectBufferPointerInline(&void_pointer, &size); 264 if (size > 0) { 265 const uint8* buffer = reinterpret_cast<const uint8*>(void_pointer); 266 // The number of bytes each type occupies on the wire. 267 const int per_value_size = tag_size + sizeof(value); 268 269 int elements_available = min(values->Capacity() - values->size(), 270 size / per_value_size); 271 int num_read = 0; 272 while (num_read < elements_available && 273 (buffer = io::CodedInputStream::ExpectTagFromArray( 274 buffer, tag)) != NULL) { 275 buffer = ReadPrimitiveFromArray<CType, DeclaredType>(buffer, &value); 276 values->AddAlreadyReserved(value); 277 ++num_read; 278 } 279 const int read_bytes = num_read * per_value_size; 280 if (read_bytes > 0) { 281 input->Skip(read_bytes); 282 } 283 } 284 return true; 285 } 286 287 // Specializations of ReadRepeatedPrimitive for the fixed size types, which use 288 // the optimized code path. 289 #define READ_REPEATED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE) \ 290 template <> \ 291 inline bool WireFormatLite::ReadRepeatedPrimitive< \ 292 CPPTYPE, WireFormatLite::DECLARED_TYPE>( \ 293 int tag_size, \ 294 uint32 tag, \ 295 io::CodedInputStream* input, \ 296 RepeatedField<CPPTYPE>* values) { \ 297 return ReadRepeatedFixedSizePrimitive< \ 298 CPPTYPE, WireFormatLite::DECLARED_TYPE>( \ 299 tag_size, tag, input, values); \ 300 } 301 302 READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32) 303 READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64) 304 READ_REPEATED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32) 305 READ_REPEATED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64) 306 READ_REPEATED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT) 307 READ_REPEATED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE) 308 309 #undef READ_REPEATED_FIXED_SIZE_PRIMITIVE 310 311 template <typename CType, enum WireFormatLite::FieldType DeclaredType> 312 bool WireFormatLite::ReadRepeatedPrimitiveNoInline( 313 int tag_size, 314 uint32 tag, 315 io::CodedInputStream* input, 316 RepeatedField<CType>* value) { 317 return ReadRepeatedPrimitive<CType, DeclaredType>( 318 tag_size, tag, input, value); 319 } 320 321 template <typename CType, enum WireFormatLite::FieldType DeclaredType> 322 inline bool WireFormatLite::ReadPackedPrimitive(io::CodedInputStream* input, 323 RepeatedField<CType>* values) { 324 uint32 length; 325 if (!input->ReadVarint32(&length)) return false; 326 io::CodedInputStream::Limit limit = input->PushLimit(length); 327 while (input->BytesUntilLimit() > 0) { 328 CType value; 329 if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; 330 values->Add(value); 331 } 332 input->PopLimit(limit); 333 return true; 334 } 335 336 template <typename CType, enum WireFormatLite::FieldType DeclaredType> 337 bool WireFormatLite::ReadPackedPrimitiveNoInline(io::CodedInputStream* input, 338 RepeatedField<CType>* values) { 339 return ReadPackedPrimitive<CType, DeclaredType>(input, values); 340 } 341 342 343 inline bool WireFormatLite::ReadGroup(int field_number, 344 io::CodedInputStream* input, 345 MessageLite* value) { 346 if (!input->IncrementRecursionDepth()) return false; 347 if (!value->MergePartialFromCodedStream(input)) return false; 348 input->DecrementRecursionDepth(); 349 // Make sure the last thing read was an end tag for this group. 350 if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) { 351 return false; 352 } 353 return true; 354 } 355 inline bool WireFormatLite::ReadMessage(io::CodedInputStream* input, 356 MessageLite* value) { 357 uint32 length; 358 if (!input->ReadVarint32(&length)) return false; 359 if (!input->IncrementRecursionDepth()) return false; 360 io::CodedInputStream::Limit limit = input->PushLimit(length); 361 if (!value->MergePartialFromCodedStream(input)) return false; 362 // Make sure that parsing stopped when the limit was hit, not at an endgroup 363 // tag. 364 if (!input->ConsumedEntireMessage()) return false; 365 input->PopLimit(limit); 366 input->DecrementRecursionDepth(); 367 return true; 368 } 369 370 // We name the template parameter something long and extremely unlikely to occur 371 // elsewhere because a *qualified* member access expression designed to avoid 372 // virtual dispatch, C++03 [basic.lookup.classref] 3.4.5/4 requires that the 373 // name of the qualifying class to be looked up both in the context of the full 374 // expression (finding the template parameter) and in the context of the object 375 // whose member we are accessing. This could potentially find a nested type 376 // within that object. The standard goes on to require these names to refer to 377 // the same entity, which this collision would violate. The lack of a safe way 378 // to avoid this collision appears to be a defect in the standard, but until it 379 // is corrected, we choose the name to avoid accidental collisions. 380 template<typename MessageType_WorkAroundCppLookupDefect> 381 inline bool WireFormatLite::ReadGroupNoVirtual( 382 int field_number, io::CodedInputStream* input, 383 MessageType_WorkAroundCppLookupDefect* value) { 384 if (!input->IncrementRecursionDepth()) return false; 385 if (!value-> 386 MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input)) 387 return false; 388 input->DecrementRecursionDepth(); 389 // Make sure the last thing read was an end tag for this group. 390 if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) { 391 return false; 392 } 393 return true; 394 } 395 template<typename MessageType_WorkAroundCppLookupDefect> 396 inline bool WireFormatLite::ReadMessageNoVirtual( 397 io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) { 398 uint32 length; 399 if (!input->ReadVarint32(&length)) return false; 400 if (!input->IncrementRecursionDepth()) return false; 401 io::CodedInputStream::Limit limit = input->PushLimit(length); 402 if (!value-> 403 MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input)) 404 return false; 405 // Make sure that parsing stopped when the limit was hit, not at an endgroup 406 // tag. 407 if (!input->ConsumedEntireMessage()) return false; 408 input->PopLimit(limit); 409 input->DecrementRecursionDepth(); 410 return true; 411 } 412 413 // =================================================================== 414 415 inline void WireFormatLite::WriteTag(int field_number, WireType type, 416 io::CodedOutputStream* output) { 417 output->WriteTag(MakeTag(field_number, type)); 418 } 419 420 inline void WireFormatLite::WriteInt32NoTag(int32 value, 421 io::CodedOutputStream* output) { 422 output->WriteVarint32SignExtended(value); 423 } 424 inline void WireFormatLite::WriteInt64NoTag(int64 value, 425 io::CodedOutputStream* output) { 426 output->WriteVarint64(static_cast<uint64>(value)); 427 } 428 inline void WireFormatLite::WriteUInt32NoTag(uint32 value, 429 io::CodedOutputStream* output) { 430 output->WriteVarint32(value); 431 } 432 inline void WireFormatLite::WriteUInt64NoTag(uint64 value, 433 io::CodedOutputStream* output) { 434 output->WriteVarint64(value); 435 } 436 inline void WireFormatLite::WriteSInt32NoTag(int32 value, 437 io::CodedOutputStream* output) { 438 output->WriteVarint32(ZigZagEncode32(value)); 439 } 440 inline void WireFormatLite::WriteSInt64NoTag(int64 value, 441 io::CodedOutputStream* output) { 442 output->WriteVarint64(ZigZagEncode64(value)); 443 } 444 inline void WireFormatLite::WriteFixed32NoTag(uint32 value, 445 io::CodedOutputStream* output) { 446 output->WriteLittleEndian32(value); 447 } 448 inline void WireFormatLite::WriteFixed64NoTag(uint64 value, 449 io::CodedOutputStream* output) { 450 output->WriteLittleEndian64(value); 451 } 452 inline void WireFormatLite::WriteSFixed32NoTag(int32 value, 453 io::CodedOutputStream* output) { 454 output->WriteLittleEndian32(static_cast<uint32>(value)); 455 } 456 inline void WireFormatLite::WriteSFixed64NoTag(int64 value, 457 io::CodedOutputStream* output) { 458 output->WriteLittleEndian64(static_cast<uint64>(value)); 459 } 460 inline void WireFormatLite::WriteFloatNoTag(float value, 461 io::CodedOutputStream* output) { 462 output->WriteLittleEndian32(EncodeFloat(value)); 463 } 464 inline void WireFormatLite::WriteDoubleNoTag(double value, 465 io::CodedOutputStream* output) { 466 output->WriteLittleEndian64(EncodeDouble(value)); 467 } 468 inline void WireFormatLite::WriteBoolNoTag(bool value, 469 io::CodedOutputStream* output) { 470 output->WriteVarint32(value ? 1 : 0); 471 } 472 inline void WireFormatLite::WriteEnumNoTag(int value, 473 io::CodedOutputStream* output) { 474 output->WriteVarint32SignExtended(value); 475 } 476 477 // See comment on ReadGroupNoVirtual to understand the need for this template 478 // parameter name. 479 template<typename MessageType_WorkAroundCppLookupDefect> 480 inline void WireFormatLite::WriteGroupNoVirtual( 481 int field_number, const MessageType_WorkAroundCppLookupDefect& value, 482 io::CodedOutputStream* output) { 483 WriteTag(field_number, WIRETYPE_START_GROUP, output); 484 value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output); 485 WriteTag(field_number, WIRETYPE_END_GROUP, output); 486 } 487 template<typename MessageType_WorkAroundCppLookupDefect> 488 inline void WireFormatLite::WriteMessageNoVirtual( 489 int field_number, const MessageType_WorkAroundCppLookupDefect& value, 490 io::CodedOutputStream* output) { 491 WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); 492 output->WriteVarint32( 493 value.MessageType_WorkAroundCppLookupDefect::GetCachedSize()); 494 value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output); 495 } 496 497 // =================================================================== 498 499 inline uint8* WireFormatLite::WriteTagToArray(int field_number, 500 WireType type, 501 uint8* target) { 502 return io::CodedOutputStream::WriteTagToArray(MakeTag(field_number, type), 503 target); 504 } 505 506 inline uint8* WireFormatLite::WriteInt32NoTagToArray(int32 value, 507 uint8* target) { 508 return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target); 509 } 510 inline uint8* WireFormatLite::WriteInt64NoTagToArray(int64 value, 511 uint8* target) { 512 return io::CodedOutputStream::WriteVarint64ToArray( 513 static_cast<uint64>(value), target); 514 } 515 inline uint8* WireFormatLite::WriteUInt32NoTagToArray(uint32 value, 516 uint8* target) { 517 return io::CodedOutputStream::WriteVarint32ToArray(value, target); 518 } 519 inline uint8* WireFormatLite::WriteUInt64NoTagToArray(uint64 value, 520 uint8* target) { 521 return io::CodedOutputStream::WriteVarint64ToArray(value, target); 522 } 523 inline uint8* WireFormatLite::WriteSInt32NoTagToArray(int32 value, 524 uint8* target) { 525 return io::CodedOutputStream::WriteVarint32ToArray(ZigZagEncode32(value), 526 target); 527 } 528 inline uint8* WireFormatLite::WriteSInt64NoTagToArray(int64 value, 529 uint8* target) { 530 return io::CodedOutputStream::WriteVarint64ToArray(ZigZagEncode64(value), 531 target); 532 } 533 inline uint8* WireFormatLite::WriteFixed32NoTagToArray(uint32 value, 534 uint8* target) { 535 return io::CodedOutputStream::WriteLittleEndian32ToArray(value, target); 536 } 537 inline uint8* WireFormatLite::WriteFixed64NoTagToArray(uint64 value, 538 uint8* target) { 539 return io::CodedOutputStream::WriteLittleEndian64ToArray(value, target); 540 } 541 inline uint8* WireFormatLite::WriteSFixed32NoTagToArray(int32 value, 542 uint8* target) { 543 return io::CodedOutputStream::WriteLittleEndian32ToArray( 544 static_cast<uint32>(value), target); 545 } 546 inline uint8* WireFormatLite::WriteSFixed64NoTagToArray(int64 value, 547 uint8* target) { 548 return io::CodedOutputStream::WriteLittleEndian64ToArray( 549 static_cast<uint64>(value), target); 550 } 551 inline uint8* WireFormatLite::WriteFloatNoTagToArray(float value, 552 uint8* target) { 553 return io::CodedOutputStream::WriteLittleEndian32ToArray(EncodeFloat(value), 554 target); 555 } 556 inline uint8* WireFormatLite::WriteDoubleNoTagToArray(double value, 557 uint8* target) { 558 return io::CodedOutputStream::WriteLittleEndian64ToArray(EncodeDouble(value), 559 target); 560 } 561 inline uint8* WireFormatLite::WriteBoolNoTagToArray(bool value, 562 uint8* target) { 563 return io::CodedOutputStream::WriteVarint32ToArray(value ? 1 : 0, target); 564 } 565 inline uint8* WireFormatLite::WriteEnumNoTagToArray(int value, 566 uint8* target) { 567 return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target); 568 } 569 570 inline uint8* WireFormatLite::WriteInt32ToArray(int field_number, 571 int32 value, 572 uint8* target) { 573 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); 574 return WriteInt32NoTagToArray(value, target); 575 } 576 inline uint8* WireFormatLite::WriteInt64ToArray(int field_number, 577 int64 value, 578 uint8* target) { 579 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); 580 return WriteInt64NoTagToArray(value, target); 581 } 582 inline uint8* WireFormatLite::WriteUInt32ToArray(int field_number, 583 uint32 value, 584 uint8* target) { 585 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); 586 return WriteUInt32NoTagToArray(value, target); 587 } 588 inline uint8* WireFormatLite::WriteUInt64ToArray(int field_number, 589 uint64 value, 590 uint8* target) { 591 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); 592 return WriteUInt64NoTagToArray(value, target); 593 } 594 inline uint8* WireFormatLite::WriteSInt32ToArray(int field_number, 595 int32 value, 596 uint8* target) { 597 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); 598 return WriteSInt32NoTagToArray(value, target); 599 } 600 inline uint8* WireFormatLite::WriteSInt64ToArray(int field_number, 601 int64 value, 602 uint8* target) { 603 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); 604 return WriteSInt64NoTagToArray(value, target); 605 } 606 inline uint8* WireFormatLite::WriteFixed32ToArray(int field_number, 607 uint32 value, 608 uint8* target) { 609 target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); 610 return WriteFixed32NoTagToArray(value, target); 611 } 612 inline uint8* WireFormatLite::WriteFixed64ToArray(int field_number, 613 uint64 value, 614 uint8* target) { 615 target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); 616 return WriteFixed64NoTagToArray(value, target); 617 } 618 inline uint8* WireFormatLite::WriteSFixed32ToArray(int field_number, 619 int32 value, 620 uint8* target) { 621 target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); 622 return WriteSFixed32NoTagToArray(value, target); 623 } 624 inline uint8* WireFormatLite::WriteSFixed64ToArray(int field_number, 625 int64 value, 626 uint8* target) { 627 target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); 628 return WriteSFixed64NoTagToArray(value, target); 629 } 630 inline uint8* WireFormatLite::WriteFloatToArray(int field_number, 631 float value, 632 uint8* target) { 633 target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); 634 return WriteFloatNoTagToArray(value, target); 635 } 636 inline uint8* WireFormatLite::WriteDoubleToArray(int field_number, 637 double value, 638 uint8* target) { 639 target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); 640 return WriteDoubleNoTagToArray(value, target); 641 } 642 inline uint8* WireFormatLite::WriteBoolToArray(int field_number, 643 bool value, 644 uint8* target) { 645 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); 646 return WriteBoolNoTagToArray(value, target); 647 } 648 inline uint8* WireFormatLite::WriteEnumToArray(int field_number, 649 int value, 650 uint8* target) { 651 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); 652 return WriteEnumNoTagToArray(value, target); 653 } 654 655 inline uint8* WireFormatLite::WriteStringToArray(int field_number, 656 const string& value, 657 uint8* target) { 658 // String is for UTF-8 text only 659 // WARNING: In wire_format.cc, both strings and bytes are handled by 660 // WriteString() to avoid code duplication. If the implementations become 661 // different, you will need to update that usage. 662 target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); 663 target = io::CodedOutputStream::WriteVarint32ToArray(value.size(), target); 664 return io::CodedOutputStream::WriteStringToArray(value, target); 665 } 666 inline uint8* WireFormatLite::WriteBytesToArray(int field_number, 667 const string& value, 668 uint8* target) { 669 target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); 670 target = io::CodedOutputStream::WriteVarint32ToArray(value.size(), target); 671 return io::CodedOutputStream::WriteStringToArray(value, target); 672 } 673 674 675 inline uint8* WireFormatLite::WriteGroupToArray(int field_number, 676 const MessageLite& value, 677 uint8* target) { 678 target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target); 679 target = value.SerializeWithCachedSizesToArray(target); 680 return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target); 681 } 682 inline uint8* WireFormatLite::WriteMessageToArray(int field_number, 683 const MessageLite& value, 684 uint8* target) { 685 target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); 686 target = io::CodedOutputStream::WriteVarint32ToArray( 687 value.GetCachedSize(), target); 688 return value.SerializeWithCachedSizesToArray(target); 689 } 690 691 // See comment on ReadGroupNoVirtual to understand the need for this template 692 // parameter name. 693 template<typename MessageType_WorkAroundCppLookupDefect> 694 inline uint8* WireFormatLite::WriteGroupNoVirtualToArray( 695 int field_number, const MessageType_WorkAroundCppLookupDefect& value, 696 uint8* target) { 697 target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target); 698 target = value.MessageType_WorkAroundCppLookupDefect 699 ::SerializeWithCachedSizesToArray(target); 700 return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target); 701 } 702 template<typename MessageType_WorkAroundCppLookupDefect> 703 inline uint8* WireFormatLite::WriteMessageNoVirtualToArray( 704 int field_number, const MessageType_WorkAroundCppLookupDefect& value, 705 uint8* target) { 706 target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); 707 target = io::CodedOutputStream::WriteVarint32ToArray( 708 value.MessageType_WorkAroundCppLookupDefect::GetCachedSize(), target); 709 return value.MessageType_WorkAroundCppLookupDefect 710 ::SerializeWithCachedSizesToArray(target); 711 } 712 713 // =================================================================== 714 715 inline int WireFormatLite::Int32Size(int32 value) { 716 return io::CodedOutputStream::VarintSize32SignExtended(value); 717 } 718 inline int WireFormatLite::Int64Size(int64 value) { 719 return io::CodedOutputStream::VarintSize64(static_cast<uint64>(value)); 720 } 721 inline int WireFormatLite::UInt32Size(uint32 value) { 722 return io::CodedOutputStream::VarintSize32(value); 723 } 724 inline int WireFormatLite::UInt64Size(uint64 value) { 725 return io::CodedOutputStream::VarintSize64(value); 726 } 727 inline int WireFormatLite::SInt32Size(int32 value) { 728 return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value)); 729 } 730 inline int WireFormatLite::SInt64Size(int64 value) { 731 return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value)); 732 } 733 inline int WireFormatLite::EnumSize(int value) { 734 return io::CodedOutputStream::VarintSize32SignExtended(value); 735 } 736 737 inline int WireFormatLite::StringSize(const string& value) { 738 return io::CodedOutputStream::VarintSize32(value.size()) + 739 value.size(); 740 } 741 inline int WireFormatLite::BytesSize(const string& value) { 742 return io::CodedOutputStream::VarintSize32(value.size()) + 743 value.size(); 744 } 745 746 747 inline int WireFormatLite::GroupSize(const MessageLite& value) { 748 return value.ByteSize(); 749 } 750 inline int WireFormatLite::MessageSize(const MessageLite& value) { 751 return LengthDelimitedSize(value.ByteSize()); 752 } 753 754 // See comment on ReadGroupNoVirtual to understand the need for this template 755 // parameter name. 756 template<typename MessageType_WorkAroundCppLookupDefect> 757 inline int WireFormatLite::GroupSizeNoVirtual( 758 const MessageType_WorkAroundCppLookupDefect& value) { 759 return value.MessageType_WorkAroundCppLookupDefect::ByteSize(); 760 } 761 template<typename MessageType_WorkAroundCppLookupDefect> 762 inline int WireFormatLite::MessageSizeNoVirtual( 763 const MessageType_WorkAroundCppLookupDefect& value) { 764 return LengthDelimitedSize( 765 value.MessageType_WorkAroundCppLookupDefect::ByteSize()); 766 } 767 768 inline int WireFormatLite::LengthDelimitedSize(int length) { 769 return io::CodedOutputStream::VarintSize32(length) + length; 770 } 771 772 } // namespace internal 773 } // namespace protobuf 774 775 } // namespace google 776 #endif // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__ 777