{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE DataKinds #-}
module Raaz.Core.Primitive
(
Primitive(..), Key, Nounce, Block, BlockPtr, AlignedBlockPtr
, BlockCount(..), blocksOf
) where
import Data.Vector.Unboxed (Unbox)
import GHC.TypeLits
import Foreign.Storable ( Storable )
import Raaz.Core.Prelude
import Raaz.Core.Types.Endian
import Raaz.Core.Types.Pointer
import Raaz.Core.Types.Tuple
class ( Unbox (WordType p)
, EndianStore (WordType p)
, KnownNat (WordsPerBlock p)
) => Primitive p where
type WordType p :: Type
type WordsPerBlock p :: Nat
data family Key p :: Type
data family Nounce p :: Type
type Block p = Tuple (WordsPerBlock p) (WordType p)
type BlockPtr p = Ptr (Block p)
type AlignedBlockPtr n p = AlignedPtr n (Block p)
newtype BlockCount p = BlockCount {BlockCount p -> Int
unBlockCount :: Int}
deriving (Int -> BlockCount p -> ShowS
[BlockCount p] -> ShowS
BlockCount p -> String
(Int -> BlockCount p -> ShowS)
-> (BlockCount p -> String)
-> ([BlockCount p] -> ShowS)
-> Show (BlockCount p)
forall p. Int -> BlockCount p -> ShowS
forall p. [BlockCount p] -> ShowS
forall p. BlockCount p -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BlockCount p] -> ShowS
$cshowList :: forall p. [BlockCount p] -> ShowS
show :: BlockCount p -> String
$cshow :: forall p. BlockCount p -> String
showsPrec :: Int -> BlockCount p -> ShowS
$cshowsPrec :: forall p. Int -> BlockCount p -> ShowS
Show, BlockCount p -> BlockCount p -> Bool
(BlockCount p -> BlockCount p -> Bool)
-> (BlockCount p -> BlockCount p -> Bool) -> Eq (BlockCount p)
forall p. BlockCount p -> BlockCount p -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BlockCount p -> BlockCount p -> Bool
$c/= :: forall p. BlockCount p -> BlockCount p -> Bool
== :: BlockCount p -> BlockCount p -> Bool
$c== :: forall p. BlockCount p -> BlockCount p -> Bool
Eq, Eq (BlockCount p)
Eq (BlockCount p)
-> (BlockCount p -> BlockCount p -> Ordering)
-> (BlockCount p -> BlockCount p -> Bool)
-> (BlockCount p -> BlockCount p -> Bool)
-> (BlockCount p -> BlockCount p -> Bool)
-> (BlockCount p -> BlockCount p -> Bool)
-> (BlockCount p -> BlockCount p -> BlockCount p)
-> (BlockCount p -> BlockCount p -> BlockCount p)
-> Ord (BlockCount p)
BlockCount p -> BlockCount p -> Bool
BlockCount p -> BlockCount p -> Ordering
BlockCount p -> BlockCount p -> BlockCount p
forall p. Eq (BlockCount p)
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall p. BlockCount p -> BlockCount p -> Bool
forall p. BlockCount p -> BlockCount p -> Ordering
forall p. BlockCount p -> BlockCount p -> BlockCount p
min :: BlockCount p -> BlockCount p -> BlockCount p
$cmin :: forall p. BlockCount p -> BlockCount p -> BlockCount p
max :: BlockCount p -> BlockCount p -> BlockCount p
$cmax :: forall p. BlockCount p -> BlockCount p -> BlockCount p
>= :: BlockCount p -> BlockCount p -> Bool
$c>= :: forall p. BlockCount p -> BlockCount p -> Bool
> :: BlockCount p -> BlockCount p -> Bool
$c> :: forall p. BlockCount p -> BlockCount p -> Bool
<= :: BlockCount p -> BlockCount p -> Bool
$c<= :: forall p. BlockCount p -> BlockCount p -> Bool
< :: BlockCount p -> BlockCount p -> Bool
$c< :: forall p. BlockCount p -> BlockCount p -> Bool
compare :: BlockCount p -> BlockCount p -> Ordering
$ccompare :: forall p. BlockCount p -> BlockCount p -> Ordering
$cp1Ord :: forall p. Eq (BlockCount p)
Ord, Int -> BlockCount p
BlockCount p -> Int
BlockCount p -> [BlockCount p]
BlockCount p -> BlockCount p
BlockCount p -> BlockCount p -> [BlockCount p]
BlockCount p -> BlockCount p -> BlockCount p -> [BlockCount p]
(BlockCount p -> BlockCount p)
-> (BlockCount p -> BlockCount p)
-> (Int -> BlockCount p)
-> (BlockCount p -> Int)
-> (BlockCount p -> [BlockCount p])
-> (BlockCount p -> BlockCount p -> [BlockCount p])
-> (BlockCount p -> BlockCount p -> [BlockCount p])
-> (BlockCount p -> BlockCount p -> BlockCount p -> [BlockCount p])
-> Enum (BlockCount p)
forall p. Int -> BlockCount p
forall p. BlockCount p -> Int
forall p. BlockCount p -> [BlockCount p]
forall p. BlockCount p -> BlockCount p
forall p. BlockCount p -> BlockCount p -> [BlockCount p]
forall p.
BlockCount p -> BlockCount p -> BlockCount p -> [BlockCount p]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: BlockCount p -> BlockCount p -> BlockCount p -> [BlockCount p]
$cenumFromThenTo :: forall p.
BlockCount p -> BlockCount p -> BlockCount p -> [BlockCount p]
enumFromTo :: BlockCount p -> BlockCount p -> [BlockCount p]
$cenumFromTo :: forall p. BlockCount p -> BlockCount p -> [BlockCount p]
enumFromThen :: BlockCount p -> BlockCount p -> [BlockCount p]
$cenumFromThen :: forall p. BlockCount p -> BlockCount p -> [BlockCount p]
enumFrom :: BlockCount p -> [BlockCount p]
$cenumFrom :: forall p. BlockCount p -> [BlockCount p]
fromEnum :: BlockCount p -> Int
$cfromEnum :: forall p. BlockCount p -> Int
toEnum :: Int -> BlockCount p
$ctoEnum :: forall p. Int -> BlockCount p
pred :: BlockCount p -> BlockCount p
$cpred :: forall p. BlockCount p -> BlockCount p
succ :: BlockCount p -> BlockCount p
$csucc :: forall p. BlockCount p -> BlockCount p
Enum, Ptr b -> Int -> IO (BlockCount p)
Ptr b -> Int -> BlockCount p -> IO ()
Ptr (BlockCount p) -> IO (BlockCount p)
Ptr (BlockCount p) -> Int -> IO (BlockCount p)
Ptr (BlockCount p) -> Int -> BlockCount p -> IO ()
Ptr (BlockCount p) -> BlockCount p -> IO ()
BlockCount p -> Int
(BlockCount p -> Int)
-> (BlockCount p -> Int)
-> (Ptr (BlockCount p) -> Int -> IO (BlockCount p))
-> (Ptr (BlockCount p) -> Int -> BlockCount p -> IO ())
-> (forall b. Ptr b -> Int -> IO (BlockCount p))
-> (forall b. Ptr b -> Int -> BlockCount p -> IO ())
-> (Ptr (BlockCount p) -> IO (BlockCount p))
-> (Ptr (BlockCount p) -> BlockCount p -> IO ())
-> Storable (BlockCount p)
forall b. Ptr b -> Int -> IO (BlockCount p)
forall b. Ptr b -> Int -> BlockCount p -> IO ()
forall p. Ptr (BlockCount p) -> IO (BlockCount p)
forall p. Ptr (BlockCount p) -> Int -> IO (BlockCount p)
forall p. Ptr (BlockCount p) -> Int -> BlockCount p -> IO ()
forall p. Ptr (BlockCount p) -> BlockCount p -> IO ()
forall p. BlockCount p -> Int
forall a.
(a -> Int)
-> (a -> Int)
-> (Ptr a -> Int -> IO a)
-> (Ptr a -> Int -> a -> IO ())
-> (forall b. Ptr b -> Int -> IO a)
-> (forall b. Ptr b -> Int -> a -> IO ())
-> (Ptr a -> IO a)
-> (Ptr a -> a -> IO ())
-> Storable a
forall p b. Ptr b -> Int -> IO (BlockCount p)
forall p b. Ptr b -> Int -> BlockCount p -> IO ()
poke :: Ptr (BlockCount p) -> BlockCount p -> IO ()
$cpoke :: forall p. Ptr (BlockCount p) -> BlockCount p -> IO ()
peek :: Ptr (BlockCount p) -> IO (BlockCount p)
$cpeek :: forall p. Ptr (BlockCount p) -> IO (BlockCount p)
pokeByteOff :: Ptr b -> Int -> BlockCount p -> IO ()
$cpokeByteOff :: forall p b. Ptr b -> Int -> BlockCount p -> IO ()
peekByteOff :: Ptr b -> Int -> IO (BlockCount p)
$cpeekByteOff :: forall p b. Ptr b -> Int -> IO (BlockCount p)
pokeElemOff :: Ptr (BlockCount p) -> Int -> BlockCount p -> IO ()
$cpokeElemOff :: forall p. Ptr (BlockCount p) -> Int -> BlockCount p -> IO ()
peekElemOff :: Ptr (BlockCount p) -> Int -> IO (BlockCount p)
$cpeekElemOff :: forall p. Ptr (BlockCount p) -> Int -> IO (BlockCount p)
alignment :: BlockCount p -> Int
$calignment :: forall p. BlockCount p -> Int
sizeOf :: BlockCount p -> Int
$csizeOf :: forall p. BlockCount p -> Int
Storable)
instance Semigroup (BlockCount p) where
<> :: BlockCount p -> BlockCount p -> BlockCount p
(<>) BlockCount p
x BlockCount p
y = Int -> BlockCount p
forall p. Int -> BlockCount p
BlockCount (Int -> BlockCount p) -> Int -> BlockCount p
forall a b. (a -> b) -> a -> b
$ BlockCount p -> Int
forall p. BlockCount p -> Int
unBlockCount BlockCount p
x Int -> Int -> Int
forall a. Num a => a -> a -> a
+ BlockCount p -> Int
forall p. BlockCount p -> Int
unBlockCount BlockCount p
y
instance Monoid (BlockCount p) where
mempty :: BlockCount p
mempty = Int -> BlockCount p
forall p. Int -> BlockCount p
BlockCount Int
0
mappend :: BlockCount p -> BlockCount p -> BlockCount p
mappend = BlockCount p -> BlockCount p -> BlockCount p
forall a. Semigroup a => a -> a -> a
(<>)
instance Primitive p => LengthUnit (BlockCount p) where
inBytes :: BlockCount p -> BYTES Int
inBytes p :: BlockCount p
p@(BlockCount Int
x) = Int -> BYTES Int
forall a. Enum a => Int -> a
toEnum Int
x BYTES Int -> BYTES Int -> BYTES Int
forall a. Num a => a -> a -> a
* BlockCount p -> BYTES Int
nWords BlockCount p
p BYTES Int -> BYTES Int -> BYTES Int
forall a. Num a => a -> a -> a
* BlockCount p -> BYTES Int
wordSize BlockCount p
p
where wordSize :: BlockCount p -> BYTES Int
wordSize = Proxy (WordType p) -> BYTES Int
forall a. Storable a => Proxy a -> BYTES Int
sizeOf (Proxy (WordType p) -> BYTES Int)
-> (BlockCount p -> Proxy (WordType p))
-> BlockCount p
-> BYTES Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BlockCount p -> Proxy (WordType p)
forall p. Primitive p => BlockCount p -> Proxy (WordType p)
proxyWT
nWords :: BlockCount p -> BYTES Int
nWords = Int -> BYTES Int
forall a. Enum a => Int -> a
toEnum (Int -> BYTES Int)
-> (BlockCount p -> Int) -> BlockCount p -> BYTES Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Int
forall a. Enum a => a -> Int
fromEnum (Integer -> Int)
-> (BlockCount p -> Integer) -> BlockCount p -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy (WordsPerBlock p) -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (Proxy (WordsPerBlock p) -> Integer)
-> (BlockCount p -> Proxy (WordsPerBlock p))
-> BlockCount p
-> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BlockCount p -> Proxy (WordsPerBlock p)
forall p. Primitive p => BlockCount p -> Proxy (WordsPerBlock p)
proxyWPB
proxyWT :: Primitive p => BlockCount p -> Proxy (WordType p)
proxyWT :: BlockCount p -> Proxy (WordType p)
proxyWT = Proxy (WordType p) -> BlockCount p -> Proxy (WordType p)
forall a b. a -> b -> a
const Proxy (WordType p)
forall k (t :: k). Proxy t
Proxy
proxyWPB :: Primitive p => BlockCount p -> Proxy (WordsPerBlock p)
proxyWPB :: BlockCount p -> Proxy (WordsPerBlock p)
proxyWPB = Proxy (WordsPerBlock p) -> BlockCount p -> Proxy (WordsPerBlock p)
forall a b. a -> b -> a
const Proxy (WordsPerBlock p)
forall k (t :: k). Proxy t
Proxy
blocksOf :: Int -> Proxy p -> BlockCount p
blocksOf :: Int -> Proxy p -> BlockCount p
blocksOf Int
n Proxy p
_ = Int -> BlockCount p
forall p. Int -> BlockCount p
BlockCount Int
n