{-# LANGUAGE FlexibleInstances, ScopedTypeVariables, Rank2Types #-}moduleGeneral.Binary(BinaryOp (..),binaryOpMap ,binarySplit ,binarySplit2 ,binarySplit3 ,unsafeBinarySplit ,Builder (..),runBuilder ,sizeBuilder ,BinaryEx (..),Storable,putExStorable ,getExStorable ,putExStorableList ,getExStorableList ,putExList ,getExList ,putExN ,getExN )whereimportDevelopment.Shake.Classes importControl.MonadimportData.BinaryimportData.List.ExtraimportData.Tuple.ExtraimportForeign.Marshal.UtilsimportForeign.StorableimportForeign.PtrimportSystem.IO.UnsafeasUimportqualifiedData.ByteStringasBSimportqualifiedData.ByteString.InternalasBSimportqualifiedData.ByteString.UnsafeasBSimportqualifiedData.ByteString.LazyasLBSimportqualifiedData.ByteString.UTF8asUTF8importData.SemigroupimportPrelude----------------------------------------------------------------------- STORE TYPE-- | An explicit and more efficient version of BinarydataBinaryOp v =BinaryOp {forall v. BinaryOp v -> v -> Builder
putOp ::v ->Builder ,forall v. BinaryOp v -> ByteString -> v
getOp ::BS.ByteString->v }binaryOpMap ::BinaryEx a =>(a ->BinaryOp b )->BinaryOp (a ,b )binaryOpMap :: forall a b. BinaryEx a => (a -> BinaryOp b) -> BinaryOp (a, b)
binaryOpMap a -> BinaryOp b
mp =BinaryOp {putOp :: (a, b) -> Builder
putOp =\(a
a ,b
b )->Builder -> Builder
putExN (a -> Builder
forall a. BinaryEx a => a -> Builder
putEx a
a )Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<>BinaryOp b -> b -> Builder
forall v. BinaryOp v -> v -> Builder
putOp (a -> BinaryOp b
mp a
a )b
b ,getOp :: ByteString -> (a, b)
getOp =\ByteString
bs ->let(ByteString
bs1 ,ByteString
bs2 )=ByteString -> (ByteString, ByteString)
getExN ByteString
bs ;a :: a
a =ByteString -> a
forall a. BinaryEx a => ByteString -> a
getEx ByteString
bs1 in(a
a ,BinaryOp b -> ByteString -> b
forall v. BinaryOp v -> ByteString -> v
getOp (a -> BinaryOp b
mp a
a )ByteString
bs2 )}binarySplit ::foralla .Storablea =>BS.ByteString->(a ,BS.ByteString)binarySplit :: forall a. Storable a => ByteString -> (a, ByteString)
binarySplit ByteString
bs |ByteString -> Int
BS.lengthByteString
bs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<a -> Int
forall a. Storable a => a -> Int
sizeOf(a
forall a. HasCallStack => a
undefined::a )=[Char] -> (a, ByteString)
forall a. HasCallStack => [Char] -> a
error[Char]
"Reading from ByteString, insufficient left"|Bool
otherwise=ByteString -> (a, ByteString)
forall a. Storable a => ByteString -> (a, ByteString)
unsafeBinarySplit ByteString
bs binarySplit2 ::foralla b .(Storablea ,Storableb )=>BS.ByteString->(a ,b ,BS.ByteString)binarySplit2 :: forall a b.
(Storable a, Storable b) =>
ByteString -> (a, b, ByteString)
binarySplit2 ByteString
bs |ByteString -> Int
BS.lengthByteString
bs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<a -> Int
forall a. Storable a => a -> Int
sizeOf(a
forall a. HasCallStack => a
undefined::a )Int -> Int -> Int
forall a. Num a => a -> a -> a
+b -> Int
forall a. Storable a => a -> Int
sizeOf(b
forall a. HasCallStack => a
undefined::b )=[Char] -> (a, b, ByteString)
forall a. HasCallStack => [Char] -> a
error[Char]
"Reading from ByteString, insufficient left"|(a
a ,ByteString
bs )<-ByteString -> (a, ByteString)
forall a. Storable a => ByteString -> (a, ByteString)
unsafeBinarySplit ByteString
bs ,(b
b ,ByteString
bs )<-ByteString -> (b, ByteString)
forall a. Storable a => ByteString -> (a, ByteString)
unsafeBinarySplit ByteString
bs =(a
a ,b
b ,ByteString
bs )binarySplit3 ::foralla b c .(Storablea ,Storableb ,Storablec )=>BS.ByteString->(a ,b ,c ,BS.ByteString)binarySplit3 :: forall a b c.
(Storable a, Storable b, Storable c) =>
ByteString -> (a, b, c, ByteString)
binarySplit3 ByteString
bs |ByteString -> Int
BS.lengthByteString
bs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<a -> Int
forall a. Storable a => a -> Int
sizeOf(a
forall a. HasCallStack => a
undefined::a )Int -> Int -> Int
forall a. Num a => a -> a -> a
+b -> Int
forall a. Storable a => a -> Int
sizeOf(b
forall a. HasCallStack => a
undefined::b )Int -> Int -> Int
forall a. Num a => a -> a -> a
+c -> Int
forall a. Storable a => a -> Int
sizeOf(c
forall a. HasCallStack => a
undefined::c )=[Char] -> (a, b, c, ByteString)
forall a. HasCallStack => [Char] -> a
error[Char]
"Reading from ByteString, insufficient left"|(a
a ,ByteString
bs )<-ByteString -> (a, ByteString)
forall a. Storable a => ByteString -> (a, ByteString)
unsafeBinarySplit ByteString
bs ,(b
b ,ByteString
bs )<-ByteString -> (b, ByteString)
forall a. Storable a => ByteString -> (a, ByteString)
unsafeBinarySplit ByteString
bs ,(c
c ,ByteString
bs )<-ByteString -> (c, ByteString)
forall a. Storable a => ByteString -> (a, ByteString)
unsafeBinarySplit ByteString
bs =(a
a ,b
b ,c
c ,ByteString
bs )unsafeBinarySplit ::Storablea =>BS.ByteString->(a ,BS.ByteString)unsafeBinarySplit :: forall a. Storable a => ByteString -> (a, ByteString)
unsafeBinarySplit ByteString
bs =(a
v ,Int -> ByteString -> ByteString
BS.unsafeDrop(a -> Int
forall a. Storable a => a -> Int
sizeOfa
v )ByteString
bs )wherev :: a
v =IO a -> a
forall a. IO a -> a
unsafePerformIO(IO a -> a) -> IO a -> a
forall a b. (a -> b) -> a -> b
$ByteString -> (CString -> IO a) -> IO a
forall a. ByteString -> (CString -> IO a) -> IO a
BS.unsafeUseAsCStringByteString
bs ((CString -> IO a) -> IO a) -> (CString -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$\CString
ptr ->Ptr a -> IO a
forall a. Storable a => Ptr a -> IO a
peek(CString -> Ptr a
forall a b. Ptr a -> Ptr b
castPtrCString
ptr )-- forM for zipWithfor2M_ :: [a] -> [b] -> (a -> b -> m c) -> m ()
for2M_ [a]
as [b]
bs a -> b -> m c
f =(a -> b -> m c) -> [a] -> [b] -> m ()
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m ()
zipWithM_a -> b -> m c
f [a]
as [b]
bs ----------------------------------------------------------------------- BINARY SERIALISATION-- We can't use the Data.ByteString builder as that doesn't track the size of the chunk.dataBuilder =Builder {-# UNPACK#-}!Int(foralla .Ptra ->Int->IO())sizeBuilder ::Builder ->IntsizeBuilder :: Builder -> Int
sizeBuilder (Builder Int
i forall a. Ptr a -> Int -> IO ()
_)=Int
i runBuilder ::Builder ->BS.ByteStringrunBuilder :: Builder -> ByteString
runBuilder (Builder Int
i forall a. Ptr a -> Int -> IO ()
f )=IO ByteString -> ByteString
forall a. IO a -> a
unsafePerformIO(IO ByteString -> ByteString) -> IO ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$Int -> (Ptr Word8 -> IO ()) -> IO ByteString
BS.createInt
i ((Ptr Word8 -> IO ()) -> IO ByteString)
-> (Ptr Word8 -> IO ()) -> IO ByteString
forall a b. (a -> b) -> a -> b
$\Ptr Word8
ptr ->Ptr Word8 -> Int -> IO ()
forall a. Ptr a -> Int -> IO ()
f Ptr Word8
ptr Int
0instanceSemigroupBuilder where(Builder Int
x1 forall a. Ptr a -> Int -> IO ()
x2 )<> :: Builder -> Builder -> Builder
<>(Builder Int
y1 forall a. Ptr a -> Int -> IO ()
y2 )=Int -> (forall a. Ptr a -> Int -> IO ()) -> Builder
Builder (Int
x1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
y1 )((forall a. Ptr a -> Int -> IO ()) -> Builder)
-> (forall a. Ptr a -> Int -> IO ()) -> Builder
forall a b. (a -> b) -> a -> b
$\Ptr a
p Int
i ->doPtr a -> Int -> IO ()
forall a. Ptr a -> Int -> IO ()
x2 Ptr a
p Int
i ;Ptr a -> Int -> IO ()
forall a. Ptr a -> Int -> IO ()
y2 Ptr a
p (Int -> IO ()) -> Int -> IO ()
forall a b. (a -> b) -> a -> b
$Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
x1 instanceMonoidBuilder wheremempty :: Builder
mempty=Int -> (forall a. Ptr a -> Int -> IO ()) -> Builder
Builder Int
0((forall a. Ptr a -> Int -> IO ()) -> Builder)
-> (forall a. Ptr a -> Int -> IO ()) -> Builder
forall a b. (a -> b) -> a -> b
$\Ptr a
_Int
_->() -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure()mappend :: Builder -> Builder -> Builder
mappend=Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
(<>)-- | Methods for Binary serialisation that go directly between strict ByteString values.-- When the Database is read each key/value will be loaded as a separate ByteString,-- and for certain types (e.g. file rules) this may remain the preferred format for storing keys.-- Optimised for performance.classBinaryEx a whereputEx ::a ->Builder getEx ::BS.ByteString->a instanceBinaryEx BS.ByteStringwhereputEx :: ByteString -> Builder
putEx ByteString
x =Int -> (forall a. Ptr a -> Int -> IO ()) -> Builder
Builder Int
n ((forall a. Ptr a -> Int -> IO ()) -> Builder)
-> (forall a. Ptr a -> Int -> IO ()) -> Builder
forall a b. (a -> b) -> a -> b
$\Ptr a
ptr Int
i ->ByteString -> (CString -> IO ()) -> IO ()
forall a. ByteString -> (CString -> IO a) -> IO a
BS.unsafeUseAsCStringByteString
x ((CString -> IO ()) -> IO ()) -> (CString -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$\CString
bs ->Ptr Any -> Ptr Any -> Int -> IO ()
forall a. Ptr a -> Ptr a -> Int -> IO ()
copyBytes(Ptr a
ptr Ptr a -> Int -> Ptr Any
forall a b. Ptr a -> Int -> Ptr b
`plusPtr`Int
i )(CString -> Ptr Any
forall a b. Ptr a -> Ptr b
castPtrCString
bs )(Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegralInt
n )wheren :: Int
n =ByteString -> Int
BS.lengthByteString
x getEx :: ByteString -> ByteString
getEx =ByteString -> ByteString
forall a. a -> a
idinstanceBinaryEx LBS.ByteStringwhereputEx :: ByteString -> Builder
putEx ByteString
x =Int -> (forall a. Ptr a -> Int -> IO ()) -> Builder
Builder (Int64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral(Int64 -> Int) -> Int64 -> Int
forall a b. (a -> b) -> a -> b
$ByteString -> Int64
LBS.lengthByteString
x )((forall a. Ptr a -> Int -> IO ()) -> Builder)
-> (forall a. Ptr a -> Int -> IO ()) -> Builder
forall a b. (a -> b) -> a -> b
$\Ptr a
ptr Int
i ->doletgo :: Int -> [ByteString] -> IO ()
go Int
_[]=() -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure()go Int
i (ByteString
x :[ByteString]
xs )=doletn :: Int
n =ByteString -> Int
BS.lengthByteString
x ByteString -> (CString -> IO ()) -> IO ()
forall a. ByteString -> (CString -> IO a) -> IO a
BS.unsafeUseAsCStringByteString
x ((CString -> IO ()) -> IO ()) -> (CString -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$\CString
bs ->Ptr Any -> Ptr Any -> Int -> IO ()
forall a. Ptr a -> Ptr a -> Int -> IO ()
copyBytes(Ptr a
ptr Ptr a -> Int -> Ptr Any
forall a b. Ptr a -> Int -> Ptr b
`plusPtr`Int
i )(CString -> Ptr Any
forall a b. Ptr a -> Ptr b
castPtrCString
bs )(Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegralInt
n )Int -> [ByteString] -> IO ()
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
n )[ByteString]
xs Int -> [ByteString] -> IO ()
go Int
i ([ByteString] -> IO ()) -> [ByteString] -> IO ()
forall a b. (a -> b) -> a -> b
$ByteString -> [ByteString]
LBS.toChunksByteString
x getEx :: ByteString -> ByteString
getEx =[ByteString] -> ByteString
LBS.fromChunks([ByteString] -> ByteString)
-> (ByteString -> [ByteString]) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
.ByteString -> [ByteString]
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pureinstanceBinaryEx [BS.ByteString]where-- Format:-- n :: Word32 - number of strings-- ns :: [Word32]{n} - length of each string-- contents of each string concatenated (sum ns bytes)putEx :: [ByteString] -> Builder
putEx [ByteString]
xs =Int -> (forall a. Ptr a -> Int -> IO ()) -> Builder
Builder (Int
4Int -> Int -> Int
forall a. Num a => a -> a -> a
+(Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
4)Int -> Int -> Int
forall a. Num a => a -> a -> a
+[Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum[Int]
ns )((forall a. Ptr a -> Int -> IO ()) -> Builder)
-> (forall a. Ptr a -> Int -> IO ()) -> Builder
forall a b. (a -> b) -> a -> b
$\Ptr a
p Int
i ->doPtr a -> Int -> Word32 -> IO ()
forall b. Ptr b -> Int -> Word32 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOffPtr a
p Int
i (Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegralInt
n ::Word32)[Int] -> [Int] -> (Int -> Int -> IO ()) -> IO ()
forall {m :: * -> *} {a} {b} {c}.
Applicative m =>
[a] -> [b] -> (a -> b -> m c) -> m ()
for2M_ [Int
4Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
i ,Int
8Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
i ..][Int]
ns ((Int -> Int -> IO ()) -> IO ()) -> (Int -> Int -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$\Int
i Int
x ->Ptr a -> Int -> Word32 -> IO ()
forall b. Ptr b -> Int -> Word32 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOffPtr a
p Int
i (Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegralInt
x ::Word32)Ptr Any
p <-Ptr Any -> IO (Ptr Any)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure(Ptr Any -> IO (Ptr Any)) -> Ptr Any -> IO (Ptr Any)
forall a b. (a -> b) -> a -> b
$Ptr a
p Ptr a -> Int -> Ptr Any
forall a b. Ptr a -> Int -> Ptr b
`plusPtr`(Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
4Int -> Int -> Int
forall a. Num a => a -> a -> a
+(Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
4))[Int] -> [ByteString] -> (Int -> ByteString -> IO ()) -> IO ()
forall {m :: * -> *} {a} {b} {c}.
Applicative m =>
[a] -> [b] -> (a -> b -> m c) -> m ()
for2M_ ((Int -> Int -> Int) -> Int -> [Int] -> [Int]
forall b a. (b -> a -> b) -> b -> [a] -> [b]
scanlInt -> Int -> Int
forall a. Num a => a -> a -> a
(+)Int
0[Int]
ns )[ByteString]
xs ((Int -> ByteString -> IO ()) -> IO ())
-> (Int -> ByteString -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$\Int
i ByteString
x ->ByteString -> (CStringLen -> IO ()) -> IO ()
forall a. ByteString -> (CStringLen -> IO a) -> IO a
BS.unsafeUseAsCStringLenByteString
x ((CStringLen -> IO ()) -> IO ()) -> (CStringLen -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$\(CString
bs ,Int
n )->Ptr Any -> Ptr Any -> Int -> IO ()
forall a. Ptr a -> Ptr a -> Int -> IO ()
copyBytes(Ptr Any
p Ptr Any -> Int -> Ptr Any
forall a b. Ptr a -> Int -> Ptr b
`plusPtr`Int
i )(CString -> Ptr Any
forall a b. Ptr a -> Ptr b
castPtrCString
bs )(Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegralInt
n )wherens :: [Int]
ns =(ByteString -> Int) -> [ByteString] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
mapByteString -> Int
BS.length[ByteString]
xs n :: Int
n =[Int] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length[Int]
ns getEx :: ByteString -> [ByteString]
getEx ByteString
bs =IO [ByteString] -> [ByteString]
forall a. IO a -> a
unsafePerformIO(IO [ByteString] -> [ByteString])
-> IO [ByteString] -> [ByteString]
forall a b. (a -> b) -> a -> b
$ByteString -> (CString -> IO [ByteString]) -> IO [ByteString]
forall a. ByteString -> (CString -> IO a) -> IO a
BS.unsafeUseAsCStringByteString
bs ((CString -> IO [ByteString]) -> IO [ByteString])
-> (CString -> IO [ByteString]) -> IO [ByteString]
forall a b. (a -> b) -> a -> b
$\CString
p ->doInt
n <-Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral(Word32 -> Int) -> IO Word32 -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>(CString -> Int -> IO Word32
forall b. Ptr b -> Int -> IO Word32
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOffCString
p Int
0::IOWord32)[Word32]
ns ::[Word32]<-[Int] -> (Int -> IO Word32) -> IO [Word32]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM[Int
1..Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegralInt
n ]((Int -> IO Word32) -> IO [Word32])
-> (Int -> IO Word32) -> IO [Word32]
forall a b. (a -> b) -> a -> b
$\Int
i ->CString -> Int -> IO Word32
forall b. Ptr b -> Int -> IO Word32
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOffCString
p (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
4)[ByteString] -> IO [ByteString]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure([ByteString] -> IO [ByteString])
-> [ByteString] -> IO [ByteString]
forall a b. (a -> b) -> a -> b
$(ByteString, [ByteString]) -> [ByteString]
forall a b. (a, b) -> b
snd((ByteString, [ByteString]) -> [ByteString])
-> (ByteString, [ByteString]) -> [ByteString]
forall a b. (a -> b) -> a -> b
$(ByteString -> Word32 -> (ByteString, ByteString))
-> ByteString -> [Word32] -> (ByteString, [ByteString])
forall (t :: * -> *) s a b.
Traversable t =>
(s -> a -> (s, b)) -> s -> t a -> (s, t b)
mapAccumL(\ByteString
bs Word32
i ->(ByteString, ByteString) -> (ByteString, ByteString)
forall a b. (a, b) -> (b, a)
swap((ByteString, ByteString) -> (ByteString, ByteString))
-> (ByteString, ByteString) -> (ByteString, ByteString)
forall a b. (a -> b) -> a -> b
$Int -> ByteString -> (ByteString, ByteString)
BS.splitAt(Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegralWord32
i )ByteString
bs )(Int -> ByteString -> ByteString
BS.drop(Int
4Int -> Int -> Int
forall a. Num a => a -> a -> a
+(Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
4))ByteString
bs )[Word32]
ns instanceBinaryEx ()whereputEx :: () -> Builder
putEx ()=Builder
forall a. Monoid a => a
memptygetEx :: ByteString -> ()
getEx ByteString
_=()instanceBinaryEx StringwhereputEx :: [Char] -> Builder
putEx =ByteString -> Builder
forall a. BinaryEx a => a -> Builder
putEx (ByteString -> Builder)
-> ([Char] -> ByteString) -> [Char] -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
.[Char] -> ByteString
UTF8.fromStringgetEx :: ByteString -> [Char]
getEx =ByteString -> [Char]
UTF8.toStringinstanceBinaryEx (MaybeString)whereputEx :: Maybe [Char] -> Builder
putEx Maybe [Char]
Nothing=Builder
forall a. Monoid a => a
memptyputEx (Just[Char]
xs )=ByteString -> Builder
forall a. BinaryEx a => a -> Builder
putEx (ByteString -> Builder) -> ByteString -> Builder
forall a b. (a -> b) -> a -> b
$[Char] -> ByteString
UTF8.fromString([Char] -> ByteString) -> [Char] -> ByteString
forall a b. (a -> b) -> a -> b
$Char
'0円'Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:[Char]
xs getEx :: ByteString -> Maybe [Char]
getEx =((Char, [Char]) -> [Char]) -> Maybe (Char, [Char]) -> Maybe [Char]
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap(Char, [Char]) -> [Char]
forall a b. (a, b) -> b
snd(Maybe (Char, [Char]) -> Maybe [Char])
-> (ByteString -> Maybe (Char, [Char]))
-> ByteString
-> Maybe [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.[Char] -> Maybe (Char, [Char])
forall a. [a] -> Maybe (a, [a])
uncons([Char] -> Maybe (Char, [Char]))
-> (ByteString -> [Char]) -> ByteString -> Maybe (Char, [Char])
forall b c a. (b -> c) -> (a -> b) -> a -> c
.ByteString -> [Char]
UTF8.toStringinstanceBinaryEx [String]whereputEx :: [[Char]] -> Builder
putEx =[ByteString] -> Builder
forall a. BinaryEx a => a -> Builder
putEx ([ByteString] -> Builder)
-> ([[Char]] -> [ByteString]) -> [[Char]] -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
.([Char] -> ByteString) -> [[Char]] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
map[Char] -> ByteString
UTF8.fromStringgetEx :: ByteString -> [[Char]]
getEx =(ByteString -> [Char]) -> [ByteString] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
mapByteString -> [Char]
UTF8.toString([ByteString] -> [[Char]])
-> (ByteString -> [ByteString]) -> ByteString -> [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.ByteString -> [ByteString]
forall a. BinaryEx a => ByteString -> a
getEx instanceBinaryEx (String,[String])whereputEx :: ([Char], [[Char]]) -> Builder
putEx ([Char]
a ,[[Char]]
bs )=[[Char]] -> Builder
forall a. BinaryEx a => a -> Builder
putEx ([[Char]] -> Builder) -> [[Char]] -> Builder
forall a b. (a -> b) -> a -> b
$[Char]
a [Char] -> [[Char]] -> [[Char]]
forall a. a -> [a] -> [a]
:[[Char]]
bs getEx :: ByteString -> ([Char], [[Char]])
getEx ByteString
x =let[Char]
a :[[Char]]
bs =ByteString -> [[Char]]
forall a. BinaryEx a => ByteString -> a
getEx ByteString
x in([Char]
a ,[[Char]]
bs )instanceBinaryEx BoolwhereputEx :: Bool -> Builder
putEx Bool
False=Int -> (forall a. Ptr a -> Int -> IO ()) -> Builder
Builder Int
1((forall a. Ptr a -> Int -> IO ()) -> Builder)
-> (forall a. Ptr a -> Int -> IO ()) -> Builder
forall a b. (a -> b) -> a -> b
$\Ptr a
ptr Int
i ->Ptr a -> Int -> Word8 -> IO ()
forall b. Ptr b -> Int -> Word8 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOffPtr a
ptr Int
i (Word8
0::Word8)putEx Bool
True=Builder
forall a. Monoid a => a
memptygetEx :: ByteString -> Bool
getEx =ByteString -> Bool
BS.nullinstanceBinaryEx Word8whereputEx :: Word8 -> Builder
putEx =Word8 -> Builder
forall a. Storable a => a -> Builder
putExStorable getEx :: ByteString -> Word8
getEx =ByteString -> Word8
forall a. Storable a => ByteString -> a
getExStorable instanceBinaryEx Word16whereputEx :: Word16 -> Builder
putEx =Word16 -> Builder
forall a. Storable a => a -> Builder
putExStorable getEx :: ByteString -> Word16
getEx =ByteString -> Word16
forall a. Storable a => ByteString -> a
getExStorable instanceBinaryEx Word32whereputEx :: Word32 -> Builder
putEx =Word32 -> Builder
forall a. Storable a => a -> Builder
putExStorable getEx :: ByteString -> Word32
getEx =ByteString -> Word32
forall a. Storable a => ByteString -> a
getExStorable instanceBinaryEx IntwhereputEx :: Int -> Builder
putEx =Int -> Builder
forall a. Storable a => a -> Builder
putExStorable getEx :: ByteString -> Int
getEx =ByteString -> Int
forall a. Storable a => ByteString -> a
getExStorable instanceBinaryEx FloatwhereputEx :: Float -> Builder
putEx =Float -> Builder
forall a. Storable a => a -> Builder
putExStorable getEx :: ByteString -> Float
getEx =ByteString -> Float
forall a. Storable a => ByteString -> a
getExStorable putExStorable ::foralla .Storablea =>a ->Builder putExStorable :: forall a. Storable a => a -> Builder
putExStorable a
x =Int -> (forall a. Ptr a -> Int -> IO ()) -> Builder
Builder (a -> Int
forall a. Storable a => a -> Int
sizeOfa
x )((forall a. Ptr a -> Int -> IO ()) -> Builder)
-> (forall a. Ptr a -> Int -> IO ()) -> Builder
forall a b. (a -> b) -> a -> b
$\Ptr a
p Int
i ->Ptr a -> Int -> a -> IO ()
forall b. Ptr b -> Int -> a -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOffPtr a
p Int
i a
x getExStorable ::foralla .Storablea =>BS.ByteString->a getExStorable :: forall a. Storable a => ByteString -> a
getExStorable =\ByteString
bs ->IO a -> a
forall a. IO a -> a
unsafePerformIO(IO a -> a) -> IO a -> a
forall a b. (a -> b) -> a -> b
$ByteString -> (CStringLen -> IO a) -> IO a
forall a. ByteString -> (CStringLen -> IO a) -> IO a
BS.unsafeUseAsCStringLenByteString
bs ((CStringLen -> IO a) -> IO a) -> (CStringLen -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$\(CString
p ,Int
size )->ifInt
size Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/=Int
n then[Char] -> IO a
forall a. HasCallStack => [Char] -> a
error[Char]
"size mismatch"elsePtr a -> IO a
forall a. Storable a => Ptr a -> IO a
peek(CString -> Ptr a
forall a b. Ptr a -> Ptr b
castPtrCString
p )wheren :: Int
n =a -> Int
forall a. Storable a => a -> Int
sizeOf(a
forall a. HasCallStack => a
undefined::a )putExStorableList ::foralla .Storablea =>[a ]->Builder putExStorableList :: forall a. Storable a => [a] -> Builder
putExStorableList [a]
xs =Int -> (forall a. Ptr a -> Int -> IO ()) -> Builder
Builder (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
*[a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length[a]
xs )((forall a. Ptr a -> Int -> IO ()) -> Builder)
-> (forall a. Ptr a -> Int -> IO ()) -> Builder
forall a b. (a -> b) -> a -> b
$\Ptr a
ptr Int
i ->[Int] -> [a] -> (Int -> a -> IO ()) -> IO ()
forall {m :: * -> *} {a} {b} {c}.
Applicative m =>
[a] -> [b] -> (a -> b -> m c) -> m ()
for2M_ [Int
i ,Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
n ..][a]
xs ((Int -> a -> IO ()) -> IO ()) -> (Int -> a -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$\Int
i a
x ->Ptr a -> Int -> a -> IO ()
forall b. Ptr b -> Int -> a -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOffPtr a
ptr Int
i a
x wheren :: Int
n =a -> Int
forall a. Storable a => a -> Int
sizeOf(a
forall a. HasCallStack => a
undefined::a )getExStorableList ::foralla .Storablea =>BS.ByteString->[a ]getExStorableList :: forall a. Storable a => ByteString -> [a]
getExStorableList =\ByteString
bs ->IO [a] -> [a]
forall a. IO a -> a
unsafePerformIO(IO [a] -> [a]) -> IO [a] -> [a]
forall a b. (a -> b) -> a -> b
$ByteString -> (CStringLen -> IO [a]) -> IO [a]
forall a. ByteString -> (CStringLen -> IO a) -> IO a
BS.unsafeUseAsCStringLenByteString
bs ((CStringLen -> IO [a]) -> IO [a])
-> (CStringLen -> IO [a]) -> IO [a]
forall a b. (a -> b) -> a -> b
$\(CString
p ,Int
size )->let(Int
d ,Int
m )=Int
size Int -> Int -> (Int, Int)
forall a. Integral a => a -> a -> (a, a)
`divMod`Int
n inifInt
m Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/=Int
0then[Char] -> IO [a]
forall a. HasCallStack => [Char] -> a
error[Char]
"size mismatch"else[Int] -> (Int -> IO a) -> IO [a]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM[Int
0..Int
d Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1]((Int -> IO a) -> IO [a]) -> (Int -> IO a) -> IO [a]
forall a b. (a -> b) -> a -> b
$\Int
i ->Ptr a -> Int -> IO a
forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff(CString -> Ptr a
forall a b. Ptr a -> Ptr b
castPtrCString
p )Int
i wheren :: Int
n =a -> Int
forall a. Storable a => a -> Int
sizeOf(a
forall a. HasCallStack => a
undefined::a )-- repeating:-- Word32, length of BS-- BSputExList ::[Builder ]->Builder putExList :: [Builder] -> Builder
putExList [Builder]
xs =Int -> (forall a. Ptr a -> Int -> IO ()) -> Builder
Builder ([Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum([Int] -> Int) -> [Int] -> Int
forall a b. (a -> b) -> a -> b
$(Builder -> Int) -> [Builder] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map(\Builder
b ->Builder -> Int
sizeBuilder Builder
b Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
4)[Builder]
xs )((forall a. Ptr a -> Int -> IO ()) -> Builder)
-> (forall a. Ptr a -> Int -> IO ()) -> Builder
forall a b. (a -> b) -> a -> b
$\Ptr a
p Int
i ->doletgo :: Int -> [Builder] -> IO ()
go Int
_[]=() -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure()go Int
i (Builder Int
n forall a. Ptr a -> Int -> IO ()
b :[Builder]
xs )=doPtr a -> Int -> Word32 -> IO ()
forall b. Ptr b -> Int -> Word32 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOffPtr a
p Int
i (Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegralInt
n ::Word32)Ptr a -> Int -> IO ()
forall a. Ptr a -> Int -> IO ()
b Ptr a
p (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
4)Int -> [Builder] -> IO ()
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
4Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
n )[Builder]
xs Int -> [Builder] -> IO ()
go Int
i [Builder]
xs getExList ::BS.ByteString->[BS.ByteString]getExList :: ByteString -> [ByteString]
getExList ByteString
bs |Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==Int
0=[]|Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>=Int
4,(Word32
n ::Word32,ByteString
bs )<-ByteString -> (Word32, ByteString)
forall a. Storable a => ByteString -> (a, ByteString)
unsafeBinarySplit ByteString
bs ,Int
n <-Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegralWord32
n ,(Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
4)Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>=Int
n =Int -> ByteString -> ByteString
BS.unsafeTakeInt
n ByteString
bs ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
:ByteString -> [ByteString]
getExList (Int -> ByteString -> ByteString
BS.unsafeDropInt
n ByteString
bs )|Bool
otherwise=[Char] -> [ByteString]
forall a. HasCallStack => [Char] -> a
error[Char]
"getList, corrupted binary"wherelen :: Int
len =ByteString -> Int
BS.lengthByteString
bs putExN ::Builder ->Builder putExN :: Builder -> Builder
putExN (Builder Int
n forall a. Ptr a -> Int -> IO ()
old )=Int -> (forall a. Ptr a -> Int -> IO ()) -> Builder
Builder (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
4)((forall a. Ptr a -> Int -> IO ()) -> Builder)
-> (forall a. Ptr a -> Int -> IO ()) -> Builder
forall a b. (a -> b) -> a -> b
$\Ptr a
p Int
i ->doPtr a -> Int -> Word32 -> IO ()
forall b. Ptr b -> Int -> Word32 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOffPtr a
p Int
i (Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegralInt
n ::Word32)Ptr a -> Int -> IO ()
forall a. Ptr a -> Int -> IO ()
old Ptr a
p (Int -> IO ()) -> Int -> IO ()
forall a b. (a -> b) -> a -> b
$Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
4getExN ::BS.ByteString->(BS.ByteString,BS.ByteString)getExN :: ByteString -> (ByteString, ByteString)
getExN ByteString
bs |Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>=Int
4,(Word32
n ::Word32,ByteString
bs )<-ByteString -> (Word32, ByteString)
forall a. Storable a => ByteString -> (a, ByteString)
unsafeBinarySplit ByteString
bs ,Int
n <-Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegralWord32
n ,(Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
4)Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>=Int
n =(Int -> ByteString -> ByteString
BS.unsafeTakeInt
n ByteString
bs ,Int -> ByteString -> ByteString
BS.unsafeDropInt
n ByteString
bs )|Bool
otherwise=[Char] -> (ByteString, ByteString)
forall a. HasCallStack => [Char] -> a
error[Char]
"getList, corrupted binary"wherelen :: Int
len =ByteString -> Int
BS.lengthByteString
bs 

AltStyle によって変換されたページ (->オリジナル) /