From 105887d46817da3586cfe69c463a0873f9a7d5bb Mon Sep 17 00:00:00 2001 From: dm1sh Date: Sat, 11 Dec 2021 14:00:25 +0300 Subject: [PATCH] Added BitArray class --- QRCodeLibrary/BitArray.cpp | 37 +++++++++++++++++++ QRCodeLibrary/BitArray.hpp | 23 ++++++++++++ QRCodeLibrary/QRCodeLibrary.vcxproj | 2 ++ QRCodeLibrary/QRCodeLibrary.vcxproj.filters | 6 ++++ tests/BitArray_test.cpp | 40 +++++++++++++++++++++ tests/tests.vcxproj | 1 + 6 files changed, 109 insertions(+) create mode 100644 QRCodeLibrary/BitArray.cpp create mode 100644 QRCodeLibrary/BitArray.hpp create mode 100644 tests/BitArray_test.cpp diff --git a/QRCodeLibrary/BitArray.cpp b/QRCodeLibrary/BitArray.cpp new file mode 100644 index 0000000..35f9bce --- /dev/null +++ b/QRCodeLibrary/BitArray.cpp @@ -0,0 +1,37 @@ +#include "pch.h" +#include "BitArray.hpp" + +bool BitArray::get(unsigned index) +{ + return (v[index / 8] >> (8 - 1 - index % 8)) & 1; +} + +void BitArray::set(unsigned index, bool val) +{ + if (val) + v[index / 8] |= 1 << (8 - 1 - index % 8); + else + v[index / 8] &= ~(1 << (8 - 1 - index % 8)); +} + +unsigned BitArray::set(unsigned index, int32_t val, unsigned size) +{ + unsigned shift = index % 8, written = 0; + size = std::min(size, this->size - index); + index /= 8; + + while (written < size) { + int input_shift = size - (8 - shift) - written; + int right_rem = input_shift < 0 ? -input_shift : 0; + + v[index] = ((v[index] >> (8 - shift)) << (8 - shift)) | + (unsigned char)(((1 << (8 - shift)) - 1) & ((input_shift >= 0) ? (val >> input_shift) : (val << -input_shift))) | + (v[index] & ((1 << right_rem) - 1)); + + written += 8 - shift; + index++; + shift = 0; + } + + return written; +} diff --git a/QRCodeLibrary/BitArray.hpp b/QRCodeLibrary/BitArray.hpp new file mode 100644 index 0000000..5a45ec1 --- /dev/null +++ b/QRCodeLibrary/BitArray.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include + +using namespace std; + +constexpr unsigned ceil_div(unsigned a, unsigned b) { + return a / b + (a % b > 0); +} + +class BitArray +{ +public: + BitArray(unsigned size_ = 0) : size{ size_ }, v(ceil_div(size_, 8)) {}; + + unsigned size; + vector v; + + bool get(unsigned index); + void set(unsigned index, bool val); + unsigned set(unsigned index, int32_t val, unsigned size); +}; + diff --git a/QRCodeLibrary/QRCodeLibrary.vcxproj b/QRCodeLibrary/QRCodeLibrary.vcxproj index 708b399..de4fc7f 100644 --- a/QRCodeLibrary/QRCodeLibrary.vcxproj +++ b/QRCodeLibrary/QRCodeLibrary.vcxproj @@ -151,6 +151,7 @@ + @@ -159,6 +160,7 @@ + diff --git a/QRCodeLibrary/QRCodeLibrary.vcxproj.filters b/QRCodeLibrary/QRCodeLibrary.vcxproj.filters index 7113336..61415b4 100644 --- a/QRCodeLibrary/QRCodeLibrary.vcxproj.filters +++ b/QRCodeLibrary/QRCodeLibrary.vcxproj.filters @@ -33,6 +33,9 @@ Header Files + + Header Files + @@ -50,5 +53,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/tests/BitArray_test.cpp b/tests/BitArray_test.cpp new file mode 100644 index 0000000..2ee35d3 --- /dev/null +++ b/tests/BitArray_test.cpp @@ -0,0 +1,40 @@ +#include "pch.h" + +#define protected public +#define private public + +#include "../QRCodeLibrary/BitArray.hpp" + +class BitArrayTests: public ::testing::Test { +public: + BitArrayTests() : ::testing::Test(), a1(15) {}; + + void SetUp() override { + a1.v[0] = static_cast(0b10101010); + a1.v[1] = static_cast(0b11111111); + } + +protected: + BitArray a1; +}; + +TEST_F(BitArrayTests, GetsBitByIndex) { + EXPECT_EQ(a1.get(10), 1); + EXPECT_EQ(a1.get(0), 1); + EXPECT_EQ(a1.get(1), 0); +} + +TEST_F(BitArrayTests, SetsIndividualBit) { + a1.set(0, 0); + a1.set(1, 1); + EXPECT_EQ(a1.get(0), 0); + EXPECT_EQ(a1.get(1), 1); +} + +TEST_F(BitArrayTests, SetsMultipleBits) { + a1.set(9, 0b00110, 5); + EXPECT_EQ(a1.v[1], 0b10011011); + + a1.set(2, 0b111, 3); + EXPECT_EQ(a1.v[0], 0b10111010); +} diff --git a/tests/tests.vcxproj b/tests/tests.vcxproj index ab443c2..4680b04 100644 --- a/tests/tests.vcxproj +++ b/tests/tests.vcxproj @@ -36,6 +36,7 @@ +