{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE StrictData #-}
-- | Public core API for Tox clients.
--
-- Every function that can fail takes a function-specific error code pointer
-- that can be used to diagnose problems with the Tox state or the function
-- arguments. The error code pointer can be 'nullPtr', which does not influence
-- the function's behaviour, but can be done if the reason for failure is
-- irrelevant to the client.
--
-- The exception to this rule are simple allocation functions whose only failure
-- mode is allocation failure. They return 'nullPtr' in that case, and do not
-- set an error code.
--
-- Every error code type has an OK value to which functions will set their error
-- code value on success. Clients can keep their error code uninitialised before
-- passing it to a function. The library guarantees that after returning, the
-- value pointed to by the error code pointer has been initialised.
--
-- Functions with pointer parameters often have a 'nullPtr' error code, meaning
-- they could not perform any operation, because one of the required parameters
-- was 'nullPtr'. Some functions operate correctly or are defined as effectless
-- on 'nullPtr'.
--
-- Some functions additionally return a value outside their return type domain,
-- or a bool containing true on success and false on failure.
--
-- All functions that take a Tox instance pointer will cause undefined behaviour
-- when passed a 'nullPtr' Tox pointer.
--
-- All integer values are expected in host byte order.
--
-- Functions with parameters with enum types cause unspecified behaviour if the
-- enumeration value is outside the valid range of the type. If possible, the
-- function will try to use a sane default, but there will be no error code, and
-- one possible action for the function to take is to have no effect.
--
-- \subsection events Events and callbacks
--
-- Events are handled by callbacks. One callback can be registered per event.
-- All events have a callback function type named `tox_{event}_cb` and a
-- function to register it named `tox_callback_{event}`. Passing a 'nullPtr'
-- callback will result in no callback being registered for that event. Only one
-- callback per event can be registered, so if a client needs multiple event
-- listeners, it needs to implement the dispatch functionality itself.
--
-- \subsection threading Threading implications
--
-- It is possible to run multiple concurrent threads with a Tox instance for
-- each thread. It is also possible to run all Tox instances in the same thread.
-- A common way to run Tox (multiple or single instance) is to have one thread
-- running a simple tox_iterate loop, sleeping for tox_iteration_interval
-- milliseconds on each iteration.
--
-- If you want to access a single Tox instance from multiple threads, access to
-- the instance must be synchronised. While multiple threads can concurrently
-- access multiple different Tox instances, no more than one API function can
-- operate on a single instance at any given time.
--
-- Functions that write to variable length byte arrays will always have a size
-- function associated with them. The result of this size function is only valid
-- until another mutating function (one that takes a pointer to non-const Tox)
-- is called. Thus, clients must ensure that no other thread calls a mutating
-- function between the call to the size function and the call to the retrieval
-- function.
--
-- E.g. to get the current nickname, one would write
--
-- \code
-- CSize length = tox_self_get_name_size(tox);
-- CString name = malloc(length);
-- if (!name) abort();
-- tox_self_get_name(tox, name);
-- \endcode
--
-- If any other thread calls tox_self_set_name while this thread is allocating
-- memory, the length may have become invalid, and the call to tox_self_get_name
-- may cause undefined behaviour.
--
module Network.Tox.C.Tox where

import           Control.Exception        (bracket)
import           Control.Monad            ((>=>))
import qualified Data.ByteString          as BS
import qualified Data.ByteString.Lazy     as LBS
import qualified Data.MessagePack         as MP
import           Data.Word                (Word16, Word32, Word64)
import           Foreign.C.Enum
import           Foreign.C.String         (CString, withCString)
import           Foreign.C.Types          (CTime (..))
import           Foreign.Marshal.Array    (allocaArray, peekArray)
import           Foreign.Ptr              (Ptr, nullPtr)
import           System.Posix.Types       (EpochTime)

import           FFI.Tox.Tox              (ConferenceType, Connection,
                                           ErrBootstrap (..),
                                           ErrConferenceDelete (..),
                                           ErrConferenceGetType (..),
                                           ErrConferenceInvite (..),
                                           ErrConferenceJoin (..),
                                           ErrConferenceNew (..),
                                           ErrConferencePeerQuery (..),
                                           ErrConferenceSendMessage (..),
                                           ErrConferenceTitle (..),
                                           ErrFileControl (..), ErrFileGet (..),
                                           ErrFileSeek (..), ErrFileSend (..),
                                           ErrFileSendChunk (..),
                                           ErrFriendAdd (..),
                                           ErrFriendByPublicKey (..),
                                           ErrFriendCustomPacket (..),
                                           ErrFriendDelete (..),
                                           ErrFriendGetLastOnline (..),
                                           ErrFriendGetPublicKey (..),
                                           ErrFriendQuery (..),
                                           ErrFriendSendMessage (..),
                                           ErrGetPort (..), ErrNew (..),
                                           ErrSetInfo (..), ErrSetTyping (..),
                                           FileControl, FileKind (..),
                                           MessageType, ToxPtr, UserStatus,
                                           tox_add_tcp_relay, tox_bootstrap,
                                           tox_conference_delete,
                                           tox_conference_get_chatlist,
                                           tox_conference_get_chatlist_size,
                                           tox_conference_get_title,
                                           tox_conference_get_title_size,
                                           tox_conference_get_type,
                                           tox_conference_invite,
                                           tox_conference_join,
                                           tox_conference_new,
                                           tox_conference_peer_count,
                                           tox_conference_peer_get_name,
                                           tox_conference_peer_get_name_size,
                                           tox_conference_peer_get_public_key,
                                           tox_conference_peer_number_is_ours,
                                           tox_conference_send_message,
                                           tox_conference_set_title,
                                           tox_file_control,
                                           tox_file_get_file_id, tox_file_seek,
                                           tox_file_send, tox_file_send_chunk,
                                           tox_friend_add,
                                           tox_friend_add_norequest,
                                           tox_friend_by_public_key,
                                           tox_friend_delete, tox_friend_exists,
                                           tox_friend_get_connection_status,
                                           tox_friend_get_last_online,
                                           tox_friend_get_name,
                                           tox_friend_get_name_size,
                                           tox_friend_get_public_key,
                                           tox_friend_get_status_message,
                                           tox_friend_get_status_message_size,
                                           tox_friend_get_typing,
                                           tox_friend_send_lossless_packet,
                                           tox_friend_send_lossy_packet,
                                           tox_friend_send_message,
                                           tox_get_savedata,
                                           tox_get_savedata_size, tox_hash,
                                           tox_iteration_interval, tox_kill,
                                           tox_new, tox_self_get_address,
                                           tox_self_get_dht_id,
                                           tox_self_get_friend_list,
                                           tox_self_get_friend_list_size,
                                           tox_self_get_name,
                                           tox_self_get_name_size,
                                           tox_self_get_nospam,
                                           tox_self_get_public_key,
                                           tox_self_get_secret_key,
                                           tox_self_get_status_message,
                                           tox_self_get_status_message_size,
                                           tox_self_get_tcp_port,
                                           tox_self_get_udp_port,
                                           tox_self_set_name,
                                           tox_self_set_nospam,
                                           tox_self_set_status,
                                           tox_self_set_status_message,
                                           tox_self_set_typing)
import           Network.Tox.C.Constants
import           Network.Tox.C.Options
import           Network.Tox.Types.Events (Event)


--------------------------------------------------------------------------------
--
-- :: Global types
--
--------------------------------------------------------------------------------

-- Should we introduce such types?
-- newtype FriendNum = FriendNum { friendNum :: Word32 } deriving (Eq, Ord, Read, Show)
-- newtype ConferenceNum = ConferenceNum { conferenceNum :: Word32 } deriving (Eq, Ord, Read, Show)
-- newtype PeerNum = PeerNum { peerNum :: Word32 } deriving (Eq, Ord, Read, Show)
-- newtype FileNum = FileNum { fileNum :: Word32 } deriving (Eq, Ord, Read, Show)


--------------------------------------------------------------------------------
--
-- :: Creation and destruction
--
--------------------------------------------------------------------------------

withTox :: Options -> (ToxPtr -> IO a) -> IO (Either ErrNew a)
withTox :: Options -> (ToxPtr -> IO a) -> IO (Either ErrNew a)
withTox Options
opts ToxPtr -> IO a
f =
    (Either ErrOptionsNew (Either ErrNew a) -> Either ErrNew a)
-> IO (Either ErrOptionsNew (Either ErrNew a))
-> IO (Either ErrNew a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Either ErrOptionsNew (Either ErrNew a) -> Either ErrNew a
forall b. Either ErrOptionsNew (Either ErrNew b) -> Either ErrNew b
mapErr (IO (Either ErrOptionsNew (Either ErrNew a))
 -> IO (Either ErrNew a))
-> ((OptionsPtr -> IO (Either ErrNew a))
    -> IO (Either ErrOptionsNew (Either ErrNew a)))
-> (OptionsPtr -> IO (Either ErrNew a))
-> IO (Either ErrNew a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Options
-> (OptionsPtr -> IO (Either ErrNew a))
-> IO (Either ErrOptionsNew (Either ErrNew a))
forall r.
Options -> (OptionsPtr -> IO r) -> IO (Either ErrOptionsNew r)
withOptions Options
opts ((OptionsPtr -> IO (Either ErrNew a)) -> IO (Either ErrNew a))
-> (OptionsPtr -> IO (Either ErrNew a)) -> IO (Either ErrNew a)
forall a b. (a -> b) -> a -> b
$ \OptionsPtr
copts -> do
        Either ErrNew ToxPtr
result <- (CErr ErrNew -> IO ToxPtr) -> IO (Either ErrNew ToxPtr)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrNew -> IO ToxPtr) -> IO (Either ErrNew ToxPtr))
-> (OptionsPtr -> CErr ErrNew -> IO ToxPtr)
-> OptionsPtr
-> IO (Either ErrNew ToxPtr)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OptionsPtr -> CErr ErrNew -> IO ToxPtr
tox_new (OptionsPtr -> IO (Either ErrNew ToxPtr))
-> OptionsPtr -> IO (Either ErrNew ToxPtr)
forall a b. (a -> b) -> a -> b
$ OptionsPtr
copts
        case Either ErrNew ToxPtr
result of
            Left ErrNew
err ->
                Either ErrNew a -> IO (Either ErrNew a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ErrNew a -> IO (Either ErrNew a))
-> Either ErrNew a -> IO (Either ErrNew a)
forall a b. (a -> b) -> a -> b
$ ErrNew -> Either ErrNew a
forall a b. a -> Either a b
Left ErrNew
err
            Right ToxPtr
tox -> do
                ToxPtr -> IO ()
tox_events_init ToxPtr
tox
                a
res <- ToxPtr -> IO a
f ToxPtr
tox
                ToxPtr -> IO ()
tox_kill ToxPtr
tox
                Either ErrNew a -> IO (Either ErrNew a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ErrNew a -> IO (Either ErrNew a))
-> Either ErrNew a -> IO (Either ErrNew a)
forall a b. (a -> b) -> a -> b
$ a -> Either ErrNew a
forall a b. b -> Either a b
Right a
res

  where
    mapErr :: Either ErrOptionsNew (Either ErrNew b) -> Either ErrNew b
mapErr (Left ErrOptionsNew
ErrOptionsNewMalloc) = ErrNew -> Either ErrNew b
forall a b. a -> Either a b
Left ErrNew
ErrNewMalloc
    mapErr (Right Either ErrNew b
ok)                 = Either ErrNew b
ok

toxGetSavedata :: ToxPtr -> IO BS.ByteString
toxGetSavedata :: ToxPtr -> IO ByteString
toxGetSavedata ToxPtr
tox = do
    CSize
savedataLen <- ToxPtr -> IO CSize
tox_get_savedata_size ToxPtr
tox
    Int -> (Ptr CChar -> IO ByteString) -> IO ByteString
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray (CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
savedataLen) ((Ptr CChar -> IO ByteString) -> IO ByteString)
-> (Ptr CChar -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
savedataPtr -> do
        ToxPtr -> Ptr CChar -> IO ()
tox_get_savedata ToxPtr
tox Ptr CChar
savedataPtr
        CStringLen -> IO ByteString
BS.packCStringLen (Ptr CChar
savedataPtr, CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
savedataLen)


--------------------------------------------------------------------------------
--
-- :: Connection lifecycle and event loop
--
--------------------------------------------------------------------------------


-- | Sends a "get nodes" request to the given bootstrap node with IP, port, and
-- public key to setup connections.
--
-- This function will attempt to connect to the node using UDP. You must use
-- this function even if Options.udp_enabled was set to false.
--
-- @param address The hostname or IP address (IPv4 or IPv6) of the node.
-- @param port The port on the host on which the bootstrap Tox instance is
--   listening.
-- @param public_key The long term public key of the bootstrap node
--   ('tox_public_key_size' bytes).
-- @return true on success.
toxBootstrap :: ToxPtr -> String -> Word16 -> BS.ByteString -> IO (Either ErrBootstrap Bool)
toxBootstrap :: ToxPtr
-> String -> Word16 -> ByteString -> IO (Either ErrBootstrap Bool)
toxBootstrap ToxPtr
tox String
address Word16
port ByteString
pubKey =
    String
-> (Ptr CChar -> IO (Either ErrBootstrap Bool))
-> IO (Either ErrBootstrap Bool)
forall a. String -> (Ptr CChar -> IO a) -> IO a
withCString String
address ((Ptr CChar -> IO (Either ErrBootstrap Bool))
 -> IO (Either ErrBootstrap Bool))
-> (Ptr CChar -> IO (Either ErrBootstrap Bool))
-> IO (Either ErrBootstrap Bool)
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
address' ->
        ByteString
-> (Ptr CChar -> IO (Either ErrBootstrap Bool))
-> IO (Either ErrBootstrap Bool)
forall a. ByteString -> (Ptr CChar -> IO a) -> IO a
BS.useAsCString ByteString
pubKey ((Ptr CChar -> IO (Either ErrBootstrap Bool))
 -> IO (Either ErrBootstrap Bool))
-> (Ptr CChar -> IO (Either ErrBootstrap Bool))
-> IO (Either ErrBootstrap Bool)
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
pubKey' ->
            (CErr ErrBootstrap -> IO Bool) -> IO (Either ErrBootstrap Bool)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrBootstrap -> IO Bool) -> IO (Either ErrBootstrap Bool))
-> (CErr ErrBootstrap -> IO Bool) -> IO (Either ErrBootstrap Bool)
forall a b. (a -> b) -> a -> b
$ ToxPtr
-> Ptr CChar -> Word16 -> Ptr CChar -> CErr ErrBootstrap -> IO Bool
tox_bootstrap ToxPtr
tox Ptr CChar
address' (Word16 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
port) Ptr CChar
pubKey'


-- | Adds additional host:port pair as TCP relay.
--
-- This function can be used to initiate TCP connections to different ports on
-- the same bootstrap node, or to add TCP relays without using them as
-- bootstrap nodes.
--
-- @param address The hostname or IP address (IPv4 or IPv6) of the TCP relay.
-- @param port The port on the host on which the TCP relay is listening.
-- @param public_key The long term public key of the TCP relay
--   ('tox_public_key_size' bytes).
-- @return true on success.
toxAddTcpRelay :: ToxPtr -> String -> Word16 -> BS.ByteString -> IO (Either ErrBootstrap Bool)
toxAddTcpRelay :: ToxPtr
-> String -> Word16 -> ByteString -> IO (Either ErrBootstrap Bool)
toxAddTcpRelay ToxPtr
tox String
address Word16
port ByteString
pubKey =
    String
-> (Ptr CChar -> IO (Either ErrBootstrap Bool))
-> IO (Either ErrBootstrap Bool)
forall a. String -> (Ptr CChar -> IO a) -> IO a
withCString String
address ((Ptr CChar -> IO (Either ErrBootstrap Bool))
 -> IO (Either ErrBootstrap Bool))
-> (Ptr CChar -> IO (Either ErrBootstrap Bool))
-> IO (Either ErrBootstrap Bool)
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
address' ->
        ByteString
-> (Ptr CChar -> IO (Either ErrBootstrap Bool))
-> IO (Either ErrBootstrap Bool)
forall a. ByteString -> (Ptr CChar -> IO a) -> IO a
BS.useAsCString ByteString
pubKey ((Ptr CChar -> IO (Either ErrBootstrap Bool))
 -> IO (Either ErrBootstrap Bool))
-> (Ptr CChar -> IO (Either ErrBootstrap Bool))
-> IO (Either ErrBootstrap Bool)
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
pubKey' ->
            (CErr ErrBootstrap -> IO Bool) -> IO (Either ErrBootstrap Bool)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrBootstrap -> IO Bool) -> IO (Either ErrBootstrap Bool))
-> (CErr ErrBootstrap -> IO Bool) -> IO (Either ErrBootstrap Bool)
forall a b. (a -> b) -> a -> b
$ ToxPtr
-> Ptr CChar -> Word16 -> Ptr CChar -> CErr ErrBootstrap -> IO Bool
tox_add_tcp_relay ToxPtr
tox Ptr CChar
address' (Word16 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
port) Ptr CChar
pubKey'


data ToxEventsStruct
type ToxEvents = Ptr ToxEventsStruct

-- | Common error codes for all functions that set a piece of user-visible
-- client information.
data ErrEventsIterate
    = ErrEventsIterateMalloc
      -- The function failed to allocate enough memory to store the events.

    | ErrEventsDecode
      -- Failed to encode or decode events in msgpack.
    deriving (ErrEventsIterate -> ErrEventsIterate -> Bool
(ErrEventsIterate -> ErrEventsIterate -> Bool)
-> (ErrEventsIterate -> ErrEventsIterate -> Bool)
-> Eq ErrEventsIterate
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ErrEventsIterate -> ErrEventsIterate -> Bool
$c/= :: ErrEventsIterate -> ErrEventsIterate -> Bool
== :: ErrEventsIterate -> ErrEventsIterate -> Bool
$c== :: ErrEventsIterate -> ErrEventsIterate -> Bool
Eq, Eq ErrEventsIterate
Eq ErrEventsIterate
-> (ErrEventsIterate -> ErrEventsIterate -> Ordering)
-> (ErrEventsIterate -> ErrEventsIterate -> Bool)
-> (ErrEventsIterate -> ErrEventsIterate -> Bool)
-> (ErrEventsIterate -> ErrEventsIterate -> Bool)
-> (ErrEventsIterate -> ErrEventsIterate -> Bool)
-> (ErrEventsIterate -> ErrEventsIterate -> ErrEventsIterate)
-> (ErrEventsIterate -> ErrEventsIterate -> ErrEventsIterate)
-> Ord ErrEventsIterate
ErrEventsIterate -> ErrEventsIterate -> Bool
ErrEventsIterate -> ErrEventsIterate -> Ordering
ErrEventsIterate -> ErrEventsIterate -> ErrEventsIterate
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 :: ErrEventsIterate -> ErrEventsIterate -> ErrEventsIterate
$cmin :: ErrEventsIterate -> ErrEventsIterate -> ErrEventsIterate
max :: ErrEventsIterate -> ErrEventsIterate -> ErrEventsIterate
$cmax :: ErrEventsIterate -> ErrEventsIterate -> ErrEventsIterate
>= :: ErrEventsIterate -> ErrEventsIterate -> Bool
$c>= :: ErrEventsIterate -> ErrEventsIterate -> Bool
> :: ErrEventsIterate -> ErrEventsIterate -> Bool
$c> :: ErrEventsIterate -> ErrEventsIterate -> Bool
<= :: ErrEventsIterate -> ErrEventsIterate -> Bool
$c<= :: ErrEventsIterate -> ErrEventsIterate -> Bool
< :: ErrEventsIterate -> ErrEventsIterate -> Bool
$c< :: ErrEventsIterate -> ErrEventsIterate -> Bool
compare :: ErrEventsIterate -> ErrEventsIterate -> Ordering
$ccompare :: ErrEventsIterate -> ErrEventsIterate -> Ordering
$cp1Ord :: Eq ErrEventsIterate
Ord, Int -> ErrEventsIterate
ErrEventsIterate -> Int
ErrEventsIterate -> [ErrEventsIterate]
ErrEventsIterate -> ErrEventsIterate
ErrEventsIterate -> ErrEventsIterate -> [ErrEventsIterate]
ErrEventsIterate
-> ErrEventsIterate -> ErrEventsIterate -> [ErrEventsIterate]
(ErrEventsIterate -> ErrEventsIterate)
-> (ErrEventsIterate -> ErrEventsIterate)
-> (Int -> ErrEventsIterate)
-> (ErrEventsIterate -> Int)
-> (ErrEventsIterate -> [ErrEventsIterate])
-> (ErrEventsIterate -> ErrEventsIterate -> [ErrEventsIterate])
-> (ErrEventsIterate -> ErrEventsIterate -> [ErrEventsIterate])
-> (ErrEventsIterate
    -> ErrEventsIterate -> ErrEventsIterate -> [ErrEventsIterate])
-> Enum ErrEventsIterate
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: ErrEventsIterate
-> ErrEventsIterate -> ErrEventsIterate -> [ErrEventsIterate]
$cenumFromThenTo :: ErrEventsIterate
-> ErrEventsIterate -> ErrEventsIterate -> [ErrEventsIterate]
enumFromTo :: ErrEventsIterate -> ErrEventsIterate -> [ErrEventsIterate]
$cenumFromTo :: ErrEventsIterate -> ErrEventsIterate -> [ErrEventsIterate]
enumFromThen :: ErrEventsIterate -> ErrEventsIterate -> [ErrEventsIterate]
$cenumFromThen :: ErrEventsIterate -> ErrEventsIterate -> [ErrEventsIterate]
enumFrom :: ErrEventsIterate -> [ErrEventsIterate]
$cenumFrom :: ErrEventsIterate -> [ErrEventsIterate]
fromEnum :: ErrEventsIterate -> Int
$cfromEnum :: ErrEventsIterate -> Int
toEnum :: Int -> ErrEventsIterate
$ctoEnum :: Int -> ErrEventsIterate
pred :: ErrEventsIterate -> ErrEventsIterate
$cpred :: ErrEventsIterate -> ErrEventsIterate
succ :: ErrEventsIterate -> ErrEventsIterate
$csucc :: ErrEventsIterate -> ErrEventsIterate
Enum, ErrEventsIterate
ErrEventsIterate -> ErrEventsIterate -> Bounded ErrEventsIterate
forall a. a -> a -> Bounded a
maxBound :: ErrEventsIterate
$cmaxBound :: ErrEventsIterate
minBound :: ErrEventsIterate
$cminBound :: ErrEventsIterate
Bounded, ReadPrec [ErrEventsIterate]
ReadPrec ErrEventsIterate
Int -> ReadS ErrEventsIterate
ReadS [ErrEventsIterate]
(Int -> ReadS ErrEventsIterate)
-> ReadS [ErrEventsIterate]
-> ReadPrec ErrEventsIterate
-> ReadPrec [ErrEventsIterate]
-> Read ErrEventsIterate
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [ErrEventsIterate]
$creadListPrec :: ReadPrec [ErrEventsIterate]
readPrec :: ReadPrec ErrEventsIterate
$creadPrec :: ReadPrec ErrEventsIterate
readList :: ReadS [ErrEventsIterate]
$creadList :: ReadS [ErrEventsIterate]
readsPrec :: Int -> ReadS ErrEventsIterate
$creadsPrec :: Int -> ReadS ErrEventsIterate
Read, Int -> ErrEventsIterate -> ShowS
[ErrEventsIterate] -> ShowS
ErrEventsIterate -> String
(Int -> ErrEventsIterate -> ShowS)
-> (ErrEventsIterate -> String)
-> ([ErrEventsIterate] -> ShowS)
-> Show ErrEventsIterate
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ErrEventsIterate] -> ShowS
$cshowList :: [ErrEventsIterate] -> ShowS
show :: ErrEventsIterate -> String
$cshow :: ErrEventsIterate -> String
showsPrec :: Int -> ErrEventsIterate -> ShowS
$cshowsPrec :: Int -> ErrEventsIterate -> ShowS
Show)

foreign  import ccall tox_events_init :: ToxPtr -> IO ()
foreign  import ccall tox_events_iterate :: ToxPtr -> Bool -> CErr ErrEventsIterate -> IO ToxEvents

foreign  import ccall tox_events_bytes_size :: ToxEvents -> IO Word32
foreign  import ccall tox_events_get_bytes :: ToxEvents -> CString -> IO ()

foreign  import ccall tox_events_load :: CString -> Word32 -> IO ToxEvents
foreign  import ccall tox_events_free :: ToxEvents -> IO ()

toxEventsToPtr :: [Event] -> IO ToxEvents
toxEventsToPtr :: [Event] -> IO ToxEvents
toxEventsToPtr [Event]
events =
    let encoded :: ByteString
encoded = [Event] -> ByteString
forall a. MessagePack a => a -> ByteString
MP.pack [Event]
events in
    ByteString -> (CStringLen -> IO ToxEvents) -> IO ToxEvents
forall a. ByteString -> (CStringLen -> IO a) -> IO a
BS.useAsCStringLen (ByteString -> ByteString
LBS.toStrict ByteString
encoded) ((CStringLen -> IO ToxEvents) -> IO ToxEvents)
-> (CStringLen -> IO ToxEvents) -> IO ToxEvents
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
ptr, Int
len) ->
        Ptr CChar -> Word32 -> IO ToxEvents
tox_events_load Ptr CChar
ptr (Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)

toxEventsFromPtr :: ToxEvents -> IO (Either String [Event])
toxEventsFromPtr :: ToxEvents -> IO (Either String [Event])
toxEventsFromPtr ToxEvents
evPtr = do
    ByteString
bytes <- IO ToxEvents
-> (ToxEvents -> IO ())
-> (ToxEvents -> IO ByteString)
-> IO ByteString
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket (ToxEvents -> IO ToxEvents
forall (m :: * -> *) a. Monad m => a -> m a
return ToxEvents
evPtr) ToxEvents -> IO ()
tox_events_free ((ToxEvents -> IO ByteString) -> IO ByteString)
-> (ToxEvents -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ IO ByteString -> ToxEvents -> IO ByteString
forall a b. a -> b -> a
const (IO ByteString -> ToxEvents -> IO ByteString)
-> IO ByteString -> ToxEvents -> IO ByteString
forall a b. (a -> b) -> a -> b
$ do
        Word32
len <- ToxEvents -> IO Word32
tox_events_bytes_size ToxEvents
evPtr
        Int -> (Ptr CChar -> IO ByteString) -> IO ByteString
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray (Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
len) ((Ptr CChar -> IO ByteString) -> IO ByteString)
-> (Ptr CChar -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
ptr -> do
            ToxEvents -> Ptr CChar -> IO ()
tox_events_get_bytes ToxEvents
evPtr Ptr CChar
ptr
            CStringLen -> IO ByteString
BS.packCStringLen (Ptr CChar
ptr, Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
len)
    case ByteString -> Either DecodeError [Event]
forall a. MessagePack a => ByteString -> Either DecodeError a
MP.unpackEither (ByteString -> Either DecodeError [Event])
-> ByteString -> Either DecodeError [Event]
forall a b. (a -> b) -> a -> b
$ ByteString -> ByteString
LBS.fromStrict ByteString
bytes of
        Left DecodeError
err -> do
            Either DecodeError Object -> IO ()
forall a. Show a => a -> IO ()
print (ByteString -> Either DecodeError Object
forall a. MessagePack a => ByteString -> Either DecodeError a
MP.unpackEither (ByteString -> Either DecodeError Object)
-> ByteString -> Either DecodeError Object
forall a b. (a -> b) -> a -> b
$ ByteString -> ByteString
LBS.fromStrict ByteString
bytes :: Either MP.DecodeError MP.Object)
            Either String [Event] -> IO (Either String [Event])
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String [Event] -> IO (Either String [Event]))
-> Either String [Event] -> IO (Either String [Event])
forall a b. (a -> b) -> a -> b
$ String -> Either String [Event]
forall a b. a -> Either a b
Left (String -> Either String [Event])
-> String -> Either String [Event]
forall a b. (a -> b) -> a -> b
$ DecodeError -> String
forall a. Show a => a -> String
show DecodeError
err
        Right [Event]
ok -> Either String [Event] -> IO (Either String [Event])
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String [Event] -> IO (Either String [Event]))
-> Either String [Event] -> IO (Either String [Event])
forall a b. (a -> b) -> a -> b
$ [Event] -> Either String [Event]
forall a b. b -> Either a b
Right [Event]
ok

toxEventsIterate :: ToxPtr -> IO (Either String [Event])
toxEventsIterate :: ToxPtr -> IO (Either String [Event])
toxEventsIterate ToxPtr
tox =
    (CErr ErrEventsIterate -> IO ToxEvents)
-> IO (Either ErrEventsIterate ToxEvents)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun (ToxPtr -> Bool -> CErr ErrEventsIterate -> IO ToxEvents
tox_events_iterate ToxPtr
tox Bool
True) IO (Either ErrEventsIterate ToxEvents)
-> (Either ErrEventsIterate ToxEvents
    -> IO (Either String [Event]))
-> IO (Either String [Event])
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Left ErrEventsIterate
err    -> Either String [Event] -> IO (Either String [Event])
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String [Event] -> IO (Either String [Event]))
-> Either String [Event] -> IO (Either String [Event])
forall a b. (a -> b) -> a -> b
$ String -> Either String [Event]
forall a b. a -> Either a b
Left (String -> Either String [Event])
-> String -> Either String [Event]
forall a b. (a -> b) -> a -> b
$ ErrEventsIterate -> String
forall a. Show a => a -> String
show ErrEventsIterate
err
        Right ToxEvents
evPtr -> ToxEvents -> IO (Either String [Event])
toxEventsFromPtr ToxEvents
evPtr


-- | Return the time in milliseconds before tox_iterate() should be called again
-- for optimal performance.
toxIterationInterval :: ToxPtr -> IO Word32
toxIterationInterval :: ToxPtr -> IO Word32
toxIterationInterval = ToxPtr -> IO Word32
tox_iteration_interval

--------------------------------------------------------------------------------
--
-- :: Internal client information (Tox address/id)
--
--------------------------------------------------------------------------------


-- | Writes the Tox friend address of the client to a byte array. The address is
-- not in human-readable format. If a client wants to display the address,
-- formatting is required.
--
-- @param address A memory region of at least 'tox_address_size' bytes. If this
--   parameter is 'nullPtr', this function has no effect.
-- @see 'tox_address_size' for the address format.
toxSelfGetAddress :: ToxPtr -> IO BS.ByteString
toxSelfGetAddress :: ToxPtr -> IO ByteString
toxSelfGetAddress ToxPtr
tox =
    let addrLen :: Int
addrLen = Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
tox_address_size in
    Int -> (Ptr CChar -> IO ByteString) -> IO ByteString
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
addrLen ((Ptr CChar -> IO ByteString) -> IO ByteString)
-> (Ptr CChar -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
addrPtr -> do
        ToxPtr -> Ptr CChar -> IO ()
tox_self_get_address ToxPtr
tox Ptr CChar
addrPtr
        CStringLen -> IO ByteString
BS.packCStringLen (Ptr CChar
addrPtr, Int
addrLen)

-- | Set the 4-byte nospam part of the address.
--
-- @param nospam Any 32 bit unsigned integer.
toxSelfSetNospam :: ToxPtr -> Word32 -> IO ()
toxSelfSetNospam :: ToxPtr -> Word32 -> IO ()
toxSelfSetNospam = ToxPtr -> Word32 -> IO ()
tox_self_set_nospam

-- | Get the 4-byte nospam part of the address.
toxSelfGetNospam :: ToxPtr -> IO Word32
toxSelfGetNospam :: ToxPtr -> IO Word32
toxSelfGetNospam = ToxPtr -> IO Word32
tox_self_get_nospam

-- | Copy the Tox Public Key (long term) from the Tox object.
--
-- @param public_key A memory region of at least 'tox_public_key_size' bytes. If
--   this parameter is 'nullPtr', this function has no effect.
toxSelfGetPublicKey :: ToxPtr -> IO BS.ByteString
toxSelfGetPublicKey :: ToxPtr -> IO ByteString
toxSelfGetPublicKey ToxPtr
tox =
    let pkLen :: Int
pkLen = Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
tox_public_key_size in
    Int -> (Ptr CChar -> IO ByteString) -> IO ByteString
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
pkLen ((Ptr CChar -> IO ByteString) -> IO ByteString)
-> (Ptr CChar -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
pkPtr -> do
        ToxPtr -> Ptr CChar -> IO ()
tox_self_get_public_key ToxPtr
tox Ptr CChar
pkPtr
        CStringLen -> IO ByteString
BS.packCStringLen (Ptr CChar
pkPtr, Int
pkLen)

-- | Copy the Tox Secret Key from the Tox object.
--
-- @param secret_key A memory region of at least 'tox_secret_key_size' bytes. If
--   this parameter is 'nullPtr', this function has no effect.
toxSelfGetSecretKey :: ToxPtr -> IO BS.ByteString
toxSelfGetSecretKey :: ToxPtr -> IO ByteString
toxSelfGetSecretKey ToxPtr
tox =
    let skLen :: Int
skLen = Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
tox_secret_key_size in
    Int -> (Ptr CChar -> IO ByteString) -> IO ByteString
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
skLen ((Ptr CChar -> IO ByteString) -> IO ByteString)
-> (Ptr CChar -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
skPtr -> do
        ToxPtr -> Ptr CChar -> IO ()
tox_self_get_secret_key ToxPtr
tox Ptr CChar
skPtr
        CStringLen -> IO ByteString
BS.packCStringLen (Ptr CChar
skPtr, Int
skLen)


--------------------------------------------------------------------------------
--
-- :: User-visible client information (nickname/status)
--
--------------------------------------------------------------------------------


-- | Set the nickname for the Tox client.
--
-- Nickname length cannot exceed 'tox_max_name_length'. If length is 0, the name
-- parameter is ignored (it can be 'nullPtr'), and the nickname is set back to
-- empty.
--
-- @param name A byte array containing the new nickname.
-- @param length The size of the name byte array.
--
-- @return true on success.
toxSelfSetName :: ToxPtr -> BS.ByteString -> IO (Either ErrSetInfo Bool)
toxSelfSetName :: ToxPtr -> ByteString -> IO (Either ErrSetInfo Bool)
toxSelfSetName ToxPtr
tox ByteString
name =
    ByteString
-> (CStringLen -> IO (Either ErrSetInfo Bool))
-> IO (Either ErrSetInfo Bool)
forall a. ByteString -> (CStringLen -> IO a) -> IO a
BS.useAsCStringLen ByteString
name ((CStringLen -> IO (Either ErrSetInfo Bool))
 -> IO (Either ErrSetInfo Bool))
-> (CStringLen -> IO (Either ErrSetInfo Bool))
-> IO (Either ErrSetInfo Bool)
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
nameStr, Int
nameLen) ->
        (CErr ErrSetInfo -> IO Bool) -> IO (Either ErrSetInfo Bool)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrSetInfo -> IO Bool) -> IO (Either ErrSetInfo Bool))
-> (CErr ErrSetInfo -> IO Bool) -> IO (Either ErrSetInfo Bool)
forall a b. (a -> b) -> a -> b
$ ToxPtr -> Ptr CChar -> CSize -> CErr ErrSetInfo -> IO Bool
tox_self_set_name ToxPtr
tox Ptr CChar
nameStr (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
nameLen)

-- | Write the nickname set by tox_self_set_name to a byte array.
--
-- If no nickname was set before calling this function, the name is empty,
-- and this function has no effect.
--
-- Call tox_self_get_name_size to find out how much memory to allocate for
-- the result.
--
-- @param name A valid memory location large enough to hold the nickname.
--   If this parameter is NULL, the function has no effect.
toxSelfGetName :: ToxPtr -> IO BS.ByteString
toxSelfGetName :: ToxPtr -> IO ByteString
toxSelfGetName ToxPtr
tox = do
    CSize
nameLen <- ToxPtr -> IO CSize
tox_self_get_name_size ToxPtr
tox
    Int -> (Ptr CChar -> IO ByteString) -> IO ByteString
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray (CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
nameLen) ((Ptr CChar -> IO ByteString) -> IO ByteString)
-> (Ptr CChar -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
namePtr -> do
        ToxPtr -> Ptr CChar -> IO ()
tox_self_get_name ToxPtr
tox Ptr CChar
namePtr
        CStringLen -> IO ByteString
BS.packCStringLen (Ptr CChar
namePtr, CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
nameLen)


-- | Set the client's status message.
--
-- Status message length cannot exceed 'tox_max_status_message_length'. If
-- length is 0, the status parameter is ignored (it can be 'nullPtr'), and the
-- user status is set back to empty.
toxSelfSetStatusMessage :: ToxPtr -> BS.ByteString -> IO (Either ErrSetInfo Bool)
toxSelfSetStatusMessage :: ToxPtr -> ByteString -> IO (Either ErrSetInfo Bool)
toxSelfSetStatusMessage ToxPtr
tox ByteString
statusMsg =
    ByteString
-> (CStringLen -> IO (Either ErrSetInfo Bool))
-> IO (Either ErrSetInfo Bool)
forall a. ByteString -> (CStringLen -> IO a) -> IO a
BS.useAsCStringLen ByteString
statusMsg ((CStringLen -> IO (Either ErrSetInfo Bool))
 -> IO (Either ErrSetInfo Bool))
-> (CStringLen -> IO (Either ErrSetInfo Bool))
-> IO (Either ErrSetInfo Bool)
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
statusMsgStr, Int
statusMsgLen) ->
        (CErr ErrSetInfo -> IO Bool) -> IO (Either ErrSetInfo Bool)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrSetInfo -> IO Bool) -> IO (Either ErrSetInfo Bool))
-> (CErr ErrSetInfo -> IO Bool) -> IO (Either ErrSetInfo Bool)
forall a b. (a -> b) -> a -> b
$ ToxPtr -> Ptr CChar -> CSize -> CErr ErrSetInfo -> IO Bool
tox_self_set_status_message ToxPtr
tox Ptr CChar
statusMsgStr (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
statusMsgLen)


-- | Write the status message set by tox_self_set_status_message to a byte array.
--
-- If no status message was set before calling this function, the status is
-- empty, and this function has no effect.
--
-- Call tox_self_get_status_message_size to find out how much memory to allocate for
-- the result.
--
-- @param status_message A valid memory location large enough to hold the
--   status message. If this parameter is NULL, the function has no effect.
toxSelfGetStatusMessage :: ToxPtr -> IO BS.ByteString
toxSelfGetStatusMessage :: ToxPtr -> IO ByteString
toxSelfGetStatusMessage ToxPtr
tox = do
    CSize
statusMessageLen <- ToxPtr -> IO CSize
tox_self_get_status_message_size ToxPtr
tox
    Int -> (Ptr CChar -> IO ByteString) -> IO ByteString
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray (CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
statusMessageLen) ((Ptr CChar -> IO ByteString) -> IO ByteString)
-> (Ptr CChar -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
statusMessagePtr -> do
        ToxPtr -> Ptr CChar -> IO ()
tox_self_get_status_message ToxPtr
tox Ptr CChar
statusMessagePtr
        CStringLen -> IO ByteString
BS.packCStringLen (Ptr CChar
statusMessagePtr, CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
statusMessageLen)


-- | Set the client's user status.
--
-- @param user_status One of the user statuses listed in the enumeration above.
toxSelfSetStatus :: ToxPtr -> UserStatus -> IO ()
toxSelfSetStatus :: ToxPtr -> UserStatus -> IO ()
toxSelfSetStatus ToxPtr
tox UserStatus
userStatus =
    ToxPtr -> CEnum UserStatus -> IO ()
tox_self_set_status ToxPtr
tox (CEnum UserStatus -> IO ()) -> CEnum UserStatus -> IO ()
forall a b. (a -> b) -> a -> b
$ UserStatus -> CEnum UserStatus
forall a. Enum a => a -> CEnum a
toCEnum UserStatus
userStatus


--------------------------------------------------------------------------------
--
-- :: Friend list management
--
--------------------------------------------------------------------------------


-- | Add a friend to the friend list and send a friend request.
--
-- A friend request message must be at least 1 byte long and at most
-- 'tox_max_friend_request_length'.
--
-- Friend numbers are unique identifiers used in all functions that operate on
-- friends. Once added, a friend number is stable for the lifetime of the Tox
-- object. After saving the state and reloading it, the friend numbers may not
-- be the same as before. Deleting a friend creates a gap in the friend number
-- set, which is filled by the next adding of a friend. Any pattern in friend
-- numbers should not be relied on.
--
-- If more than INT32_MAX friends are added, this function causes undefined
-- behaviour.
--
-- @param address The address of the friend (returned by tox_self_get_address of
--   the friend you wish to add) it must be 'tox_address_size' bytes.
-- @param message The message that will be sent along with the friend request.
-- @param length The length of the data byte array.
--
-- @return the friend number on success, UINT32_MAX on failure.
toxFriendAdd :: ToxPtr -> BS.ByteString -> BS.ByteString -> IO (Either ErrFriendAdd Word32)
toxFriendAdd :: ToxPtr
-> ByteString -> ByteString -> IO (Either ErrFriendAdd Word32)
toxFriendAdd ToxPtr
tox ByteString
address ByteString
message =
    ByteString
-> (CStringLen -> IO (Either ErrFriendAdd Word32))
-> IO (Either ErrFriendAdd Word32)
forall a. ByteString -> (CStringLen -> IO a) -> IO a
BS.useAsCStringLen ByteString
message ((CStringLen -> IO (Either ErrFriendAdd Word32))
 -> IO (Either ErrFriendAdd Word32))
-> (CStringLen -> IO (Either ErrFriendAdd Word32))
-> IO (Either ErrFriendAdd Word32)
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
msgStr, Int
msgLen) ->
        ByteString
-> (Ptr CChar -> IO (Either ErrFriendAdd Word32))
-> IO (Either ErrFriendAdd Word32)
forall a. ByteString -> (Ptr CChar -> IO a) -> IO a
BS.useAsCString ByteString
address ((Ptr CChar -> IO (Either ErrFriendAdd Word32))
 -> IO (Either ErrFriendAdd Word32))
-> (Ptr CChar -> IO (Either ErrFriendAdd Word32))
-> IO (Either ErrFriendAdd Word32)
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
addr' ->
            (CErr ErrFriendAdd -> IO Word32) -> IO (Either ErrFriendAdd Word32)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrFriendAdd -> IO Word32)
 -> IO (Either ErrFriendAdd Word32))
-> (CErr ErrFriendAdd -> IO Word32)
-> IO (Either ErrFriendAdd Word32)
forall a b. (a -> b) -> a -> b
$ ToxPtr
-> Ptr CChar
-> Ptr CChar
-> CSize
-> CErr ErrFriendAdd
-> IO Word32
tox_friend_add ToxPtr
tox Ptr CChar
addr' Ptr CChar
msgStr (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
msgLen)

-- | Add a friend without sending a friend request.
--
-- This function is used to add a friend in response to a friend request. If the
-- client receives a friend request, it can be reasonably sure that the other
-- client added this client as a friend, eliminating the need for a friend
-- request.
--
-- This function is also useful in a situation where both instances are
-- controlled by the same entity, so that this entity can perform the mutual
-- friend adding. In this case, there is no need for a friend request, either.
--
-- @param public_key A byte array of length 'tox_public_key_size' containing the
--   Public Key (not the Address) of the friend to add.
--
-- @return the friend number on success, UINT32_MAX on failure.
-- @see tox_friend_add for a more detailed description of friend numbers.
toxFriendAddNorequest :: ToxPtr -> BS.ByteString -> IO (Either ErrFriendAdd Word32)
toxFriendAddNorequest :: ToxPtr -> ByteString -> IO (Either ErrFriendAdd Word32)
toxFriendAddNorequest ToxPtr
tox ByteString
address =
    ByteString
-> (Ptr CChar -> IO (Either ErrFriendAdd Word32))
-> IO (Either ErrFriendAdd Word32)
forall a. ByteString -> (Ptr CChar -> IO a) -> IO a
BS.useAsCString ByteString
address ((Ptr CChar -> IO (Either ErrFriendAdd Word32))
 -> IO (Either ErrFriendAdd Word32))
-> (Ptr CChar -> IO (Either ErrFriendAdd Word32))
-> IO (Either ErrFriendAdd Word32)
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
addr' ->
        (CErr ErrFriendAdd -> IO Word32) -> IO (Either ErrFriendAdd Word32)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrFriendAdd -> IO Word32)
 -> IO (Either ErrFriendAdd Word32))
-> (CErr ErrFriendAdd -> IO Word32)
-> IO (Either ErrFriendAdd Word32)
forall a b. (a -> b) -> a -> b
$ ToxPtr -> Ptr CChar -> CErr ErrFriendAdd -> IO Word32
tox_friend_add_norequest ToxPtr
tox Ptr CChar
addr'


-- | Remove a friend from the friend list.
--
-- This does not notify the friend of their deletion. After calling this
-- function, this client will appear offline to the friend and no communication
-- can occur between the two.
--
-- @param friend_number Friend number for the friend to be deleted.
--
-- @return true on success.
toxFriendDelete :: ToxPtr -> Word32 -> IO (Either ErrFriendDelete Bool)
toxFriendDelete :: ToxPtr -> Word32 -> IO (Either ErrFriendDelete Bool)
toxFriendDelete ToxPtr
tox Word32
fn = (CErr ErrFriendDelete -> IO Bool)
-> IO (Either ErrFriendDelete Bool)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrFriendDelete -> IO Bool)
 -> IO (Either ErrFriendDelete Bool))
-> (CErr ErrFriendDelete -> IO Bool)
-> IO (Either ErrFriendDelete Bool)
forall a b. (a -> b) -> a -> b
$ ToxPtr -> Word32 -> CErr ErrFriendDelete -> IO Bool
tox_friend_delete ToxPtr
tox Word32
fn


--------------------------------------------------------------------------------
--
-- :: Friend list queries
--
--------------------------------------------------------------------------------


-- | Return the friend number associated with that Public Key.
--
-- @return the friend number on success, UINT32_MAX on failure.
-- @param public_key A byte array containing the Public Key.
toxFriendByPublicKey :: ToxPtr -> BS.ByteString -> IO (Either ErrFriendByPublicKey Word32)
toxFriendByPublicKey :: ToxPtr -> ByteString -> IO (Either ErrFriendByPublicKey Word32)
toxFriendByPublicKey ToxPtr
tox ByteString
address =
    ByteString
-> (Ptr CChar -> IO (Either ErrFriendByPublicKey Word32))
-> IO (Either ErrFriendByPublicKey Word32)
forall a. ByteString -> (Ptr CChar -> IO a) -> IO a
BS.useAsCString ByteString
address ((Ptr CChar -> IO (Either ErrFriendByPublicKey Word32))
 -> IO (Either ErrFriendByPublicKey Word32))
-> (Ptr CChar -> IO (Either ErrFriendByPublicKey Word32))
-> IO (Either ErrFriendByPublicKey Word32)
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
addr' ->
        (CErr ErrFriendByPublicKey -> IO Word32)
-> IO (Either ErrFriendByPublicKey Word32)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrFriendByPublicKey -> IO Word32)
 -> IO (Either ErrFriendByPublicKey Word32))
-> (CErr ErrFriendByPublicKey -> IO Word32)
-> IO (Either ErrFriendByPublicKey Word32)
forall a b. (a -> b) -> a -> b
$ ToxPtr -> Ptr CChar -> CErr ErrFriendByPublicKey -> IO Word32
tox_friend_by_public_key ToxPtr
tox Ptr CChar
addr'

-- | Checks if a friend with the given friend number exists and returns true if
-- it does.
toxFriendExists :: ToxPtr -> Word32 -> IO Bool
toxFriendExists :: ToxPtr -> Word32 -> IO Bool
toxFriendExists = ToxPtr -> Word32 -> IO Bool
tox_friend_exists

-- | Copy a list of valid friend numbers into an array.
--
-- Call tox_self_get_friend_list_size to determine the number of elements to
-- allocate.
--
-- @param list A memory region with enough space to hold the friend list. If
--   this parameter is 'nullPtr', this function has no effect.
toxSelfGetFriendList :: ToxPtr -> IO [Word32]
toxSelfGetFriendList :: ToxPtr -> IO [Word32]
toxSelfGetFriendList ToxPtr
tox = do
    CSize
friendListSize <- ToxPtr -> IO CSize
tox_self_get_friend_list_size ToxPtr
tox
    Int -> (Ptr Word32 -> IO [Word32]) -> IO [Word32]
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray (CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
friendListSize) ((Ptr Word32 -> IO [Word32]) -> IO [Word32])
-> (Ptr Word32 -> IO [Word32]) -> IO [Word32]
forall a b. (a -> b) -> a -> b
$ \Ptr Word32
friendListPtr -> do
        ToxPtr -> Ptr Word32 -> IO ()
tox_self_get_friend_list ToxPtr
tox Ptr Word32
friendListPtr
        Int -> Ptr Word32 -> IO [Word32]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray (CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
friendListSize) Ptr Word32
friendListPtr


-- | Copies the Public Key associated with a given friend number to a byte
-- array.
--
-- @param friend_number The friend number you want the Public Key of.
-- @param public_key A memory region of at least 'tox_public_key_size' bytes. If
--   this parameter is 'nullPtr', this function has no effect.
--
-- @return true on success.
toxFriendGetPublicKey :: ToxPtr -> Word32 -> IO (Either ErrFriendGetPublicKey BS.ByteString)
toxFriendGetPublicKey :: ToxPtr -> Word32 -> IO (Either ErrFriendGetPublicKey ByteString)
toxFriendGetPublicKey ToxPtr
tox Word32
fn =
    let pkLen :: Int
pkLen = Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
tox_public_key_size in
    Int
-> (Ptr CChar -> IO (Either ErrFriendGetPublicKey ByteString))
-> IO (Either ErrFriendGetPublicKey ByteString)
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
pkLen ((Ptr CChar -> IO (Either ErrFriendGetPublicKey ByteString))
 -> IO (Either ErrFriendGetPublicKey ByteString))
-> (Ptr CChar -> IO (Either ErrFriendGetPublicKey ByteString))
-> IO (Either ErrFriendGetPublicKey ByteString)
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
pkPtr -> do
        Either ErrFriendGetPublicKey Bool
nameRes <- (CErr ErrFriendGetPublicKey -> IO Bool)
-> IO (Either ErrFriendGetPublicKey Bool)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrFriendGetPublicKey -> IO Bool)
 -> IO (Either ErrFriendGetPublicKey Bool))
-> (CErr ErrFriendGetPublicKey -> IO Bool)
-> IO (Either ErrFriendGetPublicKey Bool)
forall a b. (a -> b) -> a -> b
$ ToxPtr
-> Word32 -> Ptr CChar -> CErr ErrFriendGetPublicKey -> IO Bool
tox_friend_get_public_key ToxPtr
tox Word32
fn Ptr CChar
pkPtr
        case Either ErrFriendGetPublicKey Bool
nameRes of
            Left ErrFriendGetPublicKey
err -> Either ErrFriendGetPublicKey ByteString
-> IO (Either ErrFriendGetPublicKey ByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ErrFriendGetPublicKey ByteString
 -> IO (Either ErrFriendGetPublicKey ByteString))
-> Either ErrFriendGetPublicKey ByteString
-> IO (Either ErrFriendGetPublicKey ByteString)
forall a b. (a -> b) -> a -> b
$ ErrFriendGetPublicKey -> Either ErrFriendGetPublicKey ByteString
forall a b. a -> Either a b
Left ErrFriendGetPublicKey
err
            Right Bool
_  -> ByteString -> Either ErrFriendGetPublicKey ByteString
forall a b. b -> Either a b
Right (ByteString -> Either ErrFriendGetPublicKey ByteString)
-> IO ByteString -> IO (Either ErrFriendGetPublicKey ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CStringLen -> IO ByteString
BS.packCStringLen (Ptr CChar
pkPtr, Int
pkLen)


-- | Return a unix-time timestamp of the last time the friend associated with a given
-- friend number was seen online. This function will return UINT64_MAX on error.
--
-- @param friend_number The friend number you want to query.
toxFriendGetLastOnline :: ToxPtr -> Word32 -> IO (Either ErrFriendGetLastOnline EpochTime)
toxFriendGetLastOnline :: ToxPtr -> Word32 -> IO (Either ErrFriendGetLastOnline EpochTime)
toxFriendGetLastOnline ToxPtr
tox Word32
fn =
    (CErr ErrFriendGetLastOnline -> IO EpochTime)
-> IO (Either ErrFriendGetLastOnline EpochTime)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun (ToxPtr -> Word32 -> CErr ErrFriendGetLastOnline -> IO Word64
tox_friend_get_last_online ToxPtr
tox Word32
fn (CErr ErrFriendGetLastOnline -> IO Word64)
-> (Word64 -> IO EpochTime)
-> CErr ErrFriendGetLastOnline
-> IO EpochTime
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (EpochTime -> IO EpochTime
forall (m :: * -> *) a. Monad m => a -> m a
return (EpochTime -> IO EpochTime)
-> (Word64 -> EpochTime) -> Word64 -> IO EpochTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> EpochTime
CTime (Int64 -> EpochTime) -> (Word64 -> Int64) -> Word64 -> EpochTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral))


--------------------------------------------------------------------------------
--
-- :: Friend-specific state queries (can also be received through callbacks)
--
--------------------------------------------------------------------------------


-- | Write the name of the friend designated by the given friend number to a byte
-- array.
--
-- Call tox_friend_get_name_size to determine the allocation size for the `name`
-- parameter.
--
-- The data written to `name` is equal to the data received by the last
-- `friend_name` callback.
--
-- @param name A valid memory region large enough to store the friend's name.
--
-- @return true on success.
toxFriendGetName :: ToxPtr -> Word32 -> IO (Either ErrFriendQuery BS.ByteString)
toxFriendGetName :: ToxPtr -> Word32 -> IO (Either ErrFriendQuery ByteString)
toxFriendGetName ToxPtr
tox Word32
fn = do
    Either ErrFriendQuery CSize
nameLenRes <- (CErr ErrFriendQuery -> IO CSize)
-> IO (Either ErrFriendQuery CSize)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrFriendQuery -> IO CSize)
 -> IO (Either ErrFriendQuery CSize))
-> (CErr ErrFriendQuery -> IO CSize)
-> IO (Either ErrFriendQuery CSize)
forall a b. (a -> b) -> a -> b
$ ToxPtr -> Word32 -> CErr ErrFriendQuery -> IO CSize
tox_friend_get_name_size ToxPtr
tox Word32
fn
    case Either ErrFriendQuery CSize
nameLenRes of
        Left ErrFriendQuery
err -> Either ErrFriendQuery ByteString
-> IO (Either ErrFriendQuery ByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ErrFriendQuery ByteString
 -> IO (Either ErrFriendQuery ByteString))
-> Either ErrFriendQuery ByteString
-> IO (Either ErrFriendQuery ByteString)
forall a b. (a -> b) -> a -> b
$ ErrFriendQuery -> Either ErrFriendQuery ByteString
forall a b. a -> Either a b
Left ErrFriendQuery
err
        Right CSize
nameLen -> Int
-> (Ptr CChar -> IO (Either ErrFriendQuery ByteString))
-> IO (Either ErrFriendQuery ByteString)
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray (CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
nameLen) ((Ptr CChar -> IO (Either ErrFriendQuery ByteString))
 -> IO (Either ErrFriendQuery ByteString))
-> (Ptr CChar -> IO (Either ErrFriendQuery ByteString))
-> IO (Either ErrFriendQuery ByteString)
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
namePtr -> do
            Either ErrFriendQuery Bool
nameRes <- (CErr ErrFriendQuery -> IO Bool) -> IO (Either ErrFriendQuery Bool)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrFriendQuery -> IO Bool)
 -> IO (Either ErrFriendQuery Bool))
-> (CErr ErrFriendQuery -> IO Bool)
-> IO (Either ErrFriendQuery Bool)
forall a b. (a -> b) -> a -> b
$ ToxPtr -> Word32 -> Ptr CChar -> CErr ErrFriendQuery -> IO Bool
tox_friend_get_name ToxPtr
tox Word32
fn Ptr CChar
namePtr
            case Either ErrFriendQuery Bool
nameRes of
                Left ErrFriendQuery
err -> Either ErrFriendQuery ByteString
-> IO (Either ErrFriendQuery ByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ErrFriendQuery ByteString
 -> IO (Either ErrFriendQuery ByteString))
-> Either ErrFriendQuery ByteString
-> IO (Either ErrFriendQuery ByteString)
forall a b. (a -> b) -> a -> b
$ ErrFriendQuery -> Either ErrFriendQuery ByteString
forall a b. a -> Either a b
Left ErrFriendQuery
err
                Right Bool
_ -> ByteString -> Either ErrFriendQuery ByteString
forall a b. b -> Either a b
Right (ByteString -> Either ErrFriendQuery ByteString)
-> IO ByteString -> IO (Either ErrFriendQuery ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CStringLen -> IO ByteString
BS.packCStringLen (Ptr CChar
namePtr, CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
nameLen)


-- | Write the status message of the friend designated by the given friend number to a byte
-- array.
--
-- Call tox_friend_get_status_message_size to determine the allocation size for the `status_name`
-- parameter.
--
-- The data written to `status_message` is equal to the data received by the last
-- `friend_status_message` callback.
--
-- @param status_message A valid memory region large enough to store the friend's status message.
toxFriendGetStatusMessage :: ToxPtr -> Word32 -> IO (Either ErrFriendQuery BS.ByteString)
toxFriendGetStatusMessage :: ToxPtr -> Word32 -> IO (Either ErrFriendQuery ByteString)
toxFriendGetStatusMessage ToxPtr
tox Word32
fn = do
    Either ErrFriendQuery CSize
statusMessageLenRes <- (CErr ErrFriendQuery -> IO CSize)
-> IO (Either ErrFriendQuery CSize)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrFriendQuery -> IO CSize)
 -> IO (Either ErrFriendQuery CSize))
-> (CErr ErrFriendQuery -> IO CSize)
-> IO (Either ErrFriendQuery CSize)
forall a b. (a -> b) -> a -> b
$ ToxPtr -> Word32 -> CErr ErrFriendQuery -> IO CSize
tox_friend_get_status_message_size ToxPtr
tox Word32
fn
    case Either ErrFriendQuery CSize
statusMessageLenRes of
        Left ErrFriendQuery
err -> Either ErrFriendQuery ByteString
-> IO (Either ErrFriendQuery ByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ErrFriendQuery ByteString
 -> IO (Either ErrFriendQuery ByteString))
-> Either ErrFriendQuery ByteString
-> IO (Either ErrFriendQuery ByteString)
forall a b. (a -> b) -> a -> b
$ ErrFriendQuery -> Either ErrFriendQuery ByteString
forall a b. a -> Either a b
Left ErrFriendQuery
err
        Right CSize
statusMessageLen -> Int
-> (Ptr CChar -> IO (Either ErrFriendQuery ByteString))
-> IO (Either ErrFriendQuery ByteString)
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray (CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
statusMessageLen) ((Ptr CChar -> IO (Either ErrFriendQuery ByteString))
 -> IO (Either ErrFriendQuery ByteString))
-> (Ptr CChar -> IO (Either ErrFriendQuery ByteString))
-> IO (Either ErrFriendQuery ByteString)
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
statusMessagePtr -> do
            Either ErrFriendQuery Bool
statusMessageRes <- (CErr ErrFriendQuery -> IO Bool) -> IO (Either ErrFriendQuery Bool)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrFriendQuery -> IO Bool)
 -> IO (Either ErrFriendQuery Bool))
-> (CErr ErrFriendQuery -> IO Bool)
-> IO (Either ErrFriendQuery Bool)
forall a b. (a -> b) -> a -> b
$ ToxPtr -> Word32 -> Ptr CChar -> CErr ErrFriendQuery -> IO Bool
tox_friend_get_status_message ToxPtr
tox Word32
fn Ptr CChar
statusMessagePtr
            case Either ErrFriendQuery Bool
statusMessageRes of
                Left ErrFriendQuery
err -> Either ErrFriendQuery ByteString
-> IO (Either ErrFriendQuery ByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ErrFriendQuery ByteString
 -> IO (Either ErrFriendQuery ByteString))
-> Either ErrFriendQuery ByteString
-> IO (Either ErrFriendQuery ByteString)
forall a b. (a -> b) -> a -> b
$ ErrFriendQuery -> Either ErrFriendQuery ByteString
forall a b. a -> Either a b
Left ErrFriendQuery
err
                Right Bool
_ -> ByteString -> Either ErrFriendQuery ByteString
forall a b. b -> Either a b
Right (ByteString -> Either ErrFriendQuery ByteString)
-> IO ByteString -> IO (Either ErrFriendQuery ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CStringLen -> IO ByteString
BS.packCStringLen (Ptr CChar
statusMessagePtr, CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
statusMessageLen)


-- | Check whether a friend is currently connected to this client.
--
-- The result of this function is equal to the last value received by the
-- `friend_connection_status` callback.
--
-- @param friend_number The friend number for which to query the connection
--   status.
--
-- @return the friend's connection status as it was received through the
--   `friend_connection_status` event.
toxFriendGetConnectionStatus :: ToxPtr -> Word32 -> IO (Either ErrFriendQuery Connection)
toxFriendGetConnectionStatus :: ToxPtr -> Word32 -> IO (Either ErrFriendQuery Connection)
toxFriendGetConnectionStatus ToxPtr
tox Word32
fn =
    (CErr ErrFriendQuery -> IO Connection)
-> IO (Either ErrFriendQuery Connection)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun (ToxPtr -> Word32 -> CErr ErrFriendQuery -> IO (CEnum Connection)
tox_friend_get_connection_status ToxPtr
tox Word32
fn (CErr ErrFriendQuery -> IO (CEnum Connection))
-> (CEnum Connection -> IO Connection)
-> CErr ErrFriendQuery
-> IO Connection
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Connection -> IO Connection
forall (m :: * -> *) a. Monad m => a -> m a
return (Connection -> IO Connection)
-> (CEnum Connection -> Connection)
-> CEnum Connection
-> IO Connection
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CEnum Connection -> Connection
forall a. Enum a => CEnum a -> a
fromCEnum)


-- | Check whether a friend is currently typing a message.
--
-- @param friend_number The friend number for which to query the typing status.
--
-- @return true if the friend is typing.
-- @return false if the friend is not typing, or the friend number was
--   invalid. Inspect the error code to determine which case it is.
toxFriendGetTyping :: ToxPtr -> Word32 -> IO (Either ErrFriendQuery Bool)
toxFriendGetTyping :: ToxPtr -> Word32 -> IO (Either ErrFriendQuery Bool)
toxFriendGetTyping ToxPtr
tox Word32
fn = (CErr ErrFriendQuery -> IO Bool) -> IO (Either ErrFriendQuery Bool)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrFriendQuery -> IO Bool)
 -> IO (Either ErrFriendQuery Bool))
-> (CErr ErrFriendQuery -> IO Bool)
-> IO (Either ErrFriendQuery Bool)
forall a b. (a -> b) -> a -> b
$ ToxPtr -> Word32 -> CErr ErrFriendQuery -> IO Bool
tox_friend_get_typing ToxPtr
tox Word32
fn


--------------------------------------------------------------------------------
--
-- :: Sending private messages
--
--------------------------------------------------------------------------------


-- | Set the client's typing status for a friend.
--
-- The client is responsible for turning it on or off.
--
-- @param friend_number The friend to which the client is typing a message.
-- @param typing The typing status. True means the client is typing.
--
-- @return true on success.
toxSelfSetTyping :: ToxPtr -> Word32 -> Bool -> IO (Either ErrSetTyping Bool)
toxSelfSetTyping :: ToxPtr -> Word32 -> Bool -> IO (Either ErrSetTyping Bool)
toxSelfSetTyping ToxPtr
tox Word32
fn Bool
typing = (CErr ErrSetTyping -> IO Bool) -> IO (Either ErrSetTyping Bool)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrSetTyping -> IO Bool) -> IO (Either ErrSetTyping Bool))
-> (CErr ErrSetTyping -> IO Bool) -> IO (Either ErrSetTyping Bool)
forall a b. (a -> b) -> a -> b
$ ToxPtr -> Word32 -> Bool -> CErr ErrSetTyping -> IO Bool
tox_self_set_typing ToxPtr
tox Word32
fn Bool
typing


-- | Send a text chat message to an online friend.
--
-- This function creates a chat message packet and pushes it into the send
-- queue.
--
-- The message length may not exceed 'tox_max_message_length'. Larger messages
-- must be split by the client and sent as separate messages. Other clients can
-- then reassemble the fragments. Messages may not be empty.
--
-- The return value of this function is the message ID. If a read receipt is
-- received, the triggered `friend_read_receipt` event will be passed this
-- message ID.
--
-- Message IDs are unique per friend. The first message ID is 0. Message IDs are
-- incremented by 1 each time a message is sent. If UINT32_MAX messages were
-- sent, the next message ID is 0.
--
-- @param type Message type (normal, action, ...).
-- @param friend_number The friend number of the friend to send the message to.
-- @param message A non-'nullPtr' pointer to the first element of a byte array
--   containing the message text.
-- @param length Length of the message to be sent.
toxFriendSendMessage :: ToxPtr -> Word32 -> MessageType -> BS.ByteString -> IO (Either ErrFriendSendMessage Word32)
toxFriendSendMessage :: ToxPtr
-> Word32
-> MessageType
-> ByteString
-> IO (Either ErrFriendSendMessage Word32)
toxFriendSendMessage ToxPtr
tox Word32
fn MessageType
messageType ByteString
message =
    ByteString
-> (CStringLen -> IO (Either ErrFriendSendMessage Word32))
-> IO (Either ErrFriendSendMessage Word32)
forall a. ByteString -> (CStringLen -> IO a) -> IO a
BS.useAsCStringLen ByteString
message ((CStringLen -> IO (Either ErrFriendSendMessage Word32))
 -> IO (Either ErrFriendSendMessage Word32))
-> (CStringLen -> IO (Either ErrFriendSendMessage Word32))
-> IO (Either ErrFriendSendMessage Word32)
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
msgStr, Int
msgLen) ->
        (CErr ErrFriendSendMessage -> IO Word32)
-> IO (Either ErrFriendSendMessage Word32)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrFriendSendMessage -> IO Word32)
 -> IO (Either ErrFriendSendMessage Word32))
-> (CErr ErrFriendSendMessage -> IO Word32)
-> IO (Either ErrFriendSendMessage Word32)
forall a b. (a -> b) -> a -> b
$ ToxPtr
-> Word32
-> CEnum MessageType
-> Ptr CChar
-> CSize
-> CErr ErrFriendSendMessage
-> IO Word32
tox_friend_send_message ToxPtr
tox Word32
fn (MessageType -> CEnum MessageType
forall a. Enum a => a -> CEnum a
toCEnum MessageType
messageType) Ptr CChar
msgStr (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
msgLen)


--------------------------------------------------------------------------------
--
-- :: File transmission: common between sending and receiving
--
--------------------------------------------------------------------------------


-- | Generates a cryptographic hash of the given data.
--
-- This function may be used by clients for any purpose, but is provided
-- primarily for validating cached avatars. This use is highly recommended to
-- avoid unnecessary avatar updates.
--
-- If hash is 'nullPtr' or data is 'nullPtr' while length is not 0 the function
-- returns false, otherwise it returns true.
--
-- This function is a wrapper to internal message-digest functions.
--
-- @param hash A valid memory location the hash data. It must be at least
--   'tox_hash_length' bytes in size.
-- @param data Data to be hashed or 'nullPtr'.
-- @param length Size of the data array or 0.
--
-- @return true if hash was not 'nullPtr'.
toxHash :: BS.ByteString -> IO BS.ByteString
toxHash :: ByteString -> IO ByteString
toxHash ByteString
d =
    let hashLen :: Int
hashLen = Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
tox_hash_length in
    Int -> (Ptr CChar -> IO ByteString) -> IO ByteString
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
hashLen ((Ptr CChar -> IO ByteString) -> IO ByteString)
-> (Ptr CChar -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
hashPtr ->
        ByteString -> (CStringLen -> IO ByteString) -> IO ByteString
forall a. ByteString -> (CStringLen -> IO a) -> IO a
BS.useAsCStringLen ByteString
d ((CStringLen -> IO ByteString) -> IO ByteString)
-> (CStringLen -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
dataPtr, Int
dataLen) -> do
            Bool
_ <- Ptr CChar -> Ptr CChar -> CSize -> IO Bool
tox_hash Ptr CChar
hashPtr Ptr CChar
dataPtr (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
dataLen)
            CStringLen -> IO ByteString
BS.packCStringLen (Ptr CChar
dataPtr, Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
dataLen)


-- | Sends a file control command to a friend for a given file transfer.
--
-- @param friend_number The friend number of the friend the file is being
--   transferred to or received from.
-- @param file_number The friend-specific identifier for the file transfer.
-- @param control The control command to send.
--
-- @return true on success.
toxFileControl :: ToxPtr -> Word32 -> Word32 -> FileControl -> IO (Either ErrFileControl Bool)
toxFileControl :: ToxPtr
-> Word32
-> Word32
-> FileControl
-> IO (Either ErrFileControl Bool)
toxFileControl ToxPtr
tox Word32
fn Word32
fileNum FileControl
control = (CErr ErrFileControl -> IO Bool) -> IO (Either ErrFileControl Bool)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrFileControl -> IO Bool)
 -> IO (Either ErrFileControl Bool))
-> (CErr ErrFileControl -> IO Bool)
-> IO (Either ErrFileControl Bool)
forall a b. (a -> b) -> a -> b
$ ToxPtr
-> Word32
-> Word32
-> CEnum FileControl
-> CErr ErrFileControl
-> IO Bool
tox_file_control ToxPtr
tox Word32
fn Word32
fileNum (FileControl -> CEnum FileControl
forall a. Enum a => a -> CEnum a
toCEnum FileControl
control)


-- | Sends a file seek control command to a friend for a given file transfer.
--
-- This function can only be called to resume a file transfer right before
-- FileControlResume is sent.
--
-- @param friend_number The friend number of the friend the file is being
--   received from.
-- @param file_number The friend-specific identifier for the file transfer.
-- @param position The position that the file should be seeked to.
toxFileSeek :: ToxPtr -> Word32 -> Word32 -> Word64 -> IO (Either ErrFileSeek Bool)
toxFileSeek :: ToxPtr
-> Word32 -> Word32 -> Word64 -> IO (Either ErrFileSeek Bool)
toxFileSeek ToxPtr
tox Word32
fn Word32
fileNum Word64
pos = (CErr ErrFileSeek -> IO Bool) -> IO (Either ErrFileSeek Bool)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrFileSeek -> IO Bool) -> IO (Either ErrFileSeek Bool))
-> (CErr ErrFileSeek -> IO Bool) -> IO (Either ErrFileSeek Bool)
forall a b. (a -> b) -> a -> b
$ ToxPtr -> Word32 -> Word32 -> Word64 -> CErr ErrFileSeek -> IO Bool
tox_file_seek ToxPtr
tox Word32
fn Word32
fileNum Word64
pos


-- | Copy the file id associated to the file transfer to a byte array.
--
-- @param friend_number The friend number of the friend the file is being
--   transferred to or received from.
-- @param file_number The friend-specific identifier for the file transfer.
-- @param file_id A memory region of at least 'tox_file_id_length' bytes. If
--   this parameter is 'nullPtr', this function has no effect.
--
-- @return true on success.
toxFileGetFileId :: ToxPtr -> Word32 -> Word32 -> IO (Either ErrFileGet BS.ByteString)
toxFileGetFileId :: ToxPtr -> Word32 -> Word32 -> IO (Either ErrFileGet ByteString)
toxFileGetFileId ToxPtr
tox Word32
fn Word32
fileNum =
    let fileIdLen :: Int
fileIdLen = Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
tox_file_id_length in
    Int
-> (Ptr CChar -> IO (Either ErrFileGet ByteString))
-> IO (Either ErrFileGet ByteString)
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
fileIdLen ((Ptr CChar -> IO (Either ErrFileGet ByteString))
 -> IO (Either ErrFileGet ByteString))
-> (Ptr CChar -> IO (Either ErrFileGet ByteString))
-> IO (Either ErrFileGet ByteString)
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
fileIdPtr -> do
        Either ErrFileGet Bool
idRes <- (CErr ErrFileGet -> IO Bool) -> IO (Either ErrFileGet Bool)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrFileGet -> IO Bool) -> IO (Either ErrFileGet Bool))
-> (CErr ErrFileGet -> IO Bool) -> IO (Either ErrFileGet Bool)
forall a b. (a -> b) -> a -> b
$ ToxPtr
-> Word32 -> Word32 -> Ptr CChar -> CErr ErrFileGet -> IO Bool
tox_file_get_file_id ToxPtr
tox Word32
fn Word32
fileNum Ptr CChar
fileIdPtr
        case Either ErrFileGet Bool
idRes of
            Left ErrFileGet
err -> Either ErrFileGet ByteString -> IO (Either ErrFileGet ByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ErrFileGet ByteString -> IO (Either ErrFileGet ByteString))
-> Either ErrFileGet ByteString
-> IO (Either ErrFileGet ByteString)
forall a b. (a -> b) -> a -> b
$ ErrFileGet -> Either ErrFileGet ByteString
forall a b. a -> Either a b
Left ErrFileGet
err
            Right Bool
_  -> ByteString -> Either ErrFileGet ByteString
forall a b. b -> Either a b
Right (ByteString -> Either ErrFileGet ByteString)
-> IO ByteString -> IO (Either ErrFileGet ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CStringLen -> IO ByteString
BS.packCStringLen (Ptr CChar
fileIdPtr, Int
fileIdLen)


--------------------------------------------------------------------------------
--
-- :: File transmission: sending
--
--------------------------------------------------------------------------------


-- | Send a file transmission request.
--
-- Maximum filename length is 'tox_max_filename_length' bytes. The filename
-- should generally just be a file name, not a path with directory names.
--
-- If a non-UINT64_MAX file size is provided, it can be used by both sides to
-- determine the sending progress. File size can be set to UINT64_MAX for
-- streaming data of unknown size.
--
-- File transmission occurs in chunks, which are requested through the
-- `file_chunk_request` event.
--
-- When a friend goes offline, all file transfers associated with the friend are
-- purged from core.
--
-- If the file contents change during a transfer, the behaviour is unspecified
-- in general. What will actually happen depends on the mode in which the file
-- was modified and how the client determines the file size.
--
-- - If the file size was increased
--   - and sending mode was streaming (file_size = UINT64_MAX), the behaviour
--     will be as expected.
--   - and sending mode was file (file_size != UINT64_MAX), the
--     file_chunk_request callback will receive length = 0 when Core thinks
--     the file transfer has finished. If the client remembers the file size as
--     it was when sending the request, it will terminate the transfer normally.
--     If the client re-reads the size, it will think the friend cancelled the
--     transfer.
-- - If the file size was decreased
--   - and sending mode was streaming, the behaviour is as expected.
--   - and sending mode was file, the callback will return 0 at the new
--     (earlier) end-of-file, signalling to the friend that the transfer was
--     cancelled.
-- - If the file contents were modified
--   - at a position before the current read, the two files (local and remote)
--     will differ after the transfer terminates.
--   - at a position after the current read, the file transfer will succeed as
--     expected.
--   - In either case, both sides will regard the transfer as complete and
--     successful.
--
-- @param friend_number The friend number of the friend the file send request
--   should be sent to.
-- @param kind The meaning of the file to be sent.
-- @param file_size Size in bytes of the file the client wants to send,
--   UINT64_MAX if unknown or streaming.
-- @param file_id A file identifier of length 'tox_file_id_length' that can be
--   used to uniquely identify file transfers across core restarts. If
--   'nullPtr', a random one will be generated by core. It can then be obtained
--   by using tox_file_get_file_id().
-- @param filename Name of the file. Does not need to be the actual name. This
--   name will be sent along with the file send request.
-- @param filename_length Size in bytes of the filename.
--
-- @return A file number used as an identifier in subsequent callbacks. This
--   number is per friend. File numbers are reused after a transfer terminates.
--   On failure, this function returns UINT32_MAX. Any pattern in file numbers
--   should not be relied on.
toxFileSend :: ToxPtr -> Word32 -> FileKind -> Word64 -> BS.ByteString -> IO (Either ErrFileSend Word32)
toxFileSend :: ToxPtr
-> Word32
-> FileKind
-> Word64
-> ByteString
-> IO (Either ErrFileSend Word32)
toxFileSend ToxPtr
tox Word32
fn FileKind
fileKind Word64
fileSize ByteString
fileName =
    ByteString
-> (CStringLen -> IO (Either ErrFileSend Word32))
-> IO (Either ErrFileSend Word32)
forall a. ByteString -> (CStringLen -> IO a) -> IO a
BS.useAsCStringLen ByteString
fileName ((CStringLen -> IO (Either ErrFileSend Word32))
 -> IO (Either ErrFileSend Word32))
-> (CStringLen -> IO (Either ErrFileSend Word32))
-> IO (Either ErrFileSend Word32)
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
fileNamePtr, Int
fileNameLen) ->
        (CErr ErrFileSend -> IO Word32) -> IO (Either ErrFileSend Word32)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrFileSend -> IO Word32) -> IO (Either ErrFileSend Word32))
-> (CErr ErrFileSend -> IO Word32)
-> IO (Either ErrFileSend Word32)
forall a b. (a -> b) -> a -> b
$ ToxPtr
-> Word32
-> Word32
-> Word64
-> Ptr CChar
-> Ptr CChar
-> CSize
-> CErr ErrFileSend
-> IO Word32
tox_file_send ToxPtr
tox Word32
fn (Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word32) -> Int -> Word32
forall a b. (a -> b) -> a -> b
$ FileKind -> Int
forall a. Enum a => a -> Int
fromEnum FileKind
fileKind) Word64
fileSize Ptr CChar
forall a. Ptr a
nullPtr Ptr CChar
fileNamePtr (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
fileNameLen)


-- | Send a chunk of file data to a friend.
--
-- This function is called in response to the `file_chunk_request` callback.
-- The length parameter should be equal to the one received though the
-- callback.  If it is zero, the transfer is assumed complete. For files with
-- known size, Core will know that the transfer is complete after the last byte
-- has been received, so it is not necessary (though not harmful) to send a
-- zero-length chunk to terminate. For streams, core will know that the
-- transfer is finished if a chunk with length less than the length requested
-- in the callback is sent.
--
-- @param friend_number The friend number of the receiving friend for this file.
-- @param file_number The file transfer identifier returned by tox_file_send.
-- @param position The file or stream position from which to continue reading.
-- @return true on success.
toxFileSendChunk :: ToxPtr -> Word32 -> Word32 -> Word64 -> BS.ByteString -> IO (Either ErrFileSendChunk Bool)
toxFileSendChunk :: ToxPtr
-> Word32
-> Word32
-> Word64
-> ByteString
-> IO (Either ErrFileSendChunk Bool)
toxFileSendChunk ToxPtr
tox Word32
fn Word32
fileNum Word64
pos ByteString
d =
    ByteString
-> (CStringLen -> IO (Either ErrFileSendChunk Bool))
-> IO (Either ErrFileSendChunk Bool)
forall a. ByteString -> (CStringLen -> IO a) -> IO a
BS.useAsCStringLen ByteString
d ((CStringLen -> IO (Either ErrFileSendChunk Bool))
 -> IO (Either ErrFileSendChunk Bool))
-> (CStringLen -> IO (Either ErrFileSendChunk Bool))
-> IO (Either ErrFileSendChunk Bool)
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
dataPtr, Int
dataLen) ->
        (CErr ErrFileSendChunk -> IO Bool)
-> IO (Either ErrFileSendChunk Bool)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrFileSendChunk -> IO Bool)
 -> IO (Either ErrFileSendChunk Bool))
-> (CErr ErrFileSendChunk -> IO Bool)
-> IO (Either ErrFileSendChunk Bool)
forall a b. (a -> b) -> a -> b
$ ToxPtr
-> Word32
-> Word32
-> Word64
-> Ptr CChar
-> CSize
-> CErr ErrFileSendChunk
-> IO Bool
tox_file_send_chunk ToxPtr
tox Word32
fn Word32
fileNum Word64
pos Ptr CChar
dataPtr (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
dataLen)


--------------------------------------------------------------------------------
--
-- :: Conference management
--
--------------------------------------------------------------------------------


-- | Creates a new conference.
--
-- This function creates a new text conference.
--
-- @return conference number on success, or UINT32_MAX on failure.
toxConferenceNew :: ToxPtr -> IO (Either ErrConferenceNew Word32)
toxConferenceNew :: ToxPtr -> IO (Either ErrConferenceNew Word32)
toxConferenceNew ToxPtr
tox = (CErr ErrConferenceNew -> IO Word32)
-> IO (Either ErrConferenceNew Word32)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrConferenceNew -> IO Word32)
 -> IO (Either ErrConferenceNew Word32))
-> (CErr ErrConferenceNew -> IO Word32)
-> IO (Either ErrConferenceNew Word32)
forall a b. (a -> b) -> a -> b
$ ToxPtr -> CErr ErrConferenceNew -> IO Word32
tox_conference_new ToxPtr
tox


-- | This function deletes a conference.
--
-- @param conference_number The conference number of the conference to be deleted.
--
-- @return true on success.
toxConferenceDelete :: ToxPtr -> Word32 -> IO (Either ErrConferenceDelete Bool)
toxConferenceDelete :: ToxPtr -> Word32 -> IO (Either ErrConferenceDelete Bool)
toxConferenceDelete ToxPtr
tox Word32
gn = (CErr ErrConferenceDelete -> IO Bool)
-> IO (Either ErrConferenceDelete Bool)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrConferenceDelete -> IO Bool)
 -> IO (Either ErrConferenceDelete Bool))
-> (CErr ErrConferenceDelete -> IO Bool)
-> IO (Either ErrConferenceDelete Bool)
forall a b. (a -> b) -> a -> b
$ ToxPtr -> Word32 -> CErr ErrConferenceDelete -> IO Bool
tox_conference_delete ToxPtr
tox Word32
gn


-- | Return the number of peers in the conference. Return value is unspecified on failure.
toxConferencePeerCount :: ToxPtr -> Word32 -> IO (Either ErrConferencePeerQuery Word32)
toxConferencePeerCount :: ToxPtr -> Word32 -> IO (Either ErrConferencePeerQuery Word32)
toxConferencePeerCount ToxPtr
tox Word32
gn = (CErr ErrConferencePeerQuery -> IO Word32)
-> IO (Either ErrConferencePeerQuery Word32)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrConferencePeerQuery -> IO Word32)
 -> IO (Either ErrConferencePeerQuery Word32))
-> (CErr ErrConferencePeerQuery -> IO Word32)
-> IO (Either ErrConferencePeerQuery Word32)
forall a b. (a -> b) -> a -> b
$ ToxPtr -> Word32 -> CErr ErrConferencePeerQuery -> IO Word32
tox_conference_peer_count ToxPtr
tox Word32
gn


-- | Copy the name of peer_number who is in conference_number to name.
-- name must be at least TOX_MAX_NAME_LENGTH long.
--
-- @return true on success.
toxConferencePeerGetName :: ToxPtr -> Word32 -> Word32 -> IO (Either ErrConferencePeerQuery BS.ByteString)
toxConferencePeerGetName :: ToxPtr
-> Word32
-> Word32
-> IO (Either ErrConferencePeerQuery ByteString)
toxConferencePeerGetName ToxPtr
tox Word32
gn Word32
pn = do
    Either ErrConferencePeerQuery CSize
nameLenRes <- (CErr ErrConferencePeerQuery -> IO CSize)
-> IO (Either ErrConferencePeerQuery CSize)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrConferencePeerQuery -> IO CSize)
 -> IO (Either ErrConferencePeerQuery CSize))
-> (CErr ErrConferencePeerQuery -> IO CSize)
-> IO (Either ErrConferencePeerQuery CSize)
forall a b. (a -> b) -> a -> b
$ ToxPtr
-> Word32 -> Word32 -> CErr ErrConferencePeerQuery -> IO CSize
tox_conference_peer_get_name_size ToxPtr
tox Word32
gn Word32
pn
    case Either ErrConferencePeerQuery CSize
nameLenRes of
        Left ErrConferencePeerQuery
err -> Either ErrConferencePeerQuery ByteString
-> IO (Either ErrConferencePeerQuery ByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ErrConferencePeerQuery ByteString
 -> IO (Either ErrConferencePeerQuery ByteString))
-> Either ErrConferencePeerQuery ByteString
-> IO (Either ErrConferencePeerQuery ByteString)
forall a b. (a -> b) -> a -> b
$ ErrConferencePeerQuery -> Either ErrConferencePeerQuery ByteString
forall a b. a -> Either a b
Left ErrConferencePeerQuery
err
        Right CSize
nameLen -> Int
-> (Ptr CChar -> IO (Either ErrConferencePeerQuery ByteString))
-> IO (Either ErrConferencePeerQuery ByteString)
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray (CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
nameLen) ((Ptr CChar -> IO (Either ErrConferencePeerQuery ByteString))
 -> IO (Either ErrConferencePeerQuery ByteString))
-> (Ptr CChar -> IO (Either ErrConferencePeerQuery ByteString))
-> IO (Either ErrConferencePeerQuery ByteString)
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
namePtr -> do
            Either ErrConferencePeerQuery Bool
nameRes <- (CErr ErrConferencePeerQuery -> IO Bool)
-> IO (Either ErrConferencePeerQuery Bool)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrConferencePeerQuery -> IO Bool)
 -> IO (Either ErrConferencePeerQuery Bool))
-> (CErr ErrConferencePeerQuery -> IO Bool)
-> IO (Either ErrConferencePeerQuery Bool)
forall a b. (a -> b) -> a -> b
$ ToxPtr
-> Word32
-> Word32
-> Ptr CChar
-> CErr ErrConferencePeerQuery
-> IO Bool
tox_conference_peer_get_name ToxPtr
tox Word32
gn Word32
pn Ptr CChar
namePtr
            case Either ErrConferencePeerQuery Bool
nameRes of
                Left ErrConferencePeerQuery
err -> Either ErrConferencePeerQuery ByteString
-> IO (Either ErrConferencePeerQuery ByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ErrConferencePeerQuery ByteString
 -> IO (Either ErrConferencePeerQuery ByteString))
-> Either ErrConferencePeerQuery ByteString
-> IO (Either ErrConferencePeerQuery ByteString)
forall a b. (a -> b) -> a -> b
$ ErrConferencePeerQuery -> Either ErrConferencePeerQuery ByteString
forall a b. a -> Either a b
Left ErrConferencePeerQuery
err
                Right Bool
_ -> ByteString -> Either ErrConferencePeerQuery ByteString
forall a b. b -> Either a b
Right (ByteString -> Either ErrConferencePeerQuery ByteString)
-> IO ByteString -> IO (Either ErrConferencePeerQuery ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CStringLen -> IO ByteString
BS.packCStringLen (Ptr CChar
namePtr, CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
nameLen)


-- | Copy the public key of peer_number who is in conference_number to public_key.
-- public_key must be TOX_PUBLIC_KEY_SIZE long.
--
-- @return true on success.
toxConferencePeerGetPublicKey :: ToxPtr -> Word32 -> Word32 -> IO (Either ErrConferencePeerQuery BS.ByteString)
toxConferencePeerGetPublicKey :: ToxPtr
-> Word32
-> Word32
-> IO (Either ErrConferencePeerQuery ByteString)
toxConferencePeerGetPublicKey ToxPtr
tox Word32
gn Word32
pn =
    let pkLen :: Int
pkLen = Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
tox_public_key_size in
    Int
-> (Ptr CChar -> IO (Either ErrConferencePeerQuery ByteString))
-> IO (Either ErrConferencePeerQuery ByteString)
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
pkLen ((Ptr CChar -> IO (Either ErrConferencePeerQuery ByteString))
 -> IO (Either ErrConferencePeerQuery ByteString))
-> (Ptr CChar -> IO (Either ErrConferencePeerQuery ByteString))
-> IO (Either ErrConferencePeerQuery ByteString)
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
pkPtr -> do
        Either ErrConferencePeerQuery Bool
nameRes <- (CErr ErrConferencePeerQuery -> IO Bool)
-> IO (Either ErrConferencePeerQuery Bool)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrConferencePeerQuery -> IO Bool)
 -> IO (Either ErrConferencePeerQuery Bool))
-> (CErr ErrConferencePeerQuery -> IO Bool)
-> IO (Either ErrConferencePeerQuery Bool)
forall a b. (a -> b) -> a -> b
$ ToxPtr
-> Word32
-> Word32
-> Ptr CChar
-> CErr ErrConferencePeerQuery
-> IO Bool
tox_conference_peer_get_public_key ToxPtr
tox Word32
gn Word32
pn Ptr CChar
pkPtr
        case Either ErrConferencePeerQuery Bool
nameRes of
            Left ErrConferencePeerQuery
err -> Either ErrConferencePeerQuery ByteString
-> IO (Either ErrConferencePeerQuery ByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ErrConferencePeerQuery ByteString
 -> IO (Either ErrConferencePeerQuery ByteString))
-> Either ErrConferencePeerQuery ByteString
-> IO (Either ErrConferencePeerQuery ByteString)
forall a b. (a -> b) -> a -> b
$ ErrConferencePeerQuery -> Either ErrConferencePeerQuery ByteString
forall a b. a -> Either a b
Left ErrConferencePeerQuery
err
            Right Bool
_  -> ByteString -> Either ErrConferencePeerQuery ByteString
forall a b. b -> Either a b
Right (ByteString -> Either ErrConferencePeerQuery ByteString)
-> IO ByteString -> IO (Either ErrConferencePeerQuery ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CStringLen -> IO ByteString
BS.packCStringLen (Ptr CChar
pkPtr, Int
pkLen)


-- | Return true if passed peer_number corresponds to our own.
toxConferencePeerNumberIsOurs :: ToxPtr -> Word32 -> Word32 -> IO (Either ErrConferencePeerQuery Bool)
toxConferencePeerNumberIsOurs :: ToxPtr
-> Word32 -> Word32 -> IO (Either ErrConferencePeerQuery Bool)
toxConferencePeerNumberIsOurs ToxPtr
tox Word32
gn Word32
pn = (CErr ErrConferencePeerQuery -> IO Bool)
-> IO (Either ErrConferencePeerQuery Bool)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrConferencePeerQuery -> IO Bool)
 -> IO (Either ErrConferencePeerQuery Bool))
-> (CErr ErrConferencePeerQuery -> IO Bool)
-> IO (Either ErrConferencePeerQuery Bool)
forall a b. (a -> b) -> a -> b
$ ToxPtr
-> Word32 -> Word32 -> CErr ErrConferencePeerQuery -> IO Bool
tox_conference_peer_number_is_ours ToxPtr
tox Word32
gn Word32
pn


-- | Invites a friend to a conference.
--
-- @param friend_number The friend number of the friend we want to invite.
-- @param conference_number The conference number of the conference we want to invite the friend to.
--
-- @return true on success.
toxConferenceInvite :: ToxPtr -> Word32 -> Word32 -> IO (Either ErrConferenceInvite Bool)
toxConferenceInvite :: ToxPtr -> Word32 -> Word32 -> IO (Either ErrConferenceInvite Bool)
toxConferenceInvite ToxPtr
tox Word32
fn Word32
gn = (CErr ErrConferenceInvite -> IO Bool)
-> IO (Either ErrConferenceInvite Bool)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrConferenceInvite -> IO Bool)
 -> IO (Either ErrConferenceInvite Bool))
-> (CErr ErrConferenceInvite -> IO Bool)
-> IO (Either ErrConferenceInvite Bool)
forall a b. (a -> b) -> a -> b
$ ToxPtr -> Word32 -> Word32 -> CErr ErrConferenceInvite -> IO Bool
tox_conference_invite ToxPtr
tox Word32
fn Word32
gn


-- | Joins a conference that the client has been invited to.
--
-- @param friend_number The friend number of the friend who sent the invite.
-- @param cookie Received via the `conference_invite` event.
-- @param length The size of cookie.
--
-- @return conference number on success, UINT32_MAX on failure.
toxConferenceJoin :: ToxPtr -> Word32 -> BS.ByteString -> IO (Either ErrConferenceJoin Word32)
toxConferenceJoin :: ToxPtr
-> Word32 -> ByteString -> IO (Either ErrConferenceJoin Word32)
toxConferenceJoin ToxPtr
tox Word32
fn ByteString
cookie =
    ByteString
-> (CStringLen -> IO (Either ErrConferenceJoin Word32))
-> IO (Either ErrConferenceJoin Word32)
forall a. ByteString -> (CStringLen -> IO a) -> IO a
BS.useAsCStringLen ByteString
cookie ((CStringLen -> IO (Either ErrConferenceJoin Word32))
 -> IO (Either ErrConferenceJoin Word32))
-> (CStringLen -> IO (Either ErrConferenceJoin Word32))
-> IO (Either ErrConferenceJoin Word32)
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
cookiePtr, Int
cookieLen) ->
        (CErr ErrConferenceJoin -> IO Word32)
-> IO (Either ErrConferenceJoin Word32)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrConferenceJoin -> IO Word32)
 -> IO (Either ErrConferenceJoin Word32))
-> (CErr ErrConferenceJoin -> IO Word32)
-> IO (Either ErrConferenceJoin Word32)
forall a b. (a -> b) -> a -> b
$ ToxPtr
-> Word32
-> Ptr CChar
-> CSize
-> CErr ErrConferenceJoin
-> IO Word32
tox_conference_join ToxPtr
tox Word32
fn Ptr CChar
cookiePtr (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
cookieLen)


-- | Send a text chat message to the conference.
--
-- This function creates a conference message packet and pushes it into the send
-- queue.
--
-- The message length may not exceed TOX_MAX_MESSAGE_LENGTH. Larger messages
-- must be split by the client and sent as separate messages. Other clients can
-- then reassemble the fragments.
--
-- @param conference_number The conference number of the conference the message is intended for.
-- @param type Message type (normal, action, ...).
-- @param message A non-NULL pointer to the first element of a byte array
--   containing the message text.
-- @param length Length of the message to be sent.
--
-- @return true on success.
toxConferenceSendMessage :: ToxPtr -> Word32 -> MessageType -> BS.ByteString -> IO (Either ErrConferenceSendMessage Bool)
toxConferenceSendMessage :: ToxPtr
-> Word32
-> MessageType
-> ByteString
-> IO (Either ErrConferenceSendMessage Bool)
toxConferenceSendMessage ToxPtr
tox Word32
gn MessageType
messageType ByteString
message =
    ByteString
-> (CStringLen -> IO (Either ErrConferenceSendMessage Bool))
-> IO (Either ErrConferenceSendMessage Bool)
forall a. ByteString -> (CStringLen -> IO a) -> IO a
BS.useAsCStringLen ByteString
message ((CStringLen -> IO (Either ErrConferenceSendMessage Bool))
 -> IO (Either ErrConferenceSendMessage Bool))
-> (CStringLen -> IO (Either ErrConferenceSendMessage Bool))
-> IO (Either ErrConferenceSendMessage Bool)
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
msgPtr, Int
msgLen) ->
        (CErr ErrConferenceSendMessage -> IO Bool)
-> IO (Either ErrConferenceSendMessage Bool)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrConferenceSendMessage -> IO Bool)
 -> IO (Either ErrConferenceSendMessage Bool))
-> (CErr ErrConferenceSendMessage -> IO Bool)
-> IO (Either ErrConferenceSendMessage Bool)
forall a b. (a -> b) -> a -> b
$ ToxPtr
-> Word32
-> CEnum MessageType
-> Ptr CChar
-> CSize
-> CErr ErrConferenceSendMessage
-> IO Bool
tox_conference_send_message ToxPtr
tox Word32
gn (MessageType -> CEnum MessageType
forall a. Enum a => a -> CEnum a
toCEnum MessageType
messageType) Ptr CChar
msgPtr (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
msgLen)


-- | Write the title designated by the given conference number to a byte array.
--
-- Call tox_conference_get_title_size to determine the allocation size for the `title` parameter.
--
-- The data written to `title` is equal to the data received by the last
-- `conference_title` callback.
--
-- @param title A valid memory region large enough to store the title.
--   If this parameter is NULL, this function has no effect.
--
-- @return true on success.
toxConferenceGetTitle :: ToxPtr -> Word32 -> IO (Either ErrConferenceTitle BS.ByteString)
toxConferenceGetTitle :: ToxPtr -> Word32 -> IO (Either ErrConferenceTitle ByteString)
toxConferenceGetTitle ToxPtr
tox Word32
gn = do
    Either ErrConferenceTitle CSize
titleLenRes <- (CErr ErrConferenceTitle -> IO CSize)
-> IO (Either ErrConferenceTitle CSize)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrConferenceTitle -> IO CSize)
 -> IO (Either ErrConferenceTitle CSize))
-> (CErr ErrConferenceTitle -> IO CSize)
-> IO (Either ErrConferenceTitle CSize)
forall a b. (a -> b) -> a -> b
$ ToxPtr -> Word32 -> CErr ErrConferenceTitle -> IO CSize
tox_conference_get_title_size ToxPtr
tox Word32
gn
    case Either ErrConferenceTitle CSize
titleLenRes of
        Left ErrConferenceTitle
err -> Either ErrConferenceTitle ByteString
-> IO (Either ErrConferenceTitle ByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ErrConferenceTitle ByteString
 -> IO (Either ErrConferenceTitle ByteString))
-> Either ErrConferenceTitle ByteString
-> IO (Either ErrConferenceTitle ByteString)
forall a b. (a -> b) -> a -> b
$ ErrConferenceTitle -> Either ErrConferenceTitle ByteString
forall a b. a -> Either a b
Left ErrConferenceTitle
err
        Right CSize
titleLen -> Int
-> (Ptr CChar -> IO (Either ErrConferenceTitle ByteString))
-> IO (Either ErrConferenceTitle ByteString)
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray (CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
titleLen) ((Ptr CChar -> IO (Either ErrConferenceTitle ByteString))
 -> IO (Either ErrConferenceTitle ByteString))
-> (Ptr CChar -> IO (Either ErrConferenceTitle ByteString))
-> IO (Either ErrConferenceTitle ByteString)
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
titlePtr -> do
            Either ErrConferenceTitle Bool
titleRes <- (CErr ErrConferenceTitle -> IO Bool)
-> IO (Either ErrConferenceTitle Bool)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrConferenceTitle -> IO Bool)
 -> IO (Either ErrConferenceTitle Bool))
-> (CErr ErrConferenceTitle -> IO Bool)
-> IO (Either ErrConferenceTitle Bool)
forall a b. (a -> b) -> a -> b
$ ToxPtr -> Word32 -> Ptr CChar -> CErr ErrConferenceTitle -> IO Bool
tox_conference_get_title ToxPtr
tox Word32
gn Ptr CChar
titlePtr
            case Either ErrConferenceTitle Bool
titleRes of
                Left ErrConferenceTitle
err -> Either ErrConferenceTitle ByteString
-> IO (Either ErrConferenceTitle ByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ErrConferenceTitle ByteString
 -> IO (Either ErrConferenceTitle ByteString))
-> Either ErrConferenceTitle ByteString
-> IO (Either ErrConferenceTitle ByteString)
forall a b. (a -> b) -> a -> b
$ ErrConferenceTitle -> Either ErrConferenceTitle ByteString
forall a b. a -> Either a b
Left ErrConferenceTitle
err
                Right Bool
_ -> ByteString -> Either ErrConferenceTitle ByteString
forall a b. b -> Either a b
Right (ByteString -> Either ErrConferenceTitle ByteString)
-> IO ByteString -> IO (Either ErrConferenceTitle ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CStringLen -> IO ByteString
BS.packCStringLen (Ptr CChar
titlePtr, CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
titleLen)

-- | Set the conference title and broadcast it to the rest of the conference.
--
-- Title length cannot be longer than TOX_MAX_NAME_LENGTH.
--
-- @return true on success.
toxConferenceSetTitle :: ToxPtr -> Word32 -> BS.ByteString -> IO (Either ErrConferenceTitle Bool)
toxConferenceSetTitle :: ToxPtr
-> Word32 -> ByteString -> IO (Either ErrConferenceTitle Bool)
toxConferenceSetTitle ToxPtr
tox Word32
gn ByteString
title =
    ByteString
-> (CStringLen -> IO (Either ErrConferenceTitle Bool))
-> IO (Either ErrConferenceTitle Bool)
forall a. ByteString -> (CStringLen -> IO a) -> IO a
BS.useAsCStringLen ByteString
title ((CStringLen -> IO (Either ErrConferenceTitle Bool))
 -> IO (Either ErrConferenceTitle Bool))
-> (CStringLen -> IO (Either ErrConferenceTitle Bool))
-> IO (Either ErrConferenceTitle Bool)
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
titlePtr, Int
titleLen) ->
        (CErr ErrConferenceTitle -> IO Bool)
-> IO (Either ErrConferenceTitle Bool)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrConferenceTitle -> IO Bool)
 -> IO (Either ErrConferenceTitle Bool))
-> (CErr ErrConferenceTitle -> IO Bool)
-> IO (Either ErrConferenceTitle Bool)
forall a b. (a -> b) -> a -> b
$ ToxPtr
-> Word32
-> Ptr CChar
-> CSize
-> CErr ErrConferenceTitle
-> IO Bool
tox_conference_set_title ToxPtr
tox Word32
gn Ptr CChar
titlePtr (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
titleLen)


-- | Copy a list of valid conference IDs into the array chatlist. Determine how much space
-- to allocate for the array with the `tox_conference_get_chatlist_size` function.
toxConferenceGetChatlist :: ToxPtr -> IO [Word32]
toxConferenceGetChatlist :: ToxPtr -> IO [Word32]
toxConferenceGetChatlist ToxPtr
tox = do
    CSize
chatListSize <- ToxPtr -> IO CSize
tox_conference_get_chatlist_size ToxPtr
tox
    Int -> (Ptr Word32 -> IO [Word32]) -> IO [Word32]
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray (CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
chatListSize) ((Ptr Word32 -> IO [Word32]) -> IO [Word32])
-> (Ptr Word32 -> IO [Word32]) -> IO [Word32]
forall a b. (a -> b) -> a -> b
$ \Ptr Word32
chatListPtr -> do
        ToxPtr -> Ptr Word32 -> IO ()
tox_conference_get_chatlist ToxPtr
tox Ptr Word32
chatListPtr
        Int -> Ptr Word32 -> IO [Word32]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray (CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
chatListSize) Ptr Word32
chatListPtr

toxConferenceGetType :: ToxPtr -> Word32 -> IO (Either ErrConferenceGetType ConferenceType)
toxConferenceGetType :: ToxPtr -> Word32 -> IO (Either ErrConferenceGetType ConferenceType)
toxConferenceGetType ToxPtr
tox Word32
gn = (CErr ErrConferenceGetType -> IO ConferenceType)
-> IO (Either ErrConferenceGetType ConferenceType)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun (ToxPtr
-> Word32 -> CErr ErrConferenceGetType -> IO (CEnum ConferenceType)
tox_conference_get_type ToxPtr
tox Word32
gn (CErr ErrConferenceGetType -> IO (CEnum ConferenceType))
-> (CEnum ConferenceType -> IO ConferenceType)
-> CErr ErrConferenceGetType
-> IO ConferenceType
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (ConferenceType -> IO ConferenceType
forall (m :: * -> *) a. Monad m => a -> m a
return (ConferenceType -> IO ConferenceType)
-> (CEnum ConferenceType -> ConferenceType)
-> CEnum ConferenceType
-> IO ConferenceType
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CEnum ConferenceType -> ConferenceType
forall a. Enum a => CEnum a -> a
fromCEnum))


--------------------------------------------------------------------------------
--
-- :: Low-level custom packet sending and receiving
--
--------------------------------------------------------------------------------


-- | Send a custom lossy packet to a friend.
--
-- The first byte of data must be in the range 200-254. Maximum length of a
-- custom packet is 'tox_max_custom_packet_size'.
--
-- Lossy packets behave like UDP packets, meaning they might never reach the
-- other side or might arrive more than once (if someone is messing with the
-- connection) or might arrive in the wrong order.
--
-- Unless latency is an issue, it is recommended that you use lossless custom
-- packets instead.
--
-- @param friend_number The friend number of the friend this lossy packet
--   should be sent to.
-- @param data A byte array containing the packet data.
-- @param length The length of the packet data byte array.
--
-- @return true on success.
toxFriendLossyPacket :: ToxPtr -> Word32 -> BS.ByteString -> IO (Either ErrFriendCustomPacket Bool)
toxFriendLossyPacket :: ToxPtr
-> Word32 -> ByteString -> IO (Either ErrFriendCustomPacket Bool)
toxFriendLossyPacket ToxPtr
tox Word32
fn ByteString
d =
    ByteString
-> (CStringLen -> IO (Either ErrFriendCustomPacket Bool))
-> IO (Either ErrFriendCustomPacket Bool)
forall a. ByteString -> (CStringLen -> IO a) -> IO a
BS.useAsCStringLen ByteString
d ((CStringLen -> IO (Either ErrFriendCustomPacket Bool))
 -> IO (Either ErrFriendCustomPacket Bool))
-> (CStringLen -> IO (Either ErrFriendCustomPacket Bool))
-> IO (Either ErrFriendCustomPacket Bool)
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
dataPtr, Int
dataLen) ->
        (CErr ErrFriendCustomPacket -> IO Bool)
-> IO (Either ErrFriendCustomPacket Bool)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrFriendCustomPacket -> IO Bool)
 -> IO (Either ErrFriendCustomPacket Bool))
-> (CErr ErrFriendCustomPacket -> IO Bool)
-> IO (Either ErrFriendCustomPacket Bool)
forall a b. (a -> b) -> a -> b
$ ToxPtr
-> Word32
-> Ptr CChar
-> CSize
-> CErr ErrFriendCustomPacket
-> IO Bool
tox_friend_send_lossy_packet ToxPtr
tox Word32
fn Ptr CChar
dataPtr (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
dataLen)

-- | Send a custom lossless packet to a friend.
--
-- The first byte of data must be in the range 160-191. Maximum length of a
-- custom packet is 'tox_max_custom_packet_size'.
--
-- Lossless packet behaviour is comparable to TCP (reliability, arrive in order)
-- but with packets instead of a stream.
--
-- @param friend_number The friend number of the friend this lossless packet
--   should be sent to.
-- @param data A byte array containing the packet data.
-- @param length The length of the packet data byte array.
--
-- @return true on success.
toxFriendLosslessPacket :: ToxPtr -> Word32 -> BS.ByteString -> IO (Either ErrFriendCustomPacket Bool)
toxFriendLosslessPacket :: ToxPtr
-> Word32 -> ByteString -> IO (Either ErrFriendCustomPacket Bool)
toxFriendLosslessPacket ToxPtr
tox Word32
fn ByteString
d =
    ByteString
-> (CStringLen -> IO (Either ErrFriendCustomPacket Bool))
-> IO (Either ErrFriendCustomPacket Bool)
forall a. ByteString -> (CStringLen -> IO a) -> IO a
BS.useAsCStringLen ByteString
d ((CStringLen -> IO (Either ErrFriendCustomPacket Bool))
 -> IO (Either ErrFriendCustomPacket Bool))
-> (CStringLen -> IO (Either ErrFriendCustomPacket Bool))
-> IO (Either ErrFriendCustomPacket Bool)
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
dataPtr, Int
dataLen) ->
        (CErr ErrFriendCustomPacket -> IO Bool)
-> IO (Either ErrFriendCustomPacket Bool)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrFriendCustomPacket -> IO Bool)
 -> IO (Either ErrFriendCustomPacket Bool))
-> (CErr ErrFriendCustomPacket -> IO Bool)
-> IO (Either ErrFriendCustomPacket Bool)
forall a b. (a -> b) -> a -> b
$ ToxPtr
-> Word32
-> Ptr CChar
-> CSize
-> CErr ErrFriendCustomPacket
-> IO Bool
tox_friend_send_lossless_packet ToxPtr
tox Word32
fn Ptr CChar
dataPtr (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
dataLen)


--------------------------------------------------------------------------------
--
-- :: Low-level network information
--
--------------------------------------------------------------------------------


-- | Writes the temporary DHT public key of this instance to a byte array.
--
-- This can be used in combination with an externally accessible IP address and
-- the bound port (from tox_self_get_udp_port) to run a temporary bootstrap
-- node.
--
-- Be aware that every time a new instance is created, the DHT public key
-- changes, meaning this cannot be used to run a permanent bootstrap node.
--
-- @param dht_id A memory region of at least 'tox_public_key_size' bytes. If
--   this parameter is 'nullPtr', this function has no effect.
toxSelfGetDhtId :: ToxPtr -> IO BS.ByteString
toxSelfGetDhtId :: ToxPtr -> IO ByteString
toxSelfGetDhtId ToxPtr
tox =
    let idLen :: Int
idLen = Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
tox_public_key_size in
    Int -> (Ptr CChar -> IO ByteString) -> IO ByteString
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
idLen ((Ptr CChar -> IO ByteString) -> IO ByteString)
-> (Ptr CChar -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
idPtr -> do
        ToxPtr -> Ptr CChar -> IO ()
tox_self_get_dht_id ToxPtr
tox Ptr CChar
idPtr
        CStringLen -> IO ByteString
BS.packCStringLen (Ptr CChar
idPtr, Int
idLen)

-- | Return the UDP port this Tox instance is bound to.
toxSelfGetUdpPort :: ToxPtr -> IO (Either ErrGetPort Word16)
toxSelfGetUdpPort :: ToxPtr -> IO (Either ErrGetPort Word16)
toxSelfGetUdpPort ToxPtr
tox = (CErr ErrGetPort -> IO Word16) -> IO (Either ErrGetPort Word16)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrGetPort -> IO Word16) -> IO (Either ErrGetPort Word16))
-> (CErr ErrGetPort -> IO Word16) -> IO (Either ErrGetPort Word16)
forall a b. (a -> b) -> a -> b
$ ToxPtr -> CErr ErrGetPort -> IO Word16
tox_self_get_udp_port ToxPtr
tox

-- | Return the TCP port this Tox instance is bound to. This is only relevant if
-- the instance is acting as a TCP relay.
toxSelfGetTcpPort :: ToxPtr -> IO (Either ErrGetPort Word16)
toxSelfGetTcpPort :: ToxPtr -> IO (Either ErrGetPort Word16)
toxSelfGetTcpPort ToxPtr
tox = (CErr ErrGetPort -> IO Word16) -> IO (Either ErrGetPort Word16)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun ((CErr ErrGetPort -> IO Word16) -> IO (Either ErrGetPort Word16))
-> (CErr ErrGetPort -> IO Word16) -> IO (Either ErrGetPort Word16)
forall a b. (a -> b) -> a -> b
$ ToxPtr -> CErr ErrGetPort -> IO Word16
tox_self_get_tcp_port ToxPtr
tox