un-hide some modules from the Haddock docs
[ghc-base.git] / GHC / IO / BufferedIO.hs
1 {-# OPTIONS_GHC  -XNoImplicitPrelude -funbox-strict-fields #-}
2 -----------------------------------------------------------------------------
3 -- |
4 -- Module      :  GHC.IO.BufferedIO
5 -- Copyright   :  (c) The University of Glasgow 2008
6 -- License     :  see libraries/base/LICENSE
7 -- 
8 -- Maintainer  :  cvs-ghc@haskell.org
9 -- Stability   :  internal
10 -- Portability :  non-portable (GHC Extensions)
11 --
12 -- Class of buffered IO devices
13 --
14 -----------------------------------------------------------------------------
15
16 module GHC.IO.BufferedIO (
17    BufferedIO(..),
18    readBuf, readBufNonBlocking, writeBuf, writeBufNonBlocking
19  ) where
20
21 import GHC.Base
22 import GHC.Ptr
23 import Data.Word
24 import GHC.Num
25 import GHC.Real
26 import Data.Maybe
27 -- import GHC.IO
28 import GHC.IO.Device as IODevice
29 import GHC.IO.Device as RawIO
30 import GHC.IO.Buffer
31
32 -- | The purpose of 'BufferedIO' is to provide a common interface for I/O
33 -- devices that can read and write data through a buffer.  Devices that
34 -- implement 'BufferedIO' include ordinary files, memory-mapped files,
35 -- and bytestrings.  The underlying device implementing a 'Handle' must
36 -- provide 'BufferedIO'.
37 --
38 class BufferedIO dev where
39   -- | allocate a new buffer.  The size of the buffer is at the
40   -- discretion of the device; e.g. for a memory-mapped file the
41   -- buffer will probably cover the entire file.
42   newBuffer         :: dev -> BufferState -> IO (Buffer Word8)
43
44   -- | reads bytes into the buffer, blocking if there are no bytes
45   -- available.  Returns the number of bytes read (zero indicates
46   -- end-of-file), and the new buffer.
47   fillReadBuffer    :: dev -> Buffer Word8 -> IO (Int, Buffer Word8)
48
49   -- | reads bytes into the buffer without blocking.  Returns the
50   -- number of bytes read (Nothing indicates end-of-file), and the new
51   -- buffer.
52   fillReadBuffer0   :: dev -> Buffer Word8 -> IO (Maybe Int, Buffer Word8)
53
54   -- | Prepares an empty write buffer.  This lets the device decide
55   -- how to set up a write buffer: the buffer may need to point to a
56   -- specific location in memory, for example.  This is typically used
57   -- by the client when switching from reading to writing on a
58   -- buffered read/write device.
59   --
60   -- There is no corresponding operation for read buffers, because before
61   -- reading the client will always call 'fillReadBuffer'.
62   emptyWriteBuffer  :: dev -> Buffer Word8 -> IO (Buffer Word8)
63   emptyWriteBuffer _dev buf 
64     = return buf{ bufL=0, bufR=0, bufState = WriteBuffer }
65
66   -- | Flush all the data from the supplied write buffer out to the device.
67   -- The returned buffer should be empty, and ready for writing.
68   flushWriteBuffer  :: dev -> Buffer Word8 -> IO (Buffer Word8)
69
70   -- | Flush data from the supplied write buffer out to the device
71   -- without blocking.  Returns the number of bytes written and the
72   -- remaining buffer.
73   flushWriteBuffer0 :: dev -> Buffer Word8 -> IO (Int, Buffer Word8)
74
75 -- for an I/O device, these operations will perform reading/writing
76 -- to/from the device.
77
78 -- for a memory-mapped file, the buffer will be the whole file in
79 -- memory.  fillReadBuffer sets the pointers to encompass the whole
80 -- file, and flushWriteBuffer needs to do no I/O.  A memory-mapped
81 -- file has to maintain its own file pointer.
82
83 -- for a bytestring, again the buffer should match the bytestring in
84 -- memory.
85
86 -- ---------------------------------------------------------------------------
87 -- Low-level read/write to/from buffers
88
89 -- These operations make it easy to implement an instance of 'BufferedIO'
90 -- for an object that supports 'RawIO'.
91
92 readBuf :: RawIO dev => dev -> Buffer Word8 -> IO (Int, Buffer Word8)
93 readBuf dev bbuf = do
94   let bytes = bufferAvailable bbuf
95   res <- withBuffer bbuf $ \ptr ->
96              RawIO.read dev (ptr `plusPtr` bufR bbuf) (fromIntegral bytes)
97   let res' = fromIntegral res
98   return (res', bbuf{ bufR = bufR bbuf + res' })
99          -- zero indicates end of file
100
101 readBufNonBlocking :: RawIO dev => dev -> Buffer Word8
102                      -> IO (Maybe Int,   -- Nothing ==> end of file
103                                          -- Just n  ==> n bytes were read (n>=0)
104                             Buffer Word8)
105 readBufNonBlocking dev bbuf = do
106   let bytes = bufferAvailable bbuf
107   res <- withBuffer bbuf $ \ptr ->
108            IODevice.readNonBlocking dev (ptr `plusPtr` bufR bbuf) (fromIntegral bytes)
109   case res of
110      Nothing -> return (Nothing, bbuf)
111      Just n  -> return (Just n, bbuf{ bufR = bufR bbuf + fromIntegral n })
112
113 writeBuf :: RawIO dev => dev -> Buffer Word8 -> IO (Buffer Word8)
114 writeBuf dev bbuf = do
115   let bytes = bufferElems bbuf
116   withBuffer bbuf $ \ptr ->
117       IODevice.write dev (ptr `plusPtr` bufL bbuf) (fromIntegral bytes)
118   return bbuf{ bufL=0, bufR=0 }
119
120 -- XXX ToDo
121 writeBufNonBlocking :: RawIO dev => dev -> Buffer Word8 -> IO (Int, Buffer Word8)
122 writeBufNonBlocking dev bbuf = do
123   let bytes = bufferElems bbuf
124   res <- withBuffer bbuf $ \ptr ->
125             IODevice.writeNonBlocking dev (ptr `plusPtr` bufL bbuf)
126                                       (fromIntegral bytes)
127   return (res, bufferAdjustL res bbuf)