diff options
author | stolz <unknown> | 2003-02-27 13:27:50 +0000 |
---|---|---|
committer | stolz <unknown> | 2003-02-27 13:27:50 +0000 |
commit | 696266aceb54ce4ad5aa728824a267999cc9a464 (patch) | |
tree | 2fe81ba1bf9162e7aef866a444655e1ffb1e24df /System/Posix/IO.hsc | |
parent | d67d774412a4d583964a585dd4656b5db22e33b4 (diff) |
[project @ 2003-02-27 13:27:50 by stolz]
Move fd{Read,Write} to new layout. Use of memcpy() should bring a large
performance increase compared to the old version.
Diffstat (limited to 'System/Posix/IO.hsc')
-rw-r--r-- | System/Posix/IO.hsc | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/System/Posix/IO.hsc b/System/Posix/IO.hsc index f7baed7..f8d5bb1 100644 --- a/System/Posix/IO.hsc +++ b/System/Posix/IO.hsc @@ -25,10 +25,8 @@ module System.Posix.IO ( openFd, createFile, closeFd, -{- -- ** Reading/writing data fdRead, fdWrite, --} -- ** Seeking fdSeek, @@ -321,3 +319,37 @@ waitToSetLock fd lock = do allocaLock lock $ \p_flock -> throwErrnoIfMinus1_ "waitToSetLock" (c_fcntl_flock fd (#const F_SETLKW) p_flock) + +-- ----------------------------------------------------------------------------- +-- fd{Read,Write} + +fdRead :: Fd -> ByteCount -> IO (String, ByteCount) +fdRead _fd 0 = return ("", 0) +fdRead fd nbytes = do + allocaBytes (fromIntegral nbytes) $ \ bytes -> do + rc <- throwErrnoIfMinus1Retry "fdRead" (c_read fd bytes nbytes) + case rc of + 0 -> ioException (IOError Nothing EOF "fdRead" "EOF" Nothing) + n | n == nbytes -> do + s <- peekCStringLen (bytes, fromIntegral n) + return (s, n) + | otherwise -> do + -- Let go of the excessively long ByteArray# by copying to a + -- shorter one. Maybe we need a new primitive, shrinkCharArray#? + allocaBytes (fromIntegral n) $ \ bytes' -> do + c_memcpy bytes' bytes n + s <- peekCStringLen (bytes', fromIntegral n) + return (s, n) + +fdWrite :: Fd -> String -> IO ByteCount +fdWrite fd str = withCStringLen str $ \ (strPtr,len) -> do + throwErrnoIfMinus1Retry "fdWrite" (c_write fd strPtr (fromIntegral len)) + +foreign import ccall unsafe "read" + c_read :: Fd -> CString -> CSize -> IO CSize + +foreign import ccall unsafe "write" + c_write :: Fd -> CString -> CSize -> IO CSize + +foreign import ccall unsafe "memcpy" + c_memcpy :: Ptr dst -> Ptr src -> CSize -> IO (Ptr dst)
\ No newline at end of file |