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