1{-# LANGUAGE TemplateHaskell #-}
3-- This is required as all the instances in this module are orphan instances.
4{-# OPTIONS_GHC -fno-warn-orphans #-}
7-- Module : Streamly.Internal.Data.MutByteArray
8-- Copyright : (c) 2023 Composewell Technologies
9-- License : BSD3-3-Clause
10-- Maintainer : streamly@composewell.com
14module Streamly.Internal.Data.MutByteArray
17 module Streamly.Internal.Data.MutByteArray.Type
19 , module Streamly.Internal.Data.Unbox
20 , module Streamly.Internal.Data.Unbox.TH
22 , module Streamly.Internal.Data.Serialize.Type
24 , module Streamly.Internal.Data.Serialize.TH
27--------------------------------------------------------------------------------
29--------------------------------------------------------------------------------
31import Data.Proxy (Proxy(..))
32import Streamly.Internal.Data.Array (Array(..))
33import GHC.Exts (Int(..), sizeofByteArray#, unsafeCoerce#)
34import GHC.Word (Word8)
36#if __GLASGOW_HASKELL__ >= 900
37import GHC.Num.Integer (Integer(..))
39import GHC.Integer.GMP.Internals (Integer(..), BigNat(..))
42import Streamly.Internal.Data.MutByteArray.Type
43import Streamly.Internal.Data.Serialize.TH
44import Streamly.Internal.Data.Serialize.Type
45import Streamly.Internal.Data.Unbox
46import Streamly.Internal.Data.Unbox.TH
48--------------------------------------------------------------------------------
50--------------------------------------------------------------------------------
55-- Even a non-functional change such as changing the order of constructors will
56-- change the instance derivation.
58-- This will not pose a problem if both, encode, and decode are done by the same
59-- version of the application. There *might* be a problem if version that
60-- encodes differs from the version that decodes.
62-- We need to add some compatibility tests using different versions of
65-- Although such chages for the most basic types won't happen we need to detect
68-- Should we worry about these kind of changes and this kind of compatibility?
69-- This is a problem for all types of derivations that depend on the order of
70-- constructors, for example, Enum.
72-- Note on Windows build
73-- =====================
75-- On Windows, having template haskell splices here fail the build with the
79-- addLibrarySearchPath: C:\... (Win32 error 3): The system cannot find the path specified.
82-- The error might be irrelavant but having these splices triggers it. We should
83-- either fix the problem or avoid the use to template haskell splices in this
86-- Similar issue: https://github.com/haskell/cabal/issues/4741
88-- $(Serialize.deriveSerialize ''Maybe)
89instance Serialize a => Serialize (Maybe a) where
91 {-# INLINE addSizeTo #-}
95 Just field0 -> (addSizeTo (acc + 1)) field0
97 {-# INLINE deserializeAt #-}
98 deserializeAt initialOffset arr endOffset = do
99 (i0, tag) <- ((deserializeAt initialOffset) arr) endOffset
101 0 -> pure (i0, Nothing)
102 1 -> do (i1, a0) <- ((deserializeAt i0) arr) endOffset
104 _ -> error "Found invalid tag while peeking (Maybe a)"
106 {-# INLINE serializeAt #-}
107 serializeAt initialOffset arr val =
110 i0 <- ((serializeAt initialOffset) arr) (0 :: Word8)
113 i0 <- ((serializeAt initialOffset) arr) (1 :: Word8)
114 i1 <- ((serializeAt i0) arr) field0
117-- $(Serialize.deriveSerialize ''Either)
118instance (Serialize a, Serialize b) => Serialize (Either a b) where
120 {-# INLINE addSizeTo #-}
123 Left field0 -> (addSizeTo (acc + 1)) field0
124 Right field0 -> (addSizeTo (acc + 1)) field0
126 {-# INLINE deserializeAt #-}
127 deserializeAt initialOffset arr endOffset = do
128 (i0, tag) <- ((deserializeAt initialOffset) arr) endOffset
130 0 -> do (i1, a0) <- ((deserializeAt i0) arr) endOffset
132 1 -> do (i1, a0) <- ((deserializeAt i0) arr) endOffset
134 _ -> error "Found invalid tag while peeking (Either a b)"
136 {-# INLINE serializeAt #-}
137 serializeAt initialOffset arr val =
140 i0 <- ((serializeAt initialOffset) arr) (0 :: Word8)
141 i1 <- ((serializeAt i0) arr) field0
144 i0 <- ((serializeAt initialOffset) arr) (1 :: Word8)
145 i1 <- ((serializeAt i0) arr) field0
148instance Serialize (Proxy a) where
150 {-# INLINE addSizeTo #-}
151 addSizeTo acc _ = (acc + 1)
153 {-# INLINE deserializeAt #-}
154 deserializeAt initialOffset _ _ = pure ((initialOffset + 1), Proxy)
156 {-# INLINE serializeAt #-}
157 serializeAt initialOffset _ _ = pure (initialOffset + 1)
159--------------------------------------------------------------------------------
161--------------------------------------------------------------------------------
168-- $(Serialize.deriveSerialize ''LiftedInteger)
169instance Serialize LiftedInteger where
171 {-# INLINE addSizeTo #-}
174 LIS field0 -> (addSizeTo (acc + 1)) field0
175 LIP field0 -> (addSizeTo (acc + 1)) field0
176 LIN field0 -> (addSizeTo (acc + 1)) field0
178 {-# INLINE deserializeAt #-}
179 deserializeAt initialOffset arr endOffset = do
180 (i0, tag) <- ((deserializeAt initialOffset) arr) endOffset
182 0 -> do (i1, a0) <- ((deserializeAt i0) arr) endOffset
184 1 -> do (i1, a0) <- ((deserializeAt i0) arr) endOffset
186 2 -> do (i1, a0) <- ((deserializeAt i0) arr) endOffset
188 _ -> error "Found invalid tag while peeking (LiftedInteger)"
190 {-# INLINE serializeAt #-}
191 serializeAt initialOffset arr val =
194 i0 <- ((serializeAt initialOffset) arr) (0 :: Word8)
195 i1 <- ((serializeAt i0) arr) field0
198 i0 <- ((serializeAt initialOffset) arr) (1 :: Word8)
199 i1 <- ((serializeAt i0) arr) field0
202 i0 <- ((serializeAt initialOffset) arr) (2 :: Word8)
203 i1 <- ((serializeAt i0) arr) field0
206#if __GLASGOW_HASKELL__ >= 900
208{-# INLINE liftInteger #-}
209liftInteger :: Integer -> LiftedInteger
210liftInteger (IS x) = LIS (I# x)
212 LIP (Array (MutByteArray (unsafeCoerce# x)) 0 (I# (sizeofByteArray# x)))
214 LIN (Array (MutByteArray (unsafeCoerce# x)) 0 (I# (sizeofByteArray# x)))
216{-# INLINE unliftInteger #-}
217unliftInteger :: LiftedInteger -> Integer
218unliftInteger (LIS (I# x)) = IS x
219unliftInteger (LIP (Array (MutByteArray x) _ _)) = IP (unsafeCoerce# x)
220unliftInteger (LIN (Array (MutByteArray x) _ _)) = IN (unsafeCoerce# x)
224{-# INLINE liftInteger #-}
225liftInteger :: Integer -> LiftedInteger
226liftInteger (S# x) = LIS (I# x)
227liftInteger (Jp# (BN# x)) =
228 LIP (Array (MutByteArray (unsafeCoerce# x)) 0 (I# (sizeofByteArray# x)))
229liftInteger (Jn# (BN# x)) =
230 LIN (Array (MutByteArray (unsafeCoerce# x)) 0 (I# (sizeofByteArray# x)))
232{-# INLINE unliftInteger #-}
233unliftInteger :: LiftedInteger -> Integer
234unliftInteger (LIS (I# x)) = S# x
235unliftInteger (LIP (Array (MutByteArray x) _ _)) =
236 Jp# (BN# (unsafeCoerce# x))
237unliftInteger (LIN (Array (MutByteArray x) _ _)) =
238 Jn# (BN# (unsafeCoerce# x))
242instance Serialize Integer where
243 {-# INLINE addSizeTo #-}
244 addSizeTo i a = addSizeTo i (liftInteger a)
246 {-# INLINE deserializeAt #-}
247 deserializeAt off arr end =
248 fmap unliftInteger <$> deserializeAt off arr end
250 {-# INLINE serializeAt #-}
251 serializeAt off arr val = serializeAt off arr (liftInteger val)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list