// 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_writer.h"
|
|
#include <algorithm>
|
|
#include "puffin/src/logging.h"
|
|
namespace puffin {
|
|
bool BufferBitWriter::WriteBits(size_t nbits, uint32_t bits) {
|
TEST_AND_RETURN_FALSE(((out_size_ - index_) * 8) - out_holder_bits_ >= nbits);
|
TEST_AND_RETURN_FALSE(nbits <= sizeof(bits) * 8);
|
while (nbits > 0) {
|
while (out_holder_bits_ >= 8) {
|
out_buf_[index_++] = out_holder_ & 0x000000FF;
|
out_holder_ >>= 8;
|
out_holder_bits_ -= 8;
|
}
|
while (out_holder_bits_ < 24 && nbits > 0) {
|
out_holder_ |= (bits & 0x000000FF) << out_holder_bits_;
|
auto min = std::min(nbits, static_cast<size_t>(8));
|
out_holder_bits_ += min;
|
bits >>= min;
|
nbits -= min;
|
}
|
}
|
return true;
|
}
|
|
bool BufferBitWriter::WriteBytes(
|
size_t nbytes,
|
const std::function<bool(uint8_t* buffer, size_t count)>& read_fn) {
|
TEST_AND_RETURN_FALSE(((out_size_ - index_) * 8) - out_holder_bits_ >=
|
(nbytes * 8));
|
TEST_AND_RETURN_FALSE(out_holder_bits_ % 8 == 0);
|
TEST_AND_RETURN_FALSE(Flush());
|
TEST_AND_RETURN_FALSE(read_fn(&out_buf_[index_], nbytes));
|
index_ += nbytes;
|
return true;
|
}
|
|
bool BufferBitWriter::WriteBoundaryBits(uint8_t bits) {
|
return WriteBits((8 - (out_holder_bits_ & 7)) & 7, bits);
|
}
|
|
bool BufferBitWriter::Flush() {
|
TEST_AND_RETURN_FALSE(WriteBoundaryBits(0));
|
while (out_holder_bits_ > 0) {
|
out_buf_[index_++] = out_holder_ & 0x000000FF;
|
out_holder_ >>= 8;
|
out_holder_bits_ -= 8;
|
}
|
return true;
|
}
|
|
size_t BufferBitWriter::Size() const {
|
return index_;
|
}
|
|
} // namespace puffin
|