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