aboutsummaryrefslogtreecommitdiff
path: root/Src/replicant/nu/x86/ByteWriter.h
diff options
context:
space:
mode:
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++;
+}