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 (at) 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 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 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 175 bool FieldSkipper::SkipField( 176 io::CodedInputStream* input, uint32 tag) { 177 return WireFormatLite::SkipField(input, tag); 178 } 179 180 bool FieldSkipper::SkipMessage(io::CodedInputStream* input) { 181 return WireFormatLite::SkipMessage(input); 182 } 183 184 void FieldSkipper::SkipUnknownEnum( 185 int field_number, int value) { 186 // Nothing. 187 } 188 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 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 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 } 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 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 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 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 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 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 } 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