feat: Add async event handling (callbacks) code.

Instead of synchronously handling events as they happen in
`tox_iterate`, this first collects all events in a structure and then
lets the client process them. This allows clients to process events in
parallel, since the data structure returned is mostly immutable.

This also makes toxcore compatible with languages that don't (easily)
support callbacks from C into the non-C language.

If we remove the callbacks, this allows us to add fields to the events
without breaking the API.
This commit is contained in:
iphydf 2022-02-06 16:41:31 +00:00
parent cde796f1f8
commit de4af4c270
No known key found for this signature in database
GPG Key ID: 3855DBA2D74403C9
42 changed files with 5068 additions and 24 deletions

View File

@ -76,6 +76,7 @@ jobs:
testing/misc_tools.c
toxav/*.c
toxcore/*.c
toxcore/*/*.c
toxencryptsave/*.c
-lpthread
$(pkg-config --cflags --libs libsodium opus vpx)

View File

@ -109,6 +109,7 @@ jobs:
testing/misc_tools.c
toxav/*.c
toxcore/*.c
toxcore/*/*.c
toxencryptsave/*.c
$(pkg-config --cflags --libs libsodium opus vpx)
- name: Run the test
@ -146,6 +147,7 @@ jobs:
testing/misc_tools.c
toxav/*.c
toxcore/*.c
toxcore/*/*.c
toxencryptsave/*.c
-D__COMPCERT__ -DDISABLE_VLA
-lpthread $(pkg-config --cflags --libs libsodium opus vpx)

View File

@ -161,6 +161,7 @@ set(toxcore_PKGCONFIG_REQUIRES)
# LAYER 1: Crypto core
# --------------------
set(toxcore_SOURCES ${toxcore_SOURCES}
toxcore/ccompat.c
toxcore/ccompat.h
toxcore/crypto_core.c
toxcore/crypto_core.h)
@ -240,10 +241,47 @@ set(toxcore_SOURCES ${toxcore_SOURCES}
set(toxcore_SOURCES ${toxcore_SOURCES}
toxcore/tox_api.c
toxcore/tox.c
toxcore/tox_private.h
toxcore/tox.h)
toxcore/tox.h
toxcore/tox_private.h)
set(toxcore_API_HEADERS ${toxcore_API_HEADERS} ${toxcore_SOURCE_DIR}/toxcore/tox.h^tox)
# LAYER 9: New async events API
# -------------------
set(toxcore_SOURCES ${toxcore_SOURCES}
toxcore/events/conference_connected.c
toxcore/events/conference_invite.c
toxcore/events/conference_message.c
toxcore/events/conference_peer_list_changed.c
toxcore/events/conference_peer_name.c
toxcore/events/conference_title.c
toxcore/events/file_chunk_request.c
toxcore/events/file_recv.c
toxcore/events/file_recv_chunk.c
toxcore/events/file_recv_control.c
toxcore/events/friend_connection_status.c
toxcore/events/friend_lossless_packet.c
toxcore/events/friend_lossy_packet.c
toxcore/events/friend_message.c
toxcore/events/friend_name.c
toxcore/events/friend_read_receipt.c
toxcore/events/friend_request.c
toxcore/events/friend_status.c
toxcore/events/friend_status_message.c
toxcore/events/friend_typing.c
toxcore/events/events_alloc.c
toxcore/events/events_alloc.h
toxcore/events/self_connection_status.c
toxcore/tox_events.c
toxcore/tox_events.h)
set(toxcore_API_HEADERS ${toxcore_API_HEADERS} ${toxcore_SOURCE_DIR}/toxcore/tox_events.h^tox)
# LAYER 10: Dispatch recorded events to callbacks.
# -------------------
set(toxcore_SOURCES ${toxcore_SOURCES}
toxcore/tox_dispatch.c
toxcore/tox_dispatch.h)
set(toxcore_API_HEADERS ${toxcore_API_HEADERS} ${toxcore_SOURCE_DIR}/toxcore/tox_dispatch.h^tox)
################################################################################
#
# :: Audio/Video Library
@ -441,6 +479,8 @@ auto_test(save_load)
auto_test(send_message)
auto_test(set_name)
auto_test(set_status_message)
auto_test(tox_dispatch)
auto_test(tox_events)
auto_test(tox_many)
auto_test(tox_many_tcp)
auto_test(tox_one)
@ -558,4 +598,3 @@ if (BUILD_FUZZ_TESTS)
add_executable(bootstrap_fuzzer testing/fuzzing/bootstrap_harness.cc)
target_link_libraries(bootstrap_fuzzer toxcore_static fuzz_adapter -fsanitize=fuzzer)
endif()

View File

@ -61,6 +61,8 @@ flaky_tests = {
"//c-toxcore/toxcore:onion",
"//c-toxcore/toxcore:onion_announce",
"//c-toxcore/toxcore:onion_client",
"//c-toxcore/toxcore:tox_dispatch",
"//c-toxcore/toxcore:tox_events",
"//c-toxcore/toxencryptsave",
"@libsodium",
"@libvpx",

View File

@ -0,0 +1,122 @@
/* Auto Tests: Many clients.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "../testing/misc_tools.h"
#include "../toxcore/tox.h"
#include "../toxcore/tox_dispatch.h"
#include "../toxcore/tox_events.h"
#include "check_compat.h"
static void handle_events_friend_message(Tox *tox, const Tox_Event_Friend_Message *event, void *user_data)
{
bool *success = (bool *)user_data;
ck_assert(tox_event_friend_message_get_message_length(event) == sizeof("hello"));
const uint8_t *msg = tox_event_friend_message_get_message(event);
ck_assert_msg(memcmp(msg, "hello", sizeof("hello")) == 0,
"message was not expected 'hello' but '%s'", (const char *)msg);
*success = true;
}
static bool await_message(Tox **toxes, const Tox_Dispatch *dispatch)
{
for (uint32_t i = 0; i < 100; ++i) {
// Ignore events on tox 1.
tox_events_free(tox_events_iterate(toxes[0], nullptr));
// Check if tox 2 got the message from tox 1.
Tox_Events *events = tox_events_iterate(toxes[1], nullptr);
bool success = false;
tox_dispatch_invoke(dispatch, events, toxes[1], &success);
tox_events_free(events);
if (success) {
return true;
}
c_sleep(tox_iteration_interval(toxes[0]));
}
return false;
}
static void test_tox_events(void)
{
uint8_t message[sizeof("hello")];
memcpy(message, "hello", sizeof(message));
Tox *toxes[2];
uint32_t index[2];
for (uint32_t i = 0; i < 2; ++i) {
index[i] = i + 1;
toxes[i] = tox_new_log(nullptr, nullptr, &index[i]);
tox_events_init(toxes[i]);
ck_assert_msg(toxes[i] != nullptr, "failed to create tox instances %u", i);
}
Tox_Dispatch *dispatch = tox_dispatch_new(nullptr);
ck_assert_msg(dispatch != nullptr, "failed to create event dispatcher");
tox_events_callback_friend_message(dispatch, handle_events_friend_message);
uint8_t pk[TOX_PUBLIC_KEY_SIZE];
tox_self_get_dht_id(toxes[0], pk);
tox_bootstrap(toxes[1], "localhost", tox_self_get_udp_port(toxes[0], nullptr), pk, nullptr);
tox_self_get_public_key(toxes[0], pk);
tox_friend_add_norequest(toxes[1], pk, nullptr);
tox_self_get_public_key(toxes[1], pk);
tox_friend_add_norequest(toxes[0], pk, nullptr);
printf("bootstrapping and connecting 2 toxes\n");
while (tox_self_get_connection_status(toxes[0]) == TOX_CONNECTION_NONE ||
tox_self_get_connection_status(toxes[1]) == TOX_CONNECTION_NONE) {
// Ignore connection events for now.
tox_events_free(tox_events_iterate(toxes[0], nullptr));
tox_events_free(tox_events_iterate(toxes[1], nullptr));
c_sleep(tox_iteration_interval(toxes[0]));
}
printf("toxes online, waiting for friend connection\n");
while (tox_friend_get_connection_status(toxes[0], 0, nullptr) == TOX_CONNECTION_NONE ||
tox_friend_get_connection_status(toxes[1], 0, nullptr) == TOX_CONNECTION_NONE) {
// Ignore connection events for now.
tox_events_free(tox_events_iterate(toxes[0], nullptr));
tox_events_free(tox_events_iterate(toxes[1], nullptr));
c_sleep(tox_iteration_interval(toxes[0]));
}
printf("friends are connected via %s, now sending message\n",
tox_friend_get_connection_status(toxes[0], 0, nullptr) == TOX_CONNECTION_TCP ? "TCP" : "UDP");
Tox_Err_Friend_Send_Message err;
tox_friend_send_message(toxes[0], 0, TOX_MESSAGE_TYPE_NORMAL, message, sizeof(message), &err);
ck_assert(err == TOX_ERR_FRIEND_SEND_MESSAGE_OK);
ck_assert(await_message(toxes, dispatch));
tox_dispatch_free(dispatch);
for (uint32_t i = 0; i < 2; ++i) {
tox_kill(toxes[i]);
}
}
int main(void)
{
setvbuf(stdout, nullptr, _IONBF, 0);
test_tox_events();
return 0;
}

View File

@ -0,0 +1,105 @@
/* Auto Tests: Many clients.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "../testing/misc_tools.h"
#include "../toxcore/tox.h"
#include "../toxcore/tox_events.h"
#include "check_compat.h"
static bool await_message(Tox **toxes)
{
for (uint32_t i = 0; i < 100; ++i) {
// Ignore events on tox 1.
tox_events_free(tox_events_iterate(toxes[0], nullptr));
// Check if tox 2 got the message from tox 1.
Tox_Events *events = tox_events_iterate(toxes[1], nullptr);
if (events != nullptr) {
ck_assert(tox_events_get_friend_message_size(events) == 1);
const Tox_Event_Friend_Message *msg_event = tox_events_get_friend_message(events, 0);
ck_assert(tox_event_friend_message_get_message_length(msg_event) == sizeof("hello"));
const uint8_t *msg = tox_event_friend_message_get_message(msg_event);
ck_assert_msg(memcmp(msg, "hello", sizeof("hello")) == 0,
"message was not expected 'hello' but '%s'", (const char *)msg);
tox_events_free(events);
return true;
}
c_sleep(tox_iteration_interval(toxes[0]));
}
return false;
}
static void test_tox_events(void)
{
uint8_t message[sizeof("hello")];
memcpy(message, "hello", sizeof(message));
Tox *toxes[2];
uint32_t index[2];
for (uint32_t i = 0; i < 2; ++i) {
index[i] = i + 1;
toxes[i] = tox_new_log(nullptr, nullptr, &index[i]);
tox_events_init(toxes[i]);
ck_assert_msg(toxes[i] != nullptr, "failed to create tox instances %u", i);
}
uint8_t pk[TOX_PUBLIC_KEY_SIZE];
tox_self_get_dht_id(toxes[0], pk);
tox_bootstrap(toxes[1], "localhost", tox_self_get_udp_port(toxes[0], nullptr), pk, nullptr);
tox_self_get_public_key(toxes[0], pk);
tox_friend_add_norequest(toxes[1], pk, nullptr);
tox_self_get_public_key(toxes[1], pk);
tox_friend_add_norequest(toxes[0], pk, nullptr);
printf("bootstrapping and connecting 2 toxes\n");
while (tox_self_get_connection_status(toxes[0]) == TOX_CONNECTION_NONE ||
tox_self_get_connection_status(toxes[1]) == TOX_CONNECTION_NONE) {
// Ignore connection events for now.
tox_events_free(tox_events_iterate(toxes[0], nullptr));
tox_events_free(tox_events_iterate(toxes[1], nullptr));
c_sleep(tox_iteration_interval(toxes[0]));
}
printf("toxes online, waiting for friend connection\n");
while (tox_friend_get_connection_status(toxes[0], 0, nullptr) == TOX_CONNECTION_NONE ||
tox_friend_get_connection_status(toxes[1], 0, nullptr) == TOX_CONNECTION_NONE) {
// Ignore connection events for now.
tox_events_free(tox_events_iterate(toxes[0], nullptr));
tox_events_free(tox_events_iterate(toxes[1], nullptr));
c_sleep(tox_iteration_interval(toxes[0]));
}
printf("friends are connected via %s, now sending message\n",
tox_friend_get_connection_status(toxes[0], 0, nullptr) == TOX_CONNECTION_TCP ? "TCP" : "UDP");
Tox_Err_Friend_Send_Message err;
tox_friend_send_message(toxes[0], 0, TOX_MESSAGE_TYPE_NORMAL, message, sizeof(message), &err);
ck_assert(err == TOX_ERR_FRIEND_SEND_MESSAGE_OK);
ck_assert(await_message(toxes));
for (uint32_t i = 0; i < 2; ++i) {
tox_kill(toxes[i]);
}
}
int main(void)
{
setvbuf(stdout, nullptr, _IONBF, 0);
test_tox_events();
return 0;
}

View File

@ -10,6 +10,7 @@ CPPFLAGS+=("-Itesting")
CPPFLAGS+=("-Itesting/fuzzing")
CPPFLAGS+=("-Itesting/groupchats")
CPPFLAGS+=("-Itoxcore")
CPPFLAGS+=("-Itoxcore/events")
CPPFLAGS+=("-Itoxav")
CPPFLAGS+=("-Itoxencryptsave")

View File

@ -48,7 +48,7 @@ if (@ARGV and $ARGV[0] eq "-core") {
emit(abs_path $fn);
}
} else {
for my $fn (<toxav/*.c>, <toxcore/*.c>, <toxencryptsave/*.c>) {
for my $fn (<toxav/*.c>, <toxcore/*.c>, <toxcore/*/*.c>, <toxencryptsave/*.c>) {
emit(abs_path $fn);
}
}

View File

@ -10,6 +10,7 @@ exports_files(
cc_library(
name = "ccompat",
srcs = ["ccompat.c"],
hdrs = ["ccompat.h"],
visibility = ["//c-toxcore:__subpackages__"],
)
@ -459,9 +460,36 @@ cc_library(
],
)
cc_library(
name = "tox_events",
srcs = ["tox_events.c"] + glob([
"events/*.c",
"events/*.h",
]),
hdrs = ["tox_events.h"],
visibility = ["//c-toxcore:__subpackages__"],
deps = [
":ccompat",
":toxcore",
],
)
cc_library(
name = "tox_dispatch",
srcs = ["tox_dispatch.c"],
hdrs = ["tox_dispatch.h"],
visibility = ["//c-toxcore:__subpackages__"],
deps = [
":ccompat",
":tox_events",
],
)
sh_library(
name = "cimple_files",
srcs = glob([
"events/*.c",
"events/*.h",
"*.c",
"*.h",
]),

View File

@ -6,6 +6,30 @@ libtoxcore_la_include_HEADERS = \
libtoxcore_la_includedir = $(includedir)/tox
libtoxcore_la_SOURCES = ../toxcore/ccompat.h \
../toxcore/events/conference_connected.c \
../toxcore/events/conference_invite.c \
../toxcore/events/conference_message.c \
../toxcore/events/conference_peer_list_changed.c \
../toxcore/events/conference_peer_name.c \
../toxcore/events/conference_title.c \
../toxcore/events/file_chunk_request.c \
../toxcore/events/file_recv.c \
../toxcore/events/file_recv_chunk.c \
../toxcore/events/file_recv_control.c \
../toxcore/events/friend_connection_status.c \
../toxcore/events/friend_lossless_packet.c \
../toxcore/events/friend_lossy_packet.c \
../toxcore/events/friend_message.c \
../toxcore/events/friend_message.c \
../toxcore/events/friend_name.c \
../toxcore/events/friend_read_receipt.c \
../toxcore/events/friend_request.c \
../toxcore/events/friend_status.c \
../toxcore/events/friend_status_message.c \
../toxcore/events/friend_typing.c \
../toxcore/events/events_alloc.c \
../toxcore/events/events_alloc.h \
../toxcore/events/self_connection_status.c \
../toxcore/DHT.h \
../toxcore/DHT.c \
../toxcore/mono_time.h \
@ -31,8 +55,12 @@ libtoxcore_la_SOURCES = ../toxcore/ccompat.h \
../toxcore/state.h \
../toxcore/state.c \
../toxcore/tox.h \
../toxcore/tox_private.h \
../toxcore/tox.c \
../toxcore/tox_dispatch.h \
../toxcore/tox_dispatch.c \
../toxcore/tox_events.h \
../toxcore/tox_events.c \
../toxcore/tox_private.h \
../toxcore/tox_api.c \
../toxcore/util.h \
../toxcore/util.c \

4
toxcore/ccompat.c Normal file
View File

@ -0,0 +1,4 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
*/
#include "ccompat.h"

View File

@ -9,6 +9,7 @@
#define C_TOXCORE_TOXCORE_CCOMPAT_H
#include <stdbool.h>
#include <stdint.h>
bool unused_for_tokstyle(void);
@ -47,9 +48,9 @@ bool unused_for_tokstyle(void);
#endif
#define VLA(type, name, size) \
const size_t name##_size = (size) * sizeof(type); \
type *const name = (type *)alloca(name##_size)
#define SIZEOF_VLA(name) name##_size
const size_t name##_vla_size = (size) * sizeof(type); \
type *const name = (type *)alloca(name##_vla_size)
#define SIZEOF_VLA(name) name##_vla_size
#endif

View File

@ -0,0 +1,134 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
*/
#include "events_alloc.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "../ccompat.h"
#include "../tox.h"
#include "../tox_events.h"
/*****************************************************
*
* :: struct and accessors
*
*****************************************************/
struct Tox_Event_Conference_Connected {
uint32_t conference_number;
};
static void tox_event_conference_connected_construct(Tox_Event_Conference_Connected *conference_connected)
{
*conference_connected = (Tox_Event_Conference_Connected) {
0
};
}
static void tox_event_conference_connected_destruct(Tox_Event_Conference_Connected *conference_connected)
{
return;
}
static void tox_event_conference_connected_set_conference_number(Tox_Event_Conference_Connected *conference_connected,
uint32_t conference_number)
{
assert(conference_connected != nullptr);
conference_connected->conference_number = conference_number;
}
uint32_t tox_event_conference_connected_get_conference_number(const Tox_Event_Conference_Connected
*conference_connected)
{
assert(conference_connected != nullptr);
return conference_connected->conference_number;
}
/*****************************************************
*
* :: add/clear/get
*
*****************************************************/
static Tox_Event_Conference_Connected *tox_events_add_conference_connected(Tox_Events *events)
{
if (events->conference_connected_size == UINT32_MAX) {
return nullptr;
}
if (events->conference_connected_size == events->conference_connected_capacity) {
const uint32_t new_conference_connected_capacity = events->conference_connected_capacity * 2 + 1;
Tox_Event_Conference_Connected *new_conference_connected = (Tox_Event_Conference_Connected *)realloc(
events->conference_connected, new_conference_connected_capacity * sizeof(Tox_Event_Conference_Connected));
if (new_conference_connected == nullptr) {
return nullptr;
}
events->conference_connected = new_conference_connected;
events->conference_connected_capacity = new_conference_connected_capacity;
}
Tox_Event_Conference_Connected *const conference_connected =
&events->conference_connected[events->conference_connected_size];
tox_event_conference_connected_construct(conference_connected);
++events->conference_connected_size;
return conference_connected;
}
void tox_events_clear_conference_connected(Tox_Events *events)
{
if (events == nullptr) {
return;
}
for (uint32_t i = 0; i < events->conference_connected_size; ++i) {
tox_event_conference_connected_destruct(&events->conference_connected[i]);
}
free(events->conference_connected);
events->conference_connected = nullptr;
events->conference_connected_size = 0;
events->conference_connected_capacity = 0;
}
uint32_t tox_events_get_conference_connected_size(const Tox_Events *events)
{
return events->conference_connected_size;
}
const Tox_Event_Conference_Connected *tox_events_get_conference_connected(const Tox_Events *events, uint32_t index)
{
assert(index < events->conference_connected_size);
assert(events->conference_connected != nullptr);
return &events->conference_connected[index];
}
/*****************************************************
*
* :: event handler
*
*****************************************************/
void tox_events_handle_conference_connected(Tox *tox, uint32_t conference_number, void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
assert(state != nullptr);
Tox_Event_Conference_Connected *conference_connected = tox_events_add_conference_connected(state->events);
if (conference_connected == nullptr) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
return;
}
tox_event_conference_connected_set_conference_number(conference_connected, conference_number);
}

View File

@ -0,0 +1,183 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
*/
#include "events_alloc.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "../ccompat.h"
#include "../tox.h"
#include "../tox_events.h"
/*****************************************************
*
* :: struct and accessors
*
*****************************************************/
struct Tox_Event_Conference_Invite {
uint32_t friend_number;
Tox_Conference_Type type;
uint8_t *cookie;
size_t cookie_length;
};
static void tox_event_conference_invite_construct(Tox_Event_Conference_Invite *conference_invite)
{
*conference_invite = (Tox_Event_Conference_Invite) {
0
};
}
static void tox_event_conference_invite_destruct(Tox_Event_Conference_Invite *conference_invite)
{
free(conference_invite->cookie);
}
static void tox_event_conference_invite_set_friend_number(Tox_Event_Conference_Invite *conference_invite,
uint32_t friend_number)
{
assert(conference_invite != nullptr);
conference_invite->friend_number = friend_number;
}
uint32_t tox_event_conference_invite_get_friend_number(const Tox_Event_Conference_Invite *conference_invite)
{
assert(conference_invite != nullptr);
return conference_invite->friend_number;
}
static void tox_event_conference_invite_set_type(Tox_Event_Conference_Invite *conference_invite,
Tox_Conference_Type type)
{
assert(conference_invite != nullptr);
conference_invite->type = type;
}
Tox_Conference_Type tox_event_conference_invite_get_type(const Tox_Event_Conference_Invite *conference_invite)
{
assert(conference_invite != nullptr);
return conference_invite->type;
}
static bool tox_event_conference_invite_set_cookie(Tox_Event_Conference_Invite *conference_invite,
const uint8_t *cookie,
size_t cookie_length)
{
assert(conference_invite != nullptr);
if (conference_invite->cookie != nullptr) {
free(conference_invite->cookie);
conference_invite->cookie = nullptr;
conference_invite->cookie_length = 0;
}
conference_invite->cookie = (uint8_t *)malloc(cookie_length);
if (conference_invite->cookie == nullptr) {
return false;
}
memcpy(conference_invite->cookie, cookie, cookie_length);
conference_invite->cookie_length = cookie_length;
return true;
}
size_t tox_event_conference_invite_get_cookie_length(const Tox_Event_Conference_Invite *conference_invite)
{
assert(conference_invite != nullptr);
return conference_invite->cookie_length;
}
const uint8_t *tox_event_conference_invite_get_cookie(const Tox_Event_Conference_Invite *conference_invite)
{
assert(conference_invite != nullptr);
return conference_invite->cookie;
}
/*****************************************************
*
* :: add/clear/get
*
*****************************************************/
static Tox_Event_Conference_Invite *tox_events_add_conference_invite(Tox_Events *events)
{
if (events->conference_invite_size == UINT32_MAX) {
return nullptr;
}
if (events->conference_invite_size == events->conference_invite_capacity) {
const uint32_t new_conference_invite_capacity = events->conference_invite_capacity * 2 + 1;
Tox_Event_Conference_Invite *new_conference_invite = (Tox_Event_Conference_Invite *)realloc(
events->conference_invite, new_conference_invite_capacity * sizeof(Tox_Event_Conference_Invite));
if (new_conference_invite == nullptr) {
return nullptr;
}
events->conference_invite = new_conference_invite;
events->conference_invite_capacity = new_conference_invite_capacity;
}
Tox_Event_Conference_Invite *const conference_invite = &events->conference_invite[events->conference_invite_size];
tox_event_conference_invite_construct(conference_invite);
++events->conference_invite_size;
return conference_invite;
}
void tox_events_clear_conference_invite(Tox_Events *events)
{
if (events == nullptr) {
return;
}
for (uint32_t i = 0; i < events->conference_invite_size; ++i) {
tox_event_conference_invite_destruct(&events->conference_invite[i]);
}
free(events->conference_invite);
events->conference_invite = nullptr;
events->conference_invite_size = 0;
events->conference_invite_capacity = 0;
}
uint32_t tox_events_get_conference_invite_size(const Tox_Events *events)
{
return events->conference_invite_size;
}
const Tox_Event_Conference_Invite *tox_events_get_conference_invite(const Tox_Events *events, uint32_t index)
{
assert(index < events->conference_invite_size);
assert(events->conference_invite != nullptr);
return &events->conference_invite[index];
}
/*****************************************************
*
* :: event handler
*
*****************************************************/
void tox_events_handle_conference_invite(Tox *tox, uint32_t friend_number, Tox_Conference_Type type,
const uint8_t *cookie, size_t length, void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
assert(state != nullptr);
Tox_Event_Conference_Invite *conference_invite = tox_events_add_conference_invite(state->events);
if (conference_invite == nullptr) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
return;
}
tox_event_conference_invite_set_friend_number(conference_invite, friend_number);
tox_event_conference_invite_set_type(conference_invite, type);
tox_event_conference_invite_set_cookie(conference_invite, cookie, length);
}

View File

@ -0,0 +1,196 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
*/
#include "events_alloc.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "../ccompat.h"
#include "../tox.h"
#include "../tox_events.h"
/*****************************************************
*
* :: struct and accessors
*
*****************************************************/
struct Tox_Event_Conference_Message {
uint32_t conference_number;
uint32_t peer_number;
Tox_Message_Type type;
uint8_t *message;
size_t message_length;
};
static void tox_event_conference_message_construct(Tox_Event_Conference_Message *conference_message)
{
*conference_message = (Tox_Event_Conference_Message) {
0
};
}
static void tox_event_conference_message_destruct(Tox_Event_Conference_Message *conference_message)
{
free(conference_message->message);
}
static void tox_event_conference_message_set_conference_number(Tox_Event_Conference_Message *conference_message,
uint32_t conference_number)
{
assert(conference_message != nullptr);
conference_message->conference_number = conference_number;
}
uint32_t tox_event_conference_message_get_conference_number(const Tox_Event_Conference_Message *conference_message)
{
assert(conference_message != nullptr);
return conference_message->conference_number;
}
static void tox_event_conference_message_set_peer_number(Tox_Event_Conference_Message *conference_message,
uint32_t peer_number)
{
assert(conference_message != nullptr);
conference_message->peer_number = peer_number;
}
uint32_t tox_event_conference_message_get_peer_number(const Tox_Event_Conference_Message *conference_message)
{
assert(conference_message != nullptr);
return conference_message->peer_number;
}
static void tox_event_conference_message_set_type(Tox_Event_Conference_Message *conference_message,
Tox_Message_Type type)
{
assert(conference_message != nullptr);
conference_message->type = type;
}
Tox_Message_Type tox_event_conference_message_get_type(const Tox_Event_Conference_Message *conference_message)
{
assert(conference_message != nullptr);
return conference_message->type;
}
static bool tox_event_conference_message_set_message(Tox_Event_Conference_Message *conference_message,
const uint8_t *message, size_t message_length)
{
assert(conference_message != nullptr);
if (conference_message->message != nullptr) {
free(conference_message->message);
conference_message->message = nullptr;
conference_message->message_length = 0;
}
conference_message->message = (uint8_t *)malloc(message_length);
if (conference_message->message == nullptr) {
return false;
}
memcpy(conference_message->message, message, message_length);
conference_message->message_length = message_length;
return true;
}
size_t tox_event_conference_message_get_message_length(const Tox_Event_Conference_Message *conference_message)
{
assert(conference_message != nullptr);
return conference_message->message_length;
}
const uint8_t *tox_event_conference_message_get_message(const Tox_Event_Conference_Message *conference_message)
{
assert(conference_message != nullptr);
return conference_message->message;
}
/*****************************************************
*
* :: add/clear/get
*
*****************************************************/
static Tox_Event_Conference_Message *tox_events_add_conference_message(Tox_Events *events)
{
if (events->conference_message_size == UINT32_MAX) {
return nullptr;
}
if (events->conference_message_size == events->conference_message_capacity) {
const uint32_t new_conference_message_capacity = events->conference_message_capacity * 2 + 1;
Tox_Event_Conference_Message *new_conference_message = (Tox_Event_Conference_Message *)realloc(
events->conference_message, new_conference_message_capacity * sizeof(Tox_Event_Conference_Message));
if (new_conference_message == nullptr) {
return nullptr;
}
events->conference_message = new_conference_message;
events->conference_message_capacity = new_conference_message_capacity;
}
Tox_Event_Conference_Message *const conference_message = &events->conference_message[events->conference_message_size];
tox_event_conference_message_construct(conference_message);
++events->conference_message_size;
return conference_message;
}
void tox_events_clear_conference_message(Tox_Events *events)
{
if (events == nullptr) {
return;
}
for (uint32_t i = 0; i < events->conference_message_size; ++i) {
tox_event_conference_message_destruct(&events->conference_message[i]);
}
free(events->conference_message);
events->conference_message = nullptr;
events->conference_message_size = 0;
events->conference_message_capacity = 0;
}
uint32_t tox_events_get_conference_message_size(const Tox_Events *events)
{
return events->conference_message_size;
}
const Tox_Event_Conference_Message *tox_events_get_conference_message(const Tox_Events *events, uint32_t index)
{
assert(index < events->conference_message_size);
assert(events->conference_message != nullptr);
return &events->conference_message[index];
}
/*****************************************************
*
* :: event handler
*
*****************************************************/
void tox_events_handle_conference_message(Tox *tox, uint32_t conference_number, uint32_t peer_number,
Tox_Message_Type type, const uint8_t *message, size_t length, void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
assert(state != nullptr);
Tox_Event_Conference_Message *conference_message = tox_events_add_conference_message(state->events);
if (conference_message == nullptr) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
return;
}
tox_event_conference_message_set_conference_number(conference_message, conference_number);
tox_event_conference_message_set_peer_number(conference_message, peer_number);
tox_event_conference_message_set_type(conference_message, type);
tox_event_conference_message_set_message(conference_message, message, length);
}

View File

@ -0,0 +1,140 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
*/
#include "events_alloc.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "../ccompat.h"
#include "../tox.h"
#include "../tox_events.h"
/*****************************************************
*
* :: struct and accessors
*
*****************************************************/
struct Tox_Event_Conference_Peer_List_Changed {
uint32_t conference_number;
};
static void tox_event_conference_peer_list_changed_construct(Tox_Event_Conference_Peer_List_Changed
*conference_peer_list_changed)
{
*conference_peer_list_changed = (Tox_Event_Conference_Peer_List_Changed) {
0
};
}
static void tox_event_conference_peer_list_changed_destruct(Tox_Event_Conference_Peer_List_Changed
*conference_peer_list_changed)
{
return;
}
static void tox_event_conference_peer_list_changed_set_conference_number(Tox_Event_Conference_Peer_List_Changed
*conference_peer_list_changed, uint32_t conference_number)
{
assert(conference_peer_list_changed != nullptr);
conference_peer_list_changed->conference_number = conference_number;
}
uint32_t tox_event_conference_peer_list_changed_get_conference_number(const Tox_Event_Conference_Peer_List_Changed
*conference_peer_list_changed)
{
assert(conference_peer_list_changed != nullptr);
return conference_peer_list_changed->conference_number;
}
/*****************************************************
*
* :: add/clear/get
*
*****************************************************/
static Tox_Event_Conference_Peer_List_Changed *tox_events_add_conference_peer_list_changed(Tox_Events *events)
{
if (events->conference_peer_list_changed_size == UINT32_MAX) {
return nullptr;
}
if (events->conference_peer_list_changed_size == events->conference_peer_list_changed_capacity) {
const uint32_t new_conference_peer_list_changed_capacity = events->conference_peer_list_changed_capacity * 2 + 1;
Tox_Event_Conference_Peer_List_Changed *new_conference_peer_list_changed = (Tox_Event_Conference_Peer_List_Changed *)
realloc(
events->conference_peer_list_changed,
new_conference_peer_list_changed_capacity * sizeof(Tox_Event_Conference_Peer_List_Changed));
if (new_conference_peer_list_changed == nullptr) {
return nullptr;
}
events->conference_peer_list_changed = new_conference_peer_list_changed;
events->conference_peer_list_changed_capacity = new_conference_peer_list_changed_capacity;
}
Tox_Event_Conference_Peer_List_Changed *const conference_peer_list_changed =
&events->conference_peer_list_changed[events->conference_peer_list_changed_size];
tox_event_conference_peer_list_changed_construct(conference_peer_list_changed);
++events->conference_peer_list_changed_size;
return conference_peer_list_changed;
}
void tox_events_clear_conference_peer_list_changed(Tox_Events *events)
{
if (events == nullptr) {
return;
}
for (uint32_t i = 0; i < events->conference_peer_list_changed_size; ++i) {
tox_event_conference_peer_list_changed_destruct(&events->conference_peer_list_changed[i]);
}
free(events->conference_peer_list_changed);
events->conference_peer_list_changed = nullptr;
events->conference_peer_list_changed_size = 0;
events->conference_peer_list_changed_capacity = 0;
}
uint32_t tox_events_get_conference_peer_list_changed_size(const Tox_Events *events)
{
return events->conference_peer_list_changed_size;
}
const Tox_Event_Conference_Peer_List_Changed *tox_events_get_conference_peer_list_changed(const Tox_Events *events,
uint32_t index)
{
assert(index < events->conference_peer_list_changed_size);
assert(events->conference_peer_list_changed != nullptr);
return &events->conference_peer_list_changed[index];
}
/*****************************************************
*
* :: event handler
*
*****************************************************/
void tox_events_handle_conference_peer_list_changed(Tox *tox, uint32_t conference_number, void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
assert(state != nullptr);
Tox_Event_Conference_Peer_List_Changed *conference_peer_list_changed = tox_events_add_conference_peer_list_changed(
state->events);
if (conference_peer_list_changed == nullptr) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
return;
}
tox_event_conference_peer_list_changed_set_conference_number(conference_peer_list_changed, conference_number);
}

View File

@ -0,0 +1,184 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
*/
#include "events_alloc.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "../ccompat.h"
#include "../tox.h"
#include "../tox_events.h"
/*****************************************************
*
* :: struct and accessors
*
*****************************************************/
struct Tox_Event_Conference_Peer_Name {
uint32_t conference_number;
uint32_t peer_number;
uint8_t *name;
size_t name_length;
};
static void tox_event_conference_peer_name_construct(Tox_Event_Conference_Peer_Name *conference_peer_name)
{
*conference_peer_name = (Tox_Event_Conference_Peer_Name) {
0
};
}
static void tox_event_conference_peer_name_destruct(Tox_Event_Conference_Peer_Name *conference_peer_name)
{
free(conference_peer_name->name);
}
static void tox_event_conference_peer_name_set_conference_number(Tox_Event_Conference_Peer_Name *conference_peer_name,
uint32_t conference_number)
{
assert(conference_peer_name != nullptr);
conference_peer_name->conference_number = conference_number;
}
uint32_t tox_event_conference_peer_name_get_conference_number(const Tox_Event_Conference_Peer_Name
*conference_peer_name)
{
assert(conference_peer_name != nullptr);
return conference_peer_name->conference_number;
}
static void tox_event_conference_peer_name_set_peer_number(Tox_Event_Conference_Peer_Name *conference_peer_name,
uint32_t peer_number)
{
assert(conference_peer_name != nullptr);
conference_peer_name->peer_number = peer_number;
}
uint32_t tox_event_conference_peer_name_get_peer_number(const Tox_Event_Conference_Peer_Name *conference_peer_name)
{
assert(conference_peer_name != nullptr);
return conference_peer_name->peer_number;
}
static bool tox_event_conference_peer_name_set_name(Tox_Event_Conference_Peer_Name *conference_peer_name,
const uint8_t *name, size_t name_length)
{
assert(conference_peer_name != nullptr);
if (conference_peer_name->name != nullptr) {
free(conference_peer_name->name);
conference_peer_name->name = nullptr;
conference_peer_name->name_length = 0;
}
conference_peer_name->name = (uint8_t *)malloc(name_length);
if (conference_peer_name->name == nullptr) {
return false;
}
memcpy(conference_peer_name->name, name, name_length);
conference_peer_name->name_length = name_length;
return true;
}
size_t tox_event_conference_peer_name_get_name_length(const Tox_Event_Conference_Peer_Name *conference_peer_name)
{
assert(conference_peer_name != nullptr);
return conference_peer_name->name_length;
}
const uint8_t *tox_event_conference_peer_name_get_name(const Tox_Event_Conference_Peer_Name *conference_peer_name)
{
assert(conference_peer_name != nullptr);
return conference_peer_name->name;
}
/*****************************************************
*
* :: add/clear/get
*
*****************************************************/
static Tox_Event_Conference_Peer_Name *tox_events_add_conference_peer_name(Tox_Events *events)
{
if (events->conference_peer_name_size == UINT32_MAX) {
return nullptr;
}
if (events->conference_peer_name_size == events->conference_peer_name_capacity) {
const uint32_t new_conference_peer_name_capacity = events->conference_peer_name_capacity * 2 + 1;
Tox_Event_Conference_Peer_Name *new_conference_peer_name = (Tox_Event_Conference_Peer_Name *)realloc(
events->conference_peer_name, new_conference_peer_name_capacity * sizeof(Tox_Event_Conference_Peer_Name));
if (new_conference_peer_name == nullptr) {
return nullptr;
}
events->conference_peer_name = new_conference_peer_name;
events->conference_peer_name_capacity = new_conference_peer_name_capacity;
}
Tox_Event_Conference_Peer_Name *const conference_peer_name =
&events->conference_peer_name[events->conference_peer_name_size];
tox_event_conference_peer_name_construct(conference_peer_name);
++events->conference_peer_name_size;
return conference_peer_name;
}
void tox_events_clear_conference_peer_name(Tox_Events *events)
{
if (events == nullptr) {
return;
}
for (uint32_t i = 0; i < events->conference_peer_name_size; ++i) {
tox_event_conference_peer_name_destruct(&events->conference_peer_name[i]);
}
free(events->conference_peer_name);
events->conference_peer_name = nullptr;
events->conference_peer_name_size = 0;
events->conference_peer_name_capacity = 0;
}
uint32_t tox_events_get_conference_peer_name_size(const Tox_Events *events)
{
return events->conference_peer_name_size;
}
const Tox_Event_Conference_Peer_Name *tox_events_get_conference_peer_name(const Tox_Events *events, uint32_t index)
{
assert(index < events->conference_peer_name_size);
assert(events->conference_peer_name != nullptr);
return &events->conference_peer_name[index];
}
/*****************************************************
*
* :: event handler
*
*****************************************************/
void tox_events_handle_conference_peer_name(Tox *tox, uint32_t conference_number, uint32_t peer_number,
const uint8_t *name, size_t length, void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
assert(state != nullptr);
Tox_Event_Conference_Peer_Name *conference_peer_name = tox_events_add_conference_peer_name(state->events);
if (conference_peer_name == nullptr) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
return;
}
tox_event_conference_peer_name_set_conference_number(conference_peer_name, conference_number);
tox_event_conference_peer_name_set_peer_number(conference_peer_name, peer_number);
tox_event_conference_peer_name_set_name(conference_peer_name, name, length);
}

View File

@ -0,0 +1,182 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
*/
#include "events_alloc.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "../ccompat.h"
#include "../tox.h"
#include "../tox_events.h"
/*****************************************************
*
* :: struct and accessors
*
*****************************************************/
struct Tox_Event_Conference_Title {
uint32_t conference_number;
uint32_t peer_number;
uint8_t *title;
size_t title_length;
};
static void tox_event_conference_title_construct(Tox_Event_Conference_Title *conference_title)
{
*conference_title = (Tox_Event_Conference_Title) {
0
};
}
static void tox_event_conference_title_destruct(Tox_Event_Conference_Title *conference_title)
{
free(conference_title->title);
}
static void tox_event_conference_title_set_conference_number(Tox_Event_Conference_Title *conference_title,
uint32_t conference_number)
{
assert(conference_title != nullptr);
conference_title->conference_number = conference_number;
}
uint32_t tox_event_conference_title_get_conference_number(const Tox_Event_Conference_Title *conference_title)
{
assert(conference_title != nullptr);
return conference_title->conference_number;
}
static void tox_event_conference_title_set_peer_number(Tox_Event_Conference_Title *conference_title,
uint32_t peer_number)
{
assert(conference_title != nullptr);
conference_title->peer_number = peer_number;
}
uint32_t tox_event_conference_title_get_peer_number(const Tox_Event_Conference_Title *conference_title)
{
assert(conference_title != nullptr);
return conference_title->peer_number;
}
static bool tox_event_conference_title_set_title(Tox_Event_Conference_Title *conference_title, const uint8_t *title,
size_t title_length)
{
assert(conference_title != nullptr);
if (conference_title->title != nullptr) {
free(conference_title->title);
conference_title->title = nullptr;
conference_title->title_length = 0;
}
conference_title->title = (uint8_t *)malloc(title_length);
if (conference_title->title == nullptr) {
return false;
}
memcpy(conference_title->title, title, title_length);
conference_title->title_length = title_length;
return true;
}
size_t tox_event_conference_title_get_title_length(const Tox_Event_Conference_Title *conference_title)
{
assert(conference_title != nullptr);
return conference_title->title_length;
}
const uint8_t *tox_event_conference_title_get_title(const Tox_Event_Conference_Title *conference_title)
{
assert(conference_title != nullptr);
return conference_title->title;
}
/*****************************************************
*
* :: add/clear/get
*
*****************************************************/
static Tox_Event_Conference_Title *tox_events_add_conference_title(Tox_Events *events)
{
if (events->conference_title_size == UINT32_MAX) {
return nullptr;
}
if (events->conference_title_size == events->conference_title_capacity) {
const uint32_t new_conference_title_capacity = events->conference_title_capacity * 2 + 1;
Tox_Event_Conference_Title *new_conference_title = (Tox_Event_Conference_Title *)realloc(
events->conference_title, new_conference_title_capacity * sizeof(Tox_Event_Conference_Title));
if (new_conference_title == nullptr) {
return nullptr;
}
events->conference_title = new_conference_title;
events->conference_title_capacity = new_conference_title_capacity;
}
Tox_Event_Conference_Title *const conference_title = &events->conference_title[events->conference_title_size];
tox_event_conference_title_construct(conference_title);
++events->conference_title_size;
return conference_title;
}
void tox_events_clear_conference_title(Tox_Events *events)
{
if (events == nullptr) {
return;
}
for (uint32_t i = 0; i < events->conference_title_size; ++i) {
tox_event_conference_title_destruct(&events->conference_title[i]);
}
free(events->conference_title);
events->conference_title = nullptr;
events->conference_title_size = 0;
events->conference_title_capacity = 0;
}
uint32_t tox_events_get_conference_title_size(const Tox_Events *events)
{
return events->conference_title_size;
}
const Tox_Event_Conference_Title *tox_events_get_conference_title(const Tox_Events *events, uint32_t index)
{
assert(index < events->conference_title_size);
assert(events->conference_title != nullptr);
return &events->conference_title[index];
}
/*****************************************************
*
* :: event handler
*
*****************************************************/
void tox_events_handle_conference_title(Tox *tox, uint32_t conference_number, uint32_t peer_number,
const uint8_t *title, size_t length, void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
assert(state != nullptr);
Tox_Event_Conference_Title *conference_title = tox_events_add_conference_title(state->events);
if (conference_title == nullptr) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
return;
}
tox_event_conference_title_set_conference_number(conference_title, conference_number);
tox_event_conference_title_set_peer_number(conference_title, peer_number);
tox_event_conference_title_set_title(conference_title, title, length);
}

View File

@ -0,0 +1,64 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
*/
#include "events_alloc.h"
#include <assert.h>
#include <stdlib.h>
#include "../ccompat.h"
Tox_Events_State *tox_events_alloc(void *user_data)
{
Tox_Events_State *state = (Tox_Events_State *)user_data;
assert(state != nullptr);
if (state->events != nullptr) {
// Already allocated.
return state;
}
state->events = (Tox_Events *)calloc(1, sizeof(Tox_Events));
if (state->events == nullptr) {
// It's still null => allocation failed.
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
} else {
*state->events = (Tox_Events) {
nullptr
};
}
return state;
}
void tox_events_free(Tox_Events *events)
{
if (events == nullptr) {
return;
}
tox_events_clear_conference_connected(events);
tox_events_clear_conference_invite(events);
tox_events_clear_conference_message(events);
tox_events_clear_conference_peer_list_changed(events);
tox_events_clear_conference_peer_name(events);
tox_events_clear_conference_title(events);
tox_events_clear_file_chunk_request(events);
tox_events_clear_file_recv_chunk(events);
tox_events_clear_file_recv_control(events);
tox_events_clear_file_recv(events);
tox_events_clear_friend_connection_status(events);
tox_events_clear_friend_lossless_packet(events);
tox_events_clear_friend_lossy_packet(events);
tox_events_clear_friend_message(events);
tox_events_clear_friend_name(events);
tox_events_clear_friend_read_receipt(events);
tox_events_clear_friend_request(events);
tox_events_clear_friend_status(events);
tox_events_clear_friend_status_message(events);
tox_events_clear_friend_typing(events);
tox_events_clear_self_connection_status(events);
free(events);
}

View File

@ -0,0 +1,155 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
*/
#ifndef C_TOXCORE_TOXCORE_TOX_EVENTS_INTERNAL_H
#define C_TOXCORE_TOXCORE_TOX_EVENTS_INTERNAL_H
#include "../tox_events.h"
#ifdef __cplusplus
extern "C" {
#endif
struct Tox_Events {
Tox_Event_Conference_Connected *conference_connected;
uint32_t conference_connected_size;
uint32_t conference_connected_capacity;
Tox_Event_Conference_Invite *conference_invite;
uint32_t conference_invite_size;
uint32_t conference_invite_capacity;
Tox_Event_Conference_Message *conference_message;
uint32_t conference_message_size;
uint32_t conference_message_capacity;
Tox_Event_Conference_Peer_List_Changed *conference_peer_list_changed;
uint32_t conference_peer_list_changed_size;
uint32_t conference_peer_list_changed_capacity;
Tox_Event_Conference_Peer_Name *conference_peer_name;
uint32_t conference_peer_name_size;
uint32_t conference_peer_name_capacity;
Tox_Event_Conference_Title *conference_title;
uint32_t conference_title_size;
uint32_t conference_title_capacity;
Tox_Event_File_Chunk_Request *file_chunk_request;
uint32_t file_chunk_request_size;
uint32_t file_chunk_request_capacity;
Tox_Event_File_Recv *file_recv;
uint32_t file_recv_size;
uint32_t file_recv_capacity;
Tox_Event_File_Recv_Chunk *file_recv_chunk;
uint32_t file_recv_chunk_size;
uint32_t file_recv_chunk_capacity;
Tox_Event_File_Recv_Control *file_recv_control;
uint32_t file_recv_control_size;
uint32_t file_recv_control_capacity;
Tox_Event_Friend_Connection_Status *friend_connection_status;
uint32_t friend_connection_status_size;
uint32_t friend_connection_status_capacity;
Tox_Event_Friend_Lossless_Packet *friend_lossless_packet;
uint32_t friend_lossless_packet_size;
uint32_t friend_lossless_packet_capacity;
Tox_Event_Friend_Lossy_Packet *friend_lossy_packet;
uint32_t friend_lossy_packet_size;
uint32_t friend_lossy_packet_capacity;
Tox_Event_Friend_Message *friend_message;
uint32_t friend_message_size;
uint32_t friend_message_capacity;
Tox_Event_Friend_Name *friend_name;
uint32_t friend_name_size;
uint32_t friend_name_capacity;
Tox_Event_Friend_Read_Receipt *friend_read_receipt;
uint32_t friend_read_receipt_size;
uint32_t friend_read_receipt_capacity;
Tox_Event_Friend_Request *friend_request;
uint32_t friend_request_size;
uint32_t friend_request_capacity;
Tox_Event_Friend_Status *friend_status;
uint32_t friend_status_size;
uint32_t friend_status_capacity;
Tox_Event_Friend_Status_Message *friend_status_message;
uint32_t friend_status_message_size;
uint32_t friend_status_message_capacity;
Tox_Event_Friend_Typing *friend_typing;
uint32_t friend_typing_size;
uint32_t friend_typing_capacity;
Tox_Event_Self_Connection_Status *self_connection_status;
uint32_t self_connection_status_size;
uint32_t self_connection_status_capacity;
};
typedef struct Tox_Events_State {
Tox_Err_Events_Iterate error;
Tox_Events *events;
} Tox_Events_State;
tox_conference_connected_cb tox_events_handle_conference_connected;
tox_conference_invite_cb tox_events_handle_conference_invite;
tox_conference_message_cb tox_events_handle_conference_message;
tox_conference_peer_list_changed_cb tox_events_handle_conference_peer_list_changed;
tox_conference_peer_name_cb tox_events_handle_conference_peer_name;
tox_conference_title_cb tox_events_handle_conference_title;
tox_file_chunk_request_cb tox_events_handle_file_chunk_request;
tox_file_recv_cb tox_events_handle_file_recv;
tox_file_recv_chunk_cb tox_events_handle_file_recv_chunk;
tox_file_recv_control_cb tox_events_handle_file_recv_control;
tox_friend_connection_status_cb tox_events_handle_friend_connection_status;
tox_friend_lossless_packet_cb tox_events_handle_friend_lossless_packet;
tox_friend_lossy_packet_cb tox_events_handle_friend_lossy_packet;
tox_friend_message_cb tox_events_handle_friend_message;
tox_friend_name_cb tox_events_handle_friend_name;
tox_friend_read_receipt_cb tox_events_handle_friend_read_receipt;
tox_friend_request_cb tox_events_handle_friend_request;
tox_friend_status_cb tox_events_handle_friend_status;
tox_friend_status_message_cb tox_events_handle_friend_status_message;
tox_friend_typing_cb tox_events_handle_friend_typing;
tox_self_connection_status_cb tox_events_handle_self_connection_status;
void tox_events_clear_conference_connected(Tox_Events *events);
void tox_events_clear_conference_invite(Tox_Events *events);
void tox_events_clear_conference_message(Tox_Events *events);
void tox_events_clear_conference_peer_list_changed(Tox_Events *events);
void tox_events_clear_conference_peer_name(Tox_Events *events);
void tox_events_clear_conference_title(Tox_Events *events);
void tox_events_clear_file_chunk_request(Tox_Events *events);
void tox_events_clear_file_recv_chunk(Tox_Events *events);
void tox_events_clear_file_recv_control(Tox_Events *events);
void tox_events_clear_file_recv(Tox_Events *events);
void tox_events_clear_friend_connection_status(Tox_Events *events);
void tox_events_clear_friend_lossless_packet(Tox_Events *events);
void tox_events_clear_friend_lossy_packet(Tox_Events *events);
void tox_events_clear_friend_message(Tox_Events *events);
void tox_events_clear_friend_name(Tox_Events *events);
void tox_events_clear_friend_read_receipt(Tox_Events *events);
void tox_events_clear_friend_request(Tox_Events *events);
void tox_events_clear_friend_status_message(Tox_Events *events);
void tox_events_clear_friend_status(Tox_Events *events);
void tox_events_clear_friend_typing(Tox_Events *events);
void tox_events_clear_self_connection_status(Tox_Events *events);
Tox_Events_State *tox_events_alloc(void *user_data);
#ifdef __cplusplus
}
#endif
#endif // C_TOXCORE_TOXCORE_TOX_EVENTS_INTERNAL_H

View File

@ -0,0 +1,174 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
*/
#include "events_alloc.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "../ccompat.h"
#include "../tox.h"
#include "../tox_events.h"
/*****************************************************
*
* :: struct and accessors
*
*****************************************************/
struct Tox_Event_File_Chunk_Request {
uint32_t friend_number;
uint32_t file_number;
uint64_t position;
size_t length;
};
static void tox_event_file_chunk_request_construct(Tox_Event_File_Chunk_Request *file_chunk_request)
{
*file_chunk_request = (Tox_Event_File_Chunk_Request) {
0
};
}
static void tox_event_file_chunk_request_destruct(Tox_Event_File_Chunk_Request *file_chunk_request)
{
return;
}
static void tox_event_file_chunk_request_set_friend_number(Tox_Event_File_Chunk_Request *file_chunk_request,
uint32_t friend_number)
{
assert(file_chunk_request != nullptr);
file_chunk_request->friend_number = friend_number;
}
uint32_t tox_event_file_chunk_request_get_friend_number(const Tox_Event_File_Chunk_Request *file_chunk_request)
{
assert(file_chunk_request != nullptr);
return file_chunk_request->friend_number;
}
static void tox_event_file_chunk_request_set_file_number(Tox_Event_File_Chunk_Request *file_chunk_request,
uint32_t file_number)
{
assert(file_chunk_request != nullptr);
file_chunk_request->file_number = file_number;
}
uint32_t tox_event_file_chunk_request_get_file_number(const Tox_Event_File_Chunk_Request *file_chunk_request)
{
assert(file_chunk_request != nullptr);
return file_chunk_request->file_number;
}
static void tox_event_file_chunk_request_set_position(Tox_Event_File_Chunk_Request *file_chunk_request,
uint64_t position)
{
assert(file_chunk_request != nullptr);
file_chunk_request->position = position;
}
uint64_t tox_event_file_chunk_request_get_position(const Tox_Event_File_Chunk_Request *file_chunk_request)
{
assert(file_chunk_request != nullptr);
return file_chunk_request->position;
}
static void tox_event_file_chunk_request_set_length(Tox_Event_File_Chunk_Request *file_chunk_request, size_t length)
{
assert(file_chunk_request != nullptr);
file_chunk_request->length = length;
}
size_t tox_event_file_chunk_request_get_length(const Tox_Event_File_Chunk_Request *file_chunk_request)
{
assert(file_chunk_request != nullptr);
return file_chunk_request->length;
}
/*****************************************************
*
* :: add/clear/get
*
*****************************************************/
static Tox_Event_File_Chunk_Request *tox_events_add_file_chunk_request(Tox_Events *events)
{
if (events->file_chunk_request_size == UINT32_MAX) {
return nullptr;
}
if (events->file_chunk_request_size == events->file_chunk_request_capacity) {
const uint32_t new_file_chunk_request_capacity = events->file_chunk_request_capacity * 2 + 1;
Tox_Event_File_Chunk_Request *new_file_chunk_request = (Tox_Event_File_Chunk_Request *)realloc(
events->file_chunk_request, new_file_chunk_request_capacity * sizeof(Tox_Event_File_Chunk_Request));
if (new_file_chunk_request == nullptr) {
return nullptr;
}
events->file_chunk_request = new_file_chunk_request;
events->file_chunk_request_capacity = new_file_chunk_request_capacity;
}
Tox_Event_File_Chunk_Request *const file_chunk_request = &events->file_chunk_request[events->file_chunk_request_size];
tox_event_file_chunk_request_construct(file_chunk_request);
++events->file_chunk_request_size;
return file_chunk_request;
}
void tox_events_clear_file_chunk_request(Tox_Events *events)
{
if (events == nullptr) {
return;
}
for (uint32_t i = 0; i < events->file_chunk_request_size; ++i) {
tox_event_file_chunk_request_destruct(&events->file_chunk_request[i]);
}
free(events->file_chunk_request);
events->file_chunk_request = nullptr;
events->file_chunk_request_size = 0;
events->file_chunk_request_capacity = 0;
}
uint32_t tox_events_get_file_chunk_request_size(const Tox_Events *events)
{
return events->file_chunk_request_size;
}
const Tox_Event_File_Chunk_Request *tox_events_get_file_chunk_request(const Tox_Events *events, uint32_t index)
{
assert(index < events->file_chunk_request_size);
assert(events->file_chunk_request != nullptr);
return &events->file_chunk_request[index];
}
/*****************************************************
*
* :: event handler
*
*****************************************************/
void tox_events_handle_file_chunk_request(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position,
size_t length, void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
assert(state != nullptr);
Tox_Event_File_Chunk_Request *file_chunk_request = tox_events_add_file_chunk_request(state->events);
if (file_chunk_request == nullptr) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
return;
}
tox_event_file_chunk_request_set_friend_number(file_chunk_request, friend_number);
tox_event_file_chunk_request_set_file_number(file_chunk_request, file_number);
tox_event_file_chunk_request_set_position(file_chunk_request, position);
tox_event_file_chunk_request_set_length(file_chunk_request, length);
}

210
toxcore/events/file_recv.c Normal file
View File

@ -0,0 +1,210 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
*/
#include "events_alloc.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "../ccompat.h"
#include "../tox.h"
#include "../tox_events.h"
/*****************************************************
*
* :: struct and accessors
*
*****************************************************/
struct Tox_Event_File_Recv {
uint32_t friend_number;
uint32_t file_number;
uint32_t kind;
uint64_t file_size;
uint8_t *filename;
size_t filename_length;
};
static void tox_event_file_recv_construct(Tox_Event_File_Recv *file_recv)
{
*file_recv = (Tox_Event_File_Recv) {
0
};
}
static void tox_event_file_recv_destruct(Tox_Event_File_Recv *file_recv)
{
free(file_recv->filename);
}
static void tox_event_file_recv_set_friend_number(Tox_Event_File_Recv *file_recv,
uint32_t friend_number)
{
assert(file_recv != nullptr);
file_recv->friend_number = friend_number;
}
uint32_t tox_event_file_recv_get_friend_number(const Tox_Event_File_Recv *file_recv)
{
assert(file_recv != nullptr);
return file_recv->friend_number;
}
static void tox_event_file_recv_set_file_number(Tox_Event_File_Recv *file_recv,
uint32_t file_number)
{
assert(file_recv != nullptr);
file_recv->file_number = file_number;
}
uint32_t tox_event_file_recv_get_file_number(const Tox_Event_File_Recv *file_recv)
{
assert(file_recv != nullptr);
return file_recv->file_number;
}
static void tox_event_file_recv_set_kind(Tox_Event_File_Recv *file_recv,
uint32_t kind)
{
assert(file_recv != nullptr);
file_recv->kind = kind;
}
uint32_t tox_event_file_recv_get_kind(const Tox_Event_File_Recv *file_recv)
{
assert(file_recv != nullptr);
return file_recv->kind;
}
static void tox_event_file_recv_set_file_size(Tox_Event_File_Recv *file_recv,
uint32_t file_size)
{
assert(file_recv != nullptr);
file_recv->file_size = file_size;
}
uint32_t tox_event_file_recv_get_file_size(const Tox_Event_File_Recv *file_recv)
{
assert(file_recv != nullptr);
return file_recv->file_size;
}
static bool tox_event_file_recv_set_filename(Tox_Event_File_Recv *file_recv, const uint8_t *filename,
size_t filename_length)
{
assert(file_recv != nullptr);
if (file_recv->filename != nullptr) {
free(file_recv->filename);
file_recv->filename = nullptr;
file_recv->filename_length = 0;
}
file_recv->filename = (uint8_t *)malloc(filename_length);
if (file_recv->filename == nullptr) {
return false;
}
memcpy(file_recv->filename, filename, filename_length);
file_recv->filename_length = filename_length;
return true;
}
size_t tox_event_file_recv_get_filename_length(const Tox_Event_File_Recv *file_recv)
{
assert(file_recv != nullptr);
return file_recv->filename_length;
}
const uint8_t *tox_event_file_recv_get_filename(const Tox_Event_File_Recv *file_recv)
{
assert(file_recv != nullptr);
return file_recv->filename;
}
/*****************************************************
*
* :: add/clear/get
*
*****************************************************/
static Tox_Event_File_Recv *tox_events_add_file_recv(Tox_Events *events)
{
if (events->file_recv_size == UINT32_MAX) {
return nullptr;
}
if (events->file_recv_size == events->file_recv_capacity) {
const uint32_t new_file_recv_capacity = events->file_recv_capacity * 2 + 1;
Tox_Event_File_Recv *new_file_recv = (Tox_Event_File_Recv *)realloc(
events->file_recv, new_file_recv_capacity * sizeof(Tox_Event_File_Recv));
if (new_file_recv == nullptr) {
return nullptr;
}
events->file_recv = new_file_recv;
events->file_recv_capacity = new_file_recv_capacity;
}
Tox_Event_File_Recv *const file_recv = &events->file_recv[events->file_recv_size];
tox_event_file_recv_construct(file_recv);
++events->file_recv_size;
return file_recv;
}
void tox_events_clear_file_recv(Tox_Events *events)
{
if (events == nullptr) {
return;
}
for (uint32_t i = 0; i < events->file_recv_size; ++i) {
tox_event_file_recv_destruct(&events->file_recv[i]);
}
free(events->file_recv);
events->file_recv = nullptr;
events->file_recv_size = 0;
events->file_recv_capacity = 0;
}
uint32_t tox_events_get_file_recv_size(const Tox_Events *events)
{
return events->file_recv_size;
}
const Tox_Event_File_Recv *tox_events_get_file_recv(const Tox_Events *events, uint32_t index)
{
assert(index < events->file_recv_size);
assert(events->file_recv != nullptr);
return &events->file_recv[index];
}
/*****************************************************
*
* :: event handler
*
*****************************************************/
void tox_events_handle_file_recv(Tox *tox, uint32_t friend_number, uint32_t file_number, uint32_t kind,
uint64_t file_size, const uint8_t *filename, size_t filename_length, void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
assert(state != nullptr);
Tox_Event_File_Recv *file_recv = tox_events_add_file_recv(state->events);
if (file_recv == nullptr) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
return;
}
tox_event_file_recv_set_friend_number(file_recv, friend_number);
tox_event_file_recv_set_file_number(file_recv, file_number);
tox_event_file_recv_set_kind(file_recv, kind);
tox_event_file_recv_set_file_size(file_recv, file_size);
tox_event_file_recv_set_filename(file_recv, filename, filename_length);
}

View File

@ -0,0 +1,196 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
*/
#include "events_alloc.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "../ccompat.h"
#include "../tox.h"
#include "../tox_events.h"
/*****************************************************
*
* :: struct and accessors
*
*****************************************************/
struct Tox_Event_File_Recv_Chunk {
uint32_t friend_number;
uint32_t file_number;
uint64_t position;
uint8_t *data;
size_t data_length;
};
static void tox_event_file_recv_chunk_construct(Tox_Event_File_Recv_Chunk *file_recv_chunk)
{
*file_recv_chunk = (Tox_Event_File_Recv_Chunk) {
0
};
}
static void tox_event_file_recv_chunk_destruct(Tox_Event_File_Recv_Chunk *file_recv_chunk)
{
free(file_recv_chunk->data);
}
static void tox_event_file_recv_chunk_set_friend_number(Tox_Event_File_Recv_Chunk *file_recv_chunk,
uint32_t friend_number)
{
assert(file_recv_chunk != nullptr);
file_recv_chunk->friend_number = friend_number;
}
uint32_t tox_event_file_recv_chunk_get_friend_number(const Tox_Event_File_Recv_Chunk *file_recv_chunk)
{
assert(file_recv_chunk != nullptr);
return file_recv_chunk->friend_number;
}
static void tox_event_file_recv_chunk_set_file_number(Tox_Event_File_Recv_Chunk *file_recv_chunk,
uint32_t file_number)
{
assert(file_recv_chunk != nullptr);
file_recv_chunk->file_number = file_number;
}
uint32_t tox_event_file_recv_chunk_get_file_number(const Tox_Event_File_Recv_Chunk *file_recv_chunk)
{
assert(file_recv_chunk != nullptr);
return file_recv_chunk->file_number;
}
static void tox_event_file_recv_chunk_set_position(Tox_Event_File_Recv_Chunk *file_recv_chunk,
uint32_t position)
{
assert(file_recv_chunk != nullptr);
file_recv_chunk->position = position;
}
uint32_t tox_event_file_recv_chunk_get_position(const Tox_Event_File_Recv_Chunk *file_recv_chunk)
{
assert(file_recv_chunk != nullptr);
return file_recv_chunk->position;
}
static bool tox_event_file_recv_chunk_set_data(Tox_Event_File_Recv_Chunk *file_recv_chunk, const uint8_t *data,
size_t data_length)
{
assert(file_recv_chunk != nullptr);
if (file_recv_chunk->data != nullptr) {
free(file_recv_chunk->data);
file_recv_chunk->data = nullptr;
file_recv_chunk->data_length = 0;
}
file_recv_chunk->data = (uint8_t *)malloc(data_length);
if (file_recv_chunk->data == nullptr) {
return false;
}
memcpy(file_recv_chunk->data, data, data_length);
file_recv_chunk->data_length = data_length;
return true;
}
size_t tox_event_file_recv_chunk_get_length(const Tox_Event_File_Recv_Chunk *file_recv_chunk)
{
assert(file_recv_chunk != nullptr);
return file_recv_chunk->data_length;
}
const uint8_t *tox_event_file_recv_chunk_get_data(const Tox_Event_File_Recv_Chunk *file_recv_chunk)
{
assert(file_recv_chunk != nullptr);
return file_recv_chunk->data;
}
/*****************************************************
*
* :: add/clear/get
*
*****************************************************/
static Tox_Event_File_Recv_Chunk *tox_events_add_file_recv_chunk(Tox_Events *events)
{
if (events->file_recv_chunk_size == UINT32_MAX) {
return nullptr;
}
if (events->file_recv_chunk_size == events->file_recv_chunk_capacity) {
const uint32_t new_file_recv_chunk_capacity = events->file_recv_chunk_capacity * 2 + 1;
Tox_Event_File_Recv_Chunk *new_file_recv_chunk = (Tox_Event_File_Recv_Chunk *)realloc(
events->file_recv_chunk, new_file_recv_chunk_capacity * sizeof(Tox_Event_File_Recv_Chunk));
if (new_file_recv_chunk == nullptr) {
return nullptr;
}
events->file_recv_chunk = new_file_recv_chunk;
events->file_recv_chunk_capacity = new_file_recv_chunk_capacity;
}
Tox_Event_File_Recv_Chunk *const file_recv_chunk = &events->file_recv_chunk[events->file_recv_chunk_size];
tox_event_file_recv_chunk_construct(file_recv_chunk);
++events->file_recv_chunk_size;
return file_recv_chunk;
}
void tox_events_clear_file_recv_chunk(Tox_Events *events)
{
if (events == nullptr) {
return;
}
for (uint32_t i = 0; i < events->file_recv_chunk_size; ++i) {
tox_event_file_recv_chunk_destruct(&events->file_recv_chunk[i]);
}
free(events->file_recv_chunk);
events->file_recv_chunk = nullptr;
events->file_recv_chunk_size = 0;
events->file_recv_chunk_capacity = 0;
}
uint32_t tox_events_get_file_recv_chunk_size(const Tox_Events *events)
{
return events->file_recv_chunk_size;
}
const Tox_Event_File_Recv_Chunk *tox_events_get_file_recv_chunk(const Tox_Events *events, uint32_t index)
{
assert(index < events->file_recv_chunk_size);
assert(events->file_recv_chunk != nullptr);
return &events->file_recv_chunk[index];
}
/*****************************************************
*
* :: event handler
*
*****************************************************/
void tox_events_handle_file_recv_chunk(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position,
const uint8_t *data, size_t length, void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
assert(state != nullptr);
Tox_Event_File_Recv_Chunk *file_recv_chunk = tox_events_add_file_recv_chunk(state->events);
if (file_recv_chunk == nullptr) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
return;
}
tox_event_file_recv_chunk_set_friend_number(file_recv_chunk, friend_number);
tox_event_file_recv_chunk_set_file_number(file_recv_chunk, file_number);
tox_event_file_recv_chunk_set_position(file_recv_chunk, position);
tox_event_file_recv_chunk_set_data(file_recv_chunk, data, length);
}

View File

@ -0,0 +1,161 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
*/
#include "events_alloc.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "../ccompat.h"
#include "../tox.h"
#include "../tox_events.h"
/*****************************************************
*
* :: struct and accessors
*
*****************************************************/
struct Tox_Event_File_Recv_Control {
uint32_t friend_number;
uint32_t file_number;
Tox_File_Control control;
};
static void tox_event_file_recv_control_construct(Tox_Event_File_Recv_Control *file_recv_control)
{
*file_recv_control = (Tox_Event_File_Recv_Control) {
0
};
}
static void tox_event_file_recv_control_destruct(Tox_Event_File_Recv_Control *file_recv_control)
{
return;
}
static void tox_event_file_recv_control_set_friend_number(Tox_Event_File_Recv_Control *file_recv_control,
uint32_t friend_number)
{
assert(file_recv_control != nullptr);
file_recv_control->friend_number = friend_number;
}
uint32_t tox_event_file_recv_control_get_friend_number(const Tox_Event_File_Recv_Control *file_recv_control)
{
assert(file_recv_control != nullptr);
return file_recv_control->friend_number;
}
static void tox_event_file_recv_control_set_file_number(Tox_Event_File_Recv_Control *file_recv_control,
uint32_t file_number)
{
assert(file_recv_control != nullptr);
file_recv_control->file_number = file_number;
}
uint32_t tox_event_file_recv_control_get_file_number(const Tox_Event_File_Recv_Control *file_recv_control)
{
assert(file_recv_control != nullptr);
return file_recv_control->file_number;
}
static void tox_event_file_recv_control_set_control(Tox_Event_File_Recv_Control *file_recv_control,
Tox_File_Control control)
{
assert(file_recv_control != nullptr);
file_recv_control->control = control;
}
Tox_File_Control tox_event_file_recv_control_get_control(const Tox_Event_File_Recv_Control *file_recv_control)
{
assert(file_recv_control != nullptr);
return file_recv_control->control;
}
/*****************************************************
*
* :: add/clear/get
*
*****************************************************/
static Tox_Event_File_Recv_Control *tox_events_add_file_recv_control(Tox_Events *events)
{
if (events->file_recv_control_size == UINT32_MAX) {
return nullptr;
}
if (events->file_recv_control_size == events->file_recv_control_capacity) {
const uint32_t new_file_recv_control_capacity = events->file_recv_control_capacity * 2 + 1;
Tox_Event_File_Recv_Control *new_file_recv_control = (Tox_Event_File_Recv_Control *)realloc(
events->file_recv_control, new_file_recv_control_capacity * sizeof(Tox_Event_File_Recv_Control));
if (new_file_recv_control == nullptr) {
return nullptr;
}
events->file_recv_control = new_file_recv_control;
events->file_recv_control_capacity = new_file_recv_control_capacity;
}
Tox_Event_File_Recv_Control *const file_recv_control = &events->file_recv_control[events->file_recv_control_size];
tox_event_file_recv_control_construct(file_recv_control);
++events->file_recv_control_size;
return file_recv_control;
}
void tox_events_clear_file_recv_control(Tox_Events *events)
{
if (events == nullptr) {
return;
}
for (uint32_t i = 0; i < events->file_recv_control_size; ++i) {
tox_event_file_recv_control_destruct(&events->file_recv_control[i]);
}
free(events->file_recv_control);
events->file_recv_control = nullptr;
events->file_recv_control_size = 0;
events->file_recv_control_capacity = 0;
}
uint32_t tox_events_get_file_recv_control_size(const Tox_Events *events)
{
return events->file_recv_control_size;
}
const Tox_Event_File_Recv_Control *tox_events_get_file_recv_control(const Tox_Events *events, uint32_t index)
{
assert(index < events->file_recv_control_size);
assert(events->file_recv_control != nullptr);
return &events->file_recv_control[index];
}
/*****************************************************
*
* :: event handler
*
*****************************************************/
void tox_events_handle_file_recv_control(Tox *tox, uint32_t friend_number, uint32_t file_number,
Tox_File_Control control, void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
assert(state != nullptr);
Tox_Event_File_Recv_Control *file_recv_control = tox_events_add_file_recv_control(state->events);
if (file_recv_control == nullptr) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
return;
}
tox_event_file_recv_control_set_friend_number(file_recv_control, friend_number);
tox_event_file_recv_control_set_file_number(file_recv_control, file_number);
tox_event_file_recv_control_set_control(file_recv_control, control);
}

View File

@ -0,0 +1,151 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
*/
#include "events_alloc.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "../ccompat.h"
#include "../tox.h"
#include "../tox_events.h"
/*****************************************************
*
* :: struct and accessors
*
*****************************************************/
struct Tox_Event_Friend_Connection_Status {
uint32_t friend_number;
Tox_Connection connection_status;
};
static void tox_event_friend_connection_status_construct(Tox_Event_Friend_Connection_Status *friend_connection_status)
{
*friend_connection_status = (Tox_Event_Friend_Connection_Status) {
0
};
}
static void tox_event_friend_connection_status_destruct(Tox_Event_Friend_Connection_Status *friend_connection_status)
{
return;
}
static void tox_event_friend_connection_status_set_friend_number(Tox_Event_Friend_Connection_Status
*friend_connection_status, uint32_t friend_number)
{
assert(friend_connection_status != nullptr);
friend_connection_status->friend_number = friend_number;
}
uint32_t tox_event_friend_connection_status_get_friend_number(const Tox_Event_Friend_Connection_Status
*friend_connection_status)
{
assert(friend_connection_status != nullptr);
return friend_connection_status->friend_number;
}
static void tox_event_friend_connection_status_set_connection_status(Tox_Event_Friend_Connection_Status
*friend_connection_status, Tox_Connection connection_status)
{
assert(friend_connection_status != nullptr);
friend_connection_status->connection_status = connection_status;
}
Tox_Connection tox_event_friend_connection_status_get_connection_status(const Tox_Event_Friend_Connection_Status
*friend_connection_status)
{
assert(friend_connection_status != nullptr);
return friend_connection_status->connection_status;
}
/*****************************************************
*
* :: add/clear/get
*
*****************************************************/
static Tox_Event_Friend_Connection_Status *tox_events_add_friend_connection_status(Tox_Events *events)
{
if (events->friend_connection_status_size == UINT32_MAX) {
return nullptr;
}
if (events->friend_connection_status_size == events->friend_connection_status_capacity) {
const uint32_t new_friend_connection_status_capacity = events->friend_connection_status_capacity * 2 + 1;
Tox_Event_Friend_Connection_Status *new_friend_connection_status = (Tox_Event_Friend_Connection_Status *)realloc(
events->friend_connection_status, new_friend_connection_status_capacity * sizeof(Tox_Event_Friend_Connection_Status));
if (new_friend_connection_status == nullptr) {
return nullptr;
}
events->friend_connection_status = new_friend_connection_status;
events->friend_connection_status_capacity = new_friend_connection_status_capacity;
}
Tox_Event_Friend_Connection_Status *const friend_connection_status =
&events->friend_connection_status[events->friend_connection_status_size];
tox_event_friend_connection_status_construct(friend_connection_status);
++events->friend_connection_status_size;
return friend_connection_status;
}
void tox_events_clear_friend_connection_status(Tox_Events *events)
{
if (events == nullptr) {
return;
}
for (uint32_t i = 0; i < events->friend_connection_status_size; ++i) {
tox_event_friend_connection_status_destruct(&events->friend_connection_status[i]);
}
free(events->friend_connection_status);
events->friend_connection_status = nullptr;
events->friend_connection_status_size = 0;
events->friend_connection_status_capacity = 0;
}
uint32_t tox_events_get_friend_connection_status_size(const Tox_Events *events)
{
return events->friend_connection_status_size;
}
const Tox_Event_Friend_Connection_Status *tox_events_get_friend_connection_status(const Tox_Events *events,
uint32_t index)
{
assert(index < events->friend_connection_status_size);
assert(events->friend_connection_status != nullptr);
return &events->friend_connection_status[index];
}
/*****************************************************
*
* :: event handler
*
*****************************************************/
void tox_events_handle_friend_connection_status(Tox *tox, uint32_t friend_number, Tox_Connection connection_status,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
assert(state != nullptr);
Tox_Event_Friend_Connection_Status *friend_connection_status = tox_events_add_friend_connection_status(state->events);
if (friend_connection_status == nullptr) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
return;
}
tox_event_friend_connection_status_set_friend_number(friend_connection_status, friend_number);
tox_event_friend_connection_status_set_connection_status(friend_connection_status, connection_status);
}

View File

@ -0,0 +1,170 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
*/
#include "events_alloc.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "../ccompat.h"
#include "../tox.h"
#include "../tox_events.h"
/*****************************************************
*
* :: struct and accessors
*
*****************************************************/
struct Tox_Event_Friend_Lossless_Packet {
uint32_t friend_number;
uint8_t *data;
size_t data_length;
};
static void tox_event_friend_lossless_packet_construct(Tox_Event_Friend_Lossless_Packet *friend_lossless_packet)
{
*friend_lossless_packet = (Tox_Event_Friend_Lossless_Packet) {
0
};
}
static void tox_event_friend_lossless_packet_destruct(Tox_Event_Friend_Lossless_Packet *friend_lossless_packet)
{
free(friend_lossless_packet->data);
}
static void tox_event_friend_lossless_packet_set_friend_number(Tox_Event_Friend_Lossless_Packet *friend_lossless_packet,
uint32_t friend_number)
{
assert(friend_lossless_packet != nullptr);
friend_lossless_packet->friend_number = friend_number;
}
uint32_t tox_event_friend_lossless_packet_get_friend_number(const Tox_Event_Friend_Lossless_Packet
*friend_lossless_packet)
{
assert(friend_lossless_packet != nullptr);
return friend_lossless_packet->friend_number;
}
static bool tox_event_friend_lossless_packet_set_data(Tox_Event_Friend_Lossless_Packet *friend_lossless_packet,
const uint8_t *data, size_t data_length)
{
assert(friend_lossless_packet != nullptr);
if (friend_lossless_packet->data != nullptr) {
free(friend_lossless_packet->data);
friend_lossless_packet->data = nullptr;
friend_lossless_packet->data_length = 0;
}
friend_lossless_packet->data = (uint8_t *)malloc(data_length);
if (friend_lossless_packet->data == nullptr) {
return false;
}
memcpy(friend_lossless_packet->data, data, data_length);
friend_lossless_packet->data_length = data_length;
return true;
}
size_t tox_event_friend_lossless_packet_get_data_length(const Tox_Event_Friend_Lossless_Packet *friend_lossless_packet)
{
assert(friend_lossless_packet != nullptr);
return friend_lossless_packet->data_length;
}
const uint8_t *tox_event_friend_lossless_packet_get_data(const Tox_Event_Friend_Lossless_Packet *friend_lossless_packet)
{
assert(friend_lossless_packet != nullptr);
return friend_lossless_packet->data;
}
/*****************************************************
*
* :: add/clear/get
*
*****************************************************/
static Tox_Event_Friend_Lossless_Packet *tox_events_add_friend_lossless_packet(Tox_Events *events)
{
if (events->friend_lossless_packet_size == UINT32_MAX) {
return nullptr;
}
if (events->friend_lossless_packet_size == events->friend_lossless_packet_capacity) {
const uint32_t new_friend_lossless_packet_capacity = events->friend_lossless_packet_capacity * 2 + 1;
Tox_Event_Friend_Lossless_Packet *new_friend_lossless_packet = (Tox_Event_Friend_Lossless_Packet *)realloc(
events->friend_lossless_packet, new_friend_lossless_packet_capacity * sizeof(Tox_Event_Friend_Lossless_Packet));
if (new_friend_lossless_packet == nullptr) {
return nullptr;
}
events->friend_lossless_packet = new_friend_lossless_packet;
events->friend_lossless_packet_capacity = new_friend_lossless_packet_capacity;
}
Tox_Event_Friend_Lossless_Packet *const friend_lossless_packet =
&events->friend_lossless_packet[events->friend_lossless_packet_size];
tox_event_friend_lossless_packet_construct(friend_lossless_packet);
++events->friend_lossless_packet_size;
return friend_lossless_packet;
}
void tox_events_clear_friend_lossless_packet(Tox_Events *events)
{
if (events == nullptr) {
return;
}
for (uint32_t i = 0; i < events->friend_lossless_packet_size; ++i) {
tox_event_friend_lossless_packet_destruct(&events->friend_lossless_packet[i]);
}
free(events->friend_lossless_packet);
events->friend_lossless_packet = nullptr;
events->friend_lossless_packet_size = 0;
events->friend_lossless_packet_capacity = 0;
}
uint32_t tox_events_get_friend_lossless_packet_size(const Tox_Events *events)
{
return events->friend_lossless_packet_size;
}
const Tox_Event_Friend_Lossless_Packet *tox_events_get_friend_lossless_packet(const Tox_Events *events, uint32_t index)
{
assert(index < events->friend_lossless_packet_size);
assert(events->friend_lossless_packet != nullptr);
return &events->friend_lossless_packet[index];
}
/*****************************************************
*
* :: event handler
*
*****************************************************/
void tox_events_handle_friend_lossless_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
assert(state != nullptr);
Tox_Event_Friend_Lossless_Packet *friend_lossless_packet = tox_events_add_friend_lossless_packet(state->events);
if (friend_lossless_packet == nullptr) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
return;
}
tox_event_friend_lossless_packet_set_friend_number(friend_lossless_packet, friend_number);
tox_event_friend_lossless_packet_set_data(friend_lossless_packet, data, length);
}

View File

@ -0,0 +1,169 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
*/
#include "events_alloc.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "../ccompat.h"
#include "../tox.h"
#include "../tox_events.h"
/*****************************************************
*
* :: struct and accessors
*
*****************************************************/
struct Tox_Event_Friend_Lossy_Packet {
uint32_t friend_number;
uint8_t *data;
size_t data_length;
};
static void tox_event_friend_lossy_packet_construct(Tox_Event_Friend_Lossy_Packet *friend_lossy_packet)
{
*friend_lossy_packet = (Tox_Event_Friend_Lossy_Packet) {
0
};
}
static void tox_event_friend_lossy_packet_destruct(Tox_Event_Friend_Lossy_Packet *friend_lossy_packet)
{
free(friend_lossy_packet->data);
}
static void tox_event_friend_lossy_packet_set_friend_number(Tox_Event_Friend_Lossy_Packet *friend_lossy_packet,
uint32_t friend_number)
{
assert(friend_lossy_packet != nullptr);
friend_lossy_packet->friend_number = friend_number;
}
uint32_t tox_event_friend_lossy_packet_get_friend_number(const Tox_Event_Friend_Lossy_Packet *friend_lossy_packet)
{
assert(friend_lossy_packet != nullptr);
return friend_lossy_packet->friend_number;
}
static bool tox_event_friend_lossy_packet_set_data(Tox_Event_Friend_Lossy_Packet *friend_lossy_packet,
const uint8_t *data, size_t data_length)
{
assert(friend_lossy_packet != nullptr);
if (friend_lossy_packet->data != nullptr) {
free(friend_lossy_packet->data);
friend_lossy_packet->data = nullptr;
friend_lossy_packet->data_length = 0;
}
friend_lossy_packet->data = (uint8_t *)malloc(data_length);
if (friend_lossy_packet->data == nullptr) {
return false;
}
memcpy(friend_lossy_packet->data, data, data_length);
friend_lossy_packet->data_length = data_length;
return true;
}
size_t tox_event_friend_lossy_packet_get_data_length(const Tox_Event_Friend_Lossy_Packet *friend_lossy_packet)
{
assert(friend_lossy_packet != nullptr);
return friend_lossy_packet->data_length;
}
const uint8_t *tox_event_friend_lossy_packet_get_data(const Tox_Event_Friend_Lossy_Packet *friend_lossy_packet)
{
assert(friend_lossy_packet != nullptr);
return friend_lossy_packet->data;
}
/*****************************************************
*
* :: add/clear/get
*
*****************************************************/
static Tox_Event_Friend_Lossy_Packet *tox_events_add_friend_lossy_packet(Tox_Events *events)
{
if (events->friend_lossy_packet_size == UINT32_MAX) {
return nullptr;
}
if (events->friend_lossy_packet_size == events->friend_lossy_packet_capacity) {
const uint32_t new_friend_lossy_packet_capacity = events->friend_lossy_packet_capacity * 2 + 1;
Tox_Event_Friend_Lossy_Packet *new_friend_lossy_packet = (Tox_Event_Friend_Lossy_Packet *)realloc(
events->friend_lossy_packet, new_friend_lossy_packet_capacity * sizeof(Tox_Event_Friend_Lossy_Packet));
if (new_friend_lossy_packet == nullptr) {
return nullptr;
}
events->friend_lossy_packet = new_friend_lossy_packet;
events->friend_lossy_packet_capacity = new_friend_lossy_packet_capacity;
}
Tox_Event_Friend_Lossy_Packet *const friend_lossy_packet =
&events->friend_lossy_packet[events->friend_lossy_packet_size];
tox_event_friend_lossy_packet_construct(friend_lossy_packet);
++events->friend_lossy_packet_size;
return friend_lossy_packet;
}
void tox_events_clear_friend_lossy_packet(Tox_Events *events)
{
if (events == nullptr) {
return;
}
for (uint32_t i = 0; i < events->friend_lossy_packet_size; ++i) {
tox_event_friend_lossy_packet_destruct(&events->friend_lossy_packet[i]);
}
free(events->friend_lossy_packet);
events->friend_lossy_packet = nullptr;
events->friend_lossy_packet_size = 0;
events->friend_lossy_packet_capacity = 0;
}
uint32_t tox_events_get_friend_lossy_packet_size(const Tox_Events *events)
{
return events->friend_lossy_packet_size;
}
const Tox_Event_Friend_Lossy_Packet *tox_events_get_friend_lossy_packet(const Tox_Events *events, uint32_t index)
{
assert(index < events->friend_lossy_packet_size);
assert(events->friend_lossy_packet != nullptr);
return &events->friend_lossy_packet[index];
}
/*****************************************************
*
* :: event handler
*
*****************************************************/
void tox_events_handle_friend_lossy_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
assert(state != nullptr);
Tox_Event_Friend_Lossy_Packet *friend_lossy_packet = tox_events_add_friend_lossy_packet(state->events);
if (friend_lossy_packet == nullptr) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
return;
}
tox_event_friend_lossy_packet_set_friend_number(friend_lossy_packet, friend_number);
tox_event_friend_lossy_packet_set_data(friend_lossy_packet, data, length);
}

View File

@ -0,0 +1,181 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
*/
#include "events_alloc.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "../ccompat.h"
#include "../tox.h"
#include "../tox_events.h"
/*****************************************************
*
* :: struct and accessors
*
*****************************************************/
struct Tox_Event_Friend_Message {
uint32_t friend_number;
Tox_Message_Type type;
uint8_t *message;
size_t message_length;
};
static void tox_event_friend_message_construct(Tox_Event_Friend_Message *friend_message)
{
*friend_message = (Tox_Event_Friend_Message) {
0
};
}
static void tox_event_friend_message_destruct(Tox_Event_Friend_Message *friend_message)
{
free(friend_message->message);
}
static void tox_event_friend_message_set_friend_number(Tox_Event_Friend_Message *friend_message,
uint32_t friend_number)
{
assert(friend_message != nullptr);
friend_message->friend_number = friend_number;
}
uint32_t tox_event_friend_message_get_friend_number(const Tox_Event_Friend_Message *friend_message)
{
assert(friend_message != nullptr);
return friend_message->friend_number;
}
static void tox_event_friend_message_set_type(Tox_Event_Friend_Message *friend_message, Tox_Message_Type type)
{
assert(friend_message != nullptr);
friend_message->type = type;
}
Tox_Message_Type tox_event_friend_message_get_type(const Tox_Event_Friend_Message *friend_message)
{
assert(friend_message != nullptr);
return friend_message->type;
}
static bool tox_event_friend_message_set_message(Tox_Event_Friend_Message *friend_message, const uint8_t *message,
size_t message_length)
{
assert(friend_message != nullptr);
if (friend_message->message != nullptr) {
free(friend_message->message);
friend_message->message = nullptr;
friend_message->message_length = 0;
}
friend_message->message = (uint8_t *)malloc(message_length);
if (friend_message->message == nullptr) {
return false;
}
memcpy(friend_message->message, message, message_length);
friend_message->message_length = message_length;
return true;
}
size_t tox_event_friend_message_get_message_length(const Tox_Event_Friend_Message *friend_message)
{
assert(friend_message != nullptr);
return friend_message->message_length;
}
const uint8_t *tox_event_friend_message_get_message(const Tox_Event_Friend_Message *friend_message)
{
assert(friend_message != nullptr);
return friend_message->message;
}
/*****************************************************
*
* :: add/clear/get
*
*****************************************************/
static Tox_Event_Friend_Message *tox_events_add_friend_message(Tox_Events *events)
{
if (events->friend_message_size == UINT32_MAX) {
return nullptr;
}
if (events->friend_message_size == events->friend_message_capacity) {
const uint32_t new_friend_message_capacity = events->friend_message_capacity * 2 + 1;
Tox_Event_Friend_Message *new_friend_message = (Tox_Event_Friend_Message *)realloc(
events->friend_message, new_friend_message_capacity * sizeof(Tox_Event_Friend_Message));
if (new_friend_message == nullptr) {
return nullptr;
}
events->friend_message = new_friend_message;
events->friend_message_capacity = new_friend_message_capacity;
}
Tox_Event_Friend_Message *const friend_message = &events->friend_message[events->friend_message_size];
tox_event_friend_message_construct(friend_message);
++events->friend_message_size;
return friend_message;
}
void tox_events_clear_friend_message(Tox_Events *events)
{
if (events == nullptr) {
return;
}
for (uint32_t i = 0; i < events->friend_message_size; ++i) {
tox_event_friend_message_destruct(&events->friend_message[i]);
}
free(events->friend_message);
events->friend_message = nullptr;
events->friend_message_size = 0;
events->friend_message_capacity = 0;
}
uint32_t tox_events_get_friend_message_size(const Tox_Events *events)
{
return events->friend_message_size;
}
const Tox_Event_Friend_Message *tox_events_get_friend_message(const Tox_Events *events, uint32_t index)
{
assert(index < events->friend_message_size);
assert(events->friend_message != nullptr);
return &events->friend_message[index];
}
/*****************************************************
*
* :: event handler
*
*****************************************************/
void tox_events_handle_friend_message(Tox *tox, uint32_t friend_number, Tox_Message_Type type, const uint8_t *message,
size_t length, void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
assert(state != nullptr);
Tox_Event_Friend_Message *friend_message = tox_events_add_friend_message(state->events);
if (friend_message == nullptr) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
return;
}
tox_event_friend_message_set_friend_number(friend_message, friend_number);
tox_event_friend_message_set_type(friend_message, type);
tox_event_friend_message_set_message(friend_message, message, length);
}

View File

@ -0,0 +1,168 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
*/
#include "events_alloc.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "../ccompat.h"
#include "../tox.h"
#include "../tox_events.h"
/*****************************************************
*
* :: struct and accessors
*
*****************************************************/
struct Tox_Event_Friend_Name {
uint32_t friend_number;
uint8_t *name;
size_t name_length;
};
static void tox_event_friend_name_construct(Tox_Event_Friend_Name *friend_name)
{
*friend_name = (Tox_Event_Friend_Name) {
0
};
}
static void tox_event_friend_name_destruct(Tox_Event_Friend_Name *friend_name)
{
free(friend_name->name);
}
static void tox_event_friend_name_set_friend_number(Tox_Event_Friend_Name *friend_name,
uint32_t friend_number)
{
assert(friend_name != nullptr);
friend_name->friend_number = friend_number;
}
uint32_t tox_event_friend_name_get_friend_number(const Tox_Event_Friend_Name *friend_name)
{
assert(friend_name != nullptr);
return friend_name->friend_number;
}
static bool tox_event_friend_name_set_name(Tox_Event_Friend_Name *friend_name, const uint8_t *name,
size_t name_length)
{
assert(friend_name != nullptr);
if (friend_name->name != nullptr) {
free(friend_name->name);
friend_name->name = nullptr;
friend_name->name_length = 0;
}
friend_name->name = (uint8_t *)malloc(name_length);
if (friend_name->name == nullptr) {
return false;
}
memcpy(friend_name->name, name, name_length);
friend_name->name_length = name_length;
return true;
}
size_t tox_event_friend_name_get_name_length(const Tox_Event_Friend_Name *friend_name)
{
assert(friend_name != nullptr);
return friend_name->name_length;
}
const uint8_t *tox_event_friend_name_get_name(const Tox_Event_Friend_Name *friend_name)
{
assert(friend_name != nullptr);
return friend_name->name;
}
/*****************************************************
*
* :: add/clear/get
*
*****************************************************/
static Tox_Event_Friend_Name *tox_events_add_friend_name(Tox_Events *events)
{
if (events->friend_name_size == UINT32_MAX) {
return nullptr;
}
if (events->friend_name_size == events->friend_name_capacity) {
const uint32_t new_friend_name_capacity = events->friend_name_capacity * 2 + 1;
Tox_Event_Friend_Name *new_friend_name = (Tox_Event_Friend_Name *)realloc(
events->friend_name, new_friend_name_capacity * sizeof(Tox_Event_Friend_Name));
if (new_friend_name == nullptr) {
return nullptr;
}
events->friend_name = new_friend_name;
events->friend_name_capacity = new_friend_name_capacity;
}
Tox_Event_Friend_Name *const friend_name = &events->friend_name[events->friend_name_size];
tox_event_friend_name_construct(friend_name);
++events->friend_name_size;
return friend_name;
}
void tox_events_clear_friend_name(Tox_Events *events)
{
if (events == nullptr) {
return;
}
for (uint32_t i = 0; i < events->friend_name_size; ++i) {
tox_event_friend_name_destruct(&events->friend_name[i]);
}
free(events->friend_name);
events->friend_name = nullptr;
events->friend_name_size = 0;
events->friend_name_capacity = 0;
}
uint32_t tox_events_get_friend_name_size(const Tox_Events *events)
{
return events->friend_name_size;
}
const Tox_Event_Friend_Name *tox_events_get_friend_name(const Tox_Events *events, uint32_t index)
{
assert(index < events->friend_name_size);
assert(events->friend_name != nullptr);
return &events->friend_name[index];
}
/*****************************************************
*
* :: event handler
*
*****************************************************/
void tox_events_handle_friend_name(Tox *tox, uint32_t friend_number, const uint8_t *name, size_t length,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
assert(state != nullptr);
Tox_Event_Friend_Name *friend_name = tox_events_add_friend_name(state->events);
if (friend_name == nullptr) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
return;
}
tox_event_friend_name_set_friend_number(friend_name, friend_number);
tox_event_friend_name_set_name(friend_name, name, length);
}

View File

@ -0,0 +1,147 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
*/
#include "events_alloc.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "../ccompat.h"
#include "../tox.h"
#include "../tox_events.h"
/*****************************************************
*
* :: struct and accessors
*
*****************************************************/
struct Tox_Event_Friend_Read_Receipt {
uint32_t friend_number;
uint32_t message_id;
};
static void tox_event_friend_read_receipt_construct(Tox_Event_Friend_Read_Receipt *friend_read_receipt)
{
*friend_read_receipt = (Tox_Event_Friend_Read_Receipt) {
0
};
}
static void tox_event_friend_read_receipt_destruct(Tox_Event_Friend_Read_Receipt *friend_read_receipt)
{
return;
}
static void tox_event_friend_read_receipt_set_friend_number(Tox_Event_Friend_Read_Receipt *friend_read_receipt,
uint32_t friend_number)
{
assert(friend_read_receipt != nullptr);
friend_read_receipt->friend_number = friend_number;
}
uint32_t tox_event_friend_read_receipt_get_friend_number(const Tox_Event_Friend_Read_Receipt *friend_read_receipt)
{
assert(friend_read_receipt != nullptr);
return friend_read_receipt->friend_number;
}
static void tox_event_friend_read_receipt_set_message_id(Tox_Event_Friend_Read_Receipt *friend_read_receipt,
uint32_t message_id)
{
assert(friend_read_receipt != nullptr);
friend_read_receipt->message_id = message_id;
}
uint32_t tox_event_friend_read_receipt_get_message_id(const Tox_Event_Friend_Read_Receipt *friend_read_receipt)
{
assert(friend_read_receipt != nullptr);
return friend_read_receipt->message_id;
}
/*****************************************************
*
* :: add/clear/get
*
*****************************************************/
static Tox_Event_Friend_Read_Receipt *tox_events_add_friend_read_receipt(Tox_Events *events)
{
if (events->friend_read_receipt_size == UINT32_MAX) {
return nullptr;
}
if (events->friend_read_receipt_size == events->friend_read_receipt_capacity) {
const uint32_t new_friend_read_receipt_capacity = events->friend_read_receipt_capacity * 2 + 1;
Tox_Event_Friend_Read_Receipt *new_friend_read_receipt = (Tox_Event_Friend_Read_Receipt *)realloc(
events->friend_read_receipt, new_friend_read_receipt_capacity * sizeof(Tox_Event_Friend_Read_Receipt));
if (new_friend_read_receipt == nullptr) {
return nullptr;
}
events->friend_read_receipt = new_friend_read_receipt;
events->friend_read_receipt_capacity = new_friend_read_receipt_capacity;
}
Tox_Event_Friend_Read_Receipt *const friend_read_receipt =
&events->friend_read_receipt[events->friend_read_receipt_size];
tox_event_friend_read_receipt_construct(friend_read_receipt);
++events->friend_read_receipt_size;
return friend_read_receipt;
}
void tox_events_clear_friend_read_receipt(Tox_Events *events)
{
if (events == nullptr) {
return;
}
for (uint32_t i = 0; i < events->friend_read_receipt_size; ++i) {
tox_event_friend_read_receipt_destruct(&events->friend_read_receipt[i]);
}
free(events->friend_read_receipt);
events->friend_read_receipt = nullptr;
events->friend_read_receipt_size = 0;
events->friend_read_receipt_capacity = 0;
}
uint32_t tox_events_get_friend_read_receipt_size(const Tox_Events *events)
{
return events->friend_read_receipt_size;
}
const Tox_Event_Friend_Read_Receipt *tox_events_get_friend_read_receipt(const Tox_Events *events, uint32_t index)
{
assert(index < events->friend_read_receipt_size);
assert(events->friend_read_receipt != nullptr);
return &events->friend_read_receipt[index];
}
/*****************************************************
*
* :: event handler
*
*****************************************************/
void tox_events_handle_friend_read_receipt(Tox *tox, uint32_t friend_number, uint32_t message_id, void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
assert(state != nullptr);
Tox_Event_Friend_Read_Receipt *friend_read_receipt = tox_events_add_friend_read_receipt(state->events);
if (friend_read_receipt == nullptr) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
return;
}
tox_event_friend_read_receipt_set_friend_number(friend_read_receipt, friend_number);
tox_event_friend_read_receipt_set_message_id(friend_read_receipt, message_id);
}

View File

@ -0,0 +1,169 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
*/
#include "events_alloc.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "../ccompat.h"
#include "../tox.h"
#include "../tox_events.h"
/*****************************************************
*
* :: struct and accessors
*
*****************************************************/
struct Tox_Event_Friend_Request {
uint8_t public_key[TOX_PUBLIC_KEY_SIZE];
uint8_t *message;
size_t message_length;
};
static void tox_event_friend_request_construct(Tox_Event_Friend_Request *friend_request)
{
*friend_request = (Tox_Event_Friend_Request) {
0
};
}
static void tox_event_friend_request_destruct(Tox_Event_Friend_Request *friend_request)
{
free(friend_request->message);
}
static bool tox_event_friend_request_set_public_key(Tox_Event_Friend_Request *friend_request, const uint8_t *public_key)
{
assert(friend_request != nullptr);
memcpy(friend_request->public_key, public_key, TOX_PUBLIC_KEY_SIZE);
return true;
}
const uint8_t *tox_event_friend_request_get_public_key(const Tox_Event_Friend_Request *friend_request)
{
assert(friend_request != nullptr);
return friend_request->public_key;
}
static bool tox_event_friend_request_set_message(Tox_Event_Friend_Request *friend_request, const uint8_t *message,
size_t message_length)
{
assert(friend_request != nullptr);
if (friend_request->message != nullptr) {
free(friend_request->message);
friend_request->message = nullptr;
friend_request->message_length = 0;
}
friend_request->message = (uint8_t *)malloc(message_length);
if (friend_request->message == nullptr) {
return false;
}
memcpy(friend_request->message, message, message_length);
friend_request->message_length = message_length;
return true;
}
size_t tox_event_friend_request_get_message_length(const Tox_Event_Friend_Request *friend_request)
{
assert(friend_request != nullptr);
return friend_request->message_length;
}
const uint8_t *tox_event_friend_request_get_message(const Tox_Event_Friend_Request *friend_request)
{
assert(friend_request != nullptr);
return friend_request->message;
}
/*****************************************************
*
* :: add/clear/get
*
*****************************************************/
static Tox_Event_Friend_Request *tox_events_add_friend_request(Tox_Events *events)
{
if (events->friend_request_size == UINT32_MAX) {
return nullptr;
}
if (events->friend_request_size == events->friend_request_capacity) {
const uint32_t new_friend_request_capacity = events->friend_request_capacity * 2 + 1;
Tox_Event_Friend_Request *new_friend_request = (Tox_Event_Friend_Request *)realloc(
events->friend_request, new_friend_request_capacity * sizeof(Tox_Event_Friend_Request));
if (new_friend_request == nullptr) {
return nullptr;
}
events->friend_request = new_friend_request;
events->friend_request_capacity = new_friend_request_capacity;
}
Tox_Event_Friend_Request *const friend_request = &events->friend_request[events->friend_request_size];
tox_event_friend_request_construct(friend_request);
++events->friend_request_size;
return friend_request;
}
void tox_events_clear_friend_request(Tox_Events *events)
{
if (events == nullptr) {
return;
}
for (uint32_t i = 0; i < events->friend_request_size; ++i) {
tox_event_friend_request_destruct(&events->friend_request[i]);
}
free(events->friend_request);
events->friend_request = nullptr;
events->friend_request_size = 0;
events->friend_request_capacity = 0;
}
uint32_t tox_events_get_friend_request_size(const Tox_Events *events)
{
return events->friend_request_size;
}
const Tox_Event_Friend_Request *tox_events_get_friend_request(const Tox_Events *events, uint32_t index)
{
assert(index < events->friend_request_size);
assert(events->friend_request != nullptr);
return &events->friend_request[index];
}
/*****************************************************
*
* :: event handler
*
*****************************************************/
void tox_events_handle_friend_request(Tox *tox, const uint8_t *public_key, const uint8_t *message, size_t length,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
assert(state != nullptr);
Tox_Event_Friend_Request *friend_request = tox_events_add_friend_request(state->events);
if (friend_request == nullptr) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
return;
}
tox_event_friend_request_set_public_key(friend_request, public_key);
tox_event_friend_request_set_message(friend_request, message, length);
}

View File

@ -0,0 +1,147 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
*/
#include "events_alloc.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "../ccompat.h"
#include "../tox.h"
#include "../tox_events.h"
/*****************************************************
*
* :: struct and accessors
*
*****************************************************/
struct Tox_Event_Friend_Status {
uint32_t friend_number;
Tox_User_Status connection_status;
};
static void tox_event_friend_status_construct(Tox_Event_Friend_Status *friend_status)
{
*friend_status = (Tox_Event_Friend_Status) {
0
};
}
static void tox_event_friend_status_destruct(Tox_Event_Friend_Status *friend_status)
{
return;
}
static void tox_event_friend_status_set_friend_number(Tox_Event_Friend_Status *friend_status,
uint32_t friend_number)
{
assert(friend_status != nullptr);
friend_status->friend_number = friend_number;
}
uint32_t tox_event_friend_status_get_friend_number(const Tox_Event_Friend_Status *friend_status)
{
assert(friend_status != nullptr);
return friend_status->friend_number;
}
static void tox_event_friend_status_set_connection_status(Tox_Event_Friend_Status *friend_status,
Tox_User_Status connection_status)
{
assert(friend_status != nullptr);
friend_status->connection_status = connection_status;
}
Tox_User_Status tox_event_friend_status_get_connection_status(const Tox_Event_Friend_Status *friend_status)
{
assert(friend_status != nullptr);
return friend_status->connection_status;
}
/*****************************************************
*
* :: add/clear/get
*
*****************************************************/
static Tox_Event_Friend_Status *tox_events_add_friend_status(Tox_Events *events)
{
if (events->friend_status_size == UINT32_MAX) {
return nullptr;
}
if (events->friend_status_size == events->friend_status_capacity) {
const uint32_t new_friend_status_capacity = events->friend_status_capacity * 2 + 1;
Tox_Event_Friend_Status *new_friend_status = (Tox_Event_Friend_Status *)realloc(
events->friend_status, new_friend_status_capacity * sizeof(Tox_Event_Friend_Status));
if (new_friend_status == nullptr) {
return nullptr;
}
events->friend_status = new_friend_status;
events->friend_status_capacity = new_friend_status_capacity;
}
Tox_Event_Friend_Status *const friend_status = &events->friend_status[events->friend_status_size];
tox_event_friend_status_construct(friend_status);
++events->friend_status_size;
return friend_status;
}
void tox_events_clear_friend_status(Tox_Events *events)
{
if (events == nullptr) {
return;
}
for (uint32_t i = 0; i < events->friend_status_size; ++i) {
tox_event_friend_status_destruct(&events->friend_status[i]);
}
free(events->friend_status);
events->friend_status = nullptr;
events->friend_status_size = 0;
events->friend_status_capacity = 0;
}
uint32_t tox_events_get_friend_status_size(const Tox_Events *events)
{
return events->friend_status_size;
}
const Tox_Event_Friend_Status *tox_events_get_friend_status(const Tox_Events *events, uint32_t index)
{
assert(index < events->friend_status_size);
assert(events->friend_status != nullptr);
return &events->friend_status[index];
}
/*****************************************************
*
* :: event handler
*
*****************************************************/
void tox_events_handle_friend_status(Tox *tox, uint32_t friend_number, Tox_User_Status connection_status,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
assert(state != nullptr);
Tox_Event_Friend_Status *friend_status = tox_events_add_friend_status(state->events);
if (friend_status == nullptr) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
return;
}
tox_event_friend_status_set_friend_number(friend_status, friend_number);
tox_event_friend_status_set_connection_status(friend_status, connection_status);
}

View File

@ -0,0 +1,171 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
*/
#include "events_alloc.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "../ccompat.h"
#include "../tox.h"
#include "../tox_events.h"
/*****************************************************
*
* :: struct and accessors
*
*****************************************************/
struct Tox_Event_Friend_Status_Message {
uint32_t friend_number;
uint8_t *status_message;
size_t status_message_length;
};
static void tox_event_friend_status_message_construct(Tox_Event_Friend_Status_Message *friend_status_message)
{
*friend_status_message = (Tox_Event_Friend_Status_Message) {
0
};
}
static void tox_event_friend_status_message_destruct(Tox_Event_Friend_Status_Message *friend_status_message)
{
free(friend_status_message->status_message);
}
static void tox_event_friend_status_message_set_friend_number(Tox_Event_Friend_Status_Message *friend_status_message,
uint32_t friend_number)
{
assert(friend_status_message != nullptr);
friend_status_message->friend_number = friend_number;
}
uint32_t tox_event_friend_status_message_get_friend_number(const Tox_Event_Friend_Status_Message *friend_status_message)
{
assert(friend_status_message != nullptr);
return friend_status_message->friend_number;
}
static bool tox_event_friend_status_message_set_status_message(Tox_Event_Friend_Status_Message *friend_status_message,
const uint8_t *status_message, size_t status_message_length)
{
assert(friend_status_message != nullptr);
if (friend_status_message->status_message != nullptr) {
free(friend_status_message->status_message);
friend_status_message->status_message = nullptr;
friend_status_message->status_message_length = 0;
}
friend_status_message->status_message = (uint8_t *)malloc(status_message_length);
if (friend_status_message->status_message == nullptr) {
return false;
}
memcpy(friend_status_message->status_message, status_message, status_message_length);
friend_status_message->status_message_length = status_message_length;
return true;
}
size_t tox_event_friend_status_message_get_status_message_length(const Tox_Event_Friend_Status_Message
*friend_status_message)
{
assert(friend_status_message != nullptr);
return friend_status_message->status_message_length;
}
const uint8_t *tox_event_friend_status_message_get_status_message(const Tox_Event_Friend_Status_Message
*friend_status_message)
{
assert(friend_status_message != nullptr);
return friend_status_message->status_message;
}
/*****************************************************
*
* :: add/clear/get
*
*****************************************************/
static Tox_Event_Friend_Status_Message *tox_events_add_friend_status_message(Tox_Events *events)
{
if (events->friend_status_message_size == UINT32_MAX) {
return nullptr;
}
if (events->friend_status_message_size == events->friend_status_message_capacity) {
const uint32_t new_friend_status_message_capacity = events->friend_status_message_capacity * 2 + 1;
Tox_Event_Friend_Status_Message *new_friend_status_message = (Tox_Event_Friend_Status_Message *)realloc(
events->friend_status_message, new_friend_status_message_capacity * sizeof(Tox_Event_Friend_Status_Message));
if (new_friend_status_message == nullptr) {
return nullptr;
}
events->friend_status_message = new_friend_status_message;
events->friend_status_message_capacity = new_friend_status_message_capacity;
}
Tox_Event_Friend_Status_Message *const friend_status_message =
&events->friend_status_message[events->friend_status_message_size];
tox_event_friend_status_message_construct(friend_status_message);
++events->friend_status_message_size;
return friend_status_message;
}
void tox_events_clear_friend_status_message(Tox_Events *events)
{
if (events == nullptr) {
return;
}
for (uint32_t i = 0; i < events->friend_status_message_size; ++i) {
tox_event_friend_status_message_destruct(&events->friend_status_message[i]);
}
free(events->friend_status_message);
events->friend_status_message = nullptr;
events->friend_status_message_size = 0;
events->friend_status_message_capacity = 0;
}
uint32_t tox_events_get_friend_status_message_size(const Tox_Events *events)
{
return events->friend_status_message_size;
}
const Tox_Event_Friend_Status_Message *tox_events_get_friend_status_message(const Tox_Events *events, uint32_t index)
{
assert(index < events->friend_status_message_size);
assert(events->friend_status_message != nullptr);
return &events->friend_status_message[index];
}
/*****************************************************
*
* :: event handler
*
*****************************************************/
void tox_events_handle_friend_status_message(Tox *tox, uint32_t friend_number, const uint8_t *status_message,
size_t length, void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
assert(state != nullptr);
Tox_Event_Friend_Status_Message *friend_status_message = tox_events_add_friend_status_message(state->events);
if (friend_status_message == nullptr) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
return;
}
tox_event_friend_status_message_set_friend_number(friend_status_message, friend_number);
tox_event_friend_status_message_set_status_message(friend_status_message, status_message, length);
}

View File

@ -0,0 +1,145 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
*/
#include "events_alloc.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "../ccompat.h"
#include "../tox.h"
#include "../tox_events.h"
/*****************************************************
*
* :: struct and accessors
*
*****************************************************/
struct Tox_Event_Friend_Typing {
uint32_t friend_number;
bool typing;
};
static void tox_event_friend_typing_construct(Tox_Event_Friend_Typing *friend_typing)
{
*friend_typing = (Tox_Event_Friend_Typing) {
0
};
}
static void tox_event_friend_typing_destruct(Tox_Event_Friend_Typing *friend_typing)
{
return;
}
static void tox_event_friend_typing_set_friend_number(Tox_Event_Friend_Typing *friend_typing,
uint32_t friend_number)
{
assert(friend_typing != nullptr);
friend_typing->friend_number = friend_number;
}
uint32_t tox_event_friend_typing_get_friend_number(const Tox_Event_Friend_Typing *friend_typing)
{
assert(friend_typing != nullptr);
return friend_typing->friend_number;
}
static void tox_event_friend_typing_set_typing(Tox_Event_Friend_Typing *friend_typing, bool typing)
{
assert(friend_typing != nullptr);
friend_typing->typing = typing;
}
bool tox_event_friend_typing_get_typing(const Tox_Event_Friend_Typing *friend_typing)
{
assert(friend_typing != nullptr);
return friend_typing->typing;
}
/*****************************************************
*
* :: add/clear/get
*
*****************************************************/
static Tox_Event_Friend_Typing *tox_events_add_friend_typing(Tox_Events *events)
{
if (events->friend_typing_size == UINT32_MAX) {
return nullptr;
}
if (events->friend_typing_size == events->friend_typing_capacity) {
const uint32_t new_friend_typing_capacity = events->friend_typing_capacity * 2 + 1;
Tox_Event_Friend_Typing *new_friend_typing = (Tox_Event_Friend_Typing *)realloc(
events->friend_typing, new_friend_typing_capacity * sizeof(Tox_Event_Friend_Typing));
if (new_friend_typing == nullptr) {
return nullptr;
}
events->friend_typing = new_friend_typing;
events->friend_typing_capacity = new_friend_typing_capacity;
}
Tox_Event_Friend_Typing *const friend_typing = &events->friend_typing[events->friend_typing_size];
tox_event_friend_typing_construct(friend_typing);
++events->friend_typing_size;
return friend_typing;
}
void tox_events_clear_friend_typing(Tox_Events *events)
{
if (events == nullptr) {
return;
}
for (uint32_t i = 0; i < events->friend_typing_size; ++i) {
tox_event_friend_typing_destruct(&events->friend_typing[i]);
}
free(events->friend_typing);
events->friend_typing = nullptr;
events->friend_typing_size = 0;
events->friend_typing_capacity = 0;
}
uint32_t tox_events_get_friend_typing_size(const Tox_Events *events)
{
return events->friend_typing_size;
}
const Tox_Event_Friend_Typing *tox_events_get_friend_typing(const Tox_Events *events, uint32_t index)
{
assert(index < events->friend_typing_size);
assert(events->friend_typing != nullptr);
return &events->friend_typing[index];
}
/*****************************************************
*
* :: event handler
*
*****************************************************/
void tox_events_handle_friend_typing(Tox *tox, uint32_t friend_number, bool typing, void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
assert(state != nullptr);
Tox_Event_Friend_Typing *friend_typing = tox_events_add_friend_typing(state->events);
if (friend_typing == nullptr) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
return;
}
tox_event_friend_typing_set_friend_number(friend_typing, friend_number);
tox_event_friend_typing_set_typing(friend_typing, typing);
}

View File

@ -0,0 +1,134 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
*/
#include "events_alloc.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "../ccompat.h"
#include "../tox.h"
#include "../tox_events.h"
/*****************************************************
*
* :: struct and accessors
*
*****************************************************/
struct Tox_Event_Self_Connection_Status {
Tox_Connection connection_status;
};
static void tox_event_self_connection_status_construct(Tox_Event_Self_Connection_Status *self_connection_status)
{
*self_connection_status = (Tox_Event_Self_Connection_Status) {
TOX_CONNECTION_NONE
};
}
static void tox_event_self_connection_status_destruct(Tox_Event_Self_Connection_Status *self_connection_status)
{
return;
}
static void tox_event_self_connection_status_set_connection_status(Tox_Event_Self_Connection_Status
*self_connection_status, Tox_Connection connection_status)
{
assert(self_connection_status != nullptr);
self_connection_status->connection_status = connection_status;
}
Tox_Connection tox_event_self_connection_status_get_connection_status(const Tox_Event_Self_Connection_Status
*self_connection_status)
{
assert(self_connection_status != nullptr);
return self_connection_status->connection_status;
}
/*****************************************************
*
* :: add/clear/get
*
*****************************************************/
static Tox_Event_Self_Connection_Status *tox_events_add_self_connection_status(Tox_Events *events)
{
if (events->self_connection_status_size == UINT32_MAX) {
return nullptr;
}
if (events->self_connection_status_size == events->self_connection_status_capacity) {
const uint32_t new_self_connection_status_capacity = events->self_connection_status_capacity * 2 + 1;
Tox_Event_Self_Connection_Status *new_self_connection_status = (Tox_Event_Self_Connection_Status *)realloc(
events->self_connection_status, new_self_connection_status_capacity * sizeof(Tox_Event_Self_Connection_Status));
if (new_self_connection_status == nullptr) {
return nullptr;
}
events->self_connection_status = new_self_connection_status;
events->self_connection_status_capacity = new_self_connection_status_capacity;
}
Tox_Event_Self_Connection_Status *const self_connection_status =
&events->self_connection_status[events->self_connection_status_size];
tox_event_self_connection_status_construct(self_connection_status);
++events->self_connection_status_size;
return self_connection_status;
}
void tox_events_clear_self_connection_status(Tox_Events *events)
{
if (events == nullptr) {
return;
}
for (uint32_t i = 0; i < events->self_connection_status_size; ++i) {
tox_event_self_connection_status_destruct(&events->self_connection_status[i]);
}
free(events->self_connection_status);
events->self_connection_status = nullptr;
events->self_connection_status_size = 0;
events->self_connection_status_capacity = 0;
}
uint32_t tox_events_get_self_connection_status_size(const Tox_Events *events)
{
return events->self_connection_status_size;
}
const Tox_Event_Self_Connection_Status *tox_events_get_self_connection_status(const Tox_Events *events, uint32_t index)
{
assert(index < events->self_connection_status_size);
assert(events->self_connection_status != nullptr);
return &events->self_connection_status[index];
}
/*****************************************************
*
* :: event handler
*
*****************************************************/
void tox_events_handle_self_connection_status(Tox *tox, Tox_Connection connection_status, void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
assert(state != nullptr);
Tox_Event_Self_Connection_Status *self_connection_status = tox_events_add_self_connection_status(state->events);
if (self_connection_status == nullptr) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
return;
}
tox_event_self_connection_status_set_connection_status(self_connection_status, connection_status);
}

View File

@ -669,14 +669,14 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
return -1;
}
int direct_send_attempt = 0;
bool direct_send_attempt = false;
pthread_mutex_lock(conn->mutex);
IP_Port ip_port = return_ip_port_connection(c, crypt_connection_id);
// TODO(irungentoo): on bad networks, direct connections might not last indefinitely.
if (!net_family_is_unspec(ip_port.ip.family)) {
bool direct_connected = 0;
bool direct_connected = false;
// FIXME(sudden6): handle return value
crypto_connection_status(c, crypt_connection_id, &direct_connected, nullptr);
@ -688,6 +688,7 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
}
pthread_mutex_unlock(conn->mutex);
LOGGER_WARNING(c->log, "sending packet of length %d failed", length);
return -1;
}
@ -697,7 +698,7 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
if ((((UDP_DIRECT_TIMEOUT / 2) + conn->direct_send_attempt_time) < current_time && length < 96)
|| data[0] == NET_PACKET_COOKIE_REQUEST || data[0] == NET_PACKET_CRYPTO_HS) {
if ((uint32_t)sendpacket(dht_get_net(c->dht), &ip_port, data, length) == length) {
direct_send_attempt = 1;
direct_send_attempt = true;
conn->direct_send_attempt_time = mono_time_get(c->mono_time);
}
}
@ -705,7 +706,7 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
pthread_mutex_unlock(conn->mutex);
pthread_mutex_lock(&c->tcp_mutex);
int ret = send_packet_tcp_connection(c->tcp_c, conn->connection_number_tcp, data, length);
const int ret = send_packet_tcp_connection(c->tcp_c, conn->connection_number_tcp, data, length);
pthread_mutex_unlock(&c->tcp_mutex);
pthread_mutex_lock(conn->mutex);
@ -716,11 +717,11 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
pthread_mutex_unlock(conn->mutex);
if (ret == 0 || direct_send_attempt) {
if (direct_send_attempt) {
return 0;
}
return -1;
return ret;
}
/*** START: Array Related functions */
@ -1052,22 +1053,26 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_
const uint16_t max_length = MAX_CRYPTO_PACKET_SIZE - (1 + sizeof(uint16_t) + CRYPTO_MAC_SIZE);
if (length == 0 || length > max_length) {
LOGGER_WARNING(c->log, "zero-length or too large data packet: %d (max: %d)", length, max_length);
return -1;
}
Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
if (conn == nullptr) {
LOGGER_WARNING(c->log, "connection id %d not found", crypt_connection_id);
return -1;
}
pthread_mutex_lock(conn->mutex);
VLA(uint8_t, packet, 1 + sizeof(uint16_t) + length + CRYPTO_MAC_SIZE);
const uint16_t packet_size = 1 + sizeof(uint16_t) + length + CRYPTO_MAC_SIZE;
VLA(uint8_t, packet, packet_size);
packet[0] = NET_PACKET_CRYPTO_DATA;
memcpy(packet + 1, conn->sent_nonce + (CRYPTO_NONCE_SIZE - sizeof(uint16_t)), sizeof(uint16_t));
const int len = encrypt_data_symmetric(conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t));
if (len + 1 + sizeof(uint16_t) != SIZEOF_VLA(packet)) {
if (len + 1 + sizeof(uint16_t) != packet_size) {
LOGGER_WARNING(c->log, "encryption failed: %d", len);
pthread_mutex_unlock(conn->mutex);
return -1;
}
@ -1087,6 +1092,7 @@ static int send_data_packet_helper(Net_Crypto *c, int crypt_connection_id, uint3
const uint8_t *data, uint16_t length)
{
if (length == 0 || length > MAX_CRYPTO_DATA_SIZE) {
LOGGER_WARNING(c->log, "zero-length or too large data packet: %d (max: %d)", length, MAX_CRYPTO_PACKET_SIZE);
return -1;
}
@ -1161,7 +1167,7 @@ static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, cons
dt.length = length;
memcpy(dt.data, data, length);
pthread_mutex_lock(conn->mutex);
int64_t packet_num = add_data_end_of_buffer(&conn->send_array, &dt);
const int64_t packet_num = add_data_end_of_buffer(&conn->send_array, &dt);
pthread_mutex_unlock(conn->mutex);
if (packet_num == -1) {
@ -1180,7 +1186,7 @@ static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, cons
}
} else {
conn->maximum_speed_reached = 1;
LOGGER_DEBUG(c->log, "send_data_packet failed");
LOGGER_DEBUG(c->log, "send_data_packet failed (packet_num = %ld)", (long)packet_num);
}
return packet_num;

View File

@ -20,7 +20,7 @@
/*** Ranges. */
/** Packets in this range are reserved for net_crypto internal use. */
/** Packets in this range are reserved for net_crypto events_alloc use. */
#define PACKET_ID_RANGE_RESERVED_START 0
#define PACKET_ID_RANGE_RESERVED_END 15
/** Packets in this range are reserved for Messenger use. */

View File

@ -465,12 +465,12 @@ typedef enum Tox_Log_Level {
TOX_LOG_LEVEL_INFO,
/**
* Warnings about internal inconsistency or logic errors.
* Warnings about events_alloc inconsistency or logic errors.
*/
TOX_LOG_LEVEL_WARNING,
/**
* Severe unexpected errors caused by external or internal inconsistency.
* Severe unexpected errors caused by external or events_alloc inconsistency.
*/
TOX_LOG_LEVEL_ERROR,
@ -478,7 +478,7 @@ typedef enum Tox_Log_Level {
/**
* @brief This event is triggered when the toxcore library logs an internal message.
* @brief This event is triggered when the toxcore library logs an events_alloc message.
*
* This is mostly useful for debugging. This callback can be called from any
* function, not just tox_iterate. This means the user data lifetime must at
@ -800,7 +800,7 @@ typedef enum Tox_Err_New {
TOX_ERR_NEW_NULL,
/**
* The function was unable to allocate enough memory to store the internal
* The function was unable to allocate enough memory to store the events_alloc
* structures for the Tox object.
*/
TOX_ERR_NEW_MALLOC,
@ -1845,7 +1845,7 @@ void tox_callback_friend_message(Tox *tox, tox_friend_message_cb *callback);
* If hash is NULL or data is NULL while length is not 0 the function returns false,
* otherwise it returns true.
*
* This function is a wrapper to internal message-digest functions.
* This function is a wrapper to events_alloc message-digest functions.
*
* @param hash A valid memory location the hash data. It must be at least
* TOX_HASH_LENGTH bytes in size.

460
toxcore/tox_dispatch.c Normal file
View File

@ -0,0 +1,460 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
*/
#include "tox_dispatch.h"
#include <stdlib.h>
#include "ccompat.h"
struct Tox_Dispatch {
tox_events_conference_connected_cb *conference_connected_callback;
tox_events_conference_invite_cb *conference_invite_callback;
tox_events_conference_message_cb *conference_message_callback;
tox_events_conference_peer_list_changed_cb *conference_peer_list_changed_callback;
tox_events_conference_peer_name_cb *conference_peer_name_callback;
tox_events_conference_title_cb *conference_title_callback;
tox_events_file_chunk_request_cb *file_chunk_request_callback;
tox_events_file_recv_cb *file_recv_callback;
tox_events_file_recv_chunk_cb *file_recv_chunk_callback;
tox_events_file_recv_control_cb *file_recv_control_callback;
tox_events_friend_connection_status_cb *friend_connection_status_callback;
tox_events_friend_lossless_packet_cb *friend_lossless_packet_callback;
tox_events_friend_lossy_packet_cb *friend_lossy_packet_callback;
tox_events_friend_message_cb *friend_message_callback;
tox_events_friend_name_cb *friend_name_callback;
tox_events_friend_read_receipt_cb *friend_read_receipt_callback;
tox_events_friend_request_cb *friend_request_callback;
tox_events_friend_status_cb *friend_status_callback;
tox_events_friend_status_message_cb *friend_status_message_callback;
tox_events_friend_typing_cb *friend_typing_callback;
tox_events_self_connection_status_cb *self_connection_status_callback;
};
Tox_Dispatch *tox_dispatch_new(Tox_Err_Dispatch_New *error)
{
Tox_Dispatch *dispatch = (Tox_Dispatch *)calloc(1, sizeof(Tox_Dispatch));
if (dispatch == nullptr) {
if (error != nullptr) {
*error = TOX_ERR_DISPATCH_NEW_MALLOC;
}
return nullptr;
}
*dispatch = (Tox_Dispatch) {
nullptr
};
return dispatch;
}
void tox_dispatch_free(Tox_Dispatch *dispatch)
{
free(dispatch);
}
void tox_events_callback_conference_connected(
Tox_Dispatch *dispatch, tox_events_conference_connected_cb *callback)
{
dispatch->conference_connected_callback = callback;
}
void tox_events_callback_conference_invite(
Tox_Dispatch *dispatch, tox_events_conference_invite_cb *callback)
{
dispatch->conference_invite_callback = callback;
}
void tox_events_callback_conference_message(
Tox_Dispatch *dispatch, tox_events_conference_message_cb *callback)
{
dispatch->conference_message_callback = callback;
}
void tox_events_callback_conference_peer_list_changed(
Tox_Dispatch *dispatch, tox_events_conference_peer_list_changed_cb *callback)
{
dispatch->conference_peer_list_changed_callback = callback;
}
void tox_events_callback_conference_peer_name(
Tox_Dispatch *dispatch, tox_events_conference_peer_name_cb *callback)
{
dispatch->conference_peer_name_callback = callback;
}
void tox_events_callback_conference_title(
Tox_Dispatch *dispatch, tox_events_conference_title_cb *callback)
{
dispatch->conference_title_callback = callback;
}
void tox_events_callback_file_chunk_request(
Tox_Dispatch *dispatch, tox_events_file_chunk_request_cb *callback)
{
dispatch->file_chunk_request_callback = callback;
}
void tox_events_callback_file_recv(
Tox_Dispatch *dispatch, tox_events_file_recv_cb *callback)
{
dispatch->file_recv_callback = callback;
}
void tox_events_callback_file_recv_chunk(
Tox_Dispatch *dispatch, tox_events_file_recv_chunk_cb *callback)
{
dispatch->file_recv_chunk_callback = callback;
}
void tox_events_callback_file_recv_control(
Tox_Dispatch *dispatch, tox_events_file_recv_control_cb *callback)
{
dispatch->file_recv_control_callback = callback;
}
void tox_events_callback_friend_connection_status(
Tox_Dispatch *dispatch, tox_events_friend_connection_status_cb *callback)
{
dispatch->friend_connection_status_callback = callback;
}
void tox_events_callback_friend_lossless_packet(
Tox_Dispatch *dispatch, tox_events_friend_lossless_packet_cb *callback)
{
dispatch->friend_lossless_packet_callback = callback;
}
void tox_events_callback_friend_lossy_packet(
Tox_Dispatch *dispatch, tox_events_friend_lossy_packet_cb *callback)
{
dispatch->friend_lossy_packet_callback = callback;
}
void tox_events_callback_friend_message(
Tox_Dispatch *dispatch, tox_events_friend_message_cb *callback)
{
dispatch->friend_message_callback = callback;
}
void tox_events_callback_friend_name(
Tox_Dispatch *dispatch, tox_events_friend_name_cb *callback)
{
dispatch->friend_name_callback = callback;
}
void tox_events_callback_friend_read_receipt(
Tox_Dispatch *dispatch, tox_events_friend_read_receipt_cb *callback)
{
dispatch->friend_read_receipt_callback = callback;
}
void tox_events_callback_friend_request(
Tox_Dispatch *dispatch, tox_events_friend_request_cb *callback)
{
dispatch->friend_request_callback = callback;
}
void tox_events_callback_friend_status(
Tox_Dispatch *dispatch, tox_events_friend_status_cb *callback)
{
dispatch->friend_status_callback = callback;
}
void tox_events_callback_friend_status_message(
Tox_Dispatch *dispatch, tox_events_friend_status_message_cb *callback)
{
dispatch->friend_status_message_callback = callback;
}
void tox_events_callback_friend_typing(
Tox_Dispatch *dispatch, tox_events_friend_typing_cb *callback)
{
dispatch->friend_typing_callback = callback;
}
void tox_events_callback_self_connection_status(
Tox_Dispatch *dispatch, tox_events_self_connection_status_cb *callback)
{
dispatch->self_connection_status_callback = callback;
}
static void tox_dispatch_invoke_conference_connected(
const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data)
{
const uint32_t size = tox_events_get_conference_connected_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (dispatch->conference_connected_callback != nullptr) {
dispatch->conference_connected_callback(
tox, tox_events_get_conference_connected(events, i), user_data);
}
}
}
static void tox_dispatch_invoke_conference_invite(
const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data)
{
const uint32_t size = tox_events_get_conference_invite_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (dispatch->conference_invite_callback != nullptr) {
dispatch->conference_invite_callback(
tox, tox_events_get_conference_invite(events, i), user_data);
}
}
}
static void tox_dispatch_invoke_conference_message(
const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data)
{
const uint32_t size = tox_events_get_conference_message_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (dispatch->conference_message_callback != nullptr) {
dispatch->conference_message_callback(
tox, tox_events_get_conference_message(events, i), user_data);
}
}
}
static void tox_dispatch_invoke_conference_peer_list_changed(
const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data)
{
const uint32_t size = tox_events_get_conference_peer_list_changed_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (dispatch->conference_peer_list_changed_callback != nullptr) {
dispatch->conference_peer_list_changed_callback(
tox, tox_events_get_conference_peer_list_changed(events, i), user_data);
}
}
}
static void tox_dispatch_invoke_conference_peer_name(
const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data)
{
const uint32_t size = tox_events_get_conference_peer_name_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (dispatch->conference_peer_name_callback != nullptr) {
dispatch->conference_peer_name_callback(
tox, tox_events_get_conference_peer_name(events, i), user_data);
}
}
}
static void tox_dispatch_invoke_conference_title(
const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data)
{
const uint32_t size = tox_events_get_conference_title_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (dispatch->conference_title_callback != nullptr) {
dispatch->conference_title_callback(
tox, tox_events_get_conference_title(events, i), user_data);
}
}
}
static void tox_dispatch_invoke_file_chunk_request(
const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data)
{
const uint32_t size = tox_events_get_file_chunk_request_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (dispatch->file_chunk_request_callback != nullptr) {
dispatch->file_chunk_request_callback(
tox, tox_events_get_file_chunk_request(events, i), user_data);
}
}
}
static void tox_dispatch_invoke_file_recv(
const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data)
{
const uint32_t size = tox_events_get_file_recv_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (dispatch->file_recv_callback != nullptr) {
dispatch->file_recv_callback(
tox, tox_events_get_file_recv(events, i), user_data);
}
}
}
static void tox_dispatch_invoke_file_recv_chunk(
const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data)
{
const uint32_t size = tox_events_get_file_recv_chunk_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (dispatch->file_recv_chunk_callback != nullptr) {
dispatch->file_recv_chunk_callback(
tox, tox_events_get_file_recv_chunk(events, i), user_data);
}
}
}
static void tox_dispatch_invoke_file_recv_control(
const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data)
{
const uint32_t size = tox_events_get_file_recv_control_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (dispatch->file_recv_control_callback != nullptr) {
dispatch->file_recv_control_callback(
tox, tox_events_get_file_recv_control(events, i), user_data);
}
}
}
static void tox_dispatch_invoke_friend_connection_status(
const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data)
{
const uint32_t size = tox_events_get_friend_connection_status_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (dispatch->friend_connection_status_callback != nullptr) {
dispatch->friend_connection_status_callback(
tox, tox_events_get_friend_connection_status(events, i), user_data);
}
}
}
static void tox_dispatch_invoke_friend_lossless_packet(
const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data)
{
const uint32_t size = tox_events_get_friend_lossless_packet_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (dispatch->friend_lossless_packet_callback != nullptr) {
dispatch->friend_lossless_packet_callback(
tox, tox_events_get_friend_lossless_packet(events, i), user_data);
}
}
}
static void tox_dispatch_invoke_friend_lossy_packet(
const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data)
{
const uint32_t size = tox_events_get_friend_lossy_packet_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (dispatch->friend_lossy_packet_callback != nullptr) {
dispatch->friend_lossy_packet_callback(
tox, tox_events_get_friend_lossy_packet(events, i), user_data);
}
}
}
static void tox_dispatch_invoke_friend_message(
const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data)
{
const uint32_t size = tox_events_get_friend_message_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (dispatch->friend_message_callback != nullptr) {
dispatch->friend_message_callback(
tox, tox_events_get_friend_message(events, i), user_data);
}
}
}
static void tox_dispatch_invoke_friend_name(
const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data)
{
const uint32_t size = tox_events_get_friend_name_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (dispatch->friend_name_callback != nullptr) {
dispatch->friend_name_callback(
tox, tox_events_get_friend_name(events, i), user_data);
}
}
}
static void tox_dispatch_invoke_friend_read_receipt(
const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data)
{
const uint32_t size = tox_events_get_friend_read_receipt_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (dispatch->friend_read_receipt_callback != nullptr) {
dispatch->friend_read_receipt_callback(
tox, tox_events_get_friend_read_receipt(events, i), user_data);
}
}
}
static void tox_dispatch_invoke_friend_request(
const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data)
{
const uint32_t size = tox_events_get_friend_request_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (dispatch->friend_request_callback != nullptr) {
dispatch->friend_request_callback(
tox, tox_events_get_friend_request(events, i), user_data);
}
}
}
static void tox_dispatch_invoke_friend_status(
const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data)
{
const uint32_t size = tox_events_get_friend_status_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (dispatch->friend_status_callback != nullptr) {
dispatch->friend_status_callback(
tox, tox_events_get_friend_status(events, i), user_data);
}
}
}
static void tox_dispatch_invoke_friend_status_message(
const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data)
{
const uint32_t size = tox_events_get_friend_status_message_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (dispatch->friend_status_message_callback != nullptr) {
dispatch->friend_status_message_callback(
tox, tox_events_get_friend_status_message(events, i), user_data);
}
}
}
static void tox_dispatch_invoke_friend_typing(
const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data)
{
const uint32_t size = tox_events_get_friend_typing_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (dispatch->friend_typing_callback != nullptr) {
dispatch->friend_typing_callback(
tox, tox_events_get_friend_typing(events, i), user_data);
}
}
}
static void tox_dispatch_invoke_self_connection_status(
const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data)
{
const uint32_t size = tox_events_get_self_connection_status_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (dispatch->self_connection_status_callback != nullptr) {
dispatch->self_connection_status_callback(
tox, tox_events_get_self_connection_status(events, i), user_data);
}
}
}
void tox_dispatch_invoke(const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data)
{
tox_dispatch_invoke_conference_connected(dispatch, events, tox, user_data);
tox_dispatch_invoke_conference_invite(dispatch, events, tox, user_data);
tox_dispatch_invoke_conference_message(dispatch, events, tox, user_data);
tox_dispatch_invoke_conference_peer_list_changed(dispatch, events, tox, user_data);
tox_dispatch_invoke_conference_peer_name(dispatch, events, tox, user_data);
tox_dispatch_invoke_conference_title(dispatch, events, tox, user_data);
tox_dispatch_invoke_file_chunk_request(dispatch, events, tox, user_data);
tox_dispatch_invoke_file_recv(dispatch, events, tox, user_data);
tox_dispatch_invoke_file_recv_chunk(dispatch, events, tox, user_data);
tox_dispatch_invoke_file_recv_control(dispatch, events, tox, user_data);
tox_dispatch_invoke_friend_connection_status(dispatch, events, tox, user_data);
tox_dispatch_invoke_friend_lossless_packet(dispatch, events, tox, user_data);
tox_dispatch_invoke_friend_lossy_packet(dispatch, events, tox, user_data);
tox_dispatch_invoke_friend_message(dispatch, events, tox, user_data);
tox_dispatch_invoke_friend_name(dispatch, events, tox, user_data);
tox_dispatch_invoke_friend_read_receipt(dispatch, events, tox, user_data);
tox_dispatch_invoke_friend_request(dispatch, events, tox, user_data);
tox_dispatch_invoke_friend_status(dispatch, events, tox, user_data);
tox_dispatch_invoke_friend_status_message(dispatch, events, tox, user_data);
tox_dispatch_invoke_friend_typing(dispatch, events, tox, user_data);
tox_dispatch_invoke_self_connection_status(dispatch, events, tox, user_data);
}

144
toxcore/tox_dispatch.h Normal file
View File

@ -0,0 +1,144 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
*/
#ifndef C_TOXCORE_TOXCORE_TOX_DISPATCH_H
#define C_TOXCORE_TOXCORE_TOX_DISPATCH_H
#include "tox_events.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief The events dispatch table.
*
* This holds all the callbacks registered with `tox_events_callback_*`
* functions below.
*/
typedef struct Tox_Dispatch Tox_Dispatch;
typedef enum Tox_Err_Dispatch_New {
/**
* The function returned successfully.
*/
TOX_ERR_DISPATCH_NEW_OK,
/**
* The function failed to allocate memory for the dispatch table.
*/
TOX_ERR_DISPATCH_NEW_MALLOC,
} Tox_Err_Dispatch_New;
/**
* @brief Creates a new empty event dispatch table.
*/
Tox_Dispatch *tox_dispatch_new(Tox_Err_Dispatch_New *error);
/**
* @brief Deallocate an event dispatch table.
*/
void tox_dispatch_free(Tox_Dispatch *dispatch);
/**
* @brief Invoke registered callbacks for each of the events.
*
* @param dispatch The events dispatch table.
* @param events The events object received from @ref tox_events_iterate.
* @param tox The tox object to pass down to the callbacks.
* @param user_data User data pointer to pass down to the callbacks.
*/
void tox_dispatch_invoke(const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data);
typedef void tox_events_conference_connected_cb(
Tox *tox, const Tox_Event_Conference_Connected *event, void *user_data);
typedef void tox_events_conference_invite_cb(
Tox *tox, const Tox_Event_Conference_Invite *event, void *user_data);
typedef void tox_events_conference_message_cb(
Tox *tox, const Tox_Event_Conference_Message *event, void *user_data);
typedef void tox_events_conference_peer_list_changed_cb(
Tox *tox, const Tox_Event_Conference_Peer_List_Changed *event, void *user_data);
typedef void tox_events_conference_peer_name_cb(
Tox *tox, const Tox_Event_Conference_Peer_Name *event, void *user_data);
typedef void tox_events_conference_title_cb(
Tox *tox, const Tox_Event_Conference_Title *event, void *user_data);
typedef void tox_events_file_chunk_request_cb(
Tox *tox, const Tox_Event_File_Chunk_Request *event, void *user_data);
typedef void tox_events_file_recv_cb(
Tox *tox, const Tox_Event_File_Recv *event, void *user_data);
typedef void tox_events_file_recv_chunk_cb(
Tox *tox, const Tox_Event_File_Recv_Chunk *event, void *user_data);
typedef void tox_events_file_recv_control_cb(
Tox *tox, const Tox_Event_File_Recv_Control *event, void *user_data);
typedef void tox_events_friend_connection_status_cb(
Tox *tox, const Tox_Event_Friend_Connection_Status *event, void *user_data);
typedef void tox_events_friend_lossless_packet_cb(
Tox *tox, const Tox_Event_Friend_Lossless_Packet *event, void *user_data);
typedef void tox_events_friend_lossy_packet_cb(
Tox *tox, const Tox_Event_Friend_Lossy_Packet *event, void *user_data);
typedef void tox_events_friend_message_cb(
Tox *tox, const Tox_Event_Friend_Message *event, void *user_data);
typedef void tox_events_friend_name_cb(
Tox *tox, const Tox_Event_Friend_Name *event, void *user_data);
typedef void tox_events_friend_read_receipt_cb(
Tox *tox, const Tox_Event_Friend_Read_Receipt *event, void *user_data);
typedef void tox_events_friend_request_cb(
Tox *tox, const Tox_Event_Friend_Request *event, void *user_data);
typedef void tox_events_friend_status_cb(
Tox *tox, const Tox_Event_Friend_Status *event, void *user_data);
typedef void tox_events_friend_status_message_cb(
Tox *tox, const Tox_Event_Friend_Status_Message *event, void *user_data);
typedef void tox_events_friend_typing_cb(
Tox *tox, const Tox_Event_Friend_Typing *event, void *user_data);
typedef void tox_events_self_connection_status_cb(
Tox *tox, const Tox_Event_Self_Connection_Status *event, void *user_data);
void tox_events_callback_conference_connected(
Tox_Dispatch *dispatch, tox_events_conference_connected_cb *callback);
void tox_events_callback_conference_invite(
Tox_Dispatch *dispatch, tox_events_conference_invite_cb *callback);
void tox_events_callback_conference_message(
Tox_Dispatch *dispatch, tox_events_conference_message_cb *callback);
void tox_events_callback_conference_peer_list_changed(
Tox_Dispatch *dispatch, tox_events_conference_peer_list_changed_cb *callback);
void tox_events_callback_conference_peer_name(
Tox_Dispatch *dispatch, tox_events_conference_peer_name_cb *callback);
void tox_events_callback_conference_title(
Tox_Dispatch *dispatch, tox_events_conference_title_cb *callback);
void tox_events_callback_file_chunk_request(
Tox_Dispatch *dispatch, tox_events_file_chunk_request_cb *callback);
void tox_events_callback_file_recv(
Tox_Dispatch *dispatch, tox_events_file_recv_cb *callback);
void tox_events_callback_file_recv_chunk(
Tox_Dispatch *dispatch, tox_events_file_recv_chunk_cb *callback);
void tox_events_callback_file_recv_control(
Tox_Dispatch *dispatch, tox_events_file_recv_control_cb *callback);
void tox_events_callback_friend_connection_status(
Tox_Dispatch *dispatch, tox_events_friend_connection_status_cb *callback);
void tox_events_callback_friend_lossless_packet(
Tox_Dispatch *dispatch, tox_events_friend_lossless_packet_cb *callback);
void tox_events_callback_friend_lossy_packet(
Tox_Dispatch *dispatch, tox_events_friend_lossy_packet_cb *callback);
void tox_events_callback_friend_message(
Tox_Dispatch *dispatch, tox_events_friend_message_cb *callback);
void tox_events_callback_friend_name(
Tox_Dispatch *dispatch, tox_events_friend_name_cb *callback);
void tox_events_callback_friend_read_receipt(
Tox_Dispatch *dispatch, tox_events_friend_read_receipt_cb *callback);
void tox_events_callback_friend_request(
Tox_Dispatch *dispatch, tox_events_friend_request_cb *callback);
void tox_events_callback_friend_status(
Tox_Dispatch *dispatch, tox_events_friend_status_cb *callback);
void tox_events_callback_friend_status_message(
Tox_Dispatch *dispatch, tox_events_friend_status_message_cb *callback);
void tox_events_callback_friend_typing(
Tox_Dispatch *dispatch, tox_events_friend_typing_cb *callback);
void tox_events_callback_self_connection_status(
Tox_Dispatch *dispatch, tox_events_self_connection_status_cb *callback);
#ifdef __cplusplus
}
#endif
#endif // C_TOXCORE_TOXCORE_TOX_DISPATCH_H

57
toxcore/tox_events.c Normal file
View File

@ -0,0 +1,57 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
*/
#include "tox_events.h"
#include <stdlib.h>
#include <string.h>
#include "ccompat.h"
#include "events/events_alloc.h"
#include "tox.h"
/*****************************************************
*
* :: Set up event handlers.
*
*****************************************************/
void tox_events_init(Tox *tox)
{
tox_callback_conference_connected(tox, tox_events_handle_conference_connected);
tox_callback_conference_invite(tox, tox_events_handle_conference_invite);
tox_callback_conference_message(tox, tox_events_handle_conference_message);
tox_callback_conference_peer_list_changed(tox, tox_events_handle_conference_peer_list_changed);
tox_callback_conference_peer_name(tox, tox_events_handle_conference_peer_name);
tox_callback_conference_title(tox, tox_events_handle_conference_title);
tox_callback_file_chunk_request(tox, tox_events_handle_file_chunk_request);
tox_callback_file_recv_chunk(tox, tox_events_handle_file_recv_chunk);
tox_callback_file_recv_control(tox, tox_events_handle_file_recv_control);
tox_callback_file_recv(tox, tox_events_handle_file_recv);
tox_callback_friend_connection_status(tox, tox_events_handle_friend_connection_status);
tox_callback_friend_lossless_packet(tox, tox_events_handle_friend_lossless_packet);
tox_callback_friend_lossy_packet(tox, tox_events_handle_friend_lossy_packet);
tox_callback_friend_message(tox, tox_events_handle_friend_message);
tox_callback_friend_name(tox, tox_events_handle_friend_name);
tox_callback_friend_read_receipt(tox, tox_events_handle_friend_read_receipt);
tox_callback_friend_request(tox, tox_events_handle_friend_request);
tox_callback_friend_status_message(tox, tox_events_handle_friend_status_message);
tox_callback_friend_status(tox, tox_events_handle_friend_status);
tox_callback_friend_typing(tox, tox_events_handle_friend_typing);
tox_callback_self_connection_status(tox, tox_events_handle_self_connection_status);
}
Tox_Events *tox_events_iterate(Tox *tox, Tox_Err_Events_Iterate *error)
{
Tox_Events_State state = {TOX_ERR_EVENTS_ITERATE_OK};
tox_iterate(tox, &state);
if (error != nullptr) {
*error = state.error;
}
return state.events;
}

313
toxcore/tox_events.h Normal file
View File

@ -0,0 +1,313 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
*/
#ifndef C_TOXCORE_TOXCORE_TOX_EVENTS_H
#define C_TOXCORE_TOXCORE_TOX_EVENTS_H
#include "tox.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct Tox_Event_Conference_Connected Tox_Event_Conference_Connected;
uint32_t tox_event_conference_connected_get_conference_number(
const Tox_Event_Conference_Connected *conference_connected);
typedef struct Tox_Event_Conference_Invite Tox_Event_Conference_Invite;
const uint8_t *tox_event_conference_invite_get_cookie(
const Tox_Event_Conference_Invite *conference_invite);
size_t tox_event_conference_invite_get_cookie_length(
const Tox_Event_Conference_Invite *conference_invite);
Tox_Conference_Type tox_event_conference_invite_get_type(
const Tox_Event_Conference_Invite *conference_invite);
uint32_t tox_event_conference_invite_get_friend_number(
const Tox_Event_Conference_Invite *conference_invite);
typedef struct Tox_Event_Conference_Message Tox_Event_Conference_Message;
const uint8_t *tox_event_conference_message_get_message(
const Tox_Event_Conference_Message *conference_message);
size_t tox_event_conference_message_get_message_length(
const Tox_Event_Conference_Message *conference_message);
Tox_Message_Type tox_event_conference_message_get_type(
const Tox_Event_Conference_Message *conference_message);
uint32_t tox_event_conference_message_get_conference_number(
const Tox_Event_Conference_Message *conference_message);
uint32_t tox_event_conference_message_get_peer_number(
const Tox_Event_Conference_Message *conference_message);
typedef struct Tox_Event_Conference_Peer_List_Changed Tox_Event_Conference_Peer_List_Changed;
uint32_t tox_event_conference_peer_list_changed_get_conference_number(
const Tox_Event_Conference_Peer_List_Changed *conference_peer_list_changed);
typedef struct Tox_Event_Conference_Peer_Name Tox_Event_Conference_Peer_Name;
const uint8_t *tox_event_conference_peer_name_get_name(
const Tox_Event_Conference_Peer_Name *conference_peer_name);
size_t tox_event_conference_peer_name_get_name_length(
const Tox_Event_Conference_Peer_Name *conference_peer_name);
uint32_t tox_event_conference_peer_name_get_conference_number(
const Tox_Event_Conference_Peer_Name *conference_peer_name);
uint32_t tox_event_conference_peer_name_get_peer_number(
const Tox_Event_Conference_Peer_Name *conference_peer_name);
typedef struct Tox_Event_Conference_Title Tox_Event_Conference_Title;
const uint8_t *tox_event_conference_title_get_title(
const Tox_Event_Conference_Title *conference_title);
size_t tox_event_conference_title_get_title_length(
const Tox_Event_Conference_Title *conference_title);
uint32_t tox_event_conference_title_get_conference_number(
const Tox_Event_Conference_Title *conference_title);
uint32_t tox_event_conference_title_get_peer_number(
const Tox_Event_Conference_Title *conference_title);
typedef struct Tox_Event_File_Chunk_Request Tox_Event_File_Chunk_Request;
size_t tox_event_file_chunk_request_get_length(
const Tox_Event_File_Chunk_Request *file_chunk_request);
uint32_t tox_event_file_chunk_request_get_file_number(
const Tox_Event_File_Chunk_Request *file_chunk_request);
uint32_t tox_event_file_chunk_request_get_friend_number(
const Tox_Event_File_Chunk_Request *file_chunk_request);
uint64_t tox_event_file_chunk_request_get_position(
const Tox_Event_File_Chunk_Request *file_chunk_request);
typedef struct Tox_Event_File_Recv Tox_Event_File_Recv;
const uint8_t *tox_event_file_recv_get_filename(
const Tox_Event_File_Recv *file_recv);
size_t tox_event_file_recv_get_filename_length(
const Tox_Event_File_Recv *file_recv);
uint32_t tox_event_file_recv_get_file_number(
const Tox_Event_File_Recv *file_recv);
uint32_t tox_event_file_recv_get_file_size(
const Tox_Event_File_Recv *file_recv);
uint32_t tox_event_file_recv_get_friend_number(
const Tox_Event_File_Recv *file_recv);
uint32_t tox_event_file_recv_get_kind(
const Tox_Event_File_Recv *file_recv);
typedef struct Tox_Event_File_Recv_Chunk Tox_Event_File_Recv_Chunk;
const uint8_t *tox_event_file_recv_chunk_get_data(
const Tox_Event_File_Recv_Chunk *file_recv_chunk);
size_t tox_event_file_recv_chunk_get_length(
const Tox_Event_File_Recv_Chunk *file_recv_chunk);
uint32_t tox_event_file_recv_chunk_get_file_number(
const Tox_Event_File_Recv_Chunk *file_recv_chunk);
uint32_t tox_event_file_recv_chunk_get_friend_number(
const Tox_Event_File_Recv_Chunk *file_recv_chunk);
uint32_t tox_event_file_recv_chunk_get_position(
const Tox_Event_File_Recv_Chunk *file_recv_chunk);
typedef struct Tox_Event_File_Recv_Control Tox_Event_File_Recv_Control;
Tox_File_Control tox_event_file_recv_control_get_control(
const Tox_Event_File_Recv_Control *file_recv_control);
uint32_t tox_event_file_recv_control_get_file_number(
const Tox_Event_File_Recv_Control *file_recv_control);
uint32_t tox_event_file_recv_control_get_friend_number(
const Tox_Event_File_Recv_Control *file_recv_control);
typedef struct Tox_Event_Friend_Connection_Status Tox_Event_Friend_Connection_Status;
Tox_Connection tox_event_friend_connection_status_get_connection_status(
const Tox_Event_Friend_Connection_Status *friend_connection_status);
uint32_t tox_event_friend_connection_status_get_friend_number(
const Tox_Event_Friend_Connection_Status *friend_connection_status);
typedef struct Tox_Event_Friend_Lossless_Packet Tox_Event_Friend_Lossless_Packet;
const uint8_t *tox_event_friend_lossless_packet_get_data(
const Tox_Event_Friend_Lossless_Packet *friend_lossless_packet);
size_t tox_event_friend_lossless_packet_get_data_length(
const Tox_Event_Friend_Lossless_Packet *friend_lossless_packet);
uint32_t tox_event_friend_lossless_packet_get_friend_number(
const Tox_Event_Friend_Lossless_Packet *friend_lossless_packet);
typedef struct Tox_Event_Friend_Lossy_Packet Tox_Event_Friend_Lossy_Packet;
const uint8_t *tox_event_friend_lossy_packet_get_data(
const Tox_Event_Friend_Lossy_Packet *friend_lossy_packet);
size_t tox_event_friend_lossy_packet_get_data_length(
const Tox_Event_Friend_Lossy_Packet *friend_lossy_packet);
uint32_t tox_event_friend_lossy_packet_get_friend_number(
const Tox_Event_Friend_Lossy_Packet *friend_lossy_packet);
typedef struct Tox_Event_Friend_Message Tox_Event_Friend_Message;
uint32_t tox_event_friend_message_get_friend_number(
const Tox_Event_Friend_Message *friend_message);
Tox_Message_Type tox_event_friend_message_get_type(
const Tox_Event_Friend_Message *friend_message);
size_t tox_event_friend_message_get_message_length(
const Tox_Event_Friend_Message *friend_message);
const uint8_t *tox_event_friend_message_get_message(
const Tox_Event_Friend_Message *friend_message);
typedef struct Tox_Event_Friend_Name Tox_Event_Friend_Name;
const uint8_t *tox_event_friend_name_get_name(
const Tox_Event_Friend_Name *friend_name);
size_t tox_event_friend_name_get_name_length(
const Tox_Event_Friend_Name *friend_name);
uint32_t tox_event_friend_name_get_friend_number(
const Tox_Event_Friend_Name *friend_name);
typedef struct Tox_Event_Friend_Read_Receipt Tox_Event_Friend_Read_Receipt;
uint32_t tox_event_friend_read_receipt_get_friend_number(
const Tox_Event_Friend_Read_Receipt *friend_read_receipt);
uint32_t tox_event_friend_read_receipt_get_message_id(
const Tox_Event_Friend_Read_Receipt *friend_read_receipt);
typedef struct Tox_Event_Friend_Request Tox_Event_Friend_Request;
const uint8_t *tox_event_friend_request_get_message(
const Tox_Event_Friend_Request *friend_request);
const uint8_t *tox_event_friend_request_get_public_key(
const Tox_Event_Friend_Request *friend_request);
size_t tox_event_friend_request_get_message_length(
const Tox_Event_Friend_Request *friend_request);
typedef struct Tox_Event_Friend_Status Tox_Event_Friend_Status;
Tox_User_Status tox_event_friend_status_get_connection_status(
const Tox_Event_Friend_Status *friend_status);
uint32_t tox_event_friend_status_get_friend_number(
const Tox_Event_Friend_Status *friend_status);
typedef struct Tox_Event_Friend_Status_Message Tox_Event_Friend_Status_Message;
const uint8_t *tox_event_friend_status_message_get_status_message(
const Tox_Event_Friend_Status_Message *friend_status_message);
size_t tox_event_friend_status_message_get_status_message_length(
const Tox_Event_Friend_Status_Message *friend_status_message);
uint32_t tox_event_friend_status_message_get_friend_number(
const Tox_Event_Friend_Status_Message *friend_status_message);
typedef struct Tox_Event_Friend_Typing Tox_Event_Friend_Typing;
bool tox_event_friend_typing_get_typing(
const Tox_Event_Friend_Typing *friend_typing);
uint32_t tox_event_friend_typing_get_friend_number(
const Tox_Event_Friend_Typing *friend_typing);
typedef struct Tox_Event_Self_Connection_Status Tox_Event_Self_Connection_Status;
Tox_Connection tox_event_self_connection_status_get_connection_status(
const Tox_Event_Self_Connection_Status *self_connection_status);
/**
* Container object for all Tox core events.
*
* This is an immutable object once created.
*/
typedef struct Tox_Events Tox_Events;
uint32_t tox_events_get_conference_connected_size(const Tox_Events *events);
uint32_t tox_events_get_conference_invite_size(const Tox_Events *events);
uint32_t tox_events_get_conference_message_size(const Tox_Events *events);
uint32_t tox_events_get_conference_peer_list_changed_size(const Tox_Events *events);
uint32_t tox_events_get_conference_peer_name_size(const Tox_Events *events);
uint32_t tox_events_get_conference_title_size(const Tox_Events *events);
uint32_t tox_events_get_file_chunk_request_size(const Tox_Events *events);
uint32_t tox_events_get_file_recv_chunk_size(const Tox_Events *events);
uint32_t tox_events_get_file_recv_control_size(const Tox_Events *events);
uint32_t tox_events_get_file_recv_size(const Tox_Events *events);
uint32_t tox_events_get_friend_connection_status_size(const Tox_Events *events);
uint32_t tox_events_get_friend_lossless_packet_size(const Tox_Events *events);
uint32_t tox_events_get_friend_lossy_packet_size(const Tox_Events *events);
uint32_t tox_events_get_friend_message_size(const Tox_Events *events);
uint32_t tox_events_get_friend_name_size(const Tox_Events *events);
uint32_t tox_events_get_friend_read_receipt_size(const Tox_Events *events);
uint32_t tox_events_get_friend_request_size(const Tox_Events *events);
uint32_t tox_events_get_friend_status_message_size(const Tox_Events *events);
uint32_t tox_events_get_friend_status_size(const Tox_Events *events);
uint32_t tox_events_get_friend_typing_size(const Tox_Events *events);
uint32_t tox_events_get_self_connection_status_size(const Tox_Events *events);
const Tox_Event_Conference_Connected *tox_events_get_conference_connected(
const Tox_Events *events, uint32_t index);
const Tox_Event_Conference_Invite *tox_events_get_conference_invite(
const Tox_Events *events, uint32_t index);
const Tox_Event_Conference_Message *tox_events_get_conference_message(
const Tox_Events *events, uint32_t index);
const Tox_Event_Conference_Peer_List_Changed *tox_events_get_conference_peer_list_changed(
const Tox_Events *events, uint32_t index);
const Tox_Event_Conference_Peer_Name *tox_events_get_conference_peer_name(
const Tox_Events *events, uint32_t index);
const Tox_Event_Conference_Title *tox_events_get_conference_title(
const Tox_Events *events, uint32_t index);
const Tox_Event_File_Chunk_Request *tox_events_get_file_chunk_request(
const Tox_Events *events, uint32_t index);
const Tox_Event_File_Recv_Chunk *tox_events_get_file_recv_chunk(
const Tox_Events *events, uint32_t index);
const Tox_Event_File_Recv_Control *tox_events_get_file_recv_control(
const Tox_Events *events, uint32_t index);
const Tox_Event_File_Recv *tox_events_get_file_recv(
const Tox_Events *events, uint32_t index);
const Tox_Event_Friend_Connection_Status *tox_events_get_friend_connection_status(
const Tox_Events *events, uint32_t index);
const Tox_Event_Friend_Lossless_Packet *tox_events_get_friend_lossless_packet(
const Tox_Events *events, uint32_t index);
const Tox_Event_Friend_Lossy_Packet *tox_events_get_friend_lossy_packet(
const Tox_Events *events, uint32_t index);
const Tox_Event_Friend_Message *tox_events_get_friend_message(
const Tox_Events *events, uint32_t index);
const Tox_Event_Friend_Name *tox_events_get_friend_name(
const Tox_Events *events, uint32_t index);
const Tox_Event_Friend_Read_Receipt *tox_events_get_friend_read_receipt(
const Tox_Events *events, uint32_t index);
const Tox_Event_Friend_Request *tox_events_get_friend_request(
const Tox_Events *events, uint32_t index);
const Tox_Event_Friend_Status_Message *tox_events_get_friend_status_message(
const Tox_Events *events, uint32_t index);
const Tox_Event_Friend_Status *tox_events_get_friend_status(
const Tox_Events *events, uint32_t index);
const Tox_Event_Friend_Typing *tox_events_get_friend_typing(
const Tox_Events *events, uint32_t index);
const Tox_Event_Self_Connection_Status *tox_events_get_self_connection_status(
const Tox_Events *events, uint32_t index);
/**
* Initialise the events recording system.
*
* All callbacks will be set to handlers inside the events recording system.
* After this function returns, no user-defined event handlers will be
* invoked. If the client sets their own handlers after calling this function,
* the events associated with that handler will not be recorded.
*/
void tox_events_init(Tox *tox);
typedef enum Tox_Err_Events_Iterate {
/**
* The function returned successfully.
*/
TOX_ERR_EVENTS_ITERATE_OK,
/**
* The function failed to allocate enough memory to store the events.
*
* Some events may still be stored if the return value is NULL. The events
* object will always be valid (or NULL) but if this error code is set,
* the function may have missed some events.
*/
TOX_ERR_EVENTS_ITERATE_MALLOC,
} Tox_Err_Events_Iterate;
/**
* Run a single `tox_iterate` iteration and record all the events.
*
* If allocation of the top level events object fails, this returns NULL.
* Otherwise it returns an object with the recorded events in it. If an
* allocation fails while recording events, some events may be dropped.
*
* The result must be freed using `tox_events_free`.
*
* @param tox The Tox instance to iterate on.
* @param error An error code. Will be set to OK on success.
*
* @returns the recorded events structure.
*/
Tox_Events *tox_events_iterate(Tox *tox, Tox_Err_Events_Iterate *error);
/**
* Frees all memory associated with the events structure.
*
* All pointers into this object and its sub-objects, including byte buffers,
* will be invalid once this function returns.
*/
void tox_events_free(Tox_Events *events);
#ifdef __cplusplus
}
#endif
#endif // C_TOXCORE_TOXCORE_TOX_EVENTS_H