blob: a461a6cad873674f3ee5822f56d29d3b05cb22c6 [file] [log] [blame]
kenton@google.com80b1d622009-07-29 01:13:20 +00001// 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>
kenton@google.comfccb1462009-12-18 02:11:36 +000042#include <google/protobuf/repeated_field.h>
kenton@google.com80b1d622009-07-29 01:13:20 +000043#include <google/protobuf/wire_format_lite.h>
kenton@google.comfccb1462009-12-18 02:11:36 +000044#include <google/protobuf/generated_message_util.h>
kenton@google.com80b1d622009-07-29 01:13:20 +000045#include <google/protobuf/io/coded_stream.h>
46
47
48namespace google {
49namespace protobuf {
50namespace internal {
51
kenton@google.comfccb1462009-12-18 02:11:36 +000052// Implementation details of ReadPrimitive.
53
54template <>
55inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>(
56 io::CodedInputStream* input,
57 int32* value) {
kenton@google.com80b1d622009-07-29 01:13:20 +000058 uint32 temp;
59 if (!input->ReadVarint32(&temp)) return false;
60 *value = static_cast<int32>(temp);
61 return true;
62}
kenton@google.comfccb1462009-12-18 02:11:36 +000063template <>
64inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_INT64>(
65 io::CodedInputStream* input,
66 int64* value) {
kenton@google.com80b1d622009-07-29 01:13:20 +000067 uint64 temp;
68 if (!input->ReadVarint64(&temp)) return false;
69 *value = static_cast<int64>(temp);
70 return true;
71}
kenton@google.comfccb1462009-12-18 02:11:36 +000072template <>
73inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_UINT32>(
74 io::CodedInputStream* input,
75 uint32* value) {
kenton@google.com80b1d622009-07-29 01:13:20 +000076 return input->ReadVarint32(value);
77}
kenton@google.comfccb1462009-12-18 02:11:36 +000078template <>
79inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_UINT64>(
80 io::CodedInputStream* input,
81 uint64* value) {
kenton@google.com80b1d622009-07-29 01:13:20 +000082 return input->ReadVarint64(value);
83}
kenton@google.comfccb1462009-12-18 02:11:36 +000084template <>
85inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>(
86 io::CodedInputStream* input,
87 int32* value) {
kenton@google.com80b1d622009-07-29 01:13:20 +000088 uint32 temp;
89 if (!input->ReadVarint32(&temp)) return false;
90 *value = ZigZagDecode32(temp);
91 return true;
92}
kenton@google.comfccb1462009-12-18 02:11:36 +000093template <>
94inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SINT64>(
95 io::CodedInputStream* input,
96 int64* value) {
kenton@google.com80b1d622009-07-29 01:13:20 +000097 uint64 temp;
98 if (!input->ReadVarint64(&temp)) return false;
99 *value = ZigZagDecode64(temp);
100 return true;
101}
kenton@google.comfccb1462009-12-18 02:11:36 +0000102template <>
103inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_FIXED32>(
104 io::CodedInputStream* input,
105 uint32* value) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000106 return input->ReadLittleEndian32(value);
107}
kenton@google.comfccb1462009-12-18 02:11:36 +0000108template <>
109inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_FIXED64>(
110 io::CodedInputStream* input,
111 uint64* value) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000112 return input->ReadLittleEndian64(value);
113}
kenton@google.comfccb1462009-12-18 02:11:36 +0000114template <>
115inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SFIXED32>(
116 io::CodedInputStream* input,
117 int32* value) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000118 uint32 temp;
119 if (!input->ReadLittleEndian32(&temp)) return false;
120 *value = static_cast<int32>(temp);
121 return true;
122}
kenton@google.comfccb1462009-12-18 02:11:36 +0000123template <>
124inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SFIXED64>(
125 io::CodedInputStream* input,
126 int64* value) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000127 uint64 temp;
128 if (!input->ReadLittleEndian64(&temp)) return false;
129 *value = static_cast<int64>(temp);
130 return true;
131}
kenton@google.comfccb1462009-12-18 02:11:36 +0000132template <>
133inline bool WireFormatLite::ReadPrimitive<float, WireFormatLite::TYPE_FLOAT>(
134 io::CodedInputStream* input,
135 float* value) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000136 uint32 temp;
137 if (!input->ReadLittleEndian32(&temp)) return false;
138 *value = DecodeFloat(temp);
139 return true;
140}
kenton@google.comfccb1462009-12-18 02:11:36 +0000141template <>
142inline bool WireFormatLite::ReadPrimitive<double, WireFormatLite::TYPE_DOUBLE>(
143 io::CodedInputStream* input,
144 double* value) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000145 uint64 temp;
146 if (!input->ReadLittleEndian64(&temp)) return false;
147 *value = DecodeDouble(temp);
148 return true;
149}
kenton@google.comfccb1462009-12-18 02:11:36 +0000150template <>
151inline bool WireFormatLite::ReadPrimitive<bool, WireFormatLite::TYPE_BOOL>(
152 io::CodedInputStream* input,
153 bool* value) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000154 uint32 temp;
155 if (!input->ReadVarint32(&temp)) return false;
156 *value = temp != 0;
157 return true;
158}
kenton@google.comfccb1462009-12-18 02:11:36 +0000159template <>
160inline bool WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
161 io::CodedInputStream* input,
162 int* value) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000163 uint32 temp;
164 if (!input->ReadVarint32(&temp)) return false;
165 *value = static_cast<int>(temp);
166 return true;
167}
168
kenton@google.comfccb1462009-12-18 02:11:36 +0000169template <>
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 }
kenton@google.com80b1d622009-07-29 01:13:20 +0000238 return true;
239}
kenton@google.comfccb1462009-12-18 02:11:36 +0000240
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) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000325 uint32 length;
326 if (!input->ReadVarint32(&length)) return false;
kenton@google.comfccb1462009-12-18 02:11:36 +0000327 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);
kenton@google.com80b1d622009-07-29 01:13:20 +0000341}
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
liujisi@google.com33165fe2010-11-02 13:14:58 +0000371// We name the template parameter something long and extremely unlikely to occur
372// elsewhere because a *qualified* member access expression designed to avoid
373// virtual dispatch, C++03 [basic.lookup.classref] 3.4.5/4 requires that the
374// name of the qualifying class to be looked up both in the context of the full
375// expression (finding the template parameter) and in the context of the object
376// whose member we are accessing. This could potentially find a nested type
377// within that object. The standard goes on to require these names to refer to
378// the same entity, which this collision would violate. The lack of a safe way
379// to avoid this collision appears to be a defect in the standard, but until it
380// is corrected, we choose the name to avoid accidental collisions.
381template<typename MessageType_WorkAroundCppLookupDefect>
382inline bool WireFormatLite::ReadGroupNoVirtual(
383 int field_number, io::CodedInputStream* input,
384 MessageType_WorkAroundCppLookupDefect* value) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000385 if (!input->IncrementRecursionDepth()) return false;
liujisi@google.com33165fe2010-11-02 13:14:58 +0000386 if (!value->
387 MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input))
388 return false;
kenton@google.com80b1d622009-07-29 01:13:20 +0000389 input->DecrementRecursionDepth();
390 // Make sure the last thing read was an end tag for this group.
391 if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) {
392 return false;
393 }
394 return true;
395}
liujisi@google.com33165fe2010-11-02 13:14:58 +0000396template<typename MessageType_WorkAroundCppLookupDefect>
397inline bool WireFormatLite::ReadMessageNoVirtual(
398 io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000399 uint32 length;
400 if (!input->ReadVarint32(&length)) return false;
401 if (!input->IncrementRecursionDepth()) return false;
402 io::CodedInputStream::Limit limit = input->PushLimit(length);
liujisi@google.com33165fe2010-11-02 13:14:58 +0000403 if (!value->
404 MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input))
405 return false;
kenton@google.com80b1d622009-07-29 01:13:20 +0000406 // Make sure that parsing stopped when the limit was hit, not at an endgroup
407 // tag.
408 if (!input->ConsumedEntireMessage()) return false;
409 input->PopLimit(limit);
410 input->DecrementRecursionDepth();
411 return true;
412}
413
414// ===================================================================
415
416inline void WireFormatLite::WriteTag(int field_number, WireType type,
417 io::CodedOutputStream* output) {
418 output->WriteTag(MakeTag(field_number, type));
419}
420
421inline void WireFormatLite::WriteInt32NoTag(int32 value,
422 io::CodedOutputStream* output) {
423 output->WriteVarint32SignExtended(value);
424}
425inline void WireFormatLite::WriteInt64NoTag(int64 value,
426 io::CodedOutputStream* output) {
427 output->WriteVarint64(static_cast<uint64>(value));
428}
429inline void WireFormatLite::WriteUInt32NoTag(uint32 value,
430 io::CodedOutputStream* output) {
431 output->WriteVarint32(value);
432}
433inline void WireFormatLite::WriteUInt64NoTag(uint64 value,
434 io::CodedOutputStream* output) {
435 output->WriteVarint64(value);
436}
437inline void WireFormatLite::WriteSInt32NoTag(int32 value,
438 io::CodedOutputStream* output) {
439 output->WriteVarint32(ZigZagEncode32(value));
440}
441inline void WireFormatLite::WriteSInt64NoTag(int64 value,
442 io::CodedOutputStream* output) {
443 output->WriteVarint64(ZigZagEncode64(value));
444}
445inline void WireFormatLite::WriteFixed32NoTag(uint32 value,
446 io::CodedOutputStream* output) {
447 output->WriteLittleEndian32(value);
448}
449inline void WireFormatLite::WriteFixed64NoTag(uint64 value,
450 io::CodedOutputStream* output) {
451 output->WriteLittleEndian64(value);
452}
453inline void WireFormatLite::WriteSFixed32NoTag(int32 value,
454 io::CodedOutputStream* output) {
455 output->WriteLittleEndian32(static_cast<uint32>(value));
456}
457inline void WireFormatLite::WriteSFixed64NoTag(int64 value,
458 io::CodedOutputStream* output) {
459 output->WriteLittleEndian64(static_cast<uint64>(value));
460}
461inline void WireFormatLite::WriteFloatNoTag(float value,
462 io::CodedOutputStream* output) {
463 output->WriteLittleEndian32(EncodeFloat(value));
464}
465inline void WireFormatLite::WriteDoubleNoTag(double value,
466 io::CodedOutputStream* output) {
467 output->WriteLittleEndian64(EncodeDouble(value));
468}
469inline void WireFormatLite::WriteBoolNoTag(bool value,
470 io::CodedOutputStream* output) {
471 output->WriteVarint32(value ? 1 : 0);
472}
473inline void WireFormatLite::WriteEnumNoTag(int value,
474 io::CodedOutputStream* output) {
475 output->WriteVarint32SignExtended(value);
476}
477
liujisi@google.com33165fe2010-11-02 13:14:58 +0000478// See comment on ReadGroupNoVirtual to understand the need for this template
479// parameter name.
480template<typename MessageType_WorkAroundCppLookupDefect>
481inline void WireFormatLite::WriteGroupNoVirtual(
482 int field_number, const MessageType_WorkAroundCppLookupDefect& value,
483 io::CodedOutputStream* output) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000484 WriteTag(field_number, WIRETYPE_START_GROUP, output);
liujisi@google.com33165fe2010-11-02 13:14:58 +0000485 value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output);
kenton@google.com80b1d622009-07-29 01:13:20 +0000486 WriteTag(field_number, WIRETYPE_END_GROUP, output);
487}
liujisi@google.com33165fe2010-11-02 13:14:58 +0000488template<typename MessageType_WorkAroundCppLookupDefect>
489inline void WireFormatLite::WriteMessageNoVirtual(
490 int field_number, const MessageType_WorkAroundCppLookupDefect& value,
491 io::CodedOutputStream* output) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000492 WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
liujisi@google.com33165fe2010-11-02 13:14:58 +0000493 output->WriteVarint32(
494 value.MessageType_WorkAroundCppLookupDefect::GetCachedSize());
495 value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output);
kenton@google.com80b1d622009-07-29 01:13:20 +0000496}
497
498// ===================================================================
499
500inline uint8* WireFormatLite::WriteTagToArray(int field_number,
501 WireType type,
502 uint8* target) {
503 return io::CodedOutputStream::WriteTagToArray(MakeTag(field_number, type),
504 target);
505}
506
507inline uint8* WireFormatLite::WriteInt32NoTagToArray(int32 value,
508 uint8* target) {
509 return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
510}
511inline uint8* WireFormatLite::WriteInt64NoTagToArray(int64 value,
512 uint8* target) {
513 return io::CodedOutputStream::WriteVarint64ToArray(
514 static_cast<uint64>(value), target);
515}
516inline uint8* WireFormatLite::WriteUInt32NoTagToArray(uint32 value,
517 uint8* target) {
518 return io::CodedOutputStream::WriteVarint32ToArray(value, target);
519}
520inline uint8* WireFormatLite::WriteUInt64NoTagToArray(uint64 value,
521 uint8* target) {
522 return io::CodedOutputStream::WriteVarint64ToArray(value, target);
523}
524inline uint8* WireFormatLite::WriteSInt32NoTagToArray(int32 value,
525 uint8* target) {
526 return io::CodedOutputStream::WriteVarint32ToArray(ZigZagEncode32(value),
527 target);
528}
529inline uint8* WireFormatLite::WriteSInt64NoTagToArray(int64 value,
530 uint8* target) {
531 return io::CodedOutputStream::WriteVarint64ToArray(ZigZagEncode64(value),
532 target);
533}
534inline uint8* WireFormatLite::WriteFixed32NoTagToArray(uint32 value,
535 uint8* target) {
536 return io::CodedOutputStream::WriteLittleEndian32ToArray(value, target);
537}
538inline uint8* WireFormatLite::WriteFixed64NoTagToArray(uint64 value,
539 uint8* target) {
540 return io::CodedOutputStream::WriteLittleEndian64ToArray(value, target);
541}
542inline uint8* WireFormatLite::WriteSFixed32NoTagToArray(int32 value,
543 uint8* target) {
544 return io::CodedOutputStream::WriteLittleEndian32ToArray(
545 static_cast<uint32>(value), target);
546}
547inline uint8* WireFormatLite::WriteSFixed64NoTagToArray(int64 value,
548 uint8* target) {
549 return io::CodedOutputStream::WriteLittleEndian64ToArray(
550 static_cast<uint64>(value), target);
551}
552inline uint8* WireFormatLite::WriteFloatNoTagToArray(float value,
553 uint8* target) {
554 return io::CodedOutputStream::WriteLittleEndian32ToArray(EncodeFloat(value),
555 target);
556}
557inline uint8* WireFormatLite::WriteDoubleNoTagToArray(double value,
558 uint8* target) {
559 return io::CodedOutputStream::WriteLittleEndian64ToArray(EncodeDouble(value),
560 target);
561}
562inline uint8* WireFormatLite::WriteBoolNoTagToArray(bool value,
563 uint8* target) {
564 return io::CodedOutputStream::WriteVarint32ToArray(value ? 1 : 0, target);
565}
566inline uint8* WireFormatLite::WriteEnumNoTagToArray(int value,
567 uint8* target) {
568 return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
569}
570
571inline uint8* WireFormatLite::WriteInt32ToArray(int field_number,
572 int32 value,
573 uint8* target) {
574 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
575 return WriteInt32NoTagToArray(value, target);
576}
577inline uint8* WireFormatLite::WriteInt64ToArray(int field_number,
578 int64 value,
579 uint8* target) {
580 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
581 return WriteInt64NoTagToArray(value, target);
582}
583inline uint8* WireFormatLite::WriteUInt32ToArray(int field_number,
584 uint32 value,
585 uint8* target) {
586 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
587 return WriteUInt32NoTagToArray(value, target);
588}
589inline uint8* WireFormatLite::WriteUInt64ToArray(int field_number,
590 uint64 value,
591 uint8* target) {
592 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
593 return WriteUInt64NoTagToArray(value, target);
594}
595inline uint8* WireFormatLite::WriteSInt32ToArray(int field_number,
596 int32 value,
597 uint8* target) {
598 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
599 return WriteSInt32NoTagToArray(value, target);
600}
601inline uint8* WireFormatLite::WriteSInt64ToArray(int field_number,
602 int64 value,
603 uint8* target) {
604 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
605 return WriteSInt64NoTagToArray(value, target);
606}
607inline uint8* WireFormatLite::WriteFixed32ToArray(int field_number,
608 uint32 value,
609 uint8* target) {
610 target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
611 return WriteFixed32NoTagToArray(value, target);
612}
613inline uint8* WireFormatLite::WriteFixed64ToArray(int field_number,
614 uint64 value,
615 uint8* target) {
616 target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
617 return WriteFixed64NoTagToArray(value, target);
618}
619inline uint8* WireFormatLite::WriteSFixed32ToArray(int field_number,
620 int32 value,
621 uint8* target) {
622 target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
623 return WriteSFixed32NoTagToArray(value, target);
624}
625inline uint8* WireFormatLite::WriteSFixed64ToArray(int field_number,
626 int64 value,
627 uint8* target) {
628 target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
629 return WriteSFixed64NoTagToArray(value, target);
630}
631inline uint8* WireFormatLite::WriteFloatToArray(int field_number,
632 float value,
633 uint8* target) {
634 target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
635 return WriteFloatNoTagToArray(value, target);
636}
637inline uint8* WireFormatLite::WriteDoubleToArray(int field_number,
638 double value,
639 uint8* target) {
640 target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
641 return WriteDoubleNoTagToArray(value, target);
642}
643inline uint8* WireFormatLite::WriteBoolToArray(int field_number,
644 bool value,
645 uint8* target) {
646 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
647 return WriteBoolNoTagToArray(value, target);
648}
649inline uint8* WireFormatLite::WriteEnumToArray(int field_number,
650 int value,
651 uint8* target) {
652 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
653 return WriteEnumNoTagToArray(value, target);
654}
655
656inline uint8* WireFormatLite::WriteStringToArray(int field_number,
657 const string& value,
658 uint8* target) {
659 // String is for UTF-8 text only
660 // WARNING: In wire_format.cc, both strings and bytes are handled by
661 // WriteString() to avoid code duplication. If the implementations become
662 // different, you will need to update that usage.
663 target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
664 target = io::CodedOutputStream::WriteVarint32ToArray(value.size(), target);
665 return io::CodedOutputStream::WriteStringToArray(value, target);
666}
667inline uint8* WireFormatLite::WriteBytesToArray(int field_number,
668 const string& value,
669 uint8* target) {
670 target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
671 target = io::CodedOutputStream::WriteVarint32ToArray(value.size(), target);
672 return io::CodedOutputStream::WriteStringToArray(value, target);
673}
674
675
676inline uint8* WireFormatLite::WriteGroupToArray(int field_number,
677 const MessageLite& value,
678 uint8* target) {
679 target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
680 target = value.SerializeWithCachedSizesToArray(target);
681 return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
682}
683inline uint8* WireFormatLite::WriteMessageToArray(int field_number,
684 const MessageLite& value,
685 uint8* target) {
686 target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
687 target = io::CodedOutputStream::WriteVarint32ToArray(
688 value.GetCachedSize(), target);
689 return value.SerializeWithCachedSizesToArray(target);
690}
691
liujisi@google.com33165fe2010-11-02 13:14:58 +0000692// See comment on ReadGroupNoVirtual to understand the need for this template
693// parameter name.
694template<typename MessageType_WorkAroundCppLookupDefect>
kenton@google.com80b1d622009-07-29 01:13:20 +0000695inline uint8* WireFormatLite::WriteGroupNoVirtualToArray(
liujisi@google.com33165fe2010-11-02 13:14:58 +0000696 int field_number, const MessageType_WorkAroundCppLookupDefect& value,
697 uint8* target) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000698 target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
liujisi@google.com33165fe2010-11-02 13:14:58 +0000699 target = value.MessageType_WorkAroundCppLookupDefect
700 ::SerializeWithCachedSizesToArray(target);
kenton@google.com80b1d622009-07-29 01:13:20 +0000701 return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
702}
liujisi@google.com33165fe2010-11-02 13:14:58 +0000703template<typename MessageType_WorkAroundCppLookupDefect>
kenton@google.com80b1d622009-07-29 01:13:20 +0000704inline uint8* WireFormatLite::WriteMessageNoVirtualToArray(
liujisi@google.com33165fe2010-11-02 13:14:58 +0000705 int field_number, const MessageType_WorkAroundCppLookupDefect& value,
706 uint8* target) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000707 target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
708 target = io::CodedOutputStream::WriteVarint32ToArray(
liujisi@google.com33165fe2010-11-02 13:14:58 +0000709 value.MessageType_WorkAroundCppLookupDefect::GetCachedSize(), target);
710 return value.MessageType_WorkAroundCppLookupDefect
711 ::SerializeWithCachedSizesToArray(target);
kenton@google.com80b1d622009-07-29 01:13:20 +0000712}
713
714// ===================================================================
715
716inline int WireFormatLite::Int32Size(int32 value) {
717 return io::CodedOutputStream::VarintSize32SignExtended(value);
718}
719inline int WireFormatLite::Int64Size(int64 value) {
720 return io::CodedOutputStream::VarintSize64(static_cast<uint64>(value));
721}
722inline int WireFormatLite::UInt32Size(uint32 value) {
723 return io::CodedOutputStream::VarintSize32(value);
724}
725inline int WireFormatLite::UInt64Size(uint64 value) {
726 return io::CodedOutputStream::VarintSize64(value);
727}
728inline int WireFormatLite::SInt32Size(int32 value) {
729 return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value));
730}
731inline int WireFormatLite::SInt64Size(int64 value) {
732 return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value));
733}
734inline int WireFormatLite::EnumSize(int value) {
735 return io::CodedOutputStream::VarintSize32SignExtended(value);
736}
737
738inline int WireFormatLite::StringSize(const string& value) {
739 return io::CodedOutputStream::VarintSize32(value.size()) +
740 value.size();
741}
742inline int WireFormatLite::BytesSize(const string& value) {
743 return io::CodedOutputStream::VarintSize32(value.size()) +
744 value.size();
745}
746
747
748inline int WireFormatLite::GroupSize(const MessageLite& value) {
749 return value.ByteSize();
750}
751inline int WireFormatLite::MessageSize(const MessageLite& value) {
752 int size = value.ByteSize();
753 return io::CodedOutputStream::VarintSize32(size) + size;
754}
755
liujisi@google.com33165fe2010-11-02 13:14:58 +0000756// See comment on ReadGroupNoVirtual to understand the need for this template
757// parameter name.
758template<typename MessageType_WorkAroundCppLookupDefect>
759inline int WireFormatLite::GroupSizeNoVirtual(
760 const MessageType_WorkAroundCppLookupDefect& value) {
761 return value.MessageType_WorkAroundCppLookupDefect::ByteSize();
kenton@google.com80b1d622009-07-29 01:13:20 +0000762}
liujisi@google.com33165fe2010-11-02 13:14:58 +0000763template<typename MessageType_WorkAroundCppLookupDefect>
764inline int WireFormatLite::MessageSizeNoVirtual(
765 const MessageType_WorkAroundCppLookupDefect& value) {
766 int size = value.MessageType_WorkAroundCppLookupDefect::ByteSize();
kenton@google.com80b1d622009-07-29 01:13:20 +0000767 return io::CodedOutputStream::VarintSize32(size) + size;
768}
769
770} // namespace internal
771} // namespace protobuf
772
773} // namespace google
774#endif // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__