{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE Rank2Types #-}
module Data.Memory.Encoding.Base32
( toBase32
, unBase32Length
, fromBase32
) where
import Data.Memory.Internal.Compat
import Data.Memory.Internal.CompatPrim
import Data.Word
import Data.Bits ((.|.))
import GHC.Prim
import GHC.Word
import Control.Monad
import Foreign.Storable
import Foreign.Ptr (Ptr)
toBase32 :: Ptr Word8
-> Ptr Word8
-> Int
-> IO ()
toBase32 :: Ptr Word8 -> Ptr Word8 -> Int -> IO ()
toBase32 dst :: Ptr Word8
dst src :: Ptr Word8
src len :: Int
len = Int -> Int -> IO ()
loop 0 0
where
eqChar :: Word8
eqChar :: Word8
eqChar = 0x3d
peekOrZero :: Int -> IO Word8
peekOrZero :: Int -> IO Word8
peekOrZero i :: Int
i
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
len = Word8 -> IO Word8
forall (m :: * -> *) a. Monad m => a -> m a
return 0
| Bool
otherwise = Ptr Word8 -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Word8
src Int
i
pokeOrPadding :: Int
-> Int
-> Word8
-> IO ()
pokeOrPadding :: Int -> Int -> Word8 -> IO ()
pokeOrPadding i :: Int
i di :: Int
di v :: Word8
v
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
len = Ptr Word8 -> Int -> Word8 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr Word8
dst Int
di Word8
v
| Bool
otherwise = Ptr Word8 -> Int -> Word8 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr Word8
dst Int
di Word8
eqChar
loop :: Int
-> Int
-> IO ()
loop :: Int -> Int -> IO ()
loop i :: Int
i di :: Int
di
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
len = () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise = do
Word8
i1 <- Ptr Word8 -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Word8
src Int
i
Word8
i2 <- Int -> IO Word8
peekOrZero (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1)
Word8
i3 <- Int -> IO Word8
peekOrZero (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 2)
Word8
i4 <- Int -> IO Word8
peekOrZero (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 3)
Word8
i5 <- Int -> IO Word8
peekOrZero (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 4)
let (o1 :: Word8
o1,o2 :: Word8
o2,o3 :: Word8
o3,o4 :: Word8
o4,o5 :: Word8
o5,o6 :: Word8
o6,o7 :: Word8
o7,o8 :: Word8
o8) = (Word8, Word8, Word8, Word8, Word8)
-> (Word8, Word8, Word8, Word8, Word8, Word8, Word8, Word8)
toBase32Per5Bytes (Word8
i1, Word8
i2, Word8
i3, Word8
i4, Word8
i5)
Ptr Word8 -> Int -> Word8 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr Word8
dst Int
di Word8
o1
Ptr Word8 -> Int -> Word8 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr Word8
dst (Int
di Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) Word8
o2
Int -> Int -> Word8 -> IO ()
pokeOrPadding (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) (Int
di Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 2) Word8
o3
Int -> Int -> Word8 -> IO ()
pokeOrPadding (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) (Int
di Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 3) Word8
o4
Int -> Int -> Word8 -> IO ()
pokeOrPadding (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 2) (Int
di Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 4) Word8
o5
Int -> Int -> Word8 -> IO ()
pokeOrPadding (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 3) (Int
di Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 5) Word8
o6
Int -> Int -> Word8 -> IO ()
pokeOrPadding (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 3) (Int
di Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 6) Word8
o7
Int -> Int -> Word8 -> IO ()
pokeOrPadding (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 4) (Int
di Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 7) Word8
o8
Int -> Int -> IO ()
loop (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+5) (Int
diInt -> Int -> Int
forall a. Num a => a -> a -> a
+8)
toBase32Per5Bytes :: (Word8, Word8, Word8, Word8, Word8)
-> (Word8, Word8, Word8, Word8, Word8, Word8, Word8, Word8)
toBase32Per5Bytes :: (Word8, Word8, Word8, Word8, Word8)
-> (Word8, Word8, Word8, Word8, Word8, Word8, Word8, Word8)
toBase32Per5Bytes (W8# i1 :: Word#
i1, W8# i2 :: Word#
i2, W8# i3 :: Word#
i3, W8# i4 :: Word#
i4, W8# i5 :: Word#
i5) =
(Word# -> Word8
index Word#
o1, Word# -> Word8
index Word#
o2, Word# -> Word8
index Word#
o3, Word# -> Word8
index Word#
o4, Word# -> Word8
index Word#
o5, Word# -> Word8
index Word#
o6, Word# -> Word8
index Word#
o7, Word# -> Word8
index Word#
o8)
where
!o1 :: Word#
o1 = (Word# -> Int# -> Word#
uncheckedShiftRL# (Word# -> Word# -> Word#
and# Word#
i1 0xF8##) 3#)
!o2 :: Word#
o2 = Word# -> Word# -> Word#
or# (Word# -> Int# -> Word#
uncheckedShiftL# (Word# -> Word# -> Word#
and# Word#
i1 0x07##) 2#) (Word# -> Int# -> Word#
uncheckedShiftRL# (Word# -> Word# -> Word#
and# Word#
i2 0xC0##) 6#)
!o3 :: Word#
o3 = (Word# -> Int# -> Word#
uncheckedShiftRL# (Word# -> Word# -> Word#
and# Word#
i2 0x3E##) 1#)
!o4 :: Word#
o4 = Word# -> Word# -> Word#
or# (Word# -> Int# -> Word#
uncheckedShiftL# (Word# -> Word# -> Word#
and# Word#
i2 0x01##) 4#) (Word# -> Int# -> Word#
uncheckedShiftRL# (Word# -> Word# -> Word#
and# Word#
i3 0xF0##) 4#)
!o5 :: Word#
o5 = Word# -> Word# -> Word#
or# (Word# -> Int# -> Word#
uncheckedShiftL# (Word# -> Word# -> Word#
and# Word#
i3 0x0F##) 1#) (Word# -> Int# -> Word#
uncheckedShiftRL# (Word# -> Word# -> Word#
and# Word#
i4 0x80##) 7#)
!o6 :: Word#
o6 = (Word# -> Int# -> Word#
uncheckedShiftRL# (Word# -> Word# -> Word#
and# Word#
i4 0x7C##) 2#)
!o7 :: Word#
o7 = Word# -> Word# -> Word#
or# (Word# -> Int# -> Word#
uncheckedShiftL# (Word# -> Word# -> Word#
and# Word#
i4 0x03##) 3#) (Word# -> Int# -> Word#
uncheckedShiftRL# (Word# -> Word# -> Word#
and# Word#
i5 0xE0##) 5#)
!o8 :: Word#
o8 = ((Word# -> Word# -> Word#
and# Word#
i5 0x1F##))
!set :: Addr#
set = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"#
index :: Word# -> Word8
index :: Word# -> Word8
index idx :: Word#
idx = Word# -> Word8
W8# (Addr# -> Int# -> Word#
indexWord8OffAddr# Addr#
set (Word# -> Int#
word2Int# Word#
idx))
unBase32Length :: Ptr Word8 -> Int -> IO (Maybe Int)
unBase32Length :: Ptr Word8 -> Int -> IO (Maybe Int)
unBase32Length src :: Ptr Word8
src len :: Int
len
| Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 1 = Maybe Int -> IO (Maybe Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Int -> IO (Maybe Int)) -> Maybe Int -> IO (Maybe Int)
forall a b. (a -> b) -> a -> b
$ Int -> Maybe Int
forall a. a -> Maybe a
Just 0
| (Int
len Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` 8) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= 0 = Maybe Int -> IO (Maybe Int)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Int
forall a. Maybe a
Nothing
| Bool
otherwise = do
Word8
last1Byte <- Ptr Word8 -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Word8
src (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1)
Word8
last2Byte <- Ptr Word8 -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Word8
src (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- 2)
Word8
last3Byte <- Ptr Word8 -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Word8
src (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- 3)
Word8
last4Byte <- Ptr Word8 -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Word8
src (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- 4)
Word8
last5Byte <- Ptr Word8 -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Word8
src (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- 5)
Word8
last6Byte <- Ptr Word8 -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Word8
src (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- 6)
let dstLen :: Int
dstLen = Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Int
caseByte Word8
last1Byte Word8
last2Byte Word8
last3Byte Word8
last4Byte Word8
last5Byte Word8
last6Byte
Maybe Int -> IO (Maybe Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Int -> IO (Maybe Int)) -> Maybe Int -> IO (Maybe Int)
forall a b. (a -> b) -> a -> b
$ Int -> Maybe Int
forall a. a -> Maybe a
Just (Int -> Maybe Int) -> Int -> Maybe Int
forall a b. (a -> b) -> a -> b
$ (Int
len Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` 8) Int -> Int -> Int
forall a. Num a => a -> a -> a
* 5 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
dstLen
where
caseByte :: Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Int
caseByte :: Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Int
caseByte last1 :: Word8
last1 last2 :: Word8
last2 last3 :: Word8
last3 last4 :: Word8
last4 last5 :: Word8
last5 last6 :: Word8
last6
| Word8
last6 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
eqAscii = 4
| Word8
last5 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
eqAscii = 3
| Word8
last4 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
eqAscii = 3
| Word8
last3 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
eqAscii = 2
| Word8
last2 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
eqAscii = 1
| Word8
last1 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
eqAscii = 1
| Bool
otherwise = 0
eqAscii :: Word8
eqAscii :: Word8
eqAscii = 0x3D
fromBase32 :: Ptr Word8 -> Ptr Word8 -> Int -> IO (Maybe Int)
fromBase32 :: Ptr Word8 -> Ptr Word8 -> Int -> IO (Maybe Int)
fromBase32 dst :: Ptr Word8
dst src :: Ptr Word8
src len :: Int
len
| Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 0 = Maybe Int -> IO (Maybe Int)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Int
forall a. Maybe a
Nothing
| Bool
otherwise = Int -> Int -> IO (Maybe Int)
loop 0 0
where
loop :: Int
-> Int
-> IO (Maybe Int)
loop :: Int -> Int -> IO (Maybe Int)
loop di :: Int
di i :: Int
i
| Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- 8) = do
Word8
i1 <- Ptr Word8 -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Word8
src Int
i
Word8
i2 <- Ptr Word8 -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Word8
src (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1)
Word8
i3 <- Ptr Word8 -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Word8
src (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 2)
Word8
i4 <- Ptr Word8 -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Word8
src (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 3)
Word8
i5 <- Ptr Word8 -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Word8
src (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 4)
Word8
i6 <- Ptr Word8 -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Word8
src (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 5)
Word8
i7 <- Ptr Word8 -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Word8
src (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 6)
Word8
i8 <- Ptr Word8 -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Word8
src (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 7)
let (nbBytes :: Int
nbBytes, i3' :: Word8
i3', i4' :: Word8
i4', i5' :: Word8
i5', i6' :: Word8
i6', i7' :: Word8
i7', i8' :: Word8
i8') =
case (Word8
i3, Word8
i4, Word8
i5, Word8
i6, Word8
i7, Word8
i8) of
(0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D) -> (6, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41)
(0x3D, _ , _ , _ , _ , _ ) -> (0, Word8
i3, Word8
i4, Word8
i5, Word8
i6, Word8
i7, Word8
i8)
(_ , 0x3D, 0x3D, 0x3D, 0x3D, 0x3D) -> (5, Word8
i3 , 0x41, 0x41, 0x41, 0x41, 0x41)
(_ , 0x3D, _ , _ , _ , _ ) -> (0, Word8
i3, Word8
i4, Word8
i5, Word8
i6, Word8
i7, Word8
i8)
(_ , _ , 0x3D, 0x3D, 0x3D, 0x3D) -> (4, Word8
i3 , Word8
i4 , 0x41, 0x41, 0x41, 0x41)
(_ , _ , 0x3D, _ , _ , _ ) -> (0, Word8
i3, Word8
i4, Word8
i5, Word8
i6, Word8
i7, Word8
i8)
(_ , _ , _ , 0x3D, 0x3D, 0x3D) -> (3, Word8
i3 , Word8
i4 , Word8
i5 , 0x41, 0x41, 0x41)
(_ , _ , _ , 0x3D, _ , _ ) -> (0, Word8
i3, Word8
i4, Word8
i5, Word8
i6, Word8
i7, Word8
i8)
(_ , _ , _ , _ , 0x3D, 0x3D) -> (2, Word8
i3 , Word8
i4 , Word8
i5 , Word8
i6 , 0x41, 0x41)
(_ , _ , _ , _ , 0x3D, _ ) -> (0, Word8
i3, Word8
i4, Word8
i5, Word8
i6, Word8
i7, Word8
i8)
(_ , _ , _ , _ , _ , 0x3D) -> (1, Word8
i3 , Word8
i4 , Word8
i5 , Word8
i6 , Word8
i7 , 0x41)
(_ , _ , _ , _ , _ , _ ) -> (0 :: Int, Word8
i3, Word8
i4, Word8
i5, Word8
i6, Word8
i7, Word8
i8)
case (Word8, Word8, Word8, Word8, Word8, Word8, Word8, Word8)
-> Either Int (Word8, Word8, Word8, Word8, Word8)
fromBase32Per8Bytes (Word8
i1, Word8
i2, Word8
i3', Word8
i4', Word8
i5', Word8
i6', Word8
i7', Word8
i8') of
Left ofs :: Int
ofs -> Maybe Int -> IO (Maybe Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Int -> IO (Maybe Int)) -> Maybe Int -> IO (Maybe Int)
forall a b. (a -> b) -> a -> b
$ Int -> Maybe Int
forall a. a -> Maybe a
Just (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
ofs)
Right (o1 :: Word8
o1, o2 :: Word8
o2, o3 :: Word8
o3, o4 :: Word8
o4, o5 :: Word8
o5) -> do
Ptr Word8 -> Int -> Word8 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr Word8
dst Int
di Word8
o1
Ptr Word8 -> Int -> Word8 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr Word8
dst (Int
diInt -> Int -> Int
forall a. Num a => a -> a -> a
+1) Word8
o2
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
nbBytes Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 5) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ Ptr Word8 -> Int -> Word8 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr Word8
dst (Int
diInt -> Int -> Int
forall a. Num a => a -> a -> a
+2) Word8
o3
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
nbBytes Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 4) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ Ptr Word8 -> Int -> Word8 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr Word8
dst (Int
diInt -> Int -> Int
forall a. Num a => a -> a -> a
+3) Word8
o4
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
nbBytes Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 2) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ Ptr Word8 -> Int -> Word8 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr Word8
dst (Int
diInt -> Int -> Int
forall a. Num a => a -> a -> a
+4) Word8
o5
Maybe Int -> IO (Maybe Int)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Int
forall a. Maybe a
Nothing
| Bool
otherwise = do
Word8
i1 <- Ptr Word8 -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Word8
src Int
i
Word8
i2 <- Ptr Word8 -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Word8
src (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1)
Word8
i3 <- Ptr Word8 -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Word8
src (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 2)
Word8
i4 <- Ptr Word8 -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Word8
src (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 3)
Word8
i5 <- Ptr Word8 -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Word8
src (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 4)
Word8
i6 <- Ptr Word8 -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Word8
src (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 5)
Word8
i7 <- Ptr Word8 -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Word8
src (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 6)
Word8
i8 <- Ptr Word8 -> Int -> IO Word8
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Word8
src (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 7)
case (Word8, Word8, Word8, Word8, Word8, Word8, Word8, Word8)
-> Either Int (Word8, Word8, Word8, Word8, Word8)
fromBase32Per8Bytes (Word8
i1, Word8
i2, Word8
i3, Word8
i4, Word8
i5, Word8
i6, Word8
i7, Word8
i8) of
Left ofs :: Int
ofs -> Maybe Int -> IO (Maybe Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Int -> IO (Maybe Int)) -> Maybe Int -> IO (Maybe Int)
forall a b. (a -> b) -> a -> b
$ Int -> Maybe Int
forall a. a -> Maybe a
Just (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
ofs)
Right (o1 :: Word8
o1, o2 :: Word8
o2, o3 :: Word8
o3, o4 :: Word8
o4, o5 :: Word8
o5) -> do
Ptr Word8 -> Int -> Word8 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr Word8
dst Int
di Word8
o1
Ptr Word8 -> Int -> Word8 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr Word8
dst (Int
diInt -> Int -> Int
forall a. Num a => a -> a -> a
+1) Word8
o2
Ptr Word8 -> Int -> Word8 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr Word8
dst (Int
diInt -> Int -> Int
forall a. Num a => a -> a -> a
+2) Word8
o3
Ptr Word8 -> Int -> Word8 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr Word8
dst (Int
diInt -> Int -> Int
forall a. Num a => a -> a -> a
+3) Word8
o4
Ptr Word8 -> Int -> Word8 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr Word8
dst (Int
diInt -> Int -> Int
forall a. Num a => a -> a -> a
+4) Word8
o5
Int -> Int -> IO (Maybe Int)
loop (Int
diInt -> Int -> Int
forall a. Num a => a -> a -> a
+5) (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+8)
fromBase32Per8Bytes :: (Word8, Word8, Word8, Word8, Word8, Word8, Word8, Word8)
-> Either Int (Word8, Word8, Word8, Word8, Word8)
fromBase32Per8Bytes :: (Word8, Word8, Word8, Word8, Word8, Word8, Word8, Word8)
-> Either Int (Word8, Word8, Word8, Word8, Word8)
fromBase32Per8Bytes (i1 :: Word8
i1, i2 :: Word8
i2, i3 :: Word8
i3, i4 :: Word8
i4, i5 :: Word8
i5, i6 :: Word8
i6, i7 :: Word8
i7, i8 :: Word8
i8) =
case (Word8 -> Word8
rset Word8
i1, Word8 -> Word8
rset Word8
i2, Word8 -> Word8
rset Word8
i3, Word8 -> Word8
rset Word8
i4, Word8 -> Word8
rset Word8
i5, Word8 -> Word8
rset Word8
i6, Word8 -> Word8
rset Word8
i7, Word8 -> Word8
rset Word8
i8) of
(0xFF, _ , _ , _ , _ , _ , _ , _ ) -> Int -> Either Int (Word8, Word8, Word8, Word8, Word8)
forall a b. a -> Either a b
Left 0
(_ , 0xFF, _ , _ , _ , _ , _ , _ ) -> Int -> Either Int (Word8, Word8, Word8, Word8, Word8)
forall a b. a -> Either a b
Left 1
(_ , _ , 0xFF, _ , _ , _ , _ , _ ) -> Int -> Either Int (Word8, Word8, Word8, Word8, Word8)
forall a b. a -> Either a b
Left 2
(_ , _ , _ , 0xFF, _ , _ , _ , _ ) -> Int -> Either Int (Word8, Word8, Word8, Word8, Word8)
forall a b. a -> Either a b
Left 3
(_ , _ , _ , _ , 0xFF, _ , _ , _ ) -> Int -> Either Int (Word8, Word8, Word8, Word8, Word8)
forall a b. a -> Either a b
Left 4
(_ , _ , _ , _ , _ , 0xFF, _ , _ ) -> Int -> Either Int (Word8, Word8, Word8, Word8, Word8)
forall a b. a -> Either a b
Left 5
(_ , _ , _ , _ , _ , _ , 0xFF, _ ) -> Int -> Either Int (Word8, Word8, Word8, Word8, Word8)
forall a b. a -> Either a b
Left 6
(_ , _ , _ , _ , _ , _ , _ , 0xFF) -> Int -> Either Int (Word8, Word8, Word8, Word8, Word8)
forall a b. a -> Either a b
Left 7
(ri1 :: Word8
ri1 , ri2 :: Word8
ri2 , ri3 :: Word8
ri3 , ri4 :: Word8
ri4 , ri5 :: Word8
ri5 , ri6 :: Word8
ri6 , ri7 :: Word8
ri7 , ri8 :: Word8
ri8 ) ->
let o1 :: Word8
o1 = (Word8
ri1 Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`unsafeShiftL` 3) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.|. (Word8
ri2 Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`unsafeShiftR` 2)
o2 :: Word8
o2 = (Word8
ri2 Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`unsafeShiftL` 6) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.|. (Word8
ri3 Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`unsafeShiftL` 1) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.|. (Word8
ri4 Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`unsafeShiftR` 4)
o3 :: Word8
o3 = (Word8
ri4 Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`unsafeShiftL` 4) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.|. (Word8
ri5 Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`unsafeShiftR` 1)
o4 :: Word8
o4 = (Word8
ri5 Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`unsafeShiftL` 7) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.|. (Word8
ri6 Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`unsafeShiftL` 2) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.|. (Word8
ri7 Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`unsafeShiftR` 3)
o5 :: Word8
o5 = (Word8
ri7 Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`unsafeShiftL` 5) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.|. Word8
ri8
in (Word8, Word8, Word8, Word8, Word8)
-> Either Int (Word8, Word8, Word8, Word8, Word8)
forall a b. b -> Either a b
Right (Word8
o1, Word8
o2, Word8
o3, Word8
o4, Word8
o5)
where
rset :: Word8 -> Word8
rset :: Word8 -> Word8
rset (W8# w :: Word#
w)
| Int# -> Bool
booleanPrim (Word#
w Word# -> Word# -> Int#
`leWord#` 0xff##) = Word# -> Word8
W8# (Addr# -> Int# -> Word#
indexWord8OffAddr# Addr#
rsetTable (Word# -> Int#
word2Int# Word#
w))
| Bool
otherwise = 0xff
!rsetTable :: Addr#
rsetTable = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\
\\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\
\\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\
\\xFF\xFF\x1A\x1B\x1C\x1D\x1E\x1F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\
\\xFF\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\
\\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\xFF\xFF\xFF\xFF\xFF\
\\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\
\\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\
\\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\
\\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\
\\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\
\\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\
\\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\
\\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\
\\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\
\\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"#