@@ -7,8 +7,7 @@
9module Streamly.Internal.Data.Serialize
9module Streamly.Internal.Data.Serialize
11− , Serialize(..)
10+ ( Serialize(..)
13 , pinnedEncode
12 , pinnedEncode
@@ -47,11 +46,6 @@ import GHC.Exts
48--------------------------------------------------------------------------------
47--------------------------------------------------------------------------------
50−-- XXX Use (a -> Sum Int) instead, remove the Size type
52−-- | A left fold step to fold a generic structure to its serializable size.
53−newtype Size a = Size (Int -> a -> Int) -- a left fold or Sum monoid
55-- | A type implementing the 'Serialize' interface supplies operations for
49-- | A type implementing the 'Serialize' interface supplies operations for
56-- reading and writing the type from and to a mutable byte array (an unboxed
50-- reading and writing the type from and to a mutable byte array (an unboxed
57-- representation of the type) in memory. The read operation 'deserialize'
51-- representation of the type) in memory. The read operation 'deserialize'
@@ -66,7 +60,7 @@ newtype Size a = Size (Int -> a -> Int) -- a left fold or Sum monoid
66-- 'Serialize' contains enough information to serialize and deserialize variable
60-- 'Serialize' contains enough information to serialize and deserialize variable
67-- length types.
61-- length types.
69−-- >>> import Streamly.Internal.Data.Serialize (Serialize(..), Size(..))
63+-- >>> import Streamly.Internal.Data.Serialize (Serialize(..))
72-- data Object = Object
66-- data Object = Object
@@ -77,11 +71,7 @@ newtype Size a = Size (Int -> a -> Int) -- a left fold or Sum monoid
79-- instance Serialize Object where
73-- instance Serialize Object where
81−-- case (size :: Size [Int], size :: Size Int) of
82−-- (Size f, Size g) ->
84−-- acc + f 0 (_obj1 obj) + g 0 (_obj2 obj)
74+-- size acc obj = size (size acc (_obj1 obj)) (_obj2 obj)
85-- deserialize i arr len = do
75-- deserialize i arr len = do
86-- (i1, x0) <- deserialize i arr len
76-- (i1, x0) <- deserialize i arr len
87-- (i2, x1) <- deserialize i1 arr len
77-- (i2, x1) <- deserialize i1 arr len
@@ -93,9 +83,15 @@ newtype Size a = Size (Int -> a -> Int) -- a left fold or Sum monoid
95class Serialize a where
85class Serialize a where
86+ -- XXX Use (a -> Sum Int) instead, remove the Size type
88+ -- A left fold step to fold a generic structure to its serializable size.
89+ -- It is of the form @Int -> a -> Int@ because you can have tail-recursive
90+ -- traversal of the structures.
96− -- | Get the 'Size', in bytes, reqired to store the serialized
92+ -- | Get the size, in bytes, reqired to store the serialized
97 -- representation of the type. Size cannot be zero.
93 -- representation of the type. Size cannot be zero.
98− size :: Size a
94+ size :: Int -> a -> Int
100 -- We can implement the following functions without returning the `Int`
96 -- We can implement the following functions without returning the `Int`
101 -- offset but that may require traversing the Haskell structure again to get
97 -- offset but that may require traversing the Haskell structure again to get
@@ -180,7 +176,7 @@ serializeUnsafe off arr val =
180#define DERIVE_SERIALIZE_FROM_UNBOX(_type) \
176#define DERIVE_SERIALIZE_FROM_UNBOX(_type) \
181instance Serialize _type where \
177instance Serialize _type where \
182; {-# INLINE size #-} \
178; {-# INLINE size #-} \
183−; size = Size (\acc _ -> acc + Unbox.sizeOf (Proxy :: Proxy _type)) \
179+; size acc _ = acc + Unbox.sizeOf (Proxy :: Proxy _type) \
184; {-# INLINE deserialize #-} \
180; {-# INLINE deserialize #-} \
185; deserialize off arr end = deserializeUnsafe off arr end :: IO (Int, _type) \
181; deserialize off arr end = deserializeUnsafe off arr end :: IO (Int, _type) \
186; {-# INLINE serialize #-} \
182; {-# INLINE serialize #-} \
@@ -208,9 +204,7 @@ DERIVE_SERIALIZE_FROM_UNBOX((FunPtr a))
208instance forall a. Serialize a => Serialize [a] where
204instance forall a. Serialize a => Serialize [a] where
210 -- {-# INLINE size #-}
206 -- {-# INLINE size #-}
211− size = Size $ \acc xs ->
212− case size :: Size a of
213− Size f -> foldl' f (acc + (Unbox.sizeOf (Proxy :: Proxy Int))) xs
207+ size acc xs = foldl' size (acc + (Unbox.sizeOf (Proxy :: Proxy Int))) xs
215 -- Inlining this causes large compilation times for tests
209 -- Inlining this causes large compilation times for tests
216 {-# INLINABLE deserialize #-}
210 {-# INLINABLE deserialize #-}
@@ -248,9 +242,7 @@ instance forall a. Serialize a => Serialize [a] where
248encodeAs :: forall a. Serialize a => PinnedState -> a -> Array Word8
242encodeAs :: forall a. Serialize a => PinnedState -> a -> Array Word8
249encodeAs ps a =
243encodeAs ps a =
250 unsafeInlineIO $ do
244 unsafeInlineIO $ do
251− let len =
245+ let len = size 0 a
252− case size :: Size a of
254 -- We encode the length of the encoding as a header hence the 8 extra
246 -- We encode the length of the encoding as a header hence the 8 extra
255 -- bytes to encode Int64
247 -- bytes to encode Int64
256 mbarr <- Unbox.newBytesAs ps (8 + len)
248 mbarr <- Unbox.newBytesAs ps (8 + len)