aboutsummaryrefslogtreecommitdiff
path: root/Src/replicant/nu/x86/ByteWriter.h
diff options
context:
space:
mode:
authorJean-Francois Mauguit <jfmauguit@mac.com>2024-09-24 09:03:25 -0400
committerGitHub <noreply@github.com>2024-09-24 09:03:25 -0400
commitbab614c421ed7ae329d26bf028c4a3b1d2450f5a (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/replicant/nu/x86/ByteWriter.h
parent4bde6044fddf053f31795b9eaccdd2a5a527d21f (diff)
parent20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (diff)
downloadwinamp-bab614c421ed7ae329d26bf028c4a3b1d2450f5a.tar.gz
Merge pull request #5 from WinampDesktop/community
Merge to main
Diffstat (limited to 'Src/replicant/nu/x86/ByteWriter.h')
-rw-r--r--Src/replicant/nu/x86/ByteWriter.h85
1 files changed, 85 insertions, 0 deletions
diff --git a/Src/replicant/nu/x86/ByteWriter.h b/Src/replicant/nu/x86/ByteWriter.h
new file mode 100644
index 00000000..d38f0c95
--- /dev/null
+++ b/Src/replicant/nu/x86/ByteWriter.h
@@ -0,0 +1,85 @@
+#pragma once
+#include "foundation/types.h"
+#include "foundation/endian.h"
+/* this is separated out to processor-specific types for a few reasons
+
+1) Unaligned writes are fast/easy on x86, slow on some platforms (ARM, x64), very slow on a few (Itanium) and crash on others (PowerPC)
+2) ARM is very good at *ptr++, x86 is very good at ptr[offset]
+3) Endian issues
+*/
+typedef struct ByteWriter
+{
+ uint8_t *data;
+ size_t data_length;
+ size_t offset;
+} ByteWriter, *nu_bytewriter_t;
+
+/* --------- Construction & Utility --------- */
+#define BYTEWRITER_INIT(data, length) { (uint8_t *)data, length, 0 }
+
+inline static uint32_t bw_bytes_written(nu_bytewriter_t bw)
+{
+ return bw->offset;
+}
+
+/* --------- Little Endian writers --------- */
+inline static void bytewriter_fourcc_string(nu_bytewriter_t bw, const char *fourcc)
+{
+ bw->data[bw->offset] = fourcc[0];
+ bw->data[bw->offset+1] = fourcc[1];
+ bw->data[bw->offset+2] = fourcc[2];
+ bw->data[bw->offset+3] = fourcc[3];
+ bw->offset += 4;
+}
+
+inline static void bytewriter_uint32_le(nu_bytewriter_t bw, uint32_t value)
+{
+ *(uint32_t *)(&bw->data[bw->offset]) = value;
+ bw->offset+=4;
+}
+
+inline static void bytewriter_uint16_le(nu_bytewriter_t bw, uint16_t value)
+{
+ *(uint16_t *)(&bw->data[bw->offset]) = value;
+ bw->offset+=2;
+}
+
+/* --------- Big Endian writers --------- */
+inline static void bytewriter_uint32_be(nu_bytewriter_t bw, uint32_t value)
+{
+ *(uint32_t *)(&bw->data[bw->offset]) = _byteswap_ulong(value);
+ bw->offset+=4;
+}
+
+inline static void bytewriter_uint24_be(nu_bytewriter_t bw, uint32_t value)
+{
+ bw->data[bw->offset] = (uint8_t)(value >> 16) & 0xFF;
+ bw->data[bw->offset+1] = (uint8_t)(value >> 8) & 0xFF;
+ bw->data[bw->offset+2] = (uint8_t)value & 0xFF;
+ bw->offset+=3;
+}
+
+inline static void bytewriter_uint16_le(nu_bytewriter_t bw, uint16_t value)
+{
+ *(uint16_t *)(&bw->data[bw->offset]) = value;
+ bw->offset+=2;
+}
+
+/* --------- Neutral Endian writers --------- */
+inline static void bytewriter_uint32_zero(nu_bytewriter_t bw)
+{
+ *(uint32_t *)(&bw->data[bw->offset]) = 0;
+ bw->offset+=4;
+}
+
+inline static void bytewriter_uint32_nzero(nu_bytewriter_t bw, uint32_t num_zeroes)
+{
+ memset(bw->data, 0, num_zeroes*4);
+ bw->offset+=num_zeroes*4;
+}
+
+inline static void bytewriter_uint8(nu_bytewriter_t bw, uint8_t value)
+{
+ *(uint8_t *)&bw->data[bw->offset] = value;
+ bw->offset++;
+}