module Ptr.Peek
where
import Ptr.Prelude hiding (take)
import qualified Ptr.PokeAndPeek as B
import qualified Ptr.Parse as C
import qualified Ptr.ParseUnbound as D
import qualified Ptr.IO as A
data Peek output =
Peek !Int !(Ptr Word8 -> IO output)
instance Functor Peek where
fmap fn (Peek size io) =
Peek size (fmap fn . io)
instance Applicative Peek where
pure x =
Peek 0 (const (pure x))
(<*>) (Peek leftSize leftIO) (Peek rightSize rightIO) =
Peek (leftSize + rightSize) io
where
io ptr =
leftIO ptr <*> rightIO (plusPtr ptr leftSize)
word8 :: Peek Word8
word8 =
Peek 1 A.peekWord8
beWord16 :: Peek Word16
beWord16 =
Peek 2 A.peekBEWord16
beWord32 :: Peek Word32
beWord32 =
Peek 4 A.peekBEWord32
beWord64 :: Peek Word64
beWord64 =
Peek 8 A.peekBEWord64
bytes :: Int -> Peek ByteString
bytes !amount =
Peek amount (\ ptr -> A.peekBytes ptr amount)
shortByteString :: Int -> Peek ShortByteString
shortByteString !amount =
Peek amount (\ ptr -> A.peekShortByteString ptr amount)
pokeAndPeek :: B.PokeAndPeek input output -> Peek output
pokeAndPeek (B.PokeAndPeek size _ io) =
Peek size io
parse :: Int -> C.Parse a -> (Int -> a) -> (Text -> a) -> Peek a
parse amount (C.Parse parseIO) eoi error =
Peek amount $ \ ptr ->
parseIO amount ptr (return . eoi) (return . error) (\result _ _ -> return result)
parseUnbound :: Int -> D.ParseUnbound a -> (Int -> a) -> (Text -> a) -> Peek a
parseUnbound sizeBound (D.ParseUnbound parseIO) eoi error =
Peek sizeBound $ \ ptr ->
parseIO ptr (return . error)
(\ result size -> if size <= sizeBound
then return (eoi (size sizeBound))
else return result)
peekAmountAndParse :: Peek Int -> C.Parse a -> (Int -> a) -> (Text -> a) -> Peek (Peek a)
peekAmountAndParse peekAmount parse_ eoi error =
flip fmap peekAmount $ \amount ->
parse amount parse_ eoi error