cedict-0.2.1: Data/Char/CEDICT/C/PtrWalker.hs
{- }
A Monadic interface to pointer navigation.
{ -}
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE OverlappingInstances #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE FlexibleContexts #-}
module Data.Char.CEDICT.C.PtrWalker where
import System.IO.Unsafe
import Foreign.Ptr
import Foreign.Storable
import Control.Monad.State
type PtrWalker a b = (Storable a) => State (Ptr a, Int, Int) b
walkPtr :: (Storable a) => Ptr a -> PtrWalker a b -> b
walkPtr ptr walker = evalState walker (ptr, 0, sizeOf $ pikachu ptr)
skipF :: Int -> PtrWalker a ()
skipF n = do
(ptr, offset, skip) <- get
put (plusPtr ptr $ n * skip, offset + n, skip)
skipB :: Int -> PtrWalker a ()
skipB n = skipF (-n)
skipF' = skipF 1
skipB' = skipB 1
pointer :: PtrWalker a (Ptr a)
pointer = do
(ptr, _, _) <- get
return ptr
value :: PtrWalker a a
value = do
ptr <- pointer
return $ pikachu ptr
offset :: PtrWalker a Int
offset = do
(_, offset, _) <- get
return offset
pikachu :: (Storable a) => Ptr a -> a
pikachu = unsafePerformIO . peek