Advertisement
Guest User

SSCCE: Storing large structured binary data with Haskell

a guest
Aug 7th, 2013
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. {-# LANGUAGE MultiParamTypeClasses, GeneralizedNewtypeDeriving,
  2.     FunctionalDependencies, FlexibleContexts, FlexibleInstances #-}
  3. import System.IO
  4. import System.IO.MMap
  5. import System.FilePath
  6. import Data.Char(chr)
  7. import Control.Monad.Reader
  8. import Foreign.Ptr
  9. import Foreign.Storable
  10. import Data.Int(Int64)
  11. import System.IO.Unsafe
  12.  
  13. {-
  14.  - struct Foo {
  15.  -     int gunk;
  16.  -     Bar *foosBar;
  17.  - };
  18.  - struct Bar {
  19.  -     int gunk;
  20.  -     int junk;
  21.  - };
  22.  -}
  23.  
  24. class DBStruct a where
  25.     structRead :: Ptr a -> IO a
  26.  
  27. class DBStruct st => StructMem st vt name | st name -> vt where
  28.     offset :: st -> vt -> name -> Int64
  29.  
  30. --this looks really stupid but it's neccesary. eg see advancePtr
  31. strOffset :: StructMem st vt name => Ptr st -> name -> Ptr vt
  32. strOffset = doOffset undefined undefined
  33.     where doOffset :: StructMem st vt name => st -> vt -> Ptr st -> name -> Ptr vt
  34.           doOffset sdummy vdummy s n = plusPtr s $ fromIntegral $ offset sdummy vdummy n
  35.  
  36. elemRead :: (Storable vt, StructMem st vt name) => Ptr st -> name -> IO vt
  37. elemRead s n = peek $ strOffset s n
  38.  
  39. elemPtr :: (DBStruct vt, StructMem st (Ptr vt) name) => Ptr st -> name -> IO vt
  40. elemPtr s n = elemRead s n >>= structRead
  41.  
  42. elemWrite :: (Storable vt, StructMem st vt name) => Ptr st -> name -> vt -> IO ()
  43. elemWrite s n v = poke (strOffset s n) v
  44.  
  45. data Foo = Foo Int Bar
  46.     deriving Show
  47.  
  48. data Bar = Bar Int Int
  49.     deriving Show
  50.  
  51. data Gunk = Gunk
  52. data Junk = Junk
  53. data FoosBar = FoosBar
  54.  
  55. instance StructMem Foo Int Gunk where offset _ _ _ = 0
  56. instance StructMem Foo (Ptr Bar) FoosBar where offset _ _ _ = 8
  57.  
  58. instance StructMem Bar Int Gunk where offset _ _ _ = 0
  59. instance StructMem Bar Int Junk where offset _ _ _ = 8
  60.  
  61. instance DBStruct Foo where
  62.     structRead p = do
  63.         g <- elemRead p Gunk
  64.         b <- elemPtr p FoosBar
  65.         return $ Foo g b
  66.  
  67. instance DBStruct Bar where
  68.     structRead p = do
  69.         g <- elemRead p Gunk
  70.         j <- elemRead p Junk
  71.         return $ Bar g j
  72.  
  73. main = mmapWithFilePtr fname ReadWriteEx (Just (0, sz)) $ test . fst
  74.     where fname = "." </> "test"
  75.           sz = 1024
  76.  
  77. test p = do
  78.     elemWrite theFoo Gunk 17
  79.     elemWrite theFoo FoosBar theBar
  80.     elemWrite theBar Gunk 22
  81.     elemWrite theBar Junk 56
  82.     structRead theFoo >>= print
  83.     where theFoo = plusPtr p 0 :: Ptr Foo
  84.           theBar = plusPtr p 64 :: Ptr Bar
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement