commit 0aa918a8861ad8e8260309e0e0961cfb0b1b1c26
parent 155016406d44a5a12a123a91a8eaf8aaa62e7430
Author: Jacki <jacki@thejackimonster.de>
Date: Fri, 5 Jan 2024 03:53:38 +0100
Implement function to list attributes of a handle
Signed-off-by: Jacki <jacki@thejackimonster.de>
Diffstat:
4 files changed, 153 insertions(+), 1 deletion(-)
diff --git a/include/gnunet/gnunet_chat_lib.h b/include/gnunet/gnunet_chat_lib.h
@@ -191,6 +191,20 @@ typedef enum GNUNET_GenericReturnValue
struct GNUNET_CHAT_Account *account);
/**
+ * Method called for each attribute of a specific chat handle.
+ *
+ * @param[in,out] cls Closure from #GNUNET_CHAT_get_attributes
+ * @param[in] handle Chat handle
+ * @param[in] name Attribute name
+ * @param[in] value Attribute value
+ */
+typedef void
+(*GNUNET_CHAT_AttributeCallback) (void *cls,
+ struct GNUNET_CHAT_Handle *handle,
+ const char *name,
+ const char *value);
+
+/**
* Method called when a lobby is opened to share with others via a chat URI.
*
* @param[in,out] cls Closure from #GNUNET_CHAT_lobby_open
@@ -515,6 +529,19 @@ GNUNET_CHAT_delete_attribute (struct GNUNET_CHAT_Handle *handle,
const char *name);
/**
+ * Calls an optional <i>callback</i> for each attribute of a given chat
+ * <i>handle</i>.
+ *
+ * @param[in,out] handle Chat handle
+ * @param[in] callback Callback for attribute iteration (optional)
+ * @param[in,out] cls Closure for attribute iteration (optional)
+ */
+void
+GNUNET_CHAT_get_attributes (struct GNUNET_CHAT_Handle *handle,
+ GNUNET_CHAT_AttributeCallback callback,
+ void *cls);
+
+/**
* Convert an UTF-8 String to a chat URI which will be newly allocated.
*
* @param[in] uri UTF-8 string to parse
@@ -1363,7 +1390,8 @@ const struct GNUNET_CHAT_Contact*
GNUNET_CHAT_ticket_get_contact (const struct GNUNET_CHAT_Ticket *ticket);
/**
- * Consumes a given chat <i>ticket</i>.
+ * Consumes a given chat <i>ticket</i> and calls an optional <i>callback</i>
+ * for each of its attributes.
*
* @param[in,out] ticket Chat ticket
* @param[in] callback Callback for ticket consumption (optional)
diff --git a/src/gnunet_chat_handle.h b/src/gnunet_chat_handle.h
@@ -88,6 +88,9 @@ struct GNUNET_CHAT_AttributeProcess
struct GNUNET_RECLAIM_Attribute *attribute;
+ GNUNET_CHAT_AttributeCallback callback;
+ void *closure;
+
struct GNUNET_RECLAIM_AttributeIterator *iter;
struct GNUNET_RECLAIM_Operation *op;
diff --git a/src/gnunet_chat_lib.c b/src/gnunet_chat_lib.c
@@ -358,6 +358,9 @@ GNUNET_CHAT_delete_attribute (struct GNUNET_CHAT_Handle *handle,
struct GNUNET_CHAT_AttributeProcess
);
+ if (!attributes)
+ return;
+
memset(attributes, 0, sizeof(struct GNUNET_CHAT_AttributeProcess));
attributes->handle = handle;
@@ -391,6 +394,56 @@ GNUNET_CHAT_delete_attribute (struct GNUNET_CHAT_Handle *handle,
}
+void
+GNUNET_CHAT_get_attributes (struct GNUNET_CHAT_Handle *handle,
+ GNUNET_CHAT_AttributeCallback callback,
+ void *cls)
+{
+ GNUNET_CHAT_VERSION_ASSERT();
+
+ if ((!handle) || (handle->destruction))
+ return;
+
+ const struct GNUNET_CRYPTO_PrivateKey *key = handle_get_key(
+ handle
+ );
+
+ if (!key)
+ return;
+
+ struct GNUNET_CHAT_AttributeProcess *attributes = GNUNET_new(
+ struct GNUNET_CHAT_AttributeProcess
+ );
+
+ if (!attributes)
+ return;
+
+ memset(attributes, 0, sizeof(struct GNUNET_CHAT_AttributeProcess));
+
+ attributes->handle = handle;
+
+ attributes->callback = callback;
+ attributes->closure = cls;
+
+ attributes->iter = GNUNET_RECLAIM_get_attributes_start(
+ handle->reclaim,
+ key,
+ cb_task_error_iterate_attribute,
+ attributes,
+ cb_iterate_attribute,
+ attributes,
+ cb_task_finish_iterate_attribute,
+ attributes
+ );
+
+ GNUNET_CONTAINER_DLL_insert_tail(
+ handle->attributes_head,
+ handle->attributes_tail,
+ attributes
+ );
+}
+
+
struct GNUNET_CHAT_Uri*
GNUNET_CHAT_uri_parse (const char *uri,
char **emsg)
diff --git a/src/gnunet_chat_lib_intern.c b/src/gnunet_chat_lib_intern.c
@@ -343,3 +343,71 @@ cont_update_attribute_with_status (void *cls,
attributes
);
}
+
+void
+cb_task_finish_iterate_attribute (void *cls)
+{
+ GNUNET_assert(cls);
+
+ struct GNUNET_CHAT_AttributeProcess *attributes = (
+ (struct GNUNET_CHAT_AttributeProcess*) cls
+ );
+
+ struct GNUNET_CHAT_Handle *handle = attributes->handle;
+
+ if (attributes->iter)
+ GNUNET_RECLAIM_get_attributes_stop(attributes->iter);
+
+ GNUNET_CONTAINER_DLL_remove(
+ handle->attributes_head,
+ handle->attributes_tail,
+ attributes
+ );
+
+ GNUNET_free(attributes);
+}
+
+void
+cb_task_error_iterate_attribute (void *cls)
+{
+ GNUNET_assert(cls);
+
+ struct GNUNET_CHAT_AttributeProcess *attributes = (
+ (struct GNUNET_CHAT_AttributeProcess*) cls
+ );
+
+ handle_send_internal_message(
+ attributes->handle,
+ NULL,
+ GNUNET_CHAT_FLAG_WARNING,
+ "Attribute iteration failed!"
+ );
+
+ cb_task_finish_iterate_attribute(cls);
+}
+
+void
+cb_iterate_attribute (void *cls,
+ const struct GNUNET_CRYPTO_PublicKey *identity,
+ const struct GNUNET_RECLAIM_Attribute *attribute)
+{
+ GNUNET_assert(cls);
+
+ struct GNUNET_CHAT_AttributeProcess *attributes = (
+ (struct GNUNET_CHAT_AttributeProcess*) cls
+ );
+
+ struct GNUNET_CHAT_Handle *handle = attributes->handle;
+
+ const char *value = GNUNET_RECLAIM_attribute_value_to_string(
+ attribute->type,
+ attribute->data,
+ attribute->data_size
+ );
+
+ if (attributes->callback)
+ attributes->callback(attributes->closure, handle, attribute->name, value);
+
+ if (attributes->iter)
+ GNUNET_RECLAIM_get_attributes_next(attributes->iter);
+}