blob: 7d7798a4fa85eeb5b1972bd1f4b13dd889eb91ba [file] [log] [blame]
/*
*
* Copyright (c) 2022 Project CHIP Authors
*
* 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 <lib/support/BitMask.h>
#include <algorithm>
#include <cstring>
#include <initializer_list>
#include <pw_unit_test/framework.h>
#include <lib/core/StringBuilderAdapters.h>
using namespace chip;
namespace {
enum class TestEnum : uint16_t
{
kZero = 0x0000, // not a valid mask or bit flag, here anyway
kBit_0 = 0x0001,
kBits_1_2 = 0x0006,
kBits_4_7 = 0x00F0,
kBits_High4 = 0xF000,
kBits_High8 = 0xFF00,
};
TEST(TestBitMask, TestBitMaskOperations)
{
BitMask<TestEnum> mask;
EXPECT_EQ(mask.Raw(), 0);
mask.SetField(TestEnum::kBits_1_2, 2);
EXPECT_EQ(mask.Raw(), 0x0004);
mask.SetRaw(0);
mask.SetField(TestEnum::kBits_4_7, 0x0B);
EXPECT_EQ(mask.Raw(), 0x00B0);
mask.SetRaw(0);
for (uint16_t i = 0; i < 0x10; i++)
{
mask.SetField(TestEnum::kBits_High4, i);
EXPECT_EQ(mask.Raw(), (i << 12));
}
mask.SetField(TestEnum::kBits_High8, 0x23);
EXPECT_EQ(mask.Raw(), 0x2300);
mask.SetField(TestEnum::kBits_High4, 0xA);
EXPECT_EQ(mask.Raw(), 0xA300);
}
TEST(TestBitMask, TestBitFieldLogic)
{
BitMask<TestEnum> mask;
// some general logic that still applies for bit fields just in case
EXPECT_FALSE(mask.HasAny(TestEnum::kBits_High4));
EXPECT_FALSE(mask.HasAny(TestEnum::kBits_High8));
// setting something non-zero in the upper 4 bits sets "something" in both
// upper and 4 and 8 bits
mask.SetField(TestEnum::kBits_High4, 0x01);
EXPECT_TRUE(mask.HasAny(TestEnum::kBits_High4));
EXPECT_TRUE(mask.HasAny(TestEnum::kBits_High8));
// sets something visible in high 8 bits, but not high 4 bits
mask.SetField(TestEnum::kBits_High8, 0x01);
EXPECT_FALSE(mask.HasAny(TestEnum::kBits_High4));
EXPECT_TRUE(mask.HasAny(TestEnum::kBits_High8));
}
TEST(TestBitMask, TestBitMaskInvalid)
{
BitMask<TestEnum> mask;
// This generally tests for no infinite loops. Nothing to set here
mask.SetField(TestEnum::kZero, 0x01);
EXPECT_EQ(mask.Raw(), 0);
mask.SetRaw(0x1234);
mask.SetField(TestEnum::kZero, 0x01);
EXPECT_EQ(mask.Raw(), 0x1234);
}
TEST(TestBitMask, TestClear)
{
BitMask<TestEnum> mask1;
BitMask<TestEnum> mask2;
mask1.Set(TestEnum::kBit_0);
mask1.Set(TestEnum::kBits_1_2);
mask1.Set(TestEnum::kBits_High8);
mask2.Set(TestEnum::kBits_1_2);
mask1.Clear(mask2);
EXPECT_EQ(mask1.Raw(), 0xFF01);
}
} // namespace