1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
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>
49 #ifndef _MSC_VER // MSVC doesn't like definitions of inline constants, GCC
51 const int WireFormatLite::kMessageSetItemStartTag;
52 const int WireFormatLite::kMessageSetItemEndTag;
53 const int WireFormatLite::kMessageSetTypeIdTag;
54 const int WireFormatLite::kMessageSetMessageTag;
58 const int WireFormatLite::kMessageSetItemTagsSize =
59 io::CodedOutputStream::StaticVarintSize32<kMessageSetItemStartTag>::value +
60 io::CodedOutputStream::StaticVarintSize32<kMessageSetItemEndTag>::value +
61 io::CodedOutputStream::StaticVarintSize32<kMessageSetTypeIdTag>::value +
62 io::CodedOutputStream::StaticVarintSize32<kMessageSetMessageTag>::value;
64 const WireFormatLite::CppType
65 WireFormatLite::kFieldTypeToCppTypeMap[MAX_FIELD_TYPE + 1] = {
66 static_cast<CppType>(0), // 0 is reserved for errors
68 CPPTYPE_DOUBLE, // TYPE_DOUBLE
69 CPPTYPE_FLOAT, // TYPE_FLOAT
70 CPPTYPE_INT64, // TYPE_INT64
71 CPPTYPE_UINT64, // TYPE_UINT64
72 CPPTYPE_INT32, // TYPE_INT32
73 CPPTYPE_UINT64, // TYPE_FIXED64
74 CPPTYPE_UINT32, // TYPE_FIXED32
75 CPPTYPE_BOOL, // TYPE_BOOL
76 CPPTYPE_STRING, // TYPE_STRING
77 CPPTYPE_MESSAGE, // TYPE_GROUP
78 CPPTYPE_MESSAGE, // TYPE_MESSAGE
79 CPPTYPE_STRING, // TYPE_BYTES
80 CPPTYPE_UINT32, // TYPE_UINT32
81 CPPTYPE_ENUM, // TYPE_ENUM
82 CPPTYPE_INT32, // TYPE_SFIXED32
83 CPPTYPE_INT64, // TYPE_SFIXED64
84 CPPTYPE_INT32, // TYPE_SINT32
85 CPPTYPE_INT64, // TYPE_SINT64
88 const WireFormatLite::WireType
89 WireFormatLite::kWireTypeForFieldType[MAX_FIELD_TYPE + 1] = {
90 static_cast<WireFormatLite::WireType>(-1), // invalid
91 WireFormatLite::WIRETYPE_FIXED64, // TYPE_DOUBLE
92 WireFormatLite::WIRETYPE_FIXED32, // TYPE_FLOAT
93 WireFormatLite::WIRETYPE_VARINT, // TYPE_INT64
94 WireFormatLite::WIRETYPE_VARINT, // TYPE_UINT64
95 WireFormatLite::WIRETYPE_VARINT, // TYPE_INT32
96 WireFormatLite::WIRETYPE_FIXED64, // TYPE_FIXED64
97 WireFormatLite::WIRETYPE_FIXED32, // TYPE_FIXED32
98 WireFormatLite::WIRETYPE_VARINT, // TYPE_BOOL
99 WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_STRING
100 WireFormatLite::WIRETYPE_START_GROUP, // TYPE_GROUP
101 WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_MESSAGE
102 WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_BYTES
103 WireFormatLite::WIRETYPE_VARINT, // TYPE_UINT32
104 WireFormatLite::WIRETYPE_VARINT, // TYPE_ENUM
105 WireFormatLite::WIRETYPE_FIXED32, // TYPE_SFIXED32
106 WireFormatLite::WIRETYPE_FIXED64, // TYPE_SFIXED64
107 WireFormatLite::WIRETYPE_VARINT, // TYPE_SINT32
108 WireFormatLite::WIRETYPE_VARINT, // TYPE_SINT64
111 bool WireFormatLite::SkipField(
112 io::CodedInputStream* input, uint32 tag) {
113 switch (WireFormatLite::GetTagWireType(tag)) {
114 case WireFormatLite::WIRETYPE_VARINT: {
116 if (!input->ReadVarint64(&value)) return false;
119 case WireFormatLite::WIRETYPE_FIXED64: {
121 if (!input->ReadLittleEndian64(&value)) return false;
124 case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
126 if (!input->ReadVarint32(&length)) return false;
127 if (!input->Skip(length)) return false;
130 case WireFormatLite::WIRETYPE_START_GROUP: {
131 if (!input->IncrementRecursionDepth()) return false;
132 if (!SkipMessage(input)) return false;
133 input->DecrementRecursionDepth();
134 // Check that the ending tag matched the starting tag.
135 if (!input->LastTagWas(WireFormatLite::MakeTag(
136 WireFormatLite::GetTagFieldNumber(tag),
137 WireFormatLite::WIRETYPE_END_GROUP))) {
142 case WireFormatLite::WIRETYPE_END_GROUP: {
145 case WireFormatLite::WIRETYPE_FIXED32: {
147 if (!input->ReadLittleEndian32(&value)) return false;
156 bool WireFormatLite::SkipField(
157 io::CodedInputStream* input, uint32 tag, io::CodedOutputStream* output) {
158 switch (WireFormatLite::GetTagWireType(tag)) {
159 case WireFormatLite::WIRETYPE_VARINT: {
161 if (!input->ReadVarint64(&value)) return false;
162 output->WriteVarint32(tag);
163 output->WriteVarint64(value);
166 case WireFormatLite::WIRETYPE_FIXED64: {
168 if (!input->ReadLittleEndian64(&value)) return false;
169 output->WriteVarint32(tag);
170 output->WriteLittleEndian64(value);
173 case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
175 if (!input->ReadVarint32(&length)) return false;
176 output->WriteVarint32(tag);
177 output->WriteVarint32(length);
178 // TODO(mkilavuz): Provide API to prevent extra string copying.
180 if (!input->ReadString(&temp, length)) return false;
181 output->WriteString(temp);
184 case WireFormatLite::WIRETYPE_START_GROUP: {
185 output->WriteVarint32(tag);
186 if (!input->IncrementRecursionDepth()) return false;
187 if (!SkipMessage(input, output)) return false;
188 input->DecrementRecursionDepth();
189 // Check that the ending tag matched the starting tag.
190 if (!input->LastTagWas(WireFormatLite::MakeTag(
191 WireFormatLite::GetTagFieldNumber(tag),
192 WireFormatLite::WIRETYPE_END_GROUP))) {
197 case WireFormatLite::WIRETYPE_END_GROUP: {
200 case WireFormatLite::WIRETYPE_FIXED32: {
202 if (!input->ReadLittleEndian32(&value)) return false;
203 output->WriteVarint32(tag);
204 output->WriteLittleEndian32(value);
213 bool WireFormatLite::SkipMessage(io::CodedInputStream* input) {
215 uint32 tag = input->ReadTag();
217 // End of input. This is a valid place to end, so return true.
221 WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
223 if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
224 // Must be the end of the message.
228 if (!SkipField(input, tag)) return false;
232 bool WireFormatLite::SkipMessage(io::CodedInputStream* input,
233 io::CodedOutputStream* output) {
235 uint32 tag = input->ReadTag();
237 // End of input. This is a valid place to end, so return true.
241 WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
243 if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
244 output->WriteVarint32(tag);
245 // Must be the end of the message.
249 if (!SkipField(input, tag, output)) return false;
253 bool FieldSkipper::SkipField(
254 io::CodedInputStream* input, uint32 tag) {
255 return WireFormatLite::SkipField(input, tag);
258 bool FieldSkipper::SkipMessage(io::CodedInputStream* input) {
259 return WireFormatLite::SkipMessage(input);
262 void FieldSkipper::SkipUnknownEnum(
263 int /* field_number */, int /* value */) {
267 bool CodedOutputStreamFieldSkipper::SkipField(
268 io::CodedInputStream* input, uint32 tag) {
269 return WireFormatLite::SkipField(input, tag, unknown_fields_);
272 bool CodedOutputStreamFieldSkipper::SkipMessage(io::CodedInputStream* input) {
273 return WireFormatLite::SkipMessage(input, unknown_fields_);
276 void CodedOutputStreamFieldSkipper::SkipUnknownEnum(
277 int field_number, int value) {
278 unknown_fields_->WriteVarint32(field_number);
279 unknown_fields_->WriteVarint64(value);
282 bool WireFormatLite::ReadPackedEnumNoInline(io::CodedInputStream* input,
283 bool (*is_valid)(int),
284 RepeatedField<int>* values) {
286 if (!input->ReadVarint32(&length)) return false;
287 io::CodedInputStream::Limit limit = input->PushLimit(length);
288 while (input->BytesUntilLimit() > 0) {
290 if (!google::protobuf::internal::WireFormatLite::ReadPrimitive<
291 int, WireFormatLite::TYPE_ENUM>(input, &value)) {
294 if (is_valid(value)) {
298 input->PopLimit(limit);
302 void WireFormatLite::WriteInt32(int field_number, int32 value,
303 io::CodedOutputStream* output) {
304 WriteTag(field_number, WIRETYPE_VARINT, output);
305 WriteInt32NoTag(value, output);
307 void WireFormatLite::WriteInt64(int field_number, int64 value,
308 io::CodedOutputStream* output) {
309 WriteTag(field_number, WIRETYPE_VARINT, output);
310 WriteInt64NoTag(value, output);
312 void WireFormatLite::WriteUInt32(int field_number, uint32 value,
313 io::CodedOutputStream* output) {
314 WriteTag(field_number, WIRETYPE_VARINT, output);
315 WriteUInt32NoTag(value, output);
317 void WireFormatLite::WriteUInt64(int field_number, uint64 value,
318 io::CodedOutputStream* output) {
319 WriteTag(field_number, WIRETYPE_VARINT, output);
320 WriteUInt64NoTag(value, output);
322 void WireFormatLite::WriteSInt32(int field_number, int32 value,
323 io::CodedOutputStream* output) {
324 WriteTag(field_number, WIRETYPE_VARINT, output);
325 WriteSInt32NoTag(value, output);
327 void WireFormatLite::WriteSInt64(int field_number, int64 value,
328 io::CodedOutputStream* output) {
329 WriteTag(field_number, WIRETYPE_VARINT, output);
330 WriteSInt64NoTag(value, output);
332 void WireFormatLite::WriteFixed32(int field_number, uint32 value,
333 io::CodedOutputStream* output) {
334 WriteTag(field_number, WIRETYPE_FIXED32, output);
335 WriteFixed32NoTag(value, output);
337 void WireFormatLite::WriteFixed64(int field_number, uint64 value,
338 io::CodedOutputStream* output) {
339 WriteTag(field_number, WIRETYPE_FIXED64, output);
340 WriteFixed64NoTag(value, output);
342 void WireFormatLite::WriteSFixed32(int field_number, int32 value,
343 io::CodedOutputStream* output) {
344 WriteTag(field_number, WIRETYPE_FIXED32, output);
345 WriteSFixed32NoTag(value, output);
347 void WireFormatLite::WriteSFixed64(int field_number, int64 value,
348 io::CodedOutputStream* output) {
349 WriteTag(field_number, WIRETYPE_FIXED64, output);
350 WriteSFixed64NoTag(value, output);
352 void WireFormatLite::WriteFloat(int field_number, float value,
353 io::CodedOutputStream* output) {
354 WriteTag(field_number, WIRETYPE_FIXED32, output);
355 WriteFloatNoTag(value, output);
357 void WireFormatLite::WriteDouble(int field_number, double value,
358 io::CodedOutputStream* output) {
359 WriteTag(field_number, WIRETYPE_FIXED64, output);
360 WriteDoubleNoTag(value, output);
362 void WireFormatLite::WriteBool(int field_number, bool value,
363 io::CodedOutputStream* output) {
364 WriteTag(field_number, WIRETYPE_VARINT, output);
365 WriteBoolNoTag(value, output);
367 void WireFormatLite::WriteEnum(int field_number, int value,
368 io::CodedOutputStream* output) {
369 WriteTag(field_number, WIRETYPE_VARINT, output);
370 WriteEnumNoTag(value, output);
373 void WireFormatLite::WriteString(int field_number, const string& value,
374 io::CodedOutputStream* output) {
375 // String is for UTF-8 text only
376 WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
377 GOOGLE_CHECK(value.size() <= kint32max);
378 output->WriteVarint32(value.size());
379 output->WriteString(value);
381 void WireFormatLite::WriteStringMaybeAliased(
382 int field_number, const string& value,
383 io::CodedOutputStream* output) {
384 // String is for UTF-8 text only
385 WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
386 GOOGLE_CHECK(value.size() <= kint32max);
387 output->WriteVarint32(value.size());
388 output->WriteRawMaybeAliased(value.data(), value.size());
390 void WireFormatLite::WriteBytes(int field_number, const string& value,
391 io::CodedOutputStream* output) {
392 WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
393 GOOGLE_CHECK(value.size() <= kint32max);
394 output->WriteVarint32(value.size());
395 output->WriteString(value);
397 void WireFormatLite::WriteBytesMaybeAliased(
398 int field_number, const string& value,
399 io::CodedOutputStream* output) {
400 WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
401 GOOGLE_CHECK(value.size() <= kint32max);
402 output->WriteVarint32(value.size());
403 output->WriteRawMaybeAliased(value.data(), value.size());
407 void WireFormatLite::WriteGroup(int field_number,
408 const MessageLite& value,
409 io::CodedOutputStream* output) {
410 WriteTag(field_number, WIRETYPE_START_GROUP, output);
411 value.SerializeWithCachedSizes(output);
412 WriteTag(field_number, WIRETYPE_END_GROUP, output);
415 void WireFormatLite::WriteMessage(int field_number,
416 const MessageLite& value,
417 io::CodedOutputStream* output) {
418 WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
419 const int size = value.GetCachedSize();
420 output->WriteVarint32(size);
421 value.SerializeWithCachedSizes(output);
424 void WireFormatLite::WriteGroupMaybeToArray(int field_number,
425 const MessageLite& value,
426 io::CodedOutputStream* output) {
427 WriteTag(field_number, WIRETYPE_START_GROUP, output);
428 const int size = value.GetCachedSize();
429 uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
430 if (target != NULL) {
431 uint8* end = value.SerializeWithCachedSizesToArray(target);
432 GOOGLE_DCHECK_EQ(end - target, size);
434 value.SerializeWithCachedSizes(output);
436 WriteTag(field_number, WIRETYPE_END_GROUP, output);
439 void WireFormatLite::WriteMessageMaybeToArray(int field_number,
440 const MessageLite& value,
441 io::CodedOutputStream* output) {
442 WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
443 const int size = value.GetCachedSize();
444 output->WriteVarint32(size);
445 uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
446 if (target != NULL) {
447 uint8* end = value.SerializeWithCachedSizesToArray(target);
448 GOOGLE_DCHECK_EQ(end - target, size);
450 value.SerializeWithCachedSizes(output);
454 bool WireFormatLite::ReadString(io::CodedInputStream* input,
456 // String is for UTF-8 text only
458 if (!input->ReadVarint32(&length)) return false;
459 if (!input->InternalReadStringInline(value, length)) return false;
462 bool WireFormatLite::ReadBytes(io::CodedInputStream* input,
465 if (!input->ReadVarint32(&length)) return false;
466 return input->InternalReadStringInline(value, length);
469 } // namespace internal
470 } // namespace protobuf
471 } // namespace google