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