util.odin 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. package util
  2. /*
  3. Copyright 2021 zhibog
  4. Made available under the BSD-3 license.
  5. List of contributors:
  6. zhibog, dotbmp: Initial implementation.
  7. Various utility procedures
  8. */
  9. import "core:mem"
  10. // Keep vet happy
  11. _ :: mem
  12. // @note(bp): this can replace the other two
  13. cast_slice :: #force_inline proc "contextless" ($D: typeid/[]$DE, src: $S/[]$SE) -> D {
  14. src := src
  15. dst := (^mem.Raw_Slice)(&src)
  16. when size_of(DE) < size_of(SE) {
  17. when size_of(DE) % size_of(SE) == 0 {
  18. dst.len /= size_of(SE) / size_of(DE)
  19. } else {
  20. dst.len *= size_of(SE)
  21. dst.len /= size_of(DE)
  22. }
  23. } else when size_of(DE) > size_of(SE) {
  24. when size_of(DE) % size_of(SE) == 0 {
  25. dst.len *= size_of(DE) / size_of(SE)
  26. } else {
  27. dst.len *= size_of(SE)
  28. dst.len /= size_of(DE)
  29. }
  30. } else when size_of(DE) != size_of(SE) {
  31. #assert(size_of(DE) % size_of(SE) == 0, "Different size detected")
  32. dst.len *= size_of(SE)
  33. dst.len /= size_of(DE)
  34. }
  35. return (^D)(dst)^
  36. }
  37. bytes_to_slice :: #force_inline proc "contextless" ($T: typeid/[]$E, bytes: []byte) -> T {
  38. s := transmute(mem.Raw_Slice)bytes
  39. s.len /= size_of(E)
  40. return transmute(T)s
  41. }
  42. slice_to_bytes :: #force_inline proc "contextless" (slice: $E/[]$T) -> []byte {
  43. s := transmute(mem.Raw_Slice)slice
  44. s.len *= size_of(T)
  45. return transmute([]byte)s
  46. }
  47. ROTL16 :: #force_inline proc "contextless" (a, b: u16) -> u16 {
  48. return ((a << b) | (a >> (16 - b)))
  49. }
  50. ROTR16 :: #force_inline proc "contextless" (a, b: u16) -> u16 {
  51. return ((a >> b) | (a << (16 - b)))
  52. }
  53. ROTL32 :: #force_inline proc "contextless"(a: u32, b: int) -> u32 {
  54. s := uint(b) & 31
  55. return (a << s) | (a >> (32 - s))
  56. }
  57. ROTR32 :: #force_inline proc "contextless" (a: u32, b: int) -> u32 {
  58. s := uint(b) & 31
  59. return (a >> s) | (a << (32 - s))
  60. }
  61. ROTL64 :: #force_inline proc "contextless" (a, b: u64) -> u64 {
  62. return ((a << b) | (a >> (64 - b)))
  63. }
  64. ROTR64 :: #force_inline proc "contextless" (a, b: u64) -> u64 {
  65. return ((a >> b) | (a << (64 - b)))
  66. }
  67. ROTL128 :: #force_inline proc "contextless" (a, b, c, d: ^u32, n: uint) {
  68. a, b, c, d := a, b, c, d
  69. t := a^ >> (32 - n)
  70. a^ = ((a^ << n) | (b^ >> (32 - n)))
  71. b^ = ((b^ << n) | (c^ >> (32 - n)))
  72. c^ = ((c^ << n) | (d^ >> (32 - n)))
  73. d^ = ((d^ << n) | t)
  74. }
  75. U32_LE :: #force_inline proc "contextless" (b: []byte) -> u32 {
  76. return u32(b[0]) | u32(b[1]) << 8 | u32(b[2]) << 16 | u32(b[3]) << 24
  77. }
  78. U64_LE :: #force_inline proc "contextless" (b: []byte) -> u64 {
  79. return u64(b[0]) | u64(b[1]) << 8 | u64(b[2]) << 16 | u64(b[3]) << 24 |
  80. u64(b[4]) << 32 | u64(b[5]) << 40 | u64(b[6]) << 48 | u64(b[7]) << 56
  81. }
  82. U64_BE :: #force_inline proc "contextless" (b: []byte) -> u64 {
  83. return u64(b[7]) | u64(b[6]) << 8 | u64(b[5]) << 16 | u64(b[4]) << 24 |
  84. u64(b[3]) << 32 | u64(b[2]) << 40 | u64(b[1]) << 48 | u64(b[0]) << 56
  85. }
  86. PUT_U64_LE :: #force_inline proc "contextless" (b: []byte, v: u64) {
  87. b[0] = byte(v)
  88. b[1] = byte(v >> 8)
  89. b[2] = byte(v >> 16)
  90. b[3] = byte(v >> 24)
  91. b[4] = byte(v >> 32)
  92. b[5] = byte(v >> 40)
  93. b[6] = byte(v >> 48)
  94. b[7] = byte(v >> 56)
  95. }
  96. PUT_U32_LE :: #force_inline proc "contextless" (b: []byte, v: u32) {
  97. b[0] = byte(v)
  98. b[1] = byte(v >> 8)
  99. b[2] = byte(v >> 16)
  100. b[3] = byte(v >> 24)
  101. }
  102. PUT_U32_BE :: #force_inline proc "contextless" (b: []byte, v: u32) {
  103. b[0] = byte(v >> 24)
  104. b[1] = byte(v >> 16)
  105. b[2] = byte(v >> 8)
  106. b[3] = byte(v)
  107. }
  108. PUT_U64_BE :: #force_inline proc "contextless" (b: []byte, v: u64) {
  109. b[0] = byte(v >> 56)
  110. b[1] = byte(v >> 48)
  111. b[2] = byte(v >> 40)
  112. b[3] = byte(v >> 32)
  113. b[4] = byte(v >> 24)
  114. b[5] = byte(v >> 16)
  115. b[6] = byte(v >> 8)
  116. b[7] = byte(v)
  117. }
  118. XOR_BUF :: #force_inline proc "contextless" (input, output: []byte) {
  119. for i := 0; i < len(input); i += 1 {
  120. output[i] ~= input[i]
  121. }
  122. }