\section{Socket Address}

A Socket Address is a pair of Host Address and Port Number.  Together with a
Transport Protocol, it is sufficient information to address a network port on
any internet host.

\begin{code}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric      #-}
{-# LANGUAGE StrictData         #-}
module Network.Tox.NodeInfo.SocketAddress where

import           Data.Binary                            (Binary, get, put)
import qualified Data.Binary.Bits.Get                   as Bits (runBitGet)
import qualified Data.Binary.Bits.Put                   as Bits (runBitPut)
import qualified Data.Binary.Get                        as Binary (Get)
import qualified Data.Binary.Put                        as Binary (Put)
import           Data.MessagePack                       (MessagePack)
import           Data.Typeable                          (Typeable)
import           GHC.Generics                           (Generic)
import           Network.Tox.Encoding                   (bitGet, bitPut)
import           Network.Tox.NodeInfo.HostAddress       (HostAddress (..))
import qualified Network.Tox.NodeInfo.HostAddress       as HostAddress
import           Network.Tox.NodeInfo.PortNumber        (PortNumber)
import           Network.Tox.NodeInfo.TransportProtocol (TransportProtocol)
import           Test.QuickCheck.Arbitrary              (Arbitrary, arbitrary)


{-------------------------------------------------------------------------------
 -
 - :: Implementation.
 -
 ------------------------------------------------------------------------------}


data SocketAddress = SocketAddress HostAddress PortNumber
  deriving (SocketAddress -> SocketAddress -> Bool
(SocketAddress -> SocketAddress -> Bool)
-> (SocketAddress -> SocketAddress -> Bool) -> Eq SocketAddress
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SocketAddress -> SocketAddress -> Bool
$c/= :: SocketAddress -> SocketAddress -> Bool
== :: SocketAddress -> SocketAddress -> Bool
$c== :: SocketAddress -> SocketAddress -> Bool
Eq, Eq SocketAddress
Eq SocketAddress
-> (SocketAddress -> SocketAddress -> Ordering)
-> (SocketAddress -> SocketAddress -> Bool)
-> (SocketAddress -> SocketAddress -> Bool)
-> (SocketAddress -> SocketAddress -> Bool)
-> (SocketAddress -> SocketAddress -> Bool)
-> (SocketAddress -> SocketAddress -> SocketAddress)
-> (SocketAddress -> SocketAddress -> SocketAddress)
-> Ord SocketAddress
SocketAddress -> SocketAddress -> Bool
SocketAddress -> SocketAddress -> Ordering
SocketAddress -> SocketAddress -> SocketAddress
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: SocketAddress -> SocketAddress -> SocketAddress
$cmin :: SocketAddress -> SocketAddress -> SocketAddress
max :: SocketAddress -> SocketAddress -> SocketAddress
$cmax :: SocketAddress -> SocketAddress -> SocketAddress
>= :: SocketAddress -> SocketAddress -> Bool
$c>= :: SocketAddress -> SocketAddress -> Bool
> :: SocketAddress -> SocketAddress -> Bool
$c> :: SocketAddress -> SocketAddress -> Bool
<= :: SocketAddress -> SocketAddress -> Bool
$c<= :: SocketAddress -> SocketAddress -> Bool
< :: SocketAddress -> SocketAddress -> Bool
$c< :: SocketAddress -> SocketAddress -> Bool
compare :: SocketAddress -> SocketAddress -> Ordering
$ccompare :: SocketAddress -> SocketAddress -> Ordering
$cp1Ord :: Eq SocketAddress
Ord, Int -> SocketAddress -> ShowS
[SocketAddress] -> ShowS
SocketAddress -> String
(Int -> SocketAddress -> ShowS)
-> (SocketAddress -> String)
-> ([SocketAddress] -> ShowS)
-> Show SocketAddress
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SocketAddress] -> ShowS
$cshowList :: [SocketAddress] -> ShowS
show :: SocketAddress -> String
$cshow :: SocketAddress -> String
showsPrec :: Int -> SocketAddress -> ShowS
$cshowsPrec :: Int -> SocketAddress -> ShowS
Show, ReadPrec [SocketAddress]
ReadPrec SocketAddress
Int -> ReadS SocketAddress
ReadS [SocketAddress]
(Int -> ReadS SocketAddress)
-> ReadS [SocketAddress]
-> ReadPrec SocketAddress
-> ReadPrec [SocketAddress]
-> Read SocketAddress
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [SocketAddress]
$creadListPrec :: ReadPrec [SocketAddress]
readPrec :: ReadPrec SocketAddress
$creadPrec :: ReadPrec SocketAddress
readList :: ReadS [SocketAddress]
$creadList :: ReadS [SocketAddress]
readsPrec :: Int -> ReadS SocketAddress
$creadsPrec :: Int -> ReadS SocketAddress
Read, (forall x. SocketAddress -> Rep SocketAddress x)
-> (forall x. Rep SocketAddress x -> SocketAddress)
-> Generic SocketAddress
forall x. Rep SocketAddress x -> SocketAddress
forall x. SocketAddress -> Rep SocketAddress x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep SocketAddress x -> SocketAddress
$cfrom :: forall x. SocketAddress -> Rep SocketAddress x
Generic, Typeable)

instance Binary SocketAddress
instance MessagePack SocketAddress


putSocketAddress :: TransportProtocol -> SocketAddress -> Binary.Put
putSocketAddress :: TransportProtocol -> SocketAddress -> Put
putSocketAddress TransportProtocol
protocol (SocketAddress HostAddress
hostAddress PortNumber
portNumber) =
  let (BitPut ()
putAddressFamily, Put
putHostAddress) = HostAddress -> (BitPut (), Put)
HostAddress.putHostAddress HostAddress
hostAddress in
  do
    BitPut () -> Put
Bits.runBitPut (BitPut () -> Put) -> BitPut () -> Put
forall a b. (a -> b) -> a -> b
$ do
      TransportProtocol -> BitPut ()
forall a. BitEncoding a => a -> BitPut ()
bitPut TransportProtocol
protocol -- first bit = protocol
      BitPut ()
putAddressFamily -- 7 bits = address family
    Put
putHostAddress
    PortNumber -> Put
forall t. Binary t => t -> Put
put PortNumber
portNumber


getSocketAddress :: Binary.Get (TransportProtocol, SocketAddress)
getSocketAddress :: Get (TransportProtocol, SocketAddress)
getSocketAddress = do
  (TransportProtocol
protocol, Get HostAddress
getHostAddress) <- BitGet (TransportProtocol, Get HostAddress)
-> Get (TransportProtocol, Get HostAddress)
forall a. BitGet a -> Get a
Bits.runBitGet (BitGet (TransportProtocol, Get HostAddress)
 -> Get (TransportProtocol, Get HostAddress))
-> BitGet (TransportProtocol, Get HostAddress)
-> Get (TransportProtocol, Get HostAddress)
forall a b. (a -> b) -> a -> b
$ do
    TransportProtocol
protocol <- BitGet TransportProtocol
forall a. BitEncoding a => BitGet a
bitGet
    Get HostAddress
getHostAddress <- BitGet (Get HostAddress)
HostAddress.getHostAddressGetter
    (TransportProtocol, Get HostAddress)
-> BitGet (TransportProtocol, Get HostAddress)
forall (m :: * -> *) a. Monad m => a -> m a
return (TransportProtocol
protocol, Get HostAddress
getHostAddress)
  HostAddress
hostAddress <- Get HostAddress
getHostAddress
  PortNumber
portNumber <- Get PortNumber
forall t. Binary t => Get t
get
  (TransportProtocol, SocketAddress)
-> Get (TransportProtocol, SocketAddress)
forall (m :: * -> *) a. Monad m => a -> m a
return (TransportProtocol
protocol, HostAddress -> PortNumber -> SocketAddress
SocketAddress HostAddress
hostAddress PortNumber
portNumber)


{-------------------------------------------------------------------------------
 -
 - :: Tests.
 -
 ------------------------------------------------------------------------------}


instance Arbitrary SocketAddress where
  arbitrary :: Gen SocketAddress
arbitrary =
    HostAddress -> PortNumber -> SocketAddress
SocketAddress (HostAddress -> PortNumber -> SocketAddress)
-> Gen HostAddress -> Gen (PortNumber -> SocketAddress)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen HostAddress
forall a. Arbitrary a => Gen a
arbitrary Gen (PortNumber -> SocketAddress)
-> Gen PortNumber -> Gen SocketAddress
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen PortNumber
forall a. Arbitrary a => Gen a
arbitrary
\end{code}