• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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 //  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.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::VarintSize32(kMessageSetItemStartTag) +
60   io::CodedOutputStream::VarintSize32(kMessageSetItemEndTag) +
61   io::CodedOutputStream::VarintSize32(kMessageSetTypeIdTag) +
62   io::CodedOutputStream::VarintSize32(kMessageSetMessageTag);
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 
SkipMessage(io::CodedInputStream * input)156 bool WireFormatLite::SkipMessage(io::CodedInputStream* input) {
157   while(true) {
158     uint32 tag = input->ReadTag();
159     if (tag == 0) {
160       // End of input.  This is a valid place to end, so return true.
161       return true;
162     }
163 
164     WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
165 
166     if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
167       // Must be the end of the message.
168       return true;
169     }
170 
171     if (!SkipField(input, tag)) return false;
172   }
173 }
174 
SkipField(io::CodedInputStream * input,uint32 tag)175 bool FieldSkipper::SkipField(
176     io::CodedInputStream* input, uint32 tag) {
177   return WireFormatLite::SkipField(input, tag);
178 }
179 
SkipMessage(io::CodedInputStream * input)180 bool FieldSkipper::SkipMessage(io::CodedInputStream* input) {
181   return WireFormatLite::SkipMessage(input);
182 }
183 
SkipUnknownEnum(int field_number,int value)184 void FieldSkipper::SkipUnknownEnum(
185     int field_number, int value) {
186   // Nothing.
187 }
188 
ReadPackedEnumNoInline(io::CodedInputStream * input,bool (* is_valid)(int),RepeatedField<int> * values)189 bool WireFormatLite::ReadPackedEnumNoInline(io::CodedInputStream* input,
190                                             bool (*is_valid)(int),
191                                             RepeatedField<int>* values) {
192   uint32 length;
193   if (!input->ReadVarint32(&length)) return false;
194   io::CodedInputStream::Limit limit = input->PushLimit(length);
195   while (input->BytesUntilLimit() > 0) {
196     int value;
197     if (!google::protobuf::internal::WireFormatLite::ReadPrimitive<
198         int, WireFormatLite::TYPE_ENUM>(input, &value)) {
199       return false;
200     }
201     if (is_valid(value)) {
202       values->Add(value);
203     }
204   }
205   input->PopLimit(limit);
206   return true;
207 }
208 
WriteInt32(int field_number,int32 value,io::CodedOutputStream * output)209 void WireFormatLite::WriteInt32(int field_number, int32 value,
210                                 io::CodedOutputStream* output) {
211   WriteTag(field_number, WIRETYPE_VARINT, output);
212   WriteInt32NoTag(value, output);
213 }
WriteInt64(int field_number,int64 value,io::CodedOutputStream * output)214 void WireFormatLite::WriteInt64(int field_number, int64 value,
215                                 io::CodedOutputStream* output) {
216   WriteTag(field_number, WIRETYPE_VARINT, output);
217   WriteInt64NoTag(value, output);
218 }
WriteUInt32(int field_number,uint32 value,io::CodedOutputStream * output)219 void WireFormatLite::WriteUInt32(int field_number, uint32 value,
220                                  io::CodedOutputStream* output) {
221   WriteTag(field_number, WIRETYPE_VARINT, output);
222   WriteUInt32NoTag(value, output);
223 }
WriteUInt64(int field_number,uint64 value,io::CodedOutputStream * output)224 void WireFormatLite::WriteUInt64(int field_number, uint64 value,
225                                  io::CodedOutputStream* output) {
226   WriteTag(field_number, WIRETYPE_VARINT, output);
227   WriteUInt64NoTag(value, output);
228 }
WriteSInt32(int field_number,int32 value,io::CodedOutputStream * output)229 void WireFormatLite::WriteSInt32(int field_number, int32 value,
230                                  io::CodedOutputStream* output) {
231   WriteTag(field_number, WIRETYPE_VARINT, output);
232   WriteSInt32NoTag(value, output);
233 }
WriteSInt64(int field_number,int64 value,io::CodedOutputStream * output)234 void WireFormatLite::WriteSInt64(int field_number, int64 value,
235                                  io::CodedOutputStream* output) {
236   WriteTag(field_number, WIRETYPE_VARINT, output);
237   WriteSInt64NoTag(value, output);
238 }
WriteFixed32(int field_number,uint32 value,io::CodedOutputStream * output)239 void WireFormatLite::WriteFixed32(int field_number, uint32 value,
240                                   io::CodedOutputStream* output) {
241   WriteTag(field_number, WIRETYPE_FIXED32, output);
242   WriteFixed32NoTag(value, output);
243 }
WriteFixed64(int field_number,uint64 value,io::CodedOutputStream * output)244 void WireFormatLite::WriteFixed64(int field_number, uint64 value,
245                                   io::CodedOutputStream* output) {
246   WriteTag(field_number, WIRETYPE_FIXED64, output);
247   WriteFixed64NoTag(value, output);
248 }
WriteSFixed32(int field_number,int32 value,io::CodedOutputStream * output)249 void WireFormatLite::WriteSFixed32(int field_number, int32 value,
250                                    io::CodedOutputStream* output) {
251   WriteTag(field_number, WIRETYPE_FIXED32, output);
252   WriteSFixed32NoTag(value, output);
253 }
WriteSFixed64(int field_number,int64 value,io::CodedOutputStream * output)254 void WireFormatLite::WriteSFixed64(int field_number, int64 value,
255                                    io::CodedOutputStream* output) {
256   WriteTag(field_number, WIRETYPE_FIXED64, output);
257   WriteSFixed64NoTag(value, output);
258 }
WriteFloat(int field_number,float value,io::CodedOutputStream * output)259 void WireFormatLite::WriteFloat(int field_number, float value,
260                                 io::CodedOutputStream* output) {
261   WriteTag(field_number, WIRETYPE_FIXED32, output);
262   WriteFloatNoTag(value, output);
263 }
WriteDouble(int field_number,double value,io::CodedOutputStream * output)264 void WireFormatLite::WriteDouble(int field_number, double value,
265                                  io::CodedOutputStream* output) {
266   WriteTag(field_number, WIRETYPE_FIXED64, output);
267   WriteDoubleNoTag(value, output);
268 }
WriteBool(int field_number,bool value,io::CodedOutputStream * output)269 void WireFormatLite::WriteBool(int field_number, bool value,
270                                io::CodedOutputStream* output) {
271   WriteTag(field_number, WIRETYPE_VARINT, output);
272   WriteBoolNoTag(value, output);
273 }
WriteEnum(int field_number,int value,io::CodedOutputStream * output)274 void WireFormatLite::WriteEnum(int field_number, int value,
275                                io::CodedOutputStream* output) {
276   WriteTag(field_number, WIRETYPE_VARINT, output);
277   WriteEnumNoTag(value, output);
278 }
279 
WriteString(int field_number,const string & value,io::CodedOutputStream * output)280 void WireFormatLite::WriteString(int field_number, const string& value,
281                                  io::CodedOutputStream* output) {
282   // String is for UTF-8 text only
283   WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
284   output->WriteVarint32(value.size());
285   output->WriteString(value);
286 }
WriteBytes(int field_number,const string & value,io::CodedOutputStream * output)287 void WireFormatLite::WriteBytes(int field_number, const string& value,
288                                 io::CodedOutputStream* output) {
289   WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
290   output->WriteVarint32(value.size());
291   output->WriteString(value);
292 }
293 
294 
WriteGroup(int field_number,const MessageLite & value,io::CodedOutputStream * output)295 void WireFormatLite::WriteGroup(int field_number,
296                                 const MessageLite& value,
297                                 io::CodedOutputStream* output) {
298   WriteTag(field_number, WIRETYPE_START_GROUP, output);
299   value.SerializeWithCachedSizes(output);
300   WriteTag(field_number, WIRETYPE_END_GROUP, output);
301 }
302 
WriteMessage(int field_number,const MessageLite & value,io::CodedOutputStream * output)303 void WireFormatLite::WriteMessage(int field_number,
304                                   const MessageLite& value,
305                                   io::CodedOutputStream* output) {
306   WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
307   const int size = value.GetCachedSize();
308   output->WriteVarint32(size);
309   value.SerializeWithCachedSizes(output);
310 }
311 
WriteGroupMaybeToArray(int field_number,const MessageLite & value,io::CodedOutputStream * output)312 void WireFormatLite::WriteGroupMaybeToArray(int field_number,
313                                             const MessageLite& value,
314                                             io::CodedOutputStream* output) {
315   WriteTag(field_number, WIRETYPE_START_GROUP, output);
316   const int size = value.GetCachedSize();
317   uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
318   if (target != NULL) {
319     uint8* end = value.SerializeWithCachedSizesToArray(target);
320     GOOGLE_DCHECK_EQ(end - target, size);
321   } else {
322     value.SerializeWithCachedSizes(output);
323   }
324   WriteTag(field_number, WIRETYPE_END_GROUP, output);
325 }
326 
WriteMessageMaybeToArray(int field_number,const MessageLite & value,io::CodedOutputStream * output)327 void WireFormatLite::WriteMessageMaybeToArray(int field_number,
328                                               const MessageLite& value,
329                                               io::CodedOutputStream* output) {
330   WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
331   const int size = value.GetCachedSize();
332   output->WriteVarint32(size);
333   uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
334   if (target != NULL) {
335     uint8* end = value.SerializeWithCachedSizesToArray(target);
336     GOOGLE_DCHECK_EQ(end - target, size);
337   } else {
338     value.SerializeWithCachedSizes(output);
339   }
340 }
341 
ReadString(io::CodedInputStream * input,string * value)342 bool WireFormatLite::ReadString(io::CodedInputStream* input,
343                                 string* value) {
344   // String is for UTF-8 text only
345   uint32 length;
346   if (!input->ReadVarint32(&length)) return false;
347   if (!input->InternalReadStringInline(value, length)) return false;
348   return true;
349 }
ReadBytes(io::CodedInputStream * input,string * value)350 bool WireFormatLite::ReadBytes(io::CodedInputStream* input,
351                                string* value) {
352   uint32 length;
353   if (!input->ReadVarint32(&length)) return false;
354   return input->InternalReadStringInline(value, length);
355 }
356 
357 }  // namespace internal
358 }  // namespace protobuf
359 }  // namespace google
360