2020-08-11 18:11:55 +00:00
|
|
|
/*
|
|
|
|
* This file Copyright (C) 2010-2014 Mnemosyne LLC
|
|
|
|
*
|
|
|
|
* It may be used under the GNU GPL versions 2 or 3
|
|
|
|
* or any future license endorsed by Mnemosyne LLC.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2021-10-17 15:34:36 +00:00
|
|
|
#include <array>
|
|
|
|
|
2020-08-11 18:11:55 +00:00
|
|
|
#include "transmission.h"
|
|
|
|
#include "crypto-utils.h"
|
|
|
|
#include "bitfield.h"
|
|
|
|
#include "utils.h" /* tr_free */
|
|
|
|
|
|
|
|
#include "gtest/gtest.h"
|
|
|
|
|
|
|
|
TEST(Bitfield, countRange)
|
|
|
|
{
|
|
|
|
auto constexpr IterCount = int{ 10000 };
|
|
|
|
|
|
|
|
for (auto i = 0; i < IterCount; ++i)
|
|
|
|
{
|
|
|
|
int const bit_count = 100 + tr_rand_int_weak(1000);
|
|
|
|
|
|
|
|
// generate a random bitfield
|
2021-10-11 17:29:14 +00:00
|
|
|
Bitfield bf(bit_count);
|
2020-08-11 18:11:55 +00:00
|
|
|
|
|
|
|
for (int j = 0, n = tr_rand_int_weak(bit_count); j < n; ++j)
|
|
|
|
{
|
2021-10-11 17:29:14 +00:00
|
|
|
bf.setBit(tr_rand_int_weak(bit_count));
|
2020-08-11 18:11:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int begin = tr_rand_int_weak(bit_count);
|
|
|
|
int end;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
end = tr_rand_int_weak(bit_count);
|
2021-08-15 09:41:48 +00:00
|
|
|
} while (end == begin);
|
2020-08-11 18:11:55 +00:00
|
|
|
|
|
|
|
// ensure end <= begin
|
|
|
|
if (end < begin)
|
|
|
|
{
|
|
|
|
int const tmp = begin;
|
|
|
|
begin = end;
|
|
|
|
end = tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
// test the bitfield
|
|
|
|
unsigned long count1 = {};
|
|
|
|
for (auto j = begin; j < end; ++j)
|
|
|
|
{
|
2021-10-11 17:29:14 +00:00
|
|
|
if (bf.readBit(j))
|
2020-08-11 18:11:55 +00:00
|
|
|
{
|
|
|
|
++count1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-11 17:29:14 +00:00
|
|
|
auto const count2 = bf.countRange(begin, end);
|
2020-08-11 18:11:55 +00:00
|
|
|
EXPECT_EQ(count1, count2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-17 15:34:36 +00:00
|
|
|
TEST(Bitfield, ctorFromFlagArray)
|
|
|
|
{
|
|
|
|
auto constexpr Tests = std::array<std::array<bool, 10>, 3>{ {
|
|
|
|
{ false, true, false, true, false, false, true, false, false, true }, // mixed
|
|
|
|
{ true, true, true, true, true, true, true, true, true, true }, // have all
|
|
|
|
{ false, false, false, false, false, false, false, false, false, false }, // have none
|
|
|
|
} };
|
|
|
|
|
|
|
|
for (auto const& flags : Tests)
|
|
|
|
{
|
|
|
|
size_t const true_count = std::count(std::begin(flags), std::end(flags), true);
|
|
|
|
size_t const n = std::size(flags);
|
|
|
|
bool const have_all = true_count == n;
|
|
|
|
bool const have_none = true_count == 0;
|
|
|
|
|
|
|
|
auto const bf = Bitfield(std::data(flags), std::size(flags));
|
|
|
|
|
|
|
|
EXPECT_EQ(n, bf.getBitCount());
|
|
|
|
EXPECT_EQ(have_all, bf.hasAll());
|
|
|
|
EXPECT_EQ(have_none, bf.hasNone());
|
|
|
|
EXPECT_EQ(true_count, bf.countBits());
|
|
|
|
|
|
|
|
for (size_t i = 0; i < std::size(flags); ++i)
|
|
|
|
{
|
|
|
|
EXPECT_EQ(flags[i], bf.readBit(i));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(Bitfield, bitfields)
|
2020-08-11 18:11:55 +00:00
|
|
|
{
|
|
|
|
unsigned int bitcount = 500;
|
2021-10-11 17:29:14 +00:00
|
|
|
Bitfield field(bitcount);
|
2020-08-11 18:11:55 +00:00
|
|
|
|
2021-10-11 17:29:14 +00:00
|
|
|
/* test Bitfield::setBit */
|
2020-08-11 18:11:55 +00:00
|
|
|
for (unsigned int i = 0; i < bitcount; i++)
|
|
|
|
{
|
|
|
|
if (i % 7 == 0)
|
|
|
|
{
|
2021-10-11 17:29:14 +00:00
|
|
|
field.setBit(i);
|
2020-08-11 18:11:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (unsigned int i = 0; i < bitcount; i++)
|
|
|
|
{
|
2021-10-11 17:29:14 +00:00
|
|
|
EXPECT_EQ(field.readBit(i), (i % 7 == 0));
|
2020-08-11 18:11:55 +00:00
|
|
|
}
|
|
|
|
|
2021-10-11 17:29:14 +00:00
|
|
|
/* test Bitfield::setBitRange */
|
|
|
|
field.setBitRange(0, bitcount);
|
2020-08-11 18:11:55 +00:00
|
|
|
|
|
|
|
for (unsigned int i = 0; i < bitcount; i++)
|
|
|
|
{
|
2021-10-11 17:29:14 +00:00
|
|
|
EXPECT_TRUE(field.readBit(i));
|
2020-08-11 18:11:55 +00:00
|
|
|
}
|
|
|
|
|
2021-10-11 17:29:14 +00:00
|
|
|
/* test Bitfield::clearBit */
|
2020-08-11 18:11:55 +00:00
|
|
|
for (unsigned int i = 0; i < bitcount; i++)
|
|
|
|
{
|
|
|
|
if (i % 7 != 0)
|
|
|
|
{
|
2021-10-11 17:29:14 +00:00
|
|
|
field.clearBit(i);
|
2020-08-11 18:11:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (unsigned int i = 0; i < bitcount; i++)
|
|
|
|
{
|
2021-10-11 17:29:14 +00:00
|
|
|
EXPECT_EQ(field.readBit(i), (i % 7 == 0));
|
2020-08-11 18:11:55 +00:00
|
|
|
}
|
|
|
|
|
2021-10-11 17:29:14 +00:00
|
|
|
/* test Bitfield::clearBitRange in the middle of a boundary */
|
|
|
|
field.setBitRange(0, 64);
|
|
|
|
field.clearBitRange(4, 21);
|
2020-08-11 18:11:55 +00:00
|
|
|
|
|
|
|
for (unsigned int i = 0; i < 64; i++)
|
|
|
|
{
|
2021-10-11 17:29:14 +00:00
|
|
|
EXPECT_EQ(field.readBit(i), (i < 4 || i >= 21));
|
2020-08-11 18:11:55 +00:00
|
|
|
}
|
|
|
|
|
2021-10-11 17:29:14 +00:00
|
|
|
/* test Bitfield::clearBitRange on the boundaries */
|
|
|
|
field.setBitRange(0, 64);
|
|
|
|
field.clearBitRange(8, 24);
|
2020-08-11 18:11:55 +00:00
|
|
|
|
|
|
|
for (unsigned int i = 0; i < 64; i++)
|
|
|
|
{
|
2021-10-11 17:29:14 +00:00
|
|
|
EXPECT_EQ(field.readBit(i), (i < 8 || i >= 24));
|
2020-08-11 18:11:55 +00:00
|
|
|
}
|
|
|
|
|
2021-10-11 17:29:14 +00:00
|
|
|
/* test Bitfield::clearBitRange when begin & end is on the same word */
|
|
|
|
field.setBitRange(0, 64);
|
|
|
|
field.clearBitRange(4, 5);
|
2020-08-11 18:11:55 +00:00
|
|
|
|
|
|
|
for (unsigned int i = 0; i < 64; i++)
|
|
|
|
{
|
2021-10-11 17:29:14 +00:00
|
|
|
EXPECT_EQ(field.readBit(i), (i < 4 || i >= 5));
|
2020-08-11 18:11:55 +00:00
|
|
|
}
|
|
|
|
|
2021-10-11 17:29:14 +00:00
|
|
|
/* test Bitfield::setBitRange */
|
|
|
|
field.clearBitRange(0, 64);
|
|
|
|
field.setBitRange(4, 21);
|
2020-08-11 18:11:55 +00:00
|
|
|
|
|
|
|
for (unsigned int i = 0; i < 64; i++)
|
|
|
|
{
|
2021-10-11 17:29:14 +00:00
|
|
|
EXPECT_EQ(field.readBit(i), (4 <= i && i < 21));
|
2020-08-11 18:11:55 +00:00
|
|
|
}
|
|
|
|
|
2021-10-11 17:29:14 +00:00
|
|
|
/* test Bitfield::setBitRange on the boundaries */
|
|
|
|
field.clearBitRange(0, 64);
|
|
|
|
field.setBitRange(8, 24);
|
2020-08-11 18:11:55 +00:00
|
|
|
|
|
|
|
for (unsigned int i = 0; i < 64; i++)
|
|
|
|
{
|
2021-10-11 17:29:14 +00:00
|
|
|
EXPECT_EQ(field.readBit(i), (8 <= i && i < 24));
|
2020-08-11 18:11:55 +00:00
|
|
|
}
|
|
|
|
|
2021-10-11 17:29:14 +00:00
|
|
|
/* test Bitfield::setBitRange when begin & end is on the same word */
|
|
|
|
field.clearBitRange(0, 64);
|
|
|
|
field.setBitRange(4, 5);
|
2020-08-11 18:11:55 +00:00
|
|
|
|
|
|
|
for (unsigned int i = 0; i < 64; i++)
|
|
|
|
{
|
2021-10-11 17:29:14 +00:00
|
|
|
EXPECT_EQ(field.readBit(i), (4 <= i && i < 5));
|
2020-08-11 18:11:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-17 15:34:36 +00:00
|
|
|
TEST(Bitfield, hasAllNone)
|
2020-08-11 18:11:55 +00:00
|
|
|
{
|
2021-10-11 17:29:14 +00:00
|
|
|
{
|
|
|
|
Bitfield field(3);
|
2020-08-11 18:11:55 +00:00
|
|
|
|
2021-10-11 17:29:14 +00:00
|
|
|
EXPECT_TRUE(!field.hasAll());
|
|
|
|
EXPECT_TRUE(field.hasNone());
|
2020-08-11 18:11:55 +00:00
|
|
|
|
2021-10-11 17:29:14 +00:00
|
|
|
field.setBit(0);
|
|
|
|
EXPECT_TRUE(!field.hasAll());
|
|
|
|
EXPECT_TRUE(!field.hasNone());
|
2020-08-11 18:11:55 +00:00
|
|
|
|
2021-10-11 17:29:14 +00:00
|
|
|
field.clearBit(0);
|
|
|
|
field.setBit(1);
|
|
|
|
EXPECT_TRUE(!field.hasAll());
|
|
|
|
EXPECT_TRUE(!field.hasNone());
|
2020-08-11 18:11:55 +00:00
|
|
|
|
2021-10-11 17:29:14 +00:00
|
|
|
field.clearBit(1);
|
|
|
|
field.setBit(2);
|
|
|
|
EXPECT_TRUE(!field.hasAll());
|
|
|
|
EXPECT_TRUE(!field.hasNone());
|
2020-08-11 18:11:55 +00:00
|
|
|
|
2021-10-11 17:29:14 +00:00
|
|
|
field.setBit(0);
|
|
|
|
field.setBit(1);
|
|
|
|
EXPECT_TRUE(field.hasAll());
|
|
|
|
EXPECT_TRUE(!field.hasNone());
|
2020-08-11 18:11:55 +00:00
|
|
|
|
2021-10-16 14:04:19 +00:00
|
|
|
field.setMode(Bitfield::OperationMode::None);
|
2021-10-11 17:29:14 +00:00
|
|
|
EXPECT_TRUE(!field.hasAll());
|
|
|
|
EXPECT_TRUE(field.hasNone());
|
2020-08-11 18:11:55 +00:00
|
|
|
|
2021-10-16 14:04:19 +00:00
|
|
|
field.setMode(Bitfield::OperationMode::All);
|
2021-10-11 17:29:14 +00:00
|
|
|
EXPECT_TRUE(field.hasAll());
|
|
|
|
EXPECT_TRUE(!field.hasNone());
|
|
|
|
}
|
2020-08-11 18:11:55 +00:00
|
|
|
|
2021-10-11 17:29:14 +00:00
|
|
|
{
|
|
|
|
Bitfield field(0);
|
2020-08-11 18:11:55 +00:00
|
|
|
|
2021-10-11 17:29:14 +00:00
|
|
|
EXPECT_TRUE(!field.hasAll());
|
|
|
|
EXPECT_TRUE(!field.hasNone());
|
2020-08-11 18:11:55 +00:00
|
|
|
|
2021-10-16 14:04:19 +00:00
|
|
|
field.setMode(Bitfield::OperationMode::None);
|
2021-10-11 17:29:14 +00:00
|
|
|
EXPECT_TRUE(!field.hasAll());
|
|
|
|
EXPECT_TRUE(field.hasNone());
|
2020-08-11 18:11:55 +00:00
|
|
|
|
2021-10-16 14:04:19 +00:00
|
|
|
field.setMode(Bitfield::OperationMode::All);
|
2021-10-11 17:29:14 +00:00
|
|
|
EXPECT_TRUE(field.hasAll());
|
|
|
|
EXPECT_TRUE(!field.hasNone());
|
|
|
|
}
|
2020-08-11 18:11:55 +00:00
|
|
|
}
|