module Botan.Low.ZFEC
(
ZFECShare(..)
, zfecEncode
, zfecDecode
) where
import Control.Concurrent
import Data.Foldable
import qualified Data.ByteString as ByteString
import qualified Data.ByteString.Unsafe as ByteString
import Botan.Bindings.ZFEC
import Botan.Low.Error
import Botan.Low.Make
import Botan.Low.Prelude
type ZFECShare = (Int, ByteString)
zfecEncode
:: Int
-> Int
-> ByteString
-> IO [ZFECShare]
zfecEncode :: Int -> Int -> ByteString -> IO [ZFECShare]
zfecEncode Int
k Int
n ByteString
input = ByteString
-> (Ptr Word8 -> CSize -> IO [ZFECShare]) -> IO [ZFECShare]
forall byte a. ByteString -> (Ptr byte -> CSize -> IO a) -> IO a
asBytesLen ByteString
input ((Ptr Word8 -> CSize -> IO [ZFECShare]) -> IO [ZFECShare])
-> (Ptr Word8 -> CSize -> IO [ZFECShare]) -> IO [ZFECShare]
forall a b. (a -> b) -> a -> b
$ \ Ptr Word8
inputPtr CSize
inputLen -> do
let shareSize :: Int
shareSize = Int -> Int -> Int
forall a. Integral a => a -> a -> a
div (CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
inputLen) Int
k
Int -> (Ptr Word8 -> IO [ZFECShare]) -> IO [ZFECShare]
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
shareSize) ((Ptr Word8 -> IO [ZFECShare]) -> IO [ZFECShare])
-> (Ptr Word8 -> IO [ZFECShare]) -> IO [ZFECShare]
forall a b. (a -> b) -> a -> b
$ \ Ptr Word8
outPtr -> do
Int -> (Ptr (Ptr Word8) -> IO [ZFECShare]) -> IO [ZFECShare]
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
n ((Ptr (Ptr Word8) -> IO [ZFECShare]) -> IO [ZFECShare])
-> (Ptr (Ptr Word8) -> IO [ZFECShare]) -> IO [ZFECShare]
forall a b. (a -> b) -> a -> b
$ \ (Ptr (Ptr Word8)
sharePtrArrayPtr :: Ptr (Ptr Word8)) -> do
let sharePtrs :: [Ptr Word8]
sharePtrs = (Int -> Ptr Word8) -> [Int] -> [Ptr Word8]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Ptr Word8 -> Int -> Ptr Word8
forall a. Storable a => Ptr a -> Int -> Ptr a
advancePtr Ptr Word8
outPtr (Int -> Ptr Word8) -> (Int -> Int) -> Int -> Ptr Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
shareSize)) [Int
0..(Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)]
Ptr (Ptr Word8) -> [Ptr Word8] -> IO ()
forall a. Storable a => Ptr a -> [a] -> IO ()
pokeArray Ptr (Ptr Word8)
sharePtrArrayPtr [Ptr Word8]
sharePtrs
HasCallStack => IO BotanErrorCode -> IO ()
IO BotanErrorCode -> IO ()
throwBotanIfNegative_ (IO BotanErrorCode -> IO ()) -> IO BotanErrorCode -> IO ()
forall a b. (a -> b) -> a -> b
$ CSize
-> CSize
-> ConstPtr Word8
-> CSize
-> Ptr (Ptr Word8)
-> IO BotanErrorCode
botan_zfec_encode
(Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k)
(Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n)
(Ptr Word8 -> ConstPtr Word8
forall a. Ptr a -> ConstPtr a
ConstPtr Ptr Word8
inputPtr)
CSize
inputLen
Ptr (Ptr Word8)
sharePtrArrayPtr
[ByteString]
shares <- (Ptr Word8 -> IO ByteString) -> [Ptr Word8] -> IO [ByteString]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse (CStringLen -> IO ByteString
ByteString.packCStringLen (CStringLen -> IO ByteString)
-> (Ptr Word8 -> CStringLen) -> Ptr Word8 -> IO ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (,Int
shareSize) (Ptr CChar -> CStringLen)
-> (Ptr Word8 -> Ptr CChar) -> Ptr Word8 -> CStringLen
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr Word8 -> Ptr CChar
forall a b. Ptr a -> Ptr b
castPtr) [Ptr Word8]
sharePtrs
[ZFECShare] -> IO [ZFECShare]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([ZFECShare] -> IO [ZFECShare]) -> [ZFECShare] -> IO [ZFECShare]
forall a b. NFData a => (a -> b) -> a -> b
$!! [Int] -> [ByteString] -> [ZFECShare]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0..(Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)] [ByteString]
shares
zfecDecode
:: Int
-> Int
-> [ZFECShare]
-> IO ByteString
zfecDecode :: Int -> Int -> [ZFECShare] -> IO ByteString
zfecDecode Int
_ Int
_ [] = ByteString -> IO ByteString
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
""
zfecDecode Int
k Int
n shares :: [ZFECShare]
shares@((Int
_,ByteString
share0):[ZFECShare]
_) = do
Int -> (Ptr CSize -> IO ByteString) -> IO ByteString
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
k ((Ptr CSize -> IO ByteString) -> IO ByteString)
-> (Ptr CSize -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \ (Ptr CSize
indexesPtr :: Ptr CSize) -> do
Ptr CSize -> [CSize] -> IO ()
forall a. Storable a => Ptr a -> [a] -> IO ()
pokeArray Ptr CSize
indexesPtr [CSize]
shareIndexes
(forall a. ByteString -> (Ptr Word8 -> IO a) -> IO a)
-> [ByteString] -> ([Ptr Word8] -> IO ByteString) -> IO ByteString
forall typ ptr b.
(forall a. typ -> (ptr -> IO a) -> IO a)
-> [typ] -> ([ptr] -> IO b) -> IO b
withPtrs ByteString -> (Ptr Word8 -> IO a) -> IO a
forall a. ByteString -> (Ptr Word8 -> IO a) -> IO a
forall byte a. ByteString -> (Ptr byte -> IO a) -> IO a
unsafeAsBytes [ByteString]
shareBytes (([Ptr Word8] -> IO ByteString) -> IO ByteString)
-> ([Ptr Word8] -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \ ([Ptr Word8]
sharePtrs :: [Ptr Word8]) -> do
Int -> (Ptr (Ptr Word8) -> IO ByteString) -> IO ByteString
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
k ((Ptr (Ptr Word8) -> IO ByteString) -> IO ByteString)
-> (Ptr (Ptr Word8) -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \ (Ptr (Ptr Word8)
sharePtrArrayPtr :: Ptr (Ptr Word8)) -> do
Ptr (Ptr Word8) -> [Ptr Word8] -> IO ()
forall a. Storable a => Ptr a -> [a] -> IO ()
pokeArray Ptr (Ptr Word8)
sharePtrArrayPtr [Ptr Word8]
sharePtrs
Int -> (Ptr Word8 -> IO ()) -> IO ByteString
forall byte. Int -> (Ptr byte -> IO ()) -> IO ByteString
allocBytes (Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
shareSize) ((Ptr Word8 -> IO ()) -> IO ByteString)
-> (Ptr Word8 -> IO ()) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \ Ptr Word8
outPtr -> do
Int -> (Ptr (Ptr Word8) -> IO ()) -> IO ()
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
n ((Ptr (Ptr Word8) -> IO ()) -> IO ())
-> (Ptr (Ptr Word8) -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ (Ptr (Ptr Word8)
outPtrArrayPtr :: Ptr (Ptr Word8)) -> do
let outPtrs :: [Ptr Word8]
outPtrs = (Int -> Ptr Word8) -> [Int] -> [Ptr Word8]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Ptr Word8 -> Int -> Ptr Word8
forall a. Storable a => Ptr a -> Int -> Ptr a
advancePtr Ptr Word8
outPtr (Int -> Ptr Word8) -> (Int -> Int) -> Int -> Ptr Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
shareSize)) [Int
0..(Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)]
Ptr (Ptr Word8) -> [Ptr Word8] -> IO ()
forall a. Storable a => Ptr a -> [a] -> IO ()
pokeArray Ptr (Ptr Word8)
outPtrArrayPtr [Ptr Word8]
outPtrs
HasCallStack => IO BotanErrorCode -> IO ()
IO BotanErrorCode -> IO ()
throwBotanIfNegative_ (IO BotanErrorCode -> IO ()) -> IO BotanErrorCode -> IO ()
forall a b. (a -> b) -> a -> b
$ CSize
-> CSize
-> ConstPtr CSize
-> ConstPtr (ConstPtr Word8)
-> CSize
-> Ptr (Ptr Word8)
-> IO BotanErrorCode
botan_zfec_decode
(Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k)
(Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n)
(Ptr CSize -> ConstPtr CSize
forall a. Ptr a -> ConstPtr a
ConstPtr Ptr CSize
indexesPtr)
(Ptr (ConstPtr Word8) -> ConstPtr (ConstPtr Word8)
forall a. Ptr a -> ConstPtr a
ConstPtr (Ptr (ConstPtr Word8) -> ConstPtr (ConstPtr Word8))
-> Ptr (ConstPtr Word8) -> ConstPtr (ConstPtr Word8)
forall a b. (a -> b) -> a -> b
$ Ptr (Ptr Word8) -> Ptr (ConstPtr Word8)
forall a b. Ptr a -> Ptr b
castPtr Ptr (Ptr Word8)
sharePtrArrayPtr)
(Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
shareSize)
Ptr (Ptr Word8)
outPtrArrayPtr
where
shareIndexes :: [CSize]
shareIndexes = (ZFECShare -> CSize) -> [ZFECShare] -> [CSize]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CSize) -> (ZFECShare -> Int) -> ZFECShare -> CSize
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ZFECShare -> Int
forall a b. (a, b) -> a
fst) [ZFECShare]
shares
shareBytes :: [ByteString]
shareBytes = (ZFECShare -> ByteString) -> [ZFECShare] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ZFECShare -> ByteString
forall a b. (a, b) -> b
snd [ZFECShare]
shares
shareSize :: Int
shareSize = ByteString -> Int
ByteString.length ByteString
share0