raaz-0.3.11: core/Raaz/Core/Util/ByteString.hs
-- |
--
-- Module : Raaz.Core.Util.ByteString
-- Copyright : (c) Piyush P Kurur, 2019
-- License : Apache-2.0 OR BSD-3-Clause
-- Maintainer : Piyush P Kurur <ppk@iitpkd.ac.in>
-- Stability : experimental
--
{-# LANGUAGE FlexibleContexts #-}
module Raaz.Core.Util.ByteString
( length, replicate
, create, createFrom
, withByteString
, unsafeCopyToPointer
, unsafeNCopyToPointer
) where
import Prelude hiding (length, replicate)
import qualified Data.ByteString as B
import Data.ByteString (ByteString)
import qualified Data.ByteString.Internal as BI
import Data.Word
import Foreign.ForeignPtr (withForeignPtr)
import Foreign.Ptr (castPtr, plusPtr)
import Raaz.Core.Types.Pointer
import Raaz.Core.Types.Copying
-- | A typesafe length for Bytestring
length :: ByteString -> BYTES Int
length = BYTES . B.length
-- | A type safe version of replicate
replicate :: LengthUnit l => l -> Word8 -> ByteString
replicate l = B.replicate sz
where BYTES sz = inBytes l
-- | Copy the bytestring to the crypto buffer. This operation leads to
-- undefined behaviour if the crypto pointer points to an area smaller
-- than the size of the byte string.
unsafeCopyToPointer :: Pointer ptr
=> ByteString -- ^ The source.
-> ptr a -- ^ The destination.
-> IO ()
unsafeCopyToPointer bs cptr = withForeignPtr fptr $
\ p -> memcpy (destination cptr) (source $ p `plusPtr` offset) (BYTES n)
where (fptr, offset,n) = BI.toForeignPtr bs
-- | Similar to `unsafeCopyToPointer` but takes an additional input
-- @n@ which is the number of bytes (expressed in type safe length
-- units) to transfer. This operation leads to undefined behaviour if
-- either the bytestring is shorter than @n@ or the crypto pointer
-- points to an area smaller than @n@.
unsafeNCopyToPointer :: LengthUnit n
=> n -- ^ length of data to be copied
-> ByteString -- ^ The source byte string
-> Ptr a -- ^ The buffer
-> IO ()
unsafeNCopyToPointer n bs cptr = withForeignPtr fptr $
\ p -> memcpy (destination cptr) (source $ p `plusPtr` offset) n
where (fptr, offset,_) = BI.toForeignPtr bs
-- | Works directly on the pointer associated with the
-- `ByteString`. This function should only read and not modify the
-- contents of the pointer.
withByteString :: ByteString -> (Ptr something -> IO a) -> IO a
withByteString bs f = withForeignPtr fptr (f . flip plusPtr off)
where (fptr, off, _) = BI.toForeignPtr bs
-- | The action @create l act@ creates a length @l@ bytestring where
-- the contents are filled using the the @act@ to fill the buffer.
create :: LengthUnit l => l -> (Ptr a -> IO ()) -> IO ByteString
create l act = myCreate (act . castPtr)
where myCreate = BI.create $ fromIntegral $ inBytes l
-- | The IO action @createFrom n cptr@ creates a bytestring by copying
-- @n@ bytes from the pointer @cptr@.
createFrom :: LengthUnit l => l -> Ptr a -> IO ByteString
createFrom l cptr = create l filler
where filler dptr = memcpy (destination dptr) (source cptr) l
---------------------- Hexadecimal encoding. -----------------------------------