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