diff options
Diffstat (limited to 'src/utils')
-rw-r--r-- | src/utils/endians.nim | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/src/utils/endians.nim b/src/utils/endians.nim new file mode 100644 index 00000000..ea34efa7 --- /dev/null +++ b/src/utils/endians.nim @@ -0,0 +1,39 @@ +when defined(gcc) or defined(llvm_gcc) or defined(clang): + const useBuiltinSwap = true + proc builtin_bswap32(a: uint32): uint32 {. + importc: "__builtin_bswap32", nodecl, noSideEffect.} +elif defined(icc): + const useBuiltinSwap = true + proc builtin_bswap32(a: uint32): uint32 {. + importc: "_bswap", nodecl, noSideEffect.} +elif defined(vcc): + const useBuiltinSwap = true + proc builtin_bswap32(a: uint32): uint32 {. + importc: "_byteswap_ulong", nodecl, header: "<intrin.h>", noSideEffect.} +else: + const useBuiltinSwap = false + +when useBuiltinSwap: + proc swap(u: uint32): uint32 {.inline.} = + return builtin_bswap32(u) +else: + proc swap(u: uint32): uint32 {.inline.} = + return ((u and 0xFF000000) shr 24) or + ((u and 0x00FF0000) shr 8) or + ((u and 0x0000FF00) shl 8) or + (u shl 24) + +proc fromBytesBEu32*(x: openArray[uint8]): uint32 {.inline.} = + var u {.noInit.}: uint32 + copyMem(addr u, unsafeAddr x[0], sizeof(uint32)) + when system.cpuEndian == littleEndian: + return swap(u) + else: + return u + +proc toBytesBE*(u: uint32): array[sizeof(uint32), uint8] {.inline.} = + when system.cpuEndian == littleEndian: + var u = swap(u) + copyMem(addr result[0], addr u, sizeof(uint32)) + else: + copyMem(addr result[0], unsafeAddr u, sizeof(uint32)) |