module Foundation.System.Entropy
( getEntropy
) where
import Basement.Compat.Base
import Basement.Types.OffsetSize
import qualified Basement.UArray.Mutable as A
import qualified Basement.UArray as A
import Control.Exception
import Foreign.Ptr
import Foundation.Numerical
import Foundation.System.Entropy.Common
#ifdef mingw32_HOST_OS
import Foundation.System.Entropy.Windows
#else
import Foundation.System.Entropy.Unix
#endif
getEntropy :: CountOf Word8 -> IO (A.UArray Word8)
getEntropy n@(CountOf x) = do
m <- A.newPinned n
bracket entropyOpen entropyClose $ \ctx -> A.withMutablePtr m $ loop ctx x
A.unsafeFreeze m
where
loop :: EntropyCtx -> Int -> Ptr Word8 -> IO ()
loop _ 0 _ = return ()
loop ctx i p = do
let chSz = min entropyMaximumSize i
r <- entropyGather ctx p chSz
if r
then loop ctx (ichSz) (p `plusPtr` chSz)
else throwIO EntropySystemMissing