On Fri, Oct 01, 2004 at 09:34:36PM +0100, Simon Marlow wrote:
> 
> Not currently, but I could probably implement the equivalent
> (hGetArrayNonBlocking).

It is perhaps not closely related, but could we also have Network.Socket
recvFrom / sendTo working on raw buffers?

I've attached a proposed implementation. It moves most of code to
recvBufFrom and sendBufTo, and changes recvFrom / sendTo to use the
*Buf* functions.

It would be nice if these functions could be used to implement efficient
recvFromArray / sendToArray (without copying), but I don't know if it's
possible to get the pointer from MutableByteArray. Is there a danger
that GC invalidates the pointer?

Best regards,
Tom

-- 
.signature: Too many levels of symbolic links
--- libraries/network/Network/Socket.hsc        2003-10-20 13:18:30.000000000 +0200
+++ Socket.hsc  2004-10-02 13:53:40.000000000 +0200
@@ -74,7 +74,10 @@
     socketToHandle,    -- :: Socket -> IOMode -> IO Handle
 
     sendTo,            -- :: Socket -> String -> SockAddr -> IO Int
+    sendBufTo,          -- :: Socket -> Ptr CChar -> Int -> SockAddr -> IO Int
+
     recvFrom,          -- :: Socket -> Int -> IO (String, Int, SockAddr)
+    recvBufFrom,        -- :: Socket -> Int -> Ptr CChar -> IO (Int, SockAddr)
     
     send,              -- :: Socket -> String -> IO Int
     recv,              -- :: Socket -> Int    -> IO String
@@ -626,22 +629,36 @@
        -> SockAddr
        -> IO Int       -- Number of Bytes sent
 
-sendTo (MkSocket s _family _stype _protocol status) xs addr = do
- withSockAddr addr $ \p_addr sz -> do
+sendTo sock xs addr = do
  withCString xs $ \str -> do
+   sendBufTo sock str (length xs) addr
+
+sendBufTo :: Socket          -- (possibly) bound/connected Socket
+          -> Ptr CChar -> Int -- Data to send
+          -> SockAddr
+          -> IO Int          -- Number of Bytes sent
+
+sendBufTo (MkSocket s _family _stype _protocol status) ptr nbytes addr = do
+ withSockAddr addr $ \p_addr sz -> do
    liftM fromIntegral $
 #if !defined(__HUGS__)
      throwErrnoIfMinus1Retry_repeatOnBlock "sendTo"
        (threadWaitWrite (fromIntegral s)) $
 #endif
-       c_sendto s str (fromIntegral $ length xs) 0{-flags-} 
+       c_sendto s ptr (fromIntegral $ nbytes) 0{-flags-} 
                        p_addr (fromIntegral sz)
 
 recvFrom :: Socket -> Int -> IO (String, Int, SockAddr)
-recvFrom sock@(MkSocket s _family _stype _protocol status) nbytes
+recvFrom sock nbytes =
+  allocaBytes nbytes $ \ptr -> do
+    (len, sockaddr) <- recvBufFrom sock nbytes ptr
+    str <- peekCStringLen (ptr, len)
+    return (str, len, sockaddr)
+
+recvBufFrom :: Socket -> Int -> Ptr CChar -> IO (Int, SockAddr)
+recvBufFrom sock@(MkSocket s _family _stype _protocol status) nbytes ptr
  | nbytes <= 0 = ioError (mkInvalidRecvArgError "Network.Socket.recvFrom")
  | otherwise   = 
-  allocaBytes nbytes $ \ptr -> do
     withNewSockAddr AF_INET $ \ptr_addr sz -> do
       alloca $ \ptr_len -> do
        poke ptr_len (fromIntegral sz)
@@ -665,8 +682,7 @@
                   getPeerName sock
                else
                   peekSockAddr ptr_addr 
-           str <- peekCStringLen (ptr,len')
-           return (str, len', sockaddr)
+           return (len', sockaddr)
 
 -----------------------------------------------------------------------------
 -- send & recv
_______________________________________________
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

Reply via email to