wire_format_lite_inl.h revision d0332953cda33fb4f8e24ebff9c49159b69c43d6
1// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc.  All rights reserved.
3// http://code.google.com/p/protobuf/
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//         wink@google.com (Wink Saville) (refactored from wire_format.h)
33//  Based on original Protocol Buffers design by
34//  Sanjay Ghemawat, Jeff Dean, and others.
35
36#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
37#define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
38
39#include <string>
40#include <google/protobuf/stubs/common.h>
41#include <google/protobuf/message_lite.h>
42#include <google/protobuf/repeated_field.h>
43#include <google/protobuf/wire_format_lite.h>
44#include <google/protobuf/generated_message_util.h>
45#include <google/protobuf/io/coded_stream.h>
46
47
48namespace google {
49namespace protobuf {
50namespace internal {
51
52// Implementation details of ReadPrimitive.
53
54template <>
55inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>(
56    io::CodedInputStream* input,
57    int32* value) {
58  uint32 temp;
59  if (!input->ReadVarint32(&temp)) return false;
60  *value = static_cast<int32>(temp);
61  return true;
62}
63template <>
64inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_INT64>(
65    io::CodedInputStream* input,
66    int64* value) {
67  uint64 temp;
68  if (!input->ReadVarint64(&temp)) return false;
69  *value = static_cast<int64>(temp);
70  return true;
71}
72template <>
73inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_UINT32>(
74    io::CodedInputStream* input,
75    uint32* value) {
76  return input->ReadVarint32(value);
77}
78template <>
79inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_UINT64>(
80    io::CodedInputStream* input,
81    uint64* value) {
82  return input->ReadVarint64(value);
83}
84template <>
85inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>(
86    io::CodedInputStream* input,
87    int32* value) {
88  uint32 temp;
89  if (!input->ReadVarint32(&temp)) return false;
90  *value = ZigZagDecode32(temp);
91  return true;
92}
93template <>
94inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SINT64>(
95    io::CodedInputStream* input,
96    int64* value) {
97  uint64 temp;
98  if (!input->ReadVarint64(&temp)) return false;
99  *value = ZigZagDecode64(temp);
100  return true;
101}
102template <>
103inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_FIXED32>(
104    io::CodedInputStream* input,
105    uint32* value) {
106  return input->ReadLittleEndian32(value);
107}
108template <>
109inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_FIXED64>(
110    io::CodedInputStream* input,
111    uint64* value) {
112  return input->ReadLittleEndian64(value);
113}
114template <>
115inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SFIXED32>(
116    io::CodedInputStream* input,
117    int32* value) {
118  uint32 temp;
119  if (!input->ReadLittleEndian32(&temp)) return false;
120  *value = static_cast<int32>(temp);
121  return true;
122}
123template <>
124inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SFIXED64>(
125    io::CodedInputStream* input,
126    int64* value) {
127  uint64 temp;
128  if (!input->ReadLittleEndian64(&temp)) return false;
129  *value = static_cast<int64>(temp);
130  return true;
131}
132template <>
133inline bool WireFormatLite::ReadPrimitive<float, WireFormatLite::TYPE_FLOAT>(
134    io::CodedInputStream* input,
135    float* value) {
136  uint32 temp;
137  if (!input->ReadLittleEndian32(&temp)) return false;
138  *value = DecodeFloat(temp);
139  return true;
140}
141template <>
142inline bool WireFormatLite::ReadPrimitive<double, WireFormatLite::TYPE_DOUBLE>(
143    io::CodedInputStream* input,
144    double* value) {
145  uint64 temp;
146  if (!input->ReadLittleEndian64(&temp)) return false;
147  *value = DecodeDouble(temp);
148  return true;
149}
150template <>
151inline bool WireFormatLite::ReadPrimitive<bool, WireFormatLite::TYPE_BOOL>(
152    io::CodedInputStream* input,
153    bool* value) {
154  uint32 temp;
155  if (!input->ReadVarint32(&temp)) return false;
156  *value = temp != 0;
157  return true;
158}
159template <>
160inline bool WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
161    io::CodedInputStream* input,
162    int* value) {
163  uint32 temp;
164  if (!input->ReadVarint32(&temp)) return false;
165  *value = static_cast<int>(temp);
166  return true;
167}
168
169template <>
170inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
171  uint32, WireFormatLite::TYPE_FIXED32>(
172    const uint8* buffer,
173    uint32* value) {
174  return io::CodedInputStream::ReadLittleEndian32FromArray(buffer, value);
175}
176template <>
177inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
178  uint64, WireFormatLite::TYPE_FIXED64>(
179    const uint8* buffer,
180    uint64* value) {
181  return io::CodedInputStream::ReadLittleEndian64FromArray(buffer, value);
182}
183template <>
184inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
185  int32, WireFormatLite::TYPE_SFIXED32>(
186    const uint8* buffer,
187    int32* value) {
188  uint32 temp;
189  buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp);
190  *value = static_cast<int32>(temp);
191  return buffer;
192}
193template <>
194inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
195  int64, WireFormatLite::TYPE_SFIXED64>(
196    const uint8* buffer,
197    int64* value) {
198  uint64 temp;
199  buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp);
200  *value = static_cast<int64>(temp);
201  return buffer;
202}
203template <>
204inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
205  float, WireFormatLite::TYPE_FLOAT>(
206    const uint8* buffer,
207    float* value) {
208  uint32 temp;
209  buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp);
210  *value = DecodeFloat(temp);
211  return buffer;
212}
213template <>
214inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
215  double, WireFormatLite::TYPE_DOUBLE>(
216    const uint8* buffer,
217    double* value) {
218  uint64 temp;
219  buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp);
220  *value = DecodeDouble(temp);
221  return buffer;
222}
223
224template <typename CType, enum WireFormatLite::FieldType DeclaredType>
225inline bool WireFormatLite::ReadRepeatedPrimitive(int tag_size,
226                                               uint32 tag,
227                                               io::CodedInputStream* input,
228                                               RepeatedField<CType>* values) {
229  CType value;
230  if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
231  values->Add(value);
232  int elements_already_reserved = values->Capacity() - values->size();
233  while (elements_already_reserved > 0 && input->ExpectTag(tag)) {
234    if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
235    values->AddAlreadyReserved(value);
236    elements_already_reserved--;
237  }
238  return true;
239}
240
241template <typename CType, enum WireFormatLite::FieldType DeclaredType>
242inline bool WireFormatLite::ReadRepeatedFixedSizePrimitive(
243    int tag_size,
244    uint32 tag,
245    io::CodedInputStream* input,
246    RepeatedField<CType>* values) {
247  GOOGLE_DCHECK_EQ(UInt32Size(tag), tag_size);
248  CType value;
249  if (!ReadPrimitive<CType, DeclaredType>(input, &value))
250    return false;
251  values->Add(value);
252
253  // For fixed size values, repeated values can be read more quickly by
254  // reading directly from a raw array.
255  //
256  // We can get a tight loop by only reading as many elements as can be
257  // added to the RepeatedField without having to do any resizing. Additionally,
258  // we only try to read as many elements as are available from the current
259  // buffer space. Doing so avoids having to perform boundary checks when
260  // reading the value: the maximum number of elements that can be read is
261  // known outside of the loop.
262  const void* void_pointer;
263  int size;
264  input->GetDirectBufferPointerInline(&void_pointer, &size);
265  if (size > 0) {
266    const uint8* buffer = reinterpret_cast<const uint8*>(void_pointer);
267    // The number of bytes each type occupies on the wire.
268    const int per_value_size = tag_size + sizeof(value);
269
270    int elements_available = min(values->Capacity() - values->size(),
271                                 size / per_value_size);
272    int num_read = 0;
273    while (num_read < elements_available &&
274           (buffer = io::CodedInputStream::ExpectTagFromArray(
275               buffer, tag)) != NULL) {
276      buffer = ReadPrimitiveFromArray<CType, DeclaredType>(buffer, &value);
277      values->AddAlreadyReserved(value);
278      ++num_read;
279    }
280    const int read_bytes = num_read * per_value_size;
281    if (read_bytes > 0) {
282      input->Skip(read_bytes);
283    }
284  }
285  return true;
286}
287
288// Specializations of ReadRepeatedPrimitive for the fixed size types, which use
289// the optimized code path.
290#define READ_REPEATED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE)             \
291template <>                                                                    \
292inline bool WireFormatLite::ReadRepeatedPrimitive<                             \
293  CPPTYPE, WireFormatLite::DECLARED_TYPE>(                                     \
294    int tag_size,                                                              \
295    uint32 tag,                                                                \
296    io::CodedInputStream* input,                                               \
297    RepeatedField<CPPTYPE>* values) {                                          \
298  return ReadRepeatedFixedSizePrimitive<                                       \
299    CPPTYPE, WireFormatLite::DECLARED_TYPE>(                                   \
300      tag_size, tag, input, values);                                           \
301}
302
303READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32);
304READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64);
305READ_REPEATED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32);
306READ_REPEATED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64);
307READ_REPEATED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT);
308READ_REPEATED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE);
309
310#undef READ_REPEATED_FIXED_SIZE_PRIMITIVE
311
312template <typename CType, enum WireFormatLite::FieldType DeclaredType>
313bool WireFormatLite::ReadRepeatedPrimitiveNoInline(
314    int tag_size,
315    uint32 tag,
316    io::CodedInputStream* input,
317    RepeatedField<CType>* value) {
318  return ReadRepeatedPrimitive<CType, DeclaredType>(
319      tag_size, tag, input, value);
320}
321
322template <typename CType, enum WireFormatLite::FieldType DeclaredType>
323inline bool WireFormatLite::ReadPackedPrimitive(io::CodedInputStream* input,
324                                                RepeatedField<CType>* values) {
325  uint32 length;
326  if (!input->ReadVarint32(&length)) return false;
327  io::CodedInputStream::Limit limit = input->PushLimit(length);
328  while (input->BytesUntilLimit() > 0) {
329    CType value;
330    if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
331    values->Add(value);
332  }
333  input->PopLimit(limit);
334  return true;
335}
336
337template <typename CType, enum WireFormatLite::FieldType DeclaredType>
338bool WireFormatLite::ReadPackedPrimitiveNoInline(io::CodedInputStream* input,
339                                                 RepeatedField<CType>* values) {
340  return ReadPackedPrimitive<CType, DeclaredType>(input, values);
341}
342
343
344inline bool WireFormatLite::ReadGroup(int field_number,
345                                      io::CodedInputStream* input,
346                                      MessageLite* value) {
347  if (!input->IncrementRecursionDepth()) return false;
348  if (!value->MergePartialFromCodedStream(input)) return false;
349  input->DecrementRecursionDepth();
350  // Make sure the last thing read was an end tag for this group.
351  if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) {
352    return false;
353  }
354  return true;
355}
356inline bool WireFormatLite::ReadMessage(io::CodedInputStream* input,
357                                        MessageLite* value) {
358  uint32 length;
359  if (!input->ReadVarint32(&length)) return false;
360  if (!input->IncrementRecursionDepth()) return false;
361  io::CodedInputStream::Limit limit = input->PushLimit(length);
362  if (!value->MergePartialFromCodedStream(input)) return false;
363  // Make sure that parsing stopped when the limit was hit, not at an endgroup
364  // tag.
365  if (!input->ConsumedEntireMessage()) return false;
366  input->PopLimit(limit);
367  input->DecrementRecursionDepth();
368  return true;
369}
370
371template<typename MessageType>
372inline bool WireFormatLite::ReadGroupNoVirtual(int field_number,
373                                               io::CodedInputStream* input,
374                                               MessageType* value) {
375  if (!input->IncrementRecursionDepth()) return false;
376  if (!value->MessageType::MergePartialFromCodedStream(input)) return false;
377  input->DecrementRecursionDepth();
378  // Make sure the last thing read was an end tag for this group.
379  if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) {
380    return false;
381  }
382  return true;
383}
384template<typename MessageType>
385inline bool WireFormatLite::ReadMessageNoVirtual(io::CodedInputStream* input,
386                                                 MessageType* value) {
387  uint32 length;
388  if (!input->ReadVarint32(&length)) return false;
389  if (!input->IncrementRecursionDepth()) return false;
390  io::CodedInputStream::Limit limit = input->PushLimit(length);
391  if (!value->MessageType::MergePartialFromCodedStream(input)) return false;
392  // Make sure that parsing stopped when the limit was hit, not at an endgroup
393  // tag.
394  if (!input->ConsumedEntireMessage()) return false;
395  input->PopLimit(limit);
396  input->DecrementRecursionDepth();
397  return true;
398}
399
400// ===================================================================
401
402inline void WireFormatLite::WriteTag(int field_number, WireType type,
403                                     io::CodedOutputStream* output) {
404  output->WriteTag(MakeTag(field_number, type));
405}
406
407inline void WireFormatLite::WriteInt32NoTag(int32 value,
408                                            io::CodedOutputStream* output) {
409  output->WriteVarint32SignExtended(value);
410}
411inline void WireFormatLite::WriteInt64NoTag(int64 value,
412                                            io::CodedOutputStream* output) {
413  output->WriteVarint64(static_cast<uint64>(value));
414}
415inline void WireFormatLite::WriteUInt32NoTag(uint32 value,
416                                             io::CodedOutputStream* output) {
417  output->WriteVarint32(value);
418}
419inline void WireFormatLite::WriteUInt64NoTag(uint64 value,
420                                             io::CodedOutputStream* output) {
421  output->WriteVarint64(value);
422}
423inline void WireFormatLite::WriteSInt32NoTag(int32 value,
424                                             io::CodedOutputStream* output) {
425  output->WriteVarint32(ZigZagEncode32(value));
426}
427inline void WireFormatLite::WriteSInt64NoTag(int64 value,
428                                             io::CodedOutputStream* output) {
429  output->WriteVarint64(ZigZagEncode64(value));
430}
431inline void WireFormatLite::WriteFixed32NoTag(uint32 value,
432                                              io::CodedOutputStream* output) {
433  output->WriteLittleEndian32(value);
434}
435inline void WireFormatLite::WriteFixed64NoTag(uint64 value,
436                                              io::CodedOutputStream* output) {
437  output->WriteLittleEndian64(value);
438}
439inline void WireFormatLite::WriteSFixed32NoTag(int32 value,
440                                               io::CodedOutputStream* output) {
441  output->WriteLittleEndian32(static_cast<uint32>(value));
442}
443inline void WireFormatLite::WriteSFixed64NoTag(int64 value,
444                                               io::CodedOutputStream* output) {
445  output->WriteLittleEndian64(static_cast<uint64>(value));
446}
447inline void WireFormatLite::WriteFloatNoTag(float value,
448                                            io::CodedOutputStream* output) {
449  output->WriteLittleEndian32(EncodeFloat(value));
450}
451inline void WireFormatLite::WriteDoubleNoTag(double value,
452                                             io::CodedOutputStream* output) {
453  output->WriteLittleEndian64(EncodeDouble(value));
454}
455inline void WireFormatLite::WriteBoolNoTag(bool value,
456                                           io::CodedOutputStream* output) {
457  output->WriteVarint32(value ? 1 : 0);
458}
459inline void WireFormatLite::WriteEnumNoTag(int value,
460                                           io::CodedOutputStream* output) {
461  output->WriteVarint32SignExtended(value);
462}
463
464template<typename MessageType>
465inline void WireFormatLite::WriteGroupNoVirtual(int field_number,
466                                                const MessageType& value,
467                                                io::CodedOutputStream* output) {
468  WriteTag(field_number, WIRETYPE_START_GROUP, output);
469  value.MessageType::SerializeWithCachedSizes(output);
470  WriteTag(field_number, WIRETYPE_END_GROUP, output);
471}
472template<typename MessageType>
473inline void WireFormatLite::WriteMessageNoVirtual(int field_number,
474                                                const MessageType& value,
475                                                io::CodedOutputStream* output) {
476  WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
477  output->WriteVarint32(value.MessageType::GetCachedSize());
478  value.MessageType::SerializeWithCachedSizes(output);
479}
480
481// ===================================================================
482
483inline uint8* WireFormatLite::WriteTagToArray(int field_number,
484                                              WireType type,
485                                              uint8* target) {
486  return io::CodedOutputStream::WriteTagToArray(MakeTag(field_number, type),
487                                                target);
488}
489
490inline uint8* WireFormatLite::WriteInt32NoTagToArray(int32 value,
491                                                     uint8* target) {
492  return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
493}
494inline uint8* WireFormatLite::WriteInt64NoTagToArray(int64 value,
495                                                     uint8* target) {
496  return io::CodedOutputStream::WriteVarint64ToArray(
497      static_cast<uint64>(value), target);
498}
499inline uint8* WireFormatLite::WriteUInt32NoTagToArray(uint32 value,
500                                                      uint8* target) {
501  return io::CodedOutputStream::WriteVarint32ToArray(value, target);
502}
503inline uint8* WireFormatLite::WriteUInt64NoTagToArray(uint64 value,
504                                                      uint8* target) {
505  return io::CodedOutputStream::WriteVarint64ToArray(value, target);
506}
507inline uint8* WireFormatLite::WriteSInt32NoTagToArray(int32 value,
508                                                      uint8* target) {
509  return io::CodedOutputStream::WriteVarint32ToArray(ZigZagEncode32(value),
510                                                     target);
511}
512inline uint8* WireFormatLite::WriteSInt64NoTagToArray(int64 value,
513                                                      uint8* target) {
514  return io::CodedOutputStream::WriteVarint64ToArray(ZigZagEncode64(value),
515                                                     target);
516}
517inline uint8* WireFormatLite::WriteFixed32NoTagToArray(uint32 value,
518                                                       uint8* target) {
519  return io::CodedOutputStream::WriteLittleEndian32ToArray(value, target);
520}
521inline uint8* WireFormatLite::WriteFixed64NoTagToArray(uint64 value,
522                                                       uint8* target) {
523  return io::CodedOutputStream::WriteLittleEndian64ToArray(value, target);
524}
525inline uint8* WireFormatLite::WriteSFixed32NoTagToArray(int32 value,
526                                                        uint8* target) {
527  return io::CodedOutputStream::WriteLittleEndian32ToArray(
528      static_cast<uint32>(value), target);
529}
530inline uint8* WireFormatLite::WriteSFixed64NoTagToArray(int64 value,
531                                                        uint8* target) {
532  return io::CodedOutputStream::WriteLittleEndian64ToArray(
533      static_cast<uint64>(value), target);
534}
535inline uint8* WireFormatLite::WriteFloatNoTagToArray(float value,
536                                                     uint8* target) {
537  return io::CodedOutputStream::WriteLittleEndian32ToArray(EncodeFloat(value),
538                                                           target);
539}
540inline uint8* WireFormatLite::WriteDoubleNoTagToArray(double value,
541                                                      uint8* target) {
542  return io::CodedOutputStream::WriteLittleEndian64ToArray(EncodeDouble(value),
543                                                           target);
544}
545inline uint8* WireFormatLite::WriteBoolNoTagToArray(bool value,
546                                                    uint8* target) {
547  return io::CodedOutputStream::WriteVarint32ToArray(value ? 1 : 0, target);
548}
549inline uint8* WireFormatLite::WriteEnumNoTagToArray(int value,
550                                                    uint8* target) {
551  return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
552}
553
554inline uint8* WireFormatLite::WriteInt32ToArray(int field_number,
555                                                int32 value,
556                                                uint8* target) {
557  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
558  return WriteInt32NoTagToArray(value, target);
559}
560inline uint8* WireFormatLite::WriteInt64ToArray(int field_number,
561                                                int64 value,
562                                                uint8* target) {
563  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
564  return WriteInt64NoTagToArray(value, target);
565}
566inline uint8* WireFormatLite::WriteUInt32ToArray(int field_number,
567                                                 uint32 value,
568                                                 uint8* target) {
569  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
570  return WriteUInt32NoTagToArray(value, target);
571}
572inline uint8* WireFormatLite::WriteUInt64ToArray(int field_number,
573                                                 uint64 value,
574                                                 uint8* target) {
575  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
576  return WriteUInt64NoTagToArray(value, target);
577}
578inline uint8* WireFormatLite::WriteSInt32ToArray(int field_number,
579                                                 int32 value,
580                                                 uint8* target) {
581  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
582  return WriteSInt32NoTagToArray(value, target);
583}
584inline uint8* WireFormatLite::WriteSInt64ToArray(int field_number,
585                                                 int64 value,
586                                                 uint8* target) {
587  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
588  return WriteSInt64NoTagToArray(value, target);
589}
590inline uint8* WireFormatLite::WriteFixed32ToArray(int field_number,
591                                                  uint32 value,
592                                                  uint8* target) {
593  target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
594  return WriteFixed32NoTagToArray(value, target);
595}
596inline uint8* WireFormatLite::WriteFixed64ToArray(int field_number,
597                                                  uint64 value,
598                                                  uint8* target) {
599  target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
600  return WriteFixed64NoTagToArray(value, target);
601}
602inline uint8* WireFormatLite::WriteSFixed32ToArray(int field_number,
603                                                   int32 value,
604                                                   uint8* target) {
605  target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
606  return WriteSFixed32NoTagToArray(value, target);
607}
608inline uint8* WireFormatLite::WriteSFixed64ToArray(int field_number,
609                                                   int64 value,
610                                                   uint8* target) {
611  target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
612  return WriteSFixed64NoTagToArray(value, target);
613}
614inline uint8* WireFormatLite::WriteFloatToArray(int field_number,
615                                                float value,
616                                                uint8* target) {
617  target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
618  return WriteFloatNoTagToArray(value, target);
619}
620inline uint8* WireFormatLite::WriteDoubleToArray(int field_number,
621                                                 double value,
622                                                 uint8* target) {
623  target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
624  return WriteDoubleNoTagToArray(value, target);
625}
626inline uint8* WireFormatLite::WriteBoolToArray(int field_number,
627                                               bool value,
628                                               uint8* target) {
629  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
630  return WriteBoolNoTagToArray(value, target);
631}
632inline uint8* WireFormatLite::WriteEnumToArray(int field_number,
633                                               int value,
634                                               uint8* target) {
635  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
636  return WriteEnumNoTagToArray(value, target);
637}
638
639inline uint8* WireFormatLite::WriteStringToArray(int field_number,
640                                                 const string& value,
641                                                 uint8* target) {
642  // String is for UTF-8 text only
643  // WARNING:  In wire_format.cc, both strings and bytes are handled by
644  //   WriteString() to avoid code duplication.  If the implementations become
645  //   different, you will need to update that usage.
646  target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
647  target = io::CodedOutputStream::WriteVarint32ToArray(value.size(), target);
648  return io::CodedOutputStream::WriteStringToArray(value, target);
649}
650inline uint8* WireFormatLite::WriteBytesToArray(int field_number,
651                                                const string& value,
652                                                uint8* target) {
653  target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
654  target = io::CodedOutputStream::WriteVarint32ToArray(value.size(), target);
655  return io::CodedOutputStream::WriteStringToArray(value, target);
656}
657
658
659inline uint8* WireFormatLite::WriteGroupToArray(int field_number,
660                                                const MessageLite& value,
661                                                uint8* target) {
662  target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
663  target = value.SerializeWithCachedSizesToArray(target);
664  return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
665}
666inline uint8* WireFormatLite::WriteMessageToArray(int field_number,
667                                                  const MessageLite& value,
668                                                  uint8* target) {
669  target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
670  target = io::CodedOutputStream::WriteVarint32ToArray(
671    value.GetCachedSize(), target);
672  return value.SerializeWithCachedSizesToArray(target);
673}
674
675template<typename MessageType>
676inline uint8* WireFormatLite::WriteGroupNoVirtualToArray(
677    int field_number, const MessageType& value, uint8* target) {
678  target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
679  target = value.MessageType::SerializeWithCachedSizesToArray(target);
680  return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
681}
682template<typename MessageType>
683inline uint8* WireFormatLite::WriteMessageNoVirtualToArray(
684    int field_number, const MessageType& value, uint8* target) {
685  target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
686  target = io::CodedOutputStream::WriteVarint32ToArray(
687    value.MessageType::GetCachedSize(), target);
688  return value.MessageType::SerializeWithCachedSizesToArray(target);
689}
690
691// ===================================================================
692
693inline int WireFormatLite::Int32Size(int32 value) {
694  return io::CodedOutputStream::VarintSize32SignExtended(value);
695}
696inline int WireFormatLite::Int64Size(int64 value) {
697  return io::CodedOutputStream::VarintSize64(static_cast<uint64>(value));
698}
699inline int WireFormatLite::UInt32Size(uint32 value) {
700  return io::CodedOutputStream::VarintSize32(value);
701}
702inline int WireFormatLite::UInt64Size(uint64 value) {
703  return io::CodedOutputStream::VarintSize64(value);
704}
705inline int WireFormatLite::SInt32Size(int32 value) {
706  return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value));
707}
708inline int WireFormatLite::SInt64Size(int64 value) {
709  return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value));
710}
711inline int WireFormatLite::EnumSize(int value) {
712  return io::CodedOutputStream::VarintSize32SignExtended(value);
713}
714
715inline int WireFormatLite::StringSize(const string& value) {
716  return io::CodedOutputStream::VarintSize32(value.size()) +
717         value.size();
718}
719inline int WireFormatLite::BytesSize(const string& value) {
720  return io::CodedOutputStream::VarintSize32(value.size()) +
721         value.size();
722}
723
724
725inline int WireFormatLite::GroupSize(const MessageLite& value) {
726  return value.ByteSize();
727}
728inline int WireFormatLite::MessageSize(const MessageLite& value) {
729  int size = value.ByteSize();
730  return io::CodedOutputStream::VarintSize32(size) + size;
731}
732
733template<typename MessageType>
734inline int WireFormatLite::GroupSizeNoVirtual(const MessageType& value) {
735  return value.MessageType::ByteSize();
736}
737template<typename MessageType>
738inline int WireFormatLite::MessageSizeNoVirtual(const MessageType& value) {
739  int size = value.MessageType::ByteSize();
740  return io::CodedOutputStream::VarintSize32(size) + size;
741}
742
743}  // namespace internal
744}  // namespace protobuf
745
746}  // namespace google
747#endif  // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
748