{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE OverloadedStrings #-}
module Data.ByteString.Base32.Internal.Head
( encodeBase32_
, encodeBase32NoPad_
, decodeBase32_
) where
import Data.ByteString.Internal
import Data.ByteString.Base32.Internal.Loop
import Data.ByteString.Base32.Internal.Tail
import Data.ByteString.Base32.Internal.Utils
import Data.Text (Text)
import Foreign.Ptr
import Foreign.ForeignPtr
import GHC.Exts
import GHC.ForeignPtr
import GHC.Word
import System.IO.Unsafe
encodeBase32_ :: Addr# -> ByteString -> ByteString
encodeBase32_ !lut (PS !sfp !o !l) =
unsafeDupablePerformIO $ do
dfp <- mallocPlainForeignPtrBytes dlen
withForeignPtr dfp $ \dptr ->
withForeignPtr sfp $ \sptr -> do
let !end = plusPtr sptr (l + o)
innerLoop
lut
(castPtr dptr)
(plusPtr sptr o)
end
(loopTail lut dfp dptr end)
where
!q = (l * 8) `quot` 5
!r = (l * 8) `rem` 5
!dlen = padCeilN 8 (q + if r == 0 then 0 else 1)
encodeBase32NoPad_ :: Addr# -> ByteString -> ByteString
encodeBase32NoPad_ !lut (PS !sfp !o !l) =
unsafeDupablePerformIO $ do
!dfp <- mallocPlainForeignPtrBytes dlen
withForeignPtr dfp $ \dptr ->
withForeignPtr sfp $ \sptr -> do
let !end = plusPtr sptr (l + o)
innerLoop lut
(castPtr dptr)
(plusPtr sptr o)
end
(loopTailNoPad lut dfp dptr end)
where
!q = (l * 8) `quot` 5
!r = (l * 8) `rem` 5
!dlen = padCeilN 8 (q + if r == 0 then 0 else 1)
decodeBase32_ :: Int -> ForeignPtr Word8 -> ByteString -> IO (Either Text ByteString)
decodeBase32_ !dlen !dtfp (PS !sfp !soff !slen) =
withForeignPtr dtfp $ \(Ptr dtable) ->
withForeignPtr sfp $ \sptr -> do
dfp <- mallocPlainForeignPtrBytes dlen
withForeignPtr dfp $ \dptr -> do
let !end = plusPtr sptr (soff + slen)
decodeLoop dtable dfp dptr (plusPtr sptr soff) end