wire_format_lite.cc revision d0332953cda33fb4f8e24ebff9c49159b69c43d6
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 45namespace google { 46namespace protobuf { 47namespace internal { 48 49#ifndef _MSC_VER // MSVC doesn't like definitions of inline constants, GCC 50 // requires them. 51const int WireFormatLite::kMessageSetItemStartTag; 52const int WireFormatLite::kMessageSetItemEndTag; 53const int WireFormatLite::kMessageSetTypeIdTag; 54const int WireFormatLite::kMessageSetMessageTag; 55 56#endif 57 58const int WireFormatLite::kMessageSetItemTagsSize = 59 io::CodedOutputStream::VarintSize32(kMessageSetItemStartTag) + 60 io::CodedOutputStream::VarintSize32(kMessageSetItemEndTag) + 61 io::CodedOutputStream::VarintSize32(kMessageSetTypeIdTag) + 62 io::CodedOutputStream::VarintSize32(kMessageSetMessageTag); 63 64const WireFormatLite::CppType 65WireFormatLite::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 88const WireFormatLite::WireType 89WireFormatLite::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 111bool 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 156bool 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 175bool FieldSkipper::SkipField( 176 io::CodedInputStream* input, uint32 tag) { 177 return WireFormatLite::SkipField(input, tag); 178} 179 180bool FieldSkipper::SkipMessage(io::CodedInputStream* input) { 181 return WireFormatLite::SkipMessage(input); 182} 183 184void FieldSkipper::SkipUnknownEnum( 185 int field_number, int value) { 186 // Nothing. 187} 188 189bool 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 209void WireFormatLite::WriteInt32(int field_number, int32 value, 210 io::CodedOutputStream* output) { 211 WriteTag(field_number, WIRETYPE_VARINT, output); 212 WriteInt32NoTag(value, output); 213} 214void WireFormatLite::WriteInt64(int field_number, int64 value, 215 io::CodedOutputStream* output) { 216 WriteTag(field_number, WIRETYPE_VARINT, output); 217 WriteInt64NoTag(value, output); 218} 219void WireFormatLite::WriteUInt32(int field_number, uint32 value, 220 io::CodedOutputStream* output) { 221 WriteTag(field_number, WIRETYPE_VARINT, output); 222 WriteUInt32NoTag(value, output); 223} 224void WireFormatLite::WriteUInt64(int field_number, uint64 value, 225 io::CodedOutputStream* output) { 226 WriteTag(field_number, WIRETYPE_VARINT, output); 227 WriteUInt64NoTag(value, output); 228} 229void WireFormatLite::WriteSInt32(int field_number, int32 value, 230 io::CodedOutputStream* output) { 231 WriteTag(field_number, WIRETYPE_VARINT, output); 232 WriteSInt32NoTag(value, output); 233} 234void WireFormatLite::WriteSInt64(int field_number, int64 value, 235 io::CodedOutputStream* output) { 236 WriteTag(field_number, WIRETYPE_VARINT, output); 237 WriteSInt64NoTag(value, output); 238} 239void WireFormatLite::WriteFixed32(int field_number, uint32 value, 240 io::CodedOutputStream* output) { 241 WriteTag(field_number, WIRETYPE_FIXED32, output); 242 WriteFixed32NoTag(value, output); 243} 244void WireFormatLite::WriteFixed64(int field_number, uint64 value, 245 io::CodedOutputStream* output) { 246 WriteTag(field_number, WIRETYPE_FIXED64, output); 247 WriteFixed64NoTag(value, output); 248} 249void WireFormatLite::WriteSFixed32(int field_number, int32 value, 250 io::CodedOutputStream* output) { 251 WriteTag(field_number, WIRETYPE_FIXED32, output); 252 WriteSFixed32NoTag(value, output); 253} 254void WireFormatLite::WriteSFixed64(int field_number, int64 value, 255 io::CodedOutputStream* output) { 256 WriteTag(field_number, WIRETYPE_FIXED64, output); 257 WriteSFixed64NoTag(value, output); 258} 259void WireFormatLite::WriteFloat(int field_number, float value, 260 io::CodedOutputStream* output) { 261 WriteTag(field_number, WIRETYPE_FIXED32, output); 262 WriteFloatNoTag(value, output); 263} 264void WireFormatLite::WriteDouble(int field_number, double value, 265 io::CodedOutputStream* output) { 266 WriteTag(field_number, WIRETYPE_FIXED64, output); 267 WriteDoubleNoTag(value, output); 268} 269void WireFormatLite::WriteBool(int field_number, bool value, 270 io::CodedOutputStream* output) { 271 WriteTag(field_number, WIRETYPE_VARINT, output); 272 WriteBoolNoTag(value, output); 273} 274void WireFormatLite::WriteEnum(int field_number, int value, 275 io::CodedOutputStream* output) { 276 WriteTag(field_number, WIRETYPE_VARINT, output); 277 WriteEnumNoTag(value, output); 278} 279 280void 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} 287void 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 295void 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 303void 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 312void 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 327void 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 342bool 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} 350bool 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