aligned-foreignptr (empty) → 0.1
raw patch · 4 files changed
+159/−0 lines, 4 filesdep +basesetup-changed
Dependencies added: base
Files
- Foreign/ForeignPtr/Aligned.hs +92/−0
- LICENSE +32/−0
- Setup.hs +5/−0
- aligned-foreignptr.cabal +30/−0
+ Foreign/ForeignPtr/Aligned.hs view
@@ -0,0 +1,92 @@++-- | A properly aligned ForeignPtr type.+-- This can be currently achieved only by wasting some bytes.++module Foreign.ForeignPtr.Aligned + ( AlignedForeignPtr + , Alignment, align, fromAlignment+ , mallocAlignedForeignPtr+ , mallocAlignedForeignPtrArray+ , mallocAlignedForeignPtrBytes+ , withAlignedForeignPtr+ , finalizeAlignedForeignPtr+ , touchAlignedForeignPtr+ , castAlignedForeignPtr+ ) + where++--------------------------------------------------------------------------------++import Data.Bits+import Foreign.Ptr+import Foreign.ForeignPtr+import Foreign.Storable+import System.IO.Unsafe++--------------------------------------------------------------------------------++-- | Should be a power of two.+newtype Alignment = Alignment { fromAlignment :: Int } deriving Show++isPowerOfTwo :: Int -> Bool+isPowerOfTwo k + | k< 1 = False+ | k==1 = True+ | True = if odd k + then False+ else isPowerOfTwo (k `div` 2)++-- | A \"smart\" constructor which checks whether the input +-- is a power of two.+align :: Int -> Alignment+align k = if isPowerOfTwo k + then Alignment k+ else error "invalid alignment"++-- | The aligned ForeignPtr type+data AlignedForeignPtr a = AFPtr+ { _fptr :: {-# UNPACK #-} !(ForeignPtr a)+ , _offset :: {-# UNPACK #-} !Int+ } + +instance Show (AlignedForeignPtr a) where+ show afptr = unsafePerformIO $ withAlignedForeignPtr afptr $ \p -> return (show p)+ +mallocAlignedForeignPtr :: Storable a => Alignment -> IO (AlignedForeignPtr a)+mallocAlignedForeignPtr align = mallocAlignedForeignPtrArray align 1+ +mallocAlignedForeignPtrArray :: Storable a => Alignment -> Int -> IO (AlignedForeignPtr a)+mallocAlignedForeignPtrArray align n = worker where+ worker = mallocAlignedForeignPtrBytes align (n * sizeOf undef)+ undef = ioAFPtrUndefined worker ++-- | This is here only to avoid the @ScopedTypeVariables@ language extension+-- for more portability.+ioAFPtrUndefined :: IO (AlignedForeignPtr a) -> a+ioAFPtrUndefined _ = undefined++mallocAlignedForeignPtrBytes :: Alignment -> Int -> IO (AlignedForeignPtr a)+mallocAlignedForeignPtrBytes (Alignment align) n = do+ fptr <- mallocForeignPtrBytes (n+align) -- (n+align-1) would be enough, to be precise. But usually that's an odd number.+ ofs <- withForeignPtr fptr $ \p -> do+ let j = ptrToIntPtr p+ a = fromIntegral align :: IntPtr+ k = (j+a-1) .&. (complement (a-1))+ return $ fromIntegral (k-j)+ return (AFPtr fptr ofs) ++withAlignedForeignPtr :: AlignedForeignPtr a -> (Ptr a -> IO b) -> IO b+withAlignedForeignPtr (AFPtr fptr ofs) action = + withForeignPtr fptr $ \p -> action (p `plusPtr` ofs)++finalizeAlignedForeignPtr :: AlignedForeignPtr a -> IO ()+finalizeAlignedForeignPtr (AFPtr fptr ofs) = finalizeForeignPtr fptr++touchAlignedForeignPtr :: AlignedForeignPtr a -> IO ()+touchAlignedForeignPtr (AFPtr fptr ofs) = touchForeignPtr fptr++castAlignedForeignPtr :: AlignedForeignPtr a -> AlignedForeignPtr b+castAlignedForeignPtr (AFPtr fptr ofs) = AFPtr (castForeignPtr fptr) ofs++--------------------------------------------------------------------------------+
+ LICENSE view
@@ -0,0 +1,32 @@+http://creativecommons.org/licenses/publicdomain/+-------------------------------------------------++Copyright-Only Dedication (based on United States law) or +Public Domain Certification++The person or persons who have associated work with this document (the +"Dedicator" or "Certifier") hereby either (a) certifies that, to the best of +his knowledge, the work of authorship identified is in the public domain +of the country from which the work is published, or (b) hereby dedicates +whatever copyright the dedicators holds in the work of authorship identified +below (the "Work") to the public domain. A certifier, moreover, dedicates any +copyright interest he may have in the associated work, and for these purposes, +is described as a "dedicator" below.++A certifier has taken reasonable steps to verify the copyright status of this +work. Certifier recognizes that his good faith efforts may not shield him +from liability if in fact the work certified is not in the public domain.++Dedicator makes this dedication for the benefit of the public at large and +to the detriment of the Dedicator's heirs and successors. Dedicator intends +this dedication to be an overt act of relinquishment in perpetuity of all +present and future rights under copyright law, whether vested or contingent, +in the Work. Dedicator understands that such relinquishment of all rights +includes the relinquishment of all rights to enforce (by lawsuit or otherwise) +those copyrights in the Work.++Dedicator recognizes that, once placed in the public domain, the Work may +be freely reproduced, distributed, transmitted, used, modified, built upon, +or otherwise exploited by anyone for any purpose, commercial or non-commercial, +and in any way, including by methods that have not yet been invented or +conceived.
+ Setup.hs view
@@ -0,0 +1,5 @@+#! /usr/bin/env runhaskell+ +import Distribution.Simple+main = defaultMain+
+ aligned-foreignptr.cabal view
@@ -0,0 +1,30 @@+Name: aligned-foreignptr+Version: 0.1+Synopsis: An aligned ForeignPtr type+Description: An aligned ForeignPtr type.+License: PublicDomain+License-file: LICENSE+Author: Balazs Komuves+Maintainer: bkomuves (plus) hackage (at) gmail (dot) com+Homepage: http://code.haskell.org/~bkomuves/+Stability: Experimental+Category: System, Foreign+Tested-With: GHC == 6.10.1 +Cabal-Version: >= 1.2+Build-Type: Simple++Flag base4+ Description: Base v4 ++Library+ if flag(base4)+ Build-Depends: base >= 4 && < 5+ cpp-options: -DBASE_MAJOR_VERSION=4+ else+ Build-Depends: base >= 3 && < 4+ cpp-options: -DBASE_MAJOR_VERSION=3+ + Exposed-Modules: Foreign.ForeignPtr.Aligned+ + Hs-Source-Dirs: .+ Extensions: ForeignFunctionInterface