packages feed

vector-endian (empty) → 0.1.0.0

raw patch · 13 files changed

+555/−0 lines, 13 filesdep +basedep +cpudep +deepseqsetup-changed

Dependencies added: base, cpu, deepseq, vector, vector-endian, zenhack-prelude

Files

+ .gitignore view
@@ -0,0 +1,17 @@+dist+dist-newstyle+.ghc.environment.*+cabal.project.local++# Profiler outputs and formatted reports:+*.prof+*.hp+*.aux+*.ps++.hspec+.hspec-failures++# Code coverage:+.hpc+*.tix
+ CHANGELOG.md view
@@ -0,0 +1,4 @@++# 0.1.0.0++First release
+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2019 Ian Denhardt++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ README.md view
@@ -0,0 +1,8 @@+This is a Haskell package for working with flat arrays of fixed-size+numeric values in a format that is independent of host CPU endianness+(or word size).  This means that you can manipulate the array in memory,+and then just write it out to disk or the network when finished -- no+marshalling step.++The types exposed by this package can be used with the `vector` package;+they implement the type classes provided by that package.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/big-endian/Internal/Endianness.hs view
@@ -0,0 +1,7 @@+module Internal.Endianness (to, from) where++import Data.Vector.Endian.Class++from, to :: Endian a => a -> a+from = fromBE+to = toBE
+ src/endian-common/Data/Vector/Endian/Class.hs view
@@ -0,0 +1,34 @@+module Data.Vector.Endian.Class where++import System.Endian+import Zhp++class Endian a where+    fromLE :: a -> a+    toLE :: a -> a+    fromBE :: a -> a+    toBE :: a -> a++instance Endian Word8 where+    fromLE = id+    toLE = id+    fromBE = id+    toBE = id++instance Endian Word16 where+    fromLE = fromLE16+    toLE = toLE16+    fromBE = fromBE16+    toBE = toBE16++instance Endian Word32 where+    fromLE = fromLE32+    toLE = toLE32+    fromBE = fromBE32+    toBE = toBE32++instance Endian Word64 where+    fromLE = fromLE64+    toLE = toLE64+    fromBE = fromBE64+    toBE = toBE64
+ src/little-endian/Internal/Endianness.hs view
@@ -0,0 +1,7 @@+module Internal.Endianness (to, from) where++import Data.Vector.Endian.Class++from, to :: Endian a => a -> a+from = fromLE+to = toLE
+ src/vector-endian-indef/Data/Vector/Endian.hs view
@@ -0,0 +1,69 @@+module Data.Vector.Endian+    ( MVector+    , Vector++    -- * Accessors+    -- ** Length information+    , length+    , null+    -- ** Indexing+    , (!)+    , (!?)+    , head+    , last+    , unsafeIndex+    , unsafeHead+    , unsafeLast+    -- ** Monadic indexing+    , indexM+    , headM+    , lastM+    , unsafeIndexM+    , unsafeHeadM+    , unsafeLastM+    -- ** Extracting subvectors (slicing)+    , slice+    , init+    , tail+    , take+    , drop+    , splitAt+    , unsafeSlice+    , unsafeInit+    , unsafeTail+    , unsafeTake+    , unsafeDrop+    -- * Construction+    -- ** Initialisation+    , empty+    , singleton+    , replicate+    , generate+    , iterateN+    -- ** Monadic initialisation+    , replicateM+    , generateM+    , iterateNM+    , create+    , createT+    -- ** Unfolding+    , unfoldr+    , unfoldrN+    , unfoldrM+    , unfoldrNM+    , constructN+    , constructrN+    -- ** Enumeration+    , enumFromN+    , enumFromStepN+    , enumFromTo+    , enumFromThenTo+    -- * Raw pointers+    , unsafeFromForeignPtr+    , unsafeFromForeignPtr0+    , unsafeToForeignPtr+    , unsafeToForeignPtr0+    , unsafeWith+    ) where++import Internal.Vector
+ src/vector-endian-indef/Data/Vector/Endian/Mutable.hs view
@@ -0,0 +1,3 @@+module Data.Vector.Endian.Mutable(MVector) where++import Internal.Vector
+ src/vector-endian-indef/Internal/Endianness.hsig view
@@ -0,0 +1,5 @@+signature Internal.Endianness where++import Data.Vector.Endian.Class (Endian)++from, to :: Endian a => a -> a
+ src/vector-endian-indef/Internal/Vector.hs view
@@ -0,0 +1,278 @@+{-# LANGUAGE BangPatterns               #-}+{-# LANGUAGE FlexibleInstances          #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MultiParamTypeClasses      #-}+{-# LANGUAGE RankNTypes                 #-}+{-# LANGUAGE TypeFamilies               #-}+{-# LANGUAGE UndecidableInstances       #-}+module Internal.Vector where++import Zhp hiding (empty)++import Data.Vector.Endian.Class (Endian)+import Internal.Endianness      (from, to)+import Text.Read                (Read(..))++import Control.DeepSeq      (NFData)+import Control.Monad.ST     (ST)+import Data.Traversable     (Traversable)+import Data.Vector.Storable (Storable)+import Foreign.ForeignPtr   (ForeignPtr)+import Foreign.Ptr          (Ptr)+import GHC.Exts             (IsList(..))++import qualified Data.Vector.Generic          as GV+import qualified Data.Vector.Generic.Mutable  as GMV+import qualified Data.Vector.Storable         as SV+import qualified Data.Vector.Storable.Mutable as SMV++newtype MVector s a = MVector (SMV.MVector s a)+    deriving(NFData)++newtype Vector a = Vector (SV.Vector a)+    deriving(Eq, NFData, Semigroup, Monoid)++instance (Storable a, Endian a) => IsList (Vector a) where+    type Item (Vector a) = a++    fromList = Vector . fromList . map to+    fromListN len = Vector . fromListN len . map to+    toList (Vector v) = map from $ SV.toList v++instance (Show a, SV.Storable a, Endian a) => Show (Vector a) where+    show (Vector v) = show $ SV.map from v++instance (Read a, SV.Storable a, Endian a) => Read (Vector a) where+    -- Read in the storable vector, then convert all of the elemnents to+    -- the storage format we need.+    readPrec = Vector . SV.map to <$> readPrec++type instance GV.Mutable Vector = MVector++instance (SV.Storable a, Endian a) => GMV.MVector MVector a where+    -- These are all trivial wrappers around the underlying vector.+    basicLength (MVector v) = GMV.basicLength v+    basicUnsafeSlice i len (MVector v) = MVector (GMV.basicUnsafeSlice i len v)+    basicOverlaps (MVector l) (MVector r) = GMV.basicOverlaps l r+    basicUnsafeNew = fmap MVector . GMV.basicUnsafeNew+    basicInitialize (MVector v) = GMV.basicInitialize v+    basicClear (MVector v) = GMV.basicClear v+    basicUnsafeCopy (MVector l) (MVector r) = GMV.basicUnsafeCopy l r+    basicUnsafeMove (MVector l) (MVector r) = GMV.basicUnsafeMove l r+    basicUnsafeGrow (MVector v) i = MVector <$> GMV.basicUnsafeGrow v i++    -- These have to do endianness conversion:+    basicUnsafeReplicate !i !e = GMV.basicUnsafeReplicate i $! to e+    basicUnsafeRead (MVector v) i = from <$> GMV.basicUnsafeRead v i+    basicUnsafeWrite (MVector v) i e = GMV.basicUnsafeWrite v i $! to e+    basicSet (MVector v) e = GMV.basicSet v $! to e++instance (SV.Storable a, Endian a) => GV.Vector Vector a where+    -- boring wrappers:+    basicUnsafeFreeze (MVector v) = Vector <$> GV.basicUnsafeFreeze v+    basicUnsafeThaw (Vector v) = MVector <$> GV.basicUnsafeThaw v+    basicLength (Vector v) = GV.basicLength v+    basicUnsafeSlice i len (Vector v) = Vector (GV.basicUnsafeSlice i len v)+    basicUnsafeCopy (MVector mv) (Vector v) = GV.basicUnsafeCopy mv v+    elemseq (Vector v) x y = GV.elemseq v x y++    -- need to do endianness conversion:+    basicUnsafeIndexM (Vector v) i = from <$!> GV.basicUnsafeIndexM v i++---------------+-- Accessors --+---------------+++-- Length information+---------------------++length :: (Storable a, Endian a) => Vector a -> Int+length (Vector v) = SV.length v++null :: (Storable a, Endian a) => Vector a -> Bool+null (Vector v) = SV.null v++-- Indexing+-----------++(!) :: (Storable a, Endian a) => Vector a -> Int -> a+(!) (Vector v) i = from $! v SV.! i++(!?) :: (Storable a, Endian a) => Vector a -> Int -> Maybe a+Vector v !? i = from <$!> v SV.!? i++head :: (Storable a, Endian a) => Vector a -> a+head (Vector v) = from $! SV.head v++last :: (Storable a, Endian a) => Vector a -> a+last (Vector v) = from $! SV.last v++unsafeIndex :: (Storable a, Endian a) => Vector a -> Int -> a+unsafeIndex (Vector v) i = from $! SV.unsafeIndex v i++unsafeHead :: (Storable a, Endian a) => Vector a -> a+unsafeHead (Vector v) = from $! SV.unsafeHead v++unsafeLast :: (Storable a, Endian a) => Vector a -> a+unsafeLast (Vector v) = from $! SV.unsafeLast v++-- Monadic indexing+-------------------++indexM :: (Storable a, Endian a, Monad m) => Vector a -> Int -> m a+indexM (Vector v) i = from <$!> SV.indexM v i++headM :: (Storable a, Endian a, Monad m) => Vector a -> m a+headM (Vector v) = from <$!> SV.headM v++lastM :: (Storable a, Endian a, Monad m) => Vector a -> m a+lastM (Vector v) = from <$!> SV.lastM v++unsafeIndexM :: (Storable a, Endian a, Monad m) => Vector a -> Int -> m a+unsafeIndexM (Vector v) i = from <$!> SV.unsafeIndexM v i++unsafeHeadM :: (Storable a, Endian a, Monad m) => Vector a -> m a+unsafeHeadM (Vector v) = from <$!> SV.unsafeHeadM v++unsafeLastM :: (Storable a, Endian a, Monad m) => Vector a -> m a+unsafeLastM (Vector v) = from <$!> SV.unsafeLastM v++-- Extracting subvectors (slicing)+----------------------------------++slice :: (Storable a, Endian a) => Int -> Int -> Vector a -> Vector a+slice i len (Vector v) = Vector (SV.slice i len v)++init :: (Storable a, Endian a) => Vector a -> Vector a+init (Vector v) = Vector (SV.init v)++tail :: (Storable a, Endian a) => Vector a -> Vector a+tail (Vector v) = Vector (SV.tail v)++take :: (Storable a, Endian a) => Int -> Vector a -> Vector a+take count (Vector v) = Vector (SV.take count v)++drop :: (Storable a, Endian a) => Int -> Vector a -> Vector a+drop count (Vector v) = Vector (SV.drop count v)++splitAt :: (Storable a, Endian a) => Int -> Vector a -> (Vector a, Vector a)+splitAt i (Vector v) =+    let (l, r) = SV.splitAt i v+    in (Vector l, Vector r)++unsafeSlice :: (Storable a, Endian a) => Int -> Int -> Vector a -> Vector a+unsafeSlice i len (Vector v) = Vector (SV.unsafeSlice i len v)++unsafeInit :: (Storable a, Endian a) => Vector a -> Vector a+unsafeInit (Vector v) = Vector (SV.unsafeInit v)++unsafeTail :: (Storable a, Endian a) => Vector a -> Vector a+unsafeTail (Vector v) = Vector (SV.unsafeTail v)++unsafeTake :: (Storable a, Endian a) => Int -> Vector a -> Vector a+unsafeTake count (Vector v) = Vector (SV.unsafeTake count v)++unsafeDrop :: (Storable a, Endian a) => Int -> Vector a -> Vector a+unsafeDrop count (Vector v) = Vector (SV.unsafeDrop count v)++---------------+-- Construction+---------------++-- Initialisation+-----------------++empty :: (Storable a, Endian a) => Vector a+empty = Vector SV.empty++singleton :: (Storable a, Endian a) => a -> Vector a+singleton value = Vector (SV.singleton (to value))++replicate :: (Storable a, Endian a) => Int -> a -> Vector a+replicate count value = Vector (SV.replicate count (to value))++generate :: (Storable a, Endian a) => Int -> (Int -> a) -> Vector a+generate count f = Vector (SV.generate count (to . f))++iterateN :: (Storable a, Endian a) => Int -> (a -> a) -> a -> Vector a+iterateN count f orig = Vector (SV.iterateN count (to . f . from) (to orig))++-- Monadic Initialisation+-------------------------++replicateM :: (Monad m, Storable a, Endian a) => Int -> m a -> m (Vector a)+replicateM count m = Vector <$> SV.replicateM count (to <$> m)++generateM :: (Monad m, Storable a, Endian a) => Int -> (Int -> m a) -> m (Vector a)+generateM count m = Vector <$> SV.generateM count (fmap to . m)++iterateNM :: (Monad m, Storable a, Endian a) => Int -> (a -> m a) -> a -> m (Vector a)+iterateNM count m orig = Vector <$> SV.iterateNM count (fmap to . m . from) orig++create :: (Storable a, Endian a) => (forall s. ST s (MVector s a)) -> Vector a+create = GV.create++createT :: (Traversable f, Storable a, Endian a)+    => (forall s. ST s (f (MVector s a))) -> f (Vector a)+createT = GV.createT++-- Unfolding+------------++unfoldr :: (Storable a, Endian a) => (b -> Maybe (a, b)) -> b -> Vector a+unfoldr = GV.unfoldr++unfoldrN :: (Storable a, Endian a) => Int -> (b -> Maybe (a, b)) -> b -> Vector a+unfoldrN = GV.unfoldrN++unfoldrM :: (Monad m, Storable a, Endian a) => (b -> m (Maybe (a, b))) -> b -> m (Vector a)+unfoldrM = GV.unfoldrM++unfoldrNM :: (Monad m, Storable a, Endian a) => Int -> (b -> m (Maybe (a, b))) -> b -> m (Vector a)+unfoldrNM = GV.unfoldrNM++constructN :: (Storable a, Endian a) => Int -> (Vector a -> a) -> Vector a+constructN = GV.constructN++constructrN :: (Storable a, Endian a) => Int -> (Vector a -> a) -> Vector a+constructrN = GV.constructrN++-- Enumeration+--------------+enumFromN :: (Storable a, Endian a, Num a) => a -> Int -> Vector a+enumFromN = GV.enumFromN++enumFromStepN :: (Storable a, Endian a, Num a) => a -> a -> Int -> Vector a+enumFromStepN = GV.enumFromStepN++enumFromTo :: (Storable a, Endian a, Enum a) => a -> a -> Vector a+enumFromTo = GV.enumFromTo++enumFromThenTo :: (Storable a, Endian a, Enum a) => a -> a -> a -> Vector a+enumFromThenTo = GV.enumFromThenTo++---------------+-- Raw pointers+---------------++unsafeFromForeignPtr :: (SV.Storable a, Endian a)+    => ForeignPtr a -> Int -> Int -> Vector a+unsafeFromForeignPtr p off len = Vector $ SV.unsafeFromForeignPtr p off len++unsafeFromForeignPtr0 :: (SV.Storable a, Endian a)+    => ForeignPtr a -> Int -> Vector a+unsafeFromForeignPtr0 p len = Vector $ SV.unsafeFromForeignPtr0 p len++unsafeToForeignPtr :: (SV.Storable a, Endian a)+    => Vector a -> (ForeignPtr a, Int, Int)+unsafeToForeignPtr (Vector v) = SV.unsafeToForeignPtr v++unsafeToForeignPtr0 :: (SV.Storable a, Endian a)+    => Vector a -> (ForeignPtr a, Int)+unsafeToForeignPtr0 (Vector v) = SV.unsafeToForeignPtr0 v++-- | Like 'SV.unsafeWith', but note well: the pointer will point to the value+-- in its *wire format*, which may not match the host cpu endianness.+unsafeWith :: (SV.Storable a, Endian a) => Vector a -> (Ptr a -> IO b) -> IO b+unsafeWith (Vector v) = SV.unsafeWith v
+ vector-endian.cabal view
@@ -0,0 +1,101 @@+cabal-version:       2.2+name:                vector-endian+version:             0.1.0.0+synopsis:            Storable vectors with cpu-independent representation.+description:+  This package exposes data types that implement the type classes from the+  vector package, but the vectors have an in-memory representation that+  is independent of the host's CPU.+  .+  This makes the data stored within them suitable for storage or transmission+  over a network, and they can be converted to bytestrings without copying.+homepage:            https://git.zenhack.net/zenhack/haskell-vector-endian+license:             MIT+license-file:        LICENSE+author:              Ian Denhardt+maintainer:          ian@zenhack.net+copyright:           2019 Ian Denhardt+category:            Data, Data Structures++build-type:          Simple+extra-source-files:+    CHANGELOG.md+  , README.md+  , .gitignore++source-repository head+  type:     git+  branch:   master+  location: https://git.zenhack.net/zenhack/haskell-vector-endian++common shared-opts+  default-extensions:+      NoImplicitPrelude+    , OverloadedStrings+  build-depends:+      base ^>=4.12+    , zenhack-prelude ^>=0.1+    , cpu ^>=0.1.2+    , vector ^>=0.12.0+    , deepseq ^>=1.4.4+  ghc-options:+    -Wall+  default-language:    Haskell2010++library endian-common+  import: shared-opts+  exposed-modules: Data.Vector.Endian.Class+  hs-source-dirs: src/endian-common++library little-endian+  import: shared-opts+  build-depends: endian-common+  exposed-modules: Internal.Endianness+  hs-source-dirs: src/little-endian++library big-endian+  import: shared-opts+  build-depends: endian-common+  exposed-modules: Internal.Endianness+  hs-source-dirs: src/big-endian++library vector-endian-indef+  import: shared-opts+  exposed-modules:+      Data.Vector.Endian+    , Data.Vector.Endian.Mutable+  other-modules:+    Internal.Vector+  build-depends:+    endian-common+  signatures:+    Internal.Endianness+  hs-source-dirs: src/vector-endian-indef++library vector-endian-little+  import: shared-opts+  build-depends: vector-endian-indef, little-endian+  reexported-modules:+      Data.Vector.Endian as Data.Vector.Endian.Little+    , Data.Vector.Endian.Mutable as Data.Vector.Endian.Little.Mutable++library vector-endian-big+  import: shared-opts+  build-depends: vector-endian-indef, big-endian+  reexported-modules:+      Data.Vector.Endian as Data.Vector.Endian.Big+    , Data.Vector.Endian.Mutable as Data.Vector.Endian.Big.Mutable++library+  import: shared-opts+  build-depends:+      endian-common+    , vector-endian-big+    , vector-endian-little+  reexported-modules:+      Data.Vector.Endian.Class as Data.Vector.Endian+    , Data.Vector.Endian.Little+    , Data.Vector.Endian.Little.Mutable+    , Data.Vector.Endian.Big+    , Data.Vector.Endian.Big.Mutable+  hs-source-dirs:      src