Permalink
Browse files

Eliminate a buffer copy in loRead

  • Loading branch information...
lpsmith committed Dec 27, 2011
1 parent c4e334a commit c35cebb0fd528a164288d3f91bc920ac5e108abf
Showing with 13 additions and 7 deletions.
  1. +13 −7 Database/PostgreSQL/LibPQ.hsc
@@ -2179,13 +2179,19 @@ loWrite connection (LoFd fd) bytes
-- descriptor @fd@. In the event of an error, 'Nothing' is returned.
loRead :: Connection -> LoFd -> Int -> IO (Maybe B.ByteString)
-loRead connection (LoFd fd) maxlen
+loRead connection (LoFd !fd) !maxlen
= withConn connection $ \c -> do
- allocaBytes maxlen $ \(buf :: CString) -> do
- len <- c_lo_read c fd buf (fromIntegral maxlen)
- if len < 0
- then return Nothing
- else Just `fmap` B.packCStringLen (buf,fromIntegral len)
+ buf <- mallocBytes maxlen
+ len_ <- c_lo_read c fd buf (fromIntegral maxlen)
+ let len = fromIntegral len_
+ if len < 0
+ then do
+ free buf
+ return Nothing
+ else do
+ bufre <- reallocBytes buf len
+ buffp <- newForeignPtr finalizerFree bufre
+ return (Just (B.fromForeignPtr buffp 0 len))
-- | Changes the current read or write location associated with
-- a large object descriptor. The return value is the new location
@@ -2529,7 +2535,7 @@ foreign import ccall "libpq-fs.h lo_write"
c_lo_write :: Ptr PGconn -> CFd -> CString -> CSize -> IO CInt
foreign import ccall "libpq-fs.h lo_read"
- c_lo_read :: Ptr PGconn -> CFd -> CString -> CSize -> IO CInt
+ c_lo_read :: Ptr PGconn -> CFd -> Ptr Word8 -> CSize -> IO CInt
foreign import ccall "libpq-fs.h lo_lseek"
c_lo_lseek :: Ptr PGconn -> CFd -> CInt -> CInt -> IO CInt

0 comments on commit c35cebb

Please sign in to comment.