{-# LANGUAGE FlexibleContexts #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module Data.SafeCopy.Instances where import Data.SafeCopy.SafeCopy import Data.Word import Data.Int import Data.Serialize import Control.Applicative import Data.Ix import qualified Data.Array as Array import qualified Data.Array.Unboxed as UArray import qualified Data.Array.IArray as IArray import qualified Data.Foldable as Foldable import qualified Data.Map as Map import qualified Data.IntMap as IntMap import qualified Data.IntSet as IntSet import qualified Data.Sequence as Sequence import qualified Data.Set as Set import qualified Data.Tree as Tree import qualified Data.ByteString.Lazy.Char8 as L import qualified Data.ByteString.Char8 as B import Control.Monad instance SafeCopy a => SafeCopy [a] where kind = primitive getCopy = contain $ do n <- get getSafeGet >>= replicateM n putCopy lst = contain $ do put (length lst) getSafePut >>= forM_ lst instance SafeCopy a => SafeCopy (Maybe a) where kind = primitive getCopy = contain $ do n <- get if n then liftM Just safeGet else return Nothing putCopy (Just a) = contain $ put True >> safePut a putCopy Nothing = contain $ put False instance (SafeCopy a, Ord a) => SafeCopy (Set.Set a) where getCopy = contain $ fmap Set.fromDistinctAscList safeGet putCopy = contain . safePut . Set.toAscList instance (SafeCopy a, SafeCopy b, Ord a) => SafeCopy (Map.Map a b) where getCopy = contain $ fmap Map.fromDistinctAscList safeGet putCopy = contain . safePut . Map.toAscList instance (SafeCopy a) => SafeCopy (IntMap.IntMap a) where getCopy = contain $ fmap IntMap.fromDistinctAscList safeGet putCopy = contain . safePut . IntMap.toAscList instance SafeCopy IntSet.IntSet where getCopy = contain $ fmap IntSet.fromDistinctAscList safeGet putCopy = contain . safePut . IntSet.toAscList instance (SafeCopy a) => SafeCopy (Sequence.Seq a) where getCopy = contain $ fmap Sequence.fromList safeGet putCopy = contain . safePut . Foldable.toList instance (SafeCopy a) => SafeCopy (Tree.Tree a) where getCopy = contain $ liftM2 Tree.Node safeGet safeGet putCopy (Tree.Node root sub) = contain $ safePut root >> safePut sub iarray_getCopy :: (Ix i, SafeCopy e, SafeCopy i, IArray.IArray a e) => Contained (Get (a i e)) iarray_getCopy = contain $ do getIx <- getSafeGet liftM3 mkArray getIx getIx safeGet where mkArray l h xs = IArray.listArray (l, h) xs {-# INLINE iarray_getCopy #-} iarray_putCopy :: (Ix i, SafeCopy e, SafeCopy i, IArray.IArray a e) => a i e -> Contained Put iarray_putCopy arr = contain $ do putIx <- getSafePut let (l,h) = IArray.bounds arr putIx l >> putIx h safePut (IArray.elems arr) {-# INLINE iarray_putCopy #-} instance (Ix i, SafeCopy e, SafeCopy i) => SafeCopy (Array.Array i e) where getCopy = iarray_getCopy putCopy = iarray_putCopy instance (IArray.IArray UArray.UArray e, Ix i, SafeCopy e, SafeCopy i) => SafeCopy (UArray.UArray i e) where getCopy = iarray_getCopy putCopy = iarray_putCopy instance (SafeCopy a, SafeCopy b) => SafeCopy (a,b) where kind = primitive getCopy = contain $ liftM2 (,) safeGet safeGet putCopy (a,b) = contain $ safePut a >> safePut b instance (SafeCopy a, SafeCopy b, SafeCopy c) => SafeCopy (a,b,c) where kind = primitive getCopy = contain $ liftM3 (,,) safeGet safeGet safeGet putCopy (a,b,c) = contain $ safePut a >> safePut b >> safePut c instance (SafeCopy a, SafeCopy b, SafeCopy c, SafeCopy d) => SafeCopy (a,b,c,d) where kind = primitive getCopy = contain $ liftM4 (,,,) safeGet safeGet safeGet safeGet putCopy (a,b,c,d) = contain $ safePut a >> safePut b >> safePut c >> safePut d instance (SafeCopy a, SafeCopy b, SafeCopy c, SafeCopy d, SafeCopy e) => SafeCopy (a,b,c,d,e) where kind = primitive getCopy = contain $ liftM5 (,,,,) safeGet safeGet safeGet safeGet safeGet putCopy (a,b,c,d,e) = contain $ safePut a >> safePut b >> safePut c >> safePut d >> safePut e instance (SafeCopy a, SafeCopy b, SafeCopy c, SafeCopy d, SafeCopy e, SafeCopy f) => SafeCopy (a,b,c,d,e,f) where kind = primitive getCopy = contain $ (,,,,,) <$> safeGet <*> safeGet <*> safeGet <*> safeGet <*> safeGet <*> safeGet putCopy (a,b,c,d,e,f) = contain $ safePut a >> safePut b >> safePut c >> safePut d >> safePut e >> safePut f instance (SafeCopy a, SafeCopy b, SafeCopy c, SafeCopy d, SafeCopy e, SafeCopy f, SafeCopy g) => SafeCopy (a,b,c,d,e,f,g) where kind = primitive getCopy = contain $ (,,,,,,) <$> safeGet <*> safeGet <*> safeGet <*> safeGet <*> safeGet <*> safeGet <*> safeGet putCopy (a,b,c,d,e,f,g) = contain $ safePut a >> safePut b >> safePut c >> safePut d >> safePut e >> safePut f >> safePut g instance SafeCopy Int where kind = primitive; getCopy = contain get; putCopy = contain . put instance SafeCopy Integer where kind = primitive; getCopy = contain get; putCopy = contain . put instance SafeCopy Float where kind = primitive; getCopy = contain get; putCopy = contain . put instance SafeCopy Double where kind = primitive; getCopy = contain get; putCopy = contain . put instance SafeCopy L.ByteString where kind = primitive; getCopy = contain get; putCopy = contain . put instance SafeCopy B.ByteString where kind = primitive; getCopy = contain get; putCopy = contain . put instance SafeCopy Char where kind = primitive; getCopy = contain get; putCopy = contain . put instance SafeCopy Word8 where kind = primitive; getCopy = contain get; putCopy = contain . put instance SafeCopy Word16 where kind = primitive; getCopy = contain get; putCopy = contain . put instance SafeCopy Word32 where kind = primitive; getCopy = contain get; putCopy = contain . put instance SafeCopy Word64 where kind = primitive; getCopy = contain get; putCopy = contain . put instance SafeCopy Ordering where kind = primitive; getCopy = contain get; putCopy = contain . put instance SafeCopy Int8 where kind = primitive; getCopy = contain get; putCopy = contain . put instance SafeCopy Int16 where kind = primitive; getCopy = contain get; putCopy = contain . put instance SafeCopy Int32 where kind = primitive; getCopy = contain get; putCopy = contain . put instance SafeCopy Int64 where kind = primitive; getCopy = contain get; putCopy = contain . put instance SafeCopy () where kind = primitive; getCopy = contain get; putCopy = contain . put instance SafeCopy Bool where kind = primitive; getCopy = contain get; putCopy = contain . put instance (SafeCopy a, SafeCopy b) => SafeCopy (Either a b) where kind = primitive getCopy = contain $ do n <- get if n then liftM Right safeGet else liftM Left safeGet putCopy (Right a) = contain $ put True >> safePut a putCopy (Left a) = contain $ put False >> safePut a