From 9fd983c986f0a675164a6bf66ecdcf9b5e7d567a Mon Sep 17 00:00:00 2001 From: nopjne Date: Sun, 17 Nov 2024 22:13:43 -0800 Subject: [PATCH] Add big endian support --- src/formats/internal/memreader.c | 23 ++++++++++++++ src/formats/internal/memwriter.c | 32 ++++++++++++++++++- src/formats/internal/reader.c | 53 ++++++++++++++++++++++++++++++++ src/formats/internal/writer.c | 20 +++++++++++- 4 files changed, 126 insertions(+), 2 deletions(-) diff --git a/src/formats/internal/memreader.c b/src/formats/internal/memreader.c index 0cc632ff9..000ce20f6 100644 --- a/src/formats/internal/memreader.c +++ b/src/formats/internal/memreader.c @@ -62,14 +62,22 @@ uint8_t memread_ubyte(memreader *reader) { uint16_t memread_uword(memreader *reader) { uint16_t r; +#ifdef BIG_ENDIAN_BUILD + r = __builtin_bswap16(*((uint16_t *)(reader->buf + reader->pos))); +#else memcpy(&r, reader->buf + reader->pos, sizeof(r)); +#endif reader->pos += sizeof(r); return r; } uint32_t memread_udword(memreader *reader) { uint32_t r; +#ifdef BIG_ENDIAN_BUILD + r = __builtin_bswap32(*((uint32_t *)(reader->buf + reader->pos))); +#else memcpy(&r, reader->buf + reader->pos, sizeof(r)); +#endif reader->pos += sizeof(r); return r; } @@ -83,22 +91,37 @@ int8_t memread_byte(memreader *reader) { int16_t memread_word(memreader *reader) { int16_t r; +#ifdef BIG_ENDIAN_BUILD + r = __builtin_bswap16(*((uint16_t *)(reader->buf + reader->pos))); +#else memcpy(&r, reader->buf + reader->pos, sizeof(r)); +#endif reader->pos += sizeof(r); return r; } int32_t memread_dword(memreader *reader) { int32_t r; +#ifdef BIG_ENDIAN_BUILD + r = __builtin_bswap32(*((int32_t *)(reader->buf + reader->pos))); +#else memcpy(&r, reader->buf + reader->pos, sizeof(r)); +#endif reader->pos += sizeof(r); return r; } float memread_float(memreader *reader) { float r; +#ifdef BIG_ENDIAN_BUILD + uint32_t fl; + memcpy(&fl, reader->buf + reader->pos, sizeof(fl)); + fl = __builtin_bswap32(fl); + reader->pos += sizeof(fl); +#else memcpy(&r, reader->buf + reader->pos, sizeof(r)); reader->pos += sizeof(r); +#endif return r; } diff --git a/src/formats/internal/memwriter.c b/src/formats/internal/memwriter.c index c577781c4..2c42883ae 100644 --- a/src/formats/internal/memwriter.c +++ b/src/formats/internal/memwriter.c @@ -7,7 +7,6 @@ #include "formats/internal/memwriter.h" #include "formats/internal/writer.h" #include "utils/allocator.h" - #define GROW 64 #define CHECK_SIZE \ @@ -57,11 +56,23 @@ void memwrite_ubyte(memwriter *writer, uint8_t value) { } void memwrite_uword(memwriter *writer, uint16_t value) { +#ifdef BIG_ENDIAN_BUILD + uint16_t t = value; + t = __builtin_bswap16(t); + memwrite_buf(writer, (char *)&t, 2); +#else memwrite_buf(writer, (char *)&value, 2); +#endif } void memwrite_udword(memwriter *writer, uint32_t value) { +#ifdef BIG_ENDIAN_BUILD + uint32_t t = value; + t = __builtin_bswap32(t); + memwrite_buf(writer, (char *)&t, 4); +#else memwrite_buf(writer, (char *)&value, 4); +#endif } void memwrite_byte(memwriter *writer, int8_t value) { @@ -69,15 +80,34 @@ void memwrite_byte(memwriter *writer, int8_t value) { } void memwrite_word(memwriter *writer, int16_t value) { +#ifdef BIG_ENDIAN_BUILD + int16_t t = value; + t = __builtin_bswap16(t); + memwrite_buf(writer, (char *)&t, 2); +#else memwrite_buf(writer, (char *)&value, 2); +#endif } void memwrite_dword(memwriter *writer, int32_t value) { +#ifdef BIG_ENDIAN_BUILD + int32_t t = value; + t = __builtin_bswap32(t); + memwrite_buf(writer, (char *)&t, 4); +#else memwrite_buf(writer, (char *)&value, 4); +#endif } void memwrite_float(memwriter *writer, float value) { +#ifdef BIG_ENDIAN_BUILD + uint32_t t; + memcpy(&t, &value, 4); + t = __builtin_bswap32(t); + memwrite_buf(writer, (char *)&t, 4); +#else memwrite_buf(writer, (char *)&value, sizeof(float)); +#endif } void memwrite_fill(memwriter *writer, char content, int len) { diff --git a/src/formats/internal/reader.c b/src/formats/internal/reader.c index f42c1cd02..37fb428c5 100644 --- a/src/formats/internal/reader.c +++ b/src/formats/internal/reader.c @@ -110,12 +110,18 @@ uint8_t sd_read_ubyte(sd_reader *reader) { uint16_t sd_read_uword(sd_reader *reader) { uint16_t d = 0; sd_read_buf(reader, (char *)&d, 2); +#ifdef BIG_ENDIAN_BUILD + d = __builtin_bswap16(d); +#endif return d; } uint32_t sd_read_udword(sd_reader *reader) { uint32_t d = 0; sd_read_buf(reader, (char *)&d, 4); +#ifdef BIG_ENDIAN_BUILD + d = __builtin_bswap32(d); +#endif return d; } @@ -128,18 +134,31 @@ int8_t sd_read_byte(sd_reader *reader) { int16_t sd_read_word(sd_reader *reader) { int16_t d = 0; sd_read_buf(reader, (char *)&d, 2); +#ifdef BIG_ENDIAN_BUILD + d = __builtin_bswap16(d); +#endif return d; } int32_t sd_read_dword(sd_reader *reader) { int32_t d = 0; sd_read_buf(reader, (char *)&d, 4); +#ifdef BIG_ENDIAN_BUILD + d = __builtin_bswap32(d); +#endif return d; } float sd_read_float(sd_reader *reader) { float f = 0; +#ifdef BIG_ENDIAN_BUILD + uint32_t r = 0; + sd_read_buf(reader, (char *)&r, 4); + r = __builtin_bswap32(r); + memcpy(&f, &r, sizeof(f)); +#else sd_read_buf(reader, (char *)&f, 4); +#endif return f; } @@ -152,12 +171,18 @@ uint8_t sd_peek_ubyte(sd_reader *reader) { uint16_t sd_peek_uword(sd_reader *reader) { uint16_t d = 0; sd_peek_buf(reader, (char *)&d, 2); +#ifdef BIG_ENDIAN_BUILD + d = __builtin_bswap16(d); +#endif return d; } uint32_t sd_peek_udword(sd_reader *reader) { uint32_t d = 0; sd_peek_buf(reader, (char *)&d, 4); +#ifdef BIG_ENDIAN_BUILD + d = __builtin_bswap32(d); +#endif return d; } @@ -170,18 +195,27 @@ int8_t sd_peek_byte(sd_reader *reader) { int16_t sd_peek_word(sd_reader *reader) { int16_t d = 0; sd_peek_buf(reader, (char *)&d, 2); +#ifdef BIG_ENDIAN_BUILD + d = __builtin_bswap16(d); +#endif return d; } int32_t sd_peek_dword(sd_reader *reader) { int32_t d = 0; sd_peek_buf(reader, (char *)&d, 4); +#ifdef BIG_ENDIAN_BUILD + d = __builtin_bswap32(d); +#endif return d; } float sd_peek_float(sd_reader *reader) { float f = 0; sd_peek_buf(reader, (char *)&f, 4); +#ifdef BIG_ENDIAN_BUILD + f = __builtin_bswap16(f); +#endif return f; } @@ -213,6 +247,16 @@ int sd_read_line(const sd_reader *reader, char *buffer, int maxlen) { if(fgets(buffer, maxlen, reader->handle) == NULL) { return 1; } +#ifdef BIG_ENDIAN_BUILD + int len = maxlen; + for(int i = 0; i < len / 4; i += 1) { + ((int *)buffer)[i] = __builtin_bswap32(((int *)buffer)[i]); + } + + if((len & 3) == 2) { + ((uint16_t *)buffer)[(len / 2) - 1] = __builtin_bswap16(((uint16_t *)buffer)[(len / 2) - 1]); + } +#endif return 0; } @@ -231,6 +275,15 @@ void sd_read_str(sd_reader *r, str *dst) { if(len > 0) { char *buf = omf_calloc(1, len + 1); sd_read_buf(r, buf, len); +#ifdef BIG_ENDIAN_BUILD + for(int i = 0; i < len / 4; i += 1) { + ((int *)buf)[i] = __builtin_bswap32(((int *)buf)[i]); + } + + if((len & 3) == 2) { + ((uint16_t *)buf)[(len / 2) - 1] = __builtin_bswap16(((uint16_t *)buf)[(len / 2) - 1]); + } +#endif str_from_c(dst, buf); omf_free(buf); } else { diff --git a/src/formats/internal/writer.c b/src/formats/internal/writer.c index c082271b3..dedf82011 100644 --- a/src/formats/internal/writer.c +++ b/src/formats/internal/writer.c @@ -15,7 +15,6 @@ struct sd_writer { sd_writer *sd_writer_open(const char *file) { sd_writer *writer = omf_calloc(1, sizeof(sd_writer)); - writer->handle = fopen(file, "wb"); writer->sd_errno = 0; if(!writer->handle) { @@ -76,10 +75,16 @@ void sd_write_ubyte(sd_writer *writer, uint8_t data) { } void sd_write_uword(sd_writer *writer, uint16_t data) { +#ifdef BIG_ENDIAN_BUILD + data = __builtin_bswap16(data); +#endif sd_write_buf(writer, (char *)&data, 2); } void sd_write_udword(sd_writer *writer, uint32_t data) { +#ifdef BIG_ENDIAN_BUILD + data = __builtin_bswap32(data); +#endif sd_write_buf(writer, (char *)&data, 4); } @@ -88,15 +93,28 @@ void sd_write_byte(sd_writer *writer, int8_t data) { } void sd_write_word(sd_writer *writer, int16_t data) { +#ifdef BIG_ENDIAN_BUILD + data = __builtin_bswap16(data); +#endif sd_write_buf(writer, (char *)&data, 2); } void sd_write_dword(sd_writer *writer, int32_t data) { +#ifdef BIG_ENDIAN_BUILD + data = __builtin_bswap32(data); +#endif sd_write_buf(writer, (char *)&data, 4); } void sd_write_float(sd_writer *writer, float data) { +#ifdef BIG_ENDIAN_BUILD + uint32_t fl; + memcpy(&fl, &data, sizeof(fl)); + fl = __builtin_bswap32(fl); + sd_write_buf(writer, (char *)&fl, sizeof(fl)); +#else sd_write_buf(writer, (char *)&data, sizeof(float)); +#endif } void sd_write_fill(sd_writer *writer, char content, size_t len) {