jaulib v1.3.8
Jau Support Library (C++, Java, ..)
Loading...
Searching...
No Matches
test_basictypeconv.cpp

This C++ unit test validates the jau::bswap and get/set value implementation.

This C++ unit test validates the jau::bswap and get/set value implementation

/*
* Author: Sven Gothel <sgothel@jausoft.com>
* Copyright (c) 2021 Gothel Software e.K.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <cassert>
#include <cinttypes>
#include <cstring>
#include <jau/test/catch2_ext.hpp>
extern "C" {
// to test jau::endian_t::native against BYTE_ORDER macro
#ifndef BYTE_ORDER
#include <endian.h>
#endif
}
static constexpr inline bool VERBOSE = false;
using namespace jau::int_literals;
/**
* Test private impl namespace
*/
namespace test_impl {
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;
}
}
/**
* Just demonstrating usage of our type-traits
* in a convenient API manner w/o requiring to add the dummy template type.
*/
constexpr bool isLittleEndian2() noexcept {
}
TEST_CASE( "Endianess Test 00", "[endian]" ) {
fprintf(stderr, "********************************************************************************\n");
fprintf(stderr, "is_builtin_bit_cast_available: %d\n", jau::has_builtin_bit_cast());
fprintf(stderr, "endian: %s\n", jau::to_string(jau::endian_t::native).c_str());
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
const bool is_little = jau::endian_t::little == jau::endian_t::native;
const bool is_big = jau::endian_t::big == jau::endian_t::native;
REQUIRE( cpp_is_little == is_little );
REQUIRE( cpp_is_little == jau::is_little_endian() );
REQUIRE( cpp_is_big == is_big );
REQUIRE( is_little == isLittleEndian2());
}
template<typename Value_type>
static void print(const Value_type a) {
const uint8_t * pa = reinterpret_cast<const uint8_t *>(&a);
for(std::size_t i=0; i<sizeof(Value_type); i++) {
fprintf(stderr, "a[%zu] 0x%X, ", i, pa[i]);
}
}
template<typename Value_type>
static bool compare_values(const Value_type a, const Value_type b) {
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>
static void test_byteorder(const Value_type v_cpu,
const Value_type v_le,
const Value_type v_be)
{
if( VERBOSE ) {
fprintf(stderr, "test_byteorder: sizeof %zu; platform littleEndian %d", sizeof(Value_type), jau::is_little_endian());
fprintf(stderr, "\ncpu: %s: ", jau::to_hexstring(v_cpu).c_str()); print(v_cpu);
fprintf(stderr, "\nle_: %s: ", jau::to_hexstring(v_le).c_str()); print(v_le);
fprintf(stderr, "\nbe_: %s: ", jau::to_hexstring(v_be).c_str()); print(v_be);
fprintf(stderr, "\n");
}
{
Value_type r1_le = jau::bswap(v_be);
REQUIRE( r1_le == v_le );
Value_type r1_be = jau::bswap(v_le);
REQUIRE( r1_be == v_be );
}
{
#if BYTE_ORDER == LITTLE_ENDIAN
REQUIRE( compare_values(v_le, v_cpu) == true );
Value_type r1_cpu = jau::bswap(v_be);
REQUIRE( r1_cpu == v_cpu );
#else
REQUIRE( compare(v_be, v_cpu) == true );
Value_type r1_cpu = jau::bswap(v_le);
REQUIRE( r1_cpu == v_cpu );
#endif
}
{
Value_type r1_cpu = jau::le_to_cpu(v_le);
Value_type r2_cpu = jau::be_to_cpu(v_be);
REQUIRE( r1_cpu == v_cpu );
REQUIRE( r2_cpu == v_cpu );
}
}
static uint16_t composeU16(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 int16_t composeI16(const uint8_t n1, const uint8_t n2) {
int16_t dest;
uint8_t * p_dest = reinterpret_cast<uint8_t*>(&dest);
p_dest[0] = n1;
p_dest[1] = n2;
return dest;
}
static uint32_t composeU32(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 int32_t composeI32(const uint8_t n1, const uint8_t n2, const uint8_t n3, const uint8_t n4) {
int32_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 composeU64(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;
}
static int64_t composeI64(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) {
int64_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>
static Value_type compose(const uint8_t lowest_value, const jau::lb_endian_t le_or_be) {
Value_type dest;
uint8_t * p_dest = reinterpret_cast<uint8_t*>(&dest);
uint8_t byte_value = lowest_value;
if( jau::is_little_endian( le_or_be ) ) {
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>
static Value_type compose(const uint8_t lowest_value, const jau::endian_t le_or_be) {
return compose<Value_type>(lowest_value, to_lb_endian( le_or_be ) );
}
TEST_CASE( "Integer Type Byte Order Test 01", "[byteorder][bswap]" ) {
{
constexpr uint16_t cpu = 0x3210U;
uint16_t le = composeU16(0x10, 0x32); // stream: 1032
uint16_t be = composeU16(0x32, 0x10); // stream: 3210
test_byteorder(cpu, le, be);
}
{
constexpr uint16_t cpu = 0xFEDCU;
uint16_t le = composeU16(0xDC, 0xFE); // stream: DCFE
uint16_t be = composeU16(0xFE, 0xDC); // stream: FEDC
test_byteorder(cpu, le, be);
}
{
constexpr int16_t cpu = 0x3210;
int16_t le = composeI16(0x10, 0x32); // stream: 1032
int16_t be = composeI16(0x32, 0x10); // stream: 3210
test_byteorder(cpu, le, be);
}
{
constexpr int16_t cpu = -292_i16; // int16_t(0xFEDC);
int16_t le = composeI16(0xDC, 0xFE); // stream: DCFE
int16_t be = composeI16(0xFE, 0xDC); // stream: FEDC
test_byteorder(cpu, le, be);
}
{
constexpr uint32_t cpu = 0x76543210U;
uint32_t le = composeU32(0x10, 0x32, 0x54, 0x76); // stream: 10325476
uint32_t be = composeU32(0x76, 0x54, 0x32, 0x10); // stream: 76543210
test_byteorder(cpu, le, be);
}
{
constexpr uint32_t cpu = 0xFEDCBA98U;
uint32_t le = composeU32(0x98, 0xBA, 0xDC, 0xFE); // stream: 98BADCFE
uint32_t be = composeU32(0xFE, 0xDC, 0xBA, 0x98); // stream: FEDCBA98
test_byteorder(cpu, le, be);
}
{
constexpr int32_t cpu = int32_t(0x76543210);
int32_t le = composeI32(0x10, 0x32, 0x54, 0x76); // stream: 10325476
int32_t be = composeI32(0x76, 0x54, 0x32, 0x10); // stream: 76543210
test_byteorder(cpu, le, be);
}
{
constexpr int32_t cpu = -19088744_i32; // int32_t(0xFEDCBA98U);
int32_t le = composeI32(0x98, 0xBA, 0xDC, 0xFE); // stream: 98BADCFE
int32_t be = composeI32(0xFE, 0xDC, 0xBA, 0x98); // stream: FEDCBA98
test_byteorder(cpu, le, be);
}
{
constexpr uint64_t cpu = 0xfedcba9876543210ULL;
uint64_t le = composeU64(0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe); // stream: 1032547698badcfe
uint64_t be = composeU64(0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10); // stream: fedcba9876543210
test_byteorder(cpu, le, be);
}
{
constexpr int64_t cpu = -81985529216486896_i64; // int64_t(0xfedcba9876543210ULL);
int64_t le = composeI64(0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe); // stream: 1032547698badcfe
int64_t be = composeI64(0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10); // stream: fedcba9876543210
test_byteorder(cpu, le, be);
}
{
test_byteorder(cpu, le, be);
}
{
test_byteorder(cpu, le, be);
}
{
test_byteorder(cpu, le, be);
}
}
template<typename Value_type>
static void test_value_cpu(const Value_type v1, const Value_type v2, const Value_type v3) {
uint8_t buffer[3 * sizeof(Value_type)];
jau::put_value(buffer + sizeof(Value_type)*0, v1);
jau::put_value(buffer + sizeof(Value_type)*1, v2);
jau::put_value(buffer + sizeof(Value_type)*2, v3);
const Value_type r1 = jau::get_value<Value_type>(buffer + sizeof(Value_type)*0);
const Value_type r2 = jau::get_value<Value_type>(buffer + sizeof(Value_type)*1);
const Value_type r3 = jau::get_value<Value_type>(buffer + sizeof(Value_type)*2);
REQUIRE( r1 == v1);
REQUIRE( r2 == v2);
REQUIRE( r3 == v3);
}
TEST_CASE( "Integer Get/Put in CPU Byte Order Test 02", "[byteorder][get][put]" ) {
{
constexpr uint8_t a = 0x01, b = 0x11, c = 0xff;
test_value_cpu(a, b, c);
}
{
constexpr uint16_t a = 0x0123, b = 0x1122, c = 0xffee;
test_value_cpu(a, b, c);
}
{
constexpr int16_t a = 0x0123, b = 0x1122, c = -18_i16; // (int16_t)0xffee;
test_value_cpu(a, b, c);
}
{
constexpr uint32_t a = 0x01234567U, b = 0x11223344U, c = 0xffeeddccU;
test_value_cpu(a, b, c);
}
{
constexpr int32_t a = 0x01234567, b = 0x11223344, c = -1122868_i32; // (int32_t)0xffeeddcc;
test_value_cpu(a, b, c);
}
{
constexpr uint64_t a = 0x0123456789abcdefULL, b = 0x1122334455667788ULL, c = 0xffeeddcc99887766ULL;
test_value_cpu(a, b, c);
}
{
constexpr int64_t a = 0x0123456789abcdefLL, b = 0x1122334455667788LL, c = -4822678761867418_i64; // (int64_t)0xffeeddcc99887766LL;
test_value_cpu(a, b, c);
}
{
test_value_cpu(a, b, c);
}
{
test_value_cpu(a, b, c);
}
{
test_value_cpu(a, b, c);
}
}
template<typename Value_type>
static void test_value_littlebig(const Value_type v_cpu, const Value_type v_le, const Value_type v_be) {
if( VERBOSE ) {
fprintf(stderr, "test_value_littlebig: sizeof %zu; platform littleEndian %d", sizeof(Value_type), jau::is_little_endian());
fprintf(stderr, "\ncpu: %s: ", jau::to_hexstring(v_cpu).c_str()); print(v_cpu);
fprintf(stderr, "\nle_: %s: ", jau::to_hexstring(v_le).c_str()); print(v_le);
fprintf(stderr, "\nbe_: %s: ", jau::to_hexstring(v_be).c_str()); print(v_be);
fprintf(stderr, "\n");
}
uint8_t buffer[2 * sizeof(Value_type)];
jau::put_value(buffer + sizeof(Value_type)*0, v_cpu, jau::lb_endian_t::little);
jau::put_value(buffer + sizeof(Value_type)*1, v_cpu, jau::lb_endian_t::big);
const Value_type rle_raw = jau::get_value<Value_type>(buffer + sizeof(Value_type)*0);
REQUIRE( rle_raw == v_le);
REQUIRE( rle_cpu == v_cpu);
const Value_type rbe_raw = jau::get_value<Value_type>(buffer + sizeof(Value_type)*1);
REQUIRE( rbe_raw == v_be);
REQUIRE( rbe_cpu == v_cpu);
}
TEST_CASE( "Integer Get/Put in explicit Byte Order Test 03", "[byteorder][get][put]" ) {
{
constexpr uint16_t cpu = 0x3210U;
uint16_t le = composeU16(0x10, 0x32); // stream: 1032
uint16_t be = composeU16(0x32, 0x10); // stream: 3210
}
{
constexpr uint16_t cpu = 0xFEDCU;
uint16_t le = composeU16(0xDC, 0xFE); // stream: DCFE
uint16_t be = composeU16(0xFE, 0xDC); // stream: FEDC
}
{
constexpr int16_t cpu = 0x3210;
int16_t le = composeI16(0x10, 0x32); // stream: 1032
int16_t be = composeI16(0x32, 0x10); // stream: 3210
}
{
constexpr int16_t cpu = -292_i16; // int16_t(0xFEDC);
int16_t le = composeI16(0xDC, 0xFE); // stream: DCFE
int16_t be = composeI16(0xFE, 0xDC); // stream: FEDC
}
{
constexpr uint32_t cpu = 0x76543210U;
uint32_t le = composeU32(0x10, 0x32, 0x54, 0x76); // stream: 10325476
uint32_t be = composeU32(0x76, 0x54, 0x32, 0x10); // stream: 76543210
}
{
constexpr uint32_t cpu = 0xFEDCBA98U;
uint32_t le = composeU32(0x98, 0xBA, 0xDC, 0xFE); // stream: 98BADCFE
uint32_t be = composeU32(0xFE, 0xDC, 0xBA, 0x98); // stream: FEDCBA98
}
{
constexpr int32_t cpu = int32_t(0x76543210);
int32_t le = composeI32(0x10, 0x32, 0x54, 0x76); // stream: 10325476
int32_t be = composeI32(0x76, 0x54, 0x32, 0x10); // stream: 76543210
}
{
constexpr int32_t cpu = -19088744_i32; // int32_t(0xFEDCBA98U);
int32_t le = composeI32(0x98, 0xBA, 0xDC, 0xFE); // stream: 98BADCFE
int32_t be = composeI32(0xFE, 0xDC, 0xBA, 0x98); // stream: FEDCBA98
}
{
constexpr uint64_t cpu = 0xfedcba9876543210ULL;
uint64_t le = composeU64(0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe); // stream: 1032547698badcfe
uint64_t be = composeU64(0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10); // stream: fedcba9876543210
}
{
constexpr int64_t cpu = -81985529216486896_i64; // int64_t(0xfedcba9876543210ULL);
int64_t le = composeI64(0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe); // stream: 1032547698badcfe
int64_t be = composeI64(0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10); // stream: fedcba9876543210
}
{
}
{
}
{
}
}
TEST_CASE( "HexString from and to byte vector conversion - Test 04", "[hexstring]" ) {
{
std::cout << "Little Endian Representation: " << std::endl;
const std::vector<uint8_t> lalaSink1 = { 0x1a, 0x1b, 0x2a, 0x2b, 0xff };
const uint64_t v0_be = 0x000000ff2b2a1b1aU;
const uint64_t v0_le = 0x0000001a1b2a2bffU;
const std::string value_s0 = "1a1b2a2bff"; // LE
const std::string value_s1 = jau::bytesHexString(lalaSink1.data(), lalaSink1.size(), true /* lsbFirst */);
const uint64_t v1_le = jau::from_hexstring(value_s1, !jau::is_little_endian() /* lsbFirst */); // LE -> LE on native
const uint64_t v1_be = jau::from_hexstring(value_s1, jau::is_little_endian() /* lsbFirst */); // LE -> BE on native
std::vector<uint8_t> lalaSink2;
jau::hexStringBytes(lalaSink2, value_s1, true /* lsbFirst */, false);
const std::string value_s2 = jau::bytesHexString(lalaSink2.data(), lalaSink2.size(), true /* lsbFirst */);
const uint64_t v2_le = jau::from_hexstring(value_s2, !jau::is_little_endian() /* lsbFirst */); // LE -> LE on native
const uint64_t v2_be = jau::from_hexstring(value_s2, jau::is_little_endian() /* lsbFirst */); // LE -> BE on native
REQUIRE( value_s0 == value_s1 );
REQUIRE( value_s0 == value_s2 );
std::cout << "v0_le " << value_s1 << " (2) " << value_s2 << std::endl;
{
std::string v0_be_s = jau::to_hexstring(v0_be);
std::cout << "v0_be_s " << v0_be_s << std::endl;
std::string v1_be_s = jau::to_hexstring(v1_be);
std::string v2_be_s = jau::to_hexstring(v2_be);
std::cout << "v1_be_s " << v1_be_s << std::endl;
std::cout << "v2_be_s " << v2_be_s << std::endl;
std::string v0_le_s = jau::to_hexstring(v0_le);
std::cout << "v0_le_s " << v0_le_s << std::endl;
std::string v1_le_s = jau::to_hexstring(v1_le);
std::string v2_le_s = jau::to_hexstring(v2_le);
std::cout << "v1_le_s " << v1_le_s << std::endl;
std::cout << "v2_le_s " << v2_le_s << std::endl;
}
REQUIRE( v0_le == v1_le );
REQUIRE( v0_le == v2_le );
REQUIRE( v0_be == v1_be );
REQUIRE( v0_be == v2_be );
REQUIRE(lalaSink1 == lalaSink2);
std::cout << std::endl;
}
{
std::cout << "Big Endian Representation: " << std::endl;
const std::vector<uint8_t> lalaSink1 = { 0x1a, 0x1b, 0x2a, 0x2b, 0xff };
const uint64_t v0_be = 0x000000ff2b2a1b1aU;
const uint64_t v0_le = 0x0000001a1b2a2bffU;
const std::string value_s0 = "0xff2b2a1b1a";
const std::string value_s1 = jau::bytesHexString(lalaSink1.data(), lalaSink1.size(), false /* lsbFirst */);
const uint64_t v1_le = jau::from_hexstring(value_s1, jau::is_little_endian() /* lsbFirst */); // BE -> LE on native
const uint64_t v1_be = jau::from_hexstring(value_s1, !jau::is_little_endian() /* lsbFirst */); // BE -> BE on native
std::vector<uint8_t> lalaSink2;
jau::hexStringBytes(lalaSink2, value_s1, false /* lsbFirst */, true);
const std::string value_s2 = jau::bytesHexString(lalaSink2.data(), lalaSink2.size(), false /* lsbFirst */);
const uint64_t v2_le = jau::from_hexstring(value_s2, jau::is_little_endian() /* lsbFirst */); // BE -> LE on native
const uint64_t v2_be = jau::from_hexstring(value_s2, !jau::is_little_endian() /* lsbFirst */); // BE -> BE on native
REQUIRE( value_s0 == value_s1 );
REQUIRE( value_s0 == value_s2 );
std::cout << "v0_be " << value_s1 << " (2) " << value_s2 << std::endl;
{
std::string v0_be_s = jau::to_hexstring(v0_be);
std::cout << "v0_be_s " << v0_be_s << std::endl;
std::string v1_be_s = jau::to_hexstring(v1_be);
std::string v2_be_s = jau::to_hexstring(v2_be);
std::cout << "v1_be_s " << v1_be_s << std::endl;
std::cout << "v2_be_s " << v2_be_s << std::endl;
std::string v0_le_s = jau::to_hexstring(v0_le);
std::cout << "v0_le_s " << v0_le_s << std::endl;
std::string v1_le_s = jau::to_hexstring(v1_le);
std::string v2_le_s = jau::to_hexstring(v2_le);
std::cout << "v1_le_s " << v1_le_s << std::endl;
std::cout << "v2_le_s " << v2_le_s << std::endl;
}
REQUIRE( v0_le == v1_le );
REQUIRE( v0_le == v2_le );
REQUIRE( v0_be == v1_be );
REQUIRE( v0_be == v2_be );
REQUIRE(lalaSink1 == lalaSink2);
std::cout << std::endl;
}
{
// even digits
std::cout << "Even digits (1): " << std::endl;
const std::vector<uint8_t> v0_b = { 0x1a, 0x1b, 0x2a, 0x2b, 0xff };
const uint64_t v0 = 0xff2b2a1b1aU;
const std::string v0_s_msb = "0xff2b2a1b1a";
const std::string v0_s_lsb = "1a1b2a2bff";
std::cout << "v0 " << jau::to_hexstring(v0) << std::endl;
std::cout << "v0_b " << jau::to_string(v0_b) << std::endl;
std::cout << "v0_s (msb) " << v0_s_msb << std::endl;
std::cout << "v0_s (lsb) " << v0_s_lsb << std::endl;
std::vector<uint8_t> v1_b_msb_str;
std::vector<uint8_t> v1_b_lsb_str;
jau::hexStringBytes(v1_b_msb_str, v0_s_msb, false /* lsbFirst */, true);
jau::hexStringBytes(v1_b_lsb_str, v0_s_lsb, true /* lsbFirst */, true);
const std::string v1_bs_msb_str = jau::bytesHexString(v1_b_msb_str, false /* lsbFirst */);
const std::string v1_bs_lsb_str = jau::bytesHexString(v1_b_lsb_str, false /* lsbFirst */);
std::cout << "v1_b (msb str) " << jau::to_string(v1_b_msb_str) << std::endl;
std::cout << "v1_bs (msb str) " << v1_bs_msb_str << std::endl;
std::cout << "v1_b (lsb str) " << jau::to_string(v1_b_lsb_str) << std::endl;
std::cout << "v1_bs (lsb str) " << v1_bs_lsb_str << std::endl;
const uint64_t v1_msb_str = jau::from_hexstring(v0_s_msb, false);
const uint64_t v1_lsb_str = jau::from_hexstring(v0_s_lsb, true);
std::cout << "v1 (msb) " << jau::to_hexstring(v1_msb_str) << std::endl;
std::cout << "v1 (lsb) " << jau::to_hexstring(v1_lsb_str) << std::endl;
REQUIRE( v0 == v1_msb_str );
REQUIRE( v0 == v1_lsb_str );
REQUIRE( v0_b == v1_b_msb_str );
REQUIRE( v0_b == v1_b_lsb_str );
std::cout << std::endl;
}
{
// odd digits
std::cout << "Odd digits (1): " << std::endl;
const std::vector<uint8_t> v0_b_msb = { 0x1a, 0x1b, 0x2a, 0x2b, 0x0f };
const std::vector<uint8_t> v0_b_lsb = { 0x1a, 0x1b, 0x2a, 0x2b, 0xf0 };
const uint64_t v0_msb = 0x0f2b2a1b1aU;
const uint64_t v0_lsb = 0xf02b2a1b1aU;
const std::string v0_s_msb = "0xf2b2a1b1a";
const std::string v0_s_lsb = "1a1b2a2bf";
std::cout << "v0 (msb) " << jau::to_hexstring(v0_msb) << std::endl;
std::cout << "v0_b (msb) " << jau::to_string(v0_b_msb) << std::endl;
std::cout << "v0_s (msb) " << v0_s_msb << std::endl;
std::cout << "v0 (lsb) " << jau::to_hexstring(v0_lsb) << std::endl;
std::cout << "v0_b (lsb) " << jau::to_string(v0_b_lsb) << std::endl;
std::cout << "v0_s (lsb) " << v0_s_lsb << std::endl;
std::vector<uint8_t> v1_b_msb_str;
std::vector<uint8_t> v1_b_lsb_str;
jau::hexStringBytes(v1_b_msb_str, v0_s_msb, false /* lsbFirst */, true);
jau::hexStringBytes(v1_b_lsb_str, v0_s_lsb, true /* lsbFirst */, true);
const std::string v1_bs_msb_str = jau::bytesHexString(v1_b_msb_str, false /* lsbFirst */);
const std::string v1_bs_lsb_str = jau::bytesHexString(v1_b_lsb_str, false /* lsbFirst */);
std::cout << "v1_b (msb str) " << jau::to_string(v1_b_msb_str) << std::endl;
std::cout << "v1_bs (msb str) " << v1_bs_msb_str << std::endl;
std::cout << "v1_b (lsb str) " << jau::to_string(v1_b_lsb_str) << std::endl;
std::cout << "v1_bs (lsb str) " << v1_bs_lsb_str << std::endl;
const uint64_t v1_msb_str = jau::from_hexstring(v0_s_msb, false);
const uint64_t v1_lsb_str = jau::from_hexstring(v0_s_lsb, true);
std::cout << "v1 (msb) " << jau::to_hexstring(v1_msb_str) << std::endl;
std::cout << "v1 (lsb) " << jau::to_hexstring(v1_lsb_str) << std::endl;
REQUIRE( v0_msb == v1_msb_str );
REQUIRE( v0_lsb == v1_lsb_str );
REQUIRE( v0_b_msb == v1_b_msb_str );
REQUIRE( v0_b_lsb == v1_b_lsb_str );
std::cout << std::endl;
}
{
std::cout << "Even digits (2): " << std::endl;
const uint64_t v0 = 0x000000ff2b2a1b1aU;
std::string v0_s = jau::to_hexstring(v0);
const uint64_t v0_2 = jau::from_hexstring(v0_s);
std::cout << "v0_s " << v0_s << std::endl;
std::cout << "v0_2 " << jau::to_hexstring(v0_2) << std::endl;
REQUIRE( v0 == v0_2 );
std::cout << std::endl;
}
{
std::cout << "Even digits (3): " << std::endl;
std::string v0_0s1 = "0xff2b2a1b1a";
const uint64_t v0_0 = 0xff2b2a1b1aU;
std::string v0_0s2 = jau::to_hexstring(v0_0);
const uint64_t i0_0s1 = jau::from_hexstring(v0_0s1);
const uint64_t i0_0s2 = jau::from_hexstring(v0_0s2);
std::cout << "v0_0s " << v0_0s1 << std::endl;
std::cout << "v0_0s2 " << v0_0s2 << std::endl;
std::cout << "i0_0s1 " << jau::to_hexstring(i0_0s1) << std::endl;
std::cout << "i0_0s2 " << jau::to_hexstring(i0_0s2) << std::endl;
REQUIRE( v0_0 == i0_0s1 );
REQUIRE( v0_0 == i0_0s2 );
std::cout << std::endl;
}
{
std::cout << "Odd digits (3): " << std::endl;
std::string v0_0s1 = "0xf2b2a1b1a";
const uint64_t v0_0 = 0xf2b2a1b1aU;
std::string v0_0s2 = jau::to_hexstring(v0_0);
const uint64_t i0_0s1 = jau::from_hexstring(v0_0s1);
const uint64_t i0_0s2 = jau::from_hexstring(v0_0s2);
std::cout << "v0_0s " << v0_0s1 << std::endl;
std::cout << "v0_0s2 " << v0_0s2 << std::endl;
std::cout << "i0_0s1 " << jau::to_hexstring(i0_0s1) << std::endl;
std::cout << "i0_0s2 " << jau::to_hexstring(i0_0s2) << std::endl;
REQUIRE( v0_0 == i0_0s1 );
REQUIRE( v0_0 == i0_0s2 );
std::cout << std::endl;
}
}
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 );
REQUIRE( 3_inz == (jau::snsize_t)3 );
REQUIRE( 3_unz == (jau::nsize_t)3 );
}
constexpr bool is_little_endian() noexcept
Evaluates true if platform is running in little endian mode, i.e.
constexpr std::enable_if_t< std::is_standard_layout_v< T >, T > get_value(uint8_t const *buffer) noexcept
Returns a T value from the given byte address using packed_t to resolve a potential memory alignment ...
constexpr uint16_t bswap(uint16_t const source) noexcept
Definition byte_util.hpp:86
endian_t
Endian identifier, indicating endianess of all scalar types.
constexpr bool has_endian_little_v
Value access of little-endian type trait for convenience .
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 has_builtin_bit_cast() noexcept
Query whether __builtin_bit_cast(Dest_type, arg) is available via __has_builtin(__builtin_bit_cast).
constexpr int compare(const T a, const T b) noexcept
Returns -1, 0 or 1 if a is less, equal or greater than b, disregarding epsilon but considering NaN,...
uint_fast32_t nsize_t
Natural 'size_t' alternative using uint_fast32_t as its natural sized type.
Definition int_types.hpp:55
int_fast32_t snsize_t
Natural 'ssize_t' alternative using int_fast32_t as its natural sized type.
Definition int_types.hpp:67
std::string to_hexstring(value_type const &v, const bool skipLeading0x=false) noexcept
Produce a lower-case hexadecimal string representation with leading 0x in MSB of the given pointer.
uint64_t from_hexstring(std::string const &s, const bool lsbFirst=!jau::is_little_endian(), const bool checkLeading0x=true) noexcept
Converts a given hexadecimal string representation into a uint64_t value according to hexStringBytes(...
std::string bytesHexString(const void *data, const nsize_t length, const bool lsbFirst, const bool lowerCase=true, const bool skipLeading0x=false) 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.
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 int16_t composeI16(const uint8_t n1, const uint8_t n2)
static int64_t composeI64(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)
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 uint16_t composeU16(const uint8_t n1, const uint8_t n2)
static int32_t composeI32(const uint8_t n1, const uint8_t n2, const uint8_t n3, const uint8_t n4)
static uint32_t composeU32(const uint8_t n1, const uint8_t n2, const uint8_t n3, const uint8_t n4)
static constexpr bool VERBOSE
static void print(const Value_type a)
static Value_type compose(const uint8_t lowest_value, const jau::lb_endian_t le_or_be)
static uint64_t composeU64(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)
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...
uint8_t Value_type