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 <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 #include <google/protobuf/stubs/casts.h>
53
54 // Do UTF-8 validation on string type in Debug build only
55 #ifndef NDEBUG
56 #define GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
57 #endif
58
59 // Avoid conflict with iOS where <ConditionalMacros.h> #defines TYPE_BOOL.
60 //
61 // If some one needs the macro TYPE_BOOL in a file that includes this header,
62 // it's possible to bring it back using push/pop_macro as follows.
63 //
64 // #pragma push_macro("TYPE_BOOL")
65 // #include this header and/or all headers that need the macro to be undefined.
66 // #pragma pop_macro("TYPE_BOOL")
67 #undef TYPE_BOOL
68
69 #include <google/protobuf/port_def.inc>
70
71 namespace google {
72 namespace protobuf {
73 namespace internal {
74
75 // This class is for internal use by the protocol buffer library and by
76 // protocol-compiler-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
WireTypeForFieldType(WireFormatLite::FieldType type)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 constexpr int kTagTypeBits = 3;
159 // Mask for those bits.
160 static constexpr uint32_t 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_t MakeTag(int field_number, WireType type);
168 static WireType GetTagWireType(uint32_t tag);
169 static int GetTagFieldNumber(uint32_t 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_t 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_t 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_t>((static_cast<uint32_t>(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 constexpr int kMessageSetItemNumber = 1;
213 static constexpr int kMessageSetTypeIdNumber = 2;
214 static constexpr 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_t EncodeFloat(float value);
231 static float DecodeFloat(uint32_t value);
232 static uint64_t EncodeDouble(double value);
233 static double DecodeDouble(uint64_t 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_t ZigZagEncode32(int32_t n);
242 static int32_t ZigZagDecode32(uint32_t n);
243 static uint64_t ZigZagEncode64(int64_t n);
244 static int64_t ZigZagDecode64(uint64_t 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_NDEBUG_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_NDEBUG_INLINE static bool ReadRepeatedPrimitive(
264 int tag_size, uint32_t 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_t 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_NDEBUG_INLINE static const uint8_t* ReadPrimitiveFromArray(
281 const uint8_t* 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_NDEBUG_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>
ReadMessageNoVirtual(io::CodedInputStream * input,MessageType * value)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_NDEBUG_INLINE static void WriteTag(int field_number, WireType type,
349 io::CodedOutputStream* output);
350
351 // Write fields, without tags.
352 PROTOBUF_NDEBUG_INLINE static void WriteInt32NoTag(
353 int32_t value, io::CodedOutputStream* output);
354 PROTOBUF_NDEBUG_INLINE static void WriteInt64NoTag(
355 int64_t value, io::CodedOutputStream* output);
356 PROTOBUF_NDEBUG_INLINE static void WriteUInt32NoTag(
357 uint32_t value, io::CodedOutputStream* output);
358 PROTOBUF_NDEBUG_INLINE static void WriteUInt64NoTag(
359 uint64_t value, io::CodedOutputStream* output);
360 PROTOBUF_NDEBUG_INLINE static void WriteSInt32NoTag(
361 int32_t value, io::CodedOutputStream* output);
362 PROTOBUF_NDEBUG_INLINE static void WriteSInt64NoTag(
363 int64_t value, io::CodedOutputStream* output);
364 PROTOBUF_NDEBUG_INLINE static void WriteFixed32NoTag(
365 uint32_t value, io::CodedOutputStream* output);
366 PROTOBUF_NDEBUG_INLINE static void WriteFixed64NoTag(
367 uint64_t value, io::CodedOutputStream* output);
368 PROTOBUF_NDEBUG_INLINE static void WriteSFixed32NoTag(
369 int32_t value, io::CodedOutputStream* output);
370 PROTOBUF_NDEBUG_INLINE static void WriteSFixed64NoTag(
371 int64_t value, io::CodedOutputStream* output);
372 PROTOBUF_NDEBUG_INLINE static void WriteFloatNoTag(
373 float value, io::CodedOutputStream* output);
374 PROTOBUF_NDEBUG_INLINE static void WriteDoubleNoTag(
375 double value, io::CodedOutputStream* output);
376 PROTOBUF_NDEBUG_INLINE static void WriteBoolNoTag(
377 bool value, io::CodedOutputStream* output);
378 PROTOBUF_NDEBUG_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_t* a, int n,
387 io::CodedOutputStream* output);
388 static void WriteFixed64Array(const uint64_t* a, int n,
389 io::CodedOutputStream* output);
390 static void WriteSFixed32Array(const int32_t* a, int n,
391 io::CodedOutputStream* output);
392 static void WriteSFixed64Array(const int64_t* 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_t value,
399 io::CodedOutputStream* output);
400 static void WriteInt64(int field_number, int64_t value,
401 io::CodedOutputStream* output);
402 static void WriteUInt32(int field_number, uint32_t value,
403 io::CodedOutputStream* output);
404 static void WriteUInt64(int field_number, uint64_t value,
405 io::CodedOutputStream* output);
406 static void WriteSInt32(int field_number, int32_t value,
407 io::CodedOutputStream* output);
408 static void WriteSInt64(int field_number, int64_t value,
409 io::CodedOutputStream* output);
410 static void WriteFixed32(int field_number, uint32_t value,
411 io::CodedOutputStream* output);
412 static void WriteFixed64(int field_number, uint64_t value,
413 io::CodedOutputStream* output);
414 static void WriteSFixed32(int field_number, int32_t value,
415 io::CodedOutputStream* output);
416 static void WriteSFixed64(int field_number, int64_t 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_NDEBUG_INLINE static uint8_t* WriteTagToArray(int field_number,
463 WireType type,
464 uint8_t* target);
465
466 // Write fields, without tags.
467 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt32NoTagToArray(
468 int32_t value, uint8_t* target);
469 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt64NoTagToArray(
470 int64_t value, uint8_t* target);
471 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt32NoTagToArray(
472 uint32_t value, uint8_t* target);
473 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt64NoTagToArray(
474 uint64_t value, uint8_t* target);
475 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt32NoTagToArray(
476 int32_t value, uint8_t* target);
477 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt64NoTagToArray(
478 int64_t value, uint8_t* target);
479 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed32NoTagToArray(
480 uint32_t value, uint8_t* target);
481 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed64NoTagToArray(
482 uint64_t value, uint8_t* target);
483 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed32NoTagToArray(
484 int32_t value, uint8_t* target);
485 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed64NoTagToArray(
486 int64_t value, uint8_t* target);
487 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFloatNoTagToArray(
488 float value, uint8_t* target);
489 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteDoubleNoTagToArray(
490 double value, uint8_t* target);
491 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteBoolNoTagToArray(bool value,
492 uint8_t* target);
493 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteEnumNoTagToArray(int value,
494 uint8_t* target);
495
496 // Write fields, without tags. These require that value.size() > 0.
497 template <typename T>
498 PROTOBUF_NDEBUG_INLINE static uint8_t* WritePrimitiveNoTagToArray(
499 const RepeatedField<T>& value, uint8_t* (*Writer)(T, uint8_t*),
500 uint8_t* target);
501 template <typename T>
502 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixedNoTagToArray(
503 const RepeatedField<T>& value, uint8_t* (*Writer)(T, uint8_t*),
504 uint8_t* target);
505
506 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt32NoTagToArray(
507 const RepeatedField<int32_t>& value, uint8_t* output);
508 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt64NoTagToArray(
509 const RepeatedField<int64_t>& value, uint8_t* output);
510 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt32NoTagToArray(
511 const RepeatedField<uint32_t>& value, uint8_t* output);
512 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt64NoTagToArray(
513 const RepeatedField<uint64_t>& value, uint8_t* output);
514 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt32NoTagToArray(
515 const RepeatedField<int32_t>& value, uint8_t* output);
516 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt64NoTagToArray(
517 const RepeatedField<int64_t>& value, uint8_t* output);
518 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed32NoTagToArray(
519 const RepeatedField<uint32_t>& value, uint8_t* output);
520 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed64NoTagToArray(
521 const RepeatedField<uint64_t>& value, uint8_t* output);
522 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed32NoTagToArray(
523 const RepeatedField<int32_t>& value, uint8_t* output);
524 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed64NoTagToArray(
525 const RepeatedField<int64_t>& value, uint8_t* output);
526 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFloatNoTagToArray(
527 const RepeatedField<float>& value, uint8_t* output);
528 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteDoubleNoTagToArray(
529 const RepeatedField<double>& value, uint8_t* output);
530 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteBoolNoTagToArray(
531 const RepeatedField<bool>& value, uint8_t* output);
532 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteEnumNoTagToArray(
533 const RepeatedField<int>& value, uint8_t* output);
534
535 // Write fields, including tags.
536 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt32ToArray(int field_number,
537 int32_t value,
538 uint8_t* target);
539 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt64ToArray(int field_number,
540 int64_t value,
541 uint8_t* target);
542 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt32ToArray(int field_number,
543 uint32_t value,
544 uint8_t* target);
545 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt64ToArray(int field_number,
546 uint64_t value,
547 uint8_t* target);
548 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt32ToArray(int field_number,
549 int32_t value,
550 uint8_t* target);
551 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt64ToArray(int field_number,
552 int64_t value,
553 uint8_t* target);
554 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed32ToArray(int field_number,
555 uint32_t value,
556 uint8_t* target);
557 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed64ToArray(int field_number,
558 uint64_t value,
559 uint8_t* target);
560 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed32ToArray(int field_number,
561 int32_t value,
562 uint8_t* target);
563 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed64ToArray(int field_number,
564 int64_t value,
565 uint8_t* target);
566 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFloatToArray(int field_number,
567 float value,
568 uint8_t* target);
569 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteDoubleToArray(int field_number,
570 double value,
571 uint8_t* target);
572 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteBoolToArray(int field_number,
573 bool value,
574 uint8_t* target);
575 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteEnumToArray(int field_number,
576 int value,
577 uint8_t* target);
578
579 template <typename T>
580 PROTOBUF_NDEBUG_INLINE static uint8_t* WritePrimitiveToArray(
581 int field_number, const RepeatedField<T>& value,
582 uint8_t* (*Writer)(int, T, uint8_t*), uint8_t* target);
583
584 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt32ToArray(
585 int field_number, const RepeatedField<int32_t>& value, uint8_t* output);
586 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt64ToArray(
587 int field_number, const RepeatedField<int64_t>& value, uint8_t* output);
588 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt32ToArray(
589 int field_number, const RepeatedField<uint32_t>& value, uint8_t* output);
590 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt64ToArray(
591 int field_number, const RepeatedField<uint64_t>& value, uint8_t* output);
592 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt32ToArray(
593 int field_number, const RepeatedField<int32_t>& value, uint8_t* output);
594 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt64ToArray(
595 int field_number, const RepeatedField<int64_t>& value, uint8_t* output);
596 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed32ToArray(
597 int field_number, const RepeatedField<uint32_t>& value, uint8_t* output);
598 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed64ToArray(
599 int field_number, const RepeatedField<uint64_t>& value, uint8_t* output);
600 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed32ToArray(
601 int field_number, const RepeatedField<int32_t>& value, uint8_t* output);
602 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed64ToArray(
603 int field_number, const RepeatedField<int64_t>& value, uint8_t* output);
604 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFloatToArray(
605 int field_number, const RepeatedField<float>& value, uint8_t* output);
606 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteDoubleToArray(
607 int field_number, const RepeatedField<double>& value, uint8_t* output);
608 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteBoolToArray(
609 int field_number, const RepeatedField<bool>& value, uint8_t* output);
610 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteEnumToArray(
611 int field_number, const RepeatedField<int>& value, uint8_t* output);
612
613 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteStringToArray(
614 int field_number, const std::string& value, uint8_t* target);
615 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteBytesToArray(
616 int field_number, const std::string& value, uint8_t* 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_NDEBUG_INLINE static uint8_t* InternalWriteGroup(
625 int field_number, const MessageType& value, uint8_t* target,
626 io::EpsCopyOutputStream* stream);
627 template <typename MessageType>
628 PROTOBUF_NDEBUG_INLINE static uint8_t* InternalWriteMessage(
629 int field_number, const MessageType& value, uint8_t* 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_NDEBUG_INLINE static uint8_t* InternalWriteGroupNoVirtualToArray(
637 int field_number, const MessageType& value, uint8_t* target);
638 template <typename MessageType>
639 PROTOBUF_NDEBUG_INLINE static uint8_t* InternalWriteMessageNoVirtualToArray(
640 int field_number, const MessageType& value, uint8_t* target);
641
642 // For backward-compatibility, the last four methods also have versions
643 // that are non-deterministic always.
WriteGroupToArray(int field_number,const MessageLite & value,uint8_t * target)644 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteGroupToArray(
645 int field_number, const MessageLite& value, uint8_t* target) {
646 io::EpsCopyOutputStream stream(
647 target,
648 value.GetCachedSize() +
649 static_cast<int>(2 * io::CodedOutputStream::VarintSize32(
650 static_cast<uint32_t>(field_number) << 3)),
651 io::CodedOutputStream::IsDefaultSerializationDeterministic());
652 return InternalWriteGroup(field_number, value, target, &stream);
653 }
WriteMessageToArray(int field_number,const MessageLite & value,uint8_t * target)654 PROTOBUF_NDEBUG_INLINE static uint8_t* WriteMessageToArray(
655 int field_number, const MessageLite& value, uint8_t* target) {
656 int size = value.GetCachedSize();
657 io::EpsCopyOutputStream stream(
658 target,
659 size + static_cast<int>(io::CodedOutputStream::VarintSize32(
660 static_cast<uint32_t>(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_t value);
671 static inline size_t Int64Size(int64_t value);
672 static inline size_t UInt32Size(uint32_t value);
673 static inline size_t UInt64Size(uint64_t value);
674 static inline size_t SInt32Size(int32_t value);
675 static inline size_t SInt64Size(int64_t value);
676 static inline size_t EnumSize(int value);
677 static inline size_t Int32SizePlusOne(int32_t value);
678 static inline size_t Int64SizePlusOne(int64_t value);
679 static inline size_t UInt32SizePlusOne(uint32_t value);
680 static inline size_t UInt64SizePlusOne(uint64_t value);
681 static inline size_t SInt32SizePlusOne(int32_t value);
682 static inline size_t SInt64SizePlusOne(int64_t value);
683 static inline size_t EnumSizePlusOne(int value);
684
685 static size_t Int32Size(const RepeatedField<int32_t>& value);
686 static size_t Int64Size(const RepeatedField<int64_t>& value);
687 static size_t UInt32Size(const RepeatedField<uint32_t>& value);
688 static size_t UInt64Size(const RepeatedField<uint64_t>& value);
689 static size_t SInt32Size(const RepeatedField<int32_t>& value);
690 static size_t SInt64Size(const RepeatedField<int64_t>& value);
691 static size_t EnumSize(const RepeatedField<int>& value);
692
693 // These types always have the same size.
694 static constexpr size_t kFixed32Size = 4;
695 static constexpr size_t kFixed64Size = 8;
696 static constexpr size_t kSFixed32Size = 4;
697 static constexpr size_t kSFixed64Size = 8;
698 static constexpr size_t kFloatSize = 4;
699 static constexpr size_t kDoubleSize = 8;
700 static constexpr size_t kBoolSize = 1;
701
702 static inline size_t StringSize(const std::string& value);
703 static inline size_t BytesSize(const std::string& value);
704
705 template <typename MessageType>
706 static inline size_t GroupSize(const MessageType& value);
707 template <typename MessageType>
708 static inline size_t MessageSize(const MessageType& value);
709
710 // Like above, but de-virtualize the call to ByteSize(). The
711 // pointer must point at an instance of MessageType, *not* a subclass (or
712 // the subclass must not override ByteSize()).
713 template <typename MessageType>
714 static inline size_t GroupSizeNoVirtual(const MessageType& value);
715 template <typename MessageType>
716 static inline size_t MessageSizeNoVirtual(const MessageType& value);
717
718 // Given the length of data, calculate the byte size of the data on the
719 // wire if we encode the data as a length delimited field.
720 static inline size_t LengthDelimitedSize(size_t length);
721
722 private:
723 // A helper method for the repeated primitive reader. This method has
724 // optimizations for primitive types that have fixed size on the wire, and
725 // can be read using potentially faster paths.
726 template <typename CType, enum FieldType DeclaredType>
727 PROTOBUF_NDEBUG_INLINE static bool ReadRepeatedFixedSizePrimitive(
728 int tag_size, uint32_t tag, io::CodedInputStream* input,
729 RepeatedField<CType>* value);
730
731 // Like ReadRepeatedFixedSizePrimitive but for packed primitive fields.
732 template <typename CType, enum FieldType DeclaredType>
733 PROTOBUF_NDEBUG_INLINE static bool ReadPackedFixedSizePrimitive(
734 io::CodedInputStream* input, RepeatedField<CType>* value);
735
736 static const CppType kFieldTypeToCppTypeMap[];
737 static const WireFormatLite::WireType kWireTypeForFieldType[];
738 static void WriteSubMessageMaybeToArray(int size, const MessageLite& value,
739 io::CodedOutputStream* output);
740
741 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormatLite);
742 };
743
744 // A class which deals with unknown values. The default implementation just
745 // discards them. WireFormat defines a subclass which writes to an
746 // UnknownFieldSet. This class is used by ExtensionSet::ParseField(), since
747 // ExtensionSet is part of the lite library but UnknownFieldSet is not.
748 class PROTOBUF_EXPORT FieldSkipper {
749 public:
FieldSkipper()750 FieldSkipper() {}
~FieldSkipper()751 virtual ~FieldSkipper() {}
752
753 // Skip a field whose tag has already been consumed.
754 virtual bool SkipField(io::CodedInputStream* input, uint32_t tag);
755
756 // Skip an entire message or group, up to an end-group tag (which is consumed)
757 // or end-of-stream.
758 virtual bool SkipMessage(io::CodedInputStream* input);
759
760 // Deal with an already-parsed unrecognized enum value. The default
761 // implementation does nothing, but the UnknownFieldSet-based implementation
762 // saves it as an unknown varint.
763 virtual void SkipUnknownEnum(int field_number, int value);
764 };
765
766 // Subclass of FieldSkipper which saves skipped fields to a CodedOutputStream.
767
768 class PROTOBUF_EXPORT CodedOutputStreamFieldSkipper : public FieldSkipper {
769 public:
CodedOutputStreamFieldSkipper(io::CodedOutputStream * unknown_fields)770 explicit CodedOutputStreamFieldSkipper(io::CodedOutputStream* unknown_fields)
771 : unknown_fields_(unknown_fields) {}
~CodedOutputStreamFieldSkipper()772 ~CodedOutputStreamFieldSkipper() override {}
773
774 // implements FieldSkipper -----------------------------------------
775 bool SkipField(io::CodedInputStream* input, uint32_t tag) override;
776 bool SkipMessage(io::CodedInputStream* input) override;
777 void SkipUnknownEnum(int field_number, int value) override;
778
779 protected:
780 io::CodedOutputStream* unknown_fields_;
781 };
782
783 // inline methods ====================================================
784
FieldTypeToCppType(FieldType type)785 inline WireFormatLite::CppType WireFormatLite::FieldTypeToCppType(
786 FieldType type) {
787 return kFieldTypeToCppTypeMap[type];
788 }
789
MakeTag(int field_number,WireType type)790 constexpr inline uint32_t WireFormatLite::MakeTag(int field_number,
791 WireType type) {
792 return GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(field_number, type);
793 }
794
GetTagWireType(uint32_t tag)795 inline WireFormatLite::WireType WireFormatLite::GetTagWireType(uint32_t tag) {
796 return static_cast<WireType>(tag & kTagTypeMask);
797 }
798
GetTagFieldNumber(uint32_t tag)799 inline int WireFormatLite::GetTagFieldNumber(uint32_t tag) {
800 return static_cast<int>(tag >> kTagTypeBits);
801 }
802
TagSize(int field_number,WireFormatLite::FieldType type)803 inline size_t WireFormatLite::TagSize(int field_number,
804 WireFormatLite::FieldType type) {
805 size_t result = io::CodedOutputStream::VarintSize32(
806 static_cast<uint32_t>(field_number << kTagTypeBits));
807 if (type == TYPE_GROUP) {
808 // Groups have both a start and an end tag.
809 return result * 2;
810 } else {
811 return result;
812 }
813 }
814
EncodeFloat(float value)815 inline uint32_t WireFormatLite::EncodeFloat(float value) {
816 return bit_cast<uint32_t>(value);
817 }
818
DecodeFloat(uint32_t value)819 inline float WireFormatLite::DecodeFloat(uint32_t value) {
820 return bit_cast<float>(value);
821 }
822
EncodeDouble(double value)823 inline uint64_t WireFormatLite::EncodeDouble(double value) {
824 return bit_cast<uint64_t>(value);
825 }
826
DecodeDouble(uint64_t value)827 inline double WireFormatLite::DecodeDouble(uint64_t value) {
828 return bit_cast<double>(value);
829 }
830
831 // ZigZag Transform: Encodes signed integers so that they can be
832 // effectively used with varint encoding.
833 //
834 // varint operates on unsigned integers, encoding smaller numbers into
835 // fewer bytes. If you try to use it on a signed integer, it will treat
836 // this number as a very large unsigned integer, which means that even
837 // small signed numbers like -1 will take the maximum number of bytes
838 // (10) to encode. ZigZagEncode() maps signed integers to unsigned
839 // in such a way that those with a small absolute value will have smaller
840 // encoded values, making them appropriate for encoding using varint.
841 //
842 // int32_t -> uint32_t
843 // -------------------------
844 // 0 -> 0
845 // -1 -> 1
846 // 1 -> 2
847 // -2 -> 3
848 // ... -> ...
849 // 2147483647 -> 4294967294
850 // -2147483648 -> 4294967295
851 //
852 // >> encode >>
853 // << decode <<
854
ZigZagEncode32(int32_t n)855 inline uint32_t WireFormatLite::ZigZagEncode32(int32_t n) {
856 // Note: the right-shift must be arithmetic
857 // Note: left shift must be unsigned because of overflow
858 return (static_cast<uint32_t>(n) << 1) ^ static_cast<uint32_t>(n >> 31);
859 }
860
ZigZagDecode32(uint32_t n)861 inline int32_t WireFormatLite::ZigZagDecode32(uint32_t n) {
862 // Note: Using unsigned types prevent undefined behavior
863 return static_cast<int32_t>((n >> 1) ^ (~(n & 1) + 1));
864 }
865
ZigZagEncode64(int64_t n)866 inline uint64_t WireFormatLite::ZigZagEncode64(int64_t n) {
867 // Note: the right-shift must be arithmetic
868 // Note: left shift must be unsigned because of overflow
869 return (static_cast<uint64_t>(n) << 1) ^ static_cast<uint64_t>(n >> 63);
870 }
871
ZigZagDecode64(uint64_t n)872 inline int64_t WireFormatLite::ZigZagDecode64(uint64_t n) {
873 // Note: Using unsigned types prevent undefined behavior
874 return static_cast<int64_t>((n >> 1) ^ (~(n & 1) + 1));
875 }
876
877 // String is for UTF-8 text only, but, even so, ReadString() can simply
878 // call ReadBytes().
879
ReadString(io::CodedInputStream * input,std::string * value)880 inline bool WireFormatLite::ReadString(io::CodedInputStream* input,
881 std::string* value) {
882 return ReadBytes(input, value);
883 }
884
ReadString(io::CodedInputStream * input,std::string ** p)885 inline bool WireFormatLite::ReadString(io::CodedInputStream* input,
886 std::string** p) {
887 return ReadBytes(input, p);
888 }
889
InternalSerializeUnknownMessageSetItemsToArray(const std::string & unknown_fields,uint8_t * target,io::EpsCopyOutputStream * stream)890 inline uint8_t* InternalSerializeUnknownMessageSetItemsToArray(
891 const std::string& unknown_fields, uint8_t* target,
892 io::EpsCopyOutputStream* stream) {
893 return stream->WriteRaw(unknown_fields.data(),
894 static_cast<int>(unknown_fields.size()), target);
895 }
896
ComputeUnknownMessageSetItemsSize(const std::string & unknown_fields)897 inline size_t ComputeUnknownMessageSetItemsSize(
898 const std::string& unknown_fields) {
899 return unknown_fields.size();
900 }
901
902 // Implementation details of ReadPrimitive.
903
904 template <>
905 inline bool WireFormatLite::ReadPrimitive<int32_t, WireFormatLite::TYPE_INT32>(
906 io::CodedInputStream* input, int32_t* value) {
907 uint32_t temp;
908 if (!input->ReadVarint32(&temp)) return false;
909 *value = static_cast<int32_t>(temp);
910 return true;
911 }
912 template <>
913 inline bool WireFormatLite::ReadPrimitive<int64_t, WireFormatLite::TYPE_INT64>(
914 io::CodedInputStream* input, int64_t* value) {
915 uint64_t temp;
916 if (!input->ReadVarint64(&temp)) return false;
917 *value = static_cast<int64_t>(temp);
918 return true;
919 }
920 template <>
921 inline bool
922 WireFormatLite::ReadPrimitive<uint32_t, WireFormatLite::TYPE_UINT32>(
923 io::CodedInputStream* input, uint32_t* value) {
924 return input->ReadVarint32(value);
925 }
926 template <>
927 inline bool
928 WireFormatLite::ReadPrimitive<uint64_t, WireFormatLite::TYPE_UINT64>(
929 io::CodedInputStream* input, uint64_t* value) {
930 return input->ReadVarint64(value);
931 }
932 template <>
933 inline bool WireFormatLite::ReadPrimitive<int32_t, WireFormatLite::TYPE_SINT32>(
934 io::CodedInputStream* input, int32_t* value) {
935 uint32_t temp;
936 if (!input->ReadVarint32(&temp)) return false;
937 *value = ZigZagDecode32(temp);
938 return true;
939 }
940 template <>
941 inline bool WireFormatLite::ReadPrimitive<int64_t, WireFormatLite::TYPE_SINT64>(
942 io::CodedInputStream* input, int64_t* value) {
943 uint64_t temp;
944 if (!input->ReadVarint64(&temp)) return false;
945 *value = ZigZagDecode64(temp);
946 return true;
947 }
948 template <>
949 inline bool
950 WireFormatLite::ReadPrimitive<uint32_t, WireFormatLite::TYPE_FIXED32>(
951 io::CodedInputStream* input, uint32_t* value) {
952 return input->ReadLittleEndian32(value);
953 }
954 template <>
955 inline bool
956 WireFormatLite::ReadPrimitive<uint64_t, WireFormatLite::TYPE_FIXED64>(
957 io::CodedInputStream* input, uint64_t* value) {
958 return input->ReadLittleEndian64(value);
959 }
960 template <>
961 inline bool
962 WireFormatLite::ReadPrimitive<int32_t, WireFormatLite::TYPE_SFIXED32>(
963 io::CodedInputStream* input, int32_t* value) {
964 uint32_t temp;
965 if (!input->ReadLittleEndian32(&temp)) return false;
966 *value = static_cast<int32_t>(temp);
967 return true;
968 }
969 template <>
970 inline bool
971 WireFormatLite::ReadPrimitive<int64_t, WireFormatLite::TYPE_SFIXED64>(
972 io::CodedInputStream* input, int64_t* value) {
973 uint64_t temp;
974 if (!input->ReadLittleEndian64(&temp)) return false;
975 *value = static_cast<int64_t>(temp);
976 return true;
977 }
978 template <>
979 inline bool WireFormatLite::ReadPrimitive<float, WireFormatLite::TYPE_FLOAT>(
980 io::CodedInputStream* input, float* value) {
981 uint32_t temp;
982 if (!input->ReadLittleEndian32(&temp)) return false;
983 *value = DecodeFloat(temp);
984 return true;
985 }
986 template <>
987 inline bool WireFormatLite::ReadPrimitive<double, WireFormatLite::TYPE_DOUBLE>(
988 io::CodedInputStream* input, double* value) {
989 uint64_t temp;
990 if (!input->ReadLittleEndian64(&temp)) return false;
991 *value = DecodeDouble(temp);
992 return true;
993 }
994 template <>
995 inline bool WireFormatLite::ReadPrimitive<bool, WireFormatLite::TYPE_BOOL>(
996 io::CodedInputStream* input, bool* value) {
997 uint64_t temp;
998 if (!input->ReadVarint64(&temp)) return false;
999 *value = temp != 0;
1000 return true;
1001 }
1002 template <>
1003 inline bool WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
1004 io::CodedInputStream* input, int* value) {
1005 uint32_t temp;
1006 if (!input->ReadVarint32(&temp)) return false;
1007 *value = static_cast<int>(temp);
1008 return true;
1009 }
1010
1011 template <>
1012 inline const uint8_t*
1013 WireFormatLite::ReadPrimitiveFromArray<uint32_t, WireFormatLite::TYPE_FIXED32>(
1014 const uint8_t* buffer, uint32_t* value) {
1015 return io::CodedInputStream::ReadLittleEndian32FromArray(buffer, value);
1016 }
1017 template <>
1018 inline const uint8_t*
1019 WireFormatLite::ReadPrimitiveFromArray<uint64_t, WireFormatLite::TYPE_FIXED64>(
1020 const uint8_t* buffer, uint64_t* value) {
1021 return io::CodedInputStream::ReadLittleEndian64FromArray(buffer, value);
1022 }
1023 template <>
1024 inline const uint8_t*
1025 WireFormatLite::ReadPrimitiveFromArray<int32_t, WireFormatLite::TYPE_SFIXED32>(
1026 const uint8_t* buffer, int32_t* value) {
1027 uint32_t temp;
1028 buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp);
1029 *value = static_cast<int32_t>(temp);
1030 return buffer;
1031 }
1032 template <>
1033 inline const uint8_t*
1034 WireFormatLite::ReadPrimitiveFromArray<int64_t, WireFormatLite::TYPE_SFIXED64>(
1035 const uint8_t* buffer, int64_t* value) {
1036 uint64_t temp;
1037 buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp);
1038 *value = static_cast<int64_t>(temp);
1039 return buffer;
1040 }
1041 template <>
1042 inline const uint8_t*
1043 WireFormatLite::ReadPrimitiveFromArray<float, WireFormatLite::TYPE_FLOAT>(
1044 const uint8_t* buffer, float* value) {
1045 uint32_t temp;
1046 buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp);
1047 *value = DecodeFloat(temp);
1048 return buffer;
1049 }
1050 template <>
1051 inline const uint8_t*
1052 WireFormatLite::ReadPrimitiveFromArray<double, WireFormatLite::TYPE_DOUBLE>(
1053 const uint8_t* buffer, double* value) {
1054 uint64_t temp;
1055 buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp);
1056 *value = DecodeDouble(temp);
1057 return buffer;
1058 }
1059
1060 template <typename CType, enum WireFormatLite::FieldType DeclaredType>
ReadRepeatedPrimitive(int,uint32_t tag,io::CodedInputStream * input,RepeatedField<CType> * values)1061 inline bool WireFormatLite::ReadRepeatedPrimitive(
1062 int, // tag_size, unused.
1063 uint32_t tag, io::CodedInputStream* input, RepeatedField<CType>* values) {
1064 CType value;
1065 if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
1066 values->Add(value);
1067 int elements_already_reserved = values->Capacity() - values->size();
1068 while (elements_already_reserved > 0 && input->ExpectTag(tag)) {
1069 if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
1070 values->AddAlreadyReserved(value);
1071 elements_already_reserved--;
1072 }
1073 return true;
1074 }
1075
1076 template <typename CType, enum WireFormatLite::FieldType DeclaredType>
ReadRepeatedFixedSizePrimitive(int tag_size,uint32_t tag,io::CodedInputStream * input,RepeatedField<CType> * values)1077 inline bool WireFormatLite::ReadRepeatedFixedSizePrimitive(
1078 int tag_size, uint32_t tag, io::CodedInputStream* input,
1079 RepeatedField<CType>* values) {
1080 GOOGLE_DCHECK_EQ(UInt32Size(tag), static_cast<size_t>(tag_size));
1081 CType value;
1082 if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
1083 values->Add(value);
1084
1085 // For fixed size values, repeated values can be read more quickly by
1086 // reading directly from a raw array.
1087 //
1088 // We can get a tight loop by only reading as many elements as can be
1089 // added to the RepeatedField without having to do any resizing. Additionally,
1090 // we only try to read as many elements as are available from the current
1091 // buffer space. Doing so avoids having to perform boundary checks when
1092 // reading the value: the maximum number of elements that can be read is
1093 // known outside of the loop.
1094 const void* void_pointer;
1095 int size;
1096 input->GetDirectBufferPointerInline(&void_pointer, &size);
1097 if (size > 0) {
1098 const uint8_t* buffer = reinterpret_cast<const uint8_t*>(void_pointer);
1099 // The number of bytes each type occupies on the wire.
1100 const int per_value_size = tag_size + static_cast<int>(sizeof(value));
1101
1102 // parentheses around (std::min) prevents macro expansion of min(...)
1103 int elements_available =
1104 (std::min)(values->Capacity() - values->size(), size / per_value_size);
1105 int num_read = 0;
1106 while (num_read < elements_available &&
1107 (buffer = io::CodedInputStream::ExpectTagFromArray(buffer, tag)) !=
1108 NULL) {
1109 buffer = ReadPrimitiveFromArray<CType, DeclaredType>(buffer, &value);
1110 values->AddAlreadyReserved(value);
1111 ++num_read;
1112 }
1113 const int read_bytes = num_read * per_value_size;
1114 if (read_bytes > 0) {
1115 input->Skip(read_bytes);
1116 }
1117 }
1118 return true;
1119 }
1120
1121 // Specializations of ReadRepeatedPrimitive for the fixed size types, which use
1122 // the optimized code path.
1123 #define READ_REPEATED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE) \
1124 template <> \
1125 inline bool WireFormatLite::ReadRepeatedPrimitive< \
1126 CPPTYPE, WireFormatLite::DECLARED_TYPE>( \
1127 int tag_size, uint32_t tag, io::CodedInputStream* input, \
1128 RepeatedField<CPPTYPE>* values) { \
1129 return ReadRepeatedFixedSizePrimitive<CPPTYPE, \
1130 WireFormatLite::DECLARED_TYPE>( \
1131 tag_size, tag, input, values); \
1132 }
1133
READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32_t,TYPE_FIXED32)1134 READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32_t, TYPE_FIXED32)
1135 READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint64_t, TYPE_FIXED64)
1136 READ_REPEATED_FIXED_SIZE_PRIMITIVE(int32_t, TYPE_SFIXED32)
1137 READ_REPEATED_FIXED_SIZE_PRIMITIVE(int64_t, TYPE_SFIXED64)
1138 READ_REPEATED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT)
1139 READ_REPEATED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE)
1140
1141 #undef READ_REPEATED_FIXED_SIZE_PRIMITIVE
1142
1143 template <typename CType, enum WireFormatLite::FieldType DeclaredType>
1144 bool WireFormatLite::ReadRepeatedPrimitiveNoInline(
1145 int tag_size, uint32_t tag, io::CodedInputStream* input,
1146 RepeatedField<CType>* value) {
1147 return ReadRepeatedPrimitive<CType, DeclaredType>(tag_size, tag, input,
1148 value);
1149 }
1150
1151 template <typename CType, enum WireFormatLite::FieldType DeclaredType>
ReadPackedPrimitive(io::CodedInputStream * input,RepeatedField<CType> * values)1152 inline bool WireFormatLite::ReadPackedPrimitive(io::CodedInputStream* input,
1153 RepeatedField<CType>* values) {
1154 int length;
1155 if (!input->ReadVarintSizeAsInt(&length)) return false;
1156 io::CodedInputStream::Limit limit = input->PushLimit(length);
1157 while (input->BytesUntilLimit() > 0) {
1158 CType value;
1159 if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
1160 values->Add(value);
1161 }
1162 input->PopLimit(limit);
1163 return true;
1164 }
1165
1166 template <typename CType, enum WireFormatLite::FieldType DeclaredType>
ReadPackedFixedSizePrimitive(io::CodedInputStream * input,RepeatedField<CType> * values)1167 inline bool WireFormatLite::ReadPackedFixedSizePrimitive(
1168 io::CodedInputStream* input, RepeatedField<CType>* values) {
1169 int length;
1170 if (!input->ReadVarintSizeAsInt(&length)) return false;
1171 const int old_entries = values->size();
1172 const int new_entries = length / static_cast<int>(sizeof(CType));
1173 const int new_bytes = new_entries * static_cast<int>(sizeof(CType));
1174 if (new_bytes != length) return false;
1175 // We would *like* to pre-allocate the buffer to write into (for
1176 // speed), but *must* avoid performing a very large allocation due
1177 // to a malicious user-supplied "length" above. So we have a fast
1178 // path that pre-allocates when the "length" is less than a bound.
1179 // We determine the bound by calling BytesUntilTotalBytesLimit() and
1180 // BytesUntilLimit(). These return -1 to mean "no limit set".
1181 // There are four cases:
1182 // TotalBytesLimit Limit
1183 // -1 -1 Use slow path.
1184 // -1 >= 0 Use fast path if length <= Limit.
1185 // >= 0 -1 Use slow path.
1186 // >= 0 >= 0 Use fast path if length <= min(both limits).
1187 int64_t bytes_limit = input->BytesUntilTotalBytesLimit();
1188 if (bytes_limit == -1) {
1189 bytes_limit = input->BytesUntilLimit();
1190 } else {
1191 // parentheses around (std::min) prevents macro expansion of min(...)
1192 bytes_limit =
1193 (std::min)(bytes_limit, static_cast<int64_t>(input->BytesUntilLimit()));
1194 }
1195 if (bytes_limit >= new_bytes) {
1196 // Fast-path that pre-allocates *values to the final size.
1197 #if defined(PROTOBUF_LITTLE_ENDIAN)
1198 values->Resize(old_entries + new_entries, 0);
1199 // values->mutable_data() may change after Resize(), so do this after:
1200 void* dest = reinterpret_cast<void*>(values->mutable_data() + old_entries);
1201 if (!input->ReadRaw(dest, new_bytes)) {
1202 values->Truncate(old_entries);
1203 return false;
1204 }
1205 #else
1206 values->Reserve(old_entries + new_entries);
1207 CType value;
1208 for (int i = 0; i < new_entries; ++i) {
1209 if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
1210 values->AddAlreadyReserved(value);
1211 }
1212 #endif
1213 } else {
1214 // This is the slow-path case where "length" may be too large to
1215 // safely allocate. We read as much as we can into *values
1216 // without pre-allocating "length" bytes.
1217 CType value;
1218 for (int i = 0; i < new_entries; ++i) {
1219 if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
1220 values->Add(value);
1221 }
1222 }
1223 return true;
1224 }
1225
1226 // Specializations of ReadPackedPrimitive for the fixed size types, which use
1227 // an optimized code path.
1228 #define READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE) \
1229 template <> \
1230 inline bool \
1231 WireFormatLite::ReadPackedPrimitive<CPPTYPE, WireFormatLite::DECLARED_TYPE>( \
1232 io::CodedInputStream * input, RepeatedField<CPPTYPE> * values) { \
1233 return ReadPackedFixedSizePrimitive<CPPTYPE, \
1234 WireFormatLite::DECLARED_TYPE>( \
1235 input, values); \
1236 }
1237
READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint32_t,TYPE_FIXED32)1238 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint32_t, TYPE_FIXED32)
1239 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint64_t, TYPE_FIXED64)
1240 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int32_t, TYPE_SFIXED32)
1241 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int64_t, TYPE_SFIXED64)
1242 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT)
1243 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE)
1244
1245 #undef READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE
1246
1247 template <typename CType, enum WireFormatLite::FieldType DeclaredType>
1248 bool WireFormatLite::ReadPackedPrimitiveNoInline(io::CodedInputStream* input,
1249 RepeatedField<CType>* values) {
1250 return ReadPackedPrimitive<CType, DeclaredType>(input, values);
1251 }
1252
1253
1254 template <typename MessageType>
ReadGroup(int field_number,io::CodedInputStream * input,MessageType * value)1255 inline bool WireFormatLite::ReadGroup(int field_number,
1256 io::CodedInputStream* input,
1257 MessageType* value) {
1258 if (!input->IncrementRecursionDepth()) return false;
1259 if (!value->MergePartialFromCodedStream(input)) return false;
1260 input->UnsafeDecrementRecursionDepth();
1261 // Make sure the last thing read was an end tag for this group.
1262 if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) {
1263 return false;
1264 }
1265 return true;
1266 }
1267 template <typename MessageType>
ReadMessage(io::CodedInputStream * input,MessageType * value)1268 inline bool WireFormatLite::ReadMessage(io::CodedInputStream* input,
1269 MessageType* value) {
1270 int length;
1271 if (!input->ReadVarintSizeAsInt(&length)) return false;
1272 std::pair<io::CodedInputStream::Limit, int> p =
1273 input->IncrementRecursionDepthAndPushLimit(length);
1274 if (p.second < 0 || !value->MergePartialFromCodedStream(input)) return false;
1275 // Make sure that parsing stopped when the limit was hit, not at an endgroup
1276 // tag.
1277 return input->DecrementRecursionDepthAndPopLimit(p.first);
1278 }
1279
1280 // ===================================================================
1281
WriteTag(int field_number,WireType type,io::CodedOutputStream * output)1282 inline void WireFormatLite::WriteTag(int field_number, WireType type,
1283 io::CodedOutputStream* output) {
1284 output->WriteTag(MakeTag(field_number, type));
1285 }
1286
WriteInt32NoTag(int32_t value,io::CodedOutputStream * output)1287 inline void WireFormatLite::WriteInt32NoTag(int32_t value,
1288 io::CodedOutputStream* output) {
1289 output->WriteVarint32SignExtended(value);
1290 }
WriteInt64NoTag(int64_t value,io::CodedOutputStream * output)1291 inline void WireFormatLite::WriteInt64NoTag(int64_t value,
1292 io::CodedOutputStream* output) {
1293 output->WriteVarint64(static_cast<uint64_t>(value));
1294 }
WriteUInt32NoTag(uint32_t value,io::CodedOutputStream * output)1295 inline void WireFormatLite::WriteUInt32NoTag(uint32_t value,
1296 io::CodedOutputStream* output) {
1297 output->WriteVarint32(value);
1298 }
WriteUInt64NoTag(uint64_t value,io::CodedOutputStream * output)1299 inline void WireFormatLite::WriteUInt64NoTag(uint64_t value,
1300 io::CodedOutputStream* output) {
1301 output->WriteVarint64(value);
1302 }
WriteSInt32NoTag(int32_t value,io::CodedOutputStream * output)1303 inline void WireFormatLite::WriteSInt32NoTag(int32_t value,
1304 io::CodedOutputStream* output) {
1305 output->WriteVarint32(ZigZagEncode32(value));
1306 }
WriteSInt64NoTag(int64_t value,io::CodedOutputStream * output)1307 inline void WireFormatLite::WriteSInt64NoTag(int64_t value,
1308 io::CodedOutputStream* output) {
1309 output->WriteVarint64(ZigZagEncode64(value));
1310 }
WriteFixed32NoTag(uint32_t value,io::CodedOutputStream * output)1311 inline void WireFormatLite::WriteFixed32NoTag(uint32_t value,
1312 io::CodedOutputStream* output) {
1313 output->WriteLittleEndian32(value);
1314 }
WriteFixed64NoTag(uint64_t value,io::CodedOutputStream * output)1315 inline void WireFormatLite::WriteFixed64NoTag(uint64_t value,
1316 io::CodedOutputStream* output) {
1317 output->WriteLittleEndian64(value);
1318 }
WriteSFixed32NoTag(int32_t value,io::CodedOutputStream * output)1319 inline void WireFormatLite::WriteSFixed32NoTag(int32_t value,
1320 io::CodedOutputStream* output) {
1321 output->WriteLittleEndian32(static_cast<uint32_t>(value));
1322 }
WriteSFixed64NoTag(int64_t value,io::CodedOutputStream * output)1323 inline void WireFormatLite::WriteSFixed64NoTag(int64_t value,
1324 io::CodedOutputStream* output) {
1325 output->WriteLittleEndian64(static_cast<uint64_t>(value));
1326 }
WriteFloatNoTag(float value,io::CodedOutputStream * output)1327 inline void WireFormatLite::WriteFloatNoTag(float value,
1328 io::CodedOutputStream* output) {
1329 output->WriteLittleEndian32(EncodeFloat(value));
1330 }
WriteDoubleNoTag(double value,io::CodedOutputStream * output)1331 inline void WireFormatLite::WriteDoubleNoTag(double value,
1332 io::CodedOutputStream* output) {
1333 output->WriteLittleEndian64(EncodeDouble(value));
1334 }
WriteBoolNoTag(bool value,io::CodedOutputStream * output)1335 inline void WireFormatLite::WriteBoolNoTag(bool value,
1336 io::CodedOutputStream* output) {
1337 output->WriteVarint32(value ? 1 : 0);
1338 }
WriteEnumNoTag(int value,io::CodedOutputStream * output)1339 inline void WireFormatLite::WriteEnumNoTag(int value,
1340 io::CodedOutputStream* output) {
1341 output->WriteVarint32SignExtended(value);
1342 }
1343
1344 // See comment on ReadGroupNoVirtual to understand the need for this template
1345 // parameter name.
1346 template <typename MessageType_WorkAroundCppLookupDefect>
WriteGroupNoVirtual(int field_number,const MessageType_WorkAroundCppLookupDefect & value,io::CodedOutputStream * output)1347 inline void WireFormatLite::WriteGroupNoVirtual(
1348 int field_number, const MessageType_WorkAroundCppLookupDefect& value,
1349 io::CodedOutputStream* output) {
1350 WriteTag(field_number, WIRETYPE_START_GROUP, output);
1351 value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output);
1352 WriteTag(field_number, WIRETYPE_END_GROUP, output);
1353 }
1354 template <typename MessageType_WorkAroundCppLookupDefect>
WriteMessageNoVirtual(int field_number,const MessageType_WorkAroundCppLookupDefect & value,io::CodedOutputStream * output)1355 inline void WireFormatLite::WriteMessageNoVirtual(
1356 int field_number, const MessageType_WorkAroundCppLookupDefect& value,
1357 io::CodedOutputStream* output) {
1358 WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
1359 output->WriteVarint32(
1360 value.MessageType_WorkAroundCppLookupDefect::GetCachedSize());
1361 value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output);
1362 }
1363
1364 // ===================================================================
1365
WriteTagToArray(int field_number,WireType type,uint8_t * target)1366 inline uint8_t* WireFormatLite::WriteTagToArray(int field_number, WireType type,
1367 uint8_t* target) {
1368 return io::CodedOutputStream::WriteTagToArray(MakeTag(field_number, type),
1369 target);
1370 }
1371
WriteInt32NoTagToArray(int32_t value,uint8_t * target)1372 inline uint8_t* WireFormatLite::WriteInt32NoTagToArray(int32_t value,
1373 uint8_t* target) {
1374 return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
1375 }
WriteInt64NoTagToArray(int64_t value,uint8_t * target)1376 inline uint8_t* WireFormatLite::WriteInt64NoTagToArray(int64_t value,
1377 uint8_t* target) {
1378 return io::CodedOutputStream::WriteVarint64ToArray(
1379 static_cast<uint64_t>(value), target);
1380 }
WriteUInt32NoTagToArray(uint32_t value,uint8_t * target)1381 inline uint8_t* WireFormatLite::WriteUInt32NoTagToArray(uint32_t value,
1382 uint8_t* target) {
1383 return io::CodedOutputStream::WriteVarint32ToArray(value, target);
1384 }
WriteUInt64NoTagToArray(uint64_t value,uint8_t * target)1385 inline uint8_t* WireFormatLite::WriteUInt64NoTagToArray(uint64_t value,
1386 uint8_t* target) {
1387 return io::CodedOutputStream::WriteVarint64ToArray(value, target);
1388 }
WriteSInt32NoTagToArray(int32_t value,uint8_t * target)1389 inline uint8_t* WireFormatLite::WriteSInt32NoTagToArray(int32_t value,
1390 uint8_t* target) {
1391 return io::CodedOutputStream::WriteVarint32ToArray(ZigZagEncode32(value),
1392 target);
1393 }
WriteSInt64NoTagToArray(int64_t value,uint8_t * target)1394 inline uint8_t* WireFormatLite::WriteSInt64NoTagToArray(int64_t value,
1395 uint8_t* target) {
1396 return io::CodedOutputStream::WriteVarint64ToArray(ZigZagEncode64(value),
1397 target);
1398 }
WriteFixed32NoTagToArray(uint32_t value,uint8_t * target)1399 inline uint8_t* WireFormatLite::WriteFixed32NoTagToArray(uint32_t value,
1400 uint8_t* target) {
1401 return io::CodedOutputStream::WriteLittleEndian32ToArray(value, target);
1402 }
WriteFixed64NoTagToArray(uint64_t value,uint8_t * target)1403 inline uint8_t* WireFormatLite::WriteFixed64NoTagToArray(uint64_t value,
1404 uint8_t* target) {
1405 return io::CodedOutputStream::WriteLittleEndian64ToArray(value, target);
1406 }
WriteSFixed32NoTagToArray(int32_t value,uint8_t * target)1407 inline uint8_t* WireFormatLite::WriteSFixed32NoTagToArray(int32_t value,
1408 uint8_t* target) {
1409 return io::CodedOutputStream::WriteLittleEndian32ToArray(
1410 static_cast<uint32_t>(value), target);
1411 }
WriteSFixed64NoTagToArray(int64_t value,uint8_t * target)1412 inline uint8_t* WireFormatLite::WriteSFixed64NoTagToArray(int64_t value,
1413 uint8_t* target) {
1414 return io::CodedOutputStream::WriteLittleEndian64ToArray(
1415 static_cast<uint64_t>(value), target);
1416 }
WriteFloatNoTagToArray(float value,uint8_t * target)1417 inline uint8_t* WireFormatLite::WriteFloatNoTagToArray(float value,
1418 uint8_t* target) {
1419 return io::CodedOutputStream::WriteLittleEndian32ToArray(EncodeFloat(value),
1420 target);
1421 }
WriteDoubleNoTagToArray(double value,uint8_t * target)1422 inline uint8_t* WireFormatLite::WriteDoubleNoTagToArray(double value,
1423 uint8_t* target) {
1424 return io::CodedOutputStream::WriteLittleEndian64ToArray(EncodeDouble(value),
1425 target);
1426 }
WriteBoolNoTagToArray(bool value,uint8_t * target)1427 inline uint8_t* WireFormatLite::WriteBoolNoTagToArray(bool value,
1428 uint8_t* target) {
1429 return io::CodedOutputStream::WriteVarint32ToArray(value ? 1 : 0, target);
1430 }
WriteEnumNoTagToArray(int value,uint8_t * target)1431 inline uint8_t* WireFormatLite::WriteEnumNoTagToArray(int value,
1432 uint8_t* target) {
1433 return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
1434 }
1435
1436 template <typename T>
WritePrimitiveNoTagToArray(const RepeatedField<T> & value,uint8_t * (* Writer)(T,uint8_t *),uint8_t * target)1437 inline uint8_t* WireFormatLite::WritePrimitiveNoTagToArray(
1438 const RepeatedField<T>& value, uint8_t* (*Writer)(T, uint8_t*),
1439 uint8_t* target) {
1440 const int n = value.size();
1441 GOOGLE_DCHECK_GT(n, 0);
1442
1443 const T* ii = value.data();
1444 int i = 0;
1445 do {
1446 target = Writer(ii[i], target);
1447 } while (++i < n);
1448
1449 return target;
1450 }
1451
1452 template <typename T>
WriteFixedNoTagToArray(const RepeatedField<T> & value,uint8_t * (* Writer)(T,uint8_t *),uint8_t * target)1453 inline uint8_t* WireFormatLite::WriteFixedNoTagToArray(
1454 const RepeatedField<T>& value, uint8_t* (*Writer)(T, uint8_t*),
1455 uint8_t* target) {
1456 #if defined(PROTOBUF_LITTLE_ENDIAN)
1457 (void)Writer;
1458
1459 const int n = value.size();
1460 GOOGLE_DCHECK_GT(n, 0);
1461
1462 const T* ii = value.data();
1463 const int bytes = n * static_cast<int>(sizeof(ii[0]));
1464 memcpy(target, ii, static_cast<size_t>(bytes));
1465 return target + bytes;
1466 #else
1467 return WritePrimitiveNoTagToArray(value, Writer, target);
1468 #endif
1469 }
1470
WriteInt32NoTagToArray(const RepeatedField<int32_t> & value,uint8_t * target)1471 inline uint8_t* WireFormatLite::WriteInt32NoTagToArray(
1472 const RepeatedField<int32_t>& value, uint8_t* target) {
1473 return WritePrimitiveNoTagToArray(value, WriteInt32NoTagToArray, target);
1474 }
WriteInt64NoTagToArray(const RepeatedField<int64_t> & value,uint8_t * target)1475 inline uint8_t* WireFormatLite::WriteInt64NoTagToArray(
1476 const RepeatedField<int64_t>& value, uint8_t* target) {
1477 return WritePrimitiveNoTagToArray(value, WriteInt64NoTagToArray, target);
1478 }
WriteUInt32NoTagToArray(const RepeatedField<uint32_t> & value,uint8_t * target)1479 inline uint8_t* WireFormatLite::WriteUInt32NoTagToArray(
1480 const RepeatedField<uint32_t>& value, uint8_t* target) {
1481 return WritePrimitiveNoTagToArray(value, WriteUInt32NoTagToArray, target);
1482 }
WriteUInt64NoTagToArray(const RepeatedField<uint64_t> & value,uint8_t * target)1483 inline uint8_t* WireFormatLite::WriteUInt64NoTagToArray(
1484 const RepeatedField<uint64_t>& value, uint8_t* target) {
1485 return WritePrimitiveNoTagToArray(value, WriteUInt64NoTagToArray, target);
1486 }
WriteSInt32NoTagToArray(const RepeatedField<int32_t> & value,uint8_t * target)1487 inline uint8_t* WireFormatLite::WriteSInt32NoTagToArray(
1488 const RepeatedField<int32_t>& value, uint8_t* target) {
1489 return WritePrimitiveNoTagToArray(value, WriteSInt32NoTagToArray, target);
1490 }
WriteSInt64NoTagToArray(const RepeatedField<int64_t> & value,uint8_t * target)1491 inline uint8_t* WireFormatLite::WriteSInt64NoTagToArray(
1492 const RepeatedField<int64_t>& value, uint8_t* target) {
1493 return WritePrimitiveNoTagToArray(value, WriteSInt64NoTagToArray, target);
1494 }
WriteFixed32NoTagToArray(const RepeatedField<uint32_t> & value,uint8_t * target)1495 inline uint8_t* WireFormatLite::WriteFixed32NoTagToArray(
1496 const RepeatedField<uint32_t>& value, uint8_t* target) {
1497 return WriteFixedNoTagToArray(value, WriteFixed32NoTagToArray, target);
1498 }
WriteFixed64NoTagToArray(const RepeatedField<uint64_t> & value,uint8_t * target)1499 inline uint8_t* WireFormatLite::WriteFixed64NoTagToArray(
1500 const RepeatedField<uint64_t>& value, uint8_t* target) {
1501 return WriteFixedNoTagToArray(value, WriteFixed64NoTagToArray, target);
1502 }
WriteSFixed32NoTagToArray(const RepeatedField<int32_t> & value,uint8_t * target)1503 inline uint8_t* WireFormatLite::WriteSFixed32NoTagToArray(
1504 const RepeatedField<int32_t>& value, uint8_t* target) {
1505 return WriteFixedNoTagToArray(value, WriteSFixed32NoTagToArray, target);
1506 }
WriteSFixed64NoTagToArray(const RepeatedField<int64_t> & value,uint8_t * target)1507 inline uint8_t* WireFormatLite::WriteSFixed64NoTagToArray(
1508 const RepeatedField<int64_t>& value, uint8_t* target) {
1509 return WriteFixedNoTagToArray(value, WriteSFixed64NoTagToArray, target);
1510 }
WriteFloatNoTagToArray(const RepeatedField<float> & value,uint8_t * target)1511 inline uint8_t* WireFormatLite::WriteFloatNoTagToArray(
1512 const RepeatedField<float>& value, uint8_t* target) {
1513 return WriteFixedNoTagToArray(value, WriteFloatNoTagToArray, target);
1514 }
WriteDoubleNoTagToArray(const RepeatedField<double> & value,uint8_t * target)1515 inline uint8_t* WireFormatLite::WriteDoubleNoTagToArray(
1516 const RepeatedField<double>& value, uint8_t* target) {
1517 return WriteFixedNoTagToArray(value, WriteDoubleNoTagToArray, target);
1518 }
WriteBoolNoTagToArray(const RepeatedField<bool> & value,uint8_t * target)1519 inline uint8_t* WireFormatLite::WriteBoolNoTagToArray(
1520 const RepeatedField<bool>& value, uint8_t* target) {
1521 return WritePrimitiveNoTagToArray(value, WriteBoolNoTagToArray, target);
1522 }
WriteEnumNoTagToArray(const RepeatedField<int> & value,uint8_t * target)1523 inline uint8_t* WireFormatLite::WriteEnumNoTagToArray(
1524 const RepeatedField<int>& value, uint8_t* target) {
1525 return WritePrimitiveNoTagToArray(value, WriteEnumNoTagToArray, target);
1526 }
1527
WriteInt32ToArray(int field_number,int32_t value,uint8_t * target)1528 inline uint8_t* WireFormatLite::WriteInt32ToArray(int field_number,
1529 int32_t value,
1530 uint8_t* target) {
1531 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
1532 return WriteInt32NoTagToArray(value, target);
1533 }
WriteInt64ToArray(int field_number,int64_t value,uint8_t * target)1534 inline uint8_t* WireFormatLite::WriteInt64ToArray(int field_number,
1535 int64_t value,
1536 uint8_t* target) {
1537 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
1538 return WriteInt64NoTagToArray(value, target);
1539 }
WriteUInt32ToArray(int field_number,uint32_t value,uint8_t * target)1540 inline uint8_t* WireFormatLite::WriteUInt32ToArray(int field_number,
1541 uint32_t value,
1542 uint8_t* target) {
1543 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
1544 return WriteUInt32NoTagToArray(value, target);
1545 }
WriteUInt64ToArray(int field_number,uint64_t value,uint8_t * target)1546 inline uint8_t* WireFormatLite::WriteUInt64ToArray(int field_number,
1547 uint64_t value,
1548 uint8_t* target) {
1549 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
1550 return WriteUInt64NoTagToArray(value, target);
1551 }
WriteSInt32ToArray(int field_number,int32_t value,uint8_t * target)1552 inline uint8_t* WireFormatLite::WriteSInt32ToArray(int field_number,
1553 int32_t value,
1554 uint8_t* target) {
1555 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
1556 return WriteSInt32NoTagToArray(value, target);
1557 }
WriteSInt64ToArray(int field_number,int64_t value,uint8_t * target)1558 inline uint8_t* WireFormatLite::WriteSInt64ToArray(int field_number,
1559 int64_t value,
1560 uint8_t* target) {
1561 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
1562 return WriteSInt64NoTagToArray(value, target);
1563 }
WriteFixed32ToArray(int field_number,uint32_t value,uint8_t * target)1564 inline uint8_t* WireFormatLite::WriteFixed32ToArray(int field_number,
1565 uint32_t value,
1566 uint8_t* target) {
1567 target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
1568 return WriteFixed32NoTagToArray(value, target);
1569 }
WriteFixed64ToArray(int field_number,uint64_t value,uint8_t * target)1570 inline uint8_t* WireFormatLite::WriteFixed64ToArray(int field_number,
1571 uint64_t value,
1572 uint8_t* target) {
1573 target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
1574 return WriteFixed64NoTagToArray(value, target);
1575 }
WriteSFixed32ToArray(int field_number,int32_t value,uint8_t * target)1576 inline uint8_t* WireFormatLite::WriteSFixed32ToArray(int field_number,
1577 int32_t value,
1578 uint8_t* target) {
1579 target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
1580 return WriteSFixed32NoTagToArray(value, target);
1581 }
WriteSFixed64ToArray(int field_number,int64_t value,uint8_t * target)1582 inline uint8_t* WireFormatLite::WriteSFixed64ToArray(int field_number,
1583 int64_t value,
1584 uint8_t* target) {
1585 target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
1586 return WriteSFixed64NoTagToArray(value, target);
1587 }
WriteFloatToArray(int field_number,float value,uint8_t * target)1588 inline uint8_t* WireFormatLite::WriteFloatToArray(int field_number, float value,
1589 uint8_t* target) {
1590 target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
1591 return WriteFloatNoTagToArray(value, target);
1592 }
WriteDoubleToArray(int field_number,double value,uint8_t * target)1593 inline uint8_t* WireFormatLite::WriteDoubleToArray(int field_number,
1594 double value,
1595 uint8_t* target) {
1596 target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
1597 return WriteDoubleNoTagToArray(value, target);
1598 }
WriteBoolToArray(int field_number,bool value,uint8_t * target)1599 inline uint8_t* WireFormatLite::WriteBoolToArray(int field_number, bool value,
1600 uint8_t* target) {
1601 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
1602 return WriteBoolNoTagToArray(value, target);
1603 }
WriteEnumToArray(int field_number,int value,uint8_t * target)1604 inline uint8_t* WireFormatLite::WriteEnumToArray(int field_number, int value,
1605 uint8_t* target) {
1606 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
1607 return WriteEnumNoTagToArray(value, target);
1608 }
1609
1610 template <typename T>
WritePrimitiveToArray(int field_number,const RepeatedField<T> & value,uint8_t * (* Writer)(int,T,uint8_t *),uint8_t * target)1611 inline uint8_t* WireFormatLite::WritePrimitiveToArray(
1612 int field_number, const RepeatedField<T>& value,
1613 uint8_t* (*Writer)(int, T, uint8_t*), uint8_t* target) {
1614 const int n = value.size();
1615 if (n == 0) {
1616 return target;
1617 }
1618
1619 const T* ii = value.data();
1620 int i = 0;
1621 do {
1622 target = Writer(field_number, ii[i], target);
1623 } while (++i < n);
1624
1625 return target;
1626 }
1627
WriteInt32ToArray(int field_number,const RepeatedField<int32_t> & value,uint8_t * target)1628 inline uint8_t* WireFormatLite::WriteInt32ToArray(
1629 int field_number, const RepeatedField<int32_t>& value, uint8_t* target) {
1630 return WritePrimitiveToArray(field_number, value, WriteInt32ToArray, target);
1631 }
WriteInt64ToArray(int field_number,const RepeatedField<int64_t> & value,uint8_t * target)1632 inline uint8_t* WireFormatLite::WriteInt64ToArray(
1633 int field_number, const RepeatedField<int64_t>& value, uint8_t* target) {
1634 return WritePrimitiveToArray(field_number, value, WriteInt64ToArray, target);
1635 }
WriteUInt32ToArray(int field_number,const RepeatedField<uint32_t> & value,uint8_t * target)1636 inline uint8_t* WireFormatLite::WriteUInt32ToArray(
1637 int field_number, const RepeatedField<uint32_t>& value, uint8_t* target) {
1638 return WritePrimitiveToArray(field_number, value, WriteUInt32ToArray, target);
1639 }
WriteUInt64ToArray(int field_number,const RepeatedField<uint64_t> & value,uint8_t * target)1640 inline uint8_t* WireFormatLite::WriteUInt64ToArray(
1641 int field_number, const RepeatedField<uint64_t>& value, uint8_t* target) {
1642 return WritePrimitiveToArray(field_number, value, WriteUInt64ToArray, target);
1643 }
WriteSInt32ToArray(int field_number,const RepeatedField<int32_t> & value,uint8_t * target)1644 inline uint8_t* WireFormatLite::WriteSInt32ToArray(
1645 int field_number, const RepeatedField<int32_t>& value, uint8_t* target) {
1646 return WritePrimitiveToArray(field_number, value, WriteSInt32ToArray, target);
1647 }
WriteSInt64ToArray(int field_number,const RepeatedField<int64_t> & value,uint8_t * target)1648 inline uint8_t* WireFormatLite::WriteSInt64ToArray(
1649 int field_number, const RepeatedField<int64_t>& value, uint8_t* target) {
1650 return WritePrimitiveToArray(field_number, value, WriteSInt64ToArray, target);
1651 }
WriteFixed32ToArray(int field_number,const RepeatedField<uint32_t> & value,uint8_t * target)1652 inline uint8_t* WireFormatLite::WriteFixed32ToArray(
1653 int field_number, const RepeatedField<uint32_t>& value, uint8_t* target) {
1654 return WritePrimitiveToArray(field_number, value, WriteFixed32ToArray,
1655 target);
1656 }
WriteFixed64ToArray(int field_number,const RepeatedField<uint64_t> & value,uint8_t * target)1657 inline uint8_t* WireFormatLite::WriteFixed64ToArray(
1658 int field_number, const RepeatedField<uint64_t>& value, uint8_t* target) {
1659 return WritePrimitiveToArray(field_number, value, WriteFixed64ToArray,
1660 target);
1661 }
WriteSFixed32ToArray(int field_number,const RepeatedField<int32_t> & value,uint8_t * target)1662 inline uint8_t* WireFormatLite::WriteSFixed32ToArray(
1663 int field_number, const RepeatedField<int32_t>& value, uint8_t* target) {
1664 return WritePrimitiveToArray(field_number, value, WriteSFixed32ToArray,
1665 target);
1666 }
WriteSFixed64ToArray(int field_number,const RepeatedField<int64_t> & value,uint8_t * target)1667 inline uint8_t* WireFormatLite::WriteSFixed64ToArray(
1668 int field_number, const RepeatedField<int64_t>& value, uint8_t* target) {
1669 return WritePrimitiveToArray(field_number, value, WriteSFixed64ToArray,
1670 target);
1671 }
WriteFloatToArray(int field_number,const RepeatedField<float> & value,uint8_t * target)1672 inline uint8_t* WireFormatLite::WriteFloatToArray(
1673 int field_number, const RepeatedField<float>& value, uint8_t* target) {
1674 return WritePrimitiveToArray(field_number, value, WriteFloatToArray, target);
1675 }
WriteDoubleToArray(int field_number,const RepeatedField<double> & value,uint8_t * target)1676 inline uint8_t* WireFormatLite::WriteDoubleToArray(
1677 int field_number, const RepeatedField<double>& value, uint8_t* target) {
1678 return WritePrimitiveToArray(field_number, value, WriteDoubleToArray, target);
1679 }
WriteBoolToArray(int field_number,const RepeatedField<bool> & value,uint8_t * target)1680 inline uint8_t* WireFormatLite::WriteBoolToArray(
1681 int field_number, const RepeatedField<bool>& value, uint8_t* target) {
1682 return WritePrimitiveToArray(field_number, value, WriteBoolToArray, target);
1683 }
WriteEnumToArray(int field_number,const RepeatedField<int> & value,uint8_t * target)1684 inline uint8_t* WireFormatLite::WriteEnumToArray(
1685 int field_number, const RepeatedField<int>& value, uint8_t* target) {
1686 return WritePrimitiveToArray(field_number, value, WriteEnumToArray, target);
1687 }
WriteStringToArray(int field_number,const std::string & value,uint8_t * target)1688 inline uint8_t* WireFormatLite::WriteStringToArray(int field_number,
1689 const std::string& value,
1690 uint8_t* target) {
1691 // String is for UTF-8 text only
1692 // WARNING: In wire_format.cc, both strings and bytes are handled by
1693 // WriteString() to avoid code duplication. If the implementations become
1694 // different, you will need to update that usage.
1695 target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
1696 return io::CodedOutputStream::WriteStringWithSizeToArray(value, target);
1697 }
WriteBytesToArray(int field_number,const std::string & value,uint8_t * target)1698 inline uint8_t* WireFormatLite::WriteBytesToArray(int field_number,
1699 const std::string& value,
1700 uint8_t* target) {
1701 target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
1702 return io::CodedOutputStream::WriteStringWithSizeToArray(value, target);
1703 }
1704
1705
1706 template <typename MessageType>
InternalWriteGroup(int field_number,const MessageType & value,uint8_t * target,io::EpsCopyOutputStream * stream)1707 inline uint8_t* WireFormatLite::InternalWriteGroup(
1708 int field_number, const MessageType& value, uint8_t* target,
1709 io::EpsCopyOutputStream* stream) {
1710 target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
1711 target = value._InternalSerialize(target, stream);
1712 target = stream->EnsureSpace(target);
1713 return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
1714 }
1715 template <typename MessageType>
InternalWriteMessage(int field_number,const MessageType & value,uint8_t * target,io::EpsCopyOutputStream * stream)1716 inline uint8_t* WireFormatLite::InternalWriteMessage(
1717 int field_number, const MessageType& value, uint8_t* target,
1718 io::EpsCopyOutputStream* stream) {
1719 target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
1720 target = io::CodedOutputStream::WriteVarint32ToArrayOutOfLine(
1721 static_cast<uint32_t>(value.GetCachedSize()), target);
1722 return value._InternalSerialize(target, stream);
1723 }
1724
1725 // See comment on ReadGroupNoVirtual to understand the need for this template
1726 // parameter name.
1727 template <typename MessageType_WorkAroundCppLookupDefect>
InternalWriteGroupNoVirtualToArray(int field_number,const MessageType_WorkAroundCppLookupDefect & value,uint8_t * target)1728 inline uint8_t* WireFormatLite::InternalWriteGroupNoVirtualToArray(
1729 int field_number, const MessageType_WorkAroundCppLookupDefect& value,
1730 uint8_t* target) {
1731 target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
1732 target = value.MessageType_WorkAroundCppLookupDefect::
1733 SerializeWithCachedSizesToArray(target);
1734 return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
1735 }
1736 template <typename MessageType_WorkAroundCppLookupDefect>
InternalWriteMessageNoVirtualToArray(int field_number,const MessageType_WorkAroundCppLookupDefect & value,uint8_t * target)1737 inline uint8_t* WireFormatLite::InternalWriteMessageNoVirtualToArray(
1738 int field_number, const MessageType_WorkAroundCppLookupDefect& value,
1739 uint8_t* target) {
1740 target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
1741 target = io::CodedOutputStream::WriteVarint32ToArray(
1742 static_cast<uint32_t>(
1743 value.MessageType_WorkAroundCppLookupDefect::GetCachedSize()),
1744 target);
1745 return value
1746 .MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizesToArray(
1747 target);
1748 }
1749
1750 // ===================================================================
1751
Int32Size(int32_t value)1752 inline size_t WireFormatLite::Int32Size(int32_t value) {
1753 return io::CodedOutputStream::VarintSize32SignExtended(value);
1754 }
Int64Size(int64_t value)1755 inline size_t WireFormatLite::Int64Size(int64_t value) {
1756 return io::CodedOutputStream::VarintSize64(static_cast<uint64_t>(value));
1757 }
UInt32Size(uint32_t value)1758 inline size_t WireFormatLite::UInt32Size(uint32_t value) {
1759 return io::CodedOutputStream::VarintSize32(value);
1760 }
UInt64Size(uint64_t value)1761 inline size_t WireFormatLite::UInt64Size(uint64_t value) {
1762 return io::CodedOutputStream::VarintSize64(value);
1763 }
SInt32Size(int32_t value)1764 inline size_t WireFormatLite::SInt32Size(int32_t value) {
1765 return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value));
1766 }
SInt64Size(int64_t value)1767 inline size_t WireFormatLite::SInt64Size(int64_t value) {
1768 return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value));
1769 }
EnumSize(int value)1770 inline size_t WireFormatLite::EnumSize(int value) {
1771 return io::CodedOutputStream::VarintSize32SignExtended(value);
1772 }
Int32SizePlusOne(int32_t value)1773 inline size_t WireFormatLite::Int32SizePlusOne(int32_t value) {
1774 return io::CodedOutputStream::VarintSize32SignExtendedPlusOne(value);
1775 }
Int64SizePlusOne(int64_t value)1776 inline size_t WireFormatLite::Int64SizePlusOne(int64_t value) {
1777 return io::CodedOutputStream::VarintSize64PlusOne(
1778 static_cast<uint64_t>(value));
1779 }
UInt32SizePlusOne(uint32_t value)1780 inline size_t WireFormatLite::UInt32SizePlusOne(uint32_t value) {
1781 return io::CodedOutputStream::VarintSize32PlusOne(value);
1782 }
UInt64SizePlusOne(uint64_t value)1783 inline size_t WireFormatLite::UInt64SizePlusOne(uint64_t value) {
1784 return io::CodedOutputStream::VarintSize64PlusOne(value);
1785 }
SInt32SizePlusOne(int32_t value)1786 inline size_t WireFormatLite::SInt32SizePlusOne(int32_t value) {
1787 return io::CodedOutputStream::VarintSize32PlusOne(ZigZagEncode32(value));
1788 }
SInt64SizePlusOne(int64_t value)1789 inline size_t WireFormatLite::SInt64SizePlusOne(int64_t value) {
1790 return io::CodedOutputStream::VarintSize64PlusOne(ZigZagEncode64(value));
1791 }
EnumSizePlusOne(int value)1792 inline size_t WireFormatLite::EnumSizePlusOne(int value) {
1793 return io::CodedOutputStream::VarintSize32SignExtendedPlusOne(value);
1794 }
1795
StringSize(const std::string & value)1796 inline size_t WireFormatLite::StringSize(const std::string& value) {
1797 return LengthDelimitedSize(value.size());
1798 }
BytesSize(const std::string & value)1799 inline size_t WireFormatLite::BytesSize(const std::string& value) {
1800 return LengthDelimitedSize(value.size());
1801 }
1802
1803
1804 template <typename MessageType>
GroupSize(const MessageType & value)1805 inline size_t WireFormatLite::GroupSize(const MessageType& value) {
1806 return value.ByteSizeLong();
1807 }
1808 template <typename MessageType>
MessageSize(const MessageType & value)1809 inline size_t WireFormatLite::MessageSize(const MessageType& value) {
1810 return LengthDelimitedSize(value.ByteSizeLong());
1811 }
1812
1813 // See comment on ReadGroupNoVirtual to understand the need for this template
1814 // parameter name.
1815 template <typename MessageType_WorkAroundCppLookupDefect>
GroupSizeNoVirtual(const MessageType_WorkAroundCppLookupDefect & value)1816 inline size_t WireFormatLite::GroupSizeNoVirtual(
1817 const MessageType_WorkAroundCppLookupDefect& value) {
1818 return value.MessageType_WorkAroundCppLookupDefect::ByteSizeLong();
1819 }
1820 template <typename MessageType_WorkAroundCppLookupDefect>
MessageSizeNoVirtual(const MessageType_WorkAroundCppLookupDefect & value)1821 inline size_t WireFormatLite::MessageSizeNoVirtual(
1822 const MessageType_WorkAroundCppLookupDefect& value) {
1823 return LengthDelimitedSize(
1824 value.MessageType_WorkAroundCppLookupDefect::ByteSizeLong());
1825 }
1826
LengthDelimitedSize(size_t length)1827 inline size_t WireFormatLite::LengthDelimitedSize(size_t length) {
1828 // The static_cast here prevents an error in certain compiler configurations
1829 // but is not technically correct--if length is too large to fit in a uint32_t
1830 // then it will be silently truncated. We will need to fix this if we ever
1831 // decide to start supporting serialized messages greater than 2 GiB in size.
1832 return length +
1833 io::CodedOutputStream::VarintSize32(static_cast<uint32_t>(length));
1834 }
1835
1836 template <typename MS>
ParseMessageSetItemImpl(io::CodedInputStream * input,MS ms)1837 bool ParseMessageSetItemImpl(io::CodedInputStream* input, MS ms) {
1838 // This method parses a group which should contain two fields:
1839 // required int32 type_id = 2;
1840 // required data message = 3;
1841
1842 uint32_t last_type_id = 0;
1843
1844 // If we see message data before the type_id, we'll append it to this so
1845 // we can parse it later.
1846 std::string message_data;
1847
1848 while (true) {
1849 const uint32_t tag = input->ReadTagNoLastTag();
1850 if (tag == 0) return false;
1851
1852 switch (tag) {
1853 case WireFormatLite::kMessageSetTypeIdTag: {
1854 uint32_t type_id;
1855 if (!input->ReadVarint32(&type_id)) return false;
1856 last_type_id = type_id;
1857
1858 if (!message_data.empty()) {
1859 // We saw some message data before the type_id. Have to parse it
1860 // now.
1861 io::CodedInputStream sub_input(
1862 reinterpret_cast<const uint8_t*>(message_data.data()),
1863 static_cast<int>(message_data.size()));
1864 sub_input.SetRecursionLimit(input->RecursionBudget());
1865 if (!ms.ParseField(last_type_id, &sub_input)) {
1866 return false;
1867 }
1868 message_data.clear();
1869 }
1870
1871 break;
1872 }
1873
1874 case WireFormatLite::kMessageSetMessageTag: {
1875 if (last_type_id == 0) {
1876 // We haven't seen a type_id yet. Append this data to message_data.
1877 uint32_t length;
1878 if (!input->ReadVarint32(&length)) return false;
1879 if (static_cast<int32_t>(length) < 0) return false;
1880 uint32_t size = static_cast<uint32_t>(
1881 length + io::CodedOutputStream::VarintSize32(length));
1882 message_data.resize(size);
1883 auto ptr = reinterpret_cast<uint8_t*>(&message_data[0]);
1884 ptr = io::CodedOutputStream::WriteVarint32ToArray(length, ptr);
1885 if (!input->ReadRaw(ptr, length)) return false;
1886 } else {
1887 // Already saw type_id, so we can parse this directly.
1888 if (!ms.ParseField(last_type_id, input)) {
1889 return false;
1890 }
1891 }
1892
1893 break;
1894 }
1895
1896 case WireFormatLite::kMessageSetItemEndTag: {
1897 return true;
1898 }
1899
1900 default: {
1901 if (!ms.SkipField(tag, input)) return false;
1902 }
1903 }
1904 }
1905 }
1906
1907 } // namespace internal
1908 } // namespace protobuf
1909 } // namespace google
1910
1911 #include <google/protobuf/port_undef.inc>
1912
1913 #endif // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__
1914