diff options
author | David Laban <david.laban@collabora.co.uk> | 2011-05-17 20:18:19 -0400 |
---|---|---|
committer | David Laban <david.laban@collabora.co.uk> | 2011-05-17 20:18:19 -0400 |
commit | f796a5a882dd57f56b08be817d4d929643970d25 (patch) | |
tree | 6ffd06ca25df59f920d4de331bb8a15acf2724e4 /telepathy-logger/log-store-xml.c | |
parent | dc17262c8b8690801b76b62caa8d7cb78ad11a2f (diff) | |
download | telepathy-logger-f796a5a882dd57f56b08be817d4d929643970d25.tar.gz |
log_store_xml_get_events_for_file: replace edited messages.
This should support "b supersedes a ; c supersedes a" as well as
"b supersedes a ; c supersedes b"
Also, the list of returned events should only contain the most recent
version (for backwards compat with dumb log viewers, as suggested by
sjoerd).
* make a event_queue_add_text_event responsible for adding the event to
the returned gqueue (replacing the event it supersedes as needed).
* use a GHashTable of {token: place to put message} for already edited
messages, and check that first, then walk through the queue (starting
at the most recent event) trying to find it.
* add a dummy event if none can be found.
Diffstat (limited to 'telepathy-logger/log-store-xml.c')
-rw-r--r-- | telepathy-logger/log-store-xml.c | 84 |
1 files changed, 78 insertions, 6 deletions
diff --git a/telepathy-logger/log-store-xml.c b/telepathy-logger/log-store-xml.c index 045cdb9..89dd08c 100644 --- a/telepathy-logger/log-store-xml.c +++ b/telepathy-logger/log-store-xml.c @@ -1261,6 +1261,68 @@ event_queue_insert_sorted_after (GQueue *events, } } +static GList * +event_queue_add_text_event (GQueue *events, + GList *index, + GHashTable *superseded_links, + TplTextEvent *event) +{ + GList *l = NULL; + const gchar *supersedes_token = tpl_text_event_get_supersedes_token (event); + TplTextEvent *dummy_event; + + if (supersedes_token == NULL) + return event_queue_insert_sorted_after (events, index, TPL_EVENT (event)); + + l = g_hash_table_lookup (superseded_links, supersedes_token); + if (l != NULL) + { + tpl_text_event_add_supersedes (event, l->data); + g_object_unref (l->data); + l->data = event; + g_hash_table_insert (superseded_links, (gpointer) supersedes_token, l); + return index; + } + + /* Search backwards from "now" and insert (but don't update "now") */ + for (l = index; l != NULL; l = l->prev) + { + if (!tp_strdiff (tpl_text_event_get_message_token (l->data), + supersedes_token)) + { + tpl_text_event_add_supersedes (event, l->data); + g_object_unref (l->data); + l->data = event; + g_hash_table_insert (superseded_links, (gpointer) supersedes_token, l); + return index; + } + } + + DEBUG ("Can't find event %s (superseded by %s). " + "Better <s>drink my own piss</s> fake it.", + supersedes_token, tpl_text_event_get_message_token (event)); + + dummy_event = g_object_new (TPL_TYPE_TEXT_EVENT, + /* TplEvent */ + "account", tpl_event_get_account (TPL_EVENT (event)), + /* MISSING: "channel-path", channel_path, */ + "receiver", tpl_event_get_receiver (TPL_EVENT (event)), + "sender", tpl_event_get_sender (TPL_EVENT (event)), + "timestamp", tpl_event_get_timestamp (TPL_EVENT (event)), + /* TplTextEvent */ + "message-type", tpl_text_event_get_message_type (event), + "message", "", + "message-token", supersedes_token, + NULL); + + tpl_text_event_add_supersedes (event, dummy_event); + index = event_queue_insert_sorted_after (events, index, + TPL_EVENT (event)); + g_hash_table_insert (superseded_links, (gpointer) supersedes_token, + index); + return index; +} + /* returns a Glist of TplEvent instances */ static void log_store_xml_get_events_for_file (TplLogStoreXml *self, @@ -1278,6 +1340,7 @@ log_store_xml_get_events_for_file (TplLogStoreXml *self, gchar *tmp; gchar *target_id; gchar *self_id; + GHashTable *supersedes_links; GError *error = NULL; guint num_events = 0; GList *index; @@ -1340,6 +1403,11 @@ log_store_xml_get_events_for_file (TplLogStoreXml *self, g_free (dirname); g_free (tmp); + /* Temporary hash from borrowed supersedes-token to borrowed link in + * events, so that we can efficiently replace repeatedly superseded + * events as their replacements come in. */ + supersedes_links = g_hash_table_new (g_str_hash, g_str_equal); + /* Now get the events. */ index = events->head; for (node = log_node->children; node; node = node->next) @@ -1348,15 +1416,18 @@ log_store_xml_get_events_for_file (TplLogStoreXml *self, if (type == TPL_TYPE_TEXT_EVENT && strcmp ((const gchar *) node->name, "message") == 0) - event = parse_text_node (self, node, is_room, target_id, self_id, - account); + { + event = parse_text_node (self, node, is_room, target_id, self_id, + account); + index = event_queue_add_text_event (events, index, + supersedes_links, TPL_TEXT_EVENT (event)); + num_events++; + } else if (type == TPL_TYPE_CALL_EVENT && strcmp ((const char*) node->name, "call") == 0) - event = parse_call_node (self, node, is_room, target_id, self_id, - account); - - if (event != NULL) { + event = parse_call_node (self, node, is_room, target_id, self_id, + account); index = event_queue_insert_sorted_after (events, index, event); num_events++; } @@ -1367,6 +1438,7 @@ log_store_xml_get_events_for_file (TplLogStoreXml *self, g_free (target_id); xmlFreeDoc (doc); xmlFreeParserCtxt (ctxt); + g_hash_table_destroy (supersedes_links); } |