/*
* matrix-statetable.c
*
*
* Copyright (c) Openmarket UK Ltd 2015
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#include "matrix-statetable.h"
#include "debug.h"
#include "matrix-event.h"
#include "matrix-json.h"
/**
* create a new, empty, state table
*/
MatrixRoomStateEventTable *matrix_statetable_new()
{
return g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
(GDestroyNotify) g_hash_table_destroy);
}
void matrix_statetable_destroy(MatrixRoomStateEventTable *table)
{
g_hash_table_destroy(table);
}
/**
* look up a particular bit of state
*
* @returns null if this key ies not known
*/
MatrixRoomEvent *matrix_statetable_get_event(
MatrixRoomStateEventTable *state_table, const gchar *event_type,
const gchar *state_key)
{
GHashTable *tmp;
tmp = (GHashTable *) g_hash_table_lookup(state_table, event_type);
if(tmp == NULL)
return NULL;
return (MatrixRoomEvent *)g_hash_table_lookup(tmp, state_key);
}
/**
* Update the state table on a room
*/
void matrix_statetable_update(MatrixRoomStateEventTable *state_table,
JsonObject *json_event_obj,
MatrixStateUpdateCallback callback, gpointer user_data)
{
const gchar *event_type, *state_key, *sender;
JsonObject *json_content_obj;
MatrixRoomEvent *event, *old_event;
GHashTable *state_table_entry;
event_type = matrix_json_object_get_string_member(
json_event_obj, "type");
state_key = matrix_json_object_get_string_member(
json_event_obj, "state_key");
sender = matrix_json_object_get_string_member(
json_event_obj, "sender");
json_content_obj = matrix_json_object_get_object_member(
json_event_obj, "content");
if (g_strcmp0(event_type, "m.typing") == 0) {
// Create a fake key so we can keep track of typing state
state_key = "typing";
sender = "";
}
if(event_type == NULL || state_key == NULL || sender == NULL ||
json_content_obj == NULL) {
purple_debug_warning("matrixprpl", "event missing fields\n");
return;
}
event = matrix_event_new(event_type, json_content_obj);
event -> sender = g_strdup(sender);
state_table_entry = g_hash_table_lookup(state_table, event_type);
if(state_table_entry == NULL) {
state_table_entry = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, (GDestroyNotify)matrix_event_free);
g_hash_table_insert(state_table, g_strdup(event_type),
state_table_entry);
old_event = NULL;
} else {
old_event = g_hash_table_lookup(state_table_entry,
state_key);
}
if(callback) {
callback(event_type, state_key, old_event, event, user_data);
}
g_hash_table_insert(state_table_entry, g_strdup(state_key), event);
}
/**
* If the room has an official name, or an alias, return it
*
* @returns a string which should be freed
*/
gchar *matrix_statetable_get_room_alias(MatrixRoomStateEventTable *state_table)
{
GHashTable *tmp;
MatrixRoomEvent *event;
const gchar *tmpname = NULL;
/* start by looking for the official room name */
event = matrix_statetable_get_event(state_table, "m.room.name", "");
if(event != NULL) {
tmpname = matrix_json_object_get_string_member(
event->content, "name");
if(tmpname != NULL && tmpname[0] != '\0') {
return g_strdup(tmpname);
}
}
/* look for a canonical alias */
event = matrix_statetable_get_event(state_table, "m.room.canonical_alias",
"");
if(event != NULL) {
tmpname = matrix_json_object_get_string_member(
event->content, "alias");
if(tmpname != NULL) {
return g_strdup(tmpname);
}
}
/* look for an alias */
tmp = (GHashTable *) g_hash_table_lookup(state_table, "m.room.aliases");
if(tmp != NULL) {
GHashTableIter iter;
gpointer key, value;
g_hash_table_iter_init(&iter, tmp);
while(g_hash_table_iter_next(&iter, &key, &value)) {
MatrixRoomEvent *event = value;
JsonArray *array = matrix_json_object_get_array_member(
event->content, "aliases");
if(array != NULL && json_array_get_length(array) > 0) {
tmpname = matrix_json_array_get_string_element(array, 0);
if(tmpname != NULL) {
return g_strdup(tmpname);
}
}
}
}
return NULL;
}