\subsection{Conferences (0x14)}

This section contains a list of saved conferences.

\begin{code}
{-# LANGUAGE DeriveGeneric   #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE StrictData      #-}
module Network.Tox.SaveData.Conferences where

import           Data.Binary               (Binary (..))
import qualified Data.Binary.Get           as Get
import qualified Data.Binary.Put           as Put
import qualified Data.ByteString           as BS
import           Data.Word                 (Word16, Word32, Word64, Word8)
import           GHC.Generics              (Generic)
import           Network.Tox.Crypto.Key    (PublicKey)
import qualified Network.Tox.SaveData.Util as Util
import           Test.QuickCheck.Arbitrary (Arbitrary (..), genericShrink)
import qualified Test.QuickCheck.Arbitrary as Arbitrary

\end{code}

\begin{tabular}{l|l}
  Length        & Contents \\
  \hline
  \texttt{?}    & List of conferences \\
\end{tabular}

\begin{code}

newtype Conferences = Conferences [Conference]
    deriving (Conferences -> Conferences -> Bool
(Conferences -> Conferences -> Bool)
-> (Conferences -> Conferences -> Bool) -> Eq Conferences
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Conferences -> Conferences -> Bool
$c/= :: Conferences -> Conferences -> Bool
== :: Conferences -> Conferences -> Bool
$c== :: Conferences -> Conferences -> Bool
Eq, Int -> Conferences -> ShowS
[Conferences] -> ShowS
Conferences -> String
(Int -> Conferences -> ShowS)
-> (Conferences -> String)
-> ([Conferences] -> ShowS)
-> Show Conferences
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Conferences] -> ShowS
$cshowList :: [Conferences] -> ShowS
show :: Conferences -> String
$cshow :: Conferences -> String
showsPrec :: Int -> Conferences -> ShowS
$cshowsPrec :: Int -> Conferences -> ShowS
Show, ReadPrec [Conferences]
ReadPrec Conferences
Int -> ReadS Conferences
ReadS [Conferences]
(Int -> ReadS Conferences)
-> ReadS [Conferences]
-> ReadPrec Conferences
-> ReadPrec [Conferences]
-> Read Conferences
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Conferences]
$creadListPrec :: ReadPrec [Conferences]
readPrec :: ReadPrec Conferences
$creadPrec :: ReadPrec Conferences
readList :: ReadS [Conferences]
$creadList :: ReadS [Conferences]
readsPrec :: Int -> ReadS Conferences
$creadsPrec :: Int -> ReadS Conferences
Read, (forall x. Conferences -> Rep Conferences x)
-> (forall x. Rep Conferences x -> Conferences)
-> Generic Conferences
forall x. Rep Conferences x -> Conferences
forall x. Conferences -> Rep Conferences x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Conferences x -> Conferences
$cfrom :: forall x. Conferences -> Rep Conferences x
Generic)

instance Binary Conferences where
    get :: Get Conferences
get = [Conference] -> Conferences
Conferences ([Conference] -> Conferences)
-> Get [Conference] -> Get Conferences
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get [Conference]
forall a. (Binary a, Show a) => Get [a]
Util.getList
    put :: Conferences -> Put
put (Conferences [Conference]
xs) = (Conference -> Put) -> [Conference] -> Put
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Conference -> Put
forall t. Binary t => t -> Put
put [Conference]
xs

instance Arbitrary Conferences where
    arbitrary :: Gen Conferences
arbitrary = [Conference] -> Conferences
Conferences ([Conference] -> Conferences)
-> Gen [Conference] -> Gen Conferences
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen [Conference]
forall a. Arbitrary a => Gen a
arbitrary
    shrink :: Conferences -> [Conferences]
shrink    = Conferences -> [Conferences]
forall a.
(Generic a, RecursivelyShrink (Rep a), GSubterms (Rep a) a) =>
a -> [a]
genericShrink

\end{code}

Conference:

\begin{tabular}{l|l}
  Length        & Contents \\
  \hline
  \texttt{1}    & \texttt{uint8\_t} Groupchat type \\
  \texttt{32}   & Groupchat id \\
  \texttt{4}    & \texttt{uint32\_t} Message number \\
  \texttt{2}    & \texttt{uint16\_t} Lossy message number \\
  \texttt{2}    & \texttt{uint16\_t} Peer number \\
  \texttt{4}    & \texttt{uint32\_t} Number of peers \\
  \texttt{1}    & \texttt{uint8\_t} Title length \\
  \texttt{?}    & Title \\
  \texttt{?}    & List of peers \\
\end{tabular}

All peers other than the saver are saved, including frozen peers. On reload,
they all start as frozen.

\begin{code}

maxTitleLen :: Int
maxTitleLen :: Int
maxTitleLen = Int
128

data Conference = Conference
    { Conference -> Word8
conferenceType     :: Word8
    , Conference -> ByteString
conferenceId       :: BS.ByteString
    , Conference -> Word32
messageNumber      :: Word32
    , Conference -> Word16
lossyMessageNumber :: Word16
    , Conference -> Word16
selfPeerNumber     :: Word16
    , Conference -> ByteString
title              :: BS.ByteString
    , Conference -> [Peer]
peers              :: [Peer]
    }
    deriving (Conference -> Conference -> Bool
(Conference -> Conference -> Bool)
-> (Conference -> Conference -> Bool) -> Eq Conference
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Conference -> Conference -> Bool
$c/= :: Conference -> Conference -> Bool
== :: Conference -> Conference -> Bool
$c== :: Conference -> Conference -> Bool
Eq, Int -> Conference -> ShowS
[Conference] -> ShowS
Conference -> String
(Int -> Conference -> ShowS)
-> (Conference -> String)
-> ([Conference] -> ShowS)
-> Show Conference
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Conference] -> ShowS
$cshowList :: [Conference] -> ShowS
show :: Conference -> String
$cshow :: Conference -> String
showsPrec :: Int -> Conference -> ShowS
$cshowsPrec :: Int -> Conference -> ShowS
Show, ReadPrec [Conference]
ReadPrec Conference
Int -> ReadS Conference
ReadS [Conference]
(Int -> ReadS Conference)
-> ReadS [Conference]
-> ReadPrec Conference
-> ReadPrec [Conference]
-> Read Conference
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Conference]
$creadListPrec :: ReadPrec [Conference]
readPrec :: ReadPrec Conference
$creadPrec :: ReadPrec Conference
readList :: ReadS [Conference]
$creadList :: ReadS [Conference]
readsPrec :: Int -> ReadS Conference
$creadsPrec :: Int -> ReadS Conference
Read)

instance Binary Conference where
    get :: Get Conference
get = do
        Word8
conferenceType     <- Get Word8
Get.getWord8
        ByteString
conferenceId       <- Int -> Get ByteString
Get.getByteString Int
32
        Word32
messageNumber      <- Get Word32
Get.getWord32le
        Word16
lossyMessageNumber <- Get Word16
Get.getWord16le
        Word16
selfPeerNumber     <- Get Word16
Get.getWord16le
        Word32
peerCount          <- Get Word32
Get.getWord32le
        Word8
titleLength        <- Get Word8
Get.getWord8
        ByteString
title              <- Int -> Get ByteString
Get.getByteString (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
titleLength)
        [Peer]
peers              <- (Word32 -> Get Peer) -> [Word32] -> Get [Peer]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Get Peer -> Word32 -> Get Peer
forall a b. a -> b -> a
const Get Peer
forall t. Binary t => Get t
get) [Word32
1..Word32
peerCount]
        Conference -> Get Conference
forall (m :: * -> *) a. Monad m => a -> m a
return Conference :: Word8
-> ByteString
-> Word32
-> Word16
-> Word16
-> ByteString
-> [Peer]
-> Conference
Conference{[Peer]
Word8
Word16
Word32
ByteString
peers :: [Peer]
title :: ByteString
selfPeerNumber :: Word16
lossyMessageNumber :: Word16
messageNumber :: Word32
conferenceId :: ByteString
conferenceType :: Word8
peers :: [Peer]
title :: ByteString
selfPeerNumber :: Word16
lossyMessageNumber :: Word16
messageNumber :: Word32
conferenceId :: ByteString
conferenceType :: Word8
..}

    put :: Conference -> Put
put Conference{[Peer]
Word8
Word16
Word32
ByteString
peers :: [Peer]
title :: ByteString
selfPeerNumber :: Word16
lossyMessageNumber :: Word16
messageNumber :: Word32
conferenceId :: ByteString
conferenceType :: Word8
peers :: Conference -> [Peer]
title :: Conference -> ByteString
selfPeerNumber :: Conference -> Word16
lossyMessageNumber :: Conference -> Word16
messageNumber :: Conference -> Word32
conferenceId :: Conference -> ByteString
conferenceType :: Conference -> Word8
..} = do
        Word8 -> Put
Put.putWord8      Word8
conferenceType
        ByteString -> Put
Put.putByteString ByteString
conferenceId
        Word32 -> Put
Put.putWord32le   Word32
messageNumber
        Word16 -> Put
Put.putWord16le   Word16
lossyMessageNumber
        Word16 -> Put
Put.putWord16le   Word16
selfPeerNumber
        Word32 -> Put
Put.putWord32le   (Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word32) -> Int -> Word32
forall a b. (a -> b) -> a -> b
$ [Peer] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Peer]
peers)
        Word8 -> Put
Put.putWord8      (Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ ByteString -> Int
BS.length ByteString
title)
        ByteString -> Put
Put.putByteString ByteString
title
        (Peer -> Put) -> [Peer] -> Put
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Peer -> Put
forall t. Binary t => t -> Put
put [Peer]
peers


instance Arbitrary Conference where
    arbitrary :: Gen Conference
arbitrary = Word8
-> ByteString
-> Word32
-> Word16
-> Word16
-> ByteString
-> [Peer]
-> Conference
Conference
        (Word8
 -> ByteString
 -> Word32
 -> Word16
 -> Word16
 -> ByteString
 -> [Peer]
 -> Conference)
-> Gen Word8
-> Gen
     (ByteString
      -> Word32
      -> Word16
      -> Word16
      -> ByteString
      -> [Peer]
      -> Conference)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Word8
forall a. Arbitrary a => Gen a
arbitrary
        Gen
  (ByteString
   -> Word32
   -> Word16
   -> Word16
   -> ByteString
   -> [Peer]
   -> Conference)
-> Gen ByteString
-> Gen
     (Word32 -> Word16 -> Word16 -> ByteString -> [Peer] -> Conference)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ([Word8] -> ByteString
BS.pack ([Word8] -> ByteString) -> Gen [Word8] -> Gen ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Gen [Word8]
forall a. Arbitrary a => Int -> Gen [a]
Arbitrary.vector Int
32)
        Gen
  (Word32 -> Word16 -> Word16 -> ByteString -> [Peer] -> Conference)
-> Gen Word32
-> Gen (Word16 -> Word16 -> ByteString -> [Peer] -> Conference)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen Word32
forall a. Arbitrary a => Gen a
arbitrary
        Gen (Word16 -> Word16 -> ByteString -> [Peer] -> Conference)
-> Gen Word16 -> Gen (Word16 -> ByteString -> [Peer] -> Conference)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen Word16
forall a. Arbitrary a => Gen a
arbitrary
        Gen (Word16 -> ByteString -> [Peer] -> Conference)
-> Gen Word16 -> Gen (ByteString -> [Peer] -> Conference)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen Word16
forall a. Arbitrary a => Gen a
arbitrary
        Gen (ByteString -> [Peer] -> Conference)
-> Gen ByteString -> Gen ([Peer] -> Conference)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ([Word8] -> ByteString
BS.pack ([Word8] -> ByteString)
-> ([Word8] -> [Word8]) -> [Word8] -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [Word8] -> [Word8]
forall a. Int -> [a] -> [a]
take Int
maxTitleLen ([Word8] -> ByteString) -> Gen [Word8] -> Gen ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen [Word8]
forall a. Arbitrary a => Gen a
arbitrary)
        Gen ([Peer] -> Conference) -> Gen [Peer] -> Gen Conference
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen [Peer]
forall a. Arbitrary a => Gen a
arbitrary

\end{code}

Peer:

\begin{tabular}{l|l}
  Length        & Contents \\
  \hline
  \texttt{32}   & Long term public key \\
  \texttt{32}   & DHT public key \\
  \texttt{2}    & \texttt{uint16\_t} Peer number \\
  \texttt{8}    & \texttt{uint64\_t} Last active timestamp \\
  \texttt{1}    & \texttt{uint8\_t} Name length \\
  \texttt{?}    & Name \\
\end{tabular}

\begin{code}

maxNameLen :: Int
maxNameLen :: Int
maxNameLen = Int
128

data Peer = Peer
    { Peer -> PublicKey
publicKey      :: PublicKey
    , Peer -> PublicKey
dhtPublicKey   :: PublicKey
    , Peer -> Word16
peerNumber     :: Word16
    , Peer -> Word64
lastActiveTime :: Word64
    , Peer -> ByteString
name           :: BS.ByteString
    }
    deriving (Peer -> Peer -> Bool
(Peer -> Peer -> Bool) -> (Peer -> Peer -> Bool) -> Eq Peer
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Peer -> Peer -> Bool
$c/= :: Peer -> Peer -> Bool
== :: Peer -> Peer -> Bool
$c== :: Peer -> Peer -> Bool
Eq, Int -> Peer -> ShowS
[Peer] -> ShowS
Peer -> String
(Int -> Peer -> ShowS)
-> (Peer -> String) -> ([Peer] -> ShowS) -> Show Peer
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Peer] -> ShowS
$cshowList :: [Peer] -> ShowS
show :: Peer -> String
$cshow :: Peer -> String
showsPrec :: Int -> Peer -> ShowS
$cshowsPrec :: Int -> Peer -> ShowS
Show, ReadPrec [Peer]
ReadPrec Peer
Int -> ReadS Peer
ReadS [Peer]
(Int -> ReadS Peer)
-> ReadS [Peer] -> ReadPrec Peer -> ReadPrec [Peer] -> Read Peer
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Peer]
$creadListPrec :: ReadPrec [Peer]
readPrec :: ReadPrec Peer
$creadPrec :: ReadPrec Peer
readList :: ReadS [Peer]
$creadList :: ReadS [Peer]
readsPrec :: Int -> ReadS Peer
$creadsPrec :: Int -> ReadS Peer
Read)

instance Binary Peer where
    get :: Get Peer
get = do
        PublicKey
publicKey      <- Get PublicKey
forall t. Binary t => Get t
get
        PublicKey
dhtPublicKey   <- Get PublicKey
forall t. Binary t => Get t
get
        Word16
peerNumber     <- Get Word16
Get.getWord16le
        Word64
lastActiveTime <- Get Word64
Get.getWord64le
        Word8
nameLength     <- Get Word8
Get.getWord8
        ByteString
name           <- Int -> Get ByteString
Get.getByteString (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
nameLength)
        Peer -> Get Peer
forall (m :: * -> *) a. Monad m => a -> m a
return Peer :: PublicKey -> PublicKey -> Word16 -> Word64 -> ByteString -> Peer
Peer{Word16
Word64
ByteString
PublicKey
name :: ByteString
lastActiveTime :: Word64
peerNumber :: Word16
dhtPublicKey :: PublicKey
publicKey :: PublicKey
name :: ByteString
lastActiveTime :: Word64
peerNumber :: Word16
dhtPublicKey :: PublicKey
publicKey :: PublicKey
..}

    put :: Peer -> Put
put Peer{Word16
Word64
ByteString
PublicKey
name :: ByteString
lastActiveTime :: Word64
peerNumber :: Word16
dhtPublicKey :: PublicKey
publicKey :: PublicKey
name :: Peer -> ByteString
lastActiveTime :: Peer -> Word64
peerNumber :: Peer -> Word16
dhtPublicKey :: Peer -> PublicKey
publicKey :: Peer -> PublicKey
..} = do
        PublicKey -> Put
forall t. Binary t => t -> Put
put               PublicKey
publicKey
        PublicKey -> Put
forall t. Binary t => t -> Put
put               PublicKey
dhtPublicKey
        Word16 -> Put
Put.putWord16le   Word16
peerNumber
        Word64 -> Put
Put.putWord64le   Word64
lastActiveTime
        Word8 -> Put
Put.putWord8      (Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ ByteString -> Int
BS.length ByteString
name)
        ByteString -> Put
Put.putByteString ByteString
name

instance Arbitrary Peer where
    arbitrary :: Gen Peer
arbitrary = PublicKey -> PublicKey -> Word16 -> Word64 -> ByteString -> Peer
Peer
        (PublicKey -> PublicKey -> Word16 -> Word64 -> ByteString -> Peer)
-> Gen PublicKey
-> Gen (PublicKey -> Word16 -> Word64 -> ByteString -> Peer)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen PublicKey
forall a. Arbitrary a => Gen a
arbitrary
        Gen (PublicKey -> Word16 -> Word64 -> ByteString -> Peer)
-> Gen PublicKey -> Gen (Word16 -> Word64 -> ByteString -> Peer)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen PublicKey
forall a. Arbitrary a => Gen a
arbitrary
        Gen (Word16 -> Word64 -> ByteString -> Peer)
-> Gen Word16 -> Gen (Word64 -> ByteString -> Peer)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen Word16
forall a. Arbitrary a => Gen a
arbitrary
        Gen (Word64 -> ByteString -> Peer)
-> Gen Word64 -> Gen (ByteString -> Peer)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen Word64
forall a. Arbitrary a => Gen a
arbitrary
        Gen (ByteString -> Peer) -> Gen ByteString -> Gen Peer
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ([Word8] -> ByteString
BS.pack ([Word8] -> ByteString)
-> ([Word8] -> [Word8]) -> [Word8] -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [Word8] -> [Word8]
forall a. Int -> [a] -> [a]
take Int
maxNameLen ([Word8] -> ByteString) -> Gen [Word8] -> Gen ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen [Word8]
forall a. Arbitrary a => Gen a
arbitrary)

\end{code}