@@ -20,9 +20,20 @@ module Streamly.Internal.Data.Serialize
2020--------------------------------------------------------------------------------
2121
2222import Data.Proxy (Proxy)
23−import Streamly.Internal.Data.Serialize.Type
23+import Streamly.Internal.Data.Array (Array(..))
24+import Streamly.Internal.Data.Unbox (MutableByteArray(..))
25+import GHC.Exts (Int(..), sizeofByteArray#, unsafeCoerce#)
26+
2427import qualified Streamly.Internal.Data.Serialize.TH as Serialize
2528
29+#if __GLASGOW_HASKELL__ >= 900
30+import GHC.Num.Integer (Integer(..))
31+#else
32+import GHC.Integer.GMP.Internals (Integer(..), BigNat(..))
33+#endif
34+
35+import Streamly.Internal.Data.Serialize.Type
36+
2637--------------------------------------------------------------------------------
2738-- Common instances
2839--------------------------------------------------------------------------------
@@ -52,3 +63,56 @@ $(Serialize.deriveSerialize ''Either)
5263$(Serialize.deriveSerializeWith
5364 (Serialize.defaultConfig {Serialize.unconstrained = ["t"]})
5465 ''Proxy)
66+
67+--------------------------------------------------------------------------------
68+-- Integer
69+--------------------------------------------------------------------------------
70+
71+data LiftedInteger
72+ = LIS Int
73+ | LIP (Array Word)
74+ | LIN (Array Word)
75+
76+$(Serialize.deriveSerialize ''LiftedInteger)
77+
78+#if __GLASGOW_HASKELL__ >= 900
79+
80+liftInteger :: Integer -> LiftedInteger
81+liftInteger (IS x) = LIS (I# x)
82+liftInteger (IP x) =
83+ LIP (Array (MutableByteArray (unsafeCoerce# x)) 0 (I# (sizeofByteArray# x)))
84+liftInteger (IN x) =
85+ LIN (Array (MutableByteArray (unsafeCoerce# x)) 0 (I# (sizeofByteArray# x)))
86+
87+unliftInteger :: LiftedInteger -> Integer
88+unliftInteger (LIS (I# x)) = IS x
89+unliftInteger (LIP (Array (MutableByteArray x) _ _)) = IP (unsafeCoerce# x)
90+unliftInteger (LIN (Array (MutableByteArray x) _ _)) = IN (unsafeCoerce# x)
91+
92+#else
93+
94+liftInteger :: Integer -> LiftedInteger
95+liftInteger (S# x) = LIS (I# x)
96+liftInteger (Jp# (BN# x)) =
97+ LIP (Array (MutableByteArray (unsafeCoerce# x)) 0 (I# (sizeofByteArray# x)))
98+liftInteger (Jn# (BN# x)) =
99+ LIN (Array (MutableByteArray (unsafeCoerce# x)) 0 (I# (sizeofByteArray# x)))
100+
101+unliftInteger :: LiftedInteger -> Integer
102+unliftInteger (LIS (I# x)) = S# x
103+unliftInteger (LIP (Array (MutableByteArray x) _ _)) =
104+ Jp# (BN# (unsafeCoerce# x))
105+unliftInteger (LIN (Array (MutableByteArray x) _ _)) =
106+ Jn# (BN# (unsafeCoerce# x))
107+
108+#endif
109+
110+instance Serialize Integer where
111+ {-# INLINE size #-}
112+ size i a = size i (liftInteger a)
113+
114+ {-# INLINE deserialize #-}
115+ deserialize off arr end = fmap unliftInteger <$> deserialize off arr end
116+
117+ {-# INLINE serialize #-}
118+ serialize off arr val = serialize off arr (liftInteger val)