cereal-vector-0.2.0.1/0000755000000000000000000000000012300231664012566 5ustar0000000000000000cereal-vector-0.2.0.1/cereal-vector.cabal0000644000000000000000000000213412300231664016305 0ustar0000000000000000name: cereal-vector version: 0.2.0.1 synopsis: Serialize instances for Data.Vector types. homepage: https://github.com/acfoltzer/cereal-vector bug-reports: https://github.com/acfoltzer/cereal-vector/issues license: BSD3 license-file: LICENSE author: Adam C. Foltzer maintainer: acfoltzer@gmail.com category: Data build-type: Simple stability: experimental cabal-version: >=1.8 source-repository head type: git location: git://github.com/acfoltzer/cereal-vector.git library exposed-modules: Data.Vector.Serialize, Data.Vector.Storable.UnsafeSerialize build-depends: base == 4.* , vector >= 0.9 , cereal >= 0.3 , bytestring >= 0.9 test-suite test type: exitcode-stdio-1.0 hs-source-dirs: test main-is: test.hs other-modules: ghc-options: -Wall -O2 build-depends: base, vector, cereal, cereal-vector, QuickCheck cereal-vector-0.2.0.1/LICENSE0000644000000000000000000000277012300231664013601 0ustar0000000000000000Copyright (c) 2012, Adam C. Foltzer All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Adam C. Foltzer nor the names of other contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. cereal-vector-0.2.0.1/Setup.hs0000644000000000000000000000005612300231664014223 0ustar0000000000000000import Distribution.Simple main = defaultMain cereal-vector-0.2.0.1/Data/0000755000000000000000000000000012300231664013437 5ustar0000000000000000cereal-vector-0.2.0.1/Data/Vector/0000755000000000000000000000000012300231664014701 5ustar0000000000000000cereal-vector-0.2.0.1/Data/Vector/Serialize.hs0000644000000000000000000000527312300231664017173 0ustar0000000000000000{-# OPTIONS_GHC -Wall -fno-warn-orphans #-} -- | "Data.Serialize" functions for "Data.Vector.Generic" -- vectors. Orphan instances are provided for "Data.Vector", -- "Data.Vector.Unboxed", "Data.Vector.Storable", and -- "Data.Vector.Primitive" vectors. -- -- The serialized format is an 'Int64' representing the length of the -- vector, followed by the "Data.Serialize"d contents of each element. -- -- Note that the functions in "Data.Vector.Storable.UnsafeSerialize" -- perform much better when serialization does not need to account for -- host endianness and word size. module Data.Vector.Serialize ( genericGetVector , genericPutVector , genericGetVectorWith , genericPutVectorWith ) where import Control.Monad import Data.Int (Int64) import Data.Serialize (Get, Putter, Serialize(..)) import qualified Data.Vector as V import qualified Data.Vector.Primitive as VP import qualified Data.Vector.Unboxed as VU import qualified Data.Vector.Generic as VG import qualified Data.Vector.Storable as VS -- | Read a 'Data.Vector.Generic.Vector' using custom 'Get' for the -- vector's elements. genericGetVectorWith :: (VG.Vector v a) => Get a -> Get (v a) {-# INLINE genericGetVectorWith #-} genericGetVectorWith getter = do len64 <- get :: Get Int64 when (len64 > fromIntegral (maxBound :: Int)) $ fail "Host can't deserialize a Vector longer than (maxBound :: Int)" VG.replicateM (fromIntegral len64) getter -- | Write a 'Data.Vector.Generic.Vector' using custom 'Putter' for -- the vector's elements. genericPutVectorWith :: (VG.Vector v a) => Putter a -> Putter (v a) {-# INLINE genericPutVectorWith #-} genericPutVectorWith putter v = do put ((fromIntegral $ VG.length v) :: Int64) VG.mapM_ putter v -- | Write a 'Data.Vector.Generic.Vector'. genericPutVector :: (Serialize a, VG.Vector v a) => Putter (v a) {-# INLINE genericPutVector #-} genericPutVector = genericPutVectorWith put -- | Read a 'Data.Vector.Generic.Vector'. genericGetVector :: (Serialize a, VG.Vector v a) => Get (v a) {-# INLINE genericGetVector #-} genericGetVector = genericGetVectorWith get instance (Serialize a) => Serialize (V.Vector a) where get = genericGetVector ; put = genericPutVector {-# INLINE get #-} {-# INLINE put #-} instance (Serialize a, VP.Prim a) => Serialize (VP.Vector a) where get = genericGetVector ; put = genericPutVector {-# INLINE get #-} {-# INLINE put #-} instance (Serialize a, VU.Unbox a) => Serialize (VU.Vector a) where get = genericGetVector ; put = genericPutVector {-# INLINE get #-} {-# INLINE put #-} instance (Serialize a, VS.Storable a) => Serialize (VS.Vector a) where get = genericGetVector ; put = genericPutVector {-# INLINE get #-} {-# INLINE put #-} cereal-vector-0.2.0.1/Data/Vector/Storable/0000755000000000000000000000000012300231664016454 5ustar0000000000000000cereal-vector-0.2.0.1/Data/Vector/Storable/UnsafeSerialize.hs0000644000000000000000000000370412300231664022105 0ustar0000000000000000{-# LANGUAGE ScopedTypeVariables, Unsafe #-} {-# OPTIONS_GHC -Wall #-} -- | Efficient, but unsafe 'Get' and 'Putter' for -- "Data.Vector.Storable" vectors. The serialized format is an 'Int64' -- representing the length of the 'Vector', followed by the raw -- bytes. Therefore behavior may be unpredictable if serialized data -- is transferred between machines with different word size or -- endianness. module Data.Vector.Storable.UnsafeSerialize ( unsafeGetVector , unsafePutVector ) where import Control.Monad (when) import qualified Data.ByteString.Internal as BS import Data.Int (Int64) import Data.Serialize (Get, getBytes, putByteString, Putter, Serialize(..)) import Data.Vector.Storable ( unsafeFromForeignPtr0 , unsafeToForeignPtr0 , Vector) import Data.Vector.Storable.Internal (updPtr) import Foreign.ForeignPtr (castForeignPtr) import Foreign.Marshal.Array (advancePtr) import Foreign.Storable (Storable, sizeOf) -- | Get a 'Vector' in host order, endian form, and word width. unsafeGetVector :: forall a. Storable a => Get (Vector a) {-# INLINE unsafeGetVector #-} unsafeGetVector = do len64 <- get :: Get Int64 when (len64 > fromIntegral (maxBound :: Int)) $ fail "Host can't deserialize a Vector longer than (maxBound :: Int)" let len = fromIntegral len64 nbytes = len * sizeOf (undefined :: a) bs <- getBytes nbytes let (fp, off, _) = BS.toForeignPtr bs fp' | off /= 0 = updPtr (`advancePtr` off) fp | otherwise = fp return $ unsafeFromForeignPtr0 (castForeignPtr fp') len -- | Put a 'Vector' in host order, endian form, and word width. unsafePutVector :: forall a. Storable a => Putter (Vector a) {-# INLINE unsafePutVector #-} unsafePutVector v = do let (fp, len) = unsafeToForeignPtr0 v nbytes = len * sizeOf (undefined :: a) bs = BS.fromForeignPtr (castForeignPtr fp) 0 nbytes put (fromIntegral len :: Int64) putByteString bs cereal-vector-0.2.0.1/test/0000755000000000000000000000000012300231664013545 5ustar0000000000000000cereal-vector-0.2.0.1/test/test.hs0000644000000000000000000000345212300231664015064 0ustar0000000000000000{-# LANGUAGE TemplateHaskell #-} import Control.Monad import Data.Int (Int64) import Data.Serialize (decode, encode, getTwoOf, putTwoOf, runGet, runPut) import qualified Data.Vector as V import qualified Data.Vector.Primitive as VP -- import qualified Data.Vector.Generic as VG import qualified Data.Vector.Storable as VS import qualified Data.Vector.Unboxed as VU import Test.QuickCheck.All import Data.Vector.Serialize () import Data.Vector.Storable.UnsafeSerialize prop_vec :: [Int] -> Bool prop_vec xs = Right xsv == decode (encode xsv) where xsv = V.fromList xs prop_vec_tuple :: [[Int]] -> [Either [Bool] Double] -> Bool prop_vec_tuple xs ys = Right (xsv, ysv) == decode (encode (xsv, ysv)) where (xsv, ysv) = (V.fromList xs, V.fromList ys) prop_prim :: [Int] -> Bool prop_prim xs = Right xsv == decode (encode xsv) where xsv = VP.fromList xs prop_unbox :: [Int] -> Bool prop_unbox xs = Right xsv == decode (encode xsv) where xsv = VU.fromList xs prop_storable :: [Int] -> Bool prop_storable xs = Right xsv == decode (encode xsv) where xsv = VS.fromList xs prop_storable_tuple :: [Int64] -> [Double] -> Bool prop_storable_tuple xs ys = Right (xsv, ysv) == decode (encode (xsv, ysv)) where (xsv, ysv) = (VS.fromList xs, VS.fromList ys) prop_unsafe_storable :: [Int] -> Bool prop_unsafe_storable xs = Right xsv == runGet unsafeGetVector (runPut $ unsafePutVector xsv) where xsv = VS.fromList xs prop_unsafe_storable_tuple :: [Int64] -> [Double] -> Bool prop_unsafe_storable_tuple xs ys = Right (xsv, ysv) == runGet getTuple (runPut $ putTuple (xsv, ysv)) where (xsv, ysv) = (VS.fromList xs, VS.fromList ys) getTuple = getTwoOf unsafeGetVector unsafeGetVector putTuple = putTwoOf unsafePutVector unsafePutVector main :: IO () main = void $ $quickCheckAll