module Data.Repa.Convert.Internal.Unpacker
( Unpacker (..)
, unsafeRunUnpacker)
where
import Data.IORef
import Data.Word
import GHC.Exts
import Prelude hiding (fail)
import qualified Foreign.Ptr as F
data Unpacker a
= Unpacker
{
forall a.
Unpacker a
-> Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> a -> IO ())
-> IO ()
fromUnpacker
:: Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> a -> IO ())
-> IO ()
}
instance Functor Unpacker where
fmap :: forall a b. (a -> b) -> Unpacker a -> Unpacker b
fmap a -> b
f (Unpacker Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> a -> IO ())
-> IO ()
fx)
= (Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> b -> IO ())
-> IO ())
-> Unpacker b
forall a.
(Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> a -> IO ())
-> IO ())
-> Unpacker a
Unpacker ((Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> b -> IO ())
-> IO ())
-> Unpacker b)
-> (Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> b -> IO ())
-> IO ())
-> Unpacker b
forall a b. (a -> b) -> a -> b
$ \Addr#
start Addr#
end Word8 -> Bool
stop IO ()
fail Addr# -> b -> IO ()
eat
-> Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> a -> IO ())
-> IO ()
fx Addr#
start Addr#
end Word8 -> Bool
stop IO ()
fail ((Addr# -> a -> IO ()) -> IO ()) -> (Addr# -> a -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Addr#
start_x a
x
-> Addr# -> b -> IO ()
eat Addr#
start_x (a -> b
f a
x)
{-# INLINE fmap #-}
instance Applicative Unpacker where
pure :: forall a. a -> Unpacker a
pure a
x
= (Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> a -> IO ())
-> IO ())
-> Unpacker a
forall a.
(Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> a -> IO ())
-> IO ())
-> Unpacker a
Unpacker ((Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> a -> IO ())
-> IO ())
-> Unpacker a)
-> (Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> a -> IO ())
-> IO ())
-> Unpacker a
forall a b. (a -> b) -> a -> b
$ \Addr#
start Addr#
_end Word8 -> Bool
_fail IO ()
_stop Addr# -> a -> IO ()
eat
-> Addr# -> a -> IO ()
eat Addr#
start a
x
{-# INLINE pure #-}
<*> :: forall a b. Unpacker (a -> b) -> Unpacker a -> Unpacker b
(<*>) (Unpacker Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> (a -> b) -> IO ())
-> IO ()
ff) (Unpacker Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> a -> IO ())
-> IO ()
fx)
= (Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> b -> IO ())
-> IO ())
-> Unpacker b
forall a.
(Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> a -> IO ())
-> IO ())
-> Unpacker a
Unpacker ((Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> b -> IO ())
-> IO ())
-> Unpacker b)
-> (Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> b -> IO ())
-> IO ())
-> Unpacker b
forall a b. (a -> b) -> a -> b
$ \Addr#
start Addr#
end Word8 -> Bool
stop IO ()
fail Addr# -> b -> IO ()
eat
-> Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> (a -> b) -> IO ())
-> IO ()
ff Addr#
start Addr#
end Word8 -> Bool
stop IO ()
fail ((Addr# -> (a -> b) -> IO ()) -> IO ())
-> (Addr# -> (a -> b) -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Addr#
start_f a -> b
f
-> Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> a -> IO ())
-> IO ()
fx Addr#
start_f Addr#
end Word8 -> Bool
stop IO ()
fail ((Addr# -> a -> IO ()) -> IO ()) -> (Addr# -> a -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Addr#
start_x a
x
-> Addr# -> b -> IO ()
eat Addr#
start_x (a -> b
f a
x)
{-# INLINE (<*>) #-}
instance Monad Unpacker where
return :: forall a. a -> Unpacker a
return = a -> Unpacker a
forall a. a -> Unpacker a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
{-# INLINE return #-}
>>= :: forall a b. Unpacker a -> (a -> Unpacker b) -> Unpacker b
(>>=) (Unpacker Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> a -> IO ())
-> IO ()
fa) a -> Unpacker b
mkfb
= (Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> b -> IO ())
-> IO ())
-> Unpacker b
forall a.
(Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> a -> IO ())
-> IO ())
-> Unpacker a
Unpacker ((Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> b -> IO ())
-> IO ())
-> Unpacker b)
-> (Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> b -> IO ())
-> IO ())
-> Unpacker b
forall a b. (a -> b) -> a -> b
$ \Addr#
start Addr#
end Word8 -> Bool
stop IO ()
fail Addr# -> b -> IO ()
eat
-> Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> a -> IO ())
-> IO ()
fa Addr#
start Addr#
end Word8 -> Bool
stop IO ()
fail ((Addr# -> a -> IO ()) -> IO ()) -> (Addr# -> a -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Addr#
start_x a
x
-> case a -> Unpacker b
mkfb a
x of
Unpacker Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> b -> IO ())
-> IO ()
fb
-> Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> b -> IO ())
-> IO ()
fb Addr#
start_x Addr#
end Word8 -> Bool
stop IO ()
fail Addr# -> b -> IO ()
eat
{-# INLINE (>>=) #-}
unsafeRunUnpacker
:: Unpacker a
-> F.Ptr Word8
-> Int
-> (Word8 -> Bool)
-> IO (Maybe (a, F.Ptr Word8))
unsafeRunUnpacker :: forall a.
Unpacker a
-> Ptr Word8 -> Int -> (Word8 -> Bool) -> IO (Maybe (a, Ptr Word8))
unsafeRunUnpacker (Unpacker Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> a -> IO ())
-> IO ()
f) (Ptr Addr#
start) (I# Int#
len) Word8 -> Bool
stop
= do IORef (Maybe (a, Ptr Word8))
ref <- Maybe (a, Ptr Word8) -> IO (IORef (Maybe (a, Ptr Word8)))
forall a. a -> IO (IORef a)
newIORef Maybe (a, Ptr Word8)
forall a. Maybe a
Nothing
Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> a -> IO ())
-> IO ()
f Addr#
start
(Addr# -> Int# -> Addr#
plusAddr# Addr#
start Int#
len)
Word8 -> Bool
stop
(() -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ())
(\Addr#
addr' a
x -> IORef (Maybe (a, Ptr Word8)) -> Maybe (a, Ptr Word8) -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (Maybe (a, Ptr Word8))
ref ((a, Ptr Word8) -> Maybe (a, Ptr Word8)
forall a. a -> Maybe a
Just (a
x, (Addr# -> Ptr Word8
forall a. Addr# -> Ptr a
Ptr Addr#
addr'))))
IORef (Maybe (a, Ptr Word8)) -> IO (Maybe (a, Ptr Word8))
forall a. IORef a -> IO a
readIORef IORef (Maybe (a, Ptr Word8))
ref
{-# INLINE unsafeRunUnpacker #-}