diff options
author | TheJackiMonster <thejackimonster@gmail.com> | 2021-07-25 17:09:02 +0200 |
---|---|---|
committer | TheJackiMonster <thejackimonster@gmail.com> | 2021-07-25 17:09:02 +0200 |
commit | e19d4dedf548d6b16f95a97f6b67fd2a09a18643 (patch) | |
tree | a49986fa2a5c0e787e8a84649e4436f742f6affe | |
parent | e068078b3ae07d67e9d4b75574075773a88c4a3d (diff) | |
download | libgnunetchat-e19d4dedf548d6b16f95a97f6b67fd2a09a18643.tar.gz libgnunetchat-e19d4dedf548d6b16f95a97f6b67fd2a09a18643.zip |
Implemented read receipts and deletion
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-rw-r--r-- | include/gnunet_chat_lib.h | 7 | ||||
-rw-r--r-- | src/gnunet_chat_context.c | 8 | ||||
-rw-r--r-- | src/gnunet_chat_context.h | 1 | ||||
-rw-r--r-- | src/gnunet_chat_context_intern.c | 10 | ||||
-rw-r--r-- | src/gnunet_chat_handle_intern.c | 41 | ||||
-rw-r--r-- | src/gnunet_chat_lib.c | 30 | ||||
-rw-r--r-- | src/gnunet_chat_lib_intern.c | 45 | ||||
-rw-r--r-- | src/gnunet_chat_message.c | 9 | ||||
-rw-r--r-- | src/gnunet_chat_message.h | 3 | ||||
-rw-r--r-- | src/gnunet_chat_message_intern.c | 135 |
10 files changed, 128 insertions, 161 deletions
diff --git a/include/gnunet_chat_lib.h b/include/gnunet_chat_lib.h index 9734644..881938c 100644 --- a/include/gnunet_chat_lib.h +++ b/include/gnunet_chat_lib.h | |||
@@ -31,6 +31,7 @@ | |||
31 | 31 | ||
32 | #include <gnunet/platform.h> | 32 | #include <gnunet/platform.h> |
33 | #include <gnunet/gnunet_common.h> | 33 | #include <gnunet/gnunet_common.h> |
34 | #include <gnunet/gnunet_time_lib.h> | ||
34 | #include <gnunet/gnunet_util_lib.h> | 35 | #include <gnunet/gnunet_util_lib.h> |
35 | 36 | ||
36 | /** | 37 | /** |
@@ -184,8 +185,8 @@ typedef int | |||
184 | * @return | 185 | * @return |
185 | */ | 186 | */ |
186 | typedef int | 187 | typedef int |
187 | (*GNUNET_CHAT_MessageReadReceiptCallback) (void *cls, struct GNUNET_CHAT_Message *message, | 188 | (*GNUNET_CHAT_MessageReadReceiptCallback) (void *cls, const struct GNUNET_CHAT_Message *message, |
188 | struct GNUNET_CHAT_Contact *contact, | 189 | const struct GNUNET_CHAT_Contact *contact, |
189 | int read_receipt); | 190 | int read_receipt); |
190 | 191 | ||
191 | /** | 192 | /** |
@@ -373,7 +374,7 @@ GNUNET_CHAT_contact_set_user_pointer (struct GNUNET_CHAT_Contact *contact, | |||
373 | * @return | 374 | * @return |
374 | */ | 375 | */ |
375 | void* | 376 | void* |
376 | GNUNET_CHAT_contact_get_user_pointer (struct GNUNET_CHAT_Contact *contact); | 377 | GNUNET_CHAT_contact_get_user_pointer (const struct GNUNET_CHAT_Contact *contact); |
377 | 378 | ||
378 | /** | 379 | /** |
379 | * TODO | 380 | * TODO |
diff --git a/src/gnunet_chat_context.c b/src/gnunet_chat_context.c index 1124fd2..caca1f0 100644 --- a/src/gnunet_chat_context.c +++ b/src/gnunet_chat_context.c | |||
@@ -39,6 +39,7 @@ context_create_from_room (struct GNUNET_CHAT_Handle *handle, | |||
39 | context->type = GNUNET_CHAT_CONTEXT_TYPE_UNKNOWN; | 39 | context->type = GNUNET_CHAT_CONTEXT_TYPE_UNKNOWN; |
40 | context->nick = NULL; | 40 | context->nick = NULL; |
41 | 41 | ||
42 | context->timestamps = GNUNET_CONTAINER_multishortmap_create(8, GNUNET_NO); | ||
42 | context->messages = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); | 43 | context->messages = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); |
43 | context->invites = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); | 44 | context->invites = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); |
44 | context->files = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); | 45 | context->files = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); |
@@ -53,14 +54,19 @@ context_create_from_room (struct GNUNET_CHAT_Handle *handle, | |||
53 | void | 54 | void |
54 | context_destroy (struct GNUNET_CHAT_Context* context) | 55 | context_destroy (struct GNUNET_CHAT_Context* context) |
55 | { | 56 | { |
57 | GNUNET_CONTAINER_multishortmap_iterate( | ||
58 | context->timestamps, it_destroy_context_timestamps, NULL | ||
59 | ); | ||
60 | |||
56 | GNUNET_CONTAINER_multihashmap_iterate( | 61 | GNUNET_CONTAINER_multihashmap_iterate( |
57 | context->messages, it_destroy_context_messages, NULL | 62 | context->messages, it_destroy_context_messages, NULL |
58 | ); | 63 | ); |
59 | 64 | ||
60 | GNUNET_CONTAINER_multihashmap_iterate( | 65 | GNUNET_CONTAINER_multihashmap_iterate( |
61 | context->messages, it_destroy_context_invites, NULL | 66 | context->invites, it_destroy_context_invites, NULL |
62 | ); | 67 | ); |
63 | 68 | ||
69 | GNUNET_CONTAINER_multishortmap_destroy(context->timestamps); | ||
64 | GNUNET_CONTAINER_multihashmap_destroy(context->messages); | 70 | GNUNET_CONTAINER_multihashmap_destroy(context->messages); |
65 | GNUNET_CONTAINER_multihashmap_destroy(context->invites); | 71 | GNUNET_CONTAINER_multihashmap_destroy(context->invites); |
66 | GNUNET_CONTAINER_multihashmap_destroy(context->files); | 72 | GNUNET_CONTAINER_multihashmap_destroy(context->files); |
diff --git a/src/gnunet_chat_context.h b/src/gnunet_chat_context.h index 81e03c3..cb4528a 100644 --- a/src/gnunet_chat_context.h +++ b/src/gnunet_chat_context.h | |||
@@ -48,6 +48,7 @@ struct GNUNET_CHAT_Context | |||
48 | enum GNUNET_CHAT_ContextType type; | 48 | enum GNUNET_CHAT_ContextType type; |
49 | char *nick; | 49 | char *nick; |
50 | 50 | ||
51 | struct GNUNET_CONTAINER_MultiShortmap *timestamps; | ||
51 | struct GNUNET_CONTAINER_MultiHashMap *messages; | 52 | struct GNUNET_CONTAINER_MultiHashMap *messages; |
52 | struct GNUNET_CONTAINER_MultiHashMap *invites; | 53 | struct GNUNET_CONTAINER_MultiHashMap *invites; |
53 | struct GNUNET_CONTAINER_MultiHashMap *files; | 54 | struct GNUNET_CONTAINER_MultiHashMap *files; |
diff --git a/src/gnunet_chat_context_intern.c b/src/gnunet_chat_context_intern.c index af35e60..1ae146e 100644 --- a/src/gnunet_chat_context_intern.c +++ b/src/gnunet_chat_context_intern.c | |||
@@ -28,6 +28,16 @@ | |||
28 | #define GNUNET_UNUSED __attribute__ ((unused)) | 28 | #define GNUNET_UNUSED __attribute__ ((unused)) |
29 | 29 | ||
30 | int | 30 | int |
31 | it_destroy_context_timestamps (GNUNET_UNUSED void *cls, | ||
32 | GNUNET_UNUSED const struct GNUNET_ShortHashCode *key, | ||
33 | void *value) | ||
34 | { | ||
35 | struct GNUNET_TIME_Absolute *time = value; | ||
36 | GNUNET_free(time); | ||
37 | return GNUNET_YES; | ||
38 | } | ||
39 | |||
40 | int | ||
31 | it_destroy_context_messages (GNUNET_UNUSED void *cls, | 41 | it_destroy_context_messages (GNUNET_UNUSED void *cls, |
32 | GNUNET_UNUSED const struct GNUNET_HashCode *key, | 42 | GNUNET_UNUSED const struct GNUNET_HashCode *key, |
33 | void *value) | 43 | void *value) |
diff --git a/src/gnunet_chat_handle_intern.c b/src/gnunet_chat_handle_intern.c index ede1eb7..bcf0508 100644 --- a/src/gnunet_chat_handle_intern.c +++ b/src/gnunet_chat_handle_intern.c | |||
@@ -279,6 +279,37 @@ on_handle_message (void *cls, | |||
279 | if (!context) | 279 | if (!context) |
280 | return; | 280 | return; |
281 | 281 | ||
282 | const struct GNUNET_TIME_Absolute timestamp = GNUNET_TIME_absolute_ntoh( | ||
283 | msg->header.timestamp | ||
284 | ); | ||
285 | |||
286 | struct GNUNET_ShortHashCode shorthash; | ||
287 | util_shorthash_from_member(sender, &shorthash); | ||
288 | |||
289 | struct GNUNET_TIME_Absolute *time = GNUNET_CONTAINER_multishortmap_get( | ||
290 | context->timestamps, &shorthash | ||
291 | ); | ||
292 | |||
293 | if (time) | ||
294 | { | ||
295 | time = GNUNET_new(struct GNUNET_TIME_Absolute); | ||
296 | *time = timestamp; | ||
297 | |||
298 | if (GNUNET_OK != GNUNET_CONTAINER_multishortmap_put( | ||
299 | context->timestamps, &shorthash, time, | ||
300 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
301 | GNUNET_free(time); | ||
302 | } | ||
303 | else | ||
304 | { | ||
305 | struct GNUNET_TIME_Relative delta = GNUNET_TIME_absolute_get_difference( | ||
306 | timestamp, *time | ||
307 | ); | ||
308 | |||
309 | if (GNUNET_TIME_relative_get_zero_().rel_value_us == delta.rel_value_us) | ||
310 | *time = timestamp; | ||
311 | } | ||
312 | |||
282 | struct GNUNET_CHAT_Message *message = GNUNET_CONTAINER_multihashmap_get( | 313 | struct GNUNET_CHAT_Message *message = GNUNET_CONTAINER_multihashmap_get( |
283 | context->messages, hash | 314 | context->messages, hash |
284 | ); | 315 | ); |
@@ -319,6 +350,16 @@ on_handle_message (void *cls, | |||
319 | file_destroy(file); | 350 | file_destroy(file); |
320 | break; | 351 | break; |
321 | } | 352 | } |
353 | case GNUNET_MESSENGER_KIND_DELETE: | ||
354 | { | ||
355 | struct GNUNET_CHAT_Message *target = GNUNET_CONTAINER_multihashmap_get( | ||
356 | context->messages, &(msg->body.deletion.hash) | ||
357 | ); | ||
358 | |||
359 | if (target) | ||
360 | target->msg = NULL; | ||
361 | break; | ||
362 | } | ||
322 | default: | 363 | default: |
323 | break; | 364 | break; |
324 | } | 365 | } |
diff --git a/src/gnunet_chat_lib.c b/src/gnunet_chat_lib.c index 8be813b..a835e48 100644 --- a/src/gnunet_chat_lib.c +++ b/src/gnunet_chat_lib.c | |||
@@ -306,7 +306,7 @@ GNUNET_CHAT_contact_set_user_pointer (struct GNUNET_CHAT_Contact *contact, | |||
306 | 306 | ||
307 | 307 | ||
308 | void* | 308 | void* |
309 | GNUNET_CHAT_contact_get_user_pointer (struct GNUNET_CHAT_Contact *contact) | 309 | GNUNET_CHAT_contact_get_user_pointer (const struct GNUNET_CHAT_Contact *contact) |
310 | { | 310 | { |
311 | if (!contact) | 311 | if (!contact) |
312 | return NULL; | 312 | return NULL; |
@@ -611,7 +611,7 @@ GNUNET_CHAT_context_iterate_messages (struct GNUNET_CHAT_Context *context, | |||
611 | enum GNUNET_CHAT_MessageKind | 611 | enum GNUNET_CHAT_MessageKind |
612 | GNUNET_CHAT_message_get_kind (const struct GNUNET_CHAT_Message *message) | 612 | GNUNET_CHAT_message_get_kind (const struct GNUNET_CHAT_Message *message) |
613 | { | 613 | { |
614 | if (!message) | 614 | if ((!message) || (!(message->msg))) |
615 | return GNUNET_CHAT_KIND_UNKNOWN; | 615 | return GNUNET_CHAT_KIND_UNKNOWN; |
616 | 616 | ||
617 | switch (message->msg->header.kind) | 617 | switch (message->msg->header.kind) |
@@ -641,7 +641,7 @@ GNUNET_CHAT_message_get_kind (const struct GNUNET_CHAT_Message *message) | |||
641 | struct GNUNET_TIME_Absolute | 641 | struct GNUNET_TIME_Absolute |
642 | GNUNET_CHAT_message_get_timestamp (const struct GNUNET_CHAT_Message *message) | 642 | GNUNET_CHAT_message_get_timestamp (const struct GNUNET_CHAT_Message *message) |
643 | { | 643 | { |
644 | if (!message) | 644 | if ((!message) || (!(message->msg))) |
645 | return GNUNET_TIME_absolute_get_zero_(); | 645 | return GNUNET_TIME_absolute_get_zero_(); |
646 | 646 | ||
647 | return GNUNET_TIME_absolute_ntoh(message->msg->header.timestamp); | 647 | return GNUNET_TIME_absolute_ntoh(message->msg->header.timestamp); |
@@ -701,19 +701,29 @@ GNUNET_CHAT_message_get_read_receipt (const struct GNUNET_CHAT_Message *message, | |||
701 | GNUNET_CHAT_MessageReadReceiptCallback callback, | 701 | GNUNET_CHAT_MessageReadReceiptCallback callback, |
702 | void *cls) | 702 | void *cls) |
703 | { | 703 | { |
704 | if (!message) | 704 | if ((!message) || (!(message->msg))) |
705 | return GNUNET_SYSERR; | 705 | return GNUNET_SYSERR; |
706 | 706 | ||
707 | // TODO: request read receipt? / check if newer message was received of sender? | 707 | struct GNUNET_CHAT_Context *context = message->context; |
708 | 708 | ||
709 | return GNUNET_SYSERR; | 709 | if (!context) |
710 | return GNUNET_SYSERR; | ||
711 | |||
712 | struct GNUNET_CHAT_MessageIterateReadReceipts it; | ||
713 | it.message = message; | ||
714 | it.cb = callback; | ||
715 | it.cls = cls; | ||
716 | |||
717 | return GNUNET_MESSENGER_iterate_members( | ||
718 | context->room, it_message_iterate_read_receipts, &it | ||
719 | ); | ||
710 | } | 720 | } |
711 | 721 | ||
712 | 722 | ||
713 | const char* | 723 | const char* |
714 | GNUNET_CHAT_message_get_text (const struct GNUNET_CHAT_Message *message) | 724 | GNUNET_CHAT_message_get_text (const struct GNUNET_CHAT_Message *message) |
715 | { | 725 | { |
716 | if (!message) | 726 | if ((!message) || (!(message->msg))) |
717 | return NULL; | 727 | return NULL; |
718 | 728 | ||
719 | if (GNUNET_MESSENGER_KIND_TEXT != message->msg->header.kind) | 729 | if (GNUNET_MESSENGER_KIND_TEXT != message->msg->header.kind) |
@@ -726,7 +736,7 @@ GNUNET_CHAT_message_get_text (const struct GNUNET_CHAT_Message *message) | |||
726 | struct GNUNET_CHAT_File* | 736 | struct GNUNET_CHAT_File* |
727 | GNUNET_CHAT_message_get_file (const struct GNUNET_CHAT_Message *message) | 737 | GNUNET_CHAT_message_get_file (const struct GNUNET_CHAT_Message *message) |
728 | { | 738 | { |
729 | if (!message) | 739 | if ((!message) || (!(message->msg))) |
730 | return NULL; | 740 | return NULL; |
731 | 741 | ||
732 | if (GNUNET_MESSENGER_KIND_FILE != message->msg->header.kind) | 742 | if (GNUNET_MESSENGER_KIND_FILE != message->msg->header.kind) |
@@ -742,7 +752,7 @@ GNUNET_CHAT_message_get_file (const struct GNUNET_CHAT_Message *message) | |||
742 | struct GNUNET_CHAT_Invitation* | 752 | struct GNUNET_CHAT_Invitation* |
743 | GNUNET_CHAT_message_get_invitation (const struct GNUNET_CHAT_Message *message) | 753 | GNUNET_CHAT_message_get_invitation (const struct GNUNET_CHAT_Message *message) |
744 | { | 754 | { |
745 | if (!message) | 755 | if ((!message) || (!(message->msg))) |
746 | return NULL; | 756 | return NULL; |
747 | 757 | ||
748 | if (GNUNET_MESSENGER_KIND_INVITE != message->msg->header.kind) | 758 | if (GNUNET_MESSENGER_KIND_INVITE != message->msg->header.kind) |
@@ -759,7 +769,7 @@ int | |||
759 | GNUNET_CHAT_message_delete (const struct GNUNET_CHAT_Message *message, | 769 | GNUNET_CHAT_message_delete (const struct GNUNET_CHAT_Message *message, |
760 | struct GNUNET_TIME_Relative delay) | 770 | struct GNUNET_TIME_Relative delay) |
761 | { | 771 | { |
762 | if (!message) | 772 | if ((!message) || (!(message->msg))) |
763 | return GNUNET_SYSERR; | 773 | return GNUNET_SYSERR; |
764 | 774 | ||
765 | struct GNUNET_MESSENGER_Message msg; | 775 | struct GNUNET_MESSENGER_Message msg; |
diff --git a/src/gnunet_chat_lib_intern.c b/src/gnunet_chat_lib_intern.c index 8ccfce5..584ebab 100644 --- a/src/gnunet_chat_lib_intern.c +++ b/src/gnunet_chat_lib_intern.c | |||
@@ -117,8 +117,53 @@ it_context_iterate_messages (void *cls, | |||
117 | return it->cb(it->cls, it->context, message); | 117 | return it->cb(it->cls, it->context, message); |
118 | } | 118 | } |
119 | 119 | ||
120 | struct GNUNET_CHAT_MessageIterateReadReceipts | ||
121 | { | ||
122 | const struct GNUNET_CHAT_Message *message; | ||
123 | GNUNET_CHAT_MessageReadReceiptCallback cb; | ||
124 | void *cls; | ||
125 | }; | ||
126 | |||
127 | int | ||
128 | it_message_iterate_read_receipts (void *cls, | ||
129 | GNUNET_UNUSED struct GNUNET_MESSENGER_Room *room, | ||
130 | const struct GNUNET_MESSENGER_Contact *member) | ||
131 | { | ||
132 | struct GNUNET_CHAT_MessageIterateReadReceipts *it = cls; | ||
133 | struct GNUNET_CHAT_Handle *handle = it->message->context->handle; | ||
134 | |||
135 | if (!handle) | ||
136 | return GNUNET_NO; | ||
137 | |||
138 | struct GNUNET_ShortHashCode shorthash; | ||
139 | util_shorthash_from_member(member, &shorthash); | ||
120 | 140 | ||
141 | struct GNUNET_CHAT_Contact *contact = GNUNET_CONTAINER_multishortmap_get( | ||
142 | handle->contacts, &shorthash | ||
143 | ); | ||
144 | |||
145 | if (!contact) | ||
146 | return GNUNET_YES; | ||
147 | |||
148 | struct GNUNET_TIME_Absolute *timestamp = GNUNET_CONTAINER_multishortmap_get( | ||
149 | it->message->context->timestamps, &shorthash | ||
150 | ); | ||
121 | 151 | ||
152 | if (!timestamp) | ||
153 | return GNUNET_YES; | ||
122 | 154 | ||
155 | struct GNUNET_TIME_Relative delta = GNUNET_TIME_absolute_get_difference( | ||
156 | *timestamp, GNUNET_CHAT_message_get_timestamp(it->message) | ||
157 | ); | ||
123 | 158 | ||
159 | int read_receipt; | ||
160 | if (GNUNET_TIME_relative_get_zero_().rel_value_us == delta.rel_value_us) | ||
161 | read_receipt = GNUNET_YES; | ||
162 | else | ||
163 | read_receipt = GNUNET_NO; | ||
124 | 164 | ||
165 | if (it->cb) | ||
166 | it->cb(it->cls, it->message, contact, read_receipt); | ||
167 | |||
168 | return GNUNET_YES; | ||
169 | } | ||
diff --git a/src/gnunet_chat_message.c b/src/gnunet_chat_message.c index 7e47291..b88edac 100644 --- a/src/gnunet_chat_message.c +++ b/src/gnunet_chat_message.c | |||
@@ -24,8 +24,6 @@ | |||
24 | 24 | ||
25 | #include "gnunet_chat_message.h" | 25 | #include "gnunet_chat_message.h" |
26 | 26 | ||
27 | #include "gnunet_chat_message_intern.c" | ||
28 | |||
29 | struct GNUNET_CHAT_Message* | 27 | struct GNUNET_CHAT_Message* |
30 | message_create_from_msg (struct GNUNET_CHAT_Context *context, | 28 | message_create_from_msg (struct GNUNET_CHAT_Context *context, |
31 | const struct GNUNET_HashCode *hash, | 29 | const struct GNUNET_HashCode *hash, |
@@ -39,20 +37,13 @@ message_create_from_msg (struct GNUNET_CHAT_Context *context, | |||
39 | GNUNET_memcpy(&(message->hash), hash, sizeof(message->hash)); | 37 | GNUNET_memcpy(&(message->hash), hash, sizeof(message->hash)); |
40 | message->flags = flags; | 38 | message->flags = flags; |
41 | 39 | ||
42 | message->head = NULL; | ||
43 | message->tail = NULL; | ||
44 | |||
45 | message->msg = msg; | 40 | message->msg = msg; |
46 | 41 | ||
47 | link_message_parent(message); | ||
48 | |||
49 | return message; | 42 | return message; |
50 | } | 43 | } |
51 | 44 | ||
52 | void | 45 | void |
53 | message_destroy (struct GNUNET_CHAT_Message* message) | 46 | message_destroy (struct GNUNET_CHAT_Message* message) |
54 | { | 47 | { |
55 | unlink_message_parent(message); | ||
56 | clear_message_children(message); | ||
57 | GNUNET_free(message); | 48 | GNUNET_free(message); |
58 | } | 49 | } |
diff --git a/src/gnunet_chat_message.h b/src/gnunet_chat_message.h index ea5b355..4e2e504 100644 --- a/src/gnunet_chat_message.h +++ b/src/gnunet_chat_message.h | |||
@@ -48,9 +48,6 @@ struct GNUNET_CHAT_Message | |||
48 | struct GNUNET_HashCode hash; | 48 | struct GNUNET_HashCode hash; |
49 | enum GNUNET_MESSENGER_MessageFlags flags; | 49 | enum GNUNET_MESSENGER_MessageFlags flags; |
50 | 50 | ||
51 | struct GNUNET_CHAT_MessageList *head; | ||
52 | struct GNUNET_CHAT_MessageList *tail; | ||
53 | |||
54 | const struct GNUNET_MESSENGER_Message *msg; | 51 | const struct GNUNET_MESSENGER_Message *msg; |
55 | }; | 52 | }; |
56 | 53 | ||
diff --git a/src/gnunet_chat_message_intern.c b/src/gnunet_chat_message_intern.c deleted file mode 100644 index 97f3c18..0000000 --- a/src/gnunet_chat_message_intern.c +++ /dev/null | |||
@@ -1,135 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | /* | ||
21 | * @author Tobias Frisch | ||
22 | * @file gnunet_chat_message_intern.c | ||
23 | */ | ||
24 | |||
25 | #include <gnunet/gnunet_container_lib.h> | ||
26 | |||
27 | #include "gnunet_chat_context.h" | ||
28 | |||
29 | void | ||
30 | link_message_parent (struct GNUNET_CHAT_Message *message) | ||
31 | { | ||
32 | struct GNUNET_CHAT_Context *context = message->context; | ||
33 | |||
34 | struct GNUNET_CHAT_Message *prev = GNUNET_CONTAINER_multihashmap_get( | ||
35 | context->messages, &(message->msg->header.previous) | ||
36 | ); | ||
37 | |||
38 | if (prev) | ||
39 | { | ||
40 | struct GNUNET_CHAT_MessageList *list = GNUNET_new( | ||
41 | struct GNUNET_CHAT_MessageList | ||
42 | ); | ||
43 | |||
44 | list->message = message; | ||
45 | |||
46 | GNUNET_CONTAINER_DLL_insert(prev->head, prev->tail, list); | ||
47 | } | ||
48 | |||
49 | if (GNUNET_MESSENGER_KIND_MERGE != message->msg->header.kind) | ||
50 | return; | ||
51 | |||
52 | prev = GNUNET_CONTAINER_multihashmap_get( | ||
53 | context->messages, &(message->msg->body.merge.previous) | ||
54 | ); | ||
55 | |||
56 | if (prev) | ||
57 | { | ||
58 | struct GNUNET_CHAT_MessageList *list = GNUNET_new( | ||
59 | struct GNUNET_CHAT_MessageList | ||
60 | ); | ||
61 | |||
62 | list->message = message; | ||
63 | |||
64 | GNUNET_CONTAINER_DLL_insert(prev->head, prev->tail, list); | ||
65 | } | ||
66 | } | ||
67 | |||
68 | void | ||
69 | unlink_message_parent (struct GNUNET_CHAT_Message *message) | ||
70 | { | ||
71 | struct GNUNET_CHAT_Context *context = message->context; | ||
72 | |||
73 | struct GNUNET_CHAT_Message *prev = GNUNET_CONTAINER_multihashmap_get( | ||
74 | context->messages, &(message->msg->header.previous) | ||
75 | ); | ||
76 | |||
77 | if (prev) | ||
78 | { | ||
79 | struct GNUNET_CHAT_MessageList *list = prev->head; | ||
80 | |||
81 | while (list) | ||
82 | { | ||
83 | if (list->message == message) | ||
84 | break; | ||
85 | |||
86 | list = list->next; | ||
87 | } | ||
88 | |||
89 | if (list) | ||
90 | { | ||
91 | GNUNET_CONTAINER_DLL_remove(prev->head, prev->tail, list); | ||
92 | GNUNET_free(list); | ||
93 | } | ||
94 | } | ||
95 | |||
96 | if (GNUNET_MESSENGER_KIND_MERGE != message->msg->header.kind) | ||
97 | return; | ||
98 | |||
99 | prev = GNUNET_CONTAINER_multihashmap_get( | ||
100 | context->messages, &(message->msg->body.merge.previous) | ||
101 | ); | ||
102 | |||
103 | if (prev) | ||
104 | { | ||
105 | struct GNUNET_CHAT_MessageList *list = prev->head; | ||
106 | |||
107 | while (list) | ||
108 | { | ||
109 | if (list->message == message) | ||
110 | break; | ||
111 | |||
112 | list = list->next; | ||
113 | } | ||
114 | |||
115 | if (list) | ||
116 | { | ||
117 | GNUNET_CONTAINER_DLL_remove(prev->head, prev->tail, list); | ||
118 | GNUNET_free(list); | ||
119 | } | ||
120 | } | ||
121 | } | ||
122 | |||
123 | void | ||
124 | clear_message_children (struct GNUNET_CHAT_Message *message) | ||
125 | { | ||
126 | struct GNUNET_CHAT_MessageList *list = message->tail; | ||
127 | |||
128 | while (list) | ||
129 | { | ||
130 | GNUNET_CONTAINER_DLL_remove(message->head, message->tail, list); | ||
131 | GNUNET_free(list); | ||
132 | |||
133 | list = message->tail; | ||
134 | } | ||
135 | } | ||