Commit 25744852 authored by nagayama15's avatar nagayama15

Add bit stream writer

parent 7dd3140d
#ifndef INCLUDE_kyut_BitStreamWriter_hpp
#define INCLUDE_kyut_BitStreamWriter_hpp
#include <cassert>
#include <cstdint>
#include <vector>
namespace kyut {
class BitStreamWriter {
public:
explicit BitStreamWriter()
: data_()
, pos_write_(0) {}
BitStreamWriter(const BitStreamWriter &) = delete;
BitStreamWriter(BitStreamWriter &&) = delete;
BitStreamWriter &operator=(const BitStreamWriter &) = delete;
BitStreamWriter &operator=(BitStreamWriter &&) = delete;
~BitStreamWriter() noexcept = default;
[[nodiscard]] const std::vector<std::uint8_t> &data() const noexcept {
return data_;
}
[[nodiscard]] std::size_t tell() const noexcept {
return pos_write_;
}
void writeBit(bool value) {
if (pos_write_ % 8 == 0) {
data_.emplace_back(0);
}
data_[pos_write_ / 8] |= (value ? 1 : 0) << (7 - pos_write_ % 8);
pos_write_++;
}
void write(std::uint64_t value, std::size_t length) {
assert(length <= 64);
for (std::size_t i = 0; i < length; i++) {
writeBit((value & (1 << (length - i - 1))) != 0);
}
}
private:
std::vector<std::uint8_t> data_;
std::size_t pos_write_;
};
} // namespace kyut
#endif // INCLUDE_kyut_BitStreamWriter_hpp
...@@ -31,6 +31,10 @@ namespace kyut { ...@@ -31,6 +31,10 @@ namespace kyut {
reinterpret_cast<const std::uint8_t *>(s.data() + s.size())); reinterpret_cast<const std::uint8_t *>(s.data() + s.size()));
} }
[[nodiscard]] const std::vector<std::uint8_t> &data() const noexcept {
return data_;
}
[[nodiscard]] std::size_t tell() const noexcept { [[nodiscard]] std::size_t tell() const noexcept {
return pos_read_; return pos_read_;
} }
......
add_executable(test_kyut add_executable(test_kyut
test_kyut.cpp test_kyut.cpp
kyut/test_BitStreamReader.cpp kyut/test_CircularBitStreamReader.cpp
kyut/test_BitStreamWriter.cpp
kyut/watermarker/test_FunctionOrderingWatermarker.cpp kyut/watermarker/test_FunctionOrderingWatermarker.cpp
) )
......
#include <kyut/BitStreamWriter.hpp>
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_SUITE(kyut)
BOOST_AUTO_TEST_SUITE(bit_stream_writer)
BOOST_AUTO_TEST_CASE(write_bit) {
BitStreamWriter s;
BOOST_REQUIRE_EQUAL(s.data().size(), std::size_t{0});
BOOST_REQUIRE_EQUAL(s.tell(), std::size_t{0});
s.writeBit(true);
BOOST_REQUIRE_EQUAL(s.data().size(), std::size_t{1});
BOOST_REQUIRE_EQUAL(s.data()[0], std::uint8_t{0b1000'0000});
BOOST_REQUIRE_EQUAL(s.tell(), std::size_t{1});
s.writeBit(true);
BOOST_REQUIRE_EQUAL(s.data().size(), std::size_t{1});
BOOST_REQUIRE_EQUAL(s.data()[0], std::uint8_t{0b1100'0000});
BOOST_REQUIRE_EQUAL(s.tell(), std::size_t{2});
s.writeBit(false);
BOOST_REQUIRE_EQUAL(s.data().size(), std::size_t{1});
BOOST_REQUIRE_EQUAL(s.data()[0], std::uint8_t{0b1100'0000});
BOOST_REQUIRE_EQUAL(s.tell(), std::size_t{3});
s.writeBit(false);
s.writeBit(true);
s.writeBit(false);
s.writeBit(true);
s.writeBit(true);
BOOST_REQUIRE_EQUAL(s.data().size(), std::size_t{1});
BOOST_REQUIRE_EQUAL(s.data()[0], std::uint8_t{0b1100'1011});
BOOST_REQUIRE_EQUAL(s.tell(), std::size_t{8});
}
BOOST_AUTO_TEST_CASE(write) {
BitStreamWriter s;
BOOST_REQUIRE_EQUAL(s.data().size(), std::size_t{0});
BOOST_REQUIRE_EQUAL(s.tell(), std::size_t{0});
s.write(0xabcd, 16);
BOOST_REQUIRE_EQUAL(s.data().size(), std::size_t{2});
BOOST_REQUIRE_EQUAL(s.data()[0], std::uint8_t{0xab});
BOOST_REQUIRE_EQUAL(s.data()[1], std::uint8_t{0xcd});
BOOST_REQUIRE_EQUAL(s.tell(), std::size_t{16});
}
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_SUITE_END()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment