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 
SkipField(io::CodedInputStream * input,uint32 tag)111 bool WireFormatLite::SkipField(
112     io::CodedInputStream* input, uint32 tag) {
113   switch (WireFormatLite::GetTagWireType(tag)) {
114     case WireFormatLite::WIRETYPE_VARINT: {
115       uint64 value;
116       if (!input->ReadVarint64(&value)) return false;
117       return true;
118     }
119     case WireFormatLite::WIRETYPE_FIXED64: {
120       uint64 value;
121       if (!input->ReadLittleEndian64(&value)) return false;
122       return true;
123     }
124     case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
125       uint32 length;
126       if (!input->ReadVarint32(&length)) return false;
127       if (!input->Skip(length)) return false;
128       return true;
129     }
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))) {
138         return false;
139       }
140       return true;
141     }
142     case WireFormatLite::WIRETYPE_END_GROUP: {
143       return false;
144     }
145     case WireFormatLite::WIRETYPE_FIXED32: {
146       uint32 value;
147       if (!input->ReadLittleEndian32(&value)) return false;
148       return true;
149     }
150     default: {
151       return false;
152     }
153   }
154 }
155 
SkipField(io::CodedInputStream * input,uint32 tag,io::CodedOutputStream * output)156 bool WireFormatLite::SkipField(
157     io::CodedInputStream* input, uint32 tag, io::CodedOutputStream* output) {
158   switch (WireFormatLite::GetTagWireType(tag)) {
159     case WireFormatLite::WIRETYPE_VARINT: {
160       uint64 value;
161       if (!input->ReadVarint64(&value)) return false;
162       output->WriteVarint32(tag);
163       output->WriteVarint64(value);
164       return true;
165     }
166     case WireFormatLite::WIRETYPE_FIXED64: {
167       uint64 value;
168       if (!input->ReadLittleEndian64(&value)) return false;
169       output->WriteVarint32(tag);
170       output->WriteLittleEndian64(value);
171       return true;
172     }
173     case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
174       uint32 length;
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.
179       string temp;
180       if (!input->ReadString(&temp, length)) return false;
181       output->WriteString(temp);
182       return true;
183     }
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))) {
193         return false;
194       }
195       return true;
196     }
197     case WireFormatLite::WIRETYPE_END_GROUP: {
198       return false;
199     }
200     case WireFormatLite::WIRETYPE_FIXED32: {
201       uint32 value;
202       if (!input->ReadLittleEndian32(&value)) return false;
203       output->WriteVarint32(tag);
204       output->WriteLittleEndian32(value);
205       return true;
206     }
207     default: {
208       return false;
209     }
210   }
211 }
212 
SkipMessage(io::CodedInputStream * input)213 bool WireFormatLite::SkipMessage(io::CodedInputStream* input) {
214   while (true) {
215     uint32 tag = input->ReadTag();
216     if (tag == 0) {
217       // End of input.  This is a valid place to end, so return true.
218       return true;
219     }
220 
221     WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
222 
223     if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
224       // Must be the end of the message.
225       return true;
226     }
227 
228     if (!SkipField(input, tag)) return false;
229   }
230 }
231 
SkipMessage(io::CodedInputStream * input,io::CodedOutputStream * output)232 bool WireFormatLite::SkipMessage(io::CodedInputStream* input,
233     io::CodedOutputStream* output) {
234   while (true) {
235     uint32 tag = input->ReadTag();
236     if (tag == 0) {
237       // End of input.  This is a valid place to end, so return true.
238       return true;
239     }
240 
241     WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
242 
243     if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
244       output->WriteVarint32(tag);
245       // Must be the end of the message.
246       return true;
247     }
248 
249     if (!SkipField(input, tag, output)) return false;
250   }
251 }
252 
SkipField(io::CodedInputStream * input,uint32 tag)253 bool FieldSkipper::SkipField(
254     io::CodedInputStream* input, uint32 tag) {
255   return WireFormatLite::SkipField(input, tag);
256 }
257 
SkipMessage(io::CodedInputStream * input)258 bool FieldSkipper::SkipMessage(io::CodedInputStream* input) {
259   return WireFormatLite::SkipMessage(input);
260 }
261 
SkipUnknownEnum(int,int)262 void FieldSkipper::SkipUnknownEnum(
263     int /* field_number */, int /* value */) {
264   // Nothing.
265 }
266 
SkipField(io::CodedInputStream * input,uint32 tag)267 bool CodedOutputStreamFieldSkipper::SkipField(
268     io::CodedInputStream* input, uint32 tag) {
269   return WireFormatLite::SkipField(input, tag, unknown_fields_);
270 }
271 
SkipMessage(io::CodedInputStream * input)272 bool CodedOutputStreamFieldSkipper::SkipMessage(io::CodedInputStream* input) {
273   return WireFormatLite::SkipMessage(input, unknown_fields_);
274 }
275 
SkipUnknownEnum(int field_number,int value)276 void CodedOutputStreamFieldSkipper::SkipUnknownEnum(
277     int field_number, int value) {
278   unknown_fields_->WriteVarint32(field_number);
279   unknown_fields_->WriteVarint64(value);
280 }
281 
ReadPackedEnumNoInline(io::CodedInputStream * input,bool (* is_valid)(int),RepeatedField<int> * values)282 bool WireFormatLite::ReadPackedEnumNoInline(io::CodedInputStream* input,
283                                             bool (*is_valid)(int),
284                                             RepeatedField<int>* values) {
285   uint32 length;
286   if (!input->ReadVarint32(&length)) return false;
287   io::CodedInputStream::Limit limit = input->PushLimit(length);
288   while (input->BytesUntilLimit() > 0) {
289     int value;
290     if (!google::protobuf::internal::WireFormatLite::ReadPrimitive<
291         int, WireFormatLite::TYPE_ENUM>(input, &value)) {
292       return false;
293     }
294     if (is_valid(value)) {
295       values->Add(value);
296     }
297   }
298   input->PopLimit(limit);
299   return true;
300 }
301 
WriteInt32(int field_number,int32 value,io::CodedOutputStream * output)302 void WireFormatLite::WriteInt32(int field_number, int32 value,
303                                 io::CodedOutputStream* output) {
304   WriteTag(field_number, WIRETYPE_VARINT, output);
305   WriteInt32NoTag(value, output);
306 }
WriteInt64(int field_number,int64 value,io::CodedOutputStream * 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);
311 }
WriteUInt32(int field_number,uint32 value,io::CodedOutputStream * 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);
316 }
WriteUInt64(int field_number,uint64 value,io::CodedOutputStream * 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);
321 }
WriteSInt32(int field_number,int32 value,io::CodedOutputStream * 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);
326 }
WriteSInt64(int field_number,int64 value,io::CodedOutputStream * 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);
331 }
WriteFixed32(int field_number,uint32 value,io::CodedOutputStream * 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);
336 }
WriteFixed64(int field_number,uint64 value,io::CodedOutputStream * 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);
341 }
WriteSFixed32(int field_number,int32 value,io::CodedOutputStream * 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);
346 }
WriteSFixed64(int field_number,int64 value,io::CodedOutputStream * 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);
351 }
WriteFloat(int field_number,float value,io::CodedOutputStream * 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);
356 }
WriteDouble(int field_number,double value,io::CodedOutputStream * 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);
361 }
WriteBool(int field_number,bool value,io::CodedOutputStream * 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);
366 }
WriteEnum(int field_number,int value,io::CodedOutputStream * 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);
371 }
372 
WriteString(int field_number,const string & value,io::CodedOutputStream * 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);
380 }
WriteStringMaybeAliased(int field_number,const string & value,io::CodedOutputStream * output)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());
389 }
WriteBytes(int field_number,const string & value,io::CodedOutputStream * output)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);
396 }
WriteBytesMaybeAliased(int field_number,const string & value,io::CodedOutputStream * output)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());
404 }
405 
406 
WriteGroup(int field_number,const MessageLite & value,io::CodedOutputStream * output)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);
413 }
414 
WriteMessage(int field_number,const MessageLite & value,io::CodedOutputStream * 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);
422 }
423 
WriteGroupMaybeToArray(int field_number,const MessageLite & value,io::CodedOutputStream * 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);
433   } else {
434     value.SerializeWithCachedSizes(output);
435   }
436   WriteTag(field_number, WIRETYPE_END_GROUP, output);
437 }
438 
WriteMessageMaybeToArray(int field_number,const MessageLite & value,io::CodedOutputStream * 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);
449   } else {
450     value.SerializeWithCachedSizes(output);
451   }
452 }
453 
ReadString(io::CodedInputStream * input,string * value)454 bool WireFormatLite::ReadString(io::CodedInputStream* input,
455                                 string* value) {
456   // String is for UTF-8 text only
457   uint32 length;
458   if (!input->ReadVarint32(&length)) return false;
459   if (!input->InternalReadStringInline(value, length)) return false;
460   return true;
461 }
ReadBytes(io::CodedInputStream * input,string * value)462 bool WireFormatLite::ReadBytes(io::CodedInputStream* input,
463                                string* value) {
464   uint32 length;
465   if (!input->ReadVarint32(&length)) return false;
466   return input->InternalReadStringInline(value, length);
467 }
468 
469 }  // namespace internal
470 }  // namespace protobuf
471 }  // namespace google
472