| 537 | |
| 538 | template <typename T> |
| 539 | inline bool RleBatchDecoder<T>::GetLiteralValues( |
| 540 | int32_t num_literals_to_consume, T* values) { |
| 541 | DCHECK_GE(num_literals_to_consume, 0); |
| 542 | DCHECK_GE(literal_count_, num_literals_to_consume); |
| 543 | int32_t num_consumed = 0; |
| 544 | // Copy any buffered literals left over from previous calls. |
| 545 | if (HaveBufferedLiterals()) { |
| 546 | num_consumed = OutputBufferedLiterals(num_literals_to_consume, values); |
| 547 | } |
| 548 | |
| 549 | int32_t num_remaining = num_literals_to_consume - num_consumed; |
| 550 | // Copy literals directly to the output, bypassing 'literal_buffer_' when possible. |
| 551 | // Need to round to a batch of 32 if the caller is consuming only part of the current |
| 552 | // run avoid ending on a non-byte boundary. |
| 553 | int32_t num_to_bypass = std::min<int32_t>(literal_count_, |
| 554 | BitUtil::RoundDownToPowerOf2(num_remaining, 32)); |
| 555 | if (num_to_bypass > 0) { |
| 556 | int num_read = |
| 557 | bit_reader_.UnpackBatch(bit_width_, num_to_bypass, values + num_consumed); |
| 558 | // If we couldn't read the expected number, that means the input was truncated. |
| 559 | if (num_read < num_to_bypass) return false; |
| 560 | literal_count_ -= num_to_bypass; |
| 561 | num_consumed += num_to_bypass; |
| 562 | num_remaining = num_literals_to_consume - num_consumed; |
| 563 | } |
| 564 | |
| 565 | if (num_remaining > 0) { |
| 566 | // We weren't able to copy all the literals requested directly from the input. |
| 567 | // Buffer literals and copy over the requested number. |
| 568 | if (UNLIKELY(!FillLiteralBuffer())) return false; |
| 569 | int32_t num_copied = OutputBufferedLiterals(num_remaining, values + num_consumed); |
| 570 | DCHECK_EQ(num_copied, num_remaining) << "Should have buffered enough literals"; |
| 571 | } |
| 572 | return true; |
| 573 | } |
| 574 | |
| 575 | template <typename T> |
| 576 | inline bool RleBatchDecoder<T>::SkipLiteralValues(int32_t num_literals_to_skip) { |