{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE LambdaCase    #-}
{-# LANGUAGE StrictData    #-}
module Network.Tox.C.Options where

import           Control.Exception (bracket)
import           Data.ByteString   (ByteString)
import qualified Data.ByteString   as BS
import           Data.Word         (Word16)
import           Foreign.C.Enum
import           Foreign.C.String  (peekCString, withCString)
import           Foreign.Ptr       (nullPtr)
import           GHC.Generics      (Generic)

import           FFI.Tox.Tox       (LogCb, LogLevel (..), OptionsPtr,
                                    ProxyType (..), SavedataType (..),
                                    tox_options_get_end_port,
                                    tox_options_get_ipv6_enabled,
                                    tox_options_get_proxy_host,
                                    tox_options_get_proxy_port,
                                    tox_options_get_proxy_type,
                                    tox_options_get_savedata_data,
                                    tox_options_get_savedata_length,
                                    tox_options_get_savedata_type,
                                    tox_options_get_start_port,
                                    tox_options_get_tcp_port,
                                    tox_options_get_udp_enabled,
                                    tox_options_set_end_port,
                                    tox_options_set_ipv6_enabled,
                                    tox_options_set_log_callback,
                                    tox_options_set_proxy_host,
                                    tox_options_set_proxy_port,
                                    tox_options_set_proxy_type,
                                    tox_options_set_savedata_data,
                                    tox_options_set_savedata_length,
                                    tox_options_set_savedata_type,
                                    tox_options_set_start_port,
                                    tox_options_set_tcp_port,
                                    tox_options_set_udp_enabled, wrapLogCb)

--------------------------------------------------------------------------------
--
-- :: Startup options
--
--------------------------------------------------------------------------------


-- This struct contains all the startup options for Tox. You can either allocate
-- this object yourself, and pass it to tox_options_default, or call
-- tox_options_new to get a new default options object.
data Options = Options
    { Options -> Bool
ipv6Enabled  :: Bool
      -- The type of socket to create.
      --
      -- If this is set to false, an IPv4 socket is created, which subsequently
      -- only allows IPv4 communication.
      -- If it is set to true, an IPv6 socket is created, allowing both IPv4 and
      -- IPv6 communication.

    , Options -> Bool
udpEnabled   :: Bool
      -- Enable the use of UDP communication when available.
      --
      -- Setting this to false will force Tox to use TCP only. Communications will
      -- need to be relayed through a TCP relay node, potentially slowing them
      -- down. Disabling UDP support is necessary when using anonymous proxies or
      -- Tor.

    , Options -> ProxyType
proxyType    :: ProxyType
      -- Pass communications through a proxy.

    , Options -> String
proxyHost    :: String
      -- The IP address or DNS name of the proxy to be used.
      --
      -- If used, this must be non-'nullPtr' and be a valid DNS name. The name
      -- must not exceed 255 ('tox_max_filename_length') characters, and be in a
      -- NUL-terminated C string format (255 chars + 1 NUL byte).
      --
      -- This member is ignored (it can be 'nullPtr') if proxy_type is
      -- ProxyTypeNone.

    , Options -> Word16
proxyPort    :: Word16
      -- The port to use to connect to the proxy server.
      --
      -- Ports must be in the range (1, 65535). The value is ignored if proxy_type
      -- is ProxyTypeNone.

    , Options -> Word16
startPort    :: Word16
      -- The start port of the inclusive port range to attempt to use.
      --
      -- If both 'startPort' and 'endPort' are 0, the default port range will be
      -- used: [33445, 33545].
      --
      -- If either 'startPort' or 'endPort' is 0 while the other is non-zero, the
      -- non-zero port will be the only port in the range.
      --
      -- Having 'startPort' > 'endport' will yield the same behavior as if
      -- 'startPort' and 'endPort' were swapped.

    , Options -> Word16
endPort      :: Word16
      -- The end port of the inclusive port range to attempt to use.

    , Options -> Word16
tcpPort      :: Word16
      -- The port to use for the TCP server (relay). If 0, the TCP server is
      -- disabled.
      --
      -- Enabling it is not required for Tox to function properly.
      --
      -- When enabled, your Tox instance can act as a TCP relay for other Tox
      -- instance. This leads to increased traffic, thus when writing a client it
      -- is recommended to enable TCP server only if the user has an option to
      -- disable it.

    , Options -> SavedataType
savedataType :: SavedataType
      -- The type of savedata to load from.

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


defaultOptions :: Options
defaultOptions :: Options
defaultOptions = Options :: Bool
-> Bool
-> ProxyType
-> String
-> Word16
-> Word16
-> Word16
-> Word16
-> SavedataType
-> ByteString
-> Options
Options
    { ipv6Enabled :: Bool
ipv6Enabled  = Bool
True
    , udpEnabled :: Bool
udpEnabled   = Bool
True
    , proxyType :: ProxyType
proxyType    = ProxyType
ProxyTypeNone
    , proxyHost :: String
proxyHost    = String
""
    , proxyPort :: Word16
proxyPort    = Word16
0
    , startPort :: Word16
startPort    = Word16
0
    , endPort :: Word16
endPort      = Word16
0
    , tcpPort :: Word16
tcpPort      = Word16
0
    , savedataType :: SavedataType
savedataType = SavedataType
SavedataTypeNone
    , savedataData :: ByteString
savedataData = ByteString
BS.empty
    }


logLevelName :: LogLevel -> Char
logLevelName :: LogLevel -> Char
logLevelName LogLevel
LogLevelTrace   = Char
'T'
logLevelName LogLevel
LogLevelDebug   = Char
'D'
logLevelName LogLevel
LogLevelInfo    = Char
'I'
logLevelName LogLevel
LogLevelWarning = Char
'W'
logLevelName LogLevel
LogLevelError   = Char
'E'

logHandler :: LogCb
logHandler :: LogCb
logHandler ToxPtr
_ CEnum LogLevel
cLevel CString
cFile Word32
line CString
cFunc CString
cMsg Ptr ()
_ = do
    let level :: LogLevel
level = CEnum LogLevel -> LogLevel
forall a. Enum a => CEnum a -> a
fromCEnum CEnum LogLevel
cLevel
    String
file <- CString -> IO String
peekCString CString
cFile
    String
func <- CString -> IO String
peekCString CString
cFunc
    String
msg <- CString -> IO String
peekCString CString
cMsg
    case LogLevel
level of
        LogLevel
LogLevelTrace -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
        LogLevel
_ -> String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ LogLevel -> Char
logLevelName LogLevel
level Char -> ShowS
forall a. a -> [a] -> [a]
: Char
' ' Char -> ShowS
forall a. a -> [a] -> [a]
: String
file String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
":" String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Word32 -> String
forall a. Show a => a -> String
show Word32
line String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"(" String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
func String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"): " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
msg


data ErrOptionsNew
    = ErrOptionsNewMalloc
      -- The function was unable to allocate enough memory to store the internal
      -- structures for the Tox options object.
    deriving (ErrOptionsNew -> ErrOptionsNew -> Bool
(ErrOptionsNew -> ErrOptionsNew -> Bool)
-> (ErrOptionsNew -> ErrOptionsNew -> Bool) -> Eq ErrOptionsNew
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ErrOptionsNew -> ErrOptionsNew -> Bool
$c/= :: ErrOptionsNew -> ErrOptionsNew -> Bool
== :: ErrOptionsNew -> ErrOptionsNew -> Bool
$c== :: ErrOptionsNew -> ErrOptionsNew -> Bool
Eq, Eq ErrOptionsNew
Eq ErrOptionsNew
-> (ErrOptionsNew -> ErrOptionsNew -> Ordering)
-> (ErrOptionsNew -> ErrOptionsNew -> Bool)
-> (ErrOptionsNew -> ErrOptionsNew -> Bool)
-> (ErrOptionsNew -> ErrOptionsNew -> Bool)
-> (ErrOptionsNew -> ErrOptionsNew -> Bool)
-> (ErrOptionsNew -> ErrOptionsNew -> ErrOptionsNew)
-> (ErrOptionsNew -> ErrOptionsNew -> ErrOptionsNew)
-> Ord ErrOptionsNew
ErrOptionsNew -> ErrOptionsNew -> Bool
ErrOptionsNew -> ErrOptionsNew -> Ordering
ErrOptionsNew -> ErrOptionsNew -> ErrOptionsNew
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 :: ErrOptionsNew -> ErrOptionsNew -> ErrOptionsNew
$cmin :: ErrOptionsNew -> ErrOptionsNew -> ErrOptionsNew
max :: ErrOptionsNew -> ErrOptionsNew -> ErrOptionsNew
$cmax :: ErrOptionsNew -> ErrOptionsNew -> ErrOptionsNew
>= :: ErrOptionsNew -> ErrOptionsNew -> Bool
$c>= :: ErrOptionsNew -> ErrOptionsNew -> Bool
> :: ErrOptionsNew -> ErrOptionsNew -> Bool
$c> :: ErrOptionsNew -> ErrOptionsNew -> Bool
<= :: ErrOptionsNew -> ErrOptionsNew -> Bool
$c<= :: ErrOptionsNew -> ErrOptionsNew -> Bool
< :: ErrOptionsNew -> ErrOptionsNew -> Bool
$c< :: ErrOptionsNew -> ErrOptionsNew -> Bool
compare :: ErrOptionsNew -> ErrOptionsNew -> Ordering
$ccompare :: ErrOptionsNew -> ErrOptionsNew -> Ordering
$cp1Ord :: Eq ErrOptionsNew
Ord, Int -> ErrOptionsNew
ErrOptionsNew -> Int
ErrOptionsNew -> [ErrOptionsNew]
ErrOptionsNew -> ErrOptionsNew
ErrOptionsNew -> ErrOptionsNew -> [ErrOptionsNew]
ErrOptionsNew -> ErrOptionsNew -> ErrOptionsNew -> [ErrOptionsNew]
(ErrOptionsNew -> ErrOptionsNew)
-> (ErrOptionsNew -> ErrOptionsNew)
-> (Int -> ErrOptionsNew)
-> (ErrOptionsNew -> Int)
-> (ErrOptionsNew -> [ErrOptionsNew])
-> (ErrOptionsNew -> ErrOptionsNew -> [ErrOptionsNew])
-> (ErrOptionsNew -> ErrOptionsNew -> [ErrOptionsNew])
-> (ErrOptionsNew
    -> ErrOptionsNew -> ErrOptionsNew -> [ErrOptionsNew])
-> Enum ErrOptionsNew
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 :: ErrOptionsNew -> ErrOptionsNew -> ErrOptionsNew -> [ErrOptionsNew]
$cenumFromThenTo :: ErrOptionsNew -> ErrOptionsNew -> ErrOptionsNew -> [ErrOptionsNew]
enumFromTo :: ErrOptionsNew -> ErrOptionsNew -> [ErrOptionsNew]
$cenumFromTo :: ErrOptionsNew -> ErrOptionsNew -> [ErrOptionsNew]
enumFromThen :: ErrOptionsNew -> ErrOptionsNew -> [ErrOptionsNew]
$cenumFromThen :: ErrOptionsNew -> ErrOptionsNew -> [ErrOptionsNew]
enumFrom :: ErrOptionsNew -> [ErrOptionsNew]
$cenumFrom :: ErrOptionsNew -> [ErrOptionsNew]
fromEnum :: ErrOptionsNew -> Int
$cfromEnum :: ErrOptionsNew -> Int
toEnum :: Int -> ErrOptionsNew
$ctoEnum :: Int -> ErrOptionsNew
pred :: ErrOptionsNew -> ErrOptionsNew
$cpred :: ErrOptionsNew -> ErrOptionsNew
succ :: ErrOptionsNew -> ErrOptionsNew
$csucc :: ErrOptionsNew -> ErrOptionsNew
Enum, ErrOptionsNew
ErrOptionsNew -> ErrOptionsNew -> Bounded ErrOptionsNew
forall a. a -> a -> Bounded a
maxBound :: ErrOptionsNew
$cmaxBound :: ErrOptionsNew
minBound :: ErrOptionsNew
$cminBound :: ErrOptionsNew
Bounded, ReadPrec [ErrOptionsNew]
ReadPrec ErrOptionsNew
Int -> ReadS ErrOptionsNew
ReadS [ErrOptionsNew]
(Int -> ReadS ErrOptionsNew)
-> ReadS [ErrOptionsNew]
-> ReadPrec ErrOptionsNew
-> ReadPrec [ErrOptionsNew]
-> Read ErrOptionsNew
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [ErrOptionsNew]
$creadListPrec :: ReadPrec [ErrOptionsNew]
readPrec :: ReadPrec ErrOptionsNew
$creadPrec :: ReadPrec ErrOptionsNew
readList :: ReadS [ErrOptionsNew]
$creadList :: ReadS [ErrOptionsNew]
readsPrec :: Int -> ReadS ErrOptionsNew
$creadsPrec :: Int -> ReadS ErrOptionsNew
Read, Int -> ErrOptionsNew -> ShowS
[ErrOptionsNew] -> ShowS
ErrOptionsNew -> String
(Int -> ErrOptionsNew -> ShowS)
-> (ErrOptionsNew -> String)
-> ([ErrOptionsNew] -> ShowS)
-> Show ErrOptionsNew
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ErrOptionsNew] -> ShowS
$cshowList :: [ErrOptionsNew] -> ShowS
show :: ErrOptionsNew -> String
$cshow :: ErrOptionsNew -> String
showsPrec :: Int -> ErrOptionsNew -> ShowS
$cshowsPrec :: Int -> ErrOptionsNew -> ShowS
Show)


-- | Allocates a new Tox_Options object and initialises it with the default
-- options. This function can be used to preserve long term ABI compatibility by
-- giving the responsibility of allocation and deallocation to the Tox library.
--
-- Objects returned from this function must be freed using the tox_options_free
-- function.
--
-- @return A new 'OptionsPtr' with default options or 'nullPtr' on failure.
foreign import ccall tox_options_new :: CErr ErrOptionsNew -> IO OptionsPtr

toxOptionsNew :: IO (Either ErrOptionsNew OptionsPtr)
toxOptionsNew :: IO (Either ErrOptionsNew OptionsPtr)
toxOptionsNew = (CErr ErrOptionsNew -> IO OptionsPtr)
-> IO (Either ErrOptionsNew OptionsPtr)
forall err r.
(Eq err, Enum err, Bounded err) =>
(CErr err -> IO r) -> IO (Either err r)
callErrFun CErr ErrOptionsNew -> IO OptionsPtr
tox_options_new


-- | Releases all resources associated with an options objects.
--
-- Passing a pointer that was not returned by tox_options_new results in
-- undefined behaviour.
foreign import ccall "tox_options_free" toxOptionsFree :: OptionsPtr -> IO ()


withToxOptions :: (OptionsPtr -> IO r) -> IO (Either ErrOptionsNew r)
withToxOptions :: (OptionsPtr -> IO r) -> IO (Either ErrOptionsNew r)
withToxOptions OptionsPtr -> IO r
f =
    IO (Either ErrOptionsNew OptionsPtr)
-> (Either ErrOptionsNew OptionsPtr -> IO ())
-> (Either ErrOptionsNew OptionsPtr -> IO (Either ErrOptionsNew r))
-> IO (Either ErrOptionsNew r)
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket IO (Either ErrOptionsNew OptionsPtr)
toxOptionsNew ((ErrOptionsNew -> IO ())
-> (OptionsPtr -> IO ())
-> Either ErrOptionsNew OptionsPtr
-> IO ()
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (IO () -> ErrOptionsNew -> IO ()
forall a b. a -> b -> a
const (IO () -> ErrOptionsNew -> IO ())
-> IO () -> ErrOptionsNew -> IO ()
forall a b. (a -> b) -> a -> b
$ () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()) OptionsPtr -> IO ()
toxOptionsFree) ((Either ErrOptionsNew OptionsPtr -> IO (Either ErrOptionsNew r))
 -> IO (Either ErrOptionsNew r))
-> (Either ErrOptionsNew OptionsPtr -> IO (Either ErrOptionsNew r))
-> IO (Either ErrOptionsNew r)
forall a b. (a -> b) -> a -> b
$ \case
        Left ErrOptionsNew
err -> Either ErrOptionsNew r -> IO (Either ErrOptionsNew r)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ErrOptionsNew r -> IO (Either ErrOptionsNew r))
-> Either ErrOptionsNew r -> IO (Either ErrOptionsNew r)
forall a b. (a -> b) -> a -> b
$ ErrOptionsNew -> Either ErrOptionsNew r
forall a b. a -> Either a b
Left ErrOptionsNew
err
        Right OptionsPtr
ok -> r -> Either ErrOptionsNew r
forall a b. b -> Either a b
Right (r -> Either ErrOptionsNew r)
-> IO r -> IO (Either ErrOptionsNew r)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> OptionsPtr -> IO r
f OptionsPtr
ok


-- | Read 'Options' from an 'OptionsPtr'.
--
-- If the passed pointer is 'nullPtr', the behaviour is undefined.
peekToxOptions :: OptionsPtr -> IO Options
peekToxOptions :: OptionsPtr -> IO Options
peekToxOptions OptionsPtr
ptr = do
    Bool
cIpv6Enabled    <- OptionsPtr -> IO Bool
tox_options_get_ipv6_enabled    OptionsPtr
ptr
    Bool
cUdpEnabled     <- OptionsPtr -> IO Bool
tox_options_get_udp_enabled     OptionsPtr
ptr
    CEnum ProxyType
cProxyType      <- OptionsPtr -> IO (CEnum ProxyType)
tox_options_get_proxy_type      OptionsPtr
ptr
    String
cProxyHost      <- OptionsPtr -> IO CString
tox_options_get_proxy_host      OptionsPtr
ptr IO CString -> (CString -> IO String) -> IO String
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= CString -> IO String
peekNullableString
    Word16
cProxyPort      <- OptionsPtr -> IO Word16
tox_options_get_proxy_port      OptionsPtr
ptr
    Word16
cStartPort      <- OptionsPtr -> IO Word16
tox_options_get_start_port      OptionsPtr
ptr
    Word16
cEndPort        <- OptionsPtr -> IO Word16
tox_options_get_end_port        OptionsPtr
ptr
    Word16
cTcpPort        <- OptionsPtr -> IO Word16
tox_options_get_tcp_port        OptionsPtr
ptr
    CEnum SavedataType
cSavedataType   <- OptionsPtr -> IO (CEnum SavedataType)
tox_options_get_savedata_type   OptionsPtr
ptr
    CString
cSavedataData   <- OptionsPtr -> IO CString
tox_options_get_savedata_data   OptionsPtr
ptr
    CSize
cSavedataLength <- OptionsPtr -> IO CSize
tox_options_get_savedata_length OptionsPtr
ptr
    ByteString
cSavedata       <- CStringLen -> IO ByteString
BS.packCStringLen
                             ( CString
cSavedataData
                             , CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
cSavedataLength)
    Options -> IO Options
forall (m :: * -> *) a. Monad m => a -> m a
return Options :: Bool
-> Bool
-> ProxyType
-> String
-> Word16
-> Word16
-> Word16
-> Word16
-> SavedataType
-> ByteString
-> Options
Options
        { ipv6Enabled :: Bool
ipv6Enabled    = Bool
cIpv6Enabled
        , udpEnabled :: Bool
udpEnabled     = Bool
cUdpEnabled
        , proxyType :: ProxyType
proxyType      = CEnum ProxyType -> ProxyType
forall a. Enum a => CEnum a -> a
fromCEnum CEnum ProxyType
cProxyType
        , proxyHost :: String
proxyHost      = String
cProxyHost
        , proxyPort :: Word16
proxyPort      = Word16
cProxyPort
        , startPort :: Word16
startPort      = Word16
cStartPort
        , endPort :: Word16
endPort        = Word16
cEndPort
        , tcpPort :: Word16
tcpPort        = Word16
cTcpPort
        , savedataType :: SavedataType
savedataType   = CEnum SavedataType -> SavedataType
forall a. Enum a => CEnum a -> a
fromCEnum CEnum SavedataType
cSavedataType
        , savedataData :: ByteString
savedataData   = ByteString
cSavedata
        }

  where
    -- 'peekCString' doesn't handle NULL strings as empty, unlike
    -- 'packCStringLen', which ignores the pointer to zero-length 'CString's.
    peekNullableString :: CString -> IO String
peekNullableString CString
p =
        if CString
p CString -> CString -> Bool
forall a. Eq a => a -> a -> Bool
== CString
forall a. Ptr a
nullPtr
            then String -> IO String
forall (m :: * -> *) a. Monad m => a -> m a
return String
""
            else CString -> IO String
peekCString CString
p


-- | Allocate a new C options pointer, fills in the values from 'Options',
-- calls the processor function, and deallocates the options pointer.
--
-- The 'OptionsPtr' passed to the processor function is never 'nullPtr'. If
-- allocation fails, the IO action evaluates to 'Left' with an appropriate
-- error code.
withOptions :: Options -> (OptionsPtr -> IO r) -> IO (Either ErrOptionsNew r)
withOptions :: Options -> (OptionsPtr -> IO r) -> IO (Either ErrOptionsNew r)
withOptions Options
options OptionsPtr -> IO r
f =
    (OptionsPtr -> IO r) -> IO (Either ErrOptionsNew r)
forall r. (OptionsPtr -> IO r) -> IO (Either ErrOptionsNew r)
withToxOptions ((OptionsPtr -> IO r) -> IO (Either ErrOptionsNew r))
-> (OptionsPtr -> IO r) -> IO (Either ErrOptionsNew r)
forall a b. (a -> b) -> a -> b
$ \OptionsPtr
ptr ->
        String -> (CString -> IO r) -> IO r
forall a. String -> (CString -> IO a) -> IO a
withCString (Options -> String
proxyHost Options
options) ((CString -> IO r) -> IO r) -> (CString -> IO r) -> IO r
forall a b. (a -> b) -> a -> b
$ \CString
host ->
            ByteString -> (CStringLen -> IO r) -> IO r
forall a. ByteString -> (CStringLen -> IO a) -> IO a
BS.useAsCStringLen (Options -> ByteString
savedataData Options
options) ((CStringLen -> IO r) -> IO r) -> (CStringLen -> IO r) -> IO r
forall a b. (a -> b) -> a -> b
$ \(CString
saveData, Int
saveLenInt) -> do
                let saveLen :: CSize
saveLen = Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
saveLenInt
                OptionsPtr -> Bool -> IO ()
tox_options_set_ipv6_enabled    OptionsPtr
ptr (Bool -> IO ()) -> Bool -> IO ()
forall a b. (a -> b) -> a -> b
$ Options -> Bool
ipv6Enabled Options
options
                OptionsPtr -> Bool -> IO ()
tox_options_set_udp_enabled     OptionsPtr
ptr (Bool -> IO ()) -> Bool -> IO ()
forall a b. (a -> b) -> a -> b
$ Options -> Bool
udpEnabled Options
options
                OptionsPtr -> CEnum ProxyType -> IO ()
tox_options_set_proxy_type      OptionsPtr
ptr (CEnum ProxyType -> IO ()) -> CEnum ProxyType -> IO ()
forall a b. (a -> b) -> a -> b
$ ProxyType -> CEnum ProxyType
forall a. Enum a => a -> CEnum a
toCEnum (ProxyType -> CEnum ProxyType) -> ProxyType -> CEnum ProxyType
forall a b. (a -> b) -> a -> b
$ Options -> ProxyType
proxyType Options
options
                OptionsPtr -> CString -> IO ()
tox_options_set_proxy_host      OptionsPtr
ptr CString
host
                OptionsPtr -> Word16 -> IO ()
tox_options_set_proxy_port      OptionsPtr
ptr (Word16 -> IO ()) -> Word16 -> IO ()
forall a b. (a -> b) -> a -> b
$ Options -> Word16
proxyPort Options
options
                OptionsPtr -> Word16 -> IO ()
tox_options_set_start_port      OptionsPtr
ptr (Word16 -> IO ()) -> Word16 -> IO ()
forall a b. (a -> b) -> a -> b
$ Options -> Word16
startPort Options
options
                OptionsPtr -> Word16 -> IO ()
tox_options_set_end_port        OptionsPtr
ptr (Word16 -> IO ()) -> Word16 -> IO ()
forall a b. (a -> b) -> a -> b
$ Options -> Word16
endPort Options
options
                OptionsPtr -> Word16 -> IO ()
tox_options_set_tcp_port        OptionsPtr
ptr (Word16 -> IO ()) -> Word16 -> IO ()
forall a b. (a -> b) -> a -> b
$ Options -> Word16
tcpPort Options
options
                OptionsPtr -> CEnum SavedataType -> IO ()
tox_options_set_savedata_type   OptionsPtr
ptr (CEnum SavedataType -> IO ()) -> CEnum SavedataType -> IO ()
forall a b. (a -> b) -> a -> b
$ SavedataType -> CEnum SavedataType
forall a. Enum a => a -> CEnum a
toCEnum (SavedataType -> CEnum SavedataType)
-> SavedataType -> CEnum SavedataType
forall a b. (a -> b) -> a -> b
$ Options -> SavedataType
savedataType Options
options
                OptionsPtr -> CString -> CSize -> IO ()
tox_options_set_savedata_data   OptionsPtr
ptr CString
saveData CSize
saveLen
                OptionsPtr -> CSize -> IO ()
tox_options_set_savedata_length OptionsPtr
ptr CSize
saveLen
                OptionsPtr -> FunPtr LogCb -> IO ()
tox_options_set_log_callback    OptionsPtr
ptr (FunPtr LogCb -> IO ()) -> IO (FunPtr LogCb) -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< LogCb -> IO (FunPtr LogCb)
wrapLogCb LogCb
logHandler
                OptionsPtr -> IO r
f OptionsPtr
ptr