network-3.1.2.0: Network/Socket/Win32/WSABuf.hsc
{-# 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)