module Halfs.BinaryMonad (  FSRW
                          , openBinMemRW, getMemoryBlockRW
                          , resetBinRW, sizeBinMemRW, getRW, copyBytesRW
                          , putRW, putRW_, seekBinRW, tellBinRW)
    where

import Binary( BinHandle, Binary, Bin
                   , openBinMem, resetBin, sizeBinMem, get, put, put_
                   , seekBin, tellBin, copyBytes, BinaryHandle )
import System.RawDevice(BufferBlockHandle, newBufferBlockHandle)
import Halfs.FSRW ( FSRW
                  , unsafeLiftIORW)

-- NOTE: leak
getMemoryBlockRW :: (FSRW m) => m (BufferBlockHandle s)
getMemoryBlockRW = unsafeLiftIORW $ newBufferBlockHandle

openBinMemRW :: (FSRW m) => Int -> m BinHandle
openBinMemRW = unsafeLiftIORW . openBinMem

resetBinRW :: (FSRW m,BinaryHandle h) => h -> m ()
resetBinRW = unsafeLiftIORW . resetBin

seekBinRW :: (FSRW m,BinaryHandle h) => h -> Bin a -> m ()
seekBinRW h b = unsafeLiftIORW (seekBin h b)

tellBinRW :: (FSRW m,BinaryHandle h) => h -> m (Bin a)
tellBinRW = unsafeLiftIORW . tellBin

sizeBinMemRW :: (FSRW m) => BinHandle -> m Int
sizeBinMemRW = unsafeLiftIORW . sizeBinMem

getRW :: (FSRW m, Binary a,BinaryHandle h) => h -> m a
getRW = unsafeLiftIORW . get

copyBytesRW :: (FSRW m,BinaryHandle h1,BinaryHandle h2)
            => h1 -- ^input handle
            -> h2 -- ^output handle
            -> Int -- ^number of bytes to copy
            -> m ()
copyBytesRW a b c = unsafeLiftIORW (copyBytes a b c)

-- |FIX: Consider moving to just write monad.  Is this ever legit to use for reading?
putRW :: (FSRW m, Binary a, BinaryHandle h) => h -> a -> m (Bin a)
putRW b a = unsafeLiftIORW $ put b a

putRW_ :: (FSRW m, Binary a,BinaryHandle h) => h -> a -> m ()
putRW_ b a = unsafeLiftIORW $ put_ b a