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_writer.h" 6 7 #include <algorithm> 8 9 #include "puffin/src/logging.h" 10 11 namespace puffin { 12 WriteBits(size_t nbits,uint32_t bits)13bool BufferBitWriter::WriteBits(size_t nbits, uint32_t bits) { 14 TEST_AND_RETURN_FALSE(((out_size_ - index_) * 8) - out_holder_bits_ >= nbits); 15 TEST_AND_RETURN_FALSE(nbits <= sizeof(bits) * 8); 16 while (nbits > 0) { 17 while (out_holder_bits_ >= 8) { 18 out_buf_[index_++] = out_holder_ & 0x000000FF; 19 out_holder_ >>= 8; 20 out_holder_bits_ -= 8; 21 } 22 while (out_holder_bits_ < 24 && nbits > 0) { 23 out_holder_ |= (bits & 0x000000FF) << out_holder_bits_; 24 auto min = std::min(nbits, static_cast<size_t>(8)); 25 out_holder_bits_ += min; 26 bits >>= min; 27 nbits -= min; 28 } 29 } 30 return true; 31 } 32 WriteBytes(size_t nbytes,const std::function<bool (uint8_t * buffer,size_t count)> & read_fn)33bool BufferBitWriter::WriteBytes( 34 size_t nbytes, 35 const std::function<bool(uint8_t* buffer, size_t count)>& read_fn) { 36 TEST_AND_RETURN_FALSE(((out_size_ - index_) * 8) - out_holder_bits_ >= 37 (nbytes * 8)); 38 TEST_AND_RETURN_FALSE(out_holder_bits_ % 8 == 0); 39 TEST_AND_RETURN_FALSE(Flush()); 40 TEST_AND_RETURN_FALSE(read_fn(&out_buf_[index_], nbytes)); 41 index_ += nbytes; 42 return true; 43 } 44 WriteBoundaryBits(uint8_t bits)45bool BufferBitWriter::WriteBoundaryBits(uint8_t bits) { 46 return WriteBits((8 - (out_holder_bits_ & 7)) & 7, bits); 47 } 48 Flush()49bool BufferBitWriter::Flush() { 50 TEST_AND_RETURN_FALSE(WriteBoundaryBits(0)); 51 while (out_holder_bits_ > 0) { 52 out_buf_[index_++] = out_holder_ & 0x000000FF; 53 out_holder_ >>= 8; 54 out_holder_bits_ -= 8; 55 } 56 return true; 57 } 58 Size() const59size_t BufferBitWriter::Size() const { 60 return index_; 61 } 62 63 } // namespace puffin 64