\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}