aboutsummaryrefslogtreecommitdiffhomepage
path: root/System/Posix/IO.hsc
diff options
context:
space:
mode:
authorGravatar stolz <unknown>2003-02-27 13:27:50 +0000
committerGravatar stolz <unknown>2003-02-27 13:27:50 +0000
commit696266aceb54ce4ad5aa728824a267999cc9a464 (patch)
tree2fe81ba1bf9162e7aef866a444655e1ffb1e24df /System/Posix/IO.hsc
parentd67d774412a4d583964a585dd4656b5db22e33b4 (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.hsc36
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