aboutsummaryrefslogtreecommitdiffstats
path: root/src/bit_reader.cc
blob: 0ed68efc6ee9921727f4cb1214432a285763fe77 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "puffin/src/bit_reader.h"

#include "puffin/src/logging.h"

namespace puffin {

bool BufferBitReader::CacheBits(size_t nbits) {
  if ((in_size_ - index_) * 8 + in_cache_bits_ < nbits) {
    return false;
  }
  if (nbits > sizeof(in_cache_) * 8) {
    return false;
  }
  while (in_cache_bits_ < nbits) {
    in_cache_ |= in_buf_[index_++] << in_cache_bits_;
    in_cache_bits_ += 8;
  }
  return true;
}

uint32_t BufferBitReader::ReadBits(size_t nbits) {
  return in_cache_ & ((1U << nbits) - 1);
}

void BufferBitReader::DropBits(size_t nbits) {
  in_cache_ >>= nbits;
  in_cache_bits_ -= nbits;
}

uint8_t BufferBitReader::ReadBoundaryBits() {
  return in_cache_ & ((1 << (in_cache_bits_ & 7)) - 1);
}

size_t BufferBitReader::SkipBoundaryBits() {
  size_t nbits = in_cache_bits_ & 7;
  in_cache_ >>= nbits;
  in_cache_bits_ -= nbits;
  return nbits;
}

bool BufferBitReader::GetByteReaderFn(
    size_t length, std::function<bool(uint8_t*, size_t)>* read_fn) {
  index_ -= (in_cache_bits_ + 7) / 8;
  in_cache_ = 0;
  in_cache_bits_ = 0;
  TEST_AND_RETURN_FALSE(length <= in_size_ - index_);
  *read_fn = [this, length](uint8_t* buffer, size_t count) mutable {
    TEST_AND_RETURN_FALSE(count <= length);
    if (buffer != nullptr) {
      memcpy(buffer, &in_buf_[index_], count);
    }
    index_ += count;
    length -= count;
    return true;
  };
  return true;
}

size_t BufferBitReader::Offset() const {
  return index_ - in_cache_bits_ / 8;
}

uint64_t BufferBitReader::OffsetInBits() const {
  return (index_ * 8) - in_cache_bits_;
}

uint64_t BufferBitReader::BitsRemaining() const {
  return ((in_size_ - index_) * 8) + in_cache_bits_;
}

}  // namespace puffin