-- |
-- Module      : Data.ByteArray.MemView
-- License     : BSD-style
-- Maintainer  : Vincent Hanquez <vincent@snarc.org>
-- Stability   : stable
-- Portability : Good
--
module Data.ByteArray.MemView
    ( MemView(..)
    , memViewPlus
    ) where

import           Foreign.Ptr
import           Data.ByteArray.Types
import           Data.Memory.Internal.Imports

-- | 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
    deriving (Int -> MemView -> ShowS
[MemView] -> ShowS
MemView -> String
(Int -> MemView -> ShowS)
-> (MemView -> String) -> ([MemView] -> ShowS) -> Show MemView
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MemView -> ShowS
showsPrec :: Int -> MemView -> ShowS
$cshow :: MemView -> String
show :: MemView -> String
$cshowList :: [MemView] -> ShowS
showList :: [MemView] -> ShowS
Show,MemView -> MemView -> Bool
(MemView -> MemView -> Bool)
-> (MemView -> MemView -> Bool) -> Eq MemView
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MemView -> MemView -> Bool
== :: MemView -> MemView -> Bool
$c/= :: MemView -> MemView -> Bool
/= :: MemView -> MemView -> Bool
Eq)

instance ByteArrayAccess MemView where
    length :: MemView -> Int
length (MemView Ptr Word8
_ Int
l) = Int
l
    withByteArray :: forall p a. MemView -> (Ptr p -> IO a) -> IO a
withByteArray (MemView Ptr Word8
p Int
_) Ptr p -> IO a
f = Ptr p -> IO a
f (Ptr Word8 -> Ptr p
forall a b. Ptr a -> Ptr b
castPtr Ptr Word8
p)

-- | Increase the memory view while reducing the size of the window
--
-- this is useful as an abstraction to represent the current offset
-- in a buffer, and the remaining bytes left.
memViewPlus :: MemView -> Int -> MemView
memViewPlus :: MemView -> Int -> MemView
memViewPlus (MemView Ptr Word8
p Int
len) Int
n = Ptr Word8 -> Int -> MemView
MemView (Ptr Word8
p Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
n) (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n)