module System.Posix.Socket.Local
( LocalAddr(..)
, aLocalAddr
, AF_LOCAL
, pattern AF_LOCAL
) where
import Data.Typeable (Typeable)
import Data.Proxy (Proxy(..))
import Data.Word (Word8)
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import qualified Data.ByteString.Internal as BS
import qualified Data.ByteString.Unsafe as BS
import Control.Applicative ((<$>))
import Foreign.Ptr (castPtr, plusPtr)
import Foreign.Storable (Storable(..))
import System.Posix.Socket
data AF_LOCAL deriving Typeable
pattern AF_LOCAL ∷ Proxy AF_LOCAL
pattern AF_LOCAL = Proxy
data LocalAddr = LocalAddr ByteString
| NoLocalAddr
deriving (Typeable, Eq, Ord, Show)
aLocalAddr ∷ Proxy LocalAddr
aLocalAddr = Proxy
instance SockAddr LocalAddr where
sockAddrMaxSize _ = (110)
sockAddrSize (LocalAddr path) = (2)
+ BS.length path + 1
sockAddrSize NoLocalAddr = (2)
peekSockAddr p sz = do
let offset = (2)
if sz < offset + 1
then return NoLocalAddr
else LocalAddr <$> BS.packCStringLen
(castPtr $ plusPtr p offset, sz offset 1)
pokeSockAddr p (LocalAddr path) = do
let offset = (2)
BS.unsafeUseAsCStringLen path $ \(pBs, len) → do
BS.memcpy (castPtr $ plusPtr p offset) (castPtr pBs) (fromIntegral len)
poke (castPtr $ plusPtr p $ offset + len) (0 ∷ Word8)
pokeSockAddr _ NoLocalAddr = return ()
instance SockFamily AF_LOCAL where
type SockFamilyAddr AF_LOCAL = LocalAddr
sockFamilyCode _ = 1