-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/

-- | memory and related abstraction stuff
--   
--   This is a fork of memory. It's open to accept changes from anyone, and
--   aims to use existing well maintained libraries as much as possible.
--   
--   Chunk of memory, polymorphic byte array management and manipulation
--   
--   
--   
- A polymorphic byte array abstraction and function similar to
--   strict ByteString.
--   
- Different type of byte array abstraction.
--   
- Raw memory IO operations (memory set, memory copy, ..)
--   
- Aliasing with endianness support.
--   
- Encoding : Base16, Base32, Base64.
--   
- Hashing : FNV, SipHash
--   
@package ram
@version 0.19.0

-- | Extra Word size
module Data.Memory.ExtendedWords

-- | A simple Extended Word128 composed of 2 Word64
data Word128
Word128 :: !Word64 -> !Word64 -> Word128
instance GHC.Classes.Eq Data.Memory.ExtendedWords.Word128
instance GHC.Internal.Show.Show Data.Memory.ExtendedWords.Word128

module Data.Memory.Endian

-- | represent the CPU endianness
--   
--   Big endian system stores bytes with the MSB as the first byte. Little
--   endian system stores bytes with the LSB as the first byte.
--   
--   middle endian is purposely avoided.
data Endianness
LittleEndian :: Endianness
BigEndian :: Endianness

-- | Return the system endianness
getSystemEndianness :: Endianness

-- | Big Endian value
newtype BE a
BE :: a -> BE a
[unBE] :: BE a -> a

-- | Little Endian value
newtype LE a
LE :: a -> LE a
[unLE] :: LE a -> a

-- | Convert from a big endian value to the cpu endianness
fromBE :: ByteSwap a => BE a -> a

-- | Convert a value in cpu endianess to big endian
toBE :: ByteSwap a => a -> BE a

-- | Convert from a little endian value to the cpu endianness
fromLE :: ByteSwap a => LE a -> a

-- | Convert a value in cpu endianess to little endian
toLE :: ByteSwap a => a -> LE a

-- | Class of types that can be byte-swapped.
--   
--   e.g. Word16, Word32, Word64
class Storable a => ByteSwap a
instance Data.Memory.Endian.ByteSwap GHC.Internal.Word.Word16
instance Data.Memory.Endian.ByteSwap GHC.Internal.Word.Word32
instance Data.Memory.Endian.ByteSwap GHC.Internal.Word.Word64
instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Memory.Endian.BE a)
instance GHC.Classes.Eq Data.Memory.Endian.Endianness
instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Memory.Endian.LE a)
instance GHC.Internal.Show.Show a => GHC.Internal.Show.Show (Data.Memory.Endian.BE a)
instance GHC.Internal.Show.Show Data.Memory.Endian.Endianness
instance GHC.Internal.Show.Show a => GHC.Internal.Show.Show (Data.Memory.Endian.LE a)
instance GHC.Internal.Foreign.Storable.Storable a => GHC.Internal.Foreign.Storable.Storable (Data.Memory.Endian.BE a)
instance GHC.Internal.Foreign.Storable.Storable a => GHC.Internal.Foreign.Storable.Storable (Data.Memory.Endian.LE a)

-- | Low-level Base32 encoding and decoding.
--   
--   If you just want to encode or decode some bytes, you probably want to
--   use the Data.ByteArray.Encoding module.
module Data.Memory.Encoding.Base32

-- | Transform a number of bytes pointed by.src in the base32 binary
--   representation in dst
--   
--   destination memory need to be of correct size, otherwise it will lead
--   to really bad things.
toBase32 :: Ptr Word8 -> Ptr Word8 -> Int -> IO ()

-- | Get the length needed for the destination buffer for a base32
--   decoding.
--   
--   if the length is not a multiple of 8, Nothing is returned
unBase32Length :: Ptr Word8 -> Int -> IO (Maybe Int)

-- | convert from base32 in src to binary in dst, using the number
--   of bytes specified
--   
--   the user should use unBase32Length to compute the correct length, or
--   check that the length specification is proper. no check is done here.
fromBase32 :: Ptr Word8 -> Ptr Word8 -> Int -> IO (Maybe Int)

-- | Low-level Base16 encoding and decoding.
--   
--   If you just want to encode or decode some bytes, you probably want to
--   use the Data.ByteArray.Encoding module.
module Data.Memory.Encoding.Base16

-- | Transform a raw memory to an hexadecimal String
--   
--   user beware, no checks are made
showHexadecimal :: (forall a. () => (Ptr Word8 -> IO a) -> IO a) -> Int -> String

-- | Transform a number of bytes pointed by.src in the hexadecimal
--   binary representation in dst
--   
--   destination memory need to be of correct size, otherwise it will lead
--   to really bad things.
toHexadecimal :: Ptr Word8 -> Ptr Word8 -> Int -> IO ()

-- | convert a base16 src in dst.
--   
--   n need to even
fromHexadecimal :: Ptr Word8 -> Ptr Word8 -> Int -> IO (Maybe Int)

-- | Low-level Base64 encoding and decoding.
--   
--   If you just want to encode or decode some bytes, you probably want to
--   use the Data.ByteArray.Encoding module.
module Data.Memory.Encoding.Base64

-- | Transform a number of bytes pointed by src to base64 binary
--   representation in dst
--   
--   The destination memory need to be of correct size, otherwise it will
--   lead to really bad things.
toBase64 :: Ptr Word8 -> Ptr Word8 -> Int -> IO ()

-- | Transform a number of bytes pointed by src to, URL-safe
--   base64 binary representation in dst. The result will be
--   either padded or unpadded, depending on the boolean padded
--   argument.
--   
--   The destination memory need to be of correct size, otherwise it will
--   lead to really bad things.
toBase64URL :: Bool -> Ptr Word8 -> Ptr Word8 -> Int -> IO ()
toBase64OpenBSD :: Ptr Word8 -> Ptr Word8 -> Int -> IO ()

-- | Get the length needed for the destination buffer for a base64
--   decoding.
--   
--   if the length is not a multiple of 4, Nothing is returned
unBase64Length :: Ptr Word8 -> Int -> IO (Maybe Int)

-- | Get the length needed for the destination buffer for an
--   unpadded base64 decoding.
--   
--   If the length of the encoded string is a multiple of 4, plus one,
--   Nothing is returned. Any other value can be valid without padding.
unBase64LengthUnpadded :: Int -> Maybe Int

-- | convert from base64 in src to binary in dst, using
--   the number of bytes specified
--   
--   the user should use unBase64Length to compute the correct length, or
--   check that the length specification is proper. no check is done here.
fromBase64 :: Ptr Word8 -> Ptr Word8 -> Int -> IO (Maybe Int)
fromBase64URLUnpadded :: Ptr Word8 -> Ptr Word8 -> Int -> IO (Maybe Int)
fromBase64OpenBSD :: Ptr Word8 -> Ptr Word8 -> Int -> IO (Maybe Int)

-- | methods to manipulate raw memory representation
module Data.Memory.PtrMethods

-- | Create a new temporary buffer
memCreateTemporary :: Int -> (Ptr Word8 -> IO a) -> IO a

-- | xor bytes from source1 and source2 to destination
--   
--   d = s1 xor s2
--   
--   s1, nor s2 are modified unless d point to s1 or s2
memXor :: Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> Int -> IO ()

-- | xor bytes from source with a specific value to destination
--   
--   d = replicate (sizeof s) v xor s
memXorWith :: Ptr Word8 -> Word8 -> Ptr Word8 -> Int -> IO ()

-- | Copy a set number of bytes from src to dst
memCopy :: Ptr Word8 -> Ptr Word8 -> Int -> IO ()

-- | Set n number of bytes to the same value v
memSet :: Ptr Word8 -> Word8 -> Int -> IO ()

-- | Reverse a set number of bytes from src to dst.
--   Memory locations should not overlap.
memReverse :: Ptr Word8 -> Ptr Word8 -> Int -> IO ()

-- | Check if two piece of memory are equals
memEqual :: Ptr Word8 -> Ptr Word8 -> Int -> IO Bool

-- | A constant time equality test for 2 Memory buffers
--   
--   compared to normal equality function, this function will go over all
--   the bytes present before yielding a result even when knowing the
--   overall result early in the processing.
memConstEqual :: Ptr Word8 -> Ptr Word8 -> Int -> IO Bool

-- | Compare two piece of memory and returns how they compare
memCompare :: Ptr Word8 -> Ptr Word8 -> Int -> IO Ordering

-- | provide the SipHash algorithm. reference:
--   http://131002.net/siphash/siphash.pdf
module Data.ByteArray.Hash

-- | SigHash Key
data SipKey
SipKey :: {-# UNPACK #-} !Word64 -> {-# UNPACK #-} !Word64 -> SipKey

-- | Siphash tag value
newtype SipHash
SipHash :: Word64 -> SipHash

-- | Compute the SipHash tag of a byte array for a given key.
--   
--   sipHash is equivalent to 'sipHashWith 2 4'
sipHash :: ByteArrayAccess ba => SipKey -> ba -> SipHash

-- | Compute the SipHash tag of a byte array for a given key.
--   
--   The user can choose the C and D numbers of rounds.
--   
--   calling sipHash is equivalent to 'sipHashWith 2 4'
sipHashWith :: ByteArrayAccess ba => Int -> Int -> SipKey -> ba -> SipHash

-- | FNV1(a) hash (32 bit variants)
newtype FnvHash32
FnvHash32 :: Word32 -> FnvHash32

-- | FNV1(a) hash (64 bit variants)
newtype FnvHash64
FnvHash64 :: Word64 -> FnvHash64

-- | Compute the FNV1 32 bit hash value of a byte array
fnv1Hash :: ByteArrayAccess ba => ba -> FnvHash32

-- | Compute the FNV1a 32 bit hash value of a byte array
fnv1aHash :: ByteArrayAccess ba => ba -> FnvHash32

-- | Compute the FNV1 64 bit hash value of a byte array
fnv1_64Hash :: ByteArrayAccess ba => ba -> FnvHash64

-- | Compute the FNV1a 64 bit hash value of a byte array
fnv1a_64Hash :: ByteArrayAccess ba => ba -> FnvHash64

module Data.ByteArray.Sized

-- | Type class to emulate exactly the behaviour of ByteArray but
--   with a known length at compile time
class (ByteArrayAccess c, KnownNat n) => ByteArrayN (n :: Nat) c | c -> n

-- | just like allocRet but with the size at the type level
allocRet :: ByteArrayN n c => Proxy n -> (Ptr p -> IO a) -> IO (a, c)

-- | Wrapper around any collection type with the size as type parameter
data SizedByteArray (n :: Nat) ba
unSizedByteArray :: SizedByteArray n ba -> ba

-- | create a SizedByteArray from the given ByteArrayAccess
--   if the size is the same as the target size.
sizedByteArray :: forall (n :: Nat) ba. (KnownNat n, ByteArrayAccess ba) => ba -> Maybe (SizedByteArray n ba)

-- | just like the sizedByteArray function but throw an exception if
--   the size is invalid.
unsafeSizedByteArray :: forall (n :: Nat) ba. (ByteArrayAccess ba, KnownNat n) => ba -> SizedByteArray n ba

-- | Allocate a new bytearray of specific size, and run the initializer on
--   this memory
alloc :: forall (n :: Nat) ba p. (ByteArrayN n ba, KnownNat n) => (Ptr p -> IO ()) -> IO ba

-- | Allocate a new bytearray of specific size, and run the initializer on
--   this memory
create :: forall (n :: Nat) ba p. (ByteArrayN n ba, KnownNat n) => (Ptr p -> IO ()) -> IO ba

-- | similar to allocN but hide the allocation and initializer in
--   a pure context
allocAndFreeze :: forall (n :: Nat) ba p. (ByteArrayN n ba, KnownNat n) => (Ptr p -> IO ()) -> ba

-- | similar to createN but hide the allocation and initializer in
--   a pure context
unsafeCreate :: forall (n :: Nat) ba p. (ByteArrayN n ba, KnownNat n) => (Ptr p -> IO ()) -> ba
inlineUnsafeCreate :: forall (n :: Nat) ba p. (ByteArrayN n ba, KnownNat n) => (Ptr p -> IO ()) -> ba

-- | Create an empty byte array
empty :: ByteArrayN 0 ba => ba

-- | Pack a list of bytes into a bytearray
pack :: forall (n :: Nat) ba. (ByteArrayN n ba, KnownNat n) => ListN n Word8 -> ba

-- | Un-pack a bytearray into a list of bytes
unpack :: forall (n :: Nat) ba. (ByteArrayN n ba, KnownNat n, ByteArrayAccess ba) => ba -> ListN n Word8

-- | prepend a single byte to a byte array
cons :: forall (ni :: Nat) (no :: Nat) bi bo. (ByteArrayN ni bi, ByteArrayN no bo, ByteArrayAccess bi, KnownNat ni, KnownNat no, (ni + 1) ~ no) => Word8 -> bi -> bo

-- | append a single byte to a byte array
snoc :: forall bi bo (ni :: Nat) (no :: Nat). (ByteArrayN ni bi, ByteArrayN no bo, ByteArrayAccess bi, KnownNat ni, KnownNat no, (ni + 1) ~ no) => bi -> Word8 -> bo

-- | Create a xor of bytes between a and b.
--   
--   the returns byte array is the size of the smallest input.
xor :: forall (n :: Nat) a b c. (ByteArrayN n a, ByteArrayN n b, ByteArrayN n c, ByteArrayAccess a, ByteArrayAccess b, KnownNat n) => a -> b -> c

-- | return a specific byte indexed by a number from 0 in a bytearray
--   
--   unsafe, no bound checking are done
index :: forall (n :: Nat) (na :: Nat) ba. (ByteArrayN na ba, ByteArrayAccess ba, KnownNat na, KnownNat n, n <= na) => ba -> Proxy n -> Word8

-- | Split a bytearray at a specific length in two bytearray
splitAt :: forall (nblhs :: Nat) (nbi :: Nat) (nbrhs :: Nat) bi blhs brhs. (ByteArrayN nbi bi, ByteArrayN nblhs blhs, ByteArrayN nbrhs brhs, ByteArrayAccess bi, KnownNat nbi, KnownNat nblhs, KnownNat nbrhs, nblhs <= nbi, (nbrhs + nblhs) ~ nbi) => bi -> (blhs, brhs)

-- | Take the first n byte of a bytearray
take :: forall (nbo :: Nat) (nbi :: Nat) bi bo. (ByteArrayN nbi bi, ByteArrayN nbo bo, ByteArrayAccess bi, KnownNat nbi, KnownNat nbo, nbo <= nbi) => bi -> bo

-- | drop the first n byte of a bytearray
drop :: forall (n :: Nat) (nbi :: Nat) (nbo :: Nat) bi bo. (ByteArrayN nbi bi, ByteArrayN nbo bo, ByteArrayAccess bi, KnownNat n, KnownNat nbi, KnownNat nbo, (nbo + n) ~ nbi) => Proxy n -> bi -> bo

-- | append one bytearray to the other
append :: forall (nblhs :: Nat) (nbrhs :: Nat) (nbout :: Nat) blhs brhs bout. (ByteArrayN nblhs blhs, ByteArrayN nbrhs brhs, ByteArrayN nbout bout, ByteArrayAccess blhs, ByteArrayAccess brhs, KnownNat nblhs, KnownNat nbrhs, KnownNat nbout, (nbrhs + nblhs) ~ nbout) => blhs -> brhs -> bout

-- | Duplicate a bytearray into another bytearray, and run an initializer
--   on it
copy :: forall (n :: Nat) bs1 bs2 p. (ByteArrayN n bs1, ByteArrayN n bs2, ByteArrayAccess bs1, KnownNat n) => bs1 -> (Ptr p -> IO ()) -> IO bs2

-- | Similar to copy but also provide a way to return a value from
--   the initializer
copyRet :: forall (n :: Nat) bs1 bs2 p a. (ByteArrayN n bs1, ByteArrayN n bs2, ByteArrayAccess bs1, KnownNat n) => bs1 -> (Ptr p -> IO a) -> IO (a, bs2)

-- | Similiar to copy but expect the resulting bytearray in a pure
--   context
copyAndFreeze :: forall (n :: Nat) bs1 bs2 p. (ByteArrayN n bs1, ByteArrayN n bs2, ByteArrayAccess bs1, KnownNat n) => bs1 -> (Ptr p -> IO ()) -> bs2

-- | Create a bytearray of a specific size containing a repeated byte value
replicate :: forall (n :: Nat) ba. (ByteArrayN n ba, KnownNat n) => Word8 -> ba

-- | Create a bytearray of a specific size initialized to 0
zero :: forall (n :: Nat) ba. (ByteArrayN n ba, KnownNat n) => ba

-- | Convert a bytearray to another type of bytearray
convert :: forall (n :: Nat) bin bout. (ByteArrayN n bin, ByteArrayN n bout, KnownNat n) => bin -> bout

-- | Convert a ByteArrayAccess to another type of bytearray
--   
--   This function returns nothing if the size is not compatible
fromByteArrayAccess :: forall (n :: Nat) bin bout. (ByteArrayAccess bin, ByteArrayN n bout, KnownNat n) => bin -> Maybe bout

-- | Convert a ByteArrayAccess to another type of bytearray
unsafeFromByteArrayAccess :: forall (n :: Nat) bin bout. (ByteArrayAccess bin, ByteArrayN n bout, KnownNat n) => bin -> bout
instance (Data.ByteArray.Types.ByteArrayAccess ba, GHC.Internal.TypeNats.KnownNat n) => Data.ByteArray.Types.ByteArrayAccess (Data.ByteArray.Sized.SizedByteArray n ba)
instance (GHC.Internal.TypeNats.KnownNat n, Data.ByteArray.Types.ByteArray ba) => Data.ByteArray.Sized.ByteArrayN n (Data.ByteArray.Sized.SizedByteArray n ba)
instance GHC.Classes.Eq ba => GHC.Classes.Eq (Data.ByteArray.Sized.SizedByteArray n ba)
instance Data.Memory.Internal.DeepSeq.NFData ba => Data.Memory.Internal.DeepSeq.NFData (Data.ByteArray.Sized.SizedByteArray n ba)
instance GHC.Classes.Ord ba => GHC.Classes.Ord (Data.ByteArray.Sized.SizedByteArray n ba)
instance GHC.Internal.Show.Show ba => GHC.Internal.Show.Show (Data.ByteArray.Sized.SizedByteArray n ba)

-- | A very simple bytearray parser related to Parsec and Attoparsec
--   
--   Simple example:
--   
--   
--   > parse ((,,) <$> take 2 <*> byte 0x20 <*> (bytes "abc" *> anyByte)) "xx abctest"
--   ParseOK "est" ("xx", 116)
--   
module Data.ByteArray.Parse

-- | Simple ByteString parser structure
data Parser byteArray a

-- | Simple parsing result, that represent respectively:
--   
--   
--   
- failure: with the error message
--   
- continuation: that need for more input data
--   
- success: the remaining unparsed data and the parser value
--   
data Result byteArray a
ParseFail :: String -> Result byteArray a
ParseMore :: (Maybe byteArray -> Result byteArray a) -> Result byteArray a
ParseOK :: byteArray -> a -> Result byteArray a

-- | Run a Parser on a ByteString and return a Result
parse :: ByteArrayAccess byteArray => Parser byteArray a -> byteArray -> Result byteArray a

-- | Run a parser on an @initial byteArray.
--   
--   If the Parser need more data than available, the @feeder function is
--   automatically called and fed to the More continuation.
parseFeed :: (ByteArrayAccess byteArray, Monad m) => m (Maybe byteArray) -> Parser byteArray a -> byteArray -> m (Result byteArray a)
hasMore :: ByteArray byteArray => Parser byteArray Bool

-- | Parse a specific byte at current position
--   
--   if the byte is different than the expected on, this parser will raise
--   a failure.
byte :: ByteArray byteArray => Word8 -> Parser byteArray ()

-- | Get the next byte from the parser
anyByte :: ByteArray byteArray => Parser byteArray Word8

-- | Parse a sequence of bytes from current position
--   
--   if the following bytes don't match the expected bytestring completely,
--   the parser will raise a failure
bytes :: (Show ba, Eq ba, ByteArray ba) => ba -> Parser ba ()

-- | Take @n bytes from the current position in the stream
take :: ByteArray byteArray => Int -> Parser byteArray byteArray

-- | Take bytes while the @predicate hold from the current position in the
--   stream
takeWhile :: ByteArray byteArray => (Word8 -> Bool) -> Parser byteArray byteArray

-- | Take the remaining bytes from the current position in the stream
takeAll :: ByteArray byteArray => Parser byteArray byteArray

-- | Skip @n bytes from the current position in the stream
skip :: ByteArray byteArray => Int -> Parser byteArray ()

-- | Skip bytes while the @predicate hold from the current position in the
--   stream
skipWhile :: ByteArray byteArray => (Word8 -> Bool) -> Parser byteArray ()

-- | Skip all the remaining bytes from the current position in the stream
skipAll :: ByteArray byteArray => Parser byteArray ()

-- | Take a storable from the current position in the stream
takeStorable :: (ByteArray byteArray, Storable d) => Parser byteArray d
instance GHC.Internal.Base.Alternative (Data.ByteArray.Parse.Parser byteArray)
instance GHC.Internal.Base.Applicative (Data.ByteArray.Parse.Parser byteArray)
instance GHC.Internal.Base.Functor (Data.ByteArray.Parse.Parser byteArray)
instance GHC.Internal.Control.Monad.Fail.MonadFail (Data.ByteArray.Parse.Parser byteArray)
instance GHC.Internal.Base.Monad (Data.ByteArray.Parse.Parser byteArray)
instance GHC.Internal.Base.MonadPlus (Data.ByteArray.Parse.Parser byteArray)
instance (GHC.Internal.Show.Show ba, GHC.Internal.Show.Show a) => GHC.Internal.Show.Show (Data.ByteArray.Parse.Result ba a)

module Data.ByteArray.Mapping

-- | Transform a bytearray at a specific offset into a Word64 tagged as BE
--   (Big Endian)
--   
--   no bounds checking. unsafe
toW64BE :: ByteArrayAccess bs => bs -> Int -> BE Word64

-- | Transform a bytearray at a specific offset into a Word64 tagged as LE
--   (Little Endian)
--   
--   no bounds checking. unsafe
toW64LE :: ByteArrayAccess bs => bs -> Int -> LE Word64

-- | Serialize a Word64 to a ByteArray in big endian
--   format
fromW64BE :: ByteArray ba => Word64 -> ba

-- | map blocks of 64 bits of a bytearray, creating a new bytestring of
--   equivalent size where each blocks has been mapped through f
--   
--   no length checking is done. unsafe
mapAsWord64 :: ByteArray bs => (Word64 -> Word64) -> bs -> bs

-- | map blocks of 128 bits of a bytearray, creating a new bytestring of
--   equivalent size where each blocks has been mapped through f
--   
--   no length checking is done. unsafe
mapAsWord128 :: ByteArray bs => (Word128 -> Word128) -> bs -> bs

-- | Base conversions for ByteArray.
module Data.ByteArray.Encoding

-- | Encode some bytes to the equivalent representation in a specific
--   Base.
--   
--   
Examples
--   
--   Convert a ByteString to base-64:
--   
--   
--   >>> convertToBase Base64 ("foobar" :: ByteString) :: ByteString
--   "Zm9vYmFy"
--   
convertToBase :: (ByteArrayAccess bin, ByteArray bout) => Base -> bin -> bout

-- | Try to decode some bytes from the equivalent representation in a
--   specific Base.
--   
--   
Examples
--   
--   Successfully convert from base-64 to a ByteString:
--   
--   
--   >>> convertFromBase Base64 ("Zm9vYmFy" :: ByteString) :: Either String ByteString
--   Right "foobar"
--   
--   
--   Trying to decode invalid data will return an error string:
--   
--   
--   >>> convertFromBase Base64 ("!!!" :: ByteString) :: Either String ByteString
--   Left "base64: input: invalid length"
--   
convertFromBase :: (ByteArrayAccess bin, ByteArray bout) => Base -> bin -> Either String bout

-- | The different bases that can be used.
--   
--   See RFC4648 for details. In particular, Base64 can be standard
--   or URL-safe. URL-safe encoding is often used in other
--   specifications without padding characters.
--   
--   RFC 2045 defines a separate Base64 encoding, which is not
--   supported. This format requires a newline at least every 76 encoded
--   characters, which works around limitations of older email programs
--   that could not handle long lines. Be aware that other languages, such
--   as Ruby, encode the RFC 2045 version by default. To decode their
--   output, remove all newlines before decoding.
--   
--   
Examples
--   
--   A quick example to show the differences:
--   
--   
--   >>> let input = "Is 3 > 2?" :: ByteString
--   
--   >>> let convertedTo base = convertToBase base input :: ByteString
--   
--   >>> convertedTo Base16
--   "49732033203e20323f"
--   
--   >>> convertedTo Base32
--   "JFZSAMZAHYQDEPY="
--   
--   >>> convertedTo Base64
--   "SXMgMyA+IDI/"
--   
--   >>> convertedTo Base64URLUnpadded
--   "SXMgMyA-IDI_"
--   
--   >>> convertedTo Base64OpenBSD
--   "QVKeKw.8GBG9"
--   
data Base

-- | similar to hexadecimal
Base16 :: Base
Base32 :: Base

-- | standard Base64
Base64 :: Base

-- | unpadded URL-safe Base64
Base64URLUnpadded :: Base

-- | Base64 as used in OpenBSD password encoding (such as bcrypt)
Base64OpenBSD :: Base
instance GHC.Classes.Eq Data.ByteArray.Encoding.Base
instance GHC.Internal.Show.Show Data.ByteArray.Encoding.Base

-- | Simple and efficient byte array types
--   
--   This module should be imported qualified.
module Data.ByteArray

-- | Class to Access size properties and data of a ByteArray
class ByteArrayAccess ba

-- | Return the length in bytes of a bytearray
length :: ByteArrayAccess ba => ba -> Int

-- | Allow to use using a pointer
withByteArray :: ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a

-- | Copy the data of a bytearray to a ptr
copyByteArrayToPtr :: ByteArrayAccess ba => ba -> Ptr p -> IO ()

-- | Class to allocate new ByteArray of specific size
class (Eq ba, Ord ba, Monoid ba, ByteArrayAccess ba) => ByteArray ba

-- | allocate n bytes and perform the given operation
allocRet :: ByteArray ba => Int -> (Ptr p -> IO a) -> IO (a, ba)

-- | Simplest Byte Array
data Bytes

-- | ScrubbedBytes is a memory chunk which have the properties of:
--   
--   
--   
- Being scrubbed after its goes out of scope.
--   
- A Show instance that doesn't actually show any content
--   
- A Eq instance that is constant time
--   
data ScrubbedBytes

-- | A simple abstraction to a piece of memory.
--   
--   Do beware that garbage collection related to piece of memory could be
--   triggered before this is used.
--   
--   Only use with the appropriate handler has been used (e.g.
--   withForeignPtr on ForeignPtr)
data MemView
MemView :: {-# UNPACK #-} !Ptr Word8 -> {-# UNPACK #-} !Int -> MemView

-- | a view on a given bytes
--   
--   Equality test in constant time
data View bytes

-- | create a view on a given bytearray
--   
--   This function update the offset and the size in order to guarantee:
--   
--   
--   
- offset >= 0
--   
- size >= 0
--   
- offset < length
--   
- size =< length - offset
--   
view :: ByteArrayAccess bytes => bytes -> Int -> Int -> View bytes

-- | create a view from the given bytearray
takeView :: ByteArrayAccess bytes => bytes -> Int -> View bytes

-- | create a view from the given byte array starting after having dropped
--   the fist n bytes
dropView :: ByteArrayAccess bytes => bytes -> Int -> View bytes

-- | return a specific byte indexed by a number from 0 in a bytearray
--   
--   unsafe, no bound checking are done
index :: ByteArrayAccess a => a -> Int -> Word8

-- | Concatenate bytearray into a larger bytearray
concat :: (ByteArrayAccess bin, ByteArray bout) => [bin] -> bout

-- | Create an empty byte array
empty :: ByteArray a => a

-- | returns the first byte, and the remaining bytearray if the bytearray
--   is not null
uncons :: ByteArray a => a -> Maybe (Word8, a)

-- | Check if a byte array is empty
null :: ByteArrayAccess a => a -> Bool

-- | Create a bytearray of a specific size containing a repeated byte value
replicate :: ByteArray ba => Int -> Word8 -> ba

-- | Take the first n byte of a bytearray
take :: ByteArray bs => Int -> bs -> bs

-- | drop the first n byte of a bytearray
drop :: ByteArray bs => Int -> bs -> bs

-- | Split a bytearray at a specific length in two bytearray
splitAt :: ByteArray bs => Int -> bs -> (bs, bs)

-- | Split a bytearray at the point where pred becomes invalid
span :: ByteArray bs => (Word8 -> Bool) -> bs -> (bs, bs)

-- | Reverse a bytearray
reverse :: ByteArray bs => bs -> bs

-- | Check if any element of a byte array satisfies a predicate
any :: ByteArrayAccess ba => (Word8 -> Bool) -> ba -> Bool

-- | Check if all elements of a byte array satisfy a predicate
all :: ByteArrayAccess ba => (Word8 -> Bool) -> ba -> Bool

-- | Create a xor of bytes between a and b.
--   
--   the returns byte array is the size of the smallest input.
xor :: (ByteArrayAccess a, ByteArrayAccess b, ByteArray c) => a -> b -> c

-- | Create a byte array from a single byte
singleton :: ByteArray a => Word8 -> a

-- | prepend a single byte to a byte array
cons :: ByteArray a => Word8 -> a -> a

-- | append one bytearray to the other
append :: ByteArray bs => bs -> bs -> bs

-- | similar to create but hide the allocation and initializer in a
--   pure context
unsafeCreate :: ByteArray a => Int -> (Ptr p -> IO ()) -> a

-- | Allocate a new bytearray of specific size, and run the initializer on
--   this memory
create :: ByteArray ba => Int -> (Ptr p -> IO ()) -> IO ba

-- | Pack a list of bytes into a bytearray
pack :: ByteArray a => [Word8] -> a

-- | Un-pack a bytearray into a list of bytes
unpack :: ByteArrayAccess a => a -> [Word8]

-- | append a single byte to a byte array
snoc :: ByteArray a => a -> Word8 -> a

-- | Duplicate a bytearray into another bytearray, and run an initializer
--   on it
copy :: (ByteArrayAccess bs1, ByteArray bs2) => bs1 -> (Ptr p -> IO ()) -> IO bs2

-- | Check if two bytearray are equals
--   
--   This is not constant time, as soon some byte differs the function will
--   returns. use constEq in sensitive context where timing matters.
eq :: (ByteArrayAccess bs1, ByteArrayAccess bs2) => bs1 -> bs2 -> Bool

-- | Allocate a new bytearray of specific size, and run the initializer on
--   this memory
alloc :: ByteArray ba => Int -> (Ptr p -> IO ()) -> IO ba

-- | similar to alloc but hide the allocation and initializer in a
--   pure context
allocAndFreeze :: ByteArray a => Int -> (Ptr p -> IO ()) -> a

-- | Similar to copy but also provide a way to return a value from
--   the initializer
copyRet :: (ByteArrayAccess bs1, ByteArray bs2) => bs1 -> (Ptr p -> IO a) -> IO (a, bs2)

-- | Similiar to copy but expect the resulting bytearray in a pure
--   context
copyAndFreeze :: (ByteArrayAccess bs1, ByteArray bs2) => bs1 -> (Ptr p -> IO ()) -> bs2

-- | Create a bytearray of a specific size initialized to 0
zero :: ByteArray ba => Int -> ba

-- | Convert a bytearray to another type of bytearray
convert :: (ByteArrayAccess bin, ByteArray bout) => bin -> bout

-- | A constant time equality test for 2 ByteArrayAccess values.
--   
--   If values are of 2 different sizes, the function will abort early
--   without comparing any bytes.
--   
--   compared to == , this function will go over all the bytes present
--   before yielding a result even when knowing the overall result early in
--   the processing.
constEq :: (ByteArrayAccess bs1, ByteArrayAccess bs2) => bs1 -> bs2 -> Bool

-- | Simple Byte Array packer
--   
--   Simple example:
--   
--   
--   > flip pack 20 $ putWord8 0x41 >> putByteString "BCD" >> putWord8 0x20 >> putStorable (42 :: Word32)
--   Right (ABCD *\NUL\NUL\NUL")
--   
--   
--   Original code from https://hackage.haskell.org/package/bspack
--   generalized and adapted to run on memory, and spellchecked /
--   tweaked. (2015-05) Copyright (c) 2014 Nicolas DI PRIMA
module Data.ByteArray.Pack

-- | Simple ByteArray Packer
data Packer a

-- | Packing result:
--   
--   
--   
- PackerMore: the next state of Packing with an arbitrary value
--   
- PackerFail: an error happened
--   
data Result a
PackerMore :: a -> MemView -> Result a
PackerFail :: String -> Result a

-- | Fill a given sized buffer with the result of the Packer action
fill :: ByteArray byteArray => Int -> Packer a -> Either String byteArray

-- | Pack the given packer into the given bytestring

-- | Deprecated: use fill instead
pack :: ByteArray byteArray => Packer a -> Int -> Either String byteArray

-- | put Word8 in the current position in the stream
putWord8 :: Word8 -> Packer ()

-- | put Word16 in the current position in the stream /! use Host
--   Endianness
putWord16 :: Word16 -> Packer ()

-- | put Word32 in the current position in the stream /! use Host
--   Endianness
putWord32 :: Word32 -> Packer ()

-- | Put a storable from the current position in the stream
putStorable :: Storable storable => storable -> Packer ()

-- | Put a Byte Array from the current position in the stream
--   
--   If the ByteArray is null, then do nothing
putBytes :: ByteArrayAccess ba => ba -> Packer ()

-- | Will put the given storable list from the current position in the
--   stream to the end.
--   
--   This function will fail with not enough storage if the given storable
--   can't be written (not enough space)
--   
--   Example:
--   
--   
--   > pack (fillList $ [1..] :: Word8) 9
--   "\1\2\3\4\5\6\7\8\9"
--   > pack (fillList $ [1..] :: Word32) 4
--   "\1\0\0\0"
--   > pack (fillList $ [1..] :: Word32) 64
--   .. <..succesful..>
--   > pack (fillList $ [1..] :: Word32) 1
--   .. <.. not enough space ..>
--   > pack (fillList $ [1..] :: Word32) 131
--   .. <.. not enough space ..>
--   
fillList :: Storable storable => [storable] -> Packer ()

-- | Fill up from the current position in the stream to the end
--   
--   It is equivalent to:
--   
--   
--   fillUpWith s == fillList (repeat s)
--   
fillUpWith :: Storable storable => storable -> Packer ()

-- | Skip some bytes from the current position in the stream
skip :: Int -> Packer ()

-- | Skip the size of a storable from the current position in the stream
skipStorable :: Storable storable => storable -> Packer ()
