{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE TypeApplications #-}
module Data.ByteString.Base32.Internal.Loop
( innerLoop
, decodeLoop
) where
import Data.Bits
import Data.ByteString.Internal (ByteString(..))
import Data.ByteString.Base32.Internal.Utils
import Data.Text (Text)
import qualified Data.Text as T
import Foreign.Ptr
import Foreign.ForeignPtr
import Foreign.Storable
import GHC.Exts
import GHC.Word
innerLoop
:: Addr#
-> Ptr Word64
-> Ptr Word8
-> Ptr Word8
-> (Ptr Word8 -> Ptr Word8 -> IO ByteString)
-> IO ByteString
innerLoop :: Addr#
-> Ptr Word64
-> Ptr Word8
-> Ptr Word8
-> (Ptr Word8 -> Ptr Word8 -> IO ByteString)
-> IO ByteString
innerLoop !Addr#
lut !Ptr Word64
dptr !Ptr Word8
sptr !Ptr Word8
end Ptr Word8 -> Ptr Word8 -> IO ByteString
finish = Ptr Word64 -> Ptr Word8 -> IO ByteString
go Ptr Word64
dptr Ptr Word8
sptr
where
lix :: a -> Word64
lix a
a = Word8 -> Word64
w64 (Word8 -> Addr# -> Word8
aix (a -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
a Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0x1f) Addr#
lut)
{-# INLINE lix #-}
go :: Ptr Word64 -> Ptr Word8 -> IO ByteString
go !Ptr Word64
dst !Ptr Word8
src
| Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
src Int
4 Ptr Word8 -> Ptr Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Ptr Word8
end = Ptr Word8 -> Ptr Word8 -> IO ByteString
finish (Ptr Word64 -> Ptr Word8
forall a b. Ptr a -> Ptr b
castPtr Ptr Word64
dst) Ptr Word8
src
| Bool
otherwise = do
!Word32
t <- Ptr Word32 -> IO Word32
peekWord32BE (Ptr Word8 -> Ptr Word32
forall a b. Ptr a -> Ptr b
castPtr Ptr Word8
src)
!Word32
u <- Word8 -> Word32
w32 (Word8 -> Word32) -> IO Word8 -> IO Word32
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr Word8 -> IO Word8
forall a. Storable a => Ptr a -> IO a
peek (Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
src Int
4)
let !a :: Word64
a = Word32 -> Word64
forall a. Integral a => a -> Word64
lix (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
unsafeShiftR Word32
t Int
27)
!b :: Word64
b = Word32 -> Word64
forall a. Integral a => a -> Word64
lix (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
unsafeShiftR Word32
t Int
22)
!c :: Word64
c = Word32 -> Word64
forall a. Integral a => a -> Word64
lix (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
unsafeShiftR Word32
t Int
17)
!d :: Word64
d = Word32 -> Word64
forall a. Integral a => a -> Word64
lix (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
unsafeShiftR Word32
t Int
12)
!e :: Word64
e = Word32 -> Word64
forall a. Integral a => a -> Word64
lix (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
unsafeShiftR Word32
t Int
7)
!f :: Word64
f = Word32 -> Word64
forall a. Integral a => a -> Word64
lix (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
unsafeShiftR Word32
t Int
2)
!g :: Word64
g = Word32 -> Word64
forall a. Integral a => a -> Word64
lix ((Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
unsafeShiftL Word32
t Int
3) Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
unsafeShiftR Word32
u Int
5))
!h :: Word64
h = Word32 -> Word64
forall a. Integral a => a -> Word64
lix Word32
u
let !w :: Word64
w = Word64
a
Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL Word64
b Int
8)
Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL Word64
c Int
16)
Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL Word64
d Int
24)
Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL Word64
e Int
32)
Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL Word64
f Int
40)
Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL Word64
g Int
48)
Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL Word64
h Int
56)
Ptr Word64 -> Word64 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr Word64
dst Word64
w
Ptr Word64 -> Ptr Word8 -> IO ByteString
go (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
dst Int
8) (Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
src Int
5)
{-# INLINE innerLoop #-}
decodeLoop
:: Addr#
-> ForeignPtr Word8
-> Ptr Word8
-> Ptr Word64
-> Ptr Word8
-> IO (Either Text ByteString)
decodeLoop :: Addr#
-> ForeignPtr Word8
-> Ptr Word8
-> Ptr Word64
-> Ptr Word8
-> IO (Either Text ByteString)
decodeLoop !Addr#
lut !ForeignPtr Word8
dfp !Ptr Word8
dptr !Ptr Word64
sptr !Ptr Word8
end = Ptr Word8 -> Ptr Word64 -> IO (Either Text ByteString)
go Ptr Word8
dptr Ptr Word64
sptr
where
lix :: a -> Word64
lix a
a = Word8 -> Word64
w64 (Word8 -> Addr# -> Word8
aix (a -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
a) Addr#
lut)
err :: Ptr Word64 -> IO (Either Text ByteString)
err :: Ptr Word64 -> IO (Either Text ByteString)
err Ptr Word64
p = Either Text ByteString -> IO (Either Text ByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Text ByteString -> IO (Either Text ByteString))
-> (String -> Either Text ByteString)
-> String
-> IO (Either Text ByteString)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either Text ByteString
forall a b. a -> Either a b
Left (Text -> Either Text ByteString)
-> (String -> Text) -> String -> Either Text ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack
(String -> IO (Either Text ByteString))
-> String -> IO (Either Text ByteString)
forall a b. (a -> b) -> a -> b
$ String
"invalid character at offset: "
String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Ptr Word64
p Ptr Word64 -> Ptr Word64 -> Int
forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr Word64
sptr)
padErr :: Ptr Word64 -> IO (Either Text ByteString)
padErr :: Ptr Word64 -> IO (Either Text ByteString)
padErr Ptr Word64
p = Either Text ByteString -> IO (Either Text ByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Text ByteString -> IO (Either Text ByteString))
-> (String -> Either Text ByteString)
-> String
-> IO (Either Text ByteString)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either Text ByteString
forall a b. a -> Either a b
Left (Text -> Either Text ByteString)
-> (String -> Text) -> String -> Either Text ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack
(String -> IO (Either Text ByteString))
-> String -> IO (Either Text ByteString)
forall a b. (a -> b) -> a -> b
$ String
"invalid padding at offset: "
String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Ptr Word64
p Ptr Word64 -> Ptr Word64 -> Int
forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr Word64
sptr)
look :: Ptr Word8 -> IO Word64
look :: Ptr Word8 -> IO Word64
look !Ptr Word8
p = Word64 -> Word64
forall a. Integral a => a -> Word64
lix (Word64 -> Word64) -> (Word8 -> Word64) -> Word8 -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Word64
w64 (Word8 -> Word64) -> IO Word8 -> IO Word64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr Word8 -> IO Word8
forall a. Storable a => Ptr a -> IO a
peek @Word8 Ptr Word8
p
go :: Ptr Word8 -> Ptr Word64 -> IO (Either Text ByteString)
go !Ptr Word8
dst !Ptr Word64
src
| Ptr Word64 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
8 Ptr Word8 -> Ptr Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Ptr Word8
end = do
let src' :: Ptr b
src' = Ptr Word64 -> Ptr b
forall a b. Ptr a -> Ptr b
castPtr Ptr Word64
src
Word64
a <- Ptr Word8 -> IO Word64
look Ptr Word8
forall b. Ptr b
src'
Word64
b <- Ptr Word8 -> IO Word64
look (Ptr Any -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Any
forall b. Ptr b
src' Int
1)
Word64
c <- Ptr Word8 -> IO Word64
look (Ptr Any -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Any
forall b. Ptr b
src' Int
2)
Word64
d <- Ptr Word8 -> IO Word64
look (Ptr Any -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Any
forall b. Ptr b
src' Int
3)
Word64
e <- Ptr Word8 -> IO Word64
look (Ptr Any -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Any
forall b. Ptr b
src' Int
4)
Word64
f <- Ptr Word8 -> IO Word64
look (Ptr Any -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Any
forall b. Ptr b
src' Int
5)
Word64
g <- Ptr Word8 -> IO Word64
look (Ptr Any -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Any
forall b. Ptr b
src' Int
6)
Word64
h <- Ptr Word8 -> IO Word64
look (Ptr Any -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Any
forall b. Ptr b
src' Int
7)
Ptr Word8
-> Ptr Word64
-> Word64
-> Word64
-> Word64
-> Word64
-> Word64
-> Word64
-> Word64
-> Word64
-> IO (Either Text ByteString)
forall a a a a a a a a.
(Integral a, Integral a, Integral a, Integral a, Integral a,
Integral a, Integral a, Integral a) =>
Ptr Word8
-> Ptr Word64
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> IO (Either Text ByteString)
finalChunk Ptr Word8
dst Ptr Word64
src Word64
a Word64
b Word64
c Word64
d Word64
e Word64
f Word64
g Word64
h
| Bool
otherwise = do
!Word64
t <- Ptr Word64 -> IO Word64
peekWord64BE Ptr Word64
src
let a :: Word64
a = Word64 -> Word64
forall a. Integral a => a -> Word64
lix (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
t Int
56)
b :: Word64
b = Word64 -> Word64
forall a. Integral a => a -> Word64
lix (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
t Int
48)
c :: Word64
c = Word64 -> Word64
forall a. Integral a => a -> Word64
lix (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
t Int
40)
d :: Word64
d = Word64 -> Word64
forall a. Integral a => a -> Word64
lix (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
t Int
32)
e :: Word64
e = Word64 -> Word64
forall a. Integral a => a -> Word64
lix (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
t Int
24)
f :: Word64
f = Word64 -> Word64
forall a. Integral a => a -> Word64
lix (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
t Int
16)
g :: Word64
g = Word64 -> Word64
forall a. Integral a => a -> Word64
lix (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
t Int
8)
h :: Word64
h = Word64 -> Word64
forall a. Integral a => a -> Word64
lix Word64
t
Ptr Word8
-> Ptr Word64
-> Word64
-> Word64
-> Word64
-> Word64
-> Word64
-> Word64
-> Word64
-> Word64
-> IO (Either Text ByteString)
decodeChunk Ptr Word8
dst Ptr Word64
src Word64
a Word64
b Word64
c Word64
d Word64
e Word64
f Word64
g Word64
h
finalChunk :: Ptr Word8
-> Ptr Word64
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> IO (Either Text ByteString)
finalChunk !Ptr Word8
dst !Ptr Word64
src !a
a !a
b !a
c !a
d !a
e !a
f !a
g !a
h
| a
a a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0x63 = Ptr Word64 -> IO (Either Text ByteString)
padErr Ptr Word64
src
| a
b a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0x63 = Ptr Word64 -> IO (Either Text ByteString)
padErr (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
1)
| a
a a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0xff = Ptr Word64 -> IO (Either Text ByteString)
err Ptr Word64
src
| a
b a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0xff = Ptr Word64 -> IO (Either Text ByteString)
err (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
1)
| a
c a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0xff = Ptr Word64 -> IO (Either Text ByteString)
err (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
2)
| a
d a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0xff = Ptr Word64 -> IO (Either Text ByteString)
err (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
3)
| a
e a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0xff = Ptr Word64 -> IO (Either Text ByteString)
err (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
4)
| a
f a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0xff = Ptr Word64 -> IO (Either Text ByteString)
err (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
5)
| a
g a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0xff = Ptr Word64 -> IO (Either Text ByteString)
err (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
6)
| a
h a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0xff = Ptr Word64 -> IO (Either Text ByteString)
err (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
7)
| Bool
otherwise = do
let !o1 :: Word8
o1 = (a -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
a Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
3) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.|. (a -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
b Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
2)
!o2 :: Word8
o2 = (a -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
b Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
6)
Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.|. (a -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
c Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
1)
Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.|. (a -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
d Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
4)
!o3 :: Word8
o3 = (a -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
d Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
4) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.|. (a -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
e Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
1)
!o4 :: Word8
o4 = (a -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
e Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
7)
Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.|. (a -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
f Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
2)
Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.|. (a -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
g Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
3)
!o5 :: Word8
o5 = (a -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
g Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
5) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.|. a -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
h
Ptr Word8 -> Word8 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke @Word8 Ptr Word8
dst Word8
o1
Ptr Word8 -> Word8 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke @Word8 (Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
dst Int
1) Word8
o2
case (a
c,a
d,a
e,a
f,a
g,a
h) of
(a
0x63,a
0x63,a
0x63,a
0x63,a
0x63,a
0x63) ->
Either Text ByteString -> IO (Either Text ByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> Either Text ByteString
forall a b. b -> Either a b
Right (ForeignPtr Word8 -> Int -> Int -> ByteString
PS ForeignPtr Word8
dfp Int
0 (Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Ptr Word8 -> Ptr Word8 -> Int
forall a b. Ptr a -> Ptr b -> Int
minusPtr Ptr Word8
dst Ptr Word8
dptr)))
(a
0x63,a
_,a
_,a
_,a
_,a
_) -> Ptr Word64 -> IO (Either Text ByteString)
padErr (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
3)
(a
_,a
0x63,a
0x63,a
0x63,a
0x63,a
0x63) -> Ptr Word64 -> IO (Either Text ByteString)
padErr (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
3)
(a
_,a
0x63,a
_,a
_,a
_,a
_) -> Ptr Word64 -> IO (Either Text ByteString)
padErr (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
4)
(a
_,a
_,a
0x63,a
0x63,a
0x63,a
0x63) -> do
Ptr Word8 -> Word8 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke @Word8 (Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
dst Int
2) Word8
o3
Either Text ByteString -> IO (Either Text ByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> Either Text ByteString
forall a b. b -> Either a b
Right (ForeignPtr Word8 -> Int -> Int -> ByteString
PS ForeignPtr Word8
dfp Int
0 (Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Ptr Word8 -> Ptr Word8 -> Int
forall a b. Ptr a -> Ptr b -> Int
minusPtr Ptr Word8
dst Ptr Word8
dptr)))
(a
_,a
_,a
0x63,a
_,a
_,a
_) -> Ptr Word64 -> IO (Either Text ByteString)
padErr (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
5)
(a
_,a
_,a
_,a
0x63,a
0x63,a
0x63) -> do
Ptr Word8 -> Word8 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke @Word8 (Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
dst Int
2) Word8
o3
Ptr Word8 -> Word8 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke @Word8 (Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
dst Int
3) Word8
o4
Either Text ByteString -> IO (Either Text ByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> Either Text ByteString
forall a b. b -> Either a b
Right (ForeignPtr Word8 -> Int -> Int -> ByteString
PS ForeignPtr Word8
dfp Int
0 (Int
3 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Ptr Word8 -> Ptr Word8 -> Int
forall a b. Ptr a -> Ptr b -> Int
minusPtr Ptr Word8
dst Ptr Word8
dptr)))
(a
_,a
_,a
_,a
0x63,a
_,a
_) -> Ptr Word64 -> IO (Either Text ByteString)
padErr (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
6)
(a
_,a
_,a
_,a
_,a
0x63,a
0x63) -> Ptr Word64 -> IO (Either Text ByteString)
padErr (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
6)
(a
_,a
_,a
_,a
_,a
0x63,a
_) -> Ptr Word64 -> IO (Either Text ByteString)
padErr (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
7)
(a
_,a
_,a
_,a
_,a
_,a
0x63) -> do
Ptr Word8 -> Word8 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke @Word8 (Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
dst Int
2) Word8
o3
Ptr Word8 -> Word8 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke @Word8 (Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
dst Int
3) Word8
o4
Ptr Word8 -> Word8 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke @Word8 (Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
dst Int
4) Word8
o5
Either Text ByteString -> IO (Either Text ByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> Either Text ByteString
forall a b. b -> Either a b
Right (ForeignPtr Word8 -> Int -> Int -> ByteString
PS ForeignPtr Word8
dfp Int
0 (Int
4 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Ptr Word8 -> Ptr Word8 -> Int
forall a b. Ptr a -> Ptr b -> Int
minusPtr Ptr Word8
dst Ptr Word8
dptr)))
(a
_,a
_,a
_,a
_,a
_,a
_) -> do
Ptr Word8 -> Word8 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke @Word8 (Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
dst Int
2) Word8
o3
Ptr Word8 -> Word8 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke @Word8 (Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
dst Int
3) Word8
o4
Ptr Word8 -> Word8 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke @Word8 (Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
dst Int
4) Word8
o5
Either Text ByteString -> IO (Either Text ByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> Either Text ByteString
forall a b. b -> Either a b
Right (ForeignPtr Word8 -> Int -> Int -> ByteString
PS ForeignPtr Word8
dfp Int
0 (Int
5 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Ptr Word8 -> Ptr Word8 -> Int
forall a b. Ptr a -> Ptr b -> Int
minusPtr Ptr Word8
dst Ptr Word8
dptr)))
decodeChunk :: Ptr Word8
-> Ptr Word64
-> Word64
-> Word64
-> Word64
-> Word64
-> Word64
-> Word64
-> Word64
-> Word64
-> IO (Either Text ByteString)
decodeChunk !Ptr Word8
dst !Ptr Word64
src !Word64
a !Word64
b !Word64
c !Word64
d !Word64
e !Word64
f !Word64
g !Word64
h
| Word64
a Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0x63 = Ptr Word64 -> IO (Either Text ByteString)
padErr Ptr Word64
src
| Word64
b Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0x63 = Ptr Word64 -> IO (Either Text ByteString)
padErr (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
1)
| Word64
c Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0x63 = Ptr Word64 -> IO (Either Text ByteString)
padErr (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
2)
| Word64
d Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0x63 = Ptr Word64 -> IO (Either Text ByteString)
padErr (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
3)
| Word64
e Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0x63 = Ptr Word64 -> IO (Either Text ByteString)
padErr (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
4)
| Word64
f Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0x63 = Ptr Word64 -> IO (Either Text ByteString)
padErr (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
5)
| Word64
g Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0x63 = Ptr Word64 -> IO (Either Text ByteString)
padErr (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
6)
| Word64
h Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0x63 = Ptr Word64 -> IO (Either Text ByteString)
padErr (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
7)
| Word64
a Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0xff = Ptr Word64 -> IO (Either Text ByteString)
err Ptr Word64
src
| Word64
b Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0xff = Ptr Word64 -> IO (Either Text ByteString)
err (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
1)
| Word64
c Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0xff = Ptr Word64 -> IO (Either Text ByteString)
err (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
2)
| Word64
d Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0xff = Ptr Word64 -> IO (Either Text ByteString)
err (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
3)
| Word64
e Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0xff = Ptr Word64 -> IO (Either Text ByteString)
err (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
4)
| Word64
f Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0xff = Ptr Word64 -> IO (Either Text ByteString)
err (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
5)
| Word64
g Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0xff = Ptr Word64 -> IO (Either Text ByteString)
err (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
6)
| Word64
h Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0xff = Ptr Word64 -> IO (Either Text ByteString)
err (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
7)
| Bool
otherwise = do
let !w :: Word64
w = ((Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL Word64
a Int
35)
Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL Word64
b Int
30)
Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL Word64
c Int
25)
Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL Word64
d Int
20)
Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL Word64
e Int
15)
Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL Word64
f Int
10)
Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL Word64
g Int
5)
Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64
h) :: Word64
Ptr Word32 -> Word32 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke @Word32 (Ptr Word8 -> Ptr Word32
forall a b. Ptr a -> Ptr b
castPtr Ptr Word8
dst) (Word32 -> Word32
byteSwap32 (Word64 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
w Int
8)))
Ptr Word8 -> Word8 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke @Word8 (Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
dst Int
4) (Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
w)
Ptr Word8 -> Ptr Word64 -> IO (Either Text ByteString)
go (Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
dst Int
5) (Ptr Word64 -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word64
src Int
8)