packages feed

c-storable-deriving (empty) → 0.1

raw patch · 6 files changed

+252/−0 lines, 6 filesdep +basedep +ghc-primsetup-changed

Dependencies added: base, ghc-prim

Files

+ Foreign/CStorable.hs view
@@ -0,0 +1,23 @@+-- | This primarily exports the CStorable typeclass, which may have its+--   methods automatically defaulted if it has a Generic instance.+--   Then, this instance can be transfered via the `Storable' constructor.+module Foreign.CStorable+(CStorable(..),+ StorableWrap(..)+) where++import Foreign.CStorable.TypeClass+import Foreign.CStorable.BaseInstances+import Foreign.Storable+import Foreign.Ptr++-- | Applying the `Storable' constructor to something which is Storable+--   gives it a corresponding CStorable instance.+newtype StorableWrap a = Storable a++-- | Translates a Storable instance to a CStorable instance+instance (Storable a) => CStorable (StorableWrap a) where+  cPeek p                 = fmap Storable $ peek (castPtr p)+  cPoke p (Storable x)    = poke (castPtr p) x+  cAlignment (Storable x) = alignment x+  cSizeOf (Storable x)    = sizeOf x
+ Foreign/CStorable/BaseInstances.hs view
@@ -0,0 +1,82 @@+-- | Provides lots of bas instances, pulled over from `Storable'.+module Foreign.CStorable.BaseInstances where++import Data.Word+import Data.Int++import Foreign.CStorable.TypeClass+import Foreign.C.Types+import Foreign.Storable+import System.Posix.Types+import Foreign.Ptr++#define C(x) \+instance CStorable x where\+  cPeek      = peek;\+  cPoke      = poke;\+  cAlignment = alignment;\+  cSizeOf    = sizeOf\++C(Bool)+C(Char)+C(Double)+C(Float)+C(Int)+C(Int8)+C(Int16)+C(Int32)+C(Int64)+C(Word)+C(Word8)+C(Word16)+C(Word32)+C(Word64)+C(CUIntMax)+C(CIntMax)+C(CUIntPtr)+C(CIntPtr)+C(CTime)+C(CClock)+C(CSigAtomic)+C(CWchar)+C(CSize)+C(CPtrdiff)+C(CDouble)+C(CFloat)+C(CULLong)+C(CLLong)+C(CULong)+C(CLong)+C(CUInt)+C(CInt)+C(CUShort)+C(CShort)+C(CUChar)+C(CSChar)+C(CChar)+C(IntPtr)+C(WordPtr)+C(Fd)+C(CRLim)+C(CTcflag)+C(CSpeed)+C(CCc)+C(CUid)+C(CNlink)+C(CGid)+C(CSsize)+C(CPid)+C(COff)+C(CMode)+C(CIno)+C(CDev)+-- TODO Figure out how to pull these types in+{-+C(CTimeval)+C(Event)+C(Event)+C(PollFd)+C((StablePtr a))+-}+C((Ptr a))+C((FunPtr a))
+ Foreign/CStorable/TypeClass.hs view
@@ -0,0 +1,83 @@+{-# LANGUAGE DefaultSignatures #-}+-- | This module provides the mechanical deriving+--   mechanism for `CStorable'.+module Foreign.CStorable.TypeClass where++import Foreign.Ptr+import Foreign.Storable+import GHC.Generics++-- | A wrapper class for the raw autoderivation functions,+--   representing twhat is necessary for the defaulted+--   `CStorable' methods.+class GCStorable a where+  gcPeek      :: Ptr (a x)-> IO (a x)+  gcPoke      :: Ptr (a x) -> a x -> IO ()+  gcAlignment :: a x -> Int+  gcSizeOf    :: a x -> Int++instance GCStorable U1 where+  gcPeek _      = return U1+  gcPoke _ _    = return ()+  gcAlignment _ = 0+  gcSizeOf _    = 0++-- | Calculates extra space between two items based on alignment+--   and size.+padding :: (GCStorable a, GCStorable b) => a x -> b y -> Int+padding a b = let+  sizeA   = gcSizeOf a+  alignB  = gcAlignment b+  in ((alignB - sizeA) `mod` alignB)++-- | Calculates the total space consumed by a given element, including+--   alignment padding.+offset :: (GCStorable a, GCStorable b) => a x -> b y -> Int+offset a b = padding a b + gcSizeOf a++-- | Test+instance (GCStorable a, GCStorable b) => GCStorable (a :*: b) where+  gcPeek p = do+    a <- gcPeek $ castPtr p+    b <- gcPeek $ castPtr p `plusPtr` offset a (undefined :: b x)+    return $ a :*: b+  gcPoke p (a :*: b) = do+    gcPoke (castPtr p) a+    gcPoke (castPtr (p `plusPtr` offset a b)) b+  gcAlignment _ = lcm (gcAlignment (undefined :: a x))+                      (gcAlignment (undefined :: b y))+  gcSizeOf _    = let+    a = undefined :: a x+    b = undefined :: b y+    in gcSizeOf a + gcSizeOf b + padding a b++instance (GCStorable a) => GCStorable (M1 i c a) where+  gcPeek p           = fmap M1 $ gcPeek (castPtr p)+  gcPoke p (M1 x)    = gcPoke (castPtr p) x+  gcAlignment (M1 x) = gcAlignment x+  gcSizeOf (M1 x)    = gcSizeOf x++instance (CStorable a) => GCStorable (K1 i a) where+  gcPeek p           = fmap K1 $ cPeek (castPtr p)+  gcPoke p (K1 x)    = cPoke (castPtr p) x+  gcAlignment (K1 x) = cAlignment x+  gcSizeOf (K1 x)    = cSizeOf x++-- | This typeclass is basically just a duplicate of `Storable'. It exists+--   because I can't easily modify `Storable', as it is part of base.+class CStorable a where+  cPeek              :: Ptr a -> IO a+  default cPeek      :: (Generic a, GCStorable (Rep a)) => Ptr a -> IO a+  cPeek p            = fmap to $ gcPeek (castPtr p)++  cPoke              :: Ptr a -> a -> IO ()+  default cPoke      :: (Generic a, GCStorable (Rep a)) => Ptr a -> a -> IO ()+  cPoke p x          = gcPoke (castPtr p) $ from x++  cAlignment         :: a -> Int+  default cAlignment :: (Generic a, GCStorable (Rep a)) => a -> Int+  cAlignment         = gcAlignment . from++  cSizeOf            :: a -> Int+  default cSizeOf    :: (Generic a, GCStorable (Rep a)) => a -> Int+  cSizeOf            = gcAlignment . from
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c)2011, Matthew Maurer++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 Matthew Maurer 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
+ c-storable-deriving.cabal view
@@ -0,0 +1,32 @@+Name:                c-storable-deriving+Version:             0.1+Synopsis:            Generate C-like storable instances from datatypes+Description:         Automatically generates struct-rule based Storable+                     instances based on the Generic typeclass.+Homepage:            https://github.com/maurer/c-storable-deriving+License:             BSD3+License-File:        LICENSE+Author:              Matthew Maurer+Maintainer:          maurer@matthewmaurer.org+Category:            Foreign+Build-Type:          Simple+Cabal-Version:       >=1.6+Tested-With:         GHC ==7.2.1++Library+  Exposed-Modules:+    Foreign.CStorable+  Other-Modules:+    Foreign.CStorable.TypeClass+    Foreign.CStorable.BaseInstances+  Build-Depends: base < 5,+                 ghc-prim+  Extensions: FlexibleInstances,+              ScopedTypeVariables,+              TypeOperators,+              FlexibleContexts,+              CPP++Source-Repository HEAD+  Type:     git+  Location: git://github.com/maurer/c-storable-deriving.git