From d1750c19ca08d7719c5c44f13b04520026e3d7cf Mon Sep 17 00:00:00 2001 From: Intel A80486DX2-66 Date: Tue, 25 Jun 2024 11:10:59 +0300 Subject: [PATCH] C: fwrite_le.*: update to revision 3acee16 --- c-programming/io/fwrite_le.c | 36 +++++++++++++++++++----------------- c-programming/io/fwrite_le.h | 17 +++++++++++++---- 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/c-programming/io/fwrite_le.c b/c-programming/io/fwrite_le.c index c40667e..f21120a 100644 --- a/c-programming/io/fwrite_le.c +++ b/c-programming/io/fwrite_le.c @@ -8,19 +8,11 @@ #include "fwrite_le.h" int detect_endianness(void) { - volatile uint32_t i = 0x01234567; - uint8_t* bytes = (uint8_t*)(&i); - if (bytes[0] == 0x01 && - bytes[1] == 0x23 && - bytes[2] == 0x45 && - bytes[3] == 0x67) - return DETECTED_BIG_ENDIAN; - else if ( - bytes[0] == 0x67 && - bytes[1] == 0x45 && - bytes[2] == 0x23 && - bytes[3] == 0x01) - return DETECTED_LITTLE_ENDIAN; + volatile uint32_t native_order_value = ORDER_NATIVE_U32; + uint8_t* as_bytes = (uint8_t*)&native_order_value; + + ifeq_b32_ret(as_bytes, ORDER_LITTLE_ENDIAN_S4, DETECTED_LITTLE_ENDIAN); + ifeq_b32_ret(as_bytes, ORDER_BIG_ENDIAN_S4, DETECTED_BIG_ENDIAN ); return UNSUPPORTED_ENDIANNESS; } @@ -31,6 +23,11 @@ void reorder_le_be( uint8_t* bytes, #endif size_t count, size_t step) { + + if (step == 1) { + return; + } + for (size_t i = 0; i < count; i += step) { const size_t div_size = step / 2; for (size_t j = 0; j < div_size; j++) { @@ -47,7 +44,11 @@ void reorder_le_be( } } -size_t fwrite_le(void* ptr, size_t size, size_t count, FILE* stream) { +size_t fwrite_le( +#if FWRITE_LE_NO_MODIFICATION + const +#endif + void* ptr, size_t size, size_t count, FILE* stream) { /* * warning: this function modifies `void* ptr` by default! * (if FWRITE_LE_NO_MODIFICATION in the header is 0) @@ -56,11 +57,12 @@ size_t fwrite_le(void* ptr, size_t size, size_t count, FILE* stream) { return 0; int endianness = detect_endianness(); - if (endianness == UNSUPPORTED_ENDIANNESS) { + if (size == 1 || endianness == DETECTED_LITTLE_ENDIAN) + return fwrite(ptr, size, count, stream); + else if (endianness == UNSUPPORTED_ENDIANNESS) { fprintf(stderr, "Unsupported endianness\n"); exit(EXIT_FAILURE); - } else if (endianness == DETECTED_LITTLE_ENDIAN) - return fwrite(ptr, size, count, stream); + } // case: big-endian size_t bytes_count = size * count; diff --git a/c-programming/io/fwrite_le.h b/c-programming/io/fwrite_le.h index dfb4524..da215aa 100644 --- a/c-programming/io/fwrite_le.h +++ b/c-programming/io/fwrite_le.h @@ -5,22 +5,31 @@ * License: Unlicense */ +#ifndef _FWRITE_LE_H +#define _FWRITE_LE_H + #include #include #include #include -#ifndef _FWRITE_LE_H -#define _FWRITE_LE_H - #define FWRITE_LE_NO_MODIFICATION 0 #define DETECTED_LITTLE_ENDIAN 0 #define DETECTED_BIG_ENDIAN 1 #define UNSUPPORTED_ENDIANNESS -1 +#define ORDER_NATIVE_U32 0x01234567 +#define ORDER_LITTLE_ENDIAN_S4 "\x67\x45\x23\x01" +#define ORDER_BIG_ENDIAN_S4 "\x01\x23\x45\x67" +#define ifeq_b32_ret(lhs, rhs, value) if (!memcmp(lhs, rhs, 4)) return value; + int detect_endianness(void); -size_t fwrite_le(void* ptr, size_t size, size_t count, FILE* stream); +size_t fwrite_le( +#if FWRITE_LE_NO_MODIFICATION + const +#endif + void* ptr, size_t size, size_t count, FILE* stream); void reorder_le_be( #if FWRITE_LE_NO_MODIFICATION uint8_t* dest, uint8_t* src,