From 532291e440944c1096d2878485166feb968eee77 Mon Sep 17 00:00:00 2001 From: khizmax Date: Wed, 5 Aug 2015 22:46:23 +0300 Subject: [PATCH] Small fixes in split_bitstring algo improving split_bitstring test --- cds/algo/split_bitstring.h | 4 +- tests/test-hdr/misc/split_bitstring.cpp | 138 ++++++++++++++++++++++-- 2 files changed, 134 insertions(+), 8 deletions(-) diff --git a/cds/algo/split_bitstring.h b/cds/algo/split_bitstring.h index 51590e2f..19c183fd 100644 --- a/cds/algo/split_bitstring.h +++ b/cds/algo/split_bitstring.h @@ -70,7 +70,7 @@ namespace cds { namespace algo { # endif uint_type result; - size_t const nRest = c_nBitPerInt - m_pos % c_nBitPerInt; + uint_type const nRest = c_nBitPerInt - m_pos % c_nBitPerInt; m_pos += nBits; if ( nBits < nRest ) { result = *m_ptr << ( nRest - nBits ); @@ -81,7 +81,7 @@ namespace cds { namespace algo { ++m_ptr; } else { - size_t const lsb = *m_ptr >> ( c_nBitPerInt - nRest ); + uint_type const lsb = *m_ptr >> ( c_nBitPerInt - nRest ); nBits -= nRest; ++m_ptr; diff --git a/tests/test-hdr/misc/split_bitstring.cpp b/tests/test-hdr/misc/split_bitstring.cpp index af304536..3597cd25 100644 --- a/tests/test-hdr/misc/split_bitstring.cpp +++ b/tests/test-hdr/misc/split_bitstring.cpp @@ -6,9 +6,8 @@ class Split_bitstrig : public CppUnitMini::TestCase { -protected: - - void cut_uint() +private: + bool is_big_endian() { union { uint32_t ui; @@ -16,11 +15,24 @@ protected: } byte_order; byte_order.ui = 0xFF000001; - if ( byte_order.ch == 0x01 ) - cut_uint_le(); - else + return byte_order.ch != 0x01; + } +protected: + + void cut_uint() + { + if ( is_big_endian() ) cut_uint_be(); + else + cut_uint_le(); + } + void cut_uint16() + { + if ( is_big_endian() ) + cut_small_be(); + else + cut_small_le(); } void cut_uint_le() @@ -171,8 +183,122 @@ protected: } } + +private: + template + void cut_small_le() + { + CPPUNIT_MSG("little-endian byte order"); + typedef PartUInt part_uint; + + typedef cds::algo::split_bitstring< uint64_t, part_uint > split_bitstring; + + uint64_t src = 0xFEDCBA9876543210; + split_bitstring splitter(src); + uint64_t res; + + // Cut each hex digit + splitter.reset(); + for ( size_t i = 0; i < sizeof(size_t) * 2; ++i ) { + CPPUNIT_ASSERT( !splitter.eos() ); + CPPUNIT_ASSERT( splitter ); + CPPUNIT_ASSERT( static_cast(splitter.cut( 4 )) == i ); + } + CPPUNIT_ASSERT( splitter.eos() ); + CPPUNIT_ASSERT( !splitter ); + + // by one bit + { + splitter.reset(); + res = 0; + for ( size_t i = 0; i < sizeof(size_t) * 8; ++i ) { + CPPUNIT_ASSERT( !splitter.eos() ); + CPPUNIT_ASSERT( splitter ); + res = res + ( static_cast(splitter.cut( 1 )) << i); + } + CPPUNIT_ASSERT( splitter.eos() ); + CPPUNIT_ASSERT( !splitter ); + CPPUNIT_ASSERT( res == src ); + } + + // random cut + { + for ( size_t k = 0; k < 100; ++k ) { + splitter.reset(); + res = 0; + size_t shift = 0; + while ( splitter ) { + CPPUNIT_ASSERT( !splitter.eos() ); + CPPUNIT_ASSERT( splitter ); + int bits = rand() % 16; + res = res + ( static_cast(splitter.safe_cut( bits )) << shift ); + shift += bits; + } + CPPUNIT_ASSERT( splitter.eos() ); + CPPUNIT_ASSERT( !splitter ); + CPPUNIT_ASSERT( res == src ); + } + } + } + + template + void cut_small_be() + { + CPPUNIT_MSG("big-endian byte order"); + typedef PartUInt part_uint; + + typedef cds::algo::split_bitstring< uint64_t, part_uint > split_bitstring; + + uint64_t src = 0xFEDCBA9876543210; + split_bitstring splitter(src); + uint64_t res; + + // Cut each hex digit + splitter.reset(); + for ( size_t i = 0; i < sizeof(size_t) * 2; ++i ) { + CPPUNIT_ASSERT( !splitter.eos() ); + CPPUNIT_ASSERT( splitter ); + CPPUNIT_ASSERT( splitter.cut( 4 ) == 0x0F - i ); + } + CPPUNIT_ASSERT( splitter.eos() ); + CPPUNIT_ASSERT( !splitter ); + + // by one bit + { + splitter.reset(); + res = 0; + for ( size_t i = 0; i < sizeof(size_t) * 8; ++i ) { + CPPUNIT_ASSERT( !splitter.eos() ); + CPPUNIT_ASSERT( splitter ); + res = (res << 1) + splitter.cut( 1 ); + } + CPPUNIT_ASSERT( splitter.eos() ); + CPPUNIT_ASSERT( !splitter ); + CPPUNIT_ASSERT( res == src ); + } + + // random cut + { + for ( size_t k = 0; k < 100; ++k ) { + splitter.reset(); + res = 0; + while ( splitter ) { + CPPUNIT_ASSERT( !splitter.eos() ); + CPPUNIT_ASSERT( splitter ); + int bits = rand() % 16; + res = (res << bits) + splitter.safe_cut( bits ); + } + CPPUNIT_ASSERT( splitter.eos() ); + CPPUNIT_ASSERT( !splitter ); + CPPUNIT_ASSERT( res == src ); + } + } + } + + CPPUNIT_TEST_SUITE(Split_bitstrig); CPPUNIT_TEST(cut_uint) + CPPUNIT_TEST(cut_uint16) CPPUNIT_TEST_SUITE_END(); }; -- 2.34.1