ByteWriter.h 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #pragma once
  2. #include "foundation/types.h"
  3. #include "foundation/endian.h"
  4. /* this is separated out to processor-specific types for a few reasons
  5. 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)
  6. 2) ARM is very good at *ptr++, x86 is very good at ptr[offset]
  7. 3) Endian issues
  8. */
  9. typedef struct ByteWriter
  10. {
  11. uint8_t *data;
  12. size_t data_length;
  13. size_t offset;
  14. } ByteWriter, *nu_bytewriter_t;
  15. /* --------- Construction & Utility --------- */
  16. #define BYTEWRITER_INIT(data, length) { (uint8_t *)data, length, 0 }
  17. inline static uint32_t bw_bytes_written(nu_bytewriter_t bw)
  18. {
  19. return bw->offset;
  20. }
  21. /* --------- Little Endian writers --------- */
  22. inline static void bytewriter_fourcc_string(nu_bytewriter_t bw, const char *fourcc)
  23. {
  24. bw->data[bw->offset] = fourcc[0];
  25. bw->data[bw->offset+1] = fourcc[1];
  26. bw->data[bw->offset+2] = fourcc[2];
  27. bw->data[bw->offset+3] = fourcc[3];
  28. bw->offset += 4;
  29. }
  30. inline static void bytewriter_uint32_le(nu_bytewriter_t bw, uint32_t value)
  31. {
  32. *(uint32_t *)(&bw->data[bw->offset]) = value;
  33. bw->offset+=4;
  34. }
  35. inline static void bytewriter_uint16_le(nu_bytewriter_t bw, uint16_t value)
  36. {
  37. *(uint16_t *)(&bw->data[bw->offset]) = value;
  38. bw->offset+=2;
  39. }
  40. /* --------- Big Endian writers --------- */
  41. inline static void bytewriter_uint32_be(nu_bytewriter_t bw, uint32_t value)
  42. {
  43. *(uint32_t *)(&bw->data[bw->offset]) = _byteswap_ulong(value);
  44. bw->offset+=4;
  45. }
  46. inline static void bytewriter_uint24_be(nu_bytewriter_t bw, uint32_t value)
  47. {
  48. bw->data[bw->offset] = (uint8_t)(value >> 16) & 0xFF;
  49. bw->data[bw->offset+1] = (uint8_t)(value >> 8) & 0xFF;
  50. bw->data[bw->offset+2] = (uint8_t)value & 0xFF;
  51. bw->offset+=3;
  52. }
  53. inline static void bytewriter_uint16_le(nu_bytewriter_t bw, uint16_t value)
  54. {
  55. *(uint16_t *)(&bw->data[bw->offset]) = value;
  56. bw->offset+=2;
  57. }
  58. /* --------- Neutral Endian writers --------- */
  59. inline static void bytewriter_uint32_zero(nu_bytewriter_t bw)
  60. {
  61. *(uint32_t *)(&bw->data[bw->offset]) = 0;
  62. bw->offset+=4;
  63. }
  64. inline static void bytewriter_uint32_nzero(nu_bytewriter_t bw, uint32_t num_zeroes)
  65. {
  66. memset(bw->data, 0, num_zeroes*4);
  67. bw->offset+=num_zeroes*4;
  68. }
  69. inline static void bytewriter_uint8(nu_bytewriter_t bw, uint8_t value)
  70. {
  71. *(uint8_t *)&bw->data[bw->offset] = value;
  72. bw->offset++;
  73. }