endian.odin 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. package encoding_endian
  2. import "base:intrinsics"
  3. import "core:math/bits"
  4. Byte_Order :: enum u8 {
  5. Little,
  6. Big,
  7. }
  8. PLATFORM_BYTE_ORDER :: Byte_Order.Little when ODIN_ENDIAN == .Little else Byte_Order.Big
  9. unchecked_get_u16le :: #force_inline proc "contextless" (b: []byte) -> u16 {
  10. return bits.from_le_u16(intrinsics.unaligned_load((^u16)(raw_data(b))))
  11. }
  12. unchecked_get_u32le :: #force_inline proc "contextless" (b: []byte) -> u32 {
  13. return bits.from_le_u32(intrinsics.unaligned_load((^u32)(raw_data(b))))
  14. }
  15. unchecked_get_u64le :: #force_inline proc "contextless" (b: []byte) -> u64 {
  16. return bits.from_le_u64(intrinsics.unaligned_load((^u64)(raw_data(b))))
  17. }
  18. unchecked_get_u16be :: #force_inline proc "contextless" (b: []byte) -> u16 {
  19. return bits.from_be_u16(intrinsics.unaligned_load((^u16)(raw_data(b))))
  20. }
  21. unchecked_get_u32be :: #force_inline proc "contextless" (b: []byte) -> u32 {
  22. return bits.from_be_u32(intrinsics.unaligned_load((^u32)(raw_data(b))))
  23. }
  24. unchecked_get_u64be :: #force_inline proc "contextless" (b: []byte) -> u64 {
  25. return bits.from_be_u64(intrinsics.unaligned_load((^u64)(raw_data(b))))
  26. }
  27. get_u16 :: proc "contextless" (b: []byte, order: Byte_Order) -> (v: u16, ok: bool) {
  28. if len(b) < 2 {
  29. return 0, false
  30. }
  31. if order == .Little {
  32. v = unchecked_get_u16le(b)
  33. } else {
  34. v = unchecked_get_u16be(b)
  35. }
  36. return v, true
  37. }
  38. get_u32 :: proc "contextless" (b: []byte, order: Byte_Order) -> (v: u32, ok: bool) {
  39. if len(b) < 4 {
  40. return 0, false
  41. }
  42. if order == .Little {
  43. v = unchecked_get_u32le(b)
  44. } else {
  45. v = unchecked_get_u32be(b)
  46. }
  47. return v, true
  48. }
  49. get_u64 :: proc "contextless" (b: []byte, order: Byte_Order) -> (v: u64, ok: bool) {
  50. if len(b) < 8 {
  51. return 0, false
  52. }
  53. if order == .Little {
  54. v = unchecked_get_u64le(b)
  55. } else {
  56. v = unchecked_get_u64be(b)
  57. }
  58. return v, true
  59. }
  60. get_i16 :: proc "contextless" (b: []byte, order: Byte_Order) -> (i16, bool) {
  61. v, ok := get_u16(b, order)
  62. return i16(v), ok
  63. }
  64. get_i32 :: proc "contextless" (b: []byte, order: Byte_Order) -> (i32, bool) {
  65. v, ok := get_u32(b, order)
  66. return i32(v), ok
  67. }
  68. get_i64 :: proc "contextless" (b: []byte, order: Byte_Order) -> (i64, bool) {
  69. v, ok := get_u64(b, order)
  70. return i64(v), ok
  71. }
  72. get_f16 :: proc "contextless" (b: []byte, order: Byte_Order) -> (f16, bool) {
  73. v, ok := get_u16(b, order)
  74. return transmute(f16)v, ok
  75. }
  76. get_f32 :: proc "contextless" (b: []byte, order: Byte_Order) -> (f32, bool) {
  77. v, ok := get_u32(b, order)
  78. return transmute(f32)v, ok
  79. }
  80. get_f64 :: proc "contextless" (b: []byte, order: Byte_Order) -> (f64, bool) {
  81. v, ok := get_u64(b, order)
  82. return transmute(f64)v, ok
  83. }
  84. unchecked_put_u16le :: #force_inline proc "contextless" (b: []byte, v: u16) {
  85. intrinsics.unaligned_store((^u16)(raw_data(b)), bits.to_le_u16(v))
  86. }
  87. unchecked_put_u32le :: #force_inline proc "contextless" (b: []byte, v: u32) {
  88. intrinsics.unaligned_store((^u32)(raw_data(b)), bits.to_le_u32(v))
  89. }
  90. unchecked_put_u64le :: #force_inline proc "contextless" (b: []byte, v: u64) {
  91. intrinsics.unaligned_store((^u64)(raw_data(b)), bits.to_le_u64(v))
  92. }
  93. unchecked_put_u16be :: #force_inline proc "contextless" (b: []byte, v: u16) {
  94. intrinsics.unaligned_store((^u16)(raw_data(b)), bits.to_be_u16(v))
  95. }
  96. unchecked_put_u32be :: #force_inline proc "contextless" (b: []byte, v: u32) {
  97. intrinsics.unaligned_store((^u32)(raw_data(b)), bits.to_be_u32(v))
  98. }
  99. unchecked_put_u64be :: #force_inline proc "contextless" (b: []byte, v: u64) {
  100. intrinsics.unaligned_store((^u64)(raw_data(b)), bits.to_be_u64(v))
  101. }
  102. put_u16 :: proc "contextless" (b: []byte, order: Byte_Order, v: u16) -> bool {
  103. if len(b) < 2 {
  104. return false
  105. }
  106. if order == .Little {
  107. unchecked_put_u16le(b, v)
  108. } else {
  109. unchecked_put_u16be(b, v)
  110. }
  111. return true
  112. }
  113. put_u32 :: proc "contextless" (b: []byte, order: Byte_Order, v: u32) -> bool {
  114. if len(b) < 4 {
  115. return false
  116. }
  117. if order == .Little {
  118. unchecked_put_u32le(b, v)
  119. } else {
  120. unchecked_put_u32be(b, v)
  121. }
  122. return true
  123. }
  124. put_u64 :: proc "contextless" (b: []byte, order: Byte_Order, v: u64) -> bool {
  125. if len(b) < 8 {
  126. return false
  127. }
  128. if order == .Little {
  129. unchecked_put_u64le(b, v)
  130. } else {
  131. unchecked_put_u64be(b, v)
  132. }
  133. return true
  134. }
  135. put_i16 :: proc "contextless" (b: []byte, order: Byte_Order, v: i16) -> bool {
  136. return put_u16(b, order, u16(v))
  137. }
  138. put_i32 :: proc "contextless" (b: []byte, order: Byte_Order, v: i32) -> bool {
  139. return put_u32(b, order, u32(v))
  140. }
  141. put_i64 :: proc "contextless" (b: []byte, order: Byte_Order, v: i64) -> bool {
  142. return put_u64(b, order, u64(v))
  143. }
  144. put_f16 :: proc "contextless" (b: []byte, order: Byte_Order, v: f16) -> bool {
  145. return put_u16(b, order, transmute(u16)v)
  146. }
  147. put_f32 :: proc "contextless" (b: []byte, order: Byte_Order, v: f32) -> bool {
  148. return put_u32(b, order, transmute(u32)v)
  149. }
  150. put_f64 :: proc "contextless" (b: []byte, order: Byte_Order, v: f64) -> bool {
  151. return put_u64(b, order, transmute(u64)v)
  152. }