packages feed

primitive-addr (empty) → 0.1.0.0

raw patch · 5 files changed

+193/−0 lines, 5 filesdep +basedep +primitivesetup-changed

Dependencies added: base, primitive

Files

+ CHANGELOG.md view
@@ -0,0 +1,5 @@+# Revision history for primitive-addr++## 0.1.0.0 -- YYYY-mm-dd++* First version. Released on an unsuspecting world.
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2019, Andrew Martin++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 Andrew Martin 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.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ primitive-addr.cabal view
@@ -0,0 +1,21 @@+cabal-version: 2.2+name: primitive-addr+version: 0.1.0.0+synopsis: Addresses to unmanaged memory+homepage: https://github.com/andrewthad/primitive-addr+bug-reports: https://github.com/andrewthad/primitive-addr/issues+license: BSD-3-Clause+license-file: LICENSE+author: Andrew Martin+maintainer: andrew.thaddeus@gmail.com+copyright: 2019 Andrew Martin+category: Data+extra-source-files:  CHANGELOG.md++library+  exposed-modules: Data.Primitive.Addr+  build-depends:+      base >=4.11.1.0 && <5+    , primitive >=0.7 && <0.8+  hs-source-dirs: src+  default-language: Haskell2010
+ src/Data/Primitive/Addr.hs view
@@ -0,0 +1,135 @@+{-# language MagicHash #-}+{-# language UnboxedTuples #-}++-- | Primitive operations on machine addresses.+module Data.Primitive.Addr+  ( -- * Types+    Addr(..)+    -- * Address arithmetic+  , nullAddr+  , plusAddr+  , minusAddr+  , remAddr+  -- * Element access+  , indexOffAddr+  , readOffAddr+  , writeOffAddr+  -- * Block operations+  , copyAddr+  , copyAddrToByteArray+  , moveAddr+  , setAddr+  -- * Conversion+  , addrToInt+) where++import Numeric (showHex)+import Control.Monad.Primitive+import Data.Primitive.Types+import Data.Primitive.ByteArray++import GHC.Exts+import GHC.Ptr+import Foreign.Marshal.Utils++-- | A machine address+data Addr = Addr Addr#++instance Show Addr where+  showsPrec _ (Addr a) =+    showString "0x" . showHex (fromIntegral (I# (addr2Int# a)) :: Word)++instance Eq Addr where+  Addr a# == Addr b# = isTrue# (eqAddr# a# b#)+  Addr a# /= Addr b# = isTrue# (neAddr# a# b#)++instance Ord Addr where+  Addr a# > Addr b# = isTrue# (gtAddr# a# b#)+  Addr a# >= Addr b# = isTrue# (geAddr# a# b#)+  Addr a# < Addr b# = isTrue# (ltAddr# a# b#)+  Addr a# <= Addr b# = isTrue# (leAddr# a# b#)++-- | The null address+nullAddr :: Addr+nullAddr = Addr nullAddr#++infixl 6 `plusAddr`, `minusAddr`+infixl 7 `remAddr`++-- | Offset an address by the given number of bytes+plusAddr :: Addr -> Int -> Addr+plusAddr (Addr a#) (I# i#) = Addr (plusAddr# a# i#)++-- | Distance in bytes between two addresses. The result is only valid if the+-- difference fits in an 'Int'.+minusAddr :: Addr -> Addr -> Int+minusAddr (Addr a#) (Addr b#) = I# (minusAddr# a# b#)++-- | The remainder of the address and the integer.+remAddr :: Addr -> Int -> Int+remAddr (Addr a#) (I# i#) = I# (remAddr# a# i#)++-- | Read a value from a memory position given by an address and an offset.+-- The memory block the address refers to must be immutable. The offset is in+-- elements of type @a@ rather than in bytes.+indexOffAddr :: Prim a => Addr -> Int -> a+{-# INLINE indexOffAddr #-}+indexOffAddr (Addr addr#) (I# i#) = indexOffAddr# addr# i#++-- | Read a value from a memory position given by an address and an offset.+-- The offset is in elements of type @a@ rather than in bytes.+readOffAddr :: (Prim a, PrimMonad m) => Addr -> Int -> m a+{-# INLINE readOffAddr #-}+readOffAddr (Addr addr#) (I# i#) = primitive (readOffAddr# addr# i#)++-- | Write a value to a memory position given by an address and an offset.+-- The offset is in elements of type @a@ rather than in bytes.+writeOffAddr :: (Prim a, PrimMonad m) => Addr -> Int -> a -> m ()+{-# INLINE writeOffAddr #-}+writeOffAddr (Addr addr#) (I# i#) x = primitive_ (writeOffAddr# addr# i# x)++-- | Copy the given number of bytes from the second 'Addr' to the first. The+-- areas may not overlap.+copyAddr :: PrimMonad m+  => Addr -- ^ destination address+  -> Addr -- ^ source address+  -> Int -- ^ number of bytes+  -> m ()+{-# INLINE copyAddr #-}+copyAddr (Addr dst#) (Addr src#) n+  = unsafePrimToPrim $ copyBytes (Ptr dst#) (Ptr src#) n++-- | Copy the given number of bytes from the 'Addr' to the 'MutableByteArray'.+--   The areas may not overlap. This function is only available when compiling+--   with GHC 7.8 or newer.+copyAddrToByteArray :: PrimMonad m+  => MutableByteArray (PrimState m) -- ^ destination+  -> Int -- ^ offset into the destination array+  -> Addr -- ^ source+  -> Int -- ^ number of bytes to copy+  -> m ()+{-# INLINE copyAddrToByteArray #-}+copyAddrToByteArray (MutableByteArray marr) (I# off) (Addr addr) (I# len) =+  primitive_ $ copyAddrToByteArray# addr marr off len++-- | Copy the given number of bytes from the second 'Addr' to the first. The+-- areas may overlap.+moveAddr :: PrimMonad m => Addr         -- ^ destination address+                        -> Addr         -- ^ source address+                        -> Int          -- ^ number of bytes+                        -> m ()+{-# INLINE moveAddr #-}+moveAddr (Addr dst#) (Addr src#) n+  = unsafePrimToPrim $ moveBytes (Ptr dst#) (Ptr src#) n++-- | Fill a memory block of with the given value. The length is in+-- elements of type @a@ rather than in bytes.+setAddr :: (Prim a, PrimMonad m) => Addr -> Int -> a -> m ()+{-# INLINE setAddr #-}+setAddr (Addr addr#) (I# n#) x = primitive_ (setOffAddr# addr# 0# n# x)++-- | Convert an 'Addr' to an 'Int'.+addrToInt :: Addr -> Int+{-# INLINE addrToInt #-}+addrToInt (Addr addr#) = I# (addr2Int# addr#)+