#include <cassert>
#include <cinttypes>
#include <cstring>
extern "C" {
#ifndef BYTE_ORDER
#include <endian.h>
#endif
}
static constexpr inline bool VERBOSE =
false;
template<class Dummy_type>
constexpr bool isLittleEndian2_impl(std::enable_if_t<jau::has_endian_little_v<Dummy_type>,
bool> =
true) noexcept {
return true;
}
template<class Dummy_type>
constexpr bool isLittleEndian2_impl(std::enable_if_t<!jau::has_endian_little_v<Dummy_type>,
bool> =
true) noexcept {
return false;
}
}
return test_impl::isLittleEndian2_impl<bool>();
}
TEST_CASE(
"Endianess Test 00",
"[endian]" ) {
fprintf(stderr, "********************************************************************************\n");
fprintf(stderr, "********************************************************************************\n");
const bool cpp_is_little =
#if BYTE_ORDER == LITTLE_ENDIAN
true;
#else
false;
#endif
const bool cpp_is_big =
#if BYTE_ORDER == BIG_ENDIAN
true;
#else
false;
#endif
REQUIRE( cpp_is_little == is_little );
REQUIRE( cpp_is_big == is_big );
}
template<typename Value_type>
const uint8_t * pa = reinterpret_cast<const uint8_t *>(&a);
fprintf(stderr, "a[%zu] 0x%X, ", i, pa[i]);
}
}
template<typename Value_type>
const uint8_t * pa = reinterpret_cast<const uint8_t *>(&a);
const uint8_t * pb = reinterpret_cast<const uint8_t *>(&b);
bool res = true;
for(std::size_t i=0; i<
sizeof(
Value_type) && res; i++) {
res = pa[i] == pb[i];
if( !res ) {
fprintf(stderr, "pa[%zu] 0x%X != pb[%zu] 0x%X\n", i, pa[i], i, pb[i]);
}
}
return res;
}
template<typename Value_type>
{
fprintf(stderr, "\n");
}
{
REQUIRE( r1_le == v_le );
REQUIRE( r1_be == v_be );
}
{
#if BYTE_ORDER == LITTLE_ENDIAN
REQUIRE( r1_cpu == v_cpu );
#else
REQUIRE(
compare(v_be, v_cpu) ==
true );
REQUIRE( r1_cpu == v_cpu );
#endif
}
{
REQUIRE( r1_cpu == v_cpu );
REQUIRE( r2_cpu == v_cpu );
}
}
static uint16_t
compose(
const uint8_t n1,
const uint8_t n2) {
uint16_t dest;
uint8_t * p_dest = reinterpret_cast<uint8_t*>(&dest);
p_dest[0] = n1;
p_dest[1] = n2;
return dest;
}
static uint32_t
compose(
const uint8_t n1,
const uint8_t n2,
const uint8_t n3,
const uint8_t n4) {
uint32_t dest;
uint8_t * p_dest = reinterpret_cast<uint8_t*>(&dest);
p_dest[0] = n1;
p_dest[1] = n2;
p_dest[2] = n3;
p_dest[3] = n4;
return dest;
}
static uint64_t
compose(
const uint8_t n1,
const uint8_t n2,
const uint8_t n3,
const uint8_t n4,
const uint8_t n5, const uint8_t n6, const uint8_t n7, const uint8_t n8) {
uint64_t dest;
uint8_t * p_dest = reinterpret_cast<uint8_t*>(&dest);
p_dest[0] = n1;
p_dest[1] = n2;
p_dest[2] = n3;
p_dest[3] = n4;
p_dest[4] = n5;
p_dest[5] = n6;
p_dest[6] = n7;
p_dest[7] = n8;
return dest;
}
template<typename Value_type>
uint8_t * p_dest = reinterpret_cast<uint8_t*>(&dest);
uint8_t byte_value = lowest_value;
for(size_t i=0; i<sizeof(dest); i++, byte_value++) {
p_dest[i] = byte_value;
}
} else {
for(ssize_t i=sizeof(dest)-1; i>=0; i--, byte_value++) {
p_dest[i] = byte_value;
}
}
return dest;
}
template<typename Value_type>
return compose<Value_type>(lowest_value,
to_lb_endian( le_or_be ) );
}
TEST_CASE(
"Integer Type Byte Order Test 01",
"[byteorder][bswap]" ) {
{
uint16_t cpu = 0x3210U;
}
{
uint32_t cpu = 0x76543210U;
uint32_t le =
compose(0x10, 0x32, 0x54, 0x76);
uint32_t be =
compose(0x76, 0x54, 0x32, 0x10);
}
{
uint64_t cpu = 0xfedcba9876543210ULL;
uint64_t le =
compose(0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe);
uint64_t be =
compose(0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10);
}
{
}
{
}
{
}
}
template<typename Value_type>
REQUIRE( r1 == v1);
REQUIRE( r2 == v2);
REQUIRE( r3 == v3);
}
TEST_CASE(
"Integer Get/Put in CPU Byte Order Test 02",
"[byteorder][get][put]" ) {
{
uint8_t a = 0x01, b = 0x11, c = 0xff;
}
{
uint16_t a = 0x0123, b = 0x1122, c = 0xffee;
}
{
uint32_t a = 0x01234567U, b = 0x11223344U, c = 0xffeeddccU;
}
{
uint64_t a = 0x0123456789abcdefULL, b = 0x1122334455667788ULL, c = 0xffeeddcc99887766ULL;
}
{
}
{
}
{
}
}
template<typename Value_type>
fprintf(stderr, "\n");
}
REQUIRE( rle_raw == v_le);
REQUIRE( rle_cpu == v_cpu);
REQUIRE( rbe_raw == v_be);
REQUIRE( rbe_cpu == v_cpu);
}
TEST_CASE(
"Integer Get/Put in explicit Byte Order Test 03",
"[byteorder][get][put]" ) {
{
uint16_t cpu = 0x3210U;
}
{
uint32_t cpu = 0x76543210U;
uint32_t le =
compose(0x10, 0x32, 0x54, 0x76);
uint32_t be =
compose(0x76, 0x54, 0x32, 0x10);
}
{
uint64_t cpu = 0xfedcba9876543210ULL;
uint64_t le =
compose(0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe);
uint64_t be =
compose(0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10);
}
{
}
{
}
{
}
}
TEST_CASE(
"HexString from and to byte vector conversion - Test 04",
"[hexstring]" ) {
const std::vector<uint8_t> lalaSink1 = { 0x1a, 0x1b, 0x2a, 0x2b, 0xff };
{
const std::string value_s0 = "1a1b2a2bff";
const std::string value_s1 =
jau::bytesHexString(lalaSink1.data(), 0, lalaSink1.size(),
true );
std::vector<uint8_t> lalaSink2;
const std::string value_s2 =
jau::bytesHexString(lalaSink2.data(), 0, lalaSink2.size(),
true );
REQUIRE( value_s0 == value_s1 );
REQUIRE( value_s0 == value_s2 );
}
{
const std::string value_s0 = "0xff2b2a1b1a";
const std::string value_s1 =
jau::bytesHexString(lalaSink1.data(), 0, lalaSink1.size(),
false );
std::vector<uint8_t> lalaSink2;
const std::string value_s2 =
jau::bytesHexString(lalaSink2.data(), 0, lalaSink2.size(),
false );
REQUIRE( value_s0 == value_s1 );
REQUIRE( value_s0 == value_s2 );
}
}
TEST_CASE(
"Integer Type Test Test 05",
"[integer][type]" ) {
REQUIRE( 3_i8 == (int8_t)3 );
REQUIRE( 3_u8 == (uint8_t)3 );
REQUIRE( 3_i16 == (int16_t)3 );
REQUIRE( 3_u16 == (uint16_t)3 );
REQUIRE( 3_i32 == (int32_t)3 );
REQUIRE( 3_u32 == (uint32_t)3 );
REQUIRE( 3_i64 == (int64_t)3 );
REQUIRE( 3_u64 == (uint64_t)3 );
REQUIRE( 3_iz == (ssize_t)3 );
REQUIRE( 3_uz == (size_t)3 );
}
constexpr uint16_t bswap(uint16_t const source) noexcept
endian_t
Endian identifier, indicating endianess of all scalar types.
constexpr uint16_t le_to_cpu(uint16_t const l) noexcept
lb_endian_t
Simplified reduced endian type only covering little- and big-endian.
std::string to_string(const endian_t v) noexcept
Return std::string representation of the given endian.
constexpr bool is_little_endian(const endian_t byte_order) noexcept
Returns true if given byte_order equals endian::little, otherwise false.
constexpr uint16_t be_to_cpu(uint16_t const n) noexcept
constexpr std::enable_if_t< std::is_standard_layout_v< T >, void > put_value(uint8_t *buffer, const T &v) noexcept
Put the given T value into the given byte address using packed_t to resolve a potential memory alignm...
constexpr lb_endian_t to_lb_endian(const endian_t v) noexcept
@ native
Identifier for native platform type, one of the above.
@ little
Identifier for little endian.
@ big
Identifier for big endian.
@ little
Identifier for little endian, equivalent to endian::little.
@ big
Identifier for big endian, equivalent to endian::big.
consteval_cxx20 bool is_builtin_bit_cast_available() noexcept
Query whether __builtin_bit_cast(Dest_type, arg) is available, using jau::has_builtin_bit_cast.
bool compare(const file_stats &source1, const file_stats &source2, const bool verbose=false) noexcept
Compare the bytes of both files, denoted by source1 and source2.
uint_fast32_t nsize_t
Natural 'size_t' alternative using uint_fast32_t as its natural sized type.
int_fast32_t snsize_t
Natural 'ssize_t' alternative using int_fast32_t as its natural sized type.
std::string bytesHexString(const void *data, const nsize_t offset, const nsize_t length, const bool lsbFirst, const bool lowerCase=true) noexcept
Produce a hexadecimal string representation of the given byte values.
size_t hexStringBytes(std::vector< uint8_t > &out, const std::string &hexstr, const bool lsbFirst, const bool checkLeading0x) noexcept
Converts a given hexadecimal string representation into a byte vector.
std::string to_hexstring(value_type const &v) noexcept
Produce a lower-case hexadecimal string representation of the given pointer.
Test private impl namespace.
constexpr bool isLittleEndian2_impl(std::enable_if_t< jau::has_endian_little_v< Dummy_type >, bool >=true) noexcept
A 128-bit packed uint8_t data array.
A 196-bit packed uint8_t data array.
A 256-bit packed uint8_t data array.
static void test_value_littlebig(const Value_type v_cpu, const Value_type v_le, const Value_type v_be)
static bool compare_values(const Value_type a, const Value_type b)
static void test_byteorder(const Value_type v_cpu, const Value_type v_le, const Value_type v_be)
static void test_value_cpu(const Value_type v1, const Value_type v2, const Value_type v3)
static constexpr bool VERBOSE
static void print(const Value_type a)
TEST_CASE("Endianess Test 00", "[endian]")
constexpr bool isLittleEndian2() noexcept
Just demonstrating usage of our type-traits in a convenient API manner w/o requiring to add the dummy...
static uint16_t compose(const uint8_t n1, const uint8_t n2)