util.odin 3.9 KB

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