module Data.ByteArray.Types
( ByteArrayAccess(..)
, ByteArray(..)
) where
import Foreign.Ptr
import Data.Monoid
#ifdef WITH_BYTESTRING_SUPPORT
import qualified Data.ByteString as B (length)
import qualified Data.ByteString.Internal as B
import Foreign.ForeignPtr (withForeignPtr)
#endif
#ifdef WITH_FOUNDATION_SUPPORT
import qualified Foundation as F
import qualified Foundation.Collection as F
import qualified Foundation.String as F (toBytes, Encoding(UTF8))
import qualified Foundation.Array.Internal as F
#endif
class ByteArrayAccess ba where
length :: ba -> Int
withByteArray :: ba -> (Ptr p -> IO a) -> IO a
class (Eq ba, Ord ba, Monoid ba, ByteArrayAccess ba) => ByteArray ba where
allocRet :: Int -> (Ptr p -> IO a) -> IO (a, ba)
#ifdef WITH_BYTESTRING_SUPPORT
instance ByteArrayAccess B.ByteString where
length = B.length
withByteArray (B.PS fptr off _) f = withForeignPtr fptr $ \ptr -> f $! (ptr `plusPtr` off)
instance ByteArray B.ByteString where
allocRet sz f = do
fptr <- B.mallocByteString sz
r <- withForeignPtr fptr (f . castPtr)
return (r, B.PS fptr 0 sz)
#endif
#ifdef WITH_FOUNDATION_SUPPORT
uarrayRecastW8 :: F.PrimType ty => F.UArray ty -> F.UArray F.Word8
uarrayRecastW8 = F.recast
instance F.PrimType ty => ByteArrayAccess (F.UArray ty) where
length = F.length . uarrayRecastW8
withByteArray a f = F.withPtr (uarrayRecastW8 a) (f . castPtr)
instance ByteArrayAccess F.String where
length = F.length
withByteArray s f = withByteArray (F.toBytes F.UTF8 s) f
instance (Ord ty, F.PrimType ty) => ByteArray (F.UArray ty) where
allocRet sz f = do
mba <- F.new (F.Size sz)
a <- F.withMutablePtr mba (f . castPtr)
ba <- F.unsafeFreeze mba
return (a, ba)
#endif