/* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include using ::testing::Test; struct TestSpec { struct { struct bit_spec bit[8]; } single; struct { struct bit_spec high; struct bit_spec mid; struct bit_spec low; } adjacent; struct { struct bit_spec all8; struct bit_spec upper6; struct bit_spec lower6; } overlap; }; const struct TestSpec kTestSpec = { .single = { .bit = { { .value = 1, .shift = 0 }, { .value = 1, .shift = 1 }, { .value = 1, .shift = 2 }, { .value = 1, .shift = 3 }, { .value = 1, .shift = 4 }, { .value = 1, .shift = 5 }, { .value = 1, .shift = 6 }, { .value = 1, .shift = 7 }, }, }, .adjacent = { .high = { .value = 0x3, .shift = 6 }, .mid = { .value = 0xf, .shift = 2 }, .low = { .value = 0x3, .shift = 0 }, }, .overlap = { .all8 = { .value = 0xff, .shift = 0 }, .upper6 = { .value = 0x3f, .shift = 2 }, .lower6 = { .value = 0x3f, .shift = 0 }, }, }; class BitSpecTest : public virtual Test { public: BitSpecTest() { } virtual ~BitSpecTest() { } virtual void SetUp() { } virtual void TearDown() { } }; TEST_F(BitSpecTest, single_bits_assign_accrue) { uint8_t byte = 0; uint8_t expected_byte = 0; // Accrue bits. for (int bit = 0; bit < 8; ++bit) { expected_byte |= (1 << bit); bs_assign(&byte, kTestSpec.single.bit[bit], 1); EXPECT_EQ(expected_byte, byte); EXPECT_EQ(1, bs_get(kTestSpec.single.bit[bit], expected_byte)); } } TEST_F(BitSpecTest, single_bits_assign1_individual) { // One bit at a time. for (int bit = 0; bit < 8; ++bit) { uint8_t expected_byte = (1 << bit); uint8_t byte = bs_set(0, kTestSpec.single.bit[bit], 1); EXPECT_EQ(expected_byte, byte); EXPECT_EQ(1, bs_get(kTestSpec.single.bit[bit], expected_byte)); } } TEST_F(BitSpecTest, single_bits_assign0_individual) { // One bit at a time. for (int bit = 0; bit < 8; ++bit) { uint8_t expected_byte = 0xff ^ (1 << bit); uint8_t byte = bs_set(0xff, kTestSpec.single.bit[bit], 0); EXPECT_EQ(expected_byte, byte); EXPECT_EQ(0, bs_get(kTestSpec.single.bit[bit], expected_byte)); } } TEST_F(BitSpecTest, single_bits_clear_individual) { // One bit at a time. for (int bit = 0; bit < 8; ++bit) { uint8_t byte = 0xff; uint8_t expected_byte = 0xff ^ (1 << bit); byte &= bs_clear(kTestSpec.single.bit[bit]); EXPECT_EQ(expected_byte, byte); EXPECT_EQ(0, bs_get(kTestSpec.single.bit[bit], expected_byte)); } } TEST_F(BitSpecTest, adjacent_bit_assign) { uint8_t byte = 0; EXPECT_EQ(0, bs_get(kTestSpec.adjacent.high, byte)); EXPECT_EQ(0, bs_get(kTestSpec.adjacent.mid, byte)); EXPECT_EQ(0, bs_get(kTestSpec.adjacent.low, byte)); byte = 0xff; EXPECT_EQ(0x3, bs_get(kTestSpec.adjacent.high, byte)); EXPECT_EQ(0xf, bs_get(kTestSpec.adjacent.mid, byte)); EXPECT_EQ(0x3, bs_get(kTestSpec.adjacent.low, byte)); for (int i = 0; i < 0xf; ++i) { bs_assign(&byte, kTestSpec.adjacent.mid, i); EXPECT_EQ(0x3, bs_get(kTestSpec.adjacent.high, byte)); EXPECT_EQ(i, bs_get(kTestSpec.adjacent.mid, byte)); EXPECT_EQ(0x3, bs_get(kTestSpec.adjacent.low, byte)); } byte = 0xff; for (int i = 0; i < 0x3; ++i) { bs_assign(&byte, kTestSpec.adjacent.low, i); bs_assign(&byte, kTestSpec.adjacent.high, i); EXPECT_EQ(i, bs_get(kTestSpec.adjacent.high, byte)); EXPECT_EQ(0xf, bs_get(kTestSpec.adjacent.mid, byte)); EXPECT_EQ(i, bs_get(kTestSpec.adjacent.low, byte)); } } TEST_F(BitSpecTest, overlap_bit_assign) { uint8_t byte = 0; EXPECT_EQ(0, bs_get(kTestSpec.overlap.upper6, byte)); EXPECT_EQ(0, bs_get(kTestSpec.overlap.lower6, byte)); EXPECT_EQ(0, bs_get(kTestSpec.overlap.all8, byte)); byte = 0xff; EXPECT_EQ(0x3f, bs_get(kTestSpec.overlap.upper6, byte)); EXPECT_EQ(0x3f, bs_get(kTestSpec.overlap.lower6, byte)); EXPECT_EQ(0xff, bs_get(kTestSpec.overlap.all8, byte)); byte = 0; for (int i = 0; i < 0x3f; ++i) { bs_assign(&byte, kTestSpec.overlap.lower6, i); EXPECT_EQ((i & (0x3f << 2)) >> 2, bs_get(kTestSpec.overlap.upper6, byte)); EXPECT_EQ(i, bs_get(kTestSpec.overlap.lower6, byte)); EXPECT_EQ(i, bs_get(kTestSpec.overlap.all8, byte)); } byte = 0; for (int i = 0; i < 0x3f; ++i) { bs_assign(&byte, kTestSpec.overlap.upper6, i); EXPECT_EQ(i, bs_get(kTestSpec.overlap.upper6, byte)); EXPECT_EQ((i << 2) & 0x3f, bs_get(kTestSpec.overlap.lower6, byte)); EXPECT_EQ(i << 2, bs_get(kTestSpec.overlap.all8, byte)); } byte = 0; for (int i = 0; i < 0xff; ++i) { bs_assign(&byte, kTestSpec.overlap.all8, i); EXPECT_EQ(i >> 2, bs_get(kTestSpec.overlap.upper6, byte)); EXPECT_EQ(i & 0x3f, bs_get(kTestSpec.overlap.lower6, byte)); EXPECT_EQ(i, bs_get(kTestSpec.overlap.all8, byte)); } }