1 // Copyright 2017 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "puffin/src/bit_reader.h" 6 7 #include "puffin/src/logging.h" 8 9 namespace puffin { 10 11 bool BufferBitReader::CacheBits(size_t nbits) { 12 if ((in_size_ - index_) * 8 + in_cache_bits_ < nbits) { 13 return false; 14 } 15 if (nbits > sizeof(in_cache_) * 8) { 16 return false; 17 } 18 while (in_cache_bits_ < nbits) { 19 in_cache_ |= in_buf_[index_++] << in_cache_bits_; 20 in_cache_bits_ += 8; 21 } 22 return true; 23 } 24 25 uint32_t BufferBitReader::ReadBits(size_t nbits) { 26 return in_cache_ & ((1U << nbits) - 1); 27 } 28 29 void BufferBitReader::DropBits(size_t nbits) { 30 in_cache_ >>= nbits; 31 in_cache_bits_ -= nbits; 32 } 33 34 uint8_t BufferBitReader::ReadBoundaryBits() { 35 return in_cache_ & ((1 << (in_cache_bits_ & 7)) - 1); 36 } 37 38 size_t BufferBitReader::SkipBoundaryBits() { 39 size_t nbits = in_cache_bits_ & 7; 40 in_cache_ >>= nbits; 41 in_cache_bits_ -= nbits; 42 return nbits; 43 } 44 45 bool BufferBitReader::GetByteReaderFn( 46 size_t length, std::function<bool(uint8_t*, size_t)>* read_fn) { 47 index_ -= (in_cache_bits_ + 7) / 8; 48 in_cache_ = 0; 49 in_cache_bits_ = 0; 50 TEST_AND_RETURN_FALSE(length <= in_size_ - index_); 51 *read_fn = [this, length](uint8_t* buffer, size_t count) mutable { 52 TEST_AND_RETURN_FALSE(count <= length); 53 if (buffer != nullptr) { 54 memcpy(buffer, &in_buf_[index_], count); 55 } 56 index_ += count; 57 length -= count; 58 return true; 59 }; 60 return true; 61 } 62 63 size_t BufferBitReader::Offset() const { 64 return index_ - in_cache_bits_ / 8; 65 } 66 67 uint64_t BufferBitReader::OffsetInBits() const { 68 return (index_ * 8) - in_cache_bits_; 69 } 70 71 uint64_t BufferBitReader::BitsRemaining() const { 72 return ((in_size_ - index_) * 8) + in_cache_bits_; 73 } 74 75 } // namespace puffin 76