{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE UnboxedTuples #-}
module Data.ByteString.Base16.Internal.Utils
( aix
, reChunk
, runShortST
, runDecodeST
) where
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
import Data.ByteString.Short.Internal
import Data.Primitive.ByteArray
import Data.Text (Text)
import GHC.Exts
import GHC.Word
import GHC.ST (ST(..))
aix :: Word8 -> Addr# -> Word8
aix (W8# i) alpha = W8# (indexWord8OffAddr# alpha (word2Int# i))
{-# INLINE aix #-}
reChunk :: [ByteString] -> [ByteString]
reChunk [] = []
reChunk (c:cs) = case B.length c `divMod` 2 of
(_, 0) -> c : reChunk cs
(n, _) -> case B.splitAt (n * 2) c of
~(m, q) -> m : cont_ q cs
where
cont_ q [] = [q]
cont_ q (a:as) = case B.splitAt 1 a of
~(x, y) -> let q' = B.append q x
in if B.length q' == 2
then
let as' = if B.null y then as else y:as
in q' : reChunk as'
else cont_ q' as
runShortST :: (forall s. ST s ByteArray) -> ShortByteString
runShortST enc = runRW# $ \s0 -> case enc of
{ ST g -> case g s0 of
{ (# _, ByteArray r #) -> SBS r
}
}
{-# INLINE runShortST #-}
runDecodeST
:: (forall s. ST s (Either Text ByteArray))
-> Either Text ShortByteString
runDecodeST dec = runRW# $ \s0 -> case dec of
{ ST g -> case g s0 of
{ (# _, e #) -> case e of
Left t -> Left t
Right (ByteArray r) -> Right (SBS r)
}
}
{-# INLINE runDecodeST #-}