Home | History | Annotate | Download | only in src
      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/set_errors.h"
     10 
     11 namespace puffin {
     12 
     13 bool 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 
     33 bool 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 
     45 bool BufferBitWriter::WriteBoundaryBits(uint8_t bits) {
     46   return WriteBits((8 - (out_holder_bits_ & 7)) & 7, bits);
     47 }
     48 
     49 bool 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 
     59 size_t BufferBitWriter::Size() const {
     60   return index_;
     61 }
     62 
     63 }  // namespace puffin
     64