[ create a new paste ] login | about

Link: http://codepad.org/o12EL0Nh    [ raw code | fork ]

Plain Text, pasted on Sep 3:
{-# OPTIONS_GHC   -Wall                #-}
{-# LANGUAGE      ScopedTypeVariables
                  , TypeFamilies
                  , FlexibleContexts   #-}

module BitField where

import Control.Monad
--import Control.Applicative
import Data.Bits
import Foreign.Ptr
import Foreign.Storable

class (Storable (CType bitField), Bits (CType bitField))
      => BitField bitField where
   type CType bitField :: *
   size           :: bitField -> Int
   startPosition  :: bitField -> Int
   cSymbol        :: bitField -> Ptr (CType bitField)

   valueOf        :: bitField -> IO (CType bitField)
   valueOf        =  peek . cSymbol

   value          :: bitField -> IO [Bool]
   value n        =  liftM (\v -> bits v (startPosition n) (size n))
                           (valueOf n)

   setValueBit    :: bitField -> Int -> Bool -> IO (CType bitField)
   setValueBit n pos flag
      | pos >= (sizeOf (undefined::CType bitField))
         = error $ "bit Position: "     ++ show pos
                    ++ " >= (size n) :" ++ show (size n)
      | flag
         = modifyValue setBit
      | otherwise
         = modifyValue clearBit
      where modifyValue f = valueOf n
                            >>= (\x -> return $ f x pos)
                          -- could use the below instead of the above
                           --(flip f pos) <$> (valueOf n)
                            >>= poke (cSymbol n)
                            >> valueOf n

   setValue      :: bitField -> [Bool] -> IO [Bool]
   setValue n flags
      | (length flags) > (sizeOf $ cSymbol n)
         = error $ "(length flags) "  ++ show (length flags)
                   ++ " > (size n) :" ++ show (size n)
      | otherwise
         = zipWithM (setValueBit n) [(startPosition n)..] flags
           >> value n

bits           :: Bits a => a -> Int -> Int -> [Bool]
bits _ _   0   = []
bits i pos len = (testBit i pos) : bits i (succ pos) (pred len)




Create a new paste based on this one


Comments: