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 +17/−0
- CHANGELOG.md +4/−0
- LICENSE +20/−0
- README.md +8/−0
- Setup.hs +2/−0
- src/big-endian/Internal/Endianness.hs +7/−0
- src/endian-common/Data/Vector/Endian/Class.hs +34/−0
- src/little-endian/Internal/Endianness.hs +7/−0
- src/vector-endian-indef/Data/Vector/Endian.hs +69/−0
- src/vector-endian-indef/Data/Vector/Endian/Mutable.hs +3/−0
- src/vector-endian-indef/Internal/Endianness.hsig +5/−0
- src/vector-endian-indef/Internal/Vector.hs +278/−0
- vector-endian.cabal +101/−0
+ .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