[project @ 2002-05-28 16:33:46 by simonmar]
[ghc-base.git] / Data / Array / IO.hs
index c9eef9f..b225e4b 100644 (file)
@@ -1,24 +1,30 @@
+{-# OPTIONS -#include "HsBase.h" #-}
 -----------------------------------------------------------------------------
--- 
+-- |
 -- Module      :  Data.Array.IO
 -- Copyright   :  (c) The University of Glasgow 2001
--- License     :  BSD-style (see the file libraries/core/LICENSE)
+-- License     :  BSD-style (see the file libraries/base/LICENSE)
 -- 
 -- Maintainer  :  libraries@haskell.org
 -- Stability   :  experimental
 -- Portability :  non-portable
 --
--- $Id: IO.hs,v 1.2 2001/09/14 11:25:23 simonmar Exp $
---
--- Mutable boxed/unboxed arrays in the IO monad.
+-- Mutable boxed and unboxed arrays in the IO monad.
 --
 -----------------------------------------------------------------------------
 
 module Data.Array.IO (
-   module Data.Array.MArray,
+   -- * @IO@ arrays with boxed elements
    IOArray,            -- instance of: Eq, Typeable
+
+   -- * @IO@ arrays with unboxed elements
    IOUArray,           -- instance of: Eq, Typeable
    castIOUArray,       -- :: IOUArray i a -> IO (IOUArray i b)
+
+   -- * Overloaded mutable array interface
+   module Data.Array.MArray,
+
+   -- * Doing I\/O with @IOUArray@s
    hGetArray,          -- :: Handle -> IOUArray Int Word8 -> Int -> IO Int
    hPutArray,          -- :: Handle -> IOUArray Int Word8 -> Int -> IO ()
  ) where
@@ -51,8 +57,13 @@ import GHC.Conc
 import GHC.Base
 
 -----------------------------------------------------------------------------
--- Polymorphic non-strict mutable arrays (IO monad)
-
+-- | Mutable, boxed, non-strict arrays in the 'IO' monad.  The type
+-- arguments are as follows:
+--
+--  * @i@: the index type of the array (should be an instance of @Ix@)
+--
+--  * @e@: the element type of the array.
+--
 newtype IOArray i e = IOArray (STArray RealWorld i e) deriving Eq
 
 iOArrayTc :: TyCon
@@ -81,6 +92,14 @@ instance MArray IOArray e IO where
 -----------------------------------------------------------------------------
 -- Flat unboxed mutable arrays (IO monad)
 
+-- | Mutable, unboxed, strict arrays in the 'IO' monad.  The type
+-- arguments are as follows:
+--
+--  * @i@: the index type of the array (should be an instance of @Ix@)
+--
+--  * @e@: the element type of the array.  Only certain element types
+--    are supported: see 'MArray' for a list of instances.
+--
 newtype IOUArray i e = IOUArray (STUArray RealWorld i e) deriving Eq
 
 iOUArrayTc :: TyCon
@@ -363,6 +382,9 @@ unsafeThawIOUArray arr = stToIO $ do
 castSTUArray :: STUArray s ix a -> ST s (STUArray s ix b)
 castSTUArray (STUArray l u marr#) = return (STUArray l u marr#)
 
+-- | Casts an 'IOUArray' with one element type into one with a
+-- different element type.  All the elements of the resulting array
+-- are undefined (unless you know what you\'re doing...).
 castIOUArray :: IOUArray ix a -> IO (IOUArray ix b)
 castIOUArray (IOUArray marr) = stToIO $ do
     marr' <- castSTUArray marr
@@ -371,16 +393,26 @@ castIOUArray (IOUArray marr) = stToIO $ do
 -- ---------------------------------------------------------------------------
 -- hGetArray
 
-hGetArray :: Handle -> IOUArray Int Word8 -> Int -> IO Int
+-- | Reads a number of 'Word8's from the specified 'Handle' directly
+-- into an array.
+hGetArray
+       :: Handle               -- ^ Handle to read from
+       -> IOUArray Int Word8   -- ^ Array in which to place the values
+       -> Int                  -- ^ Number of 'Word8's to read
+       -> IO Int
+               -- ^ Returns: the number of 'Word8's actually 
+               -- read, which might be smaller than the number requested
+               -- if the end of file was reached.
+
 hGetArray handle (IOUArray (STUArray l u ptr)) count
   | count <= 0 || count > rangeSize (l,u)
   = illegalBufferSize handle "hGetArray" count
   | otherwise = do
       wantReadableHandle "hGetArray" handle $ 
-       \ handle_@Handle__{ haFD=fd, haBuffer=ref } -> do
+       \ handle_@Handle__{ haFD=fd, haBuffer=ref, haIsStream=is_stream } -> do
        buf@Buffer{ bufBuf=raw, bufWPtr=w, bufRPtr=r } <- readIORef ref
        if bufferEmpty buf
-          then readChunkBA fd ptr 0 count
+          then readChunk fd is_stream ptr 0 count
           else do 
                let avail = w - r
                copied <- if (count >= avail)
@@ -395,18 +427,18 @@ hGetArray handle (IOUArray (STUArray l u ptr)) count
 
                let remaining = count - copied
                if remaining > 0 
-                  then do rest <- readChunkBA fd ptr copied remaining
+                  then do rest <- readChunk fd is_stream ptr copied remaining
                           return (rest + count)
                   else return count
-               
-readChunkBA :: FD -> RawBuffer -> Int -> Int -> IO Int
-readChunkBA fd ptr init_off bytes = loop init_off bytes 
+
+readChunk :: FD -> Bool -> RawBuffer -> Int -> Int -> IO Int
+readChunk fd is_stream ptr init_off bytes = loop init_off bytes 
  where
   loop :: Int -> Int -> IO Int
   loop off bytes | bytes <= 0 = return (off - init_off)
   loop off bytes = do
     r' <- throwErrnoIfMinus1RetryMayBlock "readChunk"
-           (readBA (fromIntegral fd) ptr 
+           (read_off_ba (fromIntegral fd) is_stream ptr 
                (fromIntegral off) (fromIntegral bytes))
            (threadWaitRead fd)
     let r = fromIntegral r'
@@ -414,16 +446,14 @@ readChunkBA fd ptr init_off bytes = loop init_off bytes
        then return (off - init_off)
        else loop (off + r) (bytes - r)
 
-foreign import "read_ba_wrap" unsafe
-   readBA :: FD -> RawBuffer -> Int -> CInt -> IO CInt
-
- -----------------------------------------------------------------------------
+-- ---------------------------------------------------------------------------
 -- hPutArray
 
+-- | Writes an array of 'Word8' to the specified 'Handle'.
 hPutArray
-       :: Handle                       -- handle to write to
-       -> IOUArray Int Word8           -- buffer
-       -> Int                          -- number of bytes of data to write
+       :: Handle                       -- ^ Handle to write to
+       -> IOUArray Int Word8           -- ^ Array to write from
+       -> Int                          -- ^ Number of 'Word8's to write
        -> IO ()
 
 hPutArray handle (IOUArray (STUArray l u raw)) count
@@ -431,7 +461,7 @@ hPutArray handle (IOUArray (STUArray l u raw)) count
   = illegalBufferSize handle "hPutArray" count
   | otherwise
    = do wantWritableHandle "hPutArray" handle $ 
-          \ handle_@Handle__{ haFD=fd, haBuffer=ref } -> do
+          \ handle_@Handle__{ haFD=fd, haBuffer=ref, haIsStream=stream } -> do
 
           old_buf@Buffer{ bufBuf=old_raw, bufRPtr=r, bufWPtr=w, bufSize=size }
            <- readIORef ref
@@ -445,27 +475,27 @@ hPutArray handle (IOUArray (STUArray l u raw)) count
                    return ()
 
                -- else, we have to flush
-           else do flushed_buf <- flushWriteBuffer fd old_buf
+           else do flushed_buf <- flushWriteBuffer fd stream old_buf
                    writeIORef ref flushed_buf
                    let this_buf = 
                            Buffer{ bufBuf=raw, bufState=WriteBuffer, 
                                    bufRPtr=0, bufWPtr=count, bufSize=count }
-                   flushWriteBuffer fd this_buf
+                   flushWriteBuffer fd stream this_buf
                    return ()
 
------------------------------------------------------------------------------
+-- ---------------------------------------------------------------------------
 -- Internal Utils
 
-foreign import "memcpy_wrap_dst_off" unsafe 
+foreign import ccall unsafe "__hscore_memcpy_dst_off"
    memcpy_baoff_ba :: RawBuffer -> Int -> RawBuffer -> CSize -> IO (Ptr ())
-foreign import "memcpy_wrap_src_off" unsafe 
+foreign import ccall unsafe "__hscore_memcpy_src_off"
    memcpy_ba_baoff :: RawBuffer -> RawBuffer -> Int -> CSize -> IO (Ptr ())
 
 illegalBufferSize :: Handle -> String -> Int -> IO a
-illegalBufferSize handle fn (sz :: Int) = 
+illegalBufferSize handle fn sz = 
        ioException (IOError (Just handle)
                            InvalidArgument  fn
-                           ("illegal buffer size " ++ showsPrec 9 sz [])
+                           ("illegal buffer size " ++ showsPrec 9 (sz::Int) [])
                            Nothing)
 
 #endif /* __GLASGOW_HASKELL__ */