Line data Source code
1 : // Protocol Buffers - Google's data interchange format
2 : // Copyright 2008 Google Inc. All rights reserved.
3 : // https://developers.google.com/protocol-buffers/
4 : //
5 : // Redistribution and use in source and binary forms, with or without
6 : // modification, are permitted provided that the following conditions are
7 : // met:
8 : //
9 : // * Redistributions of source code must retain the above copyright
10 : // notice, this list of conditions and the following disclaimer.
11 : // * Redistributions in binary form must reproduce the above
12 : // copyright notice, this list of conditions and the following disclaimer
13 : // in the documentation and/or other materials provided with the
14 : // distribution.
15 : // * Neither the name of Google Inc. nor the names of its
16 : // contributors may be used to endorse or promote products derived from
17 : // this software without specific prior written permission.
18 : //
19 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 :
31 : // Author: kenton@google.com (Kenton Varda)
32 : // Based on original Protocol Buffers design by
33 : // Sanjay Ghemawat, Jeff Dean, and others.
34 :
35 : #include <google/protobuf/wire_format_lite_inl.h>
36 :
37 : #include <stack>
38 : #include <string>
39 : #include <vector>
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 :
45 : namespace google {
46 : namespace protobuf {
47 : namespace internal {
48 :
49 : #ifndef _MSC_VER // MSVC doesn't like definitions of inline constants, GCC
50 : // requires them.
51 : const int WireFormatLite::kMessageSetItemStartTag;
52 : const int WireFormatLite::kMessageSetItemEndTag;
53 : const int WireFormatLite::kMessageSetTypeIdTag;
54 : const int WireFormatLite::kMessageSetMessageTag;
55 :
56 : #endif
57 :
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;
63 :
64 : const WireFormatLite::CppType
65 : WireFormatLite::kFieldTypeToCppTypeMap[MAX_FIELD_TYPE + 1] = {
66 : static_cast<CppType>(0), // 0 is reserved for errors
67 :
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
86 : };
87 :
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
109 : };
110 :
111 0 : bool WireFormatLite::SkipField(
112 : io::CodedInputStream* input, uint32 tag) {
113 0 : switch (WireFormatLite::GetTagWireType(tag)) {
114 : case WireFormatLite::WIRETYPE_VARINT: {
115 : uint64 value;
116 0 : if (!input->ReadVarint64(&value)) return false;
117 0 : return true;
118 : }
119 : case WireFormatLite::WIRETYPE_FIXED64: {
120 : uint64 value;
121 0 : if (!input->ReadLittleEndian64(&value)) return false;
122 0 : return true;
123 : }
124 : case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
125 : uint32 length;
126 0 : if (!input->ReadVarint32(&length)) return false;
127 0 : if (!input->Skip(length)) return false;
128 0 : return true;
129 : }
130 : case WireFormatLite::WIRETYPE_START_GROUP: {
131 0 : if (!input->IncrementRecursionDepth()) return false;
132 0 : if (!SkipMessage(input)) return false;
133 0 : input->DecrementRecursionDepth();
134 : // Check that the ending tag matched the starting tag.
135 0 : if (!input->LastTagWas(WireFormatLite::MakeTag(
136 : WireFormatLite::GetTagFieldNumber(tag),
137 : WireFormatLite::WIRETYPE_END_GROUP))) {
138 0 : return false;
139 : }
140 0 : return true;
141 : }
142 : case WireFormatLite::WIRETYPE_END_GROUP: {
143 0 : return false;
144 : }
145 : case WireFormatLite::WIRETYPE_FIXED32: {
146 : uint32 value;
147 0 : if (!input->ReadLittleEndian32(&value)) return false;
148 0 : return true;
149 : }
150 : default: {
151 0 : return false;
152 : }
153 : }
154 : }
155 :
156 0 : bool WireFormatLite::SkipField(
157 : io::CodedInputStream* input, uint32 tag, io::CodedOutputStream* output) {
158 0 : switch (WireFormatLite::GetTagWireType(tag)) {
159 : case WireFormatLite::WIRETYPE_VARINT: {
160 : uint64 value;
161 0 : if (!input->ReadVarint64(&value)) return false;
162 0 : output->WriteVarint32(tag);
163 0 : output->WriteVarint64(value);
164 0 : return true;
165 : }
166 : case WireFormatLite::WIRETYPE_FIXED64: {
167 : uint64 value;
168 0 : if (!input->ReadLittleEndian64(&value)) return false;
169 0 : output->WriteVarint32(tag);
170 0 : output->WriteLittleEndian64(value);
171 0 : return true;
172 : }
173 : case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
174 : uint32 length;
175 0 : if (!input->ReadVarint32(&length)) return false;
176 0 : output->WriteVarint32(tag);
177 0 : output->WriteVarint32(length);
178 : // TODO(mkilavuz): Provide API to prevent extra string copying.
179 0 : string temp;
180 0 : if (!input->ReadString(&temp, length)) return false;
181 0 : output->WriteString(temp);
182 0 : return true;
183 : }
184 : case WireFormatLite::WIRETYPE_START_GROUP: {
185 0 : output->WriteVarint32(tag);
186 0 : if (!input->IncrementRecursionDepth()) return false;
187 0 : if (!SkipMessage(input, output)) return false;
188 0 : input->DecrementRecursionDepth();
189 : // Check that the ending tag matched the starting tag.
190 0 : if (!input->LastTagWas(WireFormatLite::MakeTag(
191 : WireFormatLite::GetTagFieldNumber(tag),
192 : WireFormatLite::WIRETYPE_END_GROUP))) {
193 0 : return false;
194 : }
195 0 : return true;
196 : }
197 : case WireFormatLite::WIRETYPE_END_GROUP: {
198 0 : return false;
199 : }
200 : case WireFormatLite::WIRETYPE_FIXED32: {
201 : uint32 value;
202 0 : if (!input->ReadLittleEndian32(&value)) return false;
203 0 : output->WriteVarint32(tag);
204 0 : output->WriteLittleEndian32(value);
205 0 : return true;
206 : }
207 : default: {
208 0 : return false;
209 : }
210 : }
211 : }
212 :
213 0 : bool WireFormatLite::SkipMessage(io::CodedInputStream* input) {
214 : while (true) {
215 0 : uint32 tag = input->ReadTag();
216 0 : if (tag == 0) {
217 : // End of input. This is a valid place to end, so return true.
218 0 : return true;
219 : }
220 :
221 0 : WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
222 :
223 0 : if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
224 : // Must be the end of the message.
225 0 : return true;
226 : }
227 :
228 0 : if (!SkipField(input, tag)) return false;
229 0 : }
230 : }
231 :
232 0 : bool WireFormatLite::SkipMessage(io::CodedInputStream* input,
233 : io::CodedOutputStream* output) {
234 : while (true) {
235 0 : uint32 tag = input->ReadTag();
236 0 : if (tag == 0) {
237 : // End of input. This is a valid place to end, so return true.
238 0 : return true;
239 : }
240 :
241 0 : WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
242 :
243 0 : if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
244 0 : output->WriteVarint32(tag);
245 : // Must be the end of the message.
246 0 : return true;
247 : }
248 :
249 0 : if (!SkipField(input, tag, output)) return false;
250 0 : }
251 : }
252 :
253 0 : bool FieldSkipper::SkipField(
254 : io::CodedInputStream* input, uint32 tag) {
255 0 : return WireFormatLite::SkipField(input, tag);
256 : }
257 :
258 0 : bool FieldSkipper::SkipMessage(io::CodedInputStream* input) {
259 0 : return WireFormatLite::SkipMessage(input);
260 : }
261 :
262 0 : void FieldSkipper::SkipUnknownEnum(
263 : int /* field_number */, int /* value */) {
264 : // Nothing.
265 0 : }
266 :
267 0 : bool CodedOutputStreamFieldSkipper::SkipField(
268 : io::CodedInputStream* input, uint32 tag) {
269 0 : return WireFormatLite::SkipField(input, tag, unknown_fields_);
270 : }
271 :
272 0 : bool CodedOutputStreamFieldSkipper::SkipMessage(io::CodedInputStream* input) {
273 0 : return WireFormatLite::SkipMessage(input, unknown_fields_);
274 : }
275 :
276 0 : void CodedOutputStreamFieldSkipper::SkipUnknownEnum(
277 : int field_number, int value) {
278 0 : unknown_fields_->WriteVarint32(field_number);
279 0 : unknown_fields_->WriteVarint64(value);
280 0 : }
281 :
282 0 : bool WireFormatLite::ReadPackedEnumNoInline(io::CodedInputStream* input,
283 : bool (*is_valid)(int),
284 : RepeatedField<int>* values) {
285 : uint32 length;
286 0 : if (!input->ReadVarint32(&length)) return false;
287 0 : io::CodedInputStream::Limit limit = input->PushLimit(length);
288 0 : while (input->BytesUntilLimit() > 0) {
289 : int value;
290 0 : if (!google::protobuf::internal::WireFormatLite::ReadPrimitive<
291 0 : int, WireFormatLite::TYPE_ENUM>(input, &value)) {
292 0 : return false;
293 : }
294 0 : if (is_valid(value)) {
295 0 : values->Add(value);
296 : }
297 : }
298 0 : input->PopLimit(limit);
299 0 : return true;
300 : }
301 :
302 0 : void WireFormatLite::WriteInt32(int field_number, int32 value,
303 : io::CodedOutputStream* output) {
304 : WriteTag(field_number, WIRETYPE_VARINT, output);
305 : WriteInt32NoTag(value, output);
306 0 : }
307 0 : void WireFormatLite::WriteInt64(int field_number, int64 value,
308 : io::CodedOutputStream* output) {
309 : WriteTag(field_number, WIRETYPE_VARINT, output);
310 : WriteInt64NoTag(value, output);
311 0 : }
312 0 : void WireFormatLite::WriteUInt32(int field_number, uint32 value,
313 : io::CodedOutputStream* output) {
314 : WriteTag(field_number, WIRETYPE_VARINT, output);
315 : WriteUInt32NoTag(value, output);
316 0 : }
317 0 : void WireFormatLite::WriteUInt64(int field_number, uint64 value,
318 : io::CodedOutputStream* output) {
319 : WriteTag(field_number, WIRETYPE_VARINT, output);
320 : WriteUInt64NoTag(value, output);
321 0 : }
322 0 : void WireFormatLite::WriteSInt32(int field_number, int32 value,
323 : io::CodedOutputStream* output) {
324 : WriteTag(field_number, WIRETYPE_VARINT, output);
325 : WriteSInt32NoTag(value, output);
326 0 : }
327 0 : void WireFormatLite::WriteSInt64(int field_number, int64 value,
328 : io::CodedOutputStream* output) {
329 : WriteTag(field_number, WIRETYPE_VARINT, output);
330 : WriteSInt64NoTag(value, output);
331 0 : }
332 0 : void WireFormatLite::WriteFixed32(int field_number, uint32 value,
333 : io::CodedOutputStream* output) {
334 : WriteTag(field_number, WIRETYPE_FIXED32, output);
335 : WriteFixed32NoTag(value, output);
336 0 : }
337 0 : void WireFormatLite::WriteFixed64(int field_number, uint64 value,
338 : io::CodedOutputStream* output) {
339 : WriteTag(field_number, WIRETYPE_FIXED64, output);
340 : WriteFixed64NoTag(value, output);
341 0 : }
342 0 : void WireFormatLite::WriteSFixed32(int field_number, int32 value,
343 : io::CodedOutputStream* output) {
344 : WriteTag(field_number, WIRETYPE_FIXED32, output);
345 : WriteSFixed32NoTag(value, output);
346 0 : }
347 0 : void WireFormatLite::WriteSFixed64(int field_number, int64 value,
348 : io::CodedOutputStream* output) {
349 : WriteTag(field_number, WIRETYPE_FIXED64, output);
350 : WriteSFixed64NoTag(value, output);
351 0 : }
352 0 : void WireFormatLite::WriteFloat(int field_number, float value,
353 : io::CodedOutputStream* output) {
354 : WriteTag(field_number, WIRETYPE_FIXED32, output);
355 : WriteFloatNoTag(value, output);
356 0 : }
357 0 : void WireFormatLite::WriteDouble(int field_number, double value,
358 : io::CodedOutputStream* output) {
359 : WriteTag(field_number, WIRETYPE_FIXED64, output);
360 : WriteDoubleNoTag(value, output);
361 0 : }
362 0 : void WireFormatLite::WriteBool(int field_number, bool value,
363 : io::CodedOutputStream* output) {
364 : WriteTag(field_number, WIRETYPE_VARINT, output);
365 0 : WriteBoolNoTag(value, output);
366 0 : }
367 0 : void WireFormatLite::WriteEnum(int field_number, int value,
368 : io::CodedOutputStream* output) {
369 : WriteTag(field_number, WIRETYPE_VARINT, output);
370 : WriteEnumNoTag(value, output);
371 0 : }
372 :
373 0 : 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 0 : GOOGLE_CHECK(value.size() <= kint32max);
378 0 : output->WriteVarint32(value.size());
379 0 : output->WriteString(value);
380 0 : }
381 0 : 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 0 : GOOGLE_CHECK(value.size() <= kint32max);
387 0 : output->WriteVarint32(value.size());
388 0 : output->WriteRawMaybeAliased(value.data(), value.size());
389 0 : }
390 0 : void WireFormatLite::WriteBytes(int field_number, const string& value,
391 : io::CodedOutputStream* output) {
392 : WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
393 0 : GOOGLE_CHECK(value.size() <= kint32max);
394 0 : output->WriteVarint32(value.size());
395 0 : output->WriteString(value);
396 0 : }
397 0 : void WireFormatLite::WriteBytesMaybeAliased(
398 : int field_number, const string& value,
399 : io::CodedOutputStream* output) {
400 : WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
401 0 : GOOGLE_CHECK(value.size() <= kint32max);
402 0 : output->WriteVarint32(value.size());
403 0 : output->WriteRawMaybeAliased(value.data(), value.size());
404 0 : }
405 :
406 :
407 0 : void WireFormatLite::WriteGroup(int field_number,
408 : const MessageLite& value,
409 : io::CodedOutputStream* output) {
410 : WriteTag(field_number, WIRETYPE_START_GROUP, output);
411 0 : value.SerializeWithCachedSizes(output);
412 : WriteTag(field_number, WIRETYPE_END_GROUP, output);
413 0 : }
414 :
415 0 : void WireFormatLite::WriteMessage(int field_number,
416 : const MessageLite& value,
417 : io::CodedOutputStream* output) {
418 : WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
419 0 : const int size = value.GetCachedSize();
420 0 : output->WriteVarint32(size);
421 0 : value.SerializeWithCachedSizes(output);
422 0 : }
423 :
424 0 : void WireFormatLite::WriteGroupMaybeToArray(int field_number,
425 : const MessageLite& value,
426 : io::CodedOutputStream* output) {
427 : WriteTag(field_number, WIRETYPE_START_GROUP, output);
428 0 : const int size = value.GetCachedSize();
429 0 : uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
430 0 : if (target != NULL) {
431 0 : uint8* end = value.SerializeWithCachedSizesToArray(target);
432 0 : GOOGLE_DCHECK_EQ(end - target, size);
433 : } else {
434 0 : value.SerializeWithCachedSizes(output);
435 : }
436 : WriteTag(field_number, WIRETYPE_END_GROUP, output);
437 0 : }
438 :
439 0 : void WireFormatLite::WriteMessageMaybeToArray(int field_number,
440 : const MessageLite& value,
441 : io::CodedOutputStream* output) {
442 : WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
443 0 : const int size = value.GetCachedSize();
444 0 : output->WriteVarint32(size);
445 0 : uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
446 0 : if (target != NULL) {
447 0 : uint8* end = value.SerializeWithCachedSizesToArray(target);
448 0 : GOOGLE_DCHECK_EQ(end - target, size);
449 : } else {
450 0 : value.SerializeWithCachedSizes(output);
451 : }
452 0 : }
453 :
454 738 : bool WireFormatLite::ReadString(io::CodedInputStream* input,
455 : string* value) {
456 : // String is for UTF-8 text only
457 : uint32 length;
458 738 : if (!input->ReadVarint32(&length)) return false;
459 1476 : if (!input->InternalReadStringInline(value, length)) return false;
460 738 : return true;
461 : }
462 0 : bool WireFormatLite::ReadBytes(io::CodedInputStream* input,
463 : string* value) {
464 : uint32 length;
465 0 : if (!input->ReadVarint32(&length)) return false;
466 0 : return input->InternalReadStringInline(value, length);
467 : }
468 :
469 : } // namespace internal
470 : } // namespace protobuf
471 9 : } // namespace google
|