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: [email protected] (Kenton Varda) |
32 | // [email protected] (Chris Atenasio) (ZigZag transform) |
33 | // [email protected] (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 | |
45 | #include <google/protobuf/stubs/common.h> |
46 | #include <google/protobuf/stubs/logging.h> |
47 | #include <google/protobuf/io/coded_stream.h> |
48 | #include <google/protobuf/arenastring.h> |
49 | #include <google/protobuf/message_lite.h> |
50 | #include <google/protobuf/port.h> |
51 | #include <google/protobuf/repeated_field.h> |
52 | |
53 | // Do UTF-8 validation on string type in Debug build only |
54 | #ifndef NDEBUG |
55 | #define GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED |
56 | #endif |
57 | |
58 | // Avoid conflict with iOS where <ConditionalMacros.h> #defines TYPE_BOOL. |
59 | // |
60 | // If some one needs the macro TYPE_BOOL in a file that includes this header, |
61 | // it's possible to bring it back using push/pop_macro as follows. |
62 | // |
63 | // #pragma push_macro("TYPE_BOOL") |
64 | // #include this header and/or all headers that need the macro to be undefined. |
65 | // #pragma pop_macro("TYPE_BOOL") |
66 | #undef TYPE_BOOL |
67 | |
68 | |
69 | namespace google { |
70 | namespace protobuf { |
71 | namespace internal { |
72 | |
73 | #include <google/protobuf/port_def.inc> |
74 | |
75 | // This class is for internal use by the protocol buffer library and by |
76 | // protocol-complier-generated message classes. It must not be called |
77 | // directly by clients. |
78 | // |
79 | // This class contains helpers for implementing the binary protocol buffer |
80 | // wire format without the need for reflection. Use WireFormat when using |
81 | // reflection. |
82 | // |
83 | // This class is really a namespace that contains only static methods. |
84 | class PROTOBUF_EXPORT WireFormatLite { |
85 | public: |
86 | // ----------------------------------------------------------------- |
87 | // Helper constants and functions related to the format. These are |
88 | // mostly meant for internal and generated code to use. |
89 | |
90 | // The wire format is composed of a sequence of tag/value pairs, each |
91 | // of which contains the value of one field (or one element of a repeated |
92 | // field). Each tag is encoded as a varint. The lower bits of the tag |
93 | // identify its wire type, which specifies the format of the data to follow. |
94 | // The rest of the bits contain the field number. Each type of field (as |
95 | // declared by FieldDescriptor::Type, in descriptor.h) maps to one of |
96 | // these wire types. Immediately following each tag is the field's value, |
97 | // encoded in the format specified by the wire type. Because the tag |
98 | // identifies the encoding of this data, it is possible to skip |
99 | // unrecognized fields for forwards compatibility. |
100 | |
101 | enum WireType { |
102 | WIRETYPE_VARINT = 0, |
103 | WIRETYPE_FIXED64 = 1, |
104 | WIRETYPE_LENGTH_DELIMITED = 2, |
105 | WIRETYPE_START_GROUP = 3, |
106 | WIRETYPE_END_GROUP = 4, |
107 | WIRETYPE_FIXED32 = 5, |
108 | }; |
109 | |
110 | // Lite alternative to FieldDescriptor::Type. Must be kept in sync. |
111 | enum FieldType { |
112 | TYPE_DOUBLE = 1, |
113 | TYPE_FLOAT = 2, |
114 | TYPE_INT64 = 3, |
115 | TYPE_UINT64 = 4, |
116 | TYPE_INT32 = 5, |
117 | TYPE_FIXED64 = 6, |
118 | TYPE_FIXED32 = 7, |
119 | TYPE_BOOL = 8, |
120 | TYPE_STRING = 9, |
121 | TYPE_GROUP = 10, |
122 | TYPE_MESSAGE = 11, |
123 | TYPE_BYTES = 12, |
124 | TYPE_UINT32 = 13, |
125 | TYPE_ENUM = 14, |
126 | TYPE_SFIXED32 = 15, |
127 | TYPE_SFIXED64 = 16, |
128 | TYPE_SINT32 = 17, |
129 | TYPE_SINT64 = 18, |
130 | MAX_FIELD_TYPE = 18, |
131 | }; |
132 | |
133 | // Lite alternative to FieldDescriptor::CppType. Must be kept in sync. |
134 | enum CppType { |
135 | CPPTYPE_INT32 = 1, |
136 | CPPTYPE_INT64 = 2, |
137 | CPPTYPE_UINT32 = 3, |
138 | CPPTYPE_UINT64 = 4, |
139 | CPPTYPE_DOUBLE = 5, |
140 | CPPTYPE_FLOAT = 6, |
141 | CPPTYPE_BOOL = 7, |
142 | CPPTYPE_ENUM = 8, |
143 | CPPTYPE_STRING = 9, |
144 | CPPTYPE_MESSAGE = 10, |
145 | MAX_CPPTYPE = 10, |
146 | }; |
147 | |
148 | // Helper method to get the CppType for a particular Type. |
149 | static CppType FieldTypeToCppType(FieldType type); |
150 | |
151 | // Given a FieldDescriptor::Type return its WireType |
152 | static inline WireFormatLite::WireType WireTypeForFieldType( |
153 | WireFormatLite::FieldType type) { |
154 | return kWireTypeForFieldType[type]; |
155 | } |
156 | |
157 | // Number of bits in a tag which identify the wire type. |
158 | static const int kTagTypeBits = 3; |
159 | // Mask for those bits. |
160 | static const uint32 kTagTypeMask = (1 << kTagTypeBits) - 1; |
161 | |
162 | // Helper functions for encoding and decoding tags. (Inlined below and in |
163 | // _inl.h) |
164 | // |
165 | // This is different from MakeTag(field->number(), field->type()) in the |
166 | // case of packed repeated fields. |
167 | constexpr static uint32 MakeTag(int field_number, WireType type); |
168 | static WireType GetTagWireType(uint32 tag); |
169 | static int GetTagFieldNumber(uint32 tag); |
170 | |
171 | // Compute the byte size of a tag. For groups, this includes both the start |
172 | // and end tags. |
173 | static inline size_t TagSize(int field_number, |
174 | WireFormatLite::FieldType type); |
175 | |
176 | // Skips a field value with the given tag. The input should start |
177 | // positioned immediately after the tag. Skipped values are simply |
178 | // discarded, not recorded anywhere. See WireFormat::SkipField() for a |
179 | // version that records to an UnknownFieldSet. |
180 | static bool SkipField(io::CodedInputStream* input, uint32 tag); |
181 | |
182 | // Skips a field value with the given tag. The input should start |
183 | // positioned immediately after the tag. Skipped values are recorded to a |
184 | // CodedOutputStream. |
185 | static bool SkipField(io::CodedInputStream* input, uint32 tag, |
186 | io::CodedOutputStream* output); |
187 | |
188 | // Reads and ignores a message from the input. Skipped values are simply |
189 | // discarded, not recorded anywhere. See WireFormat::SkipMessage() for a |
190 | // version that records to an UnknownFieldSet. |
191 | static bool SkipMessage(io::CodedInputStream* input); |
192 | |
193 | // Reads and ignores a message from the input. Skipped values are recorded |
194 | // to a CodedOutputStream. |
195 | static bool SkipMessage(io::CodedInputStream* input, |
196 | io::CodedOutputStream* output); |
197 | |
198 | // This macro does the same thing as WireFormatLite::MakeTag(), but the |
199 | // result is usable as a compile-time constant, which makes it usable |
200 | // as a switch case or a template input. WireFormatLite::MakeTag() is more |
201 | // type-safe, though, so prefer it if possible. |
202 | #define GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(FIELD_NUMBER, TYPE) \ |
203 | static_cast<uint32>((static_cast<uint32>(FIELD_NUMBER) << 3) | (TYPE)) |
204 | |
205 | // These are the tags for the old MessageSet format, which was defined as: |
206 | // message MessageSet { |
207 | // repeated group Item = 1 { |
208 | // required int32 type_id = 2; |
209 | // required string message = 3; |
210 | // } |
211 | // } |
212 | static const int kMessageSetItemNumber = 1; |
213 | static const int kMessageSetTypeIdNumber = 2; |
214 | static const int kMessageSetMessageNumber = 3; |
215 | static const int kMessageSetItemStartTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG( |
216 | kMessageSetItemNumber, WireFormatLite::WIRETYPE_START_GROUP); |
217 | static const int kMessageSetItemEndTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG( |
218 | kMessageSetItemNumber, WireFormatLite::WIRETYPE_END_GROUP); |
219 | static const int kMessageSetTypeIdTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG( |
220 | kMessageSetTypeIdNumber, WireFormatLite::WIRETYPE_VARINT); |
221 | static const int kMessageSetMessageTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG( |
222 | kMessageSetMessageNumber, WireFormatLite::WIRETYPE_LENGTH_DELIMITED); |
223 | |
224 | // Byte size of all tags of a MessageSet::Item combined. |
225 | static const size_t kMessageSetItemTagsSize; |
226 | |
227 | // Helper functions for converting between floats/doubles and IEEE-754 |
228 | // uint32s/uint64s so that they can be written. (Assumes your platform |
229 | // uses IEEE-754 floats.) |
230 | static uint32 EncodeFloat(float value); |
231 | static float DecodeFloat(uint32 value); |
232 | static uint64 EncodeDouble(double value); |
233 | static double DecodeDouble(uint64 value); |
234 | |
235 | // Helper functions for mapping signed integers to unsigned integers in |
236 | // such a way that numbers with small magnitudes will encode to smaller |
237 | // varints. If you simply static_cast a negative number to an unsigned |
238 | // number and varint-encode it, it will always take 10 bytes, defeating |
239 | // the purpose of varint. So, for the "sint32" and "sint64" field types, |
240 | // we ZigZag-encode the values. |
241 | static uint32 ZigZagEncode32(int32 n); |
242 | static int32 ZigZagDecode32(uint32 n); |
243 | static uint64 ZigZagEncode64(int64 n); |
244 | static int64 ZigZagDecode64(uint64 n); |
245 | |
246 | // ================================================================= |
247 | // Methods for reading/writing individual field. |
248 | |
249 | // Read fields, not including tags. The assumption is that you already |
250 | // read the tag to determine what field to read. |
251 | |
252 | // For primitive fields, we just use a templatized routine parameterized by |
253 | // the represented type and the FieldType. These are specialized with the |
254 | // appropriate definition for each declared type. |
255 | template <typename CType, enum FieldType DeclaredType> |
256 | PROTOBUF_ALWAYS_INLINE static bool ReadPrimitive(io::CodedInputStream* input, |
257 | CType* value); |
258 | |
259 | // Reads repeated primitive values, with optimizations for repeats. |
260 | // tag_size and tag should both be compile-time constants provided by the |
261 | // protocol compiler. |
262 | template <typename CType, enum FieldType DeclaredType> |
263 | PROTOBUF_ALWAYS_INLINE static bool ReadRepeatedPrimitive( |
264 | int tag_size, uint32 tag, io::CodedInputStream* input, |
265 | RepeatedField<CType>* value); |
266 | |
267 | // Identical to ReadRepeatedPrimitive, except will not inline the |
268 | // implementation. |
269 | template <typename CType, enum FieldType DeclaredType> |
270 | static bool ReadRepeatedPrimitiveNoInline(int tag_size, uint32 tag, |
271 | io::CodedInputStream* 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 | PROTOBUF_ALWAYS_INLINE static const uint8* ReadPrimitiveFromArray( |
281 | const uint8* buffer, CType* value); |
282 | |
283 | // Reads a primitive packed field. |
284 | // |
285 | // This is only implemented for packable types. |
286 | template <typename CType, enum FieldType DeclaredType> |
287 | PROTOBUF_ALWAYS_INLINE static bool ReadPackedPrimitive( |
288 | io::CodedInputStream* input, RepeatedField<CType>* value); |
289 | |
290 | // Identical to ReadPackedPrimitive, except will not inline the |
291 | // implementation. |
292 | template <typename CType, enum FieldType DeclaredType> |
293 | static bool ReadPackedPrimitiveNoInline(io::CodedInputStream* input, |
294 | RepeatedField<CType>* value); |
295 | |
296 | // Read a packed enum field. If the is_valid function is not NULL, values for |
297 | // which is_valid(value) returns false are silently dropped. |
298 | static bool ReadPackedEnumNoInline(io::CodedInputStream* input, |
299 | bool (*is_valid)(int), |
300 | RepeatedField<int>* values); |
301 | |
302 | // Read a packed enum field. If the is_valid function is not NULL, values for |
303 | // which is_valid(value) returns false are appended to unknown_fields_stream. |
304 | static bool ReadPackedEnumPreserveUnknowns( |
305 | io::CodedInputStream* input, int field_number, bool (*is_valid)(int), |
306 | io::CodedOutputStream* unknown_fields_stream, RepeatedField<int>* values); |
307 | |
308 | // Read a string. ReadString(..., std::string* value) requires an |
309 | // existing std::string. |
310 | static inline bool ReadString(io::CodedInputStream* input, |
311 | std::string* value); |
312 | // ReadString(..., std::string** p) is internal-only, and should only be |
313 | // called from generated code. It starts by setting *p to "new std::string" if |
314 | // *p == &GetEmptyStringAlreadyInited(). It then invokes |
315 | // ReadString(io::CodedInputStream* input, *p). This is useful for reducing |
316 | // code size. |
317 | static inline bool ReadString(io::CodedInputStream* input, std::string** p); |
318 | // Analogous to ReadString(). |
319 | static bool ReadBytes(io::CodedInputStream* input, std::string* value); |
320 | static bool ReadBytes(io::CodedInputStream* input, std::string** p); |
321 | |
322 | enum Operation { |
323 | PARSE = 0, |
324 | SERIALIZE = 1, |
325 | }; |
326 | |
327 | // Returns true if the data is valid UTF-8. |
328 | static bool VerifyUtf8String(const char* data, int size, Operation op, |
329 | const char* field_name); |
330 | |
331 | template <typename MessageType> |
332 | static inline bool ReadGroup(int field_number, io::CodedInputStream* input, |
333 | MessageType* value); |
334 | |
335 | template <typename MessageType> |
336 | static inline bool ReadMessage(io::CodedInputStream* input, |
337 | MessageType* value); |
338 | |
339 | template <typename MessageType> |
340 | static inline bool ReadMessageNoVirtual(io::CodedInputStream* input, |
341 | MessageType* value) { |
342 | return ReadMessage(input, value); |
343 | } |
344 | |
345 | // Write a tag. The Write*() functions typically include the tag, so |
346 | // normally there's no need to call this unless using the Write*NoTag() |
347 | // variants. |
348 | PROTOBUF_ALWAYS_INLINE static void WriteTag(int field_number, WireType type, |
349 | io::CodedOutputStream* output); |
350 | |
351 | // Write fields, without tags. |
352 | PROTOBUF_ALWAYS_INLINE static void WriteInt32NoTag( |
353 | int32 value, io::CodedOutputStream* output); |
354 | PROTOBUF_ALWAYS_INLINE static void WriteInt64NoTag( |
355 | int64 value, io::CodedOutputStream* output); |
356 | PROTOBUF_ALWAYS_INLINE static void WriteUInt32NoTag( |
357 | uint32 value, io::CodedOutputStream* output); |
358 | PROTOBUF_ALWAYS_INLINE static void WriteUInt64NoTag( |
359 | uint64 value, io::CodedOutputStream* output); |
360 | PROTOBUF_ALWAYS_INLINE static void WriteSInt32NoTag( |
361 | int32 value, io::CodedOutputStream* output); |
362 | PROTOBUF_ALWAYS_INLINE static void WriteSInt64NoTag( |
363 | int64 value, io::CodedOutputStream* output); |
364 | PROTOBUF_ALWAYS_INLINE static void WriteFixed32NoTag( |
365 | uint32 value, io::CodedOutputStream* output); |
366 | PROTOBUF_ALWAYS_INLINE static void WriteFixed64NoTag( |
367 | uint64 value, io::CodedOutputStream* output); |
368 | PROTOBUF_ALWAYS_INLINE static void WriteSFixed32NoTag( |
369 | int32 value, io::CodedOutputStream* output); |
370 | PROTOBUF_ALWAYS_INLINE static void WriteSFixed64NoTag( |
371 | int64 value, io::CodedOutputStream* output); |
372 | PROTOBUF_ALWAYS_INLINE static void WriteFloatNoTag( |
373 | float value, io::CodedOutputStream* output); |
374 | PROTOBUF_ALWAYS_INLINE static void WriteDoubleNoTag( |
375 | double value, io::CodedOutputStream* output); |
376 | PROTOBUF_ALWAYS_INLINE static void WriteBoolNoTag( |
377 | bool value, io::CodedOutputStream* output); |
378 | PROTOBUF_ALWAYS_INLINE static void WriteEnumNoTag( |
379 | int value, io::CodedOutputStream* output); |
380 | |
381 | // Write array of primitive fields, without tags |
382 | static void WriteFloatArray(const float* a, int n, |
383 | io::CodedOutputStream* output); |
384 | static void WriteDoubleArray(const double* a, int n, |
385 | io::CodedOutputStream* output); |
386 | static void WriteFixed32Array(const uint32* a, int n, |
387 | io::CodedOutputStream* output); |
388 | static void WriteFixed64Array(const uint64* a, int n, |
389 | io::CodedOutputStream* output); |
390 | static void WriteSFixed32Array(const int32* a, int n, |
391 | io::CodedOutputStream* output); |
392 | static void WriteSFixed64Array(const int64* a, int n, |
393 | io::CodedOutputStream* output); |
394 | static void WriteBoolArray(const bool* a, int n, |
395 | io::CodedOutputStream* output); |
396 | |
397 | // Write fields, including tags. |
398 | static void WriteInt32(int field_number, int32 value, |
399 | io::CodedOutputStream* output); |
400 | static void WriteInt64(int field_number, int64 value, |
401 | io::CodedOutputStream* output); |
402 | static void WriteUInt32(int field_number, uint32 value, |
403 | io::CodedOutputStream* output); |
404 | static void WriteUInt64(int field_number, uint64 value, |
405 | io::CodedOutputStream* output); |
406 | static void WriteSInt32(int field_number, int32 value, |
407 | io::CodedOutputStream* output); |
408 | static void WriteSInt64(int field_number, int64 value, |
409 | io::CodedOutputStream* output); |
410 | static void WriteFixed32(int field_number, uint32 value, |
411 | io::CodedOutputStream* output); |
412 | static void WriteFixed64(int field_number, uint64 value, |
413 | io::CodedOutputStream* output); |
414 | static void WriteSFixed32(int field_number, int32 value, |
415 | io::CodedOutputStream* output); |
416 | static void WriteSFixed64(int field_number, int64 value, |
417 | io::CodedOutputStream* output); |
418 | static void WriteFloat(int field_number, float value, |
419 | io::CodedOutputStream* output); |
420 | static void WriteDouble(int field_number, double value, |
421 | io::CodedOutputStream* output); |
422 | static void WriteBool(int field_number, bool value, |
423 | io::CodedOutputStream* output); |
424 | static void WriteEnum(int field_number, int value, |
425 | io::CodedOutputStream* output); |
426 | |
427 | static void WriteString(int field_number, const std::string& value, |
428 | io::CodedOutputStream* output); |
429 | static void WriteBytes(int field_number, const std::string& value, |
430 | io::CodedOutputStream* output); |
431 | static void WriteStringMaybeAliased(int field_number, |
432 | const std::string& value, |
433 | io::CodedOutputStream* output); |
434 | static void WriteBytesMaybeAliased(int field_number, const std::string& value, |
435 | io::CodedOutputStream* output); |
436 | |
437 | static void WriteGroup(int field_number, const MessageLite& value, |
438 | io::CodedOutputStream* output); |
439 | static void WriteMessage(int field_number, const MessageLite& value, |
440 | io::CodedOutputStream* output); |
441 | // Like above, but these will check if the output stream has enough |
442 | // space to write directly to a flat array. |
443 | static void WriteGroupMaybeToArray(int field_number, const MessageLite& value, |
444 | io::CodedOutputStream* output); |
445 | static void WriteMessageMaybeToArray(int field_number, |
446 | const MessageLite& value, |
447 | io::CodedOutputStream* output); |
448 | |
449 | // Like above, but de-virtualize the call to SerializeWithCachedSizes(). The |
450 | // pointer must point at an instance of MessageType, *not* a subclass (or |
451 | // the subclass must not override SerializeWithCachedSizes()). |
452 | template <typename MessageType> |
453 | static inline void WriteGroupNoVirtual(int field_number, |
454 | const MessageType& value, |
455 | io::CodedOutputStream* output); |
456 | template <typename MessageType> |
457 | static inline void WriteMessageNoVirtual(int field_number, |
458 | const MessageType& value, |
459 | io::CodedOutputStream* output); |
460 | |
461 | // Like above, but use only *ToArray methods of CodedOutputStream. |
462 | PROTOBUF_ALWAYS_INLINE static uint8* WriteTagToArray(int field_number, |
463 | WireType type, |
464 | uint8* target); |
465 | |
466 | // Write fields, without tags. |
467 | PROTOBUF_ALWAYS_INLINE static uint8* WriteInt32NoTagToArray(int32 value, |
468 | uint8* target); |
469 | PROTOBUF_ALWAYS_INLINE static uint8* WriteInt64NoTagToArray(int64 value, |
470 | uint8* target); |
471 | PROTOBUF_ALWAYS_INLINE static uint8* WriteUInt32NoTagToArray(uint32 value, |
472 | uint8* target); |
473 | PROTOBUF_ALWAYS_INLINE static uint8* WriteUInt64NoTagToArray(uint64 value, |
474 | uint8* target); |
475 | PROTOBUF_ALWAYS_INLINE static uint8* WriteSInt32NoTagToArray(int32 value, |
476 | uint8* target); |
477 | PROTOBUF_ALWAYS_INLINE static uint8* WriteSInt64NoTagToArray(int64 value, |
478 | uint8* target); |
479 | PROTOBUF_ALWAYS_INLINE static uint8* WriteFixed32NoTagToArray(uint32 value, |
480 | uint8* target); |
481 | PROTOBUF_ALWAYS_INLINE static uint8* WriteFixed64NoTagToArray(uint64 value, |
482 | uint8* target); |
483 | PROTOBUF_ALWAYS_INLINE static uint8* WriteSFixed32NoTagToArray(int32 value, |
484 | uint8* target); |
485 | PROTOBUF_ALWAYS_INLINE static uint8* WriteSFixed64NoTagToArray(int64 value, |
486 | uint8* target); |
487 | PROTOBUF_ALWAYS_INLINE static uint8* WriteFloatNoTagToArray(float value, |
488 | uint8* target); |
489 | PROTOBUF_ALWAYS_INLINE static uint8* WriteDoubleNoTagToArray(double value, |
490 | uint8* target); |
491 | PROTOBUF_ALWAYS_INLINE static uint8* WriteBoolNoTagToArray(bool value, |
492 | uint8* target); |
493 | PROTOBUF_ALWAYS_INLINE static uint8* WriteEnumNoTagToArray(int value, |
494 | uint8* target); |
495 | |
496 | // Write fields, without tags. These require that value.size() > 0. |
497 | template <typename T> |
498 | PROTOBUF_ALWAYS_INLINE static uint8* WritePrimitiveNoTagToArray( |
499 | const RepeatedField<T>& value, uint8* (*Writer)(T, uint8*), |
500 | uint8* target); |
501 | template <typename T> |
502 | PROTOBUF_ALWAYS_INLINE static uint8* WriteFixedNoTagToArray( |
503 | const RepeatedField<T>& value, uint8* (*Writer)(T, uint8*), |
504 | uint8* target); |
505 | |
506 | PROTOBUF_ALWAYS_INLINE static uint8* WriteInt32NoTagToArray( |
507 | const RepeatedField<int32>& value, uint8* output); |
508 | PROTOBUF_ALWAYS_INLINE static uint8* WriteInt64NoTagToArray( |
509 | const RepeatedField<int64>& value, uint8* output); |
510 | PROTOBUF_ALWAYS_INLINE static uint8* WriteUInt32NoTagToArray( |
511 | const RepeatedField<uint32>& value, uint8* output); |
512 | PROTOBUF_ALWAYS_INLINE static uint8* WriteUInt64NoTagToArray( |
513 | const RepeatedField<uint64>& value, uint8* output); |
514 | PROTOBUF_ALWAYS_INLINE static uint8* WriteSInt32NoTagToArray( |
515 | const RepeatedField<int32>& value, uint8* output); |
516 | PROTOBUF_ALWAYS_INLINE static uint8* WriteSInt64NoTagToArray( |
517 | const RepeatedField<int64>& value, uint8* output); |
518 | PROTOBUF_ALWAYS_INLINE static uint8* WriteFixed32NoTagToArray( |
519 | const RepeatedField<uint32>& value, uint8* output); |
520 | PROTOBUF_ALWAYS_INLINE static uint8* WriteFixed64NoTagToArray( |
521 | const RepeatedField<uint64>& value, uint8* output); |
522 | PROTOBUF_ALWAYS_INLINE static uint8* WriteSFixed32NoTagToArray( |
523 | const RepeatedField<int32>& value, uint8* output); |
524 | PROTOBUF_ALWAYS_INLINE static uint8* WriteSFixed64NoTagToArray( |
525 | const RepeatedField<int64>& value, uint8* output); |
526 | PROTOBUF_ALWAYS_INLINE static uint8* WriteFloatNoTagToArray( |
527 | const RepeatedField<float>& value, uint8* output); |
528 | PROTOBUF_ALWAYS_INLINE static uint8* WriteDoubleNoTagToArray( |
529 | const RepeatedField<double>& value, uint8* output); |
530 | PROTOBUF_ALWAYS_INLINE static uint8* WriteBoolNoTagToArray( |
531 | const RepeatedField<bool>& value, uint8* output); |
532 | PROTOBUF_ALWAYS_INLINE static uint8* WriteEnumNoTagToArray( |
533 | const RepeatedField<int>& value, uint8* output); |
534 | |
535 | // Write fields, including tags. |
536 | PROTOBUF_ALWAYS_INLINE static uint8* WriteInt32ToArray(int field_number, |
537 | int32 value, |
538 | uint8* target); |
539 | PROTOBUF_ALWAYS_INLINE static uint8* WriteInt64ToArray(int field_number, |
540 | int64 value, |
541 | uint8* target); |
542 | PROTOBUF_ALWAYS_INLINE static uint8* WriteUInt32ToArray(int field_number, |
543 | uint32 value, |
544 | uint8* target); |
545 | PROTOBUF_ALWAYS_INLINE static uint8* WriteUInt64ToArray(int field_number, |
546 | uint64 value, |
547 | uint8* target); |
548 | PROTOBUF_ALWAYS_INLINE static uint8* WriteSInt32ToArray(int field_number, |
549 | int32 value, |
550 | uint8* target); |
551 | PROTOBUF_ALWAYS_INLINE static uint8* WriteSInt64ToArray(int field_number, |
552 | int64 value, |
553 | uint8* target); |
554 | PROTOBUF_ALWAYS_INLINE static uint8* WriteFixed32ToArray(int field_number, |
555 | uint32 value, |
556 | uint8* target); |
557 | PROTOBUF_ALWAYS_INLINE static uint8* WriteFixed64ToArray(int field_number, |
558 | uint64 value, |
559 | uint8* target); |
560 | PROTOBUF_ALWAYS_INLINE static uint8* WriteSFixed32ToArray(int field_number, |
561 | int32 value, |
562 | uint8* target); |
563 | PROTOBUF_ALWAYS_INLINE static uint8* WriteSFixed64ToArray(int field_number, |
564 | int64 value, |
565 | uint8* target); |
566 | PROTOBUF_ALWAYS_INLINE static uint8* WriteFloatToArray(int field_number, |
567 | float value, |
568 | uint8* target); |
569 | PROTOBUF_ALWAYS_INLINE static uint8* WriteDoubleToArray(int field_number, |
570 | double value, |
571 | uint8* target); |
572 | PROTOBUF_ALWAYS_INLINE static uint8* WriteBoolToArray(int field_number, |
573 | bool value, |
574 | uint8* target); |
575 | PROTOBUF_ALWAYS_INLINE static uint8* WriteEnumToArray(int field_number, |
576 | int value, |
577 | uint8* target); |
578 | |
579 | template <typename T> |
580 | PROTOBUF_ALWAYS_INLINE static uint8* WritePrimitiveToArray( |
581 | int field_number, const RepeatedField<T>& value, |
582 | uint8* (*Writer)(int, T, uint8*), uint8* target); |
583 | |
584 | PROTOBUF_ALWAYS_INLINE static uint8* WriteInt32ToArray( |
585 | int field_number, const RepeatedField<int32>& value, uint8* output); |
586 | PROTOBUF_ALWAYS_INLINE static uint8* WriteInt64ToArray( |
587 | int field_number, const RepeatedField<int64>& value, uint8* output); |
588 | PROTOBUF_ALWAYS_INLINE static uint8* WriteUInt32ToArray( |
589 | int field_number, const RepeatedField<uint32>& value, uint8* output); |
590 | PROTOBUF_ALWAYS_INLINE static uint8* WriteUInt64ToArray( |
591 | int field_number, const RepeatedField<uint64>& value, uint8* output); |
592 | PROTOBUF_ALWAYS_INLINE static uint8* WriteSInt32ToArray( |
593 | int field_number, const RepeatedField<int32>& value, uint8* output); |
594 | PROTOBUF_ALWAYS_INLINE static uint8* WriteSInt64ToArray( |
595 | int field_number, const RepeatedField<int64>& value, uint8* output); |
596 | PROTOBUF_ALWAYS_INLINE static uint8* WriteFixed32ToArray( |
597 | int field_number, const RepeatedField<uint32>& value, uint8* output); |
598 | PROTOBUF_ALWAYS_INLINE static uint8* WriteFixed64ToArray( |
599 | int field_number, const RepeatedField<uint64>& value, uint8* output); |
600 | PROTOBUF_ALWAYS_INLINE static uint8* WriteSFixed32ToArray( |
601 | int field_number, const RepeatedField<int32>& value, uint8* output); |
602 | PROTOBUF_ALWAYS_INLINE static uint8* WriteSFixed64ToArray( |
603 | int field_number, const RepeatedField<int64>& value, uint8* output); |
604 | PROTOBUF_ALWAYS_INLINE static uint8* WriteFloatToArray( |
605 | int field_number, const RepeatedField<float>& value, uint8* output); |
606 | PROTOBUF_ALWAYS_INLINE static uint8* WriteDoubleToArray( |
607 | int field_number, const RepeatedField<double>& value, uint8* output); |
608 | PROTOBUF_ALWAYS_INLINE static uint8* WriteBoolToArray( |
609 | int field_number, const RepeatedField<bool>& value, uint8* output); |
610 | PROTOBUF_ALWAYS_INLINE static uint8* WriteEnumToArray( |
611 | int field_number, const RepeatedField<int>& value, uint8* output); |
612 | |
613 | PROTOBUF_ALWAYS_INLINE static uint8* WriteStringToArray( |
614 | int field_number, const std::string& value, uint8* target); |
615 | PROTOBUF_ALWAYS_INLINE static uint8* WriteBytesToArray( |
616 | int field_number, const std::string& value, uint8* target); |
617 | |
618 | // Whether to serialize deterministically (e.g., map keys are |
619 | // sorted) is a property of a CodedOutputStream, and in the process |
620 | // of serialization, the "ToArray" variants may be invoked. But they don't |
621 | // have a CodedOutputStream available, so they get an additional parameter |
622 | // telling them whether to serialize deterministically. |
623 | template <typename MessageType> |
624 | PROTOBUF_ALWAYS_INLINE static uint8* InternalWriteGroup( |
625 | int field_number, const MessageType& value, uint8* target, |
626 | io::EpsCopyOutputStream* stream); |
627 | template <typename MessageType> |
628 | PROTOBUF_ALWAYS_INLINE static uint8* InternalWriteMessage( |
629 | int field_number, const MessageType& value, uint8* target, |
630 | io::EpsCopyOutputStream* stream); |
631 | |
632 | // Like above, but de-virtualize the call to SerializeWithCachedSizes(). The |
633 | // pointer must point at an instance of MessageType, *not* a subclass (or |
634 | // the subclass must not override SerializeWithCachedSizes()). |
635 | template <typename MessageType> |
636 | PROTOBUF_ALWAYS_INLINE static uint8* InternalWriteGroupNoVirtualToArray( |
637 | int field_number, const MessageType& value, uint8* target); |
638 | template <typename MessageType> |
639 | PROTOBUF_ALWAYS_INLINE static uint8* InternalWriteMessageNoVirtualToArray( |
640 | int field_number, const MessageType& value, uint8* target); |
641 | |
642 | // For backward-compatibility, the last four methods also have versions |
643 | // that are non-deterministic always. |
644 | PROTOBUF_ALWAYS_INLINE static uint8* WriteGroupToArray( |
645 | int field_number, const MessageLite& value, uint8* target) { |
646 | io::EpsCopyOutputStream stream( |
647 | target, |
648 | value.GetCachedSize() + |
649 | static_cast<int>(2 * io::CodedOutputStream::VarintSize32( |
650 | static_cast<uint32>(field_number) << 3)), |
651 | io::CodedOutputStream::IsDefaultSerializationDeterministic()); |
652 | return InternalWriteGroup(field_number, value, target, &stream); |
653 | } |
654 | PROTOBUF_ALWAYS_INLINE static uint8* WriteMessageToArray( |
655 | int field_number, const MessageLite& value, uint8* target) { |
656 | int size = value.GetCachedSize(); |
657 | io::EpsCopyOutputStream stream( |
658 | target, |
659 | size + static_cast<int>(io::CodedOutputStream::VarintSize32( |
660 | static_cast<uint32>(field_number) << 3) + |
661 | io::CodedOutputStream::VarintSize32(size)), |
662 | io::CodedOutputStream::IsDefaultSerializationDeterministic()); |
663 | return InternalWriteMessage(field_number, value, target, &stream); |
664 | } |
665 | |
666 | // Compute the byte size of a field. The XxSize() functions do NOT include |
667 | // the tag, so you must also call TagSize(). (This is because, for repeated |
668 | // fields, you should only call TagSize() once and multiply it by the element |
669 | // count, but you may have to call XxSize() for each individual element.) |
670 | static inline size_t Int32Size(int32 value); |
671 | static inline size_t Int64Size(int64 value); |
672 | static inline size_t UInt32Size(uint32 value); |
673 | static inline size_t UInt64Size(uint64 value); |
674 | static inline size_t SInt32Size(int32 value); |
675 | static inline size_t SInt64Size(int64 value); |
676 | static inline size_t EnumSize(int value); |
677 | |
678 | static size_t Int32Size(const RepeatedField<int32>& value); |
679 | static size_t Int64Size(const RepeatedField<int64>& value); |
680 | static size_t UInt32Size(const RepeatedField<uint32>& value); |
681 | static size_t UInt64Size(const RepeatedField<uint64>& value); |
682 | static size_t SInt32Size(const RepeatedField<int32>& value); |
683 | static size_t SInt64Size(const RepeatedField<int64>& value); |
684 | static size_t EnumSize(const RepeatedField<int>& value); |
685 | |
686 | // These types always have the same size. |
687 | static const size_t kFixed32Size = 4; |
688 | static const size_t kFixed64Size = 8; |
689 | static const size_t kSFixed32Size = 4; |
690 | static const size_t kSFixed64Size = 8; |
691 | static const size_t kFloatSize = 4; |
692 | static const size_t kDoubleSize = 8; |
693 | static const size_t kBoolSize = 1; |
694 | |
695 | static inline size_t StringSize(const std::string& value); |
696 | static inline size_t BytesSize(const std::string& value); |
697 | |
698 | template <typename MessageType> |
699 | static inline size_t GroupSize(const MessageType& value); |
700 | template <typename MessageType> |
701 | static inline size_t MessageSize(const MessageType& value); |
702 | |
703 | // Like above, but de-virtualize the call to ByteSize(). The |
704 | // pointer must point at an instance of MessageType, *not* a subclass (or |
705 | // the subclass must not override ByteSize()). |
706 | template <typename MessageType> |
707 | static inline size_t GroupSizeNoVirtual(const MessageType& value); |
708 | template <typename MessageType> |
709 | static inline size_t MessageSizeNoVirtual(const MessageType& value); |
710 | |
711 | // Given the length of data, calculate the byte size of the data on the |
712 | // wire if we encode the data as a length delimited field. |
713 | static inline size_t LengthDelimitedSize(size_t length); |
714 | |
715 | private: |
716 | // A helper method for the repeated primitive reader. This method has |
717 | // optimizations for primitive types that have fixed size on the wire, and |
718 | // can be read using potentially faster paths. |
719 | template <typename CType, enum FieldType DeclaredType> |
720 | PROTOBUF_ALWAYS_INLINE static bool ReadRepeatedFixedSizePrimitive( |
721 | int tag_size, uint32 tag, io::CodedInputStream* input, |
722 | RepeatedField<CType>* value); |
723 | |
724 | // Like ReadRepeatedFixedSizePrimitive but for packed primitive fields. |
725 | template <typename CType, enum FieldType DeclaredType> |
726 | PROTOBUF_ALWAYS_INLINE static bool ReadPackedFixedSizePrimitive( |
727 | io::CodedInputStream* input, RepeatedField<CType>* value); |
728 | |
729 | static const CppType kFieldTypeToCppTypeMap[]; |
730 | static const WireFormatLite::WireType kWireTypeForFieldType[]; |
731 | static void WriteSubMessageMaybeToArray(int size, const MessageLite& value, |
732 | io::CodedOutputStream* output); |
733 | |
734 | GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormatLite); |
735 | }; |
736 | |
737 | // A class which deals with unknown values. The default implementation just |
738 | // discards them. WireFormat defines a subclass which writes to an |
739 | // UnknownFieldSet. This class is used by ExtensionSet::ParseField(), since |
740 | // ExtensionSet is part of the lite library but UnknownFieldSet is not. |
741 | class PROTOBUF_EXPORT FieldSkipper { |
742 | public: |
743 | FieldSkipper() {} |
744 | virtual ~FieldSkipper() {} |
745 | |
746 | // Skip a field whose tag has already been consumed. |
747 | virtual bool SkipField(io::CodedInputStream* input, uint32 tag); |
748 | |
749 | // Skip an entire message or group, up to an end-group tag (which is consumed) |
750 | // or end-of-stream. |
751 | virtual bool SkipMessage(io::CodedInputStream* input); |
752 | |
753 | // Deal with an already-parsed unrecognized enum value. The default |
754 | // implementation does nothing, but the UnknownFieldSet-based implementation |
755 | // saves it as an unknown varint. |
756 | virtual void SkipUnknownEnum(int field_number, int value); |
757 | }; |
758 | |
759 | // Subclass of FieldSkipper which saves skipped fields to a CodedOutputStream. |
760 | |
761 | class PROTOBUF_EXPORT CodedOutputStreamFieldSkipper : public FieldSkipper { |
762 | public: |
763 | explicit CodedOutputStreamFieldSkipper(io::CodedOutputStream* unknown_fields) |
764 | : unknown_fields_(unknown_fields) {} |
765 | ~CodedOutputStreamFieldSkipper() override {} |
766 | |
767 | // implements FieldSkipper ----------------------------------------- |
768 | bool SkipField(io::CodedInputStream* input, uint32 tag) override; |
769 | bool SkipMessage(io::CodedInputStream* input) override; |
770 | void SkipUnknownEnum(int field_number, int value) override; |
771 | |
772 | protected: |
773 | io::CodedOutputStream* unknown_fields_; |
774 | }; |
775 | |
776 | // inline methods ==================================================== |
777 | |
778 | inline WireFormatLite::CppType WireFormatLite::FieldTypeToCppType( |
779 | FieldType type) { |
780 | return kFieldTypeToCppTypeMap[type]; |
781 | } |
782 | |
783 | constexpr inline uint32 WireFormatLite::MakeTag(int field_number, |
784 | WireType type) { |
785 | return GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(field_number, type); |
786 | } |
787 | |
788 | inline WireFormatLite::WireType WireFormatLite::GetTagWireType(uint32 tag) { |
789 | return static_cast<WireType>(tag & kTagTypeMask); |
790 | } |
791 | |
792 | inline int WireFormatLite::GetTagFieldNumber(uint32 tag) { |
793 | return static_cast<int>(tag >> kTagTypeBits); |
794 | } |
795 | |
796 | inline size_t WireFormatLite::TagSize(int field_number, |
797 | WireFormatLite::FieldType type) { |
798 | size_t result = io::CodedOutputStream::VarintSize32( |
799 | static_cast<uint32>(field_number << kTagTypeBits)); |
800 | if (type == TYPE_GROUP) { |
801 | // Groups have both a start and an end tag. |
802 | return result * 2; |
803 | } else { |
804 | return result; |
805 | } |
806 | } |
807 | |
808 | inline uint32 WireFormatLite::EncodeFloat(float value) { |
809 | union { |
810 | float f; |
811 | uint32 i; |
812 | }; |
813 | f = value; |
814 | return i; |
815 | } |
816 | |
817 | inline float WireFormatLite::DecodeFloat(uint32 value) { |
818 | union { |
819 | float f; |
820 | uint32 i; |
821 | }; |
822 | i = value; |
823 | return f; |
824 | } |
825 | |
826 | inline uint64 WireFormatLite::EncodeDouble(double value) { |
827 | union { |
828 | double f; |
829 | uint64 i; |
830 | }; |
831 | f = value; |
832 | return i; |
833 | } |
834 | |
835 | inline double WireFormatLite::DecodeDouble(uint64 value) { |
836 | union { |
837 | double f; |
838 | uint64 i; |
839 | }; |
840 | i = value; |
841 | return f; |
842 | } |
843 | |
844 | // ZigZag Transform: Encodes signed integers so that they can be |
845 | // effectively used with varint encoding. |
846 | // |
847 | // varint operates on unsigned integers, encoding smaller numbers into |
848 | // fewer bytes. If you try to use it on a signed integer, it will treat |
849 | // this number as a very large unsigned integer, which means that even |
850 | // small signed numbers like -1 will take the maximum number of bytes |
851 | // (10) to encode. ZigZagEncode() maps signed integers to unsigned |
852 | // in such a way that those with a small absolute value will have smaller |
853 | // encoded values, making them appropriate for encoding using varint. |
854 | // |
855 | // int32 -> uint32 |
856 | // ------------------------- |
857 | // 0 -> 0 |
858 | // -1 -> 1 |
859 | // 1 -> 2 |
860 | // -2 -> 3 |
861 | // ... -> ... |
862 | // 2147483647 -> 4294967294 |
863 | // -2147483648 -> 4294967295 |
864 | // |
865 | // >> encode >> |
866 | // << decode << |
867 | |
868 | inline uint32 WireFormatLite::ZigZagEncode32(int32 n) { |
869 | // Note: the right-shift must be arithmetic |
870 | // Note: left shift must be unsigned because of overflow |
871 | return (static_cast<uint32>(n) << 1) ^ static_cast<uint32>(n >> 31); |
872 | } |
873 | |
874 | inline int32 WireFormatLite::ZigZagDecode32(uint32 n) { |
875 | // Note: Using unsigned types prevent undefined behavior |
876 | return static_cast<int32>((n >> 1) ^ (~(n & 1) + 1)); |
877 | } |
878 | |
879 | inline uint64 WireFormatLite::ZigZagEncode64(int64 n) { |
880 | // Note: the right-shift must be arithmetic |
881 | // Note: left shift must be unsigned because of overflow |
882 | return (static_cast<uint64>(n) << 1) ^ static_cast<uint64>(n >> 63); |
883 | } |
884 | |
885 | inline int64 WireFormatLite::ZigZagDecode64(uint64 n) { |
886 | // Note: Using unsigned types prevent undefined behavior |
887 | return static_cast<int64>((n >> 1) ^ (~(n & 1) + 1)); |
888 | } |
889 | |
890 | // String is for UTF-8 text only, but, even so, ReadString() can simply |
891 | // call ReadBytes(). |
892 | |
893 | inline bool WireFormatLite::ReadString(io::CodedInputStream* input, |
894 | std::string* value) { |
895 | return ReadBytes(input, value); |
896 | } |
897 | |
898 | inline bool WireFormatLite::ReadString(io::CodedInputStream* input, |
899 | std::string** p) { |
900 | return ReadBytes(input, p); |
901 | } |
902 | |
903 | inline uint8* InternalSerializeUnknownMessageSetItemsToArray( |
904 | const std::string& unknown_fields, uint8* target, |
905 | io::EpsCopyOutputStream* stream) { |
906 | return stream->WriteRaw(unknown_fields.data(), |
907 | static_cast<int>(unknown_fields.size()), target); |
908 | } |
909 | |
910 | inline size_t ComputeUnknownMessageSetItemsSize( |
911 | const std::string& unknown_fields) { |
912 | return unknown_fields.size(); |
913 | } |
914 | |
915 | // Implementation details of ReadPrimitive. |
916 | |
917 | template <> |
918 | inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>( |
919 | io::CodedInputStream* input, int32* value) { |
920 | uint32 temp; |
921 | if (!input->ReadVarint32(&temp)) return false; |
922 | *value = static_cast<int32>(temp); |
923 | return true; |
924 | } |
925 | template <> |
926 | inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_INT64>( |
927 | io::CodedInputStream* input, int64* value) { |
928 | uint64 temp; |
929 | if (!input->ReadVarint64(&temp)) return false; |
930 | *value = static_cast<int64>(temp); |
931 | return true; |
932 | } |
933 | template <> |
934 | inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_UINT32>( |
935 | io::CodedInputStream* input, uint32* value) { |
936 | return input->ReadVarint32(value); |
937 | } |
938 | template <> |
939 | inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_UINT64>( |
940 | io::CodedInputStream* input, uint64* value) { |
941 | return input->ReadVarint64(value); |
942 | } |
943 | template <> |
944 | inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>( |
945 | io::CodedInputStream* input, int32* value) { |
946 | uint32 temp; |
947 | if (!input->ReadVarint32(&temp)) return false; |
948 | *value = ZigZagDecode32(temp); |
949 | return true; |
950 | } |
951 | template <> |
952 | inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SINT64>( |
953 | io::CodedInputStream* input, int64* value) { |
954 | uint64 temp; |
955 | if (!input->ReadVarint64(&temp)) return false; |
956 | *value = ZigZagDecode64(temp); |
957 | return true; |
958 | } |
959 | template <> |
960 | inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_FIXED32>( |
961 | io::CodedInputStream* input, uint32* value) { |
962 | return input->ReadLittleEndian32(value); |
963 | } |
964 | template <> |
965 | inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_FIXED64>( |
966 | io::CodedInputStream* input, uint64* value) { |
967 | return input->ReadLittleEndian64(value); |
968 | } |
969 | template <> |
970 | inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SFIXED32>( |
971 | io::CodedInputStream* input, int32* value) { |
972 | uint32 temp; |
973 | if (!input->ReadLittleEndian32(&temp)) return false; |
974 | *value = static_cast<int32>(temp); |
975 | return true; |
976 | } |
977 | template <> |
978 | inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SFIXED64>( |
979 | io::CodedInputStream* input, int64* value) { |
980 | uint64 temp; |
981 | if (!input->ReadLittleEndian64(&temp)) return false; |
982 | *value = static_cast<int64>(temp); |
983 | return true; |
984 | } |
985 | template <> |
986 | inline bool WireFormatLite::ReadPrimitive<float, WireFormatLite::TYPE_FLOAT>( |
987 | io::CodedInputStream* input, float* value) { |
988 | uint32 temp; |
989 | if (!input->ReadLittleEndian32(&temp)) return false; |
990 | *value = DecodeFloat(temp); |
991 | return true; |
992 | } |
993 | template <> |
994 | inline bool WireFormatLite::ReadPrimitive<double, WireFormatLite::TYPE_DOUBLE>( |
995 | io::CodedInputStream* input, double* value) { |
996 | uint64 temp; |
997 | if (!input->ReadLittleEndian64(&temp)) return false; |
998 | *value = DecodeDouble(temp); |
999 | return true; |
1000 | } |
1001 | template <> |
1002 | inline bool WireFormatLite::ReadPrimitive<bool, WireFormatLite::TYPE_BOOL>( |
1003 | io::CodedInputStream* input, bool* value) { |
1004 | uint64 temp; |
1005 | if (!input->ReadVarint64(&temp)) return false; |
1006 | *value = temp != 0; |
1007 | return true; |
1008 | } |
1009 | template <> |
1010 | inline bool WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>( |
1011 | io::CodedInputStream* input, int* value) { |
1012 | uint32 temp; |
1013 | if (!input->ReadVarint32(&temp)) return false; |
1014 | *value = static_cast<int>(temp); |
1015 | return true; |
1016 | } |
1017 | |
1018 | template <> |
1019 | inline const uint8* |
1020 | WireFormatLite::ReadPrimitiveFromArray<uint32, WireFormatLite::TYPE_FIXED32>( |
1021 | const uint8* buffer, uint32* value) { |
1022 | return io::CodedInputStream::ReadLittleEndian32FromArray(buffer, value); |
1023 | } |
1024 | template <> |
1025 | inline const uint8* |
1026 | WireFormatLite::ReadPrimitiveFromArray<uint64, WireFormatLite::TYPE_FIXED64>( |
1027 | const uint8* buffer, uint64* value) { |
1028 | return io::CodedInputStream::ReadLittleEndian64FromArray(buffer, value); |
1029 | } |
1030 | template <> |
1031 | inline const uint8* |
1032 | WireFormatLite::ReadPrimitiveFromArray<int32, WireFormatLite::TYPE_SFIXED32>( |
1033 | const uint8* buffer, int32* value) { |
1034 | uint32 temp; |
1035 | buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp); |
1036 | *value = static_cast<int32>(temp); |
1037 | return buffer; |
1038 | } |
1039 | template <> |
1040 | inline const uint8* |
1041 | WireFormatLite::ReadPrimitiveFromArray<int64, WireFormatLite::TYPE_SFIXED64>( |
1042 | const uint8* buffer, int64* value) { |
1043 | uint64 temp; |
1044 | buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp); |
1045 | *value = static_cast<int64>(temp); |
1046 | return buffer; |
1047 | } |
1048 | template <> |
1049 | inline const uint8* |
1050 | WireFormatLite::ReadPrimitiveFromArray<float, WireFormatLite::TYPE_FLOAT>( |
1051 | const uint8* buffer, float* value) { |
1052 | uint32 temp; |
1053 | buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp); |
1054 | *value = DecodeFloat(temp); |
1055 | return buffer; |
1056 | } |
1057 | template <> |
1058 | inline const uint8* |
1059 | WireFormatLite::ReadPrimitiveFromArray<double, WireFormatLite::TYPE_DOUBLE>( |
1060 | const uint8* buffer, double* value) { |
1061 | uint64 temp; |
1062 | buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp); |
1063 | *value = DecodeDouble(temp); |
1064 | return buffer; |
1065 | } |
1066 | |
1067 | template <typename CType, enum WireFormatLite::FieldType DeclaredType> |
1068 | inline bool WireFormatLite::ReadRepeatedPrimitive( |
1069 | int, // tag_size, unused. |
1070 | uint32 tag, io::CodedInputStream* input, RepeatedField<CType>* values) { |
1071 | CType value; |
1072 | if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; |
1073 | values->Add(value); |
1074 | int elements_already_reserved = values->Capacity() - values->size(); |
1075 | while (elements_already_reserved > 0 && input->ExpectTag(tag)) { |
1076 | if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; |
1077 | values->AddAlreadyReserved(value); |
1078 | elements_already_reserved--; |
1079 | } |
1080 | return true; |
1081 | } |
1082 | |
1083 | template <typename CType, enum WireFormatLite::FieldType DeclaredType> |
1084 | inline bool WireFormatLite::ReadRepeatedFixedSizePrimitive( |
1085 | int tag_size, uint32 tag, io::CodedInputStream* input, |
1086 | RepeatedField<CType>* values) { |
1087 | GOOGLE_DCHECK_EQ(UInt32Size(tag), static_cast<size_t>(tag_size)); |
1088 | CType value; |
1089 | if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; |
1090 | values->Add(value); |
1091 | |
1092 | // For fixed size values, repeated values can be read more quickly by |
1093 | // reading directly from a raw array. |
1094 | // |
1095 | // We can get a tight loop by only reading as many elements as can be |
1096 | // added to the RepeatedField without having to do any resizing. Additionally, |
1097 | // we only try to read as many elements as are available from the current |
1098 | // buffer space. Doing so avoids having to perform boundary checks when |
1099 | // reading the value: the maximum number of elements that can be read is |
1100 | // known outside of the loop. |
1101 | const void* void_pointer; |
1102 | int size; |
1103 | input->GetDirectBufferPointerInline(&void_pointer, &size); |
1104 | if (size > 0) { |
1105 | const uint8* buffer = reinterpret_cast<const uint8*>(void_pointer); |
1106 | // The number of bytes each type occupies on the wire. |
1107 | const int per_value_size = tag_size + static_cast<int>(sizeof(value)); |
1108 | |
1109 | // parentheses around (std::min) prevents macro expansion of min(...) |
1110 | int elements_available = |
1111 | (std::min)(values->Capacity() - values->size(), size / per_value_size); |
1112 | int num_read = 0; |
1113 | while (num_read < elements_available && |
1114 | (buffer = io::CodedInputStream::ExpectTagFromArray(buffer, tag)) != |
1115 | NULL) { |
1116 | buffer = ReadPrimitiveFromArray<CType, DeclaredType>(buffer, &value); |
1117 | values->AddAlreadyReserved(value); |
1118 | ++num_read; |
1119 | } |
1120 | const int read_bytes = num_read * per_value_size; |
1121 | if (read_bytes > 0) { |
1122 | input->Skip(read_bytes); |
1123 | } |
1124 | } |
1125 | return true; |
1126 | } |
1127 | |
1128 | // Specializations of ReadRepeatedPrimitive for the fixed size types, which use |
1129 | // the optimized code path. |
1130 | #define READ_REPEATED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE) \ |
1131 | template <> \ |
1132 | inline bool WireFormatLite::ReadRepeatedPrimitive< \ |
1133 | CPPTYPE, WireFormatLite::DECLARED_TYPE>( \ |
1134 | int tag_size, uint32 tag, io::CodedInputStream* input, \ |
1135 | RepeatedField<CPPTYPE>* values) { \ |
1136 | return ReadRepeatedFixedSizePrimitive<CPPTYPE, \ |
1137 | WireFormatLite::DECLARED_TYPE>( \ |
1138 | tag_size, tag, input, values); \ |
1139 | } |
1140 | |
1141 | READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32) |
1142 | READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64) |
1143 | READ_REPEATED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32) |
1144 | READ_REPEATED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64) |
1145 | READ_REPEATED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT) |
1146 | READ_REPEATED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE) |
1147 | |
1148 | #undef READ_REPEATED_FIXED_SIZE_PRIMITIVE |
1149 | |
1150 | template <typename CType, enum WireFormatLite::FieldType DeclaredType> |
1151 | bool WireFormatLite::ReadRepeatedPrimitiveNoInline( |
1152 | int tag_size, uint32 tag, io::CodedInputStream* input, |
1153 | RepeatedField<CType>* value) { |
1154 | return ReadRepeatedPrimitive<CType, DeclaredType>(tag_size, tag, input, |
1155 | value); |
1156 | } |
1157 | |
1158 | template <typename CType, enum WireFormatLite::FieldType DeclaredType> |
1159 | inline bool WireFormatLite::ReadPackedPrimitive(io::CodedInputStream* input, |
1160 | RepeatedField<CType>* values) { |
1161 | int length; |
1162 | if (!input->ReadVarintSizeAsInt(&length)) return false; |
1163 | io::CodedInputStream::Limit limit = input->PushLimit(length); |
1164 | while (input->BytesUntilLimit() > 0) { |
1165 | CType value; |
1166 | if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; |
1167 | values->Add(value); |
1168 | } |
1169 | input->PopLimit(limit); |
1170 | return true; |
1171 | } |
1172 | |
1173 | template <typename CType, enum WireFormatLite::FieldType DeclaredType> |
1174 | inline bool WireFormatLite::ReadPackedFixedSizePrimitive( |
1175 | io::CodedInputStream* input, RepeatedField<CType>* values) { |
1176 | int length; |
1177 | if (!input->ReadVarintSizeAsInt(&length)) return false; |
1178 | const int old_entries = values->size(); |
1179 | const int new_entries = length / static_cast<int>(sizeof(CType)); |
1180 | const int new_bytes = new_entries * static_cast<int>(sizeof(CType)); |
1181 | if (new_bytes != length) return false; |
1182 | // We would *like* to pre-allocate the buffer to write into (for |
1183 | // speed), but *must* avoid performing a very large allocation due |
1184 | // to a malicious user-supplied "length" above. So we have a fast |
1185 | // path that pre-allocates when the "length" is less than a bound. |
1186 | // We determine the bound by calling BytesUntilTotalBytesLimit() and |
1187 | // BytesUntilLimit(). These return -1 to mean "no limit set". |
1188 | // There are four cases: |
1189 | // TotalBytesLimit Limit |
1190 | // -1 -1 Use slow path. |
1191 | // -1 >= 0 Use fast path if length <= Limit. |
1192 | // >= 0 -1 Use slow path. |
1193 | // >= 0 >= 0 Use fast path if length <= min(both limits). |
1194 | int64 bytes_limit = input->BytesUntilTotalBytesLimit(); |
1195 | if (bytes_limit == -1) { |
1196 | bytes_limit = input->BytesUntilLimit(); |
1197 | } else { |
1198 | // parentheses around (std::min) prevents macro expansion of min(...) |
1199 | bytes_limit = |
1200 | (std::min)(bytes_limit, static_cast<int64>(input->BytesUntilLimit())); |
1201 | } |
1202 | if (bytes_limit >= new_bytes) { |
1203 | // Fast-path that pre-allocates *values to the final size. |
1204 | #if defined(PROTOBUF_LITTLE_ENDIAN) |
1205 | values->Resize(old_entries + new_entries, 0); |
1206 | // values->mutable_data() may change after Resize(), so do this after: |
1207 | void* dest = reinterpret_cast<void*>(values->mutable_data() + old_entries); |
1208 | if (!input->ReadRaw(dest, new_bytes)) { |
1209 | values->Truncate(old_entries); |
1210 | return false; |
1211 | } |
1212 | #else |
1213 | values->Reserve(old_entries + new_entries); |
1214 | CType value; |
1215 | for (int i = 0; i < new_entries; ++i) { |
1216 | if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; |
1217 | values->AddAlreadyReserved(value); |
1218 | } |
1219 | #endif |
1220 | } else { |
1221 | // This is the slow-path case where "length" may be too large to |
1222 | // safely allocate. We read as much as we can into *values |
1223 | // without pre-allocating "length" bytes. |
1224 | CType value; |
1225 | for (int i = 0; i < new_entries; ++i) { |
1226 | if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; |
1227 | values->Add(value); |
1228 | } |
1229 | } |
1230 | return true; |
1231 | } |
1232 | |
1233 | // Specializations of ReadPackedPrimitive for the fixed size types, which use |
1234 | // an optimized code path. |
1235 | #define READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE) \ |
1236 | template <> \ |
1237 | inline bool \ |
1238 | WireFormatLite::ReadPackedPrimitive<CPPTYPE, WireFormatLite::DECLARED_TYPE>( \ |
1239 | io::CodedInputStream * input, RepeatedField<CPPTYPE> * values) { \ |
1240 | return ReadPackedFixedSizePrimitive<CPPTYPE, \ |
1241 | WireFormatLite::DECLARED_TYPE>( \ |
1242 | input, values); \ |
1243 | } |
1244 | |
1245 | READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32) |
1246 | READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64) |
1247 | READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32) |
1248 | READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64) |
1249 | READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT) |
1250 | READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE) |
1251 | |
1252 | #undef READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE |
1253 | |
1254 | template <typename CType, enum WireFormatLite::FieldType DeclaredType> |
1255 | bool WireFormatLite::ReadPackedPrimitiveNoInline(io::CodedInputStream* input, |
1256 | RepeatedField<CType>* values) { |
1257 | return ReadPackedPrimitive<CType, DeclaredType>(input, values); |
1258 | } |
1259 | |
1260 | |
1261 | template <typename MessageType> |
1262 | inline bool WireFormatLite::ReadGroup(int field_number, |
1263 | io::CodedInputStream* input, |
1264 | MessageType* value) { |
1265 | if (!input->IncrementRecursionDepth()) return false; |
1266 | if (!value->MergePartialFromCodedStream(input)) return false; |
1267 | input->UnsafeDecrementRecursionDepth(); |
1268 | // Make sure the last thing read was an end tag for this group. |
1269 | if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) { |
1270 | return false; |
1271 | } |
1272 | return true; |
1273 | } |
1274 | template <typename MessageType> |
1275 | inline bool WireFormatLite::ReadMessage(io::CodedInputStream* input, |
1276 | MessageType* value) { |
1277 | int length; |
1278 | if (!input->ReadVarintSizeAsInt(&length)) return false; |
1279 | std::pair<io::CodedInputStream::Limit, int> p = |
1280 | input->IncrementRecursionDepthAndPushLimit(length); |
1281 | if (p.second < 0 || !value->MergePartialFromCodedStream(input)) return false; |
1282 | // Make sure that parsing stopped when the limit was hit, not at an endgroup |
1283 | // tag. |
1284 | return input->DecrementRecursionDepthAndPopLimit(p.first); |
1285 | } |
1286 | |
1287 | // =================================================================== |
1288 | |
1289 | inline void WireFormatLite::WriteTag(int field_number, WireType type, |
1290 | io::CodedOutputStream* output) { |
1291 | output->WriteTag(MakeTag(field_number, type)); |
1292 | } |
1293 | |
1294 | inline void WireFormatLite::WriteInt32NoTag(int32 value, |
1295 | io::CodedOutputStream* output) { |
1296 | output->WriteVarint32SignExtended(value); |
1297 | } |
1298 | inline void WireFormatLite::WriteInt64NoTag(int64 value, |
1299 | io::CodedOutputStream* output) { |
1300 | output->WriteVarint64(static_cast<uint64>(value)); |
1301 | } |
1302 | inline void WireFormatLite::WriteUInt32NoTag(uint32 value, |
1303 | io::CodedOutputStream* output) { |
1304 | output->WriteVarint32(value); |
1305 | } |
1306 | inline void WireFormatLite::WriteUInt64NoTag(uint64 value, |
1307 | io::CodedOutputStream* output) { |
1308 | output->WriteVarint64(value); |
1309 | } |
1310 | inline void WireFormatLite::WriteSInt32NoTag(int32 value, |
1311 | io::CodedOutputStream* output) { |
1312 | output->WriteVarint32(ZigZagEncode32(value)); |
1313 | } |
1314 | inline void WireFormatLite::WriteSInt64NoTag(int64 value, |
1315 | io::CodedOutputStream* output) { |
1316 | output->WriteVarint64(ZigZagEncode64(value)); |
1317 | } |
1318 | inline void WireFormatLite::WriteFixed32NoTag(uint32 value, |
1319 | io::CodedOutputStream* output) { |
1320 | output->WriteLittleEndian32(value); |
1321 | } |
1322 | inline void WireFormatLite::WriteFixed64NoTag(uint64 value, |
1323 | io::CodedOutputStream* output) { |
1324 | output->WriteLittleEndian64(value); |
1325 | } |
1326 | inline void WireFormatLite::WriteSFixed32NoTag(int32 value, |
1327 | io::CodedOutputStream* output) { |
1328 | output->WriteLittleEndian32(static_cast<uint32>(value)); |
1329 | } |
1330 | inline void WireFormatLite::WriteSFixed64NoTag(int64 value, |
1331 | io::CodedOutputStream* output) { |
1332 | output->WriteLittleEndian64(static_cast<uint64>(value)); |
1333 | } |
1334 | inline void WireFormatLite::WriteFloatNoTag(float value, |
1335 | io::CodedOutputStream* output) { |
1336 | output->WriteLittleEndian32(EncodeFloat(value)); |
1337 | } |
1338 | inline void WireFormatLite::WriteDoubleNoTag(double value, |
1339 | io::CodedOutputStream* output) { |
1340 | output->WriteLittleEndian64(EncodeDouble(value)); |
1341 | } |
1342 | inline void WireFormatLite::WriteBoolNoTag(bool value, |
1343 | io::CodedOutputStream* output) { |
1344 | output->WriteVarint32(value ? 1 : 0); |
1345 | } |
1346 | inline void WireFormatLite::WriteEnumNoTag(int value, |
1347 | io::CodedOutputStream* output) { |
1348 | output->WriteVarint32SignExtended(value); |
1349 | } |
1350 | |
1351 | // See comment on ReadGroupNoVirtual to understand the need for this template |
1352 | // parameter name. |
1353 | template <typename MessageType_WorkAroundCppLookupDefect> |
1354 | inline void WireFormatLite::WriteGroupNoVirtual( |
1355 | int field_number, const MessageType_WorkAroundCppLookupDefect& value, |
1356 | io::CodedOutputStream* output) { |
1357 | WriteTag(field_number, WIRETYPE_START_GROUP, output); |
1358 | value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output); |
1359 | WriteTag(field_number, WIRETYPE_END_GROUP, output); |
1360 | } |
1361 | template <typename MessageType_WorkAroundCppLookupDefect> |
1362 | inline void WireFormatLite::WriteMessageNoVirtual( |
1363 | int field_number, const MessageType_WorkAroundCppLookupDefect& value, |
1364 | io::CodedOutputStream* output) { |
1365 | WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); |
1366 | output->WriteVarint32( |
1367 | value.MessageType_WorkAroundCppLookupDefect::GetCachedSize()); |
1368 | value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output); |
1369 | } |
1370 | |
1371 | // =================================================================== |
1372 | |
1373 | inline uint8* WireFormatLite::WriteTagToArray(int field_number, WireType type, |
1374 | uint8* target) { |
1375 | return io::CodedOutputStream::WriteTagToArray(MakeTag(field_number, type), |
1376 | target); |
1377 | } |
1378 | |
1379 | inline uint8* WireFormatLite::WriteInt32NoTagToArray(int32 value, |
1380 | uint8* target) { |
1381 | return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target); |
1382 | } |
1383 | inline uint8* WireFormatLite::WriteInt64NoTagToArray(int64 value, |
1384 | uint8* target) { |
1385 | return io::CodedOutputStream::WriteVarint64ToArray(static_cast<uint64>(value), |
1386 | target); |
1387 | } |
1388 | inline uint8* WireFormatLite::WriteUInt32NoTagToArray(uint32 value, |
1389 | uint8* target) { |
1390 | return io::CodedOutputStream::WriteVarint32ToArray(value, target); |
1391 | } |
1392 | inline uint8* WireFormatLite::WriteUInt64NoTagToArray(uint64 value, |
1393 | uint8* target) { |
1394 | return io::CodedOutputStream::WriteVarint64ToArray(value, target); |
1395 | } |
1396 | inline uint8* WireFormatLite::WriteSInt32NoTagToArray(int32 value, |
1397 | uint8* target) { |
1398 | return io::CodedOutputStream::WriteVarint32ToArray(ZigZagEncode32(value), |
1399 | target); |
1400 | } |
1401 | inline uint8* WireFormatLite::WriteSInt64NoTagToArray(int64 value, |
1402 | uint8* target) { |
1403 | return io::CodedOutputStream::WriteVarint64ToArray(ZigZagEncode64(value), |
1404 | target); |
1405 | } |
1406 | inline uint8* WireFormatLite::WriteFixed32NoTagToArray(uint32 value, |
1407 | uint8* target) { |
1408 | return io::CodedOutputStream::WriteLittleEndian32ToArray(value, target); |
1409 | } |
1410 | inline uint8* WireFormatLite::WriteFixed64NoTagToArray(uint64 value, |
1411 | uint8* target) { |
1412 | return io::CodedOutputStream::WriteLittleEndian64ToArray(value, target); |
1413 | } |
1414 | inline uint8* WireFormatLite::WriteSFixed32NoTagToArray(int32 value, |
1415 | uint8* target) { |
1416 | return io::CodedOutputStream::WriteLittleEndian32ToArray( |
1417 | static_cast<uint32>(value), target); |
1418 | } |
1419 | inline uint8* WireFormatLite::WriteSFixed64NoTagToArray(int64 value, |
1420 | uint8* target) { |
1421 | return io::CodedOutputStream::WriteLittleEndian64ToArray( |
1422 | static_cast<uint64>(value), target); |
1423 | } |
1424 | inline uint8* WireFormatLite::WriteFloatNoTagToArray(float value, |
1425 | uint8* target) { |
1426 | return io::CodedOutputStream::WriteLittleEndian32ToArray(EncodeFloat(value), |
1427 | target); |
1428 | } |
1429 | inline uint8* WireFormatLite::WriteDoubleNoTagToArray(double value, |
1430 | uint8* target) { |
1431 | return io::CodedOutputStream::WriteLittleEndian64ToArray(EncodeDouble(value), |
1432 | target); |
1433 | } |
1434 | inline uint8* WireFormatLite::WriteBoolNoTagToArray(bool value, uint8* target) { |
1435 | return io::CodedOutputStream::WriteVarint32ToArray(value ? 1 : 0, target); |
1436 | } |
1437 | inline uint8* WireFormatLite::WriteEnumNoTagToArray(int value, uint8* target) { |
1438 | return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target); |
1439 | } |
1440 | |
1441 | template <typename T> |
1442 | inline uint8* WireFormatLite::WritePrimitiveNoTagToArray( |
1443 | const RepeatedField<T>& value, uint8* (*Writer)(T, uint8*), uint8* target) { |
1444 | const int n = value.size(); |
1445 | GOOGLE_DCHECK_GT(n, 0); |
1446 | |
1447 | const T* ii = value.data(); |
1448 | int i = 0; |
1449 | do { |
1450 | target = Writer(ii[i], target); |
1451 | } while (++i < n); |
1452 | |
1453 | return target; |
1454 | } |
1455 | |
1456 | template <typename T> |
1457 | inline uint8* WireFormatLite::WriteFixedNoTagToArray( |
1458 | const RepeatedField<T>& value, uint8* (*Writer)(T, uint8*), uint8* target) { |
1459 | #if defined(PROTOBUF_LITTLE_ENDIAN) |
1460 | (void)Writer; |
1461 | |
1462 | const int n = value.size(); |
1463 | GOOGLE_DCHECK_GT(n, 0); |
1464 | |
1465 | const T* ii = value.data(); |
1466 | const int bytes = n * static_cast<int>(sizeof(ii[0])); |
1467 | memcpy(target, ii, static_cast<size_t>(bytes)); |
1468 | return target + bytes; |
1469 | #else |
1470 | return WritePrimitiveNoTagToArray(value, Writer, target); |
1471 | #endif |
1472 | } |
1473 | |
1474 | inline uint8* WireFormatLite::WriteInt32NoTagToArray( |
1475 | const RepeatedField<int32>& value, uint8* target) { |
1476 | return WritePrimitiveNoTagToArray(value, WriteInt32NoTagToArray, target); |
1477 | } |
1478 | inline uint8* WireFormatLite::WriteInt64NoTagToArray( |
1479 | const RepeatedField<int64>& value, uint8* target) { |
1480 | return WritePrimitiveNoTagToArray(value, WriteInt64NoTagToArray, target); |
1481 | } |
1482 | inline uint8* WireFormatLite::WriteUInt32NoTagToArray( |
1483 | const RepeatedField<uint32>& value, uint8* target) { |
1484 | return WritePrimitiveNoTagToArray(value, WriteUInt32NoTagToArray, target); |
1485 | } |
1486 | inline uint8* WireFormatLite::WriteUInt64NoTagToArray( |
1487 | const RepeatedField<uint64>& value, uint8* target) { |
1488 | return WritePrimitiveNoTagToArray(value, WriteUInt64NoTagToArray, target); |
1489 | } |
1490 | inline uint8* WireFormatLite::WriteSInt32NoTagToArray( |
1491 | const RepeatedField<int32>& value, uint8* target) { |
1492 | return WritePrimitiveNoTagToArray(value, WriteSInt32NoTagToArray, target); |
1493 | } |
1494 | inline uint8* WireFormatLite::WriteSInt64NoTagToArray( |
1495 | const RepeatedField<int64>& value, uint8* target) { |
1496 | return WritePrimitiveNoTagToArray(value, WriteSInt64NoTagToArray, target); |
1497 | } |
1498 | inline uint8* WireFormatLite::WriteFixed32NoTagToArray( |
1499 | const RepeatedField<uint32>& value, uint8* target) { |
1500 | return WriteFixedNoTagToArray(value, WriteFixed32NoTagToArray, target); |
1501 | } |
1502 | inline uint8* WireFormatLite::WriteFixed64NoTagToArray( |
1503 | const RepeatedField<uint64>& value, uint8* target) { |
1504 | return WriteFixedNoTagToArray(value, WriteFixed64NoTagToArray, target); |
1505 | } |
1506 | inline uint8* WireFormatLite::WriteSFixed32NoTagToArray( |
1507 | const RepeatedField<int32>& value, uint8* target) { |
1508 | return WriteFixedNoTagToArray(value, WriteSFixed32NoTagToArray, target); |
1509 | } |
1510 | inline uint8* WireFormatLite::WriteSFixed64NoTagToArray( |
1511 | const RepeatedField<int64>& value, uint8* target) { |
1512 | return WriteFixedNoTagToArray(value, WriteSFixed64NoTagToArray, target); |
1513 | } |
1514 | inline uint8* WireFormatLite::WriteFloatNoTagToArray( |
1515 | const RepeatedField<float>& value, uint8* target) { |
1516 | return WriteFixedNoTagToArray(value, WriteFloatNoTagToArray, target); |
1517 | } |
1518 | inline uint8* WireFormatLite::WriteDoubleNoTagToArray( |
1519 | const RepeatedField<double>& value, uint8* target) { |
1520 | return WriteFixedNoTagToArray(value, WriteDoubleNoTagToArray, target); |
1521 | } |
1522 | inline uint8* WireFormatLite::WriteBoolNoTagToArray( |
1523 | const RepeatedField<bool>& value, uint8* target) { |
1524 | return WritePrimitiveNoTagToArray(value, WriteBoolNoTagToArray, target); |
1525 | } |
1526 | inline uint8* WireFormatLite::WriteEnumNoTagToArray( |
1527 | const RepeatedField<int>& value, uint8* target) { |
1528 | return WritePrimitiveNoTagToArray(value, WriteEnumNoTagToArray, target); |
1529 | } |
1530 | |
1531 | inline uint8* WireFormatLite::WriteInt32ToArray(int field_number, int32 value, |
1532 | uint8* target) { |
1533 | target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); |
1534 | return WriteInt32NoTagToArray(value, target); |
1535 | } |
1536 | inline uint8* WireFormatLite::WriteInt64ToArray(int field_number, int64 value, |
1537 | uint8* target) { |
1538 | target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); |
1539 | return WriteInt64NoTagToArray(value, target); |
1540 | } |
1541 | inline uint8* WireFormatLite::WriteUInt32ToArray(int field_number, uint32 value, |
1542 | uint8* target) { |
1543 | target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); |
1544 | return WriteUInt32NoTagToArray(value, target); |
1545 | } |
1546 | inline uint8* WireFormatLite::WriteUInt64ToArray(int field_number, uint64 value, |
1547 | uint8* target) { |
1548 | target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); |
1549 | return WriteUInt64NoTagToArray(value, target); |
1550 | } |
1551 | inline uint8* WireFormatLite::WriteSInt32ToArray(int field_number, int32 value, |
1552 | uint8* target) { |
1553 | target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); |
1554 | return WriteSInt32NoTagToArray(value, target); |
1555 | } |
1556 | inline uint8* WireFormatLite::WriteSInt64ToArray(int field_number, int64 value, |
1557 | uint8* target) { |
1558 | target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); |
1559 | return WriteSInt64NoTagToArray(value, target); |
1560 | } |
1561 | inline uint8* WireFormatLite::WriteFixed32ToArray(int field_number, |
1562 | uint32 value, uint8* target) { |
1563 | target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); |
1564 | return WriteFixed32NoTagToArray(value, target); |
1565 | } |
1566 | inline uint8* WireFormatLite::WriteFixed64ToArray(int field_number, |
1567 | uint64 value, uint8* target) { |
1568 | target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); |
1569 | return WriteFixed64NoTagToArray(value, target); |
1570 | } |
1571 | inline uint8* WireFormatLite::WriteSFixed32ToArray(int field_number, |
1572 | int32 value, uint8* target) { |
1573 | target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); |
1574 | return WriteSFixed32NoTagToArray(value, target); |
1575 | } |
1576 | inline uint8* WireFormatLite::WriteSFixed64ToArray(int field_number, |
1577 | int64 value, uint8* target) { |
1578 | target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); |
1579 | return WriteSFixed64NoTagToArray(value, target); |
1580 | } |
1581 | inline uint8* WireFormatLite::WriteFloatToArray(int field_number, float value, |
1582 | uint8* target) { |
1583 | target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); |
1584 | return WriteFloatNoTagToArray(value, target); |
1585 | } |
1586 | inline uint8* WireFormatLite::WriteDoubleToArray(int field_number, double value, |
1587 | uint8* target) { |
1588 | target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); |
1589 | return WriteDoubleNoTagToArray(value, target); |
1590 | } |
1591 | inline uint8* WireFormatLite::WriteBoolToArray(int field_number, bool value, |
1592 | uint8* target) { |
1593 | target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); |
1594 | return WriteBoolNoTagToArray(value, target); |
1595 | } |
1596 | inline uint8* WireFormatLite::WriteEnumToArray(int field_number, int value, |
1597 | uint8* target) { |
1598 | target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); |
1599 | return WriteEnumNoTagToArray(value, target); |
1600 | } |
1601 | |
1602 | template <typename T> |
1603 | inline uint8* WireFormatLite::WritePrimitiveToArray( |
1604 | int field_number, const RepeatedField<T>& value, |
1605 | uint8* (*Writer)(int, T, uint8*), uint8* target) { |
1606 | const int n = value.size(); |
1607 | if (n == 0) { |
1608 | return target; |
1609 | } |
1610 | |
1611 | const T* ii = value.data(); |
1612 | int i = 0; |
1613 | do { |
1614 | target = Writer(field_number, ii[i], target); |
1615 | } while (++i < n); |
1616 | |
1617 | return target; |
1618 | } |
1619 | |
1620 | inline uint8* WireFormatLite::WriteInt32ToArray( |
1621 | int field_number, const RepeatedField<int32>& value, uint8* target) { |
1622 | return WritePrimitiveToArray(field_number, value, WriteInt32ToArray, target); |
1623 | } |
1624 | inline uint8* WireFormatLite::WriteInt64ToArray( |
1625 | int field_number, const RepeatedField<int64>& value, uint8* target) { |
1626 | return WritePrimitiveToArray(field_number, value, WriteInt64ToArray, target); |
1627 | } |
1628 | inline uint8* WireFormatLite::WriteUInt32ToArray( |
1629 | int field_number, const RepeatedField<uint32>& value, uint8* target) { |
1630 | return WritePrimitiveToArray(field_number, value, WriteUInt32ToArray, target); |
1631 | } |
1632 | inline uint8* WireFormatLite::WriteUInt64ToArray( |
1633 | int field_number, const RepeatedField<uint64>& value, uint8* target) { |
1634 | return WritePrimitiveToArray(field_number, value, WriteUInt64ToArray, target); |
1635 | } |
1636 | inline uint8* WireFormatLite::WriteSInt32ToArray( |
1637 | int field_number, const RepeatedField<int32>& value, uint8* target) { |
1638 | return WritePrimitiveToArray(field_number, value, WriteSInt32ToArray, target); |
1639 | } |
1640 | inline uint8* WireFormatLite::WriteSInt64ToArray( |
1641 | int field_number, const RepeatedField<int64>& value, uint8* target) { |
1642 | return WritePrimitiveToArray(field_number, value, WriteSInt64ToArray, target); |
1643 | } |
1644 | inline uint8* WireFormatLite::WriteFixed32ToArray( |
1645 | int field_number, const RepeatedField<uint32>& value, uint8* target) { |
1646 | return WritePrimitiveToArray(field_number, value, WriteFixed32ToArray, |
1647 | target); |
1648 | } |
1649 | inline uint8* WireFormatLite::WriteFixed64ToArray( |
1650 | int field_number, const RepeatedField<uint64>& value, uint8* target) { |
1651 | return WritePrimitiveToArray(field_number, value, WriteFixed64ToArray, |
1652 | target); |
1653 | } |
1654 | inline uint8* WireFormatLite::WriteSFixed32ToArray( |
1655 | int field_number, const RepeatedField<int32>& value, uint8* target) { |
1656 | return WritePrimitiveToArray(field_number, value, WriteSFixed32ToArray, |
1657 | target); |
1658 | } |
1659 | inline uint8* WireFormatLite::WriteSFixed64ToArray( |
1660 | int field_number, const RepeatedField<int64>& value, uint8* target) { |
1661 | return WritePrimitiveToArray(field_number, value, WriteSFixed64ToArray, |
1662 | target); |
1663 | } |
1664 | inline uint8* WireFormatLite::WriteFloatToArray( |
1665 | int field_number, const RepeatedField<float>& value, uint8* target) { |
1666 | return WritePrimitiveToArray(field_number, value, WriteFloatToArray, target); |
1667 | } |
1668 | inline uint8* WireFormatLite::WriteDoubleToArray( |
1669 | int field_number, const RepeatedField<double>& value, uint8* target) { |
1670 | return WritePrimitiveToArray(field_number, value, WriteDoubleToArray, target); |
1671 | } |
1672 | inline uint8* WireFormatLite::WriteBoolToArray(int field_number, |
1673 | const RepeatedField<bool>& value, |
1674 | uint8* target) { |
1675 | return WritePrimitiveToArray(field_number, value, WriteBoolToArray, target); |
1676 | } |
1677 | inline uint8* WireFormatLite::WriteEnumToArray(int field_number, |
1678 | const RepeatedField<int>& value, |
1679 | uint8* target) { |
1680 | return WritePrimitiveToArray(field_number, value, WriteEnumToArray, target); |
1681 | } |
1682 | inline uint8* WireFormatLite::WriteStringToArray(int field_number, |
1683 | const std::string& value, |
1684 | uint8* target) { |
1685 | // String is for UTF-8 text only |
1686 | // WARNING: In wire_format.cc, both strings and bytes are handled by |
1687 | // WriteString() to avoid code duplication. If the implementations become |
1688 | // different, you will need to update that usage. |
1689 | target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); |
1690 | return io::CodedOutputStream::WriteStringWithSizeToArray(value, target); |
1691 | } |
1692 | inline uint8* WireFormatLite::WriteBytesToArray(int field_number, |
1693 | const std::string& value, |
1694 | uint8* target) { |
1695 | target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); |
1696 | return io::CodedOutputStream::WriteStringWithSizeToArray(value, target); |
1697 | } |
1698 | |
1699 | |
1700 | template <typename MessageType> |
1701 | inline uint8* WireFormatLite::InternalWriteGroup( |
1702 | int field_number, const MessageType& value, uint8* target, |
1703 | io::EpsCopyOutputStream* stream) { |
1704 | target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target); |
1705 | target = value._InternalSerialize(target, stream); |
1706 | target = stream->EnsureSpace(target); |
1707 | return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target); |
1708 | } |
1709 | template <typename MessageType> |
1710 | inline uint8* WireFormatLite::InternalWriteMessage( |
1711 | int field_number, const MessageType& value, uint8* target, |
1712 | io::EpsCopyOutputStream* stream) { |
1713 | target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); |
1714 | target = io::CodedOutputStream::WriteVarint32ToArray( |
1715 | static_cast<uint32>(value.GetCachedSize()), target); |
1716 | return value._InternalSerialize(target, stream); |
1717 | } |
1718 | |
1719 | // See comment on ReadGroupNoVirtual to understand the need for this template |
1720 | // parameter name. |
1721 | template <typename MessageType_WorkAroundCppLookupDefect> |
1722 | inline uint8* WireFormatLite::InternalWriteGroupNoVirtualToArray( |
1723 | int field_number, const MessageType_WorkAroundCppLookupDefect& value, |
1724 | uint8* target) { |
1725 | target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target); |
1726 | target = value.MessageType_WorkAroundCppLookupDefect:: |
1727 | SerializeWithCachedSizesToArray(target); |
1728 | return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target); |
1729 | } |
1730 | template <typename MessageType_WorkAroundCppLookupDefect> |
1731 | inline uint8* WireFormatLite::InternalWriteMessageNoVirtualToArray( |
1732 | int field_number, const MessageType_WorkAroundCppLookupDefect& value, |
1733 | uint8* target) { |
1734 | target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); |
1735 | target = io::CodedOutputStream::WriteVarint32ToArray( |
1736 | static_cast<uint32>( |
1737 | value.MessageType_WorkAroundCppLookupDefect::GetCachedSize()), |
1738 | target); |
1739 | return value |
1740 | .MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizesToArray( |
1741 | target); |
1742 | } |
1743 | |
1744 | // =================================================================== |
1745 | |
1746 | inline size_t WireFormatLite::Int32Size(int32 value) { |
1747 | return io::CodedOutputStream::VarintSize32SignExtended(value); |
1748 | } |
1749 | inline size_t WireFormatLite::Int64Size(int64 value) { |
1750 | return io::CodedOutputStream::VarintSize64(static_cast<uint64>(value)); |
1751 | } |
1752 | inline size_t WireFormatLite::UInt32Size(uint32 value) { |
1753 | return io::CodedOutputStream::VarintSize32(value); |
1754 | } |
1755 | inline size_t WireFormatLite::UInt64Size(uint64 value) { |
1756 | return io::CodedOutputStream::VarintSize64(value); |
1757 | } |
1758 | inline size_t WireFormatLite::SInt32Size(int32 value) { |
1759 | return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value)); |
1760 | } |
1761 | inline size_t WireFormatLite::SInt64Size(int64 value) { |
1762 | return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value)); |
1763 | } |
1764 | inline size_t WireFormatLite::EnumSize(int value) { |
1765 | return io::CodedOutputStream::VarintSize32SignExtended(value); |
1766 | } |
1767 | |
1768 | inline size_t WireFormatLite::StringSize(const std::string& value) { |
1769 | return LengthDelimitedSize(value.size()); |
1770 | } |
1771 | inline size_t WireFormatLite::BytesSize(const std::string& value) { |
1772 | return LengthDelimitedSize(value.size()); |
1773 | } |
1774 | |
1775 | |
1776 | template <typename MessageType> |
1777 | inline size_t WireFormatLite::GroupSize(const MessageType& value) { |
1778 | return value.ByteSizeLong(); |
1779 | } |
1780 | template <typename MessageType> |
1781 | inline size_t WireFormatLite::MessageSize(const MessageType& value) { |
1782 | return LengthDelimitedSize(value.ByteSizeLong()); |
1783 | } |
1784 | |
1785 | // See comment on ReadGroupNoVirtual to understand the need for this template |
1786 | // parameter name. |
1787 | template <typename MessageType_WorkAroundCppLookupDefect> |
1788 | inline size_t WireFormatLite::GroupSizeNoVirtual( |
1789 | const MessageType_WorkAroundCppLookupDefect& value) { |
1790 | return value.MessageType_WorkAroundCppLookupDefect::ByteSizeLong(); |
1791 | } |
1792 | template <typename MessageType_WorkAroundCppLookupDefect> |
1793 | inline size_t WireFormatLite::MessageSizeNoVirtual( |
1794 | const MessageType_WorkAroundCppLookupDefect& value) { |
1795 | return LengthDelimitedSize( |
1796 | value.MessageType_WorkAroundCppLookupDefect::ByteSizeLong()); |
1797 | } |
1798 | |
1799 | inline size_t WireFormatLite::LengthDelimitedSize(size_t length) { |
1800 | // The static_cast here prevents an error in certain compiler configurations |
1801 | // but is not technically correct--if length is too large to fit in a uint32 |
1802 | // then it will be silently truncated. We will need to fix this if we ever |
1803 | // decide to start supporting serialized messages greater than 2 GiB in size. |
1804 | return length + |
1805 | io::CodedOutputStream::VarintSize32(static_cast<uint32>(length)); |
1806 | } |
1807 | |
1808 | template <typename MS> |
1809 | bool ParseMessageSetItemImpl(io::CodedInputStream* input, MS ms) { |
1810 | // This method parses a group which should contain two fields: |
1811 | // required int32 type_id = 2; |
1812 | // required data message = 3; |
1813 | |
1814 | uint32 last_type_id = 0; |
1815 | |
1816 | // If we see message data before the type_id, we'll append it to this so |
1817 | // we can parse it later. |
1818 | std::string message_data; |
1819 | |
1820 | while (true) { |
1821 | const uint32 tag = input->ReadTagNoLastTag(); |
1822 | if (tag == 0) return false; |
1823 | |
1824 | switch (tag) { |
1825 | case WireFormatLite::kMessageSetTypeIdTag: { |
1826 | uint32 type_id; |
1827 | if (!input->ReadVarint32(&type_id)) return false; |
1828 | last_type_id = type_id; |
1829 | |
1830 | if (!message_data.empty()) { |
1831 | // We saw some message data before the type_id. Have to parse it |
1832 | // now. |
1833 | io::CodedInputStream sub_input( |
1834 | reinterpret_cast<const uint8*>(message_data.data()), |
1835 | static_cast<int>(message_data.size())); |
1836 | sub_input.SetRecursionLimit(input->RecursionBudget()); |
1837 | if (!ms.ParseField(last_type_id, &sub_input)) { |
1838 | return false; |
1839 | } |
1840 | message_data.clear(); |
1841 | } |
1842 | |
1843 | break; |
1844 | } |
1845 | |
1846 | case WireFormatLite::kMessageSetMessageTag: { |
1847 | if (last_type_id == 0) { |
1848 | // We haven't seen a type_id yet. Append this data to message_data. |
1849 | uint32 length; |
1850 | if (!input->ReadVarint32(&length)) return false; |
1851 | if (static_cast<int32>(length) < 0) return false; |
1852 | uint32 size = static_cast<uint32>( |
1853 | length + io::CodedOutputStream::VarintSize32(length)); |
1854 | message_data.resize(size); |
1855 | auto ptr = reinterpret_cast<uint8*>(&message_data[0]); |
1856 | ptr = io::CodedOutputStream::WriteVarint32ToArray(length, ptr); |
1857 | if (!input->ReadRaw(ptr, length)) return false; |
1858 | } else { |
1859 | // Already saw type_id, so we can parse this directly. |
1860 | if (!ms.ParseField(last_type_id, input)) { |
1861 | return false; |
1862 | } |
1863 | } |
1864 | |
1865 | break; |
1866 | } |
1867 | |
1868 | case WireFormatLite::kMessageSetItemEndTag: { |
1869 | return true; |
1870 | } |
1871 | |
1872 | default: { |
1873 | if (!ms.SkipField(tag, input)) return false; |
1874 | } |
1875 | } |
1876 | } |
1877 | } |
1878 | |
1879 | } // namespace internal |
1880 | } // namespace protobuf |
1881 | } // namespace google |
1882 | |
1883 | #include <google/protobuf/port_undef.inc> |
1884 | |
1885 | #endif // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__ |
1886 | |