诸暨麻将添加redis
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 
 

504 lignes
18 KiB

  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. // Authors: wink@google.com (Wink Saville),
  31. // kenton@google.com (Kenton Varda)
  32. // Based on original Protocol Buffers design by
  33. // Sanjay Ghemawat, Jeff Dean, and others.
  34. #include <google/protobuf/message_lite.h>
  35. #include <climits>
  36. #include <cstdint>
  37. #include <string>
  38. #include <google/protobuf/stubs/logging.h>
  39. #include <google/protobuf/stubs/common.h>
  40. #include <google/protobuf/stubs/stringprintf.h>
  41. #include <google/protobuf/parse_context.h>
  42. #include <google/protobuf/io/coded_stream.h>
  43. #include <google/protobuf/io/zero_copy_stream.h>
  44. #include <google/protobuf/io/zero_copy_stream_impl.h>
  45. #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
  46. #include <google/protobuf/arena.h>
  47. #include <google/protobuf/generated_message_table_driven.h>
  48. #include <google/protobuf/generated_message_util.h>
  49. #include <google/protobuf/repeated_field.h>
  50. #include <google/protobuf/stubs/strutil.h>
  51. #include <google/protobuf/stubs/stl_util.h>
  52. #include <google/protobuf/port_def.inc>
  53. namespace google {
  54. namespace protobuf {
  55. std::string MessageLite::InitializationErrorString() const {
  56. return "(cannot determine missing fields for lite message)";
  57. }
  58. std::string MessageLite::DebugString() const {
  59. std::uintptr_t address = reinterpret_cast<std::uintptr_t>(this);
  60. return StrCat("MessageLite at 0x", strings::Hex(address));
  61. }
  62. namespace {
  63. // When serializing, we first compute the byte size, then serialize the message.
  64. // If serialization produces a different number of bytes than expected, we
  65. // call this function, which crashes. The problem could be due to a bug in the
  66. // protobuf implementation but is more likely caused by concurrent modification
  67. // of the message. This function attempts to distinguish between the two and
  68. // provide a useful error message.
  69. void ByteSizeConsistencyError(size_t byte_size_before_serialization,
  70. size_t byte_size_after_serialization,
  71. size_t bytes_produced_by_serialization,
  72. const MessageLite& message) {
  73. GOOGLE_CHECK_EQ(byte_size_before_serialization, byte_size_after_serialization)
  74. << message.GetTypeName()
  75. << " was modified concurrently during serialization.";
  76. GOOGLE_CHECK_EQ(bytes_produced_by_serialization, byte_size_before_serialization)
  77. << "Byte size calculation and serialization were inconsistent. This "
  78. "may indicate a bug in protocol buffers or it may be caused by "
  79. "concurrent modification of "
  80. << message.GetTypeName() << ".";
  81. GOOGLE_LOG(FATAL) << "This shouldn't be called if all the sizes are equal.";
  82. }
  83. std::string InitializationErrorMessage(const char* action,
  84. const MessageLite& message) {
  85. // Note: We want to avoid depending on strutil in the lite library, otherwise
  86. // we'd use:
  87. //
  88. // return strings::Substitute(
  89. // "Can't $0 message of type \"$1\" because it is missing required "
  90. // "fields: $2",
  91. // action, message.GetTypeName(),
  92. // message.InitializationErrorString());
  93. std::string result;
  94. result += "Can't ";
  95. result += action;
  96. result += " message of type \"";
  97. result += message.GetTypeName();
  98. result += "\" because it is missing required fields: ";
  99. result += message.InitializationErrorString();
  100. return result;
  101. }
  102. inline StringPiece as_string_view(const void* data, int size) {
  103. return StringPiece(static_cast<const char*>(data), size);
  104. }
  105. } // namespace
  106. void MessageLite::LogInitializationErrorMessage() const {
  107. GOOGLE_LOG(ERROR) << InitializationErrorMessage("parse", *this);
  108. }
  109. namespace internal {
  110. template <bool aliasing>
  111. bool MergePartialFromImpl(StringPiece input, MessageLite* msg) {
  112. const char* ptr;
  113. internal::ParseContext ctx(io::CodedInputStream::GetDefaultRecursionLimit(),
  114. aliasing, &ptr, input);
  115. ptr = msg->_InternalParse(ptr, &ctx);
  116. // ctx has an explicit limit set (length of string_view).
  117. return ptr && ctx.EndedAtLimit();
  118. }
  119. template <bool aliasing>
  120. bool MergePartialFromImpl(io::ZeroCopyInputStream* input, MessageLite* msg) {
  121. const char* ptr;
  122. internal::ParseContext ctx(io::CodedInputStream::GetDefaultRecursionLimit(),
  123. aliasing, &ptr, input);
  124. ptr = msg->_InternalParse(ptr, &ctx);
  125. // ctx has no explicit limit (hence we end on end of stream)
  126. return ptr && ctx.EndedAtEndOfStream();
  127. }
  128. template <bool aliasing>
  129. bool MergePartialFromImpl(BoundedZCIS input, MessageLite* msg) {
  130. const char* ptr;
  131. internal::ParseContext ctx(io::CodedInputStream::GetDefaultRecursionLimit(),
  132. aliasing, &ptr, input.zcis, input.limit);
  133. ptr = msg->_InternalParse(ptr, &ctx);
  134. if (PROTOBUF_PREDICT_FALSE(!ptr)) return false;
  135. ctx.BackUp(ptr);
  136. return ctx.EndedAtLimit();
  137. }
  138. template bool MergePartialFromImpl<false>(StringPiece input,
  139. MessageLite* msg);
  140. template bool MergePartialFromImpl<true>(StringPiece input,
  141. MessageLite* msg);
  142. template bool MergePartialFromImpl<false>(io::ZeroCopyInputStream* input,
  143. MessageLite* msg);
  144. template bool MergePartialFromImpl<true>(io::ZeroCopyInputStream* input,
  145. MessageLite* msg);
  146. template bool MergePartialFromImpl<false>(BoundedZCIS input, MessageLite* msg);
  147. template bool MergePartialFromImpl<true>(BoundedZCIS input, MessageLite* msg);
  148. } // namespace internal
  149. MessageLite* MessageLite::New(Arena* arena) const {
  150. MessageLite* message = New();
  151. if (arena != NULL) {
  152. arena->Own(message);
  153. }
  154. return message;
  155. }
  156. class ZeroCopyCodedInputStream : public io::ZeroCopyInputStream {
  157. public:
  158. ZeroCopyCodedInputStream(io::CodedInputStream* cis) : cis_(cis) {}
  159. bool Next(const void** data, int* size) final {
  160. if (!cis_->GetDirectBufferPointer(data, size)) return false;
  161. cis_->Skip(*size);
  162. return true;
  163. }
  164. void BackUp(int count) final { cis_->Advance(-count); }
  165. bool Skip(int count) final { return cis_->Skip(count); }
  166. int64_t ByteCount() const final { return 0; }
  167. bool aliasing_enabled() { return cis_->aliasing_enabled_; }
  168. private:
  169. io::CodedInputStream* cis_;
  170. };
  171. bool MessageLite::MergePartialFromCodedStream(io::CodedInputStream* input) {
  172. ZeroCopyCodedInputStream zcis(input);
  173. const char* ptr;
  174. internal::ParseContext ctx(input->RecursionBudget(), zcis.aliasing_enabled(),
  175. &ptr, &zcis);
  176. // MergePartialFromCodedStream allows terminating the wireformat by 0 or
  177. // end-group tag. Leaving it up to the caller to verify correct ending by
  178. // calling LastTagWas on input. We need to maintain this behavior.
  179. ctx.TrackCorrectEnding();
  180. ctx.data().pool = input->GetExtensionPool();
  181. ctx.data().factory = input->GetExtensionFactory();
  182. ptr = _InternalParse(ptr, &ctx);
  183. if (PROTOBUF_PREDICT_FALSE(!ptr)) return false;
  184. ctx.BackUp(ptr);
  185. if (!ctx.EndedAtEndOfStream()) {
  186. GOOGLE_DCHECK(ctx.LastTag() != 1); // We can't end on a pushed limit.
  187. if (ctx.IsExceedingLimit(ptr)) return false;
  188. input->SetLastTag(ctx.LastTag());
  189. return true;
  190. }
  191. input->SetConsumed();
  192. return true;
  193. }
  194. bool MessageLite::MergeFromCodedStream(io::CodedInputStream* input) {
  195. return MergePartialFromCodedStream(input) && IsInitializedWithErrors();
  196. }
  197. bool MessageLite::ParseFromCodedStream(io::CodedInputStream* input) {
  198. Clear();
  199. return MergeFromCodedStream(input);
  200. }
  201. bool MessageLite::ParsePartialFromCodedStream(io::CodedInputStream* input) {
  202. Clear();
  203. return MergePartialFromCodedStream(input);
  204. }
  205. bool MessageLite::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) {
  206. return ParseFrom<kParse>(input);
  207. }
  208. bool MessageLite::ParsePartialFromZeroCopyStream(
  209. io::ZeroCopyInputStream* input) {
  210. return ParseFrom<kParsePartial>(input);
  211. }
  212. bool MessageLite::ParseFromFileDescriptor(int file_descriptor) {
  213. io::FileInputStream input(file_descriptor);
  214. return ParseFromZeroCopyStream(&input) && input.GetErrno() == 0;
  215. }
  216. bool MessageLite::ParsePartialFromFileDescriptor(int file_descriptor) {
  217. io::FileInputStream input(file_descriptor);
  218. return ParsePartialFromZeroCopyStream(&input) && input.GetErrno() == 0;
  219. }
  220. bool MessageLite::ParseFromIstream(std::istream* input) {
  221. io::IstreamInputStream zero_copy_input(input);
  222. return ParseFromZeroCopyStream(&zero_copy_input) && input->eof();
  223. }
  224. bool MessageLite::ParsePartialFromIstream(std::istream* input) {
  225. io::IstreamInputStream zero_copy_input(input);
  226. return ParsePartialFromZeroCopyStream(&zero_copy_input) && input->eof();
  227. }
  228. bool MessageLite::MergePartialFromBoundedZeroCopyStream(
  229. io::ZeroCopyInputStream* input, int size) {
  230. return ParseFrom<kMergePartial>(internal::BoundedZCIS{input, size});
  231. }
  232. bool MessageLite::MergeFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input,
  233. int size) {
  234. return ParseFrom<kMerge>(internal::BoundedZCIS{input, size});
  235. }
  236. bool MessageLite::ParseFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input,
  237. int size) {
  238. return ParseFrom<kParse>(internal::BoundedZCIS{input, size});
  239. }
  240. bool MessageLite::ParsePartialFromBoundedZeroCopyStream(
  241. io::ZeroCopyInputStream* input, int size) {
  242. return ParseFrom<kParsePartial>(internal::BoundedZCIS{input, size});
  243. }
  244. bool MessageLite::ParseFromString(const std::string& data) {
  245. return ParseFrom<kParse>(data);
  246. }
  247. bool MessageLite::ParsePartialFromString(const std::string& data) {
  248. return ParseFrom<kParsePartial>(data);
  249. }
  250. bool MessageLite::ParseFromArray(const void* data, int size) {
  251. return ParseFrom<kParse>(as_string_view(data, size));
  252. }
  253. bool MessageLite::ParsePartialFromArray(const void* data, int size) {
  254. return ParseFrom<kParsePartial>(as_string_view(data, size));
  255. }
  256. bool MessageLite::MergeFromString(const std::string& data) {
  257. return ParseFrom<kMerge>(data);
  258. }
  259. // ===================================================================
  260. inline uint8* SerializeToArrayImpl(const MessageLite& msg, uint8* target,
  261. int size) {
  262. constexpr bool debug = false;
  263. if (debug) {
  264. // Force serialization to a stream with a block size of 1, which forces
  265. // all writes to the stream to cross buffers triggering all fallback paths
  266. // in the unittests when serializing to string / array.
  267. io::ArrayOutputStream stream(target, size, 1);
  268. uint8* ptr;
  269. io::EpsCopyOutputStream out(
  270. &stream, io::CodedOutputStream::IsDefaultSerializationDeterministic(),
  271. &ptr);
  272. ptr = msg.InternalSerializeWithCachedSizesToArray(ptr, &out);
  273. out.Trim(ptr);
  274. GOOGLE_DCHECK(!out.HadError() && stream.ByteCount() == size);
  275. return target + size;
  276. } else {
  277. io::EpsCopyOutputStream out(
  278. target, size,
  279. io::CodedOutputStream::IsDefaultSerializationDeterministic());
  280. auto res = msg.InternalSerializeWithCachedSizesToArray(target, &out);
  281. GOOGLE_DCHECK(target + size == res);
  282. return res;
  283. }
  284. }
  285. uint8* MessageLite::SerializeWithCachedSizesToArray(uint8* target) const {
  286. // We only optimize this when using optimize_for = SPEED. In other cases
  287. // we just use the CodedOutputStream path.
  288. return SerializeToArrayImpl(*this, target, GetCachedSize());
  289. }
  290. bool MessageLite::SerializeToCodedStream(io::CodedOutputStream* output) const {
  291. GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this);
  292. return SerializePartialToCodedStream(output);
  293. }
  294. bool MessageLite::SerializePartialToCodedStream(
  295. io::CodedOutputStream* output) const {
  296. const size_t size = ByteSizeLong(); // Force size to be cached.
  297. if (size > INT_MAX) {
  298. GOOGLE_LOG(ERROR) << GetTypeName()
  299. << " exceeded maximum protobuf size of 2GB: " << size;
  300. return false;
  301. }
  302. int original_byte_count = output->ByteCount();
  303. SerializeWithCachedSizes(output);
  304. if (output->HadError()) {
  305. return false;
  306. }
  307. int final_byte_count = output->ByteCount();
  308. if (final_byte_count - original_byte_count != size) {
  309. ByteSizeConsistencyError(size, ByteSizeLong(),
  310. final_byte_count - original_byte_count, *this);
  311. }
  312. return true;
  313. }
  314. bool MessageLite::SerializeToZeroCopyStream(
  315. io::ZeroCopyOutputStream* output) const {
  316. GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this);
  317. return SerializePartialToZeroCopyStream(output);
  318. }
  319. bool MessageLite::SerializePartialToZeroCopyStream(
  320. io::ZeroCopyOutputStream* output) const {
  321. const size_t size = ByteSizeLong(); // Force size to be cached.
  322. if (size > INT_MAX) {
  323. GOOGLE_LOG(ERROR) << GetTypeName()
  324. << " exceeded maximum protobuf size of 2GB: " << size;
  325. return false;
  326. }
  327. uint8* target;
  328. io::EpsCopyOutputStream stream(
  329. output, io::CodedOutputStream::IsDefaultSerializationDeterministic(),
  330. &target);
  331. target = InternalSerializeWithCachedSizesToArray(target, &stream);
  332. stream.Trim(target);
  333. if (stream.HadError()) return false;
  334. return true;
  335. }
  336. bool MessageLite::SerializeToFileDescriptor(int file_descriptor) const {
  337. io::FileOutputStream output(file_descriptor);
  338. return SerializeToZeroCopyStream(&output) && output.Flush();
  339. }
  340. bool MessageLite::SerializePartialToFileDescriptor(int file_descriptor) const {
  341. io::FileOutputStream output(file_descriptor);
  342. return SerializePartialToZeroCopyStream(&output) && output.Flush();
  343. }
  344. bool MessageLite::SerializeToOstream(std::ostream* output) const {
  345. {
  346. io::OstreamOutputStream zero_copy_output(output);
  347. if (!SerializeToZeroCopyStream(&zero_copy_output)) return false;
  348. }
  349. return output->good();
  350. }
  351. bool MessageLite::SerializePartialToOstream(std::ostream* output) const {
  352. io::OstreamOutputStream zero_copy_output(output);
  353. return SerializePartialToZeroCopyStream(&zero_copy_output);
  354. }
  355. bool MessageLite::AppendToString(std::string* output) const {
  356. GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this);
  357. return AppendPartialToString(output);
  358. }
  359. bool MessageLite::AppendPartialToString(std::string* output) const {
  360. size_t old_size = output->size();
  361. size_t byte_size = ByteSizeLong();
  362. if (byte_size > INT_MAX) {
  363. GOOGLE_LOG(ERROR) << GetTypeName()
  364. << " exceeded maximum protobuf size of 2GB: " << byte_size;
  365. return false;
  366. }
  367. STLStringResizeUninitialized(output, old_size + byte_size);
  368. uint8* start =
  369. reinterpret_cast<uint8*>(io::mutable_string_data(output) + old_size);
  370. SerializeToArrayImpl(*this, start, byte_size);
  371. return true;
  372. }
  373. bool MessageLite::SerializeToString(std::string* output) const {
  374. output->clear();
  375. return AppendToString(output);
  376. }
  377. bool MessageLite::SerializePartialToString(std::string* output) const {
  378. output->clear();
  379. return AppendPartialToString(output);
  380. }
  381. bool MessageLite::SerializeToArray(void* data, int size) const {
  382. GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this);
  383. return SerializePartialToArray(data, size);
  384. }
  385. bool MessageLite::SerializePartialToArray(void* data, int size) const {
  386. const size_t byte_size = ByteSizeLong();
  387. if (byte_size > INT_MAX) {
  388. GOOGLE_LOG(ERROR) << GetTypeName()
  389. << " exceeded maximum protobuf size of 2GB: " << byte_size;
  390. return false;
  391. }
  392. if (size < byte_size) return false;
  393. uint8* start = reinterpret_cast<uint8*>(data);
  394. SerializeToArrayImpl(*this, start, byte_size);
  395. return true;
  396. }
  397. std::string MessageLite::SerializeAsString() const {
  398. // If the compiler implements the (Named) Return Value Optimization,
  399. // the local variable 'output' will not actually reside on the stack
  400. // of this function, but will be overlaid with the object that the
  401. // caller supplied for the return value to be constructed in.
  402. std::string output;
  403. if (!AppendToString(&output)) output.clear();
  404. return output;
  405. }
  406. std::string MessageLite::SerializePartialAsString() const {
  407. std::string output;
  408. if (!AppendPartialToString(&output)) output.clear();
  409. return output;
  410. }
  411. namespace internal {
  412. template <>
  413. MessageLite* GenericTypeHandler<MessageLite>::NewFromPrototype(
  414. const MessageLite* prototype, Arena* arena) {
  415. return prototype->New(arena);
  416. }
  417. template <>
  418. void GenericTypeHandler<MessageLite>::Merge(const MessageLite& from,
  419. MessageLite* to) {
  420. to->CheckTypeAndMergeFrom(from);
  421. }
  422. template <>
  423. void GenericTypeHandler<std::string>::Merge(const std::string& from,
  424. std::string* to) {
  425. *to = from;
  426. }
  427. } // namespace internal
  428. } // namespace protobuf
  429. } // namespace google