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 
CacheBits(size_t nbits)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 
ReadBits(size_t nbits)25 uint32_t BufferBitReader::ReadBits(size_t nbits) {
26   return in_cache_ & ((1U << nbits) - 1);
27 }
28 
DropBits(size_t nbits)29 void BufferBitReader::DropBits(size_t nbits) {
30   in_cache_ >>= nbits;
31   in_cache_bits_ -= nbits;
32 }
33 
ReadBoundaryBits()34 uint8_t BufferBitReader::ReadBoundaryBits() {
35   return in_cache_ & ((1 << (in_cache_bits_ & 7)) - 1);
36 }
37 
SkipBoundaryBits()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 
GetByteReaderFn(size_t length,std::function<bool (uint8_t *,size_t)> * read_fn)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 
Offset() const63 size_t BufferBitReader::Offset() const {
64   return index_ - in_cache_bits_ / 8;
65 }
66 
OffsetInBits() const67 uint64_t BufferBitReader::OffsetInBits() const {
68   return (index_ * 8) - in_cache_bits_;
69 }
70 
BitsRemaining() const71 uint64_t BufferBitReader::BitsRemaining() const {
72   return ((in_size_ - index_) * 8) + in_cache_bits_;
73 }
74 
75 }  // namespace puffin
76