    {-# LANGUAGE ScopedTypeVariables, RecordWildCards #-}

    module Hoogle.Store.ReadBuffer(
        Buffer, newBuffer,
        setPos, getPos,
        getStorable, getByteString,
        ) where

    import General.Base
    import General.System
    import Foreign
    import qualified Data.ByteString as BS

    bufferSize = 100 :: Int

    data Buffer = Buffer {handle :: Handle, fptr :: ForeignPtr ()}

    newBuffer :: Handle -> IO Buffer
    newBuffer handle = do
        ptr <- mallocForeignPtrBytes bufferSize
        return $ Buffer handle ptr

    getPos :: Buffer -> IO Word32
    getPos Buffer{..} = fmap fromIntegral $ hTell handle

    setPos :: Buffer -> Word32 -> IO ()
    setPos b@Buffer{..} pos = do
        hSeek handle AbsoluteSeek $ fromIntegral pos

    getStorable :: forall a . Storable a => Buffer -> IO a
    getStorable Buffer{..} = do
        let n = sizeOf (undefined :: a)
        when (n > bufferSize) $ error $ "Buffer size overflow in getStorable"
        withForeignPtr fptr $ \ptr -> do
            hGetBuf handle ptr $ sizeOf (undefined :: a)
            peek $ castPtr ptr

    getByteString :: Buffer -> Int -> IO BString
    getByteString Buffer{..} n = BS.hGet handle n