{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE TypeApplications #-}
module Data.ByteString.Base64.Internal.Tail
( loopTail
, loopTailNoPad
) where
import Data.Bits
import Data.ByteString.Internal
import Data.ByteString.Base64.Internal.Utils
import Foreign.ForeignPtr
import Foreign.Ptr
import Foreign.Storable
import GHC.Exts
import GHC.Word
loopTail
:: ForeignPtr Word8
-> Ptr Word8
-> Ptr Word8
-> Ptr Word8
-> Ptr Word8
-> Ptr Word8
-> IO ByteString
loopTail :: ForeignPtr Word8
-> Ptr Word8
-> Ptr Word8
-> Ptr Word8
-> Ptr Word8
-> Ptr Word8
-> IO ByteString
loopTail !ForeignPtr Word8
dfp (Ptr !Addr#
alpha) !Ptr Word8
dptr !Ptr Word8
end !Ptr Word8
src !Ptr Word8
dst
| Ptr Word8
src forall a. Eq a => a -> a -> Bool
== Ptr Word8
end = forall (m :: * -> *) a. Monad m => a -> m a
return (ForeignPtr Word8 -> Int -> Int -> ByteString
PS ForeignPtr Word8
dfp Int
0 (forall a b. Ptr a -> Ptr b -> Int
minusPtr Ptr Word8
dst Ptr Word8
dptr))
| forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
src Int
1 forall a. Eq a => a -> a -> Bool
== Ptr Word8
end = do
!Word8
x <- forall a. Storable a => Ptr a -> IO a
peek @Word8 Ptr Word8
src
let !a :: Word8
a = forall a. Bits a => a -> Int -> a
unsafeShiftR (Word8
x forall a. Bits a => a -> a -> a
.&. Word8
0xfc) Int
2
!b :: Word8
b = forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8
x forall a. Bits a => a -> a -> a
.&. Word8
0x03) Int
4
forall a. Storable a => Ptr a -> a -> IO ()
poke @Word8 Ptr Word8
dst (Word8 -> Addr# -> Word8
aix Word8
a Addr#
alpha)
forall a. Storable a => Ptr a -> a -> IO ()
poke @Word8 (forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
dst Int
1) (Word8 -> Addr# -> Word8
aix Word8
b Addr#
alpha)
forall a. Storable a => Ptr a -> a -> IO ()
poke @Word8 (forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
dst Int
2) Word8
0x3d
forall a. Storable a => Ptr a -> a -> IO ()
poke @Word8 (forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
dst Int
3) Word8
0x3d
forall (m :: * -> *) a. Monad m => a -> m a
return (ForeignPtr Word8 -> Int -> Int -> ByteString
PS ForeignPtr Word8
dfp Int
0 (Int
4 forall a. Num a => a -> a -> a
+ forall a b. Ptr a -> Ptr b -> Int
minusPtr Ptr Word8
dst Ptr Word8
dptr))
| Bool
otherwise = do
!Word8
x <- forall a. Storable a => Ptr a -> IO a
peek @Word8 Ptr Word8
src
!Word8
y <- forall a. Storable a => Ptr a -> IO a
peek @Word8 (forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
src Int
1)
let !a :: Word8
a = forall a. Bits a => a -> Int -> a
unsafeShiftR (Word8
x forall a. Bits a => a -> a -> a
.&. Word8
0xfc) Int
2
!b :: Word8
b = forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8
x forall a. Bits a => a -> a -> a
.&. Word8
0x03) Int
4
let !c :: Word8
c = forall a. Bits a => a -> Int -> a
unsafeShiftR (Word8
y forall a. Bits a => a -> a -> a
.&. Word8
0xf0) Int
4 forall a. Bits a => a -> a -> a
.|. Word8
b
!d :: Word8
d = forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8
y forall a. Bits a => a -> a -> a
.&. Word8
0x0f) Int
2
forall a. Storable a => Ptr a -> a -> IO ()
poke @Word8 Ptr Word8
dst (Word8 -> Addr# -> Word8
aix Word8
a Addr#
alpha)
forall a. Storable a => Ptr a -> a -> IO ()
poke @Word8 (forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
dst Int
1) (Word8 -> Addr# -> Word8
aix Word8
c Addr#
alpha)
forall a. Storable a => Ptr a -> a -> IO ()
poke @Word8 (forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
dst Int
2) (Word8 -> Addr# -> Word8
aix Word8
d Addr#
alpha)
forall a. Storable a => Ptr a -> a -> IO ()
poke @Word8 (forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
dst Int
3) Word8
0x3d
forall (m :: * -> *) a. Monad m => a -> m a
return (ForeignPtr Word8 -> Int -> Int -> ByteString
PS ForeignPtr Word8
dfp Int
0 (Int
4 forall a. Num a => a -> a -> a
+ forall a b. Ptr a -> Ptr b -> Int
minusPtr Ptr Word8
dst Ptr Word8
dptr))
{-# inline loopTail #-}
loopTailNoPad
:: ForeignPtr Word8
-> Ptr Word8
-> Ptr Word8
-> Ptr Word8
-> Ptr Word8
-> Ptr Word8
-> IO ByteString
loopTailNoPad :: ForeignPtr Word8
-> Ptr Word8
-> Ptr Word8
-> Ptr Word8
-> Ptr Word8
-> Ptr Word8
-> IO ByteString
loopTailNoPad !ForeignPtr Word8
dfp (Ptr !Addr#
alpha) !Ptr Word8
dptr !Ptr Word8
end !Ptr Word8
src !Ptr Word8
dst
| Ptr Word8
src forall a. Eq a => a -> a -> Bool
== Ptr Word8
end = forall (m :: * -> *) a. Monad m => a -> m a
return (ForeignPtr Word8 -> Int -> Int -> ByteString
PS ForeignPtr Word8
dfp Int
0 (forall a b. Ptr a -> Ptr b -> Int
minusPtr Ptr Word8
dst Ptr Word8
dptr))
| forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
src Int
1 forall a. Eq a => a -> a -> Bool
== Ptr Word8
end = do
!Word8
x <- forall a. Storable a => Ptr a -> IO a
peek @Word8 Ptr Word8
src
let !a :: Word8
a = forall a. Bits a => a -> Int -> a
unsafeShiftR (Word8
x forall a. Bits a => a -> a -> a
.&. Word8
0xfc) Int
2
!b :: Word8
b = forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8
x forall a. Bits a => a -> a -> a
.&. Word8
0x03) Int
4
forall a. Storable a => Ptr a -> a -> IO ()
poke @Word8 Ptr Word8
dst (Word8 -> Addr# -> Word8
aix Word8
a Addr#
alpha)
forall a. Storable a => Ptr a -> a -> IO ()
poke @Word8 (forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
dst Int
1) (Word8 -> Addr# -> Word8
aix Word8
b Addr#
alpha)
forall (m :: * -> *) a. Monad m => a -> m a
return (ForeignPtr Word8 -> Int -> Int -> ByteString
PS ForeignPtr Word8
dfp Int
0 (Int
2 forall a. Num a => a -> a -> a
+ (forall a b. Ptr a -> Ptr b -> Int
minusPtr Ptr Word8
dst Ptr Word8
dptr)))
| Bool
otherwise = do
!Word8
x <- forall a. Storable a => Ptr a -> IO a
peek @Word8 Ptr Word8
src
!Word8
y <- forall a. Storable a => Ptr a -> IO a
peek @Word8 (forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
src Int
1)
let !a :: Word8
a = forall a. Bits a => a -> Int -> a
unsafeShiftR (Word8
x forall a. Bits a => a -> a -> a
.&. Word8
0xfc) Int
2
!b :: Word8
b = forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8
x forall a. Bits a => a -> a -> a
.&. Word8
0x03) Int
4
let !c :: Word8
c = forall a. Bits a => a -> Int -> a
unsafeShiftR (Word8
y forall a. Bits a => a -> a -> a
.&. Word8
0xf0) Int
4 forall a. Bits a => a -> a -> a
.|. Word8
b
!d :: Word8
d = forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8
y forall a. Bits a => a -> a -> a
.&. Word8
0x0f) Int
2
forall a. Storable a => Ptr a -> a -> IO ()
poke @Word8 Ptr Word8
dst (Word8 -> Addr# -> Word8
aix Word8
a Addr#
alpha)
forall a. Storable a => Ptr a -> a -> IO ()
poke @Word8 (forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
dst Int
1) (Word8 -> Addr# -> Word8
aix Word8
c Addr#
alpha)
forall a. Storable a => Ptr a -> a -> IO ()
poke @Word8 (forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
dst Int
2) (Word8 -> Addr# -> Word8
aix Word8
d Addr#
alpha)
forall (m :: * -> *) a. Monad m => a -> m a
return (ForeignPtr Word8 -> Int -> Int -> ByteString
PS ForeignPtr Word8
dfp Int
0 (Int
3 forall a. Num a => a -> a -> a
+ (forall a b. Ptr a -> Ptr b -> Int
minusPtr Ptr Word8
dst Ptr Word8
dptr)))
{-# inline loopTailNoPad #-}