blob: 1f2fc2a0465e8c7360634ee18bdbc2a19a4d659b [file] [log] [blame]
/*
* 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 <stdint.h>
#include <ese/bit_spec.h>
#include <gtest/gtest.h>
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));
}
}