{-# LANGUAGE
TemplateHaskell, MultiParamTypeClasses, GADTs
#-}
module Data.Random.Source.DevRandom
( DevRandom(..)
) where
import Data.Random.Source
import Foreign.Marshal (allocaBytes)
import Foreign.Ptr (castPtr)
import Foreign.Storable (peek)
import System.IO (openBinaryFile, hGetBuf, Handle, IOMode(..))
import System.IO.Unsafe (unsafePerformIO)
data DevRandom = DevRandom | DevURandom
deriving (Eq, Show)
{-# NOINLINE devRandom #-}
devRandom :: Handle
devRandom = unsafePerformIO (openBinaryFile "/dev/random" ReadMode)
{-# NOINLINE devURandom #-}
devURandom :: Handle
devURandom = unsafePerformIO (openBinaryFile "/dev/urandom" ReadMode)
dev :: DevRandom -> Handle
dev DevRandom = devRandom
dev DevURandom = devURandom
$(randomSource
[d| instance RandomSource IO DevRandom where
getRandomWord8From src = allocaBytes 1 $ \buf -> do
1 <- hGetBuf (dev src) buf 1
peek buf
getRandomWord16From src = allocaBytes 2 $ \buf -> do
2 <- hGetBuf (dev src) buf 2
peek (castPtr buf)
getRandomWord32From src = allocaBytes 4 $ \buf -> do
4 <- hGetBuf (dev src) buf 4
peek (castPtr buf)
getRandomWord64From src = allocaBytes 8 $ \buf -> do
8 <- hGetBuf (dev src) buf 8
peek (castPtr buf)
|])