{-# OPTIONS_GHC -fno-warn-orphans #-} module Data.Vector.Serial ( genericDeserializeVector , genericDeserializeVectorWith , genericSerializeVector , genericSerializeVectorWith ) where import Data.Bytes.Serial as Bytes import Data.Bytes.Get as Bytes import Data.Bytes.Put as Bytes import qualified Data.Vector.Generic as G import qualified Data.Vector.Generic.Mutable as GM import qualified Data.Vector.Unboxed as U import qualified Data.Vector.Storable as S import qualified Data.Vector.Primitive as P import Data.Vector (Vector) import Foreign.Storable (Storable) import System.IO.Unsafe -------------------------------------------------------------------------------- -- | Orphan in "Data.Vector.Serial". Boxed, generic vectors. instance Bytes.Serial a => Bytes.Serial (Vector a) where serialize = genericSerializeVector deserialize = genericDeserializeVector {-# INLINE deserialize #-} -- | Orphan in "Data.Vector.Serial". Unboxed vectors instance (U.Unbox a, Bytes.Serial a) => Bytes.Serial (U.Vector a) where serialize = genericSerializeVector deserialize = genericDeserializeVector {-# INLINE deserialize #-} -- | Orphan in "Data.Vector.Serial". Primitive vectors instance (P.Prim a, Bytes.Serial a) => Bytes.Serial (P.Vector a) where serialize = genericSerializeVector deserialize = genericDeserializeVector {-# INLINE deserialize #-} -- | Orphan in "Data.Vector.Serial". Storable vectors instance (Storable a, Bytes.Serial a) => Bytes.Serial (S.Vector a) where serialize = genericSerializeVector deserialize = genericDeserializeVector {-# INLINE deserialize #-} ------------------------------------------------------------------------ -- | Deserialize vector using custom parsers. genericDeserializeVectorWith :: (G.Vector v a, Bytes.Serial a, Bytes.MonadGet m) => m Int -- ^ Parser for vector size -> m a -- ^ Parser for vector's element -> m (v a) {-# INLINE genericDeserializeVectorWith #-} genericDeserializeVectorWith deserializeN deserializeA = do n <- deserializeN v <- return $ unsafePerformIO $ GM.unsafeNew n let go 0 = return () go i = do x <- deserializeA () <- return $ unsafePerformIO $ GM.unsafeWrite v (n-i) x go (i-1) () <- go n return $ unsafePerformIO $ G.unsafeFreeze v -- | Generic serialize for anything in the 'G.Vector' class which uses custom -- encoders. genericSerializeVectorWith :: (G.Vector v a, Bytes.Serial a, Bytes.MonadPut m) => (Int -> m ()) -- ^ Encoder for vector size -> (a -> m ()) -- ^ Encoder for vector's element -> v a -> m () {-# INLINE genericSerializeVectorWith #-} genericSerializeVectorWith serializeN serializeA v = do serializeN (G.length v) G.mapM_ serializeA v -- | Generic function for vector deserialization. genericDeserializeVector :: (G.Vector v a, Bytes.Serial a, Bytes.MonadGet m) => m (v a) {-# INLINE genericDeserializeVector #-} genericDeserializeVector = genericDeserializeVectorWith deserialize deserialize -- | Generic serialize for anything in the 'G.Vector' class. genericSerializeVector :: (G.Vector v a, Bytes.Serial a, Bytes.MonadPut m) => v a -> m () {-# INLINE genericSerializeVector #-} genericSerializeVector = genericSerializeVectorWith serialize serialize