-- |
-- Sketches of new module, which implements the poking actions.
module Ptr.PokeIO where

import qualified Ptr.IO as IO
import Ptr.Prelude

type PokeIO =
  Ptr Word8 -> IO ()

{-# INLINE sequentially #-}
sequentially :: Int -> PokeIO -> PokeIO -> PokeIO
sequentially :: Int -> PokeIO -> PokeIO -> PokeIO
sequentially Int
space1 PokeIO
action1 PokeIO
action2 Ptr Word8
ptr =
  PokeIO
action1 Ptr Word8
ptr IO () -> IO () -> IO ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> PokeIO
action2 (Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
ptr Int
space1)

{-# INLINE concurrently #-}
concurrently :: Int -> PokeIO -> PokeIO -> PokeIO
concurrently :: Int -> PokeIO -> PokeIO -> PokeIO
concurrently Int
space1 PokeIO
action1 PokeIO
action2 Ptr Word8
ptr =
  do
    MVar ()
lock <- IO (MVar ())
forall a. IO (MVar a)
newEmptyMVar
    IO () -> IO ThreadId
forkIO (IO () -> IO ThreadId) -> IO () -> IO ThreadId
forall a b. (a -> b) -> a -> b
$ do
      PokeIO
action1 Ptr Word8
ptr
      MVar () -> () -> IO ()
forall a. MVar a -> a -> IO ()
putMVar MVar ()
lock ()
    PokeIO
action2 (Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
ptr Int
space1)
    MVar () -> IO ()
forall a. MVar a -> IO a
takeMVar MVar ()
lock

-- | Unsigned ASCII integral
{-# INLINE asciiUnsignedIntegral #-}
asciiUnsignedIntegral :: (Integral a) => Int -> a -> PokeIO
asciiUnsignedIntegral :: Int -> a -> PokeIO
asciiUnsignedIntegral =
  let loop :: Ptr Word8 -> t -> IO ()
loop Ptr Word8
ptr t
x = case t -> t -> (t, t)
forall a. Integral a => a -> a -> (a, a)
quotRem t
x t
10 of
        (t
quot, t
rem) -> do
          Ptr Word8 -> Word8 -> IO ()
IO.pokeWord8 Ptr Word8
ptr (Word8
48 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ t -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral t
rem)
          case t
quot of
            t
0 -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
            t
_ -> Ptr Word8 -> t -> IO ()
loop (Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
ptr (-Int
1)) t
quot
   in \Int
lastIndex a
x Ptr Word8
ptr -> Ptr Word8 -> a -> IO ()
forall t. Integral t => Ptr Word8 -> t -> IO ()
loop (Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
ptr Int
lastIndex) a
x

{-# INLINE reverseAsciiDigits #-}
reverseAsciiDigits :: (Integral a) => Int -> [a] -> PokeIO
reverseAsciiDigits :: Int -> [a] -> PokeIO
reverseAsciiDigits Int
index [a]
elements Ptr Word8
ptr =
  let loop :: Ptr Word8 -> [a] -> IO ()
loop Ptr Word8
ptr =
        \case
          a
digit : [a]
tail -> do
            Ptr Word8 -> Word8 -> IO ()
IO.pokeWord8 Ptr Word8
ptr (Word8
48 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ a -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
digit)
            Ptr Word8 -> [a] -> IO ()
loop (Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
ptr (-Int
1)) [a]
tail
          [a]
_ -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
   in Ptr Word8 -> [a] -> IO ()
forall a. Integral a => Ptr Word8 -> [a] -> IO ()
loop (Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
ptr Int
index) [a]
elements