module Data.ByteArray.View
( View
, view
, takeView
, dropView
) where
import Data.ByteArray.Methods
import Data.ByteArray.Types
import Data.Memory.PtrMethods
import Data.Memory.Internal.Compat
import Foreign.Ptr (plusPtr)
import Prelude hiding (length, take, drop)
data View bytes = View
{ View bytes -> Int
viewOffset :: !Int
, View bytes -> Int
viewSize :: !Int
, View bytes -> bytes
unView :: !bytes
}
instance ByteArrayAccess bytes => Eq (View bytes) where
== :: View bytes -> View bytes -> Bool
(==) = View bytes -> View bytes -> Bool
forall bs1 bs2.
(ByteArrayAccess bs1, ByteArrayAccess bs2) =>
bs1 -> bs2 -> Bool
constEq
instance ByteArrayAccess bytes => Ord (View bytes) where
compare :: View bytes -> View bytes -> Ordering
compare View bytes
v1 View bytes
v2 = IO Ordering -> Ordering
forall a. IO a -> a
unsafeDoIO (IO Ordering -> Ordering) -> IO Ordering -> Ordering
forall a b. (a -> b) -> a -> b
$
View bytes -> (Ptr Word8 -> IO Ordering) -> IO Ordering
forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray View bytes
v1 ((Ptr Word8 -> IO Ordering) -> IO Ordering)
-> (Ptr Word8 -> IO Ordering) -> IO Ordering
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
ptr1 ->
View bytes -> (Ptr Word8 -> IO Ordering) -> IO Ordering
forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray View bytes
v2 ((Ptr Word8 -> IO Ordering) -> IO Ordering)
-> (Ptr Word8 -> IO Ordering) -> IO Ordering
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
ptr2 -> do
Ordering
ret <- Ptr Word8 -> Ptr Word8 -> Int -> IO Ordering
memCompare Ptr Word8
ptr1 Ptr Word8
ptr2 (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min (View bytes -> Int
forall bytes. View bytes -> Int
viewSize View bytes
v1) (View bytes -> Int
forall bytes. View bytes -> Int
viewSize View bytes
v2))
Ordering -> IO Ordering
forall (m :: * -> *) a. Monad m => a -> m a
return (Ordering -> IO Ordering) -> Ordering -> IO Ordering
forall a b. (a -> b) -> a -> b
$ case Ordering
ret of
Ordering
EQ | View bytes -> Int
forall ba. ByteArrayAccess ba => ba -> Int
length View bytes
v1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> View bytes -> Int
forall ba. ByteArrayAccess ba => ba -> Int
length View bytes
v2 -> Ordering
GT
| View bytes -> Int
forall ba. ByteArrayAccess ba => ba -> Int
length View bytes
v1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< View bytes -> Int
forall ba. ByteArrayAccess ba => ba -> Int
length View bytes
v2 -> Ordering
LT
| View bytes -> Int
forall ba. ByteArrayAccess ba => ba -> Int
length View bytes
v1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== View bytes -> Int
forall ba. ByteArrayAccess ba => ba -> Int
length View bytes
v2 -> Ordering
EQ
Ordering
_ -> Ordering
ret
instance ByteArrayAccess bytes => Show (View bytes) where
showsPrec :: Int -> View bytes -> ShowS
showsPrec Int
p View bytes
v String
r = Int -> String -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
p (View bytes -> ShowS
forall bytes. ByteArrayAccess bytes => View bytes -> ShowS
viewUnpackChars View bytes
v []) String
r
instance ByteArrayAccess bytes => ByteArrayAccess (View bytes) where
length :: View bytes -> Int
length = View bytes -> Int
forall bytes. View bytes -> Int
viewSize
withByteArray :: View bytes -> (Ptr p -> IO a) -> IO a
withByteArray View bytes
v Ptr p -> IO a
f = bytes -> (Ptr Any -> IO a) -> IO a
forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray (View bytes -> bytes
forall bytes. View bytes -> bytes
unView View bytes
v) ((Ptr Any -> IO a) -> IO a) -> (Ptr Any -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \Ptr Any
ptr -> Ptr p -> IO a
f (Ptr Any
ptr Ptr Any -> Int -> Ptr p
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` (View bytes -> Int
forall bytes. View bytes -> Int
viewOffset View bytes
v))
viewUnpackChars :: ByteArrayAccess bytes
=> View bytes
-> String
-> String
viewUnpackChars :: View bytes -> ShowS
viewUnpackChars View bytes
v String
xs = Int -> String
chunkLoop Int
0
where
len :: Int
len = View bytes -> Int
forall ba. ByteArrayAccess ba => ba -> Int
length View bytes
v
chunkLoop :: Int -> [Char]
chunkLoop :: Int -> String
chunkLoop Int
idx
| Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
idx = []
| (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
idx) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
63 =
Int -> Int -> ShowS
bytesLoop Int
idx (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
64) (Int -> String
chunkLoop (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
64))
| Bool
otherwise =
Int -> Int -> ShowS
bytesLoop Int
idx (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
idx) String
xs
bytesLoop :: Int -> Int -> [Char] -> [Char]
bytesLoop :: Int -> Int -> ShowS
bytesLoop Int
idx Int
chunkLenM1 String
paramAcc =
Int -> ShowS
loop (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
chunkLenM1 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) String
paramAcc
where
loop :: Int -> ShowS
loop Int
i String
acc
| Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
idx = (Int -> Char
rChar Int
i Char -> ShowS
forall a. a -> [a] -> [a]
: String
acc)
| Bool
otherwise = Int -> ShowS
loop (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) (Int -> Char
rChar Int
i Char -> ShowS
forall a. a -> [a] -> [a]
: String
acc)
rChar :: Int -> Char
rChar :: Int -> Char
rChar Int
idx = Int -> Char
forall a. Enum a => Int -> a
toEnum (Int -> Char) -> Int -> Char
forall a b. (a -> b) -> a -> b
$ Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Int) -> Word8 -> Int
forall a b. (a -> b) -> a -> b
$ View bytes -> Int -> Word8
forall a. ByteArrayAccess a => a -> Int -> Word8
index View bytes
v Int
idx
view :: ByteArrayAccess bytes
=> bytes
-> Int
-> Int
-> View bytes
view :: bytes -> Int -> Int -> View bytes
view bytes
b Int
offset'' Int
size'' = Int -> Int -> bytes -> View bytes
forall bytes. Int -> Int -> bytes -> View bytes
View Int
offset Int
size bytes
b
where
offset' :: Int
offset' :: Int
offset' = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
offset'' Int
0
offset :: Int
offset :: Int
offset = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
offset' (bytes -> Int
forall ba. ByteArrayAccess ba => ba -> Int
length bytes
b Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
size' :: Int
size' :: Int
size' = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
size'' Int
0
size :: Int
size :: Int
size = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
size' (bytes -> Int
forall ba. ByteArrayAccess ba => ba -> Int
length bytes
b Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
offset)
takeView :: ByteArrayAccess bytes
=> bytes
-> Int
-> View bytes
takeView :: bytes -> Int -> View bytes
takeView bytes
b Int
size = bytes -> Int -> Int -> View bytes
forall bytes.
ByteArrayAccess bytes =>
bytes -> Int -> Int -> View bytes
view bytes
b Int
0 Int
size
dropView :: ByteArrayAccess bytes
=> bytes
-> Int
-> View bytes
dropView :: bytes -> Int -> View bytes
dropView bytes
b Int
offset = bytes -> Int -> Int -> View bytes
forall bytes.
ByteArrayAccess bytes =>
bytes -> Int -> Int -> View bytes
view bytes
b Int
offset (bytes -> Int
forall ba. ByteArrayAccess ba => ba -> Int
length bytes
b Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
offset)