coded_stream.cc 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780
  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_inl.h>
  40. #include <algorithm>
  41. #include <utility>
  42. #include <limits.h>
  43. #include <google/protobuf/io/zero_copy_stream.h>
  44. #include <google/protobuf/arena.h>
  45. #include <google/protobuf/stubs/logging.h>
  46. #include <google/protobuf/stubs/common.h>
  47. #include <google/protobuf/stubs/stl_util.h>
  48. namespace google {
  49. namespace protobuf {
  50. namespace io {
  51. namespace {
  52. static const int kMaxVarintBytes = 10;
  53. static const int kMaxVarint32Bytes = 5;
  54. inline bool NextNonEmpty(ZeroCopyInputStream* input,
  55. const void** data, int* size) {
  56. bool success;
  57. do {
  58. success = input->Next(data, size);
  59. } while (success && *size == 0);
  60. return success;
  61. }
  62. } // namespace
  63. // CodedInputStream ==================================================
  64. CodedInputStream::~CodedInputStream() {
  65. if (input_ != NULL) {
  66. BackUpInputToCurrentPosition();
  67. }
  68. }
  69. // Static.
  70. int CodedInputStream::default_recursion_limit_ = 100;
  71. void CodedOutputStream::EnableAliasing(bool enabled) {
  72. aliasing_enabled_ = enabled && output_->AllowsAliasing();
  73. }
  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 (GOOGLE_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) << "A protocol message was rejected because it was too "
  159. "big (more than " << total_bytes_limit_
  160. << " bytes). To increase the limit (or to disable these "
  161. "warnings), see CodedInputStream::SetTotalBytesLimit() "
  162. "in google/protobuf/io/coded_stream.h.";
  163. }
  164. bool CodedInputStream::SkipFallback(int count, int original_buffer_size) {
  165. if (buffer_size_after_limit_ > 0) {
  166. // We hit a limit inside this buffer. Advance to the limit and fail.
  167. Advance(original_buffer_size);
  168. return false;
  169. }
  170. count -= original_buffer_size;
  171. buffer_ = NULL;
  172. buffer_end_ = buffer_;
  173. // Make sure this skip doesn't try to skip past the current limit.
  174. int closest_limit = std::min(current_limit_, total_bytes_limit_);
  175. int bytes_until_limit = closest_limit - total_bytes_read_;
  176. if (bytes_until_limit < count) {
  177. // We hit the limit. Skip up to it then fail.
  178. if (bytes_until_limit > 0) {
  179. total_bytes_read_ = closest_limit;
  180. input_->Skip(bytes_until_limit);
  181. }
  182. return false;
  183. }
  184. if (!input_->Skip(count)) {
  185. total_bytes_read_ = input_->ByteCount();
  186. return false;
  187. }
  188. total_bytes_read_ += count;
  189. return true;
  190. }
  191. bool CodedInputStream::GetDirectBufferPointer(const void** data, int* size) {
  192. if (BufferSize() == 0 && !Refresh()) return false;
  193. *data = buffer_;
  194. *size = BufferSize();
  195. return true;
  196. }
  197. bool CodedInputStream::ReadRaw(void* buffer, int size) {
  198. return InternalReadRawInline(buffer, size);
  199. }
  200. bool CodedInputStream::ReadString(string* buffer, int size) {
  201. if (size < 0) return false; // security: size is often user-supplied
  202. return InternalReadStringInline(buffer, size);
  203. }
  204. bool CodedInputStream::ReadStringFallback(string* buffer, int size) {
  205. if (!buffer->empty()) {
  206. buffer->clear();
  207. }
  208. int closest_limit = std::min(current_limit_, total_bytes_limit_);
  209. if (closest_limit != INT_MAX) {
  210. int bytes_to_limit = closest_limit - CurrentPosition();
  211. if (bytes_to_limit > 0 && size > 0 && size <= bytes_to_limit) {
  212. buffer->reserve(size);
  213. }
  214. }
  215. int current_buffer_size;
  216. while ((current_buffer_size = BufferSize()) < size) {
  217. // Some STL implementations "helpfully" crash on buffer->append(NULL, 0).
  218. if (current_buffer_size != 0) {
  219. // Note: string1.append(string2) is O(string2.size()) (as opposed to
  220. // O(string1.size() + string2.size()), which would be bad).
  221. buffer->append(reinterpret_cast<const char*>(buffer_),
  222. current_buffer_size);
  223. }
  224. size -= current_buffer_size;
  225. Advance(current_buffer_size);
  226. if (!Refresh()) return false;
  227. }
  228. buffer->append(reinterpret_cast<const char*>(buffer_), size);
  229. Advance(size);
  230. return true;
  231. }
  232. bool CodedInputStream::ReadLittleEndian32Fallback(uint32* value) {
  233. uint8 bytes[sizeof(*value)];
  234. const uint8* ptr;
  235. if (BufferSize() >= sizeof(*value)) {
  236. // Fast path: Enough bytes in the buffer to read directly.
  237. ptr = buffer_;
  238. Advance(sizeof(*value));
  239. } else {
  240. // Slow path: Had to read past the end of the buffer.
  241. if (!ReadRaw(bytes, sizeof(*value))) return false;
  242. ptr = bytes;
  243. }
  244. ReadLittleEndian32FromArray(ptr, value);
  245. return true;
  246. }
  247. bool CodedInputStream::ReadLittleEndian64Fallback(uint64* value) {
  248. uint8 bytes[sizeof(*value)];
  249. const uint8* ptr;
  250. if (BufferSize() >= sizeof(*value)) {
  251. // Fast path: Enough bytes in the buffer to read directly.
  252. ptr = buffer_;
  253. Advance(sizeof(*value));
  254. } else {
  255. // Slow path: Had to read past the end of the buffer.
  256. if (!ReadRaw(bytes, sizeof(*value))) return false;
  257. ptr = bytes;
  258. }
  259. ReadLittleEndian64FromArray(ptr, value);
  260. return true;
  261. }
  262. namespace {
  263. // Read a varint from the given buffer, write it to *value, and return a pair.
  264. // The first part of the pair is true iff the read was successful. The second
  265. // part is buffer + (number of bytes read). This function is always inlined,
  266. // so returning a pair is costless.
  267. GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
  268. ::std::pair<bool, const uint8*> ReadVarint32FromArray(
  269. uint32 first_byte, const uint8* buffer,
  270. uint32* value);
  271. inline ::std::pair<bool, const uint8*> ReadVarint32FromArray(
  272. uint32 first_byte, const uint8* buffer, uint32* value) {
  273. // Fast path: We have enough bytes left in the buffer to guarantee that
  274. // this read won't cross the end, so we can skip the checks.
  275. GOOGLE_DCHECK_EQ(*buffer, first_byte);
  276. GOOGLE_DCHECK_EQ(first_byte & 0x80, 0x80) << first_byte;
  277. const uint8* ptr = buffer;
  278. uint32 b;
  279. uint32 result = first_byte - 0x80;
  280. ++ptr; // We just processed the first byte. Move on to the second.
  281. b = *(ptr++); result += b << 7; if (!(b & 0x80)) goto done;
  282. result -= 0x80 << 7;
  283. b = *(ptr++); result += b << 14; if (!(b & 0x80)) goto done;
  284. result -= 0x80 << 14;
  285. b = *(ptr++); result += b << 21; if (!(b & 0x80)) goto done;
  286. result -= 0x80 << 21;
  287. b = *(ptr++); result += b << 28; if (!(b & 0x80)) goto done;
  288. // "result -= 0x80 << 28" is irrevelant.
  289. // If the input is larger than 32 bits, we still need to read it all
  290. // and discard the high-order bits.
  291. for (int i = 0; i < kMaxVarintBytes - kMaxVarint32Bytes; i++) {
  292. b = *(ptr++); if (!(b & 0x80)) goto done;
  293. }
  294. // We have overrun the maximum size of a varint (10 bytes). Assume
  295. // the data is corrupt.
  296. return std::make_pair(false, ptr);
  297. done:
  298. *value = result;
  299. return std::make_pair(true, ptr);
  300. }
  301. GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE::std::pair<bool, const uint8*>
  302. ReadVarint64FromArray(const uint8* buffer, uint64* value);
  303. inline ::std::pair<bool, const uint8*> ReadVarint64FromArray(
  304. const uint8* buffer, uint64* value) {
  305. const uint8* ptr = buffer;
  306. uint32 b;
  307. // Splitting into 32-bit pieces gives better performance on 32-bit
  308. // processors.
  309. uint32 part0 = 0, part1 = 0, part2 = 0;
  310. b = *(ptr++); part0 = b ; if (!(b & 0x80)) goto done;
  311. part0 -= 0x80;
  312. b = *(ptr++); part0 += b << 7; if (!(b & 0x80)) goto done;
  313. part0 -= 0x80 << 7;
  314. b = *(ptr++); part0 += b << 14; if (!(b & 0x80)) goto done;
  315. part0 -= 0x80 << 14;
  316. b = *(ptr++); part0 += b << 21; if (!(b & 0x80)) goto done;
  317. part0 -= 0x80 << 21;
  318. b = *(ptr++); part1 = b ; if (!(b & 0x80)) goto done;
  319. part1 -= 0x80;
  320. b = *(ptr++); part1 += b << 7; if (!(b & 0x80)) goto done;
  321. part1 -= 0x80 << 7;
  322. b = *(ptr++); part1 += b << 14; if (!(b & 0x80)) goto done;
  323. part1 -= 0x80 << 14;
  324. b = *(ptr++); part1 += b << 21; if (!(b & 0x80)) goto done;
  325. part1 -= 0x80 << 21;
  326. b = *(ptr++); part2 = b ; if (!(b & 0x80)) goto done;
  327. part2 -= 0x80;
  328. b = *(ptr++); part2 += b << 7; if (!(b & 0x80)) goto done;
  329. // "part2 -= 0x80 << 7" is irrelevant because (0x80 << 7) << 56 is 0.
  330. // We have overrun the maximum size of a varint (10 bytes). Assume
  331. // the data is corrupt.
  332. return std::make_pair(false, ptr);
  333. done:
  334. *value = (static_cast<uint64>(part0)) |
  335. (static_cast<uint64>(part1) << 28) |
  336. (static_cast<uint64>(part2) << 56);
  337. return std::make_pair(true, ptr);
  338. }
  339. } // namespace
  340. bool CodedInputStream::ReadVarint32Slow(uint32* value) {
  341. // Directly invoke ReadVarint64Fallback, since we already tried to optimize
  342. // for one-byte varints.
  343. std::pair<uint64, bool> p = ReadVarint64Fallback();
  344. *value = static_cast<uint32>(p.first);
  345. return p.second;
  346. }
  347. int64 CodedInputStream::ReadVarint32Fallback(uint32 first_byte_or_zero) {
  348. if (BufferSize() >= kMaxVarintBytes ||
  349. // Optimization: We're also safe if the buffer is non-empty and it ends
  350. // with a byte that would terminate a varint.
  351. (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) {
  352. GOOGLE_DCHECK_NE(first_byte_or_zero, 0)
  353. << "Caller should provide us with *buffer_ when buffer is non-empty";
  354. uint32 temp;
  355. ::std::pair<bool, const uint8*> p =
  356. ReadVarint32FromArray(first_byte_or_zero, buffer_, &temp);
  357. if (!p.first) return -1;
  358. buffer_ = p.second;
  359. return temp;
  360. } else {
  361. // Really slow case: we will incur the cost of an extra function call here,
  362. // but moving this out of line reduces the size of this function, which
  363. // improves the common case. In micro benchmarks, this is worth about 10-15%
  364. uint32 temp;
  365. return ReadVarint32Slow(&temp) ? static_cast<int64>(temp) : -1;
  366. }
  367. }
  368. int CodedInputStream::ReadVarintSizeAsIntSlow() {
  369. // Directly invoke ReadVarint64Fallback, since we already tried to optimize
  370. // for one-byte varints.
  371. std::pair<uint64, bool> p = ReadVarint64Fallback();
  372. if (!p.second || p.first > static_cast<uint64>(INT_MAX)) return -1;
  373. return p.first;
  374. }
  375. int CodedInputStream::ReadVarintSizeAsIntFallback() {
  376. if (BufferSize() >= kMaxVarintBytes ||
  377. // Optimization: We're also safe if the buffer is non-empty and it ends
  378. // with a byte that would terminate a varint.
  379. (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) {
  380. uint64 temp;
  381. ::std::pair<bool, const uint8*> p = ReadVarint64FromArray(buffer_, &temp);
  382. if (!p.first || temp > static_cast<uint64>(INT_MAX)) return -1;
  383. buffer_ = p.second;
  384. return temp;
  385. } else {
  386. // Really slow case: we will incur the cost of an extra function call here,
  387. // but moving this out of line reduces the size of this function, which
  388. // improves the common case. In micro benchmarks, this is worth about 10-15%
  389. return ReadVarintSizeAsIntSlow();
  390. }
  391. }
  392. uint32 CodedInputStream::ReadTagSlow() {
  393. if (buffer_ == buffer_end_) {
  394. // Call refresh.
  395. if (!Refresh()) {
  396. // Refresh failed. Make sure that it failed due to EOF, not because
  397. // we hit total_bytes_limit_, which, unlike normal limits, is not a
  398. // valid place to end a message.
  399. int current_position = total_bytes_read_ - buffer_size_after_limit_;
  400. if (current_position >= total_bytes_limit_) {
  401. // Hit total_bytes_limit_. But if we also hit the normal limit,
  402. // we're still OK.
  403. legitimate_message_end_ = current_limit_ == total_bytes_limit_;
  404. } else {
  405. legitimate_message_end_ = true;
  406. }
  407. return 0;
  408. }
  409. }
  410. // For the slow path, just do a 64-bit read. Try to optimize for one-byte tags
  411. // again, since we have now refreshed the buffer.
  412. uint64 result = 0;
  413. if (!ReadVarint64(&result)) return 0;
  414. return static_cast<uint32>(result);
  415. }
  416. uint32 CodedInputStream::ReadTagFallback(uint32 first_byte_or_zero) {
  417. const int buf_size = BufferSize();
  418. if (buf_size >= kMaxVarintBytes ||
  419. // Optimization: We're also safe if the buffer is non-empty and it ends
  420. // with a byte that would terminate a varint.
  421. (buf_size > 0 && !(buffer_end_[-1] & 0x80))) {
  422. GOOGLE_DCHECK_EQ(first_byte_or_zero, buffer_[0]);
  423. if (first_byte_or_zero == 0) {
  424. ++buffer_;
  425. return 0;
  426. }
  427. uint32 tag;
  428. ::std::pair<bool, const uint8*> p =
  429. ReadVarint32FromArray(first_byte_or_zero, buffer_, &tag);
  430. if (!p.first) {
  431. return 0;
  432. }
  433. buffer_ = p.second;
  434. return tag;
  435. } else {
  436. // We are commonly at a limit when attempting to read tags. Try to quickly
  437. // detect this case without making another function call.
  438. if ((buf_size == 0) &&
  439. ((buffer_size_after_limit_ > 0) ||
  440. (total_bytes_read_ == current_limit_)) &&
  441. // Make sure that the limit we hit is not total_bytes_limit_, since
  442. // in that case we still need to call Refresh() so that it prints an
  443. // error.
  444. total_bytes_read_ - buffer_size_after_limit_ < total_bytes_limit_) {
  445. // We hit a byte limit.
  446. legitimate_message_end_ = true;
  447. return 0;
  448. }
  449. return ReadTagSlow();
  450. }
  451. }
  452. bool CodedInputStream::ReadVarint64Slow(uint64* value) {
  453. // Slow path: This read might cross the end of the buffer, so we
  454. // need to check and refresh the buffer if and when it does.
  455. uint64 result = 0;
  456. int count = 0;
  457. uint32 b;
  458. do {
  459. if (count == kMaxVarintBytes) {
  460. *value = 0;
  461. return false;
  462. }
  463. while (buffer_ == buffer_end_) {
  464. if (!Refresh()) {
  465. *value = 0;
  466. return false;
  467. }
  468. }
  469. b = *buffer_;
  470. result |= static_cast<uint64>(b & 0x7F) << (7 * count);
  471. Advance(1);
  472. ++count;
  473. } while (b & 0x80);
  474. *value = result;
  475. return true;
  476. }
  477. std::pair<uint64, bool> CodedInputStream::ReadVarint64Fallback() {
  478. if (BufferSize() >= kMaxVarintBytes ||
  479. // Optimization: We're also safe if the buffer is non-empty and it ends
  480. // with a byte that would terminate a varint.
  481. (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) {
  482. uint64 temp;
  483. ::std::pair<bool, const uint8*> p = ReadVarint64FromArray(buffer_, &temp);
  484. if (!p.first) {
  485. return std::make_pair(0, false);
  486. }
  487. buffer_ = p.second;
  488. return std::make_pair(temp, true);
  489. } else {
  490. uint64 temp;
  491. bool success = ReadVarint64Slow(&temp);
  492. return std::make_pair(temp, success);
  493. }
  494. }
  495. bool CodedInputStream::Refresh() {
  496. GOOGLE_DCHECK_EQ(0, BufferSize());
  497. if (buffer_size_after_limit_ > 0 || overflow_bytes_ > 0 ||
  498. total_bytes_read_ == current_limit_) {
  499. // We've hit a limit. Stop.
  500. int current_position = total_bytes_read_ - buffer_size_after_limit_;
  501. if (current_position >= total_bytes_limit_ &&
  502. total_bytes_limit_ != current_limit_) {
  503. // Hit total_bytes_limit_.
  504. PrintTotalBytesLimitError();
  505. }
  506. return false;
  507. }
  508. const void* void_buffer;
  509. int buffer_size;
  510. if (NextNonEmpty(input_, &void_buffer, &buffer_size)) {
  511. buffer_ = reinterpret_cast<const uint8*>(void_buffer);
  512. buffer_end_ = buffer_ + buffer_size;
  513. GOOGLE_CHECK_GE(buffer_size, 0);
  514. if (total_bytes_read_ <= INT_MAX - buffer_size) {
  515. total_bytes_read_ += buffer_size;
  516. } else {
  517. // Overflow. Reset buffer_end_ to not include the bytes beyond INT_MAX.
  518. // We can't get that far anyway, because total_bytes_limit_ is guaranteed
  519. // to be less than it. We need to keep track of the number of bytes
  520. // we discarded, though, so that we can call input_->BackUp() to back
  521. // up over them on destruction.
  522. // The following line is equivalent to:
  523. // overflow_bytes_ = total_bytes_read_ + buffer_size - INT_MAX;
  524. // except that it avoids overflows. Signed integer overflow has
  525. // undefined results according to the C standard.
  526. overflow_bytes_ = total_bytes_read_ - (INT_MAX - buffer_size);
  527. buffer_end_ -= overflow_bytes_;
  528. total_bytes_read_ = INT_MAX;
  529. }
  530. RecomputeBufferLimits();
  531. return true;
  532. } else {
  533. buffer_ = NULL;
  534. buffer_end_ = NULL;
  535. return false;
  536. }
  537. }
  538. // CodedOutputStream =================================================
  539. std::atomic<bool> CodedOutputStream::default_serialization_deterministic_{
  540. false};
  541. CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output)
  542. : CodedOutputStream(output, true) {}
  543. CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output,
  544. bool do_eager_refresh)
  545. : output_(output),
  546. buffer_(NULL),
  547. buffer_size_(0),
  548. total_bytes_(0),
  549. had_error_(false),
  550. aliasing_enabled_(false),
  551. is_serialization_deterministic_(IsDefaultSerializationDeterministic()) {
  552. if (do_eager_refresh) {
  553. // Eagerly Refresh() so buffer space is immediately available.
  554. Refresh();
  555. // The Refresh() may have failed. If the client doesn't write any data,
  556. // though, don't consider this an error. If the client does write data, then
  557. // another Refresh() will be attempted and it will set the error once again.
  558. had_error_ = false;
  559. }
  560. }
  561. CodedOutputStream::~CodedOutputStream() {
  562. Trim();
  563. }
  564. void CodedOutputStream::Trim() {
  565. if (buffer_size_ > 0) {
  566. output_->BackUp(buffer_size_);
  567. total_bytes_ -= buffer_size_;
  568. buffer_size_ = 0;
  569. buffer_ = NULL;
  570. }
  571. }
  572. bool CodedOutputStream::Skip(int count) {
  573. if (count < 0) return false;
  574. while (count > buffer_size_) {
  575. count -= buffer_size_;
  576. if (!Refresh()) return false;
  577. }
  578. Advance(count);
  579. return true;
  580. }
  581. bool CodedOutputStream::GetDirectBufferPointer(void** data, int* size) {
  582. if (buffer_size_ == 0 && !Refresh()) return false;
  583. *data = buffer_;
  584. *size = buffer_size_;
  585. return true;
  586. }
  587. void CodedOutputStream::WriteRaw(const void* data, int size) {
  588. while (buffer_size_ < size) {
  589. memcpy(buffer_, data, buffer_size_);
  590. size -= buffer_size_;
  591. data = reinterpret_cast<const uint8*>(data) + buffer_size_;
  592. if (!Refresh()) return;
  593. }
  594. memcpy(buffer_, data, size);
  595. Advance(size);
  596. }
  597. uint8* CodedOutputStream::WriteRawToArray(
  598. const void* data, int size, uint8* target) {
  599. memcpy(target, data, size);
  600. return target + size;
  601. }
  602. void CodedOutputStream::WriteAliasedRaw(const void* data, int size) {
  603. if (size < buffer_size_
  604. ) {
  605. WriteRaw(data, size);
  606. } else {
  607. Trim();
  608. total_bytes_ += size;
  609. had_error_ |= !output_->WriteAliasedRaw(data, size);
  610. }
  611. }
  612. void CodedOutputStream::WriteLittleEndian32(uint32 value) {
  613. uint8 bytes[sizeof(value)];
  614. bool use_fast = buffer_size_ >= sizeof(value);
  615. uint8* ptr = use_fast ? buffer_ : bytes;
  616. WriteLittleEndian32ToArray(value, ptr);
  617. if (use_fast) {
  618. Advance(sizeof(value));
  619. } else {
  620. WriteRaw(bytes, sizeof(value));
  621. }
  622. }
  623. void CodedOutputStream::WriteLittleEndian64(uint64 value) {
  624. uint8 bytes[sizeof(value)];
  625. bool use_fast = buffer_size_ >= sizeof(value);
  626. uint8* ptr = use_fast ? buffer_ : bytes;
  627. WriteLittleEndian64ToArray(value, ptr);
  628. if (use_fast) {
  629. Advance(sizeof(value));
  630. } else {
  631. WriteRaw(bytes, sizeof(value));
  632. }
  633. }
  634. void CodedOutputStream::WriteVarint32SlowPath(uint32 value) {
  635. uint8 bytes[kMaxVarint32Bytes];
  636. uint8* target = &bytes[0];
  637. uint8* end = WriteVarint32ToArray(value, target);
  638. int size = end - target;
  639. WriteRaw(bytes, size);
  640. }
  641. void CodedOutputStream::WriteVarint64SlowPath(uint64 value) {
  642. uint8 bytes[kMaxVarintBytes];
  643. uint8* target = &bytes[0];
  644. uint8* end = WriteVarint64ToArray(value, target);
  645. int size = end - target;
  646. WriteRaw(bytes, size);
  647. }
  648. bool CodedOutputStream::Refresh() {
  649. void* void_buffer;
  650. if (output_->Next(&void_buffer, &buffer_size_)) {
  651. buffer_ = reinterpret_cast<uint8*>(void_buffer);
  652. total_bytes_ += buffer_size_;
  653. return true;
  654. } else {
  655. buffer_ = NULL;
  656. buffer_size_ = 0;
  657. had_error_ = true;
  658. return false;
  659. }
  660. }
  661. uint8* CodedOutputStream::WriteStringWithSizeToArray(const string& str,
  662. uint8* target) {
  663. GOOGLE_DCHECK_LE(str.size(), kuint32max);
  664. target = WriteVarint32ToArray(str.size(), target);
  665. return WriteStringToArray(str, target);
  666. }
  667. } // namespace io
  668. } // namespace protobuf
  669. } // namespace google