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
46namespace google {
47
48namespace 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
56namespace protobuf {
57namespace internal {
58
59class 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.
70class 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.
501class 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
521inline WireFormatLite::CppType
522WireFormatLite::FieldTypeToCppType(FieldType type) {
523  return kFieldTypeToCppTypeMap[type];
524}
525
526inline uint32 WireFormatLite::MakeTag(int field_number, WireType type) {
527  return GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(field_number, type);
528}
529
530inline WireFormatLite::WireType WireFormatLite::GetTagWireType(uint32 tag) {
531  return static_cast<WireType>(tag & kTagTypeMask);
532}
533
534inline int WireFormatLite::GetTagFieldNumber(uint32 tag) {
535  return static_cast<int>(tag >> kTagTypeBits);
536}
537
538inline 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
550inline uint32 WireFormatLite::EncodeFloat(float value) {
551  union {float f; uint32 i;};
552  f = value;
553  return i;
554}
555
556inline float WireFormatLite::DecodeFloat(uint32 value) {
557  union {float f; uint32 i;};
558  i = value;
559  return f;
560}
561
562inline uint64 WireFormatLite::EncodeDouble(double value) {
563  union {double f; uint64 i;};
564  f = value;
565  return i;
566}
567
568inline 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
598inline uint32 WireFormatLite::ZigZagEncode32(int32 n) {
599  // Note:  the right-shift must be arithmetic
600  return (n << 1) ^ (n >> 31);
601}
602
603inline int32 WireFormatLite::ZigZagDecode32(uint32 n) {
604  return (n >> 1) ^ -static_cast<int32>(n & 1);
605}
606
607inline uint64 WireFormatLite::ZigZagEncode64(int64 n) {
608  // Note:  the right-shift must be arithmetic
609  return (n << 1) ^ (n >> 63);
610}
611
612inline 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