{-# LANGUAGE Trustworthy #-} module Data.Columbia.Integral where import Data.Generics.SYB.WithClass.Basics import Data.Bits import Data.Word import Control.Monad import Control.Monad.Reader import Control.Monad.Trans import Data.Columbia.SeekableStream import Data.Columbia.SeekableWriter readIntegral :: (Monad m, Bits i, Integral i) => ReaderT(SeekableStream m Word8) m i readIntegral = liftM4(\x1 x2 x3 x4 -> shiftL(fromIntegral x1) 24 .|. shiftL(fromIntegral x2) 16 .|. shiftL(fromIntegral x3) 8 .|. fromIntegral x4) consumeToken consumeToken consumeToken consumeToken writeIntegral :: (Monad m, Bits i, Integral i) => i -> ReaderT(SeekableWriter m Word8) m () writeIntegral x = do putToken$!fromIntegral$shiftR x 24 putToken$!fromIntegral$shiftR x 16 putToken$!fromIntegral$shiftR x 8 putToken$!fromIntegral x readIntegral16 :: (Monad m, Bits i, Integral i) => ReaderT(SeekableStream m Word8) m i readIntegral16 = liftM2(\x1 x2 -> shiftL(fromIntegral x1) 8 .|. fromIntegral x2) consumeToken consumeToken writeIntegral16 :: (Monad m, Bits i, Integral i) => i -> ReaderT(SeekableWriter m Word8) m () writeIntegral16 x = do putToken$!fromIntegral$shiftR x 8 putToken$!fromIntegral x seekByPointer :: (Monad m) => ReaderT(SeekableStream m Word8) m () seekByPointer = do n <- readIntegral seek n