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

source code of include/google/protobuf/wire_format_lite.h