ncdc/libdc/src/channel.c

285 lines
6.5 KiB
C

#include <dc/channel.h>
#include "internal.h"
struct dc_channel_
{
dc_refable_t ref;
dc_channel_type_t type;
/* snowflake of the channel
*/
char *id;
/* Guild ID this channel belongs to, may be NULL
*/
char *guild_id;
/* Name of the channel
*/
char *name;
/* Slaneeshi filth?
*/
bool nsfw;
/* ID of last message in the channel
*/
char *last_message_id;
/* list of recipients, array of dc_account_t
*/
GPtrArray *recipients;
/* Snowflake of the owner
*/
char *owner_id;
/* ID of the parent channel or bot
*/
char *parent_id;
/* application ID of the group DM creator if it is bot-created
*/
char *application_id;
GPtrArray *messages;
};
static void dc_channel_free(dc_channel_t c)
{
return_if_true(c == NULL,);
free(c->id);
free(c->guild_id);
free(c->name);
free(c->last_message_id);
free(c->owner_id);
free(c->parent_id);
free(c->application_id);
if (c->recipients != NULL) {
g_ptr_array_unref(c->recipients);
c->recipients = NULL;
}
if (c->messages != NULL) {
g_ptr_array_unref(c->messages);
c->messages = NULL;
}
free(c);
}
dc_channel_t dc_channel_new(void)
{
dc_channel_t c = calloc(1, sizeof(struct dc_channel_));
return_if_true(c == NULL, NULL);
c->ref.cleanup = (dc_cleanup_t)dc_channel_free;
c->recipients = g_ptr_array_new_with_free_func(
(GDestroyNotify)dc_unref
);
c->messages = g_ptr_array_new_with_free_func(
(GDestroyNotify)dc_unref
);
return dc_ref(c);
}
dc_channel_t dc_channel_from_json(json_t *j)
{
json_t *v = NULL;
dc_channel_t c = dc_channel_new();
goto_if_true(!json_is_object(j), error);
v = json_object_get(j, "id");
goto_if_true(v == NULL || !json_is_string(v), error);
c->id = strdup(json_string_value(v));
v = json_object_get(j, "type");
goto_if_true(v == NULL || !json_is_integer(v), error);
c->type = json_integer_value(v);
v = json_object_get(j, "guild_id");
if (v != NULL && json_is_string(v)) {
c->guild_id = strdup(json_string_value(v));
}
v = json_object_get(j, "name");
if (v == NULL && json_is_string(v)) {
c->name = strdup(json_string_value(v));
}
v = json_object_get(j, "nsfw");
if (v != NULL && json_is_boolean(v)) {
c->nsfw = json_boolean_value(v);
}
v = json_object_get(j, "last_message_id");
if (v != NULL && json_is_string(v)) {
c->last_message_id = strdup(json_string_value(v));
}
v = json_object_get(j, "owner_id");
if (v != NULL && json_is_string(v)) {
c->owner_id = strdup(json_string_value(v));
}
v = json_object_get(j, "parent_id");
if (v != NULL && json_is_string(v)) {
c->parent_id = strdup(json_string_value(v));
}
v = json_object_get(j, "application_id");
if (v != NULL && json_is_string(v)) {
c->application_id = strdup(json_string_value(v));
}
v = json_object_get(j, "recipients");
if (v != NULL && json_is_array(v)) {
json_t *i = NULL;
size_t idx = 0;
json_array_foreach(v, idx, i) {
dc_account_t a = dc_account_from_json(i);
if (a != NULL) {
g_ptr_array_add(c->recipients, a);
}
}
}
return c;
error:
dc_unref(c);
return NULL;
}
json_t *dc_channel_to_json(dc_channel_t c)
{
json_t *j = NULL;
return_if_true(c->id == NULL, NULL);
j = json_object();
return_if_true(j == NULL, NULL);
/* I was so close in making a J_SET() macro for my lazy ass.
*/
json_object_set_new(j, "id", json_string(c->id));
json_object_set_new(j, "type", json_integer(c->type));
/* TODO: tribool to see if it was actually set, or assume "false"
* is a sane default and continue on.
*/
json_object_set_new(j, "nsfw", json_boolean(c->nsfw));
if (c->guild_id != NULL) {
json_object_set_new(j, "guild_id", json_string(c->guild_id));
}
if (c->name != NULL) {
json_object_set_new(j, "name", json_string(c->name));
}
if (c->last_message_id != NULL) {
json_object_set_new(j, "last_message_id",
json_string(c->last_message_id));
}
if (c->owner_id != NULL) {
json_object_set_new(j, "owner_id", json_string(c->owner_id));
}
if (c->parent_id != NULL) {
json_object_set_new(j, "parent_id", json_string(c->parent_id));
}
if (c->application_id != NULL) {
json_object_set_new(j, "application_id",
json_string(c->application_id));
}
if (c->recipients != NULL && c->recipients->len > 0) {
size_t i = 0;
json_t *arr = json_array();
for (i = 0; i < c->recipients->len; i++) {
dc_account_t acc = g_ptr_array_index(c->recipients, i);
json_t *a = dc_account_to_json(acc);
if (a != NULL) {
json_array_append_new(arr, a);
}
}
json_object_set_new(j, "recipients", arr);
}
return j;
}
char const *dc_channel_id(dc_channel_t c)
{
return_if_true(c == NULL, NULL);
return c->id;
}
dc_channel_type_t dc_channel_type(dc_channel_t c)
{
return_if_true(c == NULL, -1);
return c->type;
}
void dc_channel_set_type(dc_channel_t c, dc_channel_type_t t)
{
return_if_true(c == NULL,);
c->type = t;
}
size_t dc_channel_recipients(dc_channel_t c)
{
return_if_true(c == NULL || c->recipients == NULL, 0);
return c->recipients->len;
}
dc_account_t dc_channel_nthrecipient(dc_channel_t c, size_t i)
{
return_if_true(c == NULL || c->recipients == NULL, NULL);
return_if_true(i >= c->recipients->len, NULL);
return g_ptr_array_index(c->recipients, i);
}
size_t dc_channel_messages(dc_channel_t c)
{
return_if_true(c == NULL || c->messages == NULL, 0);
return c->messages->len;
}
dc_message_t dc_channel_nthmessage(dc_channel_t c, size_t i)
{
return_if_true(c == NULL || c->messages == NULL, NULL);
return_if_true(i >= c->messages->len, NULL);
return g_ptr_array_index(c->messages, i);
}
void dc_channel_addmessages(dc_channel_t c, dc_message_t *m, size_t s)
{
return_if_true(c == NULL || c->messages == NULL,);
return_if_true(m == NULL || s == 0,);
size_t i = 0;
for (i = 0; i < s; i++) {
g_ptr_array_add(c->messages, dc_ref(m[i]));
}
g_ptr_array_sort(c->messages, (GCompareFunc)dc_message_compare);
}