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 // atenasio (at) google.com (Chris Atenasio) (ZigZag transform) 33 // wink (at) google.com (Wink Saville) (refactored from wire_format.h) 34 // Based on original Protocol Buffers design by 35 // Sanjay Ghemawat, Jeff Dean, and others. 36 // 37 // This header is logically internal, but is made public because it is used 38 // from protocol-compiler-generated code, which may reside in other components. 39 40 #ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__ 41 #define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__ 42 43 #include <string> 44 #include <google/protobuf/message_lite.h> 45 46 namespace google { 47 48 namespace protobuf { 49 template <typename T> class RepeatedField; // repeated_field.h 50 namespace io { 51 class CodedInputStream; // coded_stream.h 52 class CodedOutputStream; // coded_stream.h 53 } 54 } 55 56 namespace protobuf { 57 namespace internal { 58 59 class StringPieceField; 60 61 // This class is for internal use by the protocol buffer library and by 62 // protocol-complier-generated message classes. It must not be called 63 // directly by clients. 64 // 65 // This class contains helpers for implementing the binary protocol buffer 66 // wire format without the need for reflection. Use WireFormat when using 67 // reflection. 68 // 69 // This class is really a namespace that contains only static methods. 70 class LIBPROTOBUF_EXPORT WireFormatLite { 71 public: 72 73 // ----------------------------------------------------------------- 74 // Helper constants and functions related to the format. These are 75 // mostly meant for internal and generated code to use. 76 77 // The wire format is composed of a sequence of tag/value pairs, each 78 // of which contains the value of one field (or one element of a repeated 79 // field). Each tag is encoded as a varint. The lower bits of the tag 80 // identify its wire type, which specifies the format of the data to follow. 81 // The rest of the bits contain the field number. Each type of field (as 82 // declared by FieldDescriptor::Type, in descriptor.h) maps to one of 83 // these wire types. Immediately following each tag is the field's value, 84 // encoded in the format specified by the wire type. Because the tag 85 // identifies the encoding of this data, it is possible to skip 86 // unrecognized fields for forwards compatibility. 87 88 enum WireType { 89 WIRETYPE_VARINT = 0, 90 WIRETYPE_FIXED64 = 1, 91 WIRETYPE_LENGTH_DELIMITED = 2, 92 WIRETYPE_START_GROUP = 3, 93 WIRETYPE_END_GROUP = 4, 94 WIRETYPE_FIXED32 = 5, 95 }; 96 97 // Lite alternative to FieldDescriptor::Type. Must be kept in sync. 98 enum FieldType { 99 TYPE_DOUBLE = 1, 100 TYPE_FLOAT = 2, 101 TYPE_INT64 = 3, 102 TYPE_UINT64 = 4, 103 TYPE_INT32 = 5, 104 TYPE_FIXED64 = 6, 105 TYPE_FIXED32 = 7, 106 TYPE_BOOL = 8, 107 TYPE_STRING = 9, 108 TYPE_GROUP = 10, 109 TYPE_MESSAGE = 11, 110 TYPE_BYTES = 12, 111 TYPE_UINT32 = 13, 112 TYPE_ENUM = 14, 113 TYPE_SFIXED32 = 15, 114 TYPE_SFIXED64 = 16, 115 TYPE_SINT32 = 17, 116 TYPE_SINT64 = 18, 117 MAX_FIELD_TYPE = 18, 118 }; 119 120 // Lite alternative to FieldDescriptor::CppType. Must be kept in sync. 121 enum CppType { 122 CPPTYPE_INT32 = 1, 123 CPPTYPE_INT64 = 2, 124 CPPTYPE_UINT32 = 3, 125 CPPTYPE_UINT64 = 4, 126 CPPTYPE_DOUBLE = 5, 127 CPPTYPE_FLOAT = 6, 128 CPPTYPE_BOOL = 7, 129 CPPTYPE_ENUM = 8, 130 CPPTYPE_STRING = 9, 131 CPPTYPE_MESSAGE = 10, 132 MAX_CPPTYPE = 10, 133 }; 134 135 // Helper method to get the CppType for a particular Type. 136 static CppType FieldTypeToCppType(FieldType type); 137 138 // Given a FieldSescriptor::Type return its WireType 139 static inline WireFormatLite::WireType WireTypeForFieldType( 140 WireFormatLite::FieldType type) { 141 return kWireTypeForFieldType[type]; 142 } 143 144 // Number of bits in a tag which identify the wire type. 145 static const int kTagTypeBits = 3; 146 // Mask for those bits. 147 static const uint32 kTagTypeMask = (1 << kTagTypeBits) - 1; 148 149 // Helper functions for encoding and decoding tags. (Inlined below and in 150 // _inl.h) 151 // 152 // This is different from MakeTag(field->number(), field->type()) in the case 153 // of packed repeated fields. 154 static uint32 MakeTag(int field_number, WireType type); 155 static WireType GetTagWireType(uint32 tag); 156 static int GetTagFieldNumber(uint32 tag); 157 158 // Compute the byte size of a tag. For groups, this includes both the start 159 // and end tags. 160 static inline int TagSize(int field_number, WireFormatLite::FieldType type); 161 162 // Skips a field value with the given tag. The input should start 163 // positioned immediately after the tag. Skipped values are simply discarded, 164 // not recorded anywhere. See WireFormat::SkipField() for a version that 165 // records to an UnknownFieldSet. 166 static bool SkipField(io::CodedInputStream* input, uint32 tag); 167 168 // Reads and ignores a message from the input. Skipped values are simply 169 // discarded, not recorded anywhere. See WireFormat::SkipMessage() for a 170 // version that records to an UnknownFieldSet. 171 static bool SkipMessage(io::CodedInputStream* input); 172 173 // This macro does the same thing as WireFormatLite::MakeTag(), but the 174 // result is usable as a compile-time constant, which makes it usable 175 // as a switch case or a template input. WireFormatLite::MakeTag() is more 176 // type-safe, though, so prefer it if possible. 177 #define GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(FIELD_NUMBER, TYPE) \ 178 static_cast<uint32>( \ 179 ((FIELD_NUMBER) << ::google::protobuf::internal::WireFormatLite::kTagTypeBits) \ 180 | (TYPE)) 181 182 // These are the tags for the old MessageSet format, which was defined as: 183 // message MessageSet { 184 // repeated group Item = 1 { 185 // required int32 type_id = 2; 186 // required string message = 3; 187 // } 188 // } 189 static const int kMessageSetItemNumber = 1; 190 static const int kMessageSetTypeIdNumber = 2; 191 static const int kMessageSetMessageNumber = 3; 192 static const int kMessageSetItemStartTag = 193 GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetItemNumber, 194 WireFormatLite::WIRETYPE_START_GROUP); 195 static const int kMessageSetItemEndTag = 196 GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetItemNumber, 197 WireFormatLite::WIRETYPE_END_GROUP); 198 static const int kMessageSetTypeIdTag = 199 GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetTypeIdNumber, 200 WireFormatLite::WIRETYPE_VARINT); 201 static const int kMessageSetMessageTag = 202 GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetMessageNumber, 203 WireFormatLite::WIRETYPE_LENGTH_DELIMITED); 204 205 // Byte size of all tags of a MessageSet::Item combined. 206 static const int kMessageSetItemTagsSize; 207 208 // Helper functions for converting between floats/doubles and IEEE-754 209 // uint32s/uint64s so that they can be written. (Assumes your platform 210 // uses IEEE-754 floats.) 211 static uint32 EncodeFloat(float value); 212 static float DecodeFloat(uint32 value); 213 static uint64 EncodeDouble(double value); 214 static double DecodeDouble(uint64 value); 215 216 // Helper functions for mapping signed integers to unsigned integers in 217 // such a way that numbers with small magnitudes will encode to smaller 218 // varints. If you simply static_cast a negative number to an unsigned 219 // number and varint-encode it, it will always take 10 bytes, defeating 220 // the purpose of varint. So, for the "sint32" and "sint64" field types, 221 // we ZigZag-encode the values. 222 static uint32 ZigZagEncode32(int32 n); 223 static int32 ZigZagDecode32(uint32 n); 224 static uint64 ZigZagEncode64(int64 n); 225 static int64 ZigZagDecode64(uint64 n); 226 227 // ================================================================= 228 // Methods for reading/writing individual field. The implementations 229 // of these methods are defined in wire_format_lite_inl.h; you must #include 230 // that file to use these. 231 232 // Avoid ugly line wrapping 233 #define input io::CodedInputStream* input 234 #define output io::CodedOutputStream* output 235 #define field_number int field_number 236 #define INL GOOGLE_ATTRIBUTE_ALWAYS_INLINE 237 238 // Read fields, not including tags. The assumption is that you already 239 // read the tag to determine what field to read. 240 241 // For primitive fields, we just use a templatized routine parameterized by 242 // the represented type and the FieldType. These are specialized with the 243 // appropriate definition for each declared type. 244 template <typename CType, enum FieldType DeclaredType> 245 static inline bool ReadPrimitive(input, CType* value) INL; 246 247 // Reads repeated primitive values, with optimizations for repeats. 248 // tag_size and tag should both be compile-time constants provided by the 249 // protocol compiler. 250 template <typename CType, enum FieldType DeclaredType> 251 static inline bool ReadRepeatedPrimitive(int tag_size, 252 uint32 tag, 253 input, 254 RepeatedField<CType>* value) INL; 255 256 // Identical to ReadRepeatedPrimitive, except will not inline the 257 // implementation. 258 template <typename CType, enum FieldType DeclaredType> 259 static bool ReadRepeatedPrimitiveNoInline(int tag_size, 260 uint32 tag, 261 input, 262 RepeatedField<CType>* value); 263 264 // Reads a primitive value directly from the provided buffer. It returns a 265 // pointer past the segment of data that was read. 266 // 267 // This is only implemented for the types with fixed wire size, e.g. 268 // float, double, and the (s)fixed* types. 269 template <typename CType, enum FieldType DeclaredType> 270 static inline const uint8* ReadPrimitiveFromArray(const uint8* buffer, 271 CType* value) INL; 272 273 // Reads a primitive packed field. 274 // 275 // This is only implemented for packable types. 276 template <typename CType, enum FieldType DeclaredType> 277 static inline bool ReadPackedPrimitive(input, 278 RepeatedField<CType>* value) INL; 279 280 // Identical to ReadPackedPrimitive, except will not inline the 281 // implementation. 282 template <typename CType, enum FieldType DeclaredType> 283 static bool ReadPackedPrimitiveNoInline(input, RepeatedField<CType>* value); 284 285 // Read a packed enum field. Values for which is_valid() returns false are 286 // dropped. 287 static bool ReadPackedEnumNoInline(input, 288 bool (*is_valid)(int), 289 RepeatedField<int>* value); 290 291 static bool ReadString(input, string* value); 292 static bool ReadBytes (input, string* value); 293 294 static inline bool ReadGroup (field_number, input, MessageLite* value); 295 static inline bool ReadMessage(input, MessageLite* value); 296 297 // Like above, but de-virtualize the call to MergePartialFromCodedStream(). 298 // The pointer must point at an instance of MessageType, *not* a subclass (or 299 // the subclass must not override MergePartialFromCodedStream()). 300 template<typename MessageType> 301 static inline bool ReadGroupNoVirtual(field_number, input, 302 MessageType* value); 303 template<typename MessageType> 304 static inline bool ReadMessageNoVirtual(input, MessageType* value); 305 306 // Write a tag. The Write*() functions typically include the tag, so 307 // normally there's no need to call this unless using the Write*NoTag() 308 // variants. 309 static inline void WriteTag(field_number, WireType type, output) INL; 310 311 // Write fields, without tags. 312 static inline void WriteInt32NoTag (int32 value, output) INL; 313 static inline void WriteInt64NoTag (int64 value, output) INL; 314 static inline void WriteUInt32NoTag (uint32 value, output) INL; 315 static inline void WriteUInt64NoTag (uint64 value, output) INL; 316 static inline void WriteSInt32NoTag (int32 value, output) INL; 317 static inline void WriteSInt64NoTag (int64 value, output) INL; 318 static inline void WriteFixed32NoTag (uint32 value, output) INL; 319 static inline void WriteFixed64NoTag (uint64 value, output) INL; 320 static inline void WriteSFixed32NoTag(int32 value, output) INL; 321 static inline void WriteSFixed64NoTag(int64 value, output) INL; 322 static inline void WriteFloatNoTag (float value, output) INL; 323 static inline void WriteDoubleNoTag (double value, output) INL; 324 static inline void WriteBoolNoTag (bool value, output) INL; 325 static inline void WriteEnumNoTag (int value, output) INL; 326 327 // Write fields, including tags. 328 static void WriteInt32 (field_number, int32 value, output); 329 static void WriteInt64 (field_number, int64 value, output); 330 static void WriteUInt32 (field_number, uint32 value, output); 331 static void WriteUInt64 (field_number, uint64 value, output); 332 static void WriteSInt32 (field_number, int32 value, output); 333 static void WriteSInt64 (field_number, int64 value, output); 334 static void WriteFixed32 (field_number, uint32 value, output); 335 static void WriteFixed64 (field_number, uint64 value, output); 336 static void WriteSFixed32(field_number, int32 value, output); 337 static void WriteSFixed64(field_number, int64 value, output); 338 static void WriteFloat (field_number, float value, output); 339 static void WriteDouble (field_number, double value, output); 340 static void WriteBool (field_number, bool value, output); 341 static void WriteEnum (field_number, int value, output); 342 343 static void WriteString(field_number, const string& value, output); 344 static void WriteBytes (field_number, const string& value, output); 345 346 static void WriteGroup( 347 field_number, const MessageLite& value, output); 348 static void WriteMessage( 349 field_number, const MessageLite& value, output); 350 // Like above, but these will check if the output stream has enough 351 // space to write directly to a flat array. 352 static void WriteGroupMaybeToArray( 353 field_number, const MessageLite& value, output); 354 static void WriteMessageMaybeToArray( 355 field_number, const MessageLite& value, output); 356 357 // Like above, but de-virtualize the call to SerializeWithCachedSizes(). The 358 // pointer must point at an instance of MessageType, *not* a subclass (or 359 // the subclass must not override SerializeWithCachedSizes()). 360 template<typename MessageType> 361 static inline void WriteGroupNoVirtual( 362 field_number, const MessageType& value, output); 363 template<typename MessageType> 364 static inline void WriteMessageNoVirtual( 365 field_number, const MessageType& value, output); 366 367 #undef output 368 #define output uint8* target 369 370 // Like above, but use only *ToArray methods of CodedOutputStream. 371 static inline uint8* WriteTagToArray(field_number, WireType type, output) INL; 372 373 // Write fields, without tags. 374 static inline uint8* WriteInt32NoTagToArray (int32 value, output) INL; 375 static inline uint8* WriteInt64NoTagToArray (int64 value, output) INL; 376 static inline uint8* WriteUInt32NoTagToArray (uint32 value, output) INL; 377 static inline uint8* WriteUInt64NoTagToArray (uint64 value, output) INL; 378 static inline uint8* WriteSInt32NoTagToArray (int32 value, output) INL; 379 static inline uint8* WriteSInt64NoTagToArray (int64 value, output) INL; 380 static inline uint8* WriteFixed32NoTagToArray (uint32 value, output) INL; 381 static inline uint8* WriteFixed64NoTagToArray (uint64 value, output) INL; 382 static inline uint8* WriteSFixed32NoTagToArray(int32 value, output) INL; 383 static inline uint8* WriteSFixed64NoTagToArray(int64 value, output) INL; 384 static inline uint8* WriteFloatNoTagToArray (float value, output) INL; 385 static inline uint8* WriteDoubleNoTagToArray (double value, output) INL; 386 static inline uint8* WriteBoolNoTagToArray (bool value, output) INL; 387 static inline uint8* WriteEnumNoTagToArray (int value, output) INL; 388 389 // Write fields, including tags. 390 static inline uint8* WriteInt32ToArray( 391 field_number, int32 value, output) INL; 392 static inline uint8* WriteInt64ToArray( 393 field_number, int64 value, output) INL; 394 static inline uint8* WriteUInt32ToArray( 395 field_number, uint32 value, output) INL; 396 static inline uint8* WriteUInt64ToArray( 397 field_number, uint64 value, output) INL; 398 static inline uint8* WriteSInt32ToArray( 399 field_number, int32 value, output) INL; 400 static inline uint8* WriteSInt64ToArray( 401 field_number, int64 value, output) INL; 402 static inline uint8* WriteFixed32ToArray( 403 field_number, uint32 value, output) INL; 404 static inline uint8* WriteFixed64ToArray( 405 field_number, uint64 value, output) INL; 406 static inline uint8* WriteSFixed32ToArray( 407 field_number, int32 value, output) INL; 408 static inline uint8* WriteSFixed64ToArray( 409 field_number, int64 value, output) INL; 410 static inline uint8* WriteFloatToArray( 411 field_number, float value, output) INL; 412 static inline uint8* WriteDoubleToArray( 413 field_number, double value, output) INL; 414 static inline uint8* WriteBoolToArray( 415 field_number, bool value, output) INL; 416 static inline uint8* WriteEnumToArray( 417 field_number, int value, output) INL; 418 419 static inline uint8* WriteStringToArray( 420 field_number, const string& value, output) INL; 421 static inline uint8* WriteBytesToArray( 422 field_number, const string& value, output) INL; 423 424 static inline uint8* WriteGroupToArray( 425 field_number, const MessageLite& value, output) INL; 426 static inline uint8* WriteMessageToArray( 427 field_number, const MessageLite& value, output) INL; 428 429 // Like above, but de-virtualize the call to SerializeWithCachedSizes(). The 430 // pointer must point at an instance of MessageType, *not* a subclass (or 431 // the subclass must not override SerializeWithCachedSizes()). 432 template<typename MessageType> 433 static inline uint8* WriteGroupNoVirtualToArray( 434 field_number, const MessageType& value, output) INL; 435 template<typename MessageType> 436 static inline uint8* WriteMessageNoVirtualToArray( 437 field_number, const MessageType& value, output) INL; 438 439 #undef output 440 #undef input 441 #undef INL 442 443 #undef field_number 444 445 // Compute the byte size of a field. The XxSize() functions do NOT include 446 // the tag, so you must also call TagSize(). (This is because, for repeated 447 // fields, you should only call TagSize() once and multiply it by the element 448 // count, but you may have to call XxSize() for each individual element.) 449 static inline int Int32Size ( int32 value); 450 static inline int Int64Size ( int64 value); 451 static inline int UInt32Size (uint32 value); 452 static inline int UInt64Size (uint64 value); 453 static inline int SInt32Size ( int32 value); 454 static inline int SInt64Size ( int64 value); 455 static inline int EnumSize ( int value); 456 457 // These types always have the same size. 458 static const int kFixed32Size = 4; 459 static const int kFixed64Size = 8; 460 static const int kSFixed32Size = 4; 461 static const int kSFixed64Size = 8; 462 static const int kFloatSize = 4; 463 static const int kDoubleSize = 8; 464 static const int kBoolSize = 1; 465 466 static inline int StringSize(const string& value); 467 static inline int BytesSize (const string& value); 468 469 static inline int GroupSize (const MessageLite& value); 470 static inline int MessageSize(const MessageLite& value); 471 472 // Like above, but de-virtualize the call to ByteSize(). The 473 // pointer must point at an instance of MessageType, *not* a subclass (or 474 // the subclass must not override ByteSize()). 475 template<typename MessageType> 476 static inline int GroupSizeNoVirtual (const MessageType& value); 477 template<typename MessageType> 478 static inline int MessageSizeNoVirtual(const MessageType& value); 479 480 private: 481 // A helper method for the repeated primitive reader. This method has 482 // optimizations for primitive types that have fixed size on the wire, and 483 // can be read using potentially faster paths. 484 template <typename CType, enum FieldType DeclaredType> 485 static inline bool ReadRepeatedFixedSizePrimitive( 486 int tag_size, 487 uint32 tag, 488 google::protobuf::io::CodedInputStream* input, 489 RepeatedField<CType>* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; 490 491 static const CppType kFieldTypeToCppTypeMap[]; 492 static const WireFormatLite::WireType kWireTypeForFieldType[]; 493 494 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormatLite); 495 }; 496 497 // A class which deals with unknown values. The default implementation just 498 // discards them. WireFormat defines a subclass which writes to an 499 // UnknownFieldSet. This class is used by ExtensionSet::ParseField(), since 500 // ExtensionSet is part of the lite library but UnknownFieldSet is not. 501 class LIBPROTOBUF_EXPORT FieldSkipper { 502 public: 503 FieldSkipper() {} 504 virtual ~FieldSkipper() {} 505 506 // Skip a field whose tag has already been consumed. 507 virtual bool SkipField(io::CodedInputStream* input, uint32 tag); 508 509 // Skip an entire message or group, up to an end-group tag (which is consumed) 510 // or end-of-stream. 511 virtual bool SkipMessage(io::CodedInputStream* input); 512 513 // Deal with an already-parsed unrecognized enum value. The default 514 // implementation does nothing, but the UnknownFieldSet-based implementation 515 // saves it as an unknown varint. 516 virtual void SkipUnknownEnum(int field_number, int value); 517 }; 518 519 // inline methods ==================================================== 520 521 inline WireFormatLite::CppType 522 WireFormatLite::FieldTypeToCppType(FieldType type) { 523 return kFieldTypeToCppTypeMap[type]; 524 } 525 526 inline uint32 WireFormatLite::MakeTag(int field_number, WireType type) { 527 return GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(field_number, type); 528 } 529 530 inline WireFormatLite::WireType WireFormatLite::GetTagWireType(uint32 tag) { 531 return static_cast<WireType>(tag & kTagTypeMask); 532 } 533 534 inline int WireFormatLite::GetTagFieldNumber(uint32 tag) { 535 return static_cast<int>(tag >> kTagTypeBits); 536 } 537 538 inline int WireFormatLite::TagSize(int field_number, 539 WireFormatLite::FieldType type) { 540 int result = io::CodedOutputStream::VarintSize32( 541 field_number << kTagTypeBits); 542 if (type == TYPE_GROUP) { 543 // Groups have both a start and an end tag. 544 return result * 2; 545 } else { 546 return result; 547 } 548 } 549 550 inline uint32 WireFormatLite::EncodeFloat(float value) { 551 union {float f; uint32 i;}; 552 f = value; 553 return i; 554 } 555 556 inline float WireFormatLite::DecodeFloat(uint32 value) { 557 union {float f; uint32 i;}; 558 i = value; 559 return f; 560 } 561 562 inline uint64 WireFormatLite::EncodeDouble(double value) { 563 union {double f; uint64 i;}; 564 f = value; 565 return i; 566 } 567 568 inline double WireFormatLite::DecodeDouble(uint64 value) { 569 union {double f; uint64 i;}; 570 i = value; 571 return f; 572 } 573 574 // ZigZag Transform: Encodes signed integers so that they can be 575 // effectively used with varint encoding. 576 // 577 // varint operates on unsigned integers, encoding smaller numbers into 578 // fewer bytes. If you try to use it on a signed integer, it will treat 579 // this number as a very large unsigned integer, which means that even 580 // small signed numbers like -1 will take the maximum number of bytes 581 // (10) to encode. ZigZagEncode() maps signed integers to unsigned 582 // in such a way that those with a small absolute value will have smaller 583 // encoded values, making them appropriate for encoding using varint. 584 // 585 // int32 -> uint32 586 // ------------------------- 587 // 0 -> 0 588 // -1 -> 1 589 // 1 -> 2 590 // -2 -> 3 591 // ... -> ... 592 // 2147483647 -> 4294967294 593 // -2147483648 -> 4294967295 594 // 595 // >> encode >> 596 // << decode << 597 598 inline uint32 WireFormatLite::ZigZagEncode32(int32 n) { 599 // Note: the right-shift must be arithmetic 600 return (n << 1) ^ (n >> 31); 601 } 602 603 inline int32 WireFormatLite::ZigZagDecode32(uint32 n) { 604 return (n >> 1) ^ -static_cast<int32>(n & 1); 605 } 606 607 inline uint64 WireFormatLite::ZigZagEncode64(int64 n) { 608 // Note: the right-shift must be arithmetic 609 return (n << 1) ^ (n >> 63); 610 } 611 612 inline int64 WireFormatLite::ZigZagDecode64(uint64 n) { 613 return (n >> 1) ^ -static_cast<int64>(n & 1); 614 } 615 616 } // namespace internal 617 } // namespace protobuf 618 619 } // namespace google 620 #endif // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__ 621