1
0

C: add fwrite_le.*, correct include var. in template

This commit is contained in:
Intel A80486DX2-66 2023-12-31 15:19:42 +03:00
parent aa5f7359c2
commit ff5608e0d0
Signed by: 80486DX2-66
GPG Key ID: 83631EF27054609B
3 changed files with 87 additions and 1 deletions

68
src/fwrite_le.c Normal file
View File

@ -0,0 +1,68 @@
#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;
return UNSUPPORTED_ENDIANNESS;
}
size_t fwrite_le(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)
*/
if (ptr == NULL)
return 0;
int endianness = detect_endianness();
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;
#if FWRITE_LE_NO_MODIFICATION
uint8_t* bytes = calloc(bytes_count, sizeof(uint8_t));
if (bytes == NULL) {
perror("calloc");
exit(EXIT_FAILURE);
}
memcpy(bytes, ptr, bytes_count);
#else
uint8_t* bytes = (uint8_t*) ptr;
#endif
for (size_t i = 0; i < bytes_count; i += size) {
const size_t div_size = size >> 1; // divide by 2
for (size_t j = 0; j < div_size; j++) {
const size_t old_pos = i + j, new_pos = i + size - j - 1;
uint8_t temp = bytes[old_pos];
bytes[old_pos] = bytes[new_pos];
bytes[new_pos] = temp;
}
}
#if FWRITE_LE_NO_MODIFICATION
size_t res =
#else
return
#endif
fwrite(bytes, size, count, stream);
#if FWRITE_LE_NO_MODIFICATION
free(bytes);
return res;
#endif
}

18
src/fwrite_le.h Normal file
View File

@ -0,0 +1,18 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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
int detect_endianness(void);
size_t fwrite_le(void* ptr, size_t size, size_t count, FILE* stream);
#endif /* _FWRITE_LE_H */

View File

@ -7,7 +7,7 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include "`path_to_fwrite_le`" #include "`fwrite_le`"
// constants // constants
#if defined(_WIN32) #if defined(_WIN32)