-{-# OPTIONS_GHC -fno-implicit-prelude -funbox-strict-fields #-}
-{-# OPTIONS_HADDOCK hide #-}
+{-# OPTIONS_GHC -XNoImplicitPrelude -funbox-strict-fields #-}
-----------------------------------------------------------------------------
-- |
-- Module : GHC.IO.BufferedIO
import GHC.Ptr
import Data.Word
import GHC.Num
-import GHC.Real
import Data.Maybe
-- import GHC.IO
import GHC.IO.Device as IODevice
-- buffer.
fillReadBuffer0 :: dev -> Buffer Word8 -> IO (Maybe Int, Buffer Word8)
- -- | Flush all the data from the supplied write buffer out to the device
- flushWriteBuffer :: dev -> Buffer Word8 -> IO ()
+ -- | Prepares an empty write buffer. This lets the device decide
+ -- how to set up a write buffer: the buffer may need to point to a
+ -- specific location in memory, for example. This is typically used
+ -- by the client when switching from reading to writing on a
+ -- buffered read/write device.
+ --
+ -- There is no corresponding operation for read buffers, because before
+ -- reading the client will always call 'fillReadBuffer'.
+ emptyWriteBuffer :: dev -> Buffer Word8 -> IO (Buffer Word8)
+ emptyWriteBuffer _dev buf
+ = return buf{ bufL=0, bufR=0, bufState = WriteBuffer }
+
+ -- | Flush all the data from the supplied write buffer out to the device.
+ -- The returned buffer should be empty, and ready for writing.
+ flushWriteBuffer :: dev -> Buffer Word8 -> IO (Buffer Word8)
-- | Flush data from the supplied write buffer out to the device
-- without blocking. Returns the number of bytes written and the
-- for a memory-mapped file, the buffer will be the whole file in
-- memory. fillReadBuffer sets the pointers to encompass the whole
--- file, and flushWriteBuffer will do nothing. A memory-mapped file
--- has to maintain its own file pointer.
+-- file, and flushWriteBuffer needs to do no I/O. A memory-mapped
+-- file has to maintain its own file pointer.
-- for a bytestring, again the buffer should match the bytestring in
-- memory.
readBuf dev bbuf = do
let bytes = bufferAvailable bbuf
res <- withBuffer bbuf $ \ptr ->
- RawIO.read dev (ptr `plusPtr` bufR bbuf) (fromIntegral bytes)
- let res' = fromIntegral res
- return (res', bbuf{ bufR = bufR bbuf + res' })
+ RawIO.read dev (ptr `plusPtr` bufR bbuf) bytes
+ return (res, bbuf{ bufR = bufR bbuf + res })
-- zero indicates end of file
readBufNonBlocking :: RawIO dev => dev -> Buffer Word8
readBufNonBlocking dev bbuf = do
let bytes = bufferAvailable bbuf
res <- withBuffer bbuf $ \ptr ->
- IODevice.readNonBlocking dev (ptr `plusPtr` bufR bbuf) (fromIntegral bytes)
+ IODevice.readNonBlocking dev (ptr `plusPtr` bufR bbuf) bytes
case res of
Nothing -> return (Nothing, bbuf)
- Just n -> return (Just n, bbuf{ bufR = bufR bbuf + fromIntegral n })
+ Just n -> return (Just n, bbuf{ bufR = bufR bbuf + n })
-writeBuf :: RawIO dev => dev -> Buffer Word8 -> IO ()
+writeBuf :: RawIO dev => dev -> Buffer Word8 -> IO (Buffer Word8)
writeBuf dev bbuf = do
let bytes = bufferElems bbuf
withBuffer bbuf $ \ptr ->
- IODevice.write dev (ptr `plusPtr` bufL bbuf) (fromIntegral bytes)
+ IODevice.write dev (ptr `plusPtr` bufL bbuf) bytes
+ return bbuf{ bufL=0, bufR=0 }
-- XXX ToDo
writeBufNonBlocking :: RawIO dev => dev -> Buffer Word8 -> IO (Int, Buffer Word8)
writeBufNonBlocking dev bbuf = do
let bytes = bufferElems bbuf
res <- withBuffer bbuf $ \ptr ->
- IODevice.writeNonBlocking dev (ptr `plusPtr` bufL bbuf)
- (fromIntegral bytes)
- return (res, bbuf{ bufL = bufL bbuf + res })
-
+ IODevice.writeNonBlocking dev (ptr `plusPtr` bufL bbuf) bytes
+ return (res, bufferAdjustL res bbuf)