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@google.com (Kenton Varda)
32 // atenasio@google.com (Chris Atenasio) (ZigZag transform)
33 // wink@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
WireTypeForFieldType(WireFormatLite::FieldType type)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:
FieldSkipper()503 FieldSkipper() {}
~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
FieldTypeToCppType(FieldType type)522 WireFormatLite::FieldTypeToCppType(FieldType type) {
523 return kFieldTypeToCppTypeMap[type];
524 }
525
MakeTag(int field_number,WireType type)526 inline uint32 WireFormatLite::MakeTag(int field_number, WireType type) {
527 return GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(field_number, type);
528 }
529
GetTagWireType(uint32 tag)530 inline WireFormatLite::WireType WireFormatLite::GetTagWireType(uint32 tag) {
531 return static_cast<WireType>(tag & kTagTypeMask);
532 }
533
GetTagFieldNumber(uint32 tag)534 inline int WireFormatLite::GetTagFieldNumber(uint32 tag) {
535 return static_cast<int>(tag >> kTagTypeBits);
536 }
537
TagSize(int field_number,WireFormatLite::FieldType type)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
EncodeFloat(float value)550 inline uint32 WireFormatLite::EncodeFloat(float value) {
551 union {float f; uint32 i;};
552 f = value;
553 return i;
554 }
555
DecodeFloat(uint32 value)556 inline float WireFormatLite::DecodeFloat(uint32 value) {
557 union {float f; uint32 i;};
558 i = value;
559 return f;
560 }
561
EncodeDouble(double value)562 inline uint64 WireFormatLite::EncodeDouble(double value) {
563 union {double f; uint64 i;};
564 f = value;
565 return i;
566 }
567
DecodeDouble(uint64 value)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
ZigZagEncode32(int32 n)598 inline uint32 WireFormatLite::ZigZagEncode32(int32 n) {
599 // Note: the right-shift must be arithmetic
600 return (n << 1) ^ (n >> 31);
601 }
602
ZigZagDecode32(uint32 n)603 inline int32 WireFormatLite::ZigZagDecode32(uint32 n) {
604 return (n >> 1) ^ -static_cast<int32>(n & 1);
605 }
606
ZigZagEncode64(int64 n)607 inline uint64 WireFormatLite::ZigZagEncode64(int64 n) {
608 // Note: the right-shift must be arithmetic
609 return (n << 1) ^ (n >> 63);
610 }
611
ZigZagDecode64(uint64 n)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