{-# OPTIONS_GHC -funbox-strict-fields #-} -- | Support module for the Windows winsock system calls. module Network.Socket.Win32.WSABuf ( WSABuf(..) , withWSABuf ) where #include "HsNet.h" import Foreign.Marshal.Array (allocaArray) import Network.Socket.Imports type ULONG = Word32 data WSABuf = WSABuf { wsaBufPtr :: !(Ptr Word8) , wsaBufLen :: !ULONG } instance Storable WSABuf where sizeOf _ = #{size WSABUF} alignment _ = #alignment WSABUF peek p = do base <- (#peek WSABUF, buf) p len <- (#peek WSABUF, len) p return $ WSABuf base len poke p iov = do (#poke WSABUF, buf) p (wsaBufPtr iov) (#poke WSABUF, len) p (wsaBufLen iov) -- | @withWSABuf cs f@ executes the computation @f@, passing as argument a pair -- consisting of a pointer to a temporarily allocated array of pointers to -- WSABBUF made from @cs@ and the number of pointers (@length cs@). -- /Windows only/. withWSABuf :: [(Ptr Word8, Int)] -> ((Ptr WSABuf, Int) -> IO a) -> IO a withWSABuf [] f = f (nullPtr, 0) withWSABuf cs f = allocaArray csLen $ \aPtr -> do zipWithM_ pokeWsaBuf (ptrs aPtr) cs f (aPtr, csLen) where csLen = length cs ptrs = iterate (`plusPtr` sizeOf (WSABuf nullPtr 0)) pokeWsaBuf ptr (sPtr, sLen) = poke ptr $ WSABuf sPtr (fromIntegral sLen)