1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // http://code.google.com/p/protobuf/
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
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
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.
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.
31 // Author: kenton@google.com (Kenton Varda)
32 // Based on original Protocol Buffers design by
33 // Sanjay Ghemawat, Jeff Dean, and others.
35 #include <google/protobuf/wire_format_lite_inl.h>
40 #include <google/protobuf/stubs/common.h>
41 #include <google/protobuf/io/coded_stream_inl.h>
42 #include <google/protobuf/io/zero_copy_stream.h>
43 #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
44 #include <google/protobuf/unknown_field_set.h>
50 #ifndef _MSC_VER // MSVC doesn't like definitions of inline constants, GCC
52 const int WireFormatLite::kMessageSetItemStartTag;
53 const int WireFormatLite::kMessageSetItemEndTag;
54 const int WireFormatLite::kMessageSetTypeIdTag;
55 const int WireFormatLite::kMessageSetMessageTag;
59 // ===================================================================
61 bool FieldSkipper::SkipField(
62 io::CodedInputStream* input, uint32 tag) {
63 return WireFormatLite::SkipField(input, tag, unknown_fields_);
66 bool FieldSkipper::SkipMessage(io::CodedInputStream* input) {
67 return WireFormatLite::SkipMessage(input, unknown_fields_);
70 void FieldSkipper::SkipUnknownEnum(
71 int field_number, int value) {
72 unknown_fields_->AddVarint(field_number, value);
75 // ===================================================================
77 const int WireFormatLite::kMessageSetItemTagsSize =
78 io::CodedOutputStream::StaticVarintSize32<kMessageSetItemStartTag>::value +
79 io::CodedOutputStream::StaticVarintSize32<kMessageSetItemEndTag>::value +
80 io::CodedOutputStream::StaticVarintSize32<kMessageSetTypeIdTag>::value +
81 io::CodedOutputStream::StaticVarintSize32<kMessageSetMessageTag>::value;
83 const WireFormatLite::CppType
84 WireFormatLite::kFieldTypeToCppTypeMap[MAX_FIELD_TYPE + 1] = {
85 static_cast<CppType>(0), // 0 is reserved for errors
87 CPPTYPE_DOUBLE, // TYPE_DOUBLE
88 CPPTYPE_FLOAT, // TYPE_FLOAT
89 CPPTYPE_INT64, // TYPE_INT64
90 CPPTYPE_UINT64, // TYPE_UINT64
91 CPPTYPE_INT32, // TYPE_INT32
92 CPPTYPE_UINT64, // TYPE_FIXED64
93 CPPTYPE_UINT32, // TYPE_FIXED32
94 CPPTYPE_BOOL, // TYPE_BOOL
95 CPPTYPE_STRING, // TYPE_STRING
96 CPPTYPE_MESSAGE, // TYPE_GROUP
97 CPPTYPE_MESSAGE, // TYPE_MESSAGE
98 CPPTYPE_STRING, // TYPE_BYTES
99 CPPTYPE_UINT32, // TYPE_UINT32
100 CPPTYPE_ENUM, // TYPE_ENUM
101 CPPTYPE_INT32, // TYPE_SFIXED32
102 CPPTYPE_INT64, // TYPE_SFIXED64
103 CPPTYPE_INT32, // TYPE_SINT32
104 CPPTYPE_INT64, // TYPE_SINT64
107 const WireFormatLite::WireType
108 WireFormatLite::kWireTypeForFieldType[MAX_FIELD_TYPE + 1] = {
109 static_cast<WireFormatLite::WireType>(-1), // invalid
110 WireFormatLite::WIRETYPE_FIXED64, // TYPE_DOUBLE
111 WireFormatLite::WIRETYPE_FIXED32, // TYPE_FLOAT
112 WireFormatLite::WIRETYPE_VARINT, // TYPE_INT64
113 WireFormatLite::WIRETYPE_VARINT, // TYPE_UINT64
114 WireFormatLite::WIRETYPE_VARINT, // TYPE_INT32
115 WireFormatLite::WIRETYPE_FIXED64, // TYPE_FIXED64
116 WireFormatLite::WIRETYPE_FIXED32, // TYPE_FIXED32
117 WireFormatLite::WIRETYPE_VARINT, // TYPE_BOOL
118 WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_STRING
119 WireFormatLite::WIRETYPE_START_GROUP, // TYPE_GROUP
120 WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_MESSAGE
121 WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_BYTES
122 WireFormatLite::WIRETYPE_VARINT, // TYPE_UINT32
123 WireFormatLite::WIRETYPE_VARINT, // TYPE_ENUM
124 WireFormatLite::WIRETYPE_FIXED32, // TYPE_SFIXED32
125 WireFormatLite::WIRETYPE_FIXED64, // TYPE_SFIXED64
126 WireFormatLite::WIRETYPE_VARINT, // TYPE_SINT32
127 WireFormatLite::WIRETYPE_VARINT, // TYPE_SINT64
130 bool WireFormatLite::SkipField(io::CodedInputStream* input, uint32 tag,
131 UnknownFieldSet* unknown_fields) {
132 int number = WireFormatLite::GetTagFieldNumber(tag);
134 switch (WireFormatLite::GetTagWireType(tag)) {
135 case WireFormatLite::WIRETYPE_VARINT: {
137 if (!input->ReadVarint64(&value)) return false;
138 if (unknown_fields != NULL) unknown_fields->AddVarint(number, value);
141 case WireFormatLite::WIRETYPE_FIXED64: {
143 if (!input->ReadLittleEndian64(&value)) return false;
144 if (unknown_fields != NULL) unknown_fields->AddFixed64(number, value);
147 case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
149 if (!input->ReadVarint32(&length)) return false;
150 if (unknown_fields == NULL) {
151 if (!input->Skip(length)) return false;
153 if (!input->ReadString(unknown_fields->AddLengthDelimited(number),
160 case WireFormatLite::WIRETYPE_START_GROUP: {
161 if (!input->IncrementRecursionDepth()) return false;
162 if (!SkipMessage(input, (unknown_fields == NULL) ?
163 NULL : unknown_fields->AddGroup(number))) {
166 input->DecrementRecursionDepth();
167 // Check that the ending tag matched the starting tag.
168 if (!input->LastTagWas(WireFormatLite::MakeTag(
169 WireFormatLite::GetTagFieldNumber(tag),
170 WireFormatLite::WIRETYPE_END_GROUP))) {
175 case WireFormatLite::WIRETYPE_END_GROUP: {
178 case WireFormatLite::WIRETYPE_FIXED32: {
180 if (!input->ReadLittleEndian32(&value)) return false;
181 if (unknown_fields != NULL) unknown_fields->AddFixed32(number, value);
190 bool WireFormatLite::SkipMessage(io::CodedInputStream* input,
191 UnknownFieldSet* unknown_fields) {
193 uint32 tag = input->ReadTag();
195 // End of input. This is a valid place to end, so return true.
199 WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
201 if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
202 // Must be the end of the message.
206 if (!SkipField(input, tag, unknown_fields)) return false;
210 void WireFormatLite::SerializeUnknownFields(const UnknownFieldSet& unknown_fields,
211 io::CodedOutputStream* output) {
212 for (int i = 0; i < unknown_fields.field_count(); i++) {
213 const UnknownField& field = unknown_fields.field(i);
214 switch (field.type()) {
215 case UnknownField::TYPE_VARINT:
216 output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
217 WireFormatLite::WIRETYPE_VARINT));
218 output->WriteVarint64(field.varint());
220 case UnknownField::TYPE_FIXED32:
221 output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
222 WireFormatLite::WIRETYPE_FIXED32));
223 output->WriteLittleEndian32(field.fixed32());
225 case UnknownField::TYPE_FIXED64:
226 output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
227 WireFormatLite::WIRETYPE_FIXED64));
228 output->WriteLittleEndian64(field.fixed64());
230 case UnknownField::TYPE_LENGTH_DELIMITED:
231 output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
232 WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
233 output->WriteVarint32(field.length_delimited().size());
234 output->WriteString(field.length_delimited());
236 case UnknownField::TYPE_GROUP:
237 output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
238 WireFormatLite::WIRETYPE_START_GROUP));
239 SerializeUnknownFields(field.group(), output);
240 output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
241 WireFormatLite::WIRETYPE_END_GROUP));
247 uint8* WireFormatLite::SerializeUnknownFieldsToArray(
248 const UnknownFieldSet& unknown_fields,
250 for (int i = 0; i < unknown_fields.field_count(); i++) {
251 const UnknownField& field = unknown_fields.field(i);
253 switch (field.type()) {
254 case UnknownField::TYPE_VARINT:
255 target = WireFormatLite::WriteInt64ToArray(
256 field.number(), field.varint(), target);
258 case UnknownField::TYPE_FIXED32:
259 target = WireFormatLite::WriteFixed32ToArray(
260 field.number(), field.fixed32(), target);
262 case UnknownField::TYPE_FIXED64:
263 target = WireFormatLite::WriteFixed64ToArray(
264 field.number(), field.fixed64(), target);
266 case UnknownField::TYPE_LENGTH_DELIMITED:
267 target = WireFormatLite::WriteBytesToArray(
268 field.number(), field.length_delimited(), target);
270 case UnknownField::TYPE_GROUP:
271 target = WireFormatLite::WriteTagToArray(
272 field.number(), WireFormatLite::WIRETYPE_START_GROUP, target);
273 target = SerializeUnknownFieldsToArray(field.group(), target);
274 target = WireFormatLite::WriteTagToArray(
275 field.number(), WireFormatLite::WIRETYPE_END_GROUP, target);
282 void WireFormatLite::SerializeUnknownMessageSetItems(
283 const UnknownFieldSet& unknown_fields,
284 io::CodedOutputStream* output) {
285 for (int i = 0; i < unknown_fields.field_count(); i++) {
286 const UnknownField& field = unknown_fields.field(i);
287 // The only unknown fields that are allowed to exist in a MessageSet are
288 // messages, which are length-delimited.
289 if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) {
290 const string& data = field.length_delimited();
293 output->WriteVarint32(WireFormatLite::kMessageSetItemStartTag);
296 output->WriteVarint32(WireFormatLite::kMessageSetTypeIdTag);
297 output->WriteVarint32(field.number());
300 output->WriteVarint32(WireFormatLite::kMessageSetMessageTag);
301 output->WriteVarint32(data.size());
302 output->WriteString(data);
305 output->WriteVarint32(WireFormatLite::kMessageSetItemEndTag);
310 uint8* WireFormatLite::SerializeUnknownMessageSetItemsToArray(
311 const UnknownFieldSet& unknown_fields,
313 for (int i = 0; i < unknown_fields.field_count(); i++) {
314 const UnknownField& field = unknown_fields.field(i);
316 // The only unknown fields that are allowed to exist in a MessageSet are
317 // messages, which are length-delimited.
318 if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) {
319 const string& data = field.length_delimited();
322 target = io::CodedOutputStream::WriteTagToArray(
323 WireFormatLite::kMessageSetItemStartTag, target);
326 target = io::CodedOutputStream::WriteTagToArray(
327 WireFormatLite::kMessageSetTypeIdTag, target);
328 target = io::CodedOutputStream::WriteVarint32ToArray(
329 field.number(), target);
332 target = io::CodedOutputStream::WriteTagToArray(
333 WireFormatLite::kMessageSetMessageTag, target);
334 target = io::CodedOutputStream::WriteVarint32ToArray(data.size(), target);
335 target = io::CodedOutputStream::WriteStringToArray(data, target);
338 target = io::CodedOutputStream::WriteTagToArray(
339 WireFormatLite::kMessageSetItemEndTag, target);
346 int WireFormatLite::ComputeUnknownFieldsSize(
347 const UnknownFieldSet& unknown_fields) {
349 for (int i = 0; i < unknown_fields.field_count(); i++) {
350 const UnknownField& field = unknown_fields.field(i);
352 switch (field.type()) {
353 case UnknownField::TYPE_VARINT:
354 size += io::CodedOutputStream::VarintSize32(
355 WireFormatLite::MakeTag(field.number(),
356 WireFormatLite::WIRETYPE_VARINT));
357 size += io::CodedOutputStream::VarintSize64(field.varint());
359 case UnknownField::TYPE_FIXED32:
360 size += io::CodedOutputStream::VarintSize32(
361 WireFormatLite::MakeTag(field.number(),
362 WireFormatLite::WIRETYPE_FIXED32));
363 size += sizeof(int32);
365 case UnknownField::TYPE_FIXED64:
366 size += io::CodedOutputStream::VarintSize32(
367 WireFormatLite::MakeTag(field.number(),
368 WireFormatLite::WIRETYPE_FIXED64));
369 size += sizeof(int64);
371 case UnknownField::TYPE_LENGTH_DELIMITED:
372 size += io::CodedOutputStream::VarintSize32(
373 WireFormatLite::MakeTag(field.number(),
374 WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
375 size += io::CodedOutputStream::VarintSize32(
376 field.length_delimited().size());
377 size += field.length_delimited().size();
379 case UnknownField::TYPE_GROUP:
380 size += io::CodedOutputStream::VarintSize32(
381 WireFormatLite::MakeTag(field.number(),
382 WireFormatLite::WIRETYPE_START_GROUP));
383 size += ComputeUnknownFieldsSize(field.group());
384 size += io::CodedOutputStream::VarintSize32(
385 WireFormatLite::MakeTag(field.number(),
386 WireFormatLite::WIRETYPE_END_GROUP));
394 int WireFormatLite::ComputeUnknownMessageSetItemsSize(
395 const UnknownFieldSet& unknown_fields) {
397 for (int i = 0; i < unknown_fields.field_count(); i++) {
398 const UnknownField& field = unknown_fields.field(i);
400 // The only unknown fields that are allowed to exist in a MessageSet are
401 // messages, which are length-delimited.
402 if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) {
403 size += WireFormatLite::kMessageSetItemTagsSize;
404 size += io::CodedOutputStream::VarintSize32(field.number());
405 size += io::CodedOutputStream::VarintSize32(
406 field.length_delimited().size());
407 size += field.length_delimited().size();
414 bool WireFormatLite::ReadPackedEnumNoInline(io::CodedInputStream* input,
415 bool (*is_valid)(int),
416 RepeatedField<int>* values) {
418 if (!input->ReadVarint32(&length)) return false;
419 io::CodedInputStream::Limit limit = input->PushLimit(length);
420 while (input->BytesUntilLimit() > 0) {
422 if (!google::protobuf::internal::WireFormatLite::ReadPrimitive<
423 int, WireFormatLite::TYPE_ENUM>(input, &value)) {
426 if (is_valid(value)) {
430 input->PopLimit(limit);
434 void WireFormatLite::WriteInt32(int field_number, int32 value,
435 io::CodedOutputStream* output) {
436 WriteTag(field_number, WIRETYPE_VARINT, output);
437 WriteInt32NoTag(value, output);
439 void WireFormatLite::WriteInt64(int field_number, int64 value,
440 io::CodedOutputStream* output) {
441 WriteTag(field_number, WIRETYPE_VARINT, output);
442 WriteInt64NoTag(value, output);
444 void WireFormatLite::WriteUInt32(int field_number, uint32 value,
445 io::CodedOutputStream* output) {
446 WriteTag(field_number, WIRETYPE_VARINT, output);
447 WriteUInt32NoTag(value, output);
449 void WireFormatLite::WriteUInt64(int field_number, uint64 value,
450 io::CodedOutputStream* output) {
451 WriteTag(field_number, WIRETYPE_VARINT, output);
452 WriteUInt64NoTag(value, output);
454 void WireFormatLite::WriteSInt32(int field_number, int32 value,
455 io::CodedOutputStream* output) {
456 WriteTag(field_number, WIRETYPE_VARINT, output);
457 WriteSInt32NoTag(value, output);
459 void WireFormatLite::WriteSInt64(int field_number, int64 value,
460 io::CodedOutputStream* output) {
461 WriteTag(field_number, WIRETYPE_VARINT, output);
462 WriteSInt64NoTag(value, output);
464 void WireFormatLite::WriteFixed32(int field_number, uint32 value,
465 io::CodedOutputStream* output) {
466 WriteTag(field_number, WIRETYPE_FIXED32, output);
467 WriteFixed32NoTag(value, output);
469 void WireFormatLite::WriteFixed64(int field_number, uint64 value,
470 io::CodedOutputStream* output) {
471 WriteTag(field_number, WIRETYPE_FIXED64, output);
472 WriteFixed64NoTag(value, output);
474 void WireFormatLite::WriteSFixed32(int field_number, int32 value,
475 io::CodedOutputStream* output) {
476 WriteTag(field_number, WIRETYPE_FIXED32, output);
477 WriteSFixed32NoTag(value, output);
479 void WireFormatLite::WriteSFixed64(int field_number, int64 value,
480 io::CodedOutputStream* output) {
481 WriteTag(field_number, WIRETYPE_FIXED64, output);
482 WriteSFixed64NoTag(value, output);
484 void WireFormatLite::WriteFloat(int field_number, float value,
485 io::CodedOutputStream* output) {
486 WriteTag(field_number, WIRETYPE_FIXED32, output);
487 WriteFloatNoTag(value, output);
489 void WireFormatLite::WriteDouble(int field_number, double value,
490 io::CodedOutputStream* output) {
491 WriteTag(field_number, WIRETYPE_FIXED64, output);
492 WriteDoubleNoTag(value, output);
494 void WireFormatLite::WriteBool(int field_number, bool value,
495 io::CodedOutputStream* output) {
496 WriteTag(field_number, WIRETYPE_VARINT, output);
497 WriteBoolNoTag(value, output);
499 void WireFormatLite::WriteEnum(int field_number, int value,
500 io::CodedOutputStream* output) {
501 WriteTag(field_number, WIRETYPE_VARINT, output);
502 WriteEnumNoTag(value, output);
505 void WireFormatLite::WriteString(int field_number, const string& value,
506 io::CodedOutputStream* output) {
507 // String is for UTF-8 text only
508 WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
509 GOOGLE_CHECK(value.size() <= kint32max);
510 output->WriteVarint32(value.size());
511 output->WriteString(value);
513 void WireFormatLite::WriteBytes(int field_number, const string& value,
514 io::CodedOutputStream* output) {
515 WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
516 GOOGLE_CHECK(value.size() <= kint32max);
517 output->WriteVarint32(value.size());
518 output->WriteString(value);
522 void WireFormatLite::WriteGroup(int field_number,
523 const MessageLite& value,
524 io::CodedOutputStream* output) {
525 WriteTag(field_number, WIRETYPE_START_GROUP, output);
526 value.SerializeWithCachedSizes(output);
527 WriteTag(field_number, WIRETYPE_END_GROUP, output);
530 void WireFormatLite::WriteMessage(int field_number,
531 const MessageLite& value,
532 io::CodedOutputStream* output) {
533 WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
534 const int size = value.GetCachedSize();
535 output->WriteVarint32(size);
536 value.SerializeWithCachedSizes(output);
539 void WireFormatLite::WriteGroupMaybeToArray(int field_number,
540 const MessageLite& value,
541 io::CodedOutputStream* output) {
542 WriteTag(field_number, WIRETYPE_START_GROUP, output);
543 const int size = value.GetCachedSize();
544 uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
545 if (target != NULL) {
546 uint8* end = value.SerializeWithCachedSizesToArray(target);
547 GOOGLE_DCHECK_EQ(end - target, size);
549 value.SerializeWithCachedSizes(output);
551 WriteTag(field_number, WIRETYPE_END_GROUP, output);
554 void WireFormatLite::WriteMessageMaybeToArray(int field_number,
555 const MessageLite& value,
556 io::CodedOutputStream* output) {
557 WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
558 const int size = value.GetCachedSize();
559 output->WriteVarint32(size);
560 uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
561 if (target != NULL) {
562 uint8* end = value.SerializeWithCachedSizesToArray(target);
563 GOOGLE_DCHECK_EQ(end - target, size);
565 value.SerializeWithCachedSizes(output);
569 bool WireFormatLite::ReadString(io::CodedInputStream* input,
571 // String is for UTF-8 text only
573 if (!input->ReadVarint32(&length)) return false;
574 if (!input->InternalReadStringInline(value, length)) return false;
577 bool WireFormatLite::ReadBytes(io::CodedInputStream* input,
580 if (!input->ReadVarint32(&length)) return false;
581 return input->InternalReadStringInline(value, length);
584 } // namespace internal
585 } // namespace protobuf
586 } // namespace google