{-# LANGUAGE FlexibleContexts #-}
module Raaz.Core.Util.ByteString
( length, replicate
, fromByteStringStorable
, 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 Foreign.Storable (peek, Storable)
import System.IO.Unsafe (unsafePerformIO)
import Raaz.Core.Types.Pointer
import Raaz.Core.Types.Copying
length :: ByteString -> BYTES Int
length = BYTES . B.length
replicate :: LengthUnit l => l -> Word8 -> ByteString
replicate l = B.replicate sz
where BYTES sz = inBytes l
unsafeCopyToPointer :: ByteString
-> Pointer
-> IO ()
unsafeCopyToPointer bs cptr = withForeignPtr fptr $
\ p -> memcpy dptr (source $ p `plusPtr` offset) (BYTES n)
where (fptr, offset,n) = BI.toForeignPtr bs
dptr = destination $ castPtr cptr
unsafeNCopyToPointer :: LengthUnit n
=> n
-> ByteString
-> Pointer
-> IO ()
unsafeNCopyToPointer n bs cptr = withForeignPtr fptr $
\ p -> memcpy dptr (source $ p `plusPtr` offset) n
where (fptr, offset,_) = BI.toForeignPtr bs
dptr = destination $ castPtr cptr
withByteString :: ByteString -> (Pointer -> IO a) -> IO a
withByteString bs f = withForeignPtr fptr (f . flip plusPtr off . castPtr)
where (fptr, off, _) = BI.toForeignPtr bs
fromByteStringStorable :: Storable k => ByteString -> k
fromByteStringStorable str = unsafePerformIO $ withByteString str (peek . castPtr)
create :: LengthUnit l => l -> (Pointer -> IO ()) -> IO ByteString
create l act = myCreate (act . castPtr)
where myCreate = BI.create $ fromIntegral $ inBytes l
createFrom :: LengthUnit l => l -> Pointer -> IO ByteString
createFrom l cptr = create l filler
where filler dptr = memcpy (destination $ castPtr dptr) (source cptr) l