诸暨麻将添加redis
Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 
 
 
 

957 righe
31 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. // Author: kenton@google.com (Kenton Varda)
  31. // Based on original Protocol Buffers design by
  32. // Sanjay Ghemawat, Jeff Dean, and others.
  33. //
  34. // This implementation is heavily optimized to make reads and writes
  35. // of small values (especially varints) as fast as possible. In
  36. // particular, we optimize for the common case that a read or a write
  37. // will not cross the end of the buffer, since we can avoid a lot
  38. // of branching in this case.
  39. #include <google/protobuf/io/coded_stream.h>
  40. #include <limits.h>
  41. #include <algorithm>
  42. #include <cstring>
  43. #include <utility>
  44. #include <google/protobuf/stubs/logging.h>
  45. #include <google/protobuf/stubs/common.h>
  46. #include <google/protobuf/arena.h>
  47. #include <google/protobuf/io/zero_copy_stream.h>
  48. #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
  49. #include <google/protobuf/stubs/stl_util.h>
  50. #include <google/protobuf/port_def.inc>
  51. namespace google {
  52. namespace protobuf {
  53. namespace io {
  54. namespace {
  55. static const int kMaxVarintBytes = 10;
  56. static const int kMaxVarint32Bytes = 5;
  57. inline bool NextNonEmpty(ZeroCopyInputStream* input, const void** data,
  58. int* size) {
  59. bool success;
  60. do {
  61. success = input->Next(data, size);
  62. } while (success && *size == 0);
  63. return success;
  64. }
  65. } // namespace
  66. // CodedInputStream ==================================================
  67. CodedInputStream::~CodedInputStream() {
  68. if (input_ != NULL) {
  69. BackUpInputToCurrentPosition();
  70. }
  71. }
  72. // Static.
  73. int CodedInputStream::default_recursion_limit_ = 100;
  74. void CodedInputStream::BackUpInputToCurrentPosition() {
  75. int backup_bytes = BufferSize() + buffer_size_after_limit_ + overflow_bytes_;
  76. if (backup_bytes > 0) {
  77. input_->BackUp(backup_bytes);
  78. // total_bytes_read_ doesn't include overflow_bytes_.
  79. total_bytes_read_ -= BufferSize() + buffer_size_after_limit_;
  80. buffer_end_ = buffer_;
  81. buffer_size_after_limit_ = 0;
  82. overflow_bytes_ = 0;
  83. }
  84. }
  85. inline void CodedInputStream::RecomputeBufferLimits() {
  86. buffer_end_ += buffer_size_after_limit_;
  87. int closest_limit = std::min(current_limit_, total_bytes_limit_);
  88. if (closest_limit < total_bytes_read_) {
  89. // The limit position is in the current buffer. We must adjust
  90. // the buffer size accordingly.
  91. buffer_size_after_limit_ = total_bytes_read_ - closest_limit;
  92. buffer_end_ -= buffer_size_after_limit_;
  93. } else {
  94. buffer_size_after_limit_ = 0;
  95. }
  96. }
  97. CodedInputStream::Limit CodedInputStream::PushLimit(int byte_limit) {
  98. // Current position relative to the beginning of the stream.
  99. int current_position = CurrentPosition();
  100. Limit old_limit = current_limit_;
  101. // security: byte_limit is possibly evil, so check for negative values
  102. // and overflow. Also check that the new requested limit is before the
  103. // previous limit; otherwise we continue to enforce the previous limit.
  104. if (PROTOBUF_PREDICT_TRUE(byte_limit >= 0 &&
  105. byte_limit <= INT_MAX - current_position &&
  106. byte_limit < current_limit_ - current_position)) {
  107. current_limit_ = current_position + byte_limit;
  108. RecomputeBufferLimits();
  109. }
  110. return old_limit;
  111. }
  112. void CodedInputStream::PopLimit(Limit limit) {
  113. // The limit passed in is actually the *old* limit, which we returned from
  114. // PushLimit().
  115. current_limit_ = limit;
  116. RecomputeBufferLimits();
  117. // We may no longer be at a legitimate message end. ReadTag() needs to be
  118. // called again to find out.
  119. legitimate_message_end_ = false;
  120. }
  121. std::pair<CodedInputStream::Limit, int>
  122. CodedInputStream::IncrementRecursionDepthAndPushLimit(int byte_limit) {
  123. return std::make_pair(PushLimit(byte_limit), --recursion_budget_);
  124. }
  125. CodedInputStream::Limit CodedInputStream::ReadLengthAndPushLimit() {
  126. uint32 length;
  127. return PushLimit(ReadVarint32(&length) ? length : 0);
  128. }
  129. bool CodedInputStream::DecrementRecursionDepthAndPopLimit(Limit limit) {
  130. bool result = ConsumedEntireMessage();
  131. PopLimit(limit);
  132. GOOGLE_DCHECK_LT(recursion_budget_, recursion_limit_);
  133. ++recursion_budget_;
  134. return result;
  135. }
  136. bool CodedInputStream::CheckEntireMessageConsumedAndPopLimit(Limit limit) {
  137. bool result = ConsumedEntireMessage();
  138. PopLimit(limit);
  139. return result;
  140. }
  141. int CodedInputStream::BytesUntilLimit() const {
  142. if (current_limit_ == INT_MAX) return -1;
  143. int current_position = CurrentPosition();
  144. return current_limit_ - current_position;
  145. }
  146. void CodedInputStream::SetTotalBytesLimit(int total_bytes_limit) {
  147. // Make sure the limit isn't already past, since this could confuse other
  148. // code.
  149. int current_position = CurrentPosition();
  150. total_bytes_limit_ = std::max(current_position, total_bytes_limit);
  151. RecomputeBufferLimits();
  152. }
  153. int CodedInputStream::BytesUntilTotalBytesLimit() const {
  154. if (total_bytes_limit_ == INT_MAX) return -1;
  155. return total_bytes_limit_ - CurrentPosition();
  156. }
  157. void CodedInputStream::PrintTotalBytesLimitError() {
  158. GOOGLE_LOG(ERROR)
  159. << "A protocol message was rejected because it was too "
  160. "big (more than "
  161. << total_bytes_limit_
  162. << " bytes). To increase the limit (or to disable these "
  163. "warnings), see CodedInputStream::SetTotalBytesLimit() "
  164. "in third_party/protobuf/src/google/protobuf/io/coded_stream.h.";
  165. }
  166. bool CodedInputStream::SkipFallback(int count, int original_buffer_size) {
  167. if (buffer_size_after_limit_ > 0) {
  168. // We hit a limit inside this buffer. Advance to the limit and fail.
  169. Advance(original_buffer_size);
  170. return false;
  171. }
  172. count -= original_buffer_size;
  173. buffer_ = NULL;
  174. buffer_end_ = buffer_;
  175. // Make sure this skip doesn't try to skip past the current limit.
  176. int closest_limit = std::min(current_limit_, total_bytes_limit_);
  177. int bytes_until_limit = closest_limit - total_bytes_read_;
  178. if (bytes_until_limit < count) {
  179. // We hit the limit. Skip up to it then fail.
  180. if (bytes_until_limit > 0) {
  181. total_bytes_read_ = closest_limit;
  182. input_->Skip(bytes_until_limit);
  183. }
  184. return false;
  185. }
  186. if (!input_->Skip(count)) {
  187. total_bytes_read_ = input_->ByteCount();
  188. return false;
  189. }
  190. total_bytes_read_ += count;
  191. return true;
  192. }
  193. bool CodedInputStream::GetDirectBufferPointer(const void** data, int* size) {
  194. if (BufferSize() == 0 && !Refresh()) return false;
  195. *data = buffer_;
  196. *size = BufferSize();
  197. return true;
  198. }
  199. bool CodedInputStream::ReadRaw(void* buffer, int size) {
  200. int current_buffer_size;
  201. while ((current_buffer_size = BufferSize()) < size) {
  202. // Reading past end of buffer. Copy what we have, then refresh.
  203. memcpy(buffer, buffer_, current_buffer_size);
  204. buffer = reinterpret_cast<uint8*>(buffer) + current_buffer_size;
  205. size -= current_buffer_size;
  206. Advance(current_buffer_size);
  207. if (!Refresh()) return false;
  208. }
  209. memcpy(buffer, buffer_, size);
  210. Advance(size);
  211. return true;
  212. }
  213. bool CodedInputStream::ReadString(std::string* buffer, int size) {
  214. if (size < 0) return false; // security: size is often user-supplied
  215. if (BufferSize() >= size) {
  216. STLStringResizeUninitialized(buffer, size);
  217. std::pair<char*, bool> z = as_string_data(buffer);
  218. if (z.second) {
  219. // Oddly enough, memcpy() requires its first two args to be non-NULL even
  220. // if we copy 0 bytes. So, we have ensured that z.first is non-NULL here.
  221. GOOGLE_DCHECK(z.first != NULL);
  222. memcpy(z.first, buffer_, size);
  223. Advance(size);
  224. }
  225. return true;
  226. }
  227. return ReadStringFallback(buffer, size);
  228. }
  229. bool CodedInputStream::ReadStringFallback(std::string* buffer, int size) {
  230. if (!buffer->empty()) {
  231. buffer->clear();
  232. }
  233. int closest_limit = std::min(current_limit_, total_bytes_limit_);
  234. if (closest_limit != INT_MAX) {
  235. int bytes_to_limit = closest_limit - CurrentPosition();
  236. if (bytes_to_limit > 0 && size > 0 && size <= bytes_to_limit) {
  237. buffer->reserve(size);
  238. }
  239. }
  240. int current_buffer_size;
  241. while ((current_buffer_size = BufferSize()) < size) {
  242. // Some STL implementations "helpfully" crash on buffer->append(NULL, 0).
  243. if (current_buffer_size != 0) {
  244. // Note: string1.append(string2) is O(string2.size()) (as opposed to
  245. // O(string1.size() + string2.size()), which would be bad).
  246. buffer->append(reinterpret_cast<const char*>(buffer_),
  247. current_buffer_size);
  248. }
  249. size -= current_buffer_size;
  250. Advance(current_buffer_size);
  251. if (!Refresh()) return false;
  252. }
  253. buffer->append(reinterpret_cast<const char*>(buffer_), size);
  254. Advance(size);
  255. return true;
  256. }
  257. bool CodedInputStream::ReadLittleEndian32Fallback(uint32* value) {
  258. uint8 bytes[sizeof(*value)];
  259. const uint8* ptr;
  260. if (BufferSize() >= sizeof(*value)) {
  261. // Fast path: Enough bytes in the buffer to read directly.
  262. ptr = buffer_;
  263. Advance(sizeof(*value));
  264. } else {
  265. // Slow path: Had to read past the end of the buffer.
  266. if (!ReadRaw(bytes, sizeof(*value))) return false;
  267. ptr = bytes;
  268. }
  269. ReadLittleEndian32FromArray(ptr, value);
  270. return true;
  271. }
  272. bool CodedInputStream::ReadLittleEndian64Fallback(uint64* value) {
  273. uint8 bytes[sizeof(*value)];
  274. const uint8* ptr;
  275. if (BufferSize() >= sizeof(*value)) {
  276. // Fast path: Enough bytes in the buffer to read directly.
  277. ptr = buffer_;
  278. Advance(sizeof(*value));
  279. } else {
  280. // Slow path: Had to read past the end of the buffer.
  281. if (!ReadRaw(bytes, sizeof(*value))) return false;
  282. ptr = bytes;
  283. }
  284. ReadLittleEndian64FromArray(ptr, value);
  285. return true;
  286. }
  287. namespace {
  288. // Decodes varint64 with known size, N, and returns next pointer. Knowing N at
  289. // compile time, compiler can generate optimal code. For example, instead of
  290. // subtracting 0x80 at each iteration, it subtracts properly shifted mask once.
  291. template <size_t N>
  292. const uint8* DecodeVarint64KnownSize(const uint8* buffer, uint64* value) {
  293. GOOGLE_DCHECK_GT(N, 0);
  294. uint64 result = static_cast<uint64>(buffer[N - 1]) << (7 * (N - 1));
  295. for (int i = 0, offset = 0; i < N - 1; i++, offset += 7) {
  296. result += static_cast<uint64>(buffer[i] - 0x80) << offset;
  297. }
  298. *value = result;
  299. return buffer + N;
  300. }
  301. // Read a varint from the given buffer, write it to *value, and return a pair.
  302. // The first part of the pair is true iff the read was successful. The second
  303. // part is buffer + (number of bytes read). This function is always inlined,
  304. // so returning a pair is costless.
  305. PROTOBUF_ALWAYS_INLINE
  306. ::std::pair<bool, const uint8*> ReadVarint32FromArray(uint32 first_byte,
  307. const uint8* buffer,
  308. uint32* value);
  309. inline ::std::pair<bool, const uint8*> ReadVarint32FromArray(
  310. uint32 first_byte, const uint8* buffer, uint32* value) {
  311. // Fast path: We have enough bytes left in the buffer to guarantee that
  312. // this read won't cross the end, so we can skip the checks.
  313. GOOGLE_DCHECK_EQ(*buffer, first_byte);
  314. GOOGLE_DCHECK_EQ(first_byte & 0x80, 0x80) << first_byte;
  315. const uint8* ptr = buffer;
  316. uint32 b;
  317. uint32 result = first_byte - 0x80;
  318. ++ptr; // We just processed the first byte. Move on to the second.
  319. b = *(ptr++);
  320. result += b << 7;
  321. if (!(b & 0x80)) goto done;
  322. result -= 0x80 << 7;
  323. b = *(ptr++);
  324. result += b << 14;
  325. if (!(b & 0x80)) goto done;
  326. result -= 0x80 << 14;
  327. b = *(ptr++);
  328. result += b << 21;
  329. if (!(b & 0x80)) goto done;
  330. result -= 0x80 << 21;
  331. b = *(ptr++);
  332. result += b << 28;
  333. if (!(b & 0x80)) goto done;
  334. // "result -= 0x80 << 28" is irrevelant.
  335. // If the input is larger than 32 bits, we still need to read it all
  336. // and discard the high-order bits.
  337. for (int i = 0; i < kMaxVarintBytes - kMaxVarint32Bytes; i++) {
  338. b = *(ptr++);
  339. if (!(b & 0x80)) goto done;
  340. }
  341. // We have overrun the maximum size of a varint (10 bytes). Assume
  342. // the data is corrupt.
  343. return std::make_pair(false, ptr);
  344. done:
  345. *value = result;
  346. return std::make_pair(true, ptr);
  347. }
  348. PROTOBUF_ALWAYS_INLINE::std::pair<bool, const uint8*> ReadVarint64FromArray(
  349. const uint8* buffer, uint64* value);
  350. inline ::std::pair<bool, const uint8*> ReadVarint64FromArray(
  351. const uint8* buffer, uint64* value) {
  352. // Assumes varint64 is at least 2 bytes.
  353. GOOGLE_DCHECK_GE(buffer[0], 128);
  354. const uint8* next;
  355. if (buffer[1] < 128) {
  356. next = DecodeVarint64KnownSize<2>(buffer, value);
  357. } else if (buffer[2] < 128) {
  358. next = DecodeVarint64KnownSize<3>(buffer, value);
  359. } else if (buffer[3] < 128) {
  360. next = DecodeVarint64KnownSize<4>(buffer, value);
  361. } else if (buffer[4] < 128) {
  362. next = DecodeVarint64KnownSize<5>(buffer, value);
  363. } else if (buffer[5] < 128) {
  364. next = DecodeVarint64KnownSize<6>(buffer, value);
  365. } else if (buffer[6] < 128) {
  366. next = DecodeVarint64KnownSize<7>(buffer, value);
  367. } else if (buffer[7] < 128) {
  368. next = DecodeVarint64KnownSize<8>(buffer, value);
  369. } else if (buffer[8] < 128) {
  370. next = DecodeVarint64KnownSize<9>(buffer, value);
  371. } else if (buffer[9] < 128) {
  372. next = DecodeVarint64KnownSize<10>(buffer, value);
  373. } else {
  374. // We have overrun the maximum size of a varint (10 bytes). Assume
  375. // the data is corrupt.
  376. return std::make_pair(false, buffer + 11);
  377. }
  378. return std::make_pair(true, next);
  379. }
  380. } // namespace
  381. bool CodedInputStream::ReadVarint32Slow(uint32* value) {
  382. // Directly invoke ReadVarint64Fallback, since we already tried to optimize
  383. // for one-byte varints.
  384. std::pair<uint64, bool> p = ReadVarint64Fallback();
  385. *value = static_cast<uint32>(p.first);
  386. return p.second;
  387. }
  388. int64 CodedInputStream::ReadVarint32Fallback(uint32 first_byte_or_zero) {
  389. if (BufferSize() >= kMaxVarintBytes ||
  390. // Optimization: We're also safe if the buffer is non-empty and it ends
  391. // with a byte that would terminate a varint.
  392. (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) {
  393. GOOGLE_DCHECK_NE(first_byte_or_zero, 0)
  394. << "Caller should provide us with *buffer_ when buffer is non-empty";
  395. uint32 temp;
  396. ::std::pair<bool, const uint8*> p =
  397. ReadVarint32FromArray(first_byte_or_zero, buffer_, &temp);
  398. if (!p.first) return -1;
  399. buffer_ = p.second;
  400. return temp;
  401. } else {
  402. // Really slow case: we will incur the cost of an extra function call here,
  403. // but moving this out of line reduces the size of this function, which
  404. // improves the common case. In micro benchmarks, this is worth about 10-15%
  405. uint32 temp;
  406. return ReadVarint32Slow(&temp) ? static_cast<int64>(temp) : -1;
  407. }
  408. }
  409. int CodedInputStream::ReadVarintSizeAsIntSlow() {
  410. // Directly invoke ReadVarint64Fallback, since we already tried to optimize
  411. // for one-byte varints.
  412. std::pair<uint64, bool> p = ReadVarint64Fallback();
  413. if (!p.second || p.first > static_cast<uint64>(INT_MAX)) return -1;
  414. return p.first;
  415. }
  416. int CodedInputStream::ReadVarintSizeAsIntFallback() {
  417. if (BufferSize() >= kMaxVarintBytes ||
  418. // Optimization: We're also safe if the buffer is non-empty and it ends
  419. // with a byte that would terminate a varint.
  420. (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) {
  421. uint64 temp;
  422. ::std::pair<bool, const uint8*> p = ReadVarint64FromArray(buffer_, &temp);
  423. if (!p.first || temp > static_cast<uint64>(INT_MAX)) return -1;
  424. buffer_ = p.second;
  425. return temp;
  426. } else {
  427. // Really slow case: we will incur the cost of an extra function call here,
  428. // but moving this out of line reduces the size of this function, which
  429. // improves the common case. In micro benchmarks, this is worth about 10-15%
  430. return ReadVarintSizeAsIntSlow();
  431. }
  432. }
  433. uint32 CodedInputStream::ReadTagSlow() {
  434. if (buffer_ == buffer_end_) {
  435. // Call refresh.
  436. if (!Refresh()) {
  437. // Refresh failed. Make sure that it failed due to EOF, not because
  438. // we hit total_bytes_limit_, which, unlike normal limits, is not a
  439. // valid place to end a message.
  440. int current_position = total_bytes_read_ - buffer_size_after_limit_;
  441. if (current_position >= total_bytes_limit_) {
  442. // Hit total_bytes_limit_. But if we also hit the normal limit,
  443. // we're still OK.
  444. legitimate_message_end_ = current_limit_ == total_bytes_limit_;
  445. } else {
  446. legitimate_message_end_ = true;
  447. }
  448. return 0;
  449. }
  450. }
  451. // For the slow path, just do a 64-bit read. Try to optimize for one-byte tags
  452. // again, since we have now refreshed the buffer.
  453. uint64 result = 0;
  454. if (!ReadVarint64(&result)) return 0;
  455. return static_cast<uint32>(result);
  456. }
  457. uint32 CodedInputStream::ReadTagFallback(uint32 first_byte_or_zero) {
  458. const int buf_size = BufferSize();
  459. if (buf_size >= kMaxVarintBytes ||
  460. // Optimization: We're also safe if the buffer is non-empty and it ends
  461. // with a byte that would terminate a varint.
  462. (buf_size > 0 && !(buffer_end_[-1] & 0x80))) {
  463. GOOGLE_DCHECK_EQ(first_byte_or_zero, buffer_[0]);
  464. if (first_byte_or_zero == 0) {
  465. ++buffer_;
  466. return 0;
  467. }
  468. uint32 tag;
  469. ::std::pair<bool, const uint8*> p =
  470. ReadVarint32FromArray(first_byte_or_zero, buffer_, &tag);
  471. if (!p.first) {
  472. return 0;
  473. }
  474. buffer_ = p.second;
  475. return tag;
  476. } else {
  477. // We are commonly at a limit when attempting to read tags. Try to quickly
  478. // detect this case without making another function call.
  479. if ((buf_size == 0) &&
  480. ((buffer_size_after_limit_ > 0) ||
  481. (total_bytes_read_ == current_limit_)) &&
  482. // Make sure that the limit we hit is not total_bytes_limit_, since
  483. // in that case we still need to call Refresh() so that it prints an
  484. // error.
  485. total_bytes_read_ - buffer_size_after_limit_ < total_bytes_limit_) {
  486. // We hit a byte limit.
  487. legitimate_message_end_ = true;
  488. return 0;
  489. }
  490. return ReadTagSlow();
  491. }
  492. }
  493. bool CodedInputStream::ReadVarint64Slow(uint64* value) {
  494. // Slow path: This read might cross the end of the buffer, so we
  495. // need to check and refresh the buffer if and when it does.
  496. uint64 result = 0;
  497. int count = 0;
  498. uint32 b;
  499. do {
  500. if (count == kMaxVarintBytes) {
  501. *value = 0;
  502. return false;
  503. }
  504. while (buffer_ == buffer_end_) {
  505. if (!Refresh()) {
  506. *value = 0;
  507. return false;
  508. }
  509. }
  510. b = *buffer_;
  511. result |= static_cast<uint64>(b & 0x7F) << (7 * count);
  512. Advance(1);
  513. ++count;
  514. } while (b & 0x80);
  515. *value = result;
  516. return true;
  517. }
  518. std::pair<uint64, bool> CodedInputStream::ReadVarint64Fallback() {
  519. if (BufferSize() >= kMaxVarintBytes ||
  520. // Optimization: We're also safe if the buffer is non-empty and it ends
  521. // with a byte that would terminate a varint.
  522. (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) {
  523. uint64 temp;
  524. ::std::pair<bool, const uint8*> p = ReadVarint64FromArray(buffer_, &temp);
  525. if (!p.first) {
  526. return std::make_pair(0, false);
  527. }
  528. buffer_ = p.second;
  529. return std::make_pair(temp, true);
  530. } else {
  531. uint64 temp;
  532. bool success = ReadVarint64Slow(&temp);
  533. return std::make_pair(temp, success);
  534. }
  535. }
  536. bool CodedInputStream::Refresh() {
  537. GOOGLE_DCHECK_EQ(0, BufferSize());
  538. if (buffer_size_after_limit_ > 0 || overflow_bytes_ > 0 ||
  539. total_bytes_read_ == current_limit_) {
  540. // We've hit a limit. Stop.
  541. int current_position = total_bytes_read_ - buffer_size_after_limit_;
  542. if (current_position >= total_bytes_limit_ &&
  543. total_bytes_limit_ != current_limit_) {
  544. // Hit total_bytes_limit_.
  545. PrintTotalBytesLimitError();
  546. }
  547. return false;
  548. }
  549. const void* void_buffer;
  550. int buffer_size;
  551. if (NextNonEmpty(input_, &void_buffer, &buffer_size)) {
  552. buffer_ = reinterpret_cast<const uint8*>(void_buffer);
  553. buffer_end_ = buffer_ + buffer_size;
  554. GOOGLE_CHECK_GE(buffer_size, 0);
  555. if (total_bytes_read_ <= INT_MAX - buffer_size) {
  556. total_bytes_read_ += buffer_size;
  557. } else {
  558. // Overflow. Reset buffer_end_ to not include the bytes beyond INT_MAX.
  559. // We can't get that far anyway, because total_bytes_limit_ is guaranteed
  560. // to be less than it. We need to keep track of the number of bytes
  561. // we discarded, though, so that we can call input_->BackUp() to back
  562. // up over them on destruction.
  563. // The following line is equivalent to:
  564. // overflow_bytes_ = total_bytes_read_ + buffer_size - INT_MAX;
  565. // except that it avoids overflows. Signed integer overflow has
  566. // undefined results according to the C standard.
  567. overflow_bytes_ = total_bytes_read_ - (INT_MAX - buffer_size);
  568. buffer_end_ -= overflow_bytes_;
  569. total_bytes_read_ = INT_MAX;
  570. }
  571. RecomputeBufferLimits();
  572. return true;
  573. } else {
  574. buffer_ = NULL;
  575. buffer_end_ = NULL;
  576. return false;
  577. }
  578. }
  579. // CodedOutputStream =================================================
  580. void EpsCopyOutputStream::EnableAliasing(bool enabled) {
  581. aliasing_enabled_ = enabled && stream_->AllowsAliasing();
  582. }
  583. int64 EpsCopyOutputStream::ByteCount(uint8* ptr) const {
  584. // Calculate the current offset relative to the end of the stream buffer.
  585. int delta = (end_ - ptr) + (buffer_end_ ? 0 : kSlopBytes);
  586. return stream_->ByteCount() - delta;
  587. }
  588. // Flushes what's written out to the underlying ZeroCopyOutputStream buffers.
  589. // Returns the size remaining in the buffer and sets buffer_end_ to the start
  590. // of the remaining buffer, ie. [buffer_end_, buffer_end_ + return value)
  591. int EpsCopyOutputStream::Flush(uint8* ptr) {
  592. while (buffer_end_ && ptr > end_) {
  593. int overrun = ptr - end_;
  594. GOOGLE_DCHECK(!had_error_);
  595. GOOGLE_DCHECK(overrun <= kSlopBytes); // NOLINT
  596. ptr = Next() + overrun;
  597. if (had_error_) return 0;
  598. }
  599. int s;
  600. if (buffer_end_) {
  601. std::memcpy(buffer_end_, buffer_, ptr - buffer_);
  602. buffer_end_ += ptr - buffer_;
  603. s = end_ - ptr;
  604. } else {
  605. // The stream is writing directly in the ZeroCopyOutputStream buffer.
  606. s = end_ + kSlopBytes - ptr;
  607. buffer_end_ = ptr;
  608. }
  609. GOOGLE_DCHECK(s >= 0); // NOLINT
  610. return s;
  611. }
  612. uint8* EpsCopyOutputStream::Trim(uint8* ptr) {
  613. if (had_error_) return ptr;
  614. int s = Flush(ptr);
  615. if (s) stream_->BackUp(s);
  616. // Reset to initial state (expecting new buffer)
  617. buffer_end_ = end_ = buffer_;
  618. return buffer_;
  619. }
  620. uint8* EpsCopyOutputStream::FlushAndResetBuffer(uint8* ptr) {
  621. if (had_error_) return buffer_;
  622. int s = Flush(ptr);
  623. if (had_error_) return buffer_;
  624. return SetInitialBuffer(buffer_end_, s);
  625. }
  626. bool EpsCopyOutputStream::Skip(int count, uint8** pp) {
  627. if (count < 0) return false;
  628. if (had_error_) {
  629. *pp = buffer_;
  630. return false;
  631. }
  632. int size = Flush(*pp);
  633. if (had_error_) {
  634. *pp = buffer_;
  635. return false;
  636. }
  637. void* data = buffer_end_;
  638. while (count > size) {
  639. count -= size;
  640. if (!stream_->Next(&data, &size)) {
  641. *pp = Error();
  642. return false;
  643. }
  644. }
  645. *pp = SetInitialBuffer(static_cast<uint8*>(data) + count, size - count);
  646. return true;
  647. }
  648. bool EpsCopyOutputStream::GetDirectBufferPointer(void** data, int* size,
  649. uint8** pp) {
  650. if (had_error_) {
  651. *pp = buffer_;
  652. return false;
  653. }
  654. *size = Flush(*pp);
  655. if (had_error_) {
  656. *pp = buffer_;
  657. return false;
  658. }
  659. *data = buffer_end_;
  660. while (*size == 0) {
  661. if (!stream_->Next(data, size)) {
  662. *pp = Error();
  663. return false;
  664. }
  665. }
  666. *pp = SetInitialBuffer(*data, *size);
  667. return true;
  668. }
  669. uint8* EpsCopyOutputStream::GetDirectBufferForNBytesAndAdvance(int size,
  670. uint8** pp) {
  671. if (had_error_) {
  672. *pp = buffer_;
  673. return nullptr;
  674. }
  675. int s = Flush(*pp);
  676. if (had_error_) {
  677. *pp = buffer_;
  678. return nullptr;
  679. }
  680. if (s >= size) {
  681. auto res = buffer_end_;
  682. *pp = SetInitialBuffer(buffer_end_ + size, s - size);
  683. return res;
  684. } else {
  685. *pp = SetInitialBuffer(buffer_end_, s);
  686. return nullptr;
  687. }
  688. }
  689. uint8* EpsCopyOutputStream::Next() {
  690. GOOGLE_DCHECK(!had_error_); // NOLINT
  691. if (PROTOBUF_PREDICT_FALSE(stream_ == nullptr)) return Error();
  692. if (buffer_end_) {
  693. // We're in the patch buffer and need to fill up the previous buffer.
  694. std::memcpy(buffer_end_, buffer_, end_ - buffer_);
  695. uint8* ptr;
  696. int size;
  697. do {
  698. void* data;
  699. if (PROTOBUF_PREDICT_FALSE(!stream_->Next(&data, &size))) {
  700. // Stream has an error, we use the patch buffer to continue to be
  701. // able to write.
  702. return Error();
  703. }
  704. ptr = static_cast<uint8*>(data);
  705. } while (size == 0);
  706. if (PROTOBUF_PREDICT_TRUE(size > kSlopBytes)) {
  707. std::memcpy(ptr, end_, kSlopBytes);
  708. end_ = ptr + size - kSlopBytes;
  709. buffer_end_ = nullptr;
  710. return ptr;
  711. } else {
  712. GOOGLE_DCHECK(size > 0); // NOLINT
  713. // Buffer to small
  714. std::memmove(buffer_, end_, kSlopBytes);
  715. buffer_end_ = ptr;
  716. end_ = buffer_ + size;
  717. return buffer_;
  718. }
  719. } else {
  720. std::memcpy(buffer_, end_, kSlopBytes);
  721. buffer_end_ = end_;
  722. end_ = buffer_ + kSlopBytes;
  723. return buffer_;
  724. }
  725. }
  726. uint8* EpsCopyOutputStream::EnsureSpaceFallback(uint8* ptr) {
  727. do {
  728. if (PROTOBUF_PREDICT_FALSE(had_error_)) return buffer_;
  729. int overrun = ptr - end_;
  730. GOOGLE_DCHECK(overrun >= 0); // NOLINT
  731. GOOGLE_DCHECK(overrun <= kSlopBytes); // NOLINT
  732. ptr = Next() + overrun;
  733. } while (ptr >= end_);
  734. GOOGLE_DCHECK(ptr < end_); // NOLINT
  735. return ptr;
  736. }
  737. uint8* EpsCopyOutputStream::WriteRawFallback(const void* data, int size,
  738. uint8* ptr) {
  739. int s = GetSize(ptr);
  740. while (s < size) {
  741. std::memcpy(ptr, data, s);
  742. size -= s;
  743. data = static_cast<const uint8*>(data) + s;
  744. ptr = EnsureSpaceFallback(ptr + s);
  745. s = GetSize(ptr);
  746. }
  747. std::memcpy(ptr, data, size);
  748. return ptr + size;
  749. }
  750. uint8* EpsCopyOutputStream::WriteAliasedRaw(const void* data, int size,
  751. uint8* ptr) {
  752. if (size < GetSize(ptr)
  753. ) {
  754. return WriteRaw(data, size, ptr);
  755. } else {
  756. ptr = Trim(ptr);
  757. if (stream_->WriteAliasedRaw(data, size)) return ptr;
  758. return Error();
  759. }
  760. }
  761. #ifndef PROTOBUF_LITTLE_ENDIAN
  762. uint8* EpsCopyOutputStream::WriteRawLittleEndian32(const void* data, int size,
  763. uint8* ptr) {
  764. auto p = static_cast<const uint8*>(data);
  765. auto end = p + size;
  766. while (end - p >= kSlopBytes) {
  767. ptr = EnsureSpace(ptr);
  768. uint32 buffer[4];
  769. static_assert(sizeof(buffer) == kSlopBytes, "Buffer must be kSlopBytes");
  770. std::memcpy(buffer, p, kSlopBytes);
  771. p += kSlopBytes;
  772. for (auto x : buffer)
  773. ptr = CodedOutputStream::WriteLittleEndian32ToArray(x, ptr);
  774. }
  775. while (p < end) {
  776. ptr = EnsureSpace(ptr);
  777. uint32 buffer;
  778. std::memcpy(&buffer, p, 4);
  779. p += 4;
  780. ptr = CodedOutputStream::WriteLittleEndian32ToArray(buffer, ptr);
  781. }
  782. return ptr;
  783. }
  784. uint8* EpsCopyOutputStream::WriteRawLittleEndian64(const void* data, int size,
  785. uint8* ptr) {
  786. auto p = static_cast<const uint8*>(data);
  787. auto end = p + size;
  788. while (end - p >= kSlopBytes) {
  789. ptr = EnsureSpace(ptr);
  790. uint64 buffer[2];
  791. static_assert(sizeof(buffer) == kSlopBytes, "Buffer must be kSlopBytes");
  792. std::memcpy(buffer, p, kSlopBytes);
  793. p += kSlopBytes;
  794. for (auto x : buffer)
  795. ptr = CodedOutputStream::WriteLittleEndian64ToArray(x, ptr);
  796. }
  797. while (p < end) {
  798. ptr = EnsureSpace(ptr);
  799. uint64 buffer;
  800. std::memcpy(&buffer, p, 8);
  801. p += 8;
  802. ptr = CodedOutputStream::WriteLittleEndian64ToArray(buffer, ptr);
  803. }
  804. return ptr;
  805. }
  806. #endif
  807. uint8* EpsCopyOutputStream::WriteStringMaybeAliasedOutline(uint32 num,
  808. const std::string& s,
  809. uint8* ptr) {
  810. ptr = EnsureSpace(ptr);
  811. uint32 size = s.size();
  812. ptr = WriteLengthDelim(num, size, ptr);
  813. return WriteRawMaybeAliased(s.data(), size, ptr);
  814. }
  815. uint8* EpsCopyOutputStream::WriteStringOutline(uint32 num, const std::string& s,
  816. uint8* ptr) {
  817. ptr = EnsureSpace(ptr);
  818. uint32 size = s.size();
  819. ptr = WriteLengthDelim(num, size, ptr);
  820. return WriteRaw(s.data(), size, ptr);
  821. }
  822. std::atomic<bool> CodedOutputStream::default_serialization_deterministic_{
  823. false};
  824. CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* stream,
  825. bool do_eager_refresh)
  826. : impl_(stream, IsDefaultSerializationDeterministic(), &cur_),
  827. start_count_(stream->ByteCount()) {
  828. if (do_eager_refresh) {
  829. void* data;
  830. int size;
  831. if (!stream->Next(&data, &size) || size == 0) return;
  832. cur_ = impl_.SetInitialBuffer(data, size);
  833. }
  834. }
  835. CodedOutputStream::~CodedOutputStream() { Trim(); }
  836. uint8* CodedOutputStream::WriteStringWithSizeToArray(const std::string& str,
  837. uint8* target) {
  838. GOOGLE_DCHECK_LE(str.size(), kuint32max);
  839. target = WriteVarint32ToArray(str.size(), target);
  840. return WriteStringToArray(str, target);
  841. }
  842. } // namespace io
  843. } // namespace protobuf
  844. } // namespace google