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 (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_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 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::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 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 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 253 bool FieldSkipper::SkipField( 254 io::CodedInputStream* input, uint32 tag) { 255 return WireFormatLite::SkipField(input, tag); 256 } 257 258 bool FieldSkipper::SkipMessage(io::CodedInputStream* input) { 259 return WireFormatLite::SkipMessage(input); 260 } 261 262 void FieldSkipper::SkipUnknownEnum( 263 int /* field_number */, int /* value */) { 264 // Nothing. 265 } 266 267 bool CodedOutputStreamFieldSkipper::SkipField( 268 io::CodedInputStream* input, uint32 tag) { 269 return WireFormatLite::SkipField(input, tag, unknown_fields_); 270 } 271 272 bool CodedOutputStreamFieldSkipper::SkipMessage(io::CodedInputStream* input) { 273 return WireFormatLite::SkipMessage(input, unknown_fields_); 274 } 275 276 void CodedOutputStreamFieldSkipper::SkipUnknownEnum( 277 int field_number, int value) { 278 unknown_fields_->WriteVarint32(field_number); 279 unknown_fields_->WriteVarint64(value); 280 } 281 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 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 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 } 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 } 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 } 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 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 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 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 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 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 } 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