/thirdparty/breakpad/third_party/protobuf/protobuf/src/google/protobuf/wire_format_lite.cc

http://github.com/tomahawk-player/tomahawk · C++ · 359 lines · 292 code · 28 blank · 39 comment · 28 complexity · 2c9e50ee715f3518fc2e5724f78eb0b3 MD5 · raw file

  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. // Author: kenton@google.com (Kenton Varda)
  31. // Based on original Protocol Buffers design by
  32. // Sanjay Ghemawat, Jeff Dean, and others.
  33. #include <google/protobuf/wire_format_lite_inl.h>
  34. #include <stack>
  35. #include <string>
  36. #include <vector>
  37. #include <google/protobuf/stubs/common.h>
  38. #include <google/protobuf/io/coded_stream_inl.h>
  39. #include <google/protobuf/io/zero_copy_stream.h>
  40. #include <google/protobuf/io/zero_copy_stream_impl.h>
  41. namespace google {
  42. namespace protobuf {
  43. namespace internal {
  44. #ifndef _MSC_VER // MSVC doesn't like definitions of inline constants, GCC
  45. // requires them.
  46. const int WireFormatLite::kMessageSetItemStartTag;
  47. const int WireFormatLite::kMessageSetItemEndTag;
  48. const int WireFormatLite::kMessageSetTypeIdTag;
  49. const int WireFormatLite::kMessageSetMessageTag;
  50. #endif
  51. const int WireFormatLite::kMessageSetItemTagsSize =
  52. io::CodedOutputStream::VarintSize32(kMessageSetItemStartTag) +
  53. io::CodedOutputStream::VarintSize32(kMessageSetItemEndTag) +
  54. io::CodedOutputStream::VarintSize32(kMessageSetTypeIdTag) +
  55. io::CodedOutputStream::VarintSize32(kMessageSetMessageTag);
  56. const WireFormatLite::CppType
  57. WireFormatLite::kFieldTypeToCppTypeMap[MAX_FIELD_TYPE + 1] = {
  58. static_cast<CppType>(0), // 0 is reserved for errors
  59. CPPTYPE_DOUBLE, // TYPE_DOUBLE
  60. CPPTYPE_FLOAT, // TYPE_FLOAT
  61. CPPTYPE_INT64, // TYPE_INT64
  62. CPPTYPE_UINT64, // TYPE_UINT64
  63. CPPTYPE_INT32, // TYPE_INT32
  64. CPPTYPE_UINT64, // TYPE_FIXED64
  65. CPPTYPE_UINT32, // TYPE_FIXED32
  66. CPPTYPE_BOOL, // TYPE_BOOL
  67. CPPTYPE_STRING, // TYPE_STRING
  68. CPPTYPE_MESSAGE, // TYPE_GROUP
  69. CPPTYPE_MESSAGE, // TYPE_MESSAGE
  70. CPPTYPE_STRING, // TYPE_BYTES
  71. CPPTYPE_UINT32, // TYPE_UINT32
  72. CPPTYPE_ENUM, // TYPE_ENUM
  73. CPPTYPE_INT32, // TYPE_SFIXED32
  74. CPPTYPE_INT64, // TYPE_SFIXED64
  75. CPPTYPE_INT32, // TYPE_SINT32
  76. CPPTYPE_INT64, // TYPE_SINT64
  77. };
  78. const WireFormatLite::WireType
  79. WireFormatLite::kWireTypeForFieldType[MAX_FIELD_TYPE + 1] = {
  80. static_cast<WireFormatLite::WireType>(-1), // invalid
  81. WireFormatLite::WIRETYPE_FIXED64, // TYPE_DOUBLE
  82. WireFormatLite::WIRETYPE_FIXED32, // TYPE_FLOAT
  83. WireFormatLite::WIRETYPE_VARINT, // TYPE_INT64
  84. WireFormatLite::WIRETYPE_VARINT, // TYPE_UINT64
  85. WireFormatLite::WIRETYPE_VARINT, // TYPE_INT32
  86. WireFormatLite::WIRETYPE_FIXED64, // TYPE_FIXED64
  87. WireFormatLite::WIRETYPE_FIXED32, // TYPE_FIXED32
  88. WireFormatLite::WIRETYPE_VARINT, // TYPE_BOOL
  89. WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_STRING
  90. WireFormatLite::WIRETYPE_START_GROUP, // TYPE_GROUP
  91. WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_MESSAGE
  92. WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_BYTES
  93. WireFormatLite::WIRETYPE_VARINT, // TYPE_UINT32
  94. WireFormatLite::WIRETYPE_VARINT, // TYPE_ENUM
  95. WireFormatLite::WIRETYPE_FIXED32, // TYPE_SFIXED32
  96. WireFormatLite::WIRETYPE_FIXED64, // TYPE_SFIXED64
  97. WireFormatLite::WIRETYPE_VARINT, // TYPE_SINT32
  98. WireFormatLite::WIRETYPE_VARINT, // TYPE_SINT64
  99. };
  100. bool WireFormatLite::SkipField(
  101. io::CodedInputStream* input, uint32 tag) {
  102. switch (WireFormatLite::GetTagWireType(tag)) {
  103. case WireFormatLite::WIRETYPE_VARINT: {
  104. uint64 value;
  105. if (!input->ReadVarint64(&value)) return false;
  106. return true;
  107. }
  108. case WireFormatLite::WIRETYPE_FIXED64: {
  109. uint64 value;
  110. if (!input->ReadLittleEndian64(&value)) return false;
  111. return true;
  112. }
  113. case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
  114. uint32 length;
  115. if (!input->ReadVarint32(&length)) return false;
  116. if (!input->Skip(length)) return false;
  117. return true;
  118. }
  119. case WireFormatLite::WIRETYPE_START_GROUP: {
  120. if (!input->IncrementRecursionDepth()) return false;
  121. if (!SkipMessage(input)) return false;
  122. input->DecrementRecursionDepth();
  123. // Check that the ending tag matched the starting tag.
  124. if (!input->LastTagWas(WireFormatLite::MakeTag(
  125. WireFormatLite::GetTagFieldNumber(tag),
  126. WireFormatLite::WIRETYPE_END_GROUP))) {
  127. return false;
  128. }
  129. return true;
  130. }
  131. case WireFormatLite::WIRETYPE_END_GROUP: {
  132. return false;
  133. }
  134. case WireFormatLite::WIRETYPE_FIXED32: {
  135. uint32 value;
  136. if (!input->ReadLittleEndian32(&value)) return false;
  137. return true;
  138. }
  139. default: {
  140. return false;
  141. }
  142. }
  143. }
  144. bool WireFormatLite::SkipMessage(io::CodedInputStream* input) {
  145. while(true) {
  146. uint32 tag = input->ReadTag();
  147. if (tag == 0) {
  148. // End of input. This is a valid place to end, so return true.
  149. return true;
  150. }
  151. WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
  152. if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
  153. // Must be the end of the message.
  154. return true;
  155. }
  156. if (!SkipField(input, tag)) return false;
  157. }
  158. }
  159. bool FieldSkipper::SkipField(
  160. io::CodedInputStream* input, uint32 tag) {
  161. return WireFormatLite::SkipField(input, tag);
  162. }
  163. bool FieldSkipper::SkipMessage(io::CodedInputStream* input) {
  164. return WireFormatLite::SkipMessage(input);
  165. }
  166. void FieldSkipper::SkipUnknownEnum(
  167. int field_number, int value) {
  168. // Nothing.
  169. }
  170. bool WireFormatLite::ReadPackedEnumNoInline(io::CodedInputStream* input,
  171. bool (*is_valid)(int),
  172. RepeatedField<int>* values) {
  173. uint32 length;
  174. if (!input->ReadVarint32(&length)) return false;
  175. io::CodedInputStream::Limit limit = input->PushLimit(length);
  176. while (input->BytesUntilLimit() > 0) {
  177. int value;
  178. if (!google::protobuf::internal::WireFormatLite::ReadPrimitive<
  179. int, WireFormatLite::TYPE_ENUM>(input, &value)) {
  180. return false;
  181. }
  182. if (is_valid(value)) {
  183. values->Add(value);
  184. }
  185. }
  186. input->PopLimit(limit);
  187. return true;
  188. }
  189. void WireFormatLite::WriteInt32(int field_number, int32 value,
  190. io::CodedOutputStream* output) {
  191. WriteTag(field_number, WIRETYPE_VARINT, output);
  192. WriteInt32NoTag(value, output);
  193. }
  194. void WireFormatLite::WriteInt64(int field_number, int64 value,
  195. io::CodedOutputStream* output) {
  196. WriteTag(field_number, WIRETYPE_VARINT, output);
  197. WriteInt64NoTag(value, output);
  198. }
  199. void WireFormatLite::WriteUInt32(int field_number, uint32 value,
  200. io::CodedOutputStream* output) {
  201. WriteTag(field_number, WIRETYPE_VARINT, output);
  202. WriteUInt32NoTag(value, output);
  203. }
  204. void WireFormatLite::WriteUInt64(int field_number, uint64 value,
  205. io::CodedOutputStream* output) {
  206. WriteTag(field_number, WIRETYPE_VARINT, output);
  207. WriteUInt64NoTag(value, output);
  208. }
  209. void WireFormatLite::WriteSInt32(int field_number, int32 value,
  210. io::CodedOutputStream* output) {
  211. WriteTag(field_number, WIRETYPE_VARINT, output);
  212. WriteSInt32NoTag(value, output);
  213. }
  214. void WireFormatLite::WriteSInt64(int field_number, int64 value,
  215. io::CodedOutputStream* output) {
  216. WriteTag(field_number, WIRETYPE_VARINT, output);
  217. WriteSInt64NoTag(value, output);
  218. }
  219. void WireFormatLite::WriteFixed32(int field_number, uint32 value,
  220. io::CodedOutputStream* output) {
  221. WriteTag(field_number, WIRETYPE_FIXED32, output);
  222. WriteFixed32NoTag(value, output);
  223. }
  224. void WireFormatLite::WriteFixed64(int field_number, uint64 value,
  225. io::CodedOutputStream* output) {
  226. WriteTag(field_number, WIRETYPE_FIXED64, output);
  227. WriteFixed64NoTag(value, output);
  228. }
  229. void WireFormatLite::WriteSFixed32(int field_number, int32 value,
  230. io::CodedOutputStream* output) {
  231. WriteTag(field_number, WIRETYPE_FIXED32, output);
  232. WriteSFixed32NoTag(value, output);
  233. }
  234. void WireFormatLite::WriteSFixed64(int field_number, int64 value,
  235. io::CodedOutputStream* output) {
  236. WriteTag(field_number, WIRETYPE_FIXED64, output);
  237. WriteSFixed64NoTag(value, output);
  238. }
  239. void WireFormatLite::WriteFloat(int field_number, float value,
  240. io::CodedOutputStream* output) {
  241. WriteTag(field_number, WIRETYPE_FIXED32, output);
  242. WriteFloatNoTag(value, output);
  243. }
  244. void WireFormatLite::WriteDouble(int field_number, double value,
  245. io::CodedOutputStream* output) {
  246. WriteTag(field_number, WIRETYPE_FIXED64, output);
  247. WriteDoubleNoTag(value, output);
  248. }
  249. void WireFormatLite::WriteBool(int field_number, bool value,
  250. io::CodedOutputStream* output) {
  251. WriteTag(field_number, WIRETYPE_VARINT, output);
  252. WriteBoolNoTag(value, output);
  253. }
  254. void WireFormatLite::WriteEnum(int field_number, int value,
  255. io::CodedOutputStream* output) {
  256. WriteTag(field_number, WIRETYPE_VARINT, output);
  257. WriteEnumNoTag(value, output);
  258. }
  259. void WireFormatLite::WriteString(int field_number, const string& value,
  260. io::CodedOutputStream* output) {
  261. // String is for UTF-8 text only
  262. WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
  263. output->WriteVarint32(value.size());
  264. output->WriteString(value);
  265. }
  266. void WireFormatLite::WriteBytes(int field_number, const string& value,
  267. io::CodedOutputStream* output) {
  268. WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
  269. output->WriteVarint32(value.size());
  270. output->WriteString(value);
  271. }
  272. void WireFormatLite::WriteGroup(int field_number,
  273. const MessageLite& value,
  274. io::CodedOutputStream* output) {
  275. WriteTag(field_number, WIRETYPE_START_GROUP, output);
  276. value.SerializeWithCachedSizes(output);
  277. WriteTag(field_number, WIRETYPE_END_GROUP, output);
  278. }
  279. void WireFormatLite::WriteMessage(int field_number,
  280. const MessageLite& value,
  281. io::CodedOutputStream* output) {
  282. WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
  283. const int size = value.GetCachedSize();
  284. output->WriteVarint32(size);
  285. value.SerializeWithCachedSizes(output);
  286. }
  287. void WireFormatLite::WriteGroupMaybeToArray(int field_number,
  288. const MessageLite& value,
  289. io::CodedOutputStream* output) {
  290. WriteTag(field_number, WIRETYPE_START_GROUP, output);
  291. const int size = value.GetCachedSize();
  292. uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
  293. if (target != NULL) {
  294. uint8* end = value.SerializeWithCachedSizesToArray(target);
  295. GOOGLE_DCHECK_EQ(end - target, size);
  296. } else {
  297. value.SerializeWithCachedSizes(output);
  298. }
  299. WriteTag(field_number, WIRETYPE_END_GROUP, output);
  300. }
  301. void WireFormatLite::WriteMessageMaybeToArray(int field_number,
  302. const MessageLite& value,
  303. io::CodedOutputStream* output) {
  304. WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
  305. const int size = value.GetCachedSize();
  306. output->WriteVarint32(size);
  307. uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
  308. if (target != NULL) {
  309. uint8* end = value.SerializeWithCachedSizesToArray(target);
  310. GOOGLE_DCHECK_EQ(end - target, size);
  311. } else {
  312. value.SerializeWithCachedSizes(output);
  313. }
  314. }
  315. bool WireFormatLite::ReadString(io::CodedInputStream* input,
  316. string* value) {
  317. // String is for UTF-8 text only
  318. uint32 length;
  319. if (!input->ReadVarint32(&length)) return false;
  320. if (!input->InternalReadStringInline(value, length)) return false;
  321. return true;
  322. }
  323. bool WireFormatLite::ReadBytes(io::CodedInputStream* input,
  324. string* value) {
  325. uint32 length;
  326. if (!input->ReadVarint32(&length)) return false;
  327. return input->InternalReadStringInline(value, length);
  328. }
  329. } // namespace internal
  330. } // namespace protobuf
  331. } // namespace google