hashabler-0.1.0.0: src/MachDeps.hs
{-# LANGUAGE TemplateHaskell #-}
module MachDeps (littleEndian) where
-- technique stolen from: http://stackoverflow.com/a/6129295/176841 and
-- https://hackage.haskell.org/package/cpu-0.1.0/docs/src/System-Endian.html#getSystemEndianness
import Language.Haskell.TH.Syntax(Lift(..))
import Foreign.Marshal.Alloc
import Foreign.Storable
import Foreign.Ptr
import System.IO.Unsafe (unsafePerformIO)
import Data.Word
-- TODO TESTING: CORRECT ON 64-BIT LE MACHINES
-- | Compile-time constant; True on LE, False on BE, and compile-time error otherwise.
littleEndian :: Bool
littleEndian =
$(
let cst :: Word32
cst = 0x01020304
check :: [Word8] -> Bool
check x
| x == [1,2,3,4] = False -- BE
| x == [4,3,2,1] = True -- LE
| otherwise = error $ "Very interesting endianness! "
++"(unfortunately we don't support it yet)"
in lift $ unsafePerformIO $ alloca $ \p -> do
poke p cst
let wd8Ptrs = map (castPtr p `plusPtr`) [0..3]
mapM peek wd8Ptrs >>= return . check
)