socket-0.2.0.0: src/System/Socket/Address/SockAddrIn.hsc
module System.Socket.Address.SockAddrIn
( SockAddrIn (..)
) where
import Data.Word
import Data.List
import qualified Data.ByteString as BS
import qualified Data.ByteString.Unsafe as BS
import Foreign.Ptr
import Foreign.Storable
import Foreign.Marshal.Utils
import System.Socket.Address
import System.Socket.Internal.FFI
#include "sys/types.h"
#include "sys/socket.h"
#include "sys/un.h"
#include "netinet/in.h"
#let alignment t = "%lu", (unsigned long)offsetof(struct {char x__; t (y__); }, y__)
instance Address SockAddrIn where
addressFamilyNumber _ = (#const AF_INET)
data SockAddrIn
= SockAddrIn
{ sinPort :: Word16
, sinAddr :: BS.ByteString
} deriving (Eq, Ord)
instance Show SockAddrIn where
show (SockAddrIn p a) =
"\"" ++ (concat $ intersperse "." $ map show $ BS.unpack a) ++ ":" ++ show p ++ "\""
instance Storable SockAddrIn where
sizeOf _ = (#size struct sockaddr_in)
alignment _ = (#alignment struct sockaddr_in)
peek ptr = do
ph <- peekByteOff (sin_port ptr) 0 :: IO Word8
pl <- peekByteOff (sin_port ptr) 1 :: IO Word8
a <- BS.packCStringLen (sin_addr ptr, 4) :: IO BS.ByteString
return (SockAddrIn (fromIntegral ph * 256 + fromIntegral pl) a)
where
sin_port = (#ptr struct sockaddr_in, sin_port)
sin_addr = (#ptr struct in_addr, s_addr) . (#ptr struct sockaddr_in, sin_addr)
poke ptr (SockAddrIn p a) = do
c_memset ptr 0 (#const sizeof(struct sockaddr_in))
poke (sin_family ptr) ((#const AF_INET) :: Word16)
pokeByteOff (sin_port ptr) 0 (fromIntegral $ rem (quot p 256) 256 :: Word8)
pokeByteOff (sin_port ptr) 1 (fromIntegral $ rem p 256 :: Word8)
BS.unsafeUseAsCString a $ \a'-> do
copyBytes (sin_addr ptr) a' (min 4 $ BS.length a)-- copyBytes dest from count
where
sin_family = (#ptr struct sockaddr_in, sin_family)
sin_port = (#ptr struct sockaddr_in, sin_port)
sin_addr = (#ptr struct in_addr, s_addr) . (#ptr struct sockaddr_in, sin_addr)