gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r36313 - in gnunet/src: include psycstore social


From: gnunet
Subject: [GNUnet-SVN] r36313 - in gnunet/src: include psycstore social
Date: Fri, 4 Sep 2015 18:57:30 +0200

Author: tg
Date: 2015-09-04 18:57:30 +0200 (Fri, 04 Sep 2015)
New Revision: 36313

Modified:
   gnunet/src/include/gnunet_social_service.h
   gnunet/src/psycstore/psyc_util_lib.c
   gnunet/src/social/social_api.c
   gnunet/src/social/test_social.c
Log:
social: watch modifiers

Modified: gnunet/src/include/gnunet_social_service.h
===================================================================
--- gnunet/src/include/gnunet_social_service.h  2015-09-03 18:04:11 UTC (rev 
36312)
+++ gnunet/src/include/gnunet_social_service.h  2015-09-04 16:57:30 UTC (rev 
36313)
@@ -105,7 +105,7 @@
 
 
 /**
- * Function called upon receiving a data fragment of a message.
+ * Function called upon receiving a modifier of a message.
  *
  * @param cls
  *        Closure.
@@ -115,8 +115,10 @@
  *        Message part, as it arrived from the network.
  * @param oper
  *        Operation to perform.
+ *        0 in case of a modifier continuation.
  * @param name
  *        Name of the modifier.
+ *        NULL in case of a modifier continuation.
  * @param value
  *        Value of the modifier.
  * @param value_size
@@ -124,12 +126,13 @@
  */
 typedef void
 (*GNUNET_SOCIAL_ModifierCallback) (void *cls,
-                                   const struct GNUNET_PSYC_MessageModifier 
*msg,
+                                   const struct GNUNET_MessageHeader *msg,
                                    uint64_t message_id,
                                    enum GNUNET_ENV_Operator oper,
                                    const char *name,
                                    const void *value,
-                                   uint16_t value_size);
+                                   uint16_t value_size,
+                                   uint16_t full_value_size);
 
 
 /**
@@ -185,6 +188,9 @@
 /**
  * Create a try-and-slice instance.
  *
+ * A slicer processes incoming messages and notifies callbacks about matching
+ * methods or modifiers encountered.
+ *
  * @return A new try-and-slice construct.
  */
 struct GNUNET_SOCIAL_Slicer *
@@ -194,45 +200,107 @@
 /**
  * Add a method to the try-and-slice instance.
  *
- * A slicer processes messages and calls methods that match a message. A match
- * happens whenever the method name of a message starts with the method_name
- * parameter given here.
+ * The callbacks are called for messages with a matching @a method_name prefix.
  *
- * @param slicer The try-and-slice instance to extend.
- * @param method_name Name of the given method, use empty string for default.
- * @param method Method to invoke.
- * @param method_cls Closure for method.
+ * @param slicer
+ *        The try-and-slice instance to extend.
+ * @param method_name
+ *        Name of the given method, use empty string to match all.
+ * @param method_cb
+ *        Method handler invoked upon a matching message.
+ * @param modifier_cb
+ *        Modifier handler, invoked after @a method_cb
+ *        for each modifier in the message.
+ * @param data_cb
+ *        Data handler, invoked after @a modifier_cb for each data fragment.
+ * @param eom_cb
+ *        Invoked upon reaching the end of a matching message.
+ * @param cls
+ *        Closure for the callbacks.
  */
 void
-GNUNET_SOCIAL_slicer_add (struct GNUNET_SOCIAL_Slicer *slicer,
-                          const char *method_name,
-                          GNUNET_SOCIAL_MethodCallback method_cb,
-                          GNUNET_SOCIAL_ModifierCallback modifier_cb,
-                          GNUNET_SOCIAL_DataCallback data_cb,
-                          GNUNET_SOCIAL_EndOfMessageCallback eom_cb,
-                          void *cls);
+GNUNET_SOCIAL_slicer_method_add (struct GNUNET_SOCIAL_Slicer *slicer,
+                                 const char *method_name,
+                                 GNUNET_SOCIAL_MethodCallback method_cb,
+                                 GNUNET_SOCIAL_ModifierCallback modifier_cb,
+                                 GNUNET_SOCIAL_DataCallback data_cb,
+                                 GNUNET_SOCIAL_EndOfMessageCallback eom_cb,
+                                 void *cls);
 
+/**
+ * Remove a registered method from the try-and-slice instance.
+ *
+ * Removes one matching handler registered with the given
+ * @a method_name and callbacks.
+ *
+ * @param slicer
+ *        The try-and-slice instance.
+ * @param method_name
+ *        Name of the method to remove.
+ * @param method_cb
+ *        Method handler.
+ * @param modifier_cb
+ *        Modifier handler.
+ * @param data_cb
+ *        Data handler.
+ * @param eom_cb
+ *        End of message handler.
+ *
+ * @return #GNUNET_OK if a method handler was removed,
+ *         #GNUNET_NO if no handler matched the given method name and 
callbacks.
+ */
+int
+GNUNET_SOCIAL_slicer_method_remove (struct GNUNET_SOCIAL_Slicer *slicer,
+                                    const char *method_name,
+                                    GNUNET_SOCIAL_MethodCallback method_cb,
+                                    GNUNET_SOCIAL_ModifierCallback modifier_cb,
+                                    GNUNET_SOCIAL_DataCallback data_cb,
+                                    GNUNET_SOCIAL_EndOfMessageCallback eom_cb);
 
+
 /**
- * Remove a registered method handler from the try-and-slice instance.
+ * Watch a place for changed objects.
  *
- * @param slicer The try-and-slice instance.
- * @param method_name Name of the method to remove.
- * @param method Method handler.
+ * @param slicer
+ *        The try-and-slice instance.
+ * @param object_filter
+ *        Object prefix to match.
+ * @param modifier_cb
+ *        Function to call when encountering a state modifier.
+ * @param cls
+ *        Closure for callback.
  */
+void
+GNUNET_SOCIAL_slicer_modifier_add (struct GNUNET_SOCIAL_Slicer *slicer,
+                                   const char *object_filter,
+                                   GNUNET_SOCIAL_ModifierCallback modifier_cb,
+                                   void *cls);
+
+
+/**
+ * Remove a registered modifier from the try-and-slice instance.
+ *
+ * Removes one matching handler registered with the given
+ * @a object_filter and callback.
+ *
+ * @param slicer
+ *        The try-and-slice instance.
+ * @param object_filter
+ *        Object prefix to match.
+ * @param modifier_cb
+ *        Function to call when encountering a state modifier changes.
+ */
 int
-GNUNET_SOCIAL_slicer_remove (struct GNUNET_SOCIAL_Slicer *slicer,
-                             const char *method_name,
-                             GNUNET_SOCIAL_MethodCallback method_cb,
-                             GNUNET_SOCIAL_ModifierCallback modifier_cb,
-                             GNUNET_SOCIAL_DataCallback data_cb,
-                             GNUNET_SOCIAL_EndOfMessageCallback eom_cb);
+GNUNET_SOCIAL_slicer_modifier_remove (struct GNUNET_SOCIAL_Slicer *slicer,
+                                      const char *object_filter,
+                                      GNUNET_SOCIAL_ModifierCallback 
modifier_cb);
 
 
 /**
  * Destroy a given try-and-slice instance.
  *
- * @param slicer slicer to destroy
+ * @param slicer
+ *        Slicer to destroy
  */
 void
 GNUNET_SOCIAL_slicer_destroy (struct GNUNET_SOCIAL_Slicer *slicer);
@@ -826,38 +894,6 @@
 GNUNET_SOCIAL_place_history_replay_cancel (struct GNUNET_SOCIAL_HistoryRequest 
*hist);
 
 
-struct GNUNET_SOCIAL_WatchHandle;
-
-/**
- * Watch a place for changed objects.
- *
- * @param place
- *        Place to watch.
- * @param object_filter
- *        Object prefix to match.
- * @param var_cb
- *        Function to call when an object/state var changes.
- * @param cls
- *        Closure for callback.
- *
- * @return Handle that can be used to cancel watching.
- */
-struct GNUNET_SOCIAL_WatchHandle *
-GNUNET_SOCIAL_place_watch (struct GNUNET_SOCIAL_Place *place,
-                           const char *object_filter,
-                           GNUNET_PSYC_StateVarCallback var_cb,
-                           void *cls);
-
-
-/**
- * Cancel watching a place for changed objects.
- *
- * @param wh Watch handle to cancel.
- */
-void
-GNUNET_SOCIAL_place_watch_cancel (struct GNUNET_SOCIAL_WatchHandle *wh);
-
-
 struct GNUNET_SOCIAL_LookHandle;
 
 

Modified: gnunet/src/psycstore/psyc_util_lib.c
===================================================================
--- gnunet/src/psycstore/psyc_util_lib.c        2015-09-03 18:04:11 UTC (rev 
36312)
+++ gnunet/src/psycstore/psyc_util_lib.c        2015-09-04 16:57:30 UTC (rev 
36313)
@@ -590,9 +590,10 @@
 
     if (name_size + tmit->mod->value_size <= *data_size)
     {
-      *data_size = name_size + tmit->mod->value_size;
+      value_size = tmit->mod->value_size;
+      *data_size = name_size + value_size;
     }
-    else
+    else /* full modifier does not fit in data, continuation needed */
     {
       value_size = *data_size - name_size;
       tmit->mod_value = tmit->mod->value + value_size;

Modified: gnunet/src/social/social_api.c
===================================================================
--- gnunet/src/social/social_api.c      2015-09-03 18:04:11 UTC (rev 36312)
+++ gnunet/src/social/social_api.c      2015-09-04 16:57:30 UTC (rev 36313)
@@ -179,10 +179,14 @@
 struct GNUNET_SOCIAL_Slicer
 {
   /**
-   * Message handlers: method_name -> SlicerCallbacks
+   * Method handlers: method_name -> SlicerMethodCallbacks
    */
-  struct GNUNET_CONTAINER_MultiHashMap *handlers;
+  struct GNUNET_CONTAINER_MultiHashMap *method_handlers;
 
+  /**
+   * Modifier handlers: modifier name -> SlicerModifierCallbacks
+   */
+  struct GNUNET_CONTAINER_MultiHashMap *modifier_handlers;
 
   /**
    * Currently being processed message part.
@@ -200,6 +204,16 @@
   char *method_name;
 
   /**
+   * Name of currently processed modifier.
+   */
+  char *mod_name;
+
+  /**
+   * Value of currently processed modifier.
+   */
+  char *mod_value;
+
+  /**
    * Public key of the nym the current message originates from.
    */
   struct GNUNET_CRYPTO_EcdsaPublicKey nym_key;
@@ -208,6 +222,31 @@
    * Size of @a method_name (including terminating \0).
    */
   uint16_t method_name_size;
+
+  /**
+   * Size of @a modifier_name (including terminating \0).
+   */
+  uint16_t mod_name_size;
+
+  /**
+   * Size of modifier value fragment.
+   */
+  uint16_t mod_value_size;
+
+  /**
+   * Full size of modifier value.
+   */
+  uint16_t mod_full_value_size;
+
+  /**
+   * Remaining bytes from the value of the current modifier.
+   */
+  uint16_t mod_value_remaining;
+
+  /**
+   * Operator of currently processed modifier.
+   */
+  uint8_t mod_oper;
 };
 
 
@@ -214,7 +253,7 @@
 /**
  * Callbacks for a slicer method handler.
  */
-struct SlicerCallbacks
+struct SlicerMethodCallbacks
 {
   GNUNET_SOCIAL_MethodCallback method_cb;
   GNUNET_SOCIAL_ModifierCallback modifier_cb;
@@ -224,32 +263,43 @@
 };
 
 
-struct SlicerRemoveClosure
+struct SlicerMethodRemoveClosure
 {
   struct GNUNET_SOCIAL_Slicer *slicer;
-  struct SlicerCallbacks rm_cbs;
+  struct SlicerMethodCallbacks rm_cbs;
 };
 
 
 /**
- * Handle for an announcement request.
+ * Callbacks for a slicer method handler.
  */
-struct GNUNET_SOCIAL_Announcement
+struct SlicerModifierCallbacks
 {
+  GNUNET_SOCIAL_ModifierCallback modifier_cb;
+  void *cls;
+};
 
+
+struct SlicerModifierRemoveClosure
+{
+  struct GNUNET_SOCIAL_Slicer *slicer;
+  struct SlicerModifierCallbacks rm_cbs;
 };
 
 
 /**
- * A talk request.
+ * Handle for an announcement request.
  */
-struct GNUNET_SOCIAL_TalkRequest
+struct GNUNET_SOCIAL_Announcement
 {
 
 };
 
 
-struct GNUNET_SOCIAL_WatchHandle
+/**
+ * A talk request.
+ */
+struct GNUNET_SOCIAL_TalkRequest
 {
 
 };
@@ -368,21 +418,15 @@
 
 
 /**
- * Call a handler for an incoming message part.
- *
- * @param cls
- * @param key
- * @param value
- *
- * @return
+ * Call a method handler for an incoming message part.
  */
 int
-slicer_handler_notify (void *cls, const struct GNUNET_HashCode *key,
-                       void *value)
+slicer_method_handler_notify (void *cls, const struct GNUNET_HashCode *key,
+                              void *value)
 {
   struct GNUNET_SOCIAL_Slicer *slicer = cls;
   const struct GNUNET_MessageHeader *msg = slicer->msg;
-  struct SlicerCallbacks *cbs = value;
+  struct SlicerMethodCallbacks *cbs = value;
   uint16_t ptype = ntohs (msg->type);
 
   switch (ptype)
@@ -406,9 +450,10 @@
       break;
     struct GNUNET_PSYC_MessageModifier *
       mod = (struct GNUNET_PSYC_MessageModifier *) msg;
-    cbs->modifier_cb (cbs->cls, mod, slicer->message_id,
+    cbs->modifier_cb (cbs->cls, &mod->header, slicer->message_id,
                       mod->oper, (const char *) &mod[1],
                       (const void *) &mod[1] + ntohs (mod->name_size),
+                      ntohs (mod->header.size) - sizeof (*mod) - ntohs 
(mod->name_size),
                       ntohs (mod->value_size));
     break;
   }
@@ -417,7 +462,10 @@
   {
     if (NULL == cbs->modifier_cb)
       break;
-    /* FIXME: concatenate until done */
+    cbs->modifier_cb (cbs->cls, msg, slicer->message_id,
+                      slicer->mod_oper, slicer->mod_name, &msg[1],
+                      ntohs (msg->size) - sizeof (*msg),
+                      slicer->mod_full_value_size);
     break;
   }
 
@@ -448,6 +496,23 @@
 
 
 /**
+ * Call a method handler for an incoming message part.
+ */
+int
+slicer_modifier_handler_notify (void *cls, const struct GNUNET_HashCode *key,
+                                void *value)
+{
+  struct GNUNET_SOCIAL_Slicer *slicer = cls;
+  struct SlicerModifierCallbacks *cbs = value;
+
+  cbs->modifier_cb (cbs->cls, slicer->msg, slicer->message_id, 
slicer->mod_oper,
+                    slicer->mod_name, slicer->mod_value,
+                    slicer->mod_value_size, slicer->mod_full_value_size);
+  return GNUNET_YES;
+}
+
+
+/**
  * Process an incoming message part and call matching handlers.
  *
  * @param cls
@@ -486,6 +551,52 @@
        ptype, ntohs (msg->size), message_id, slicer->method_name);
 
   slicer->msg = msg;
+
+  /* try-and-slice modifier */
+
+  switch (ptype)
+  {
+  case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MODIFIER:
+  {
+    struct GNUNET_PSYC_MessageModifier *
+      mod = (struct GNUNET_PSYC_MessageModifier *) msg;
+    slicer->mod_oper = mod->oper;
+    slicer->mod_name_size = ntohs (mod->name_size);
+    slicer->mod_name = GNUNET_malloc (slicer->mod_name_size);
+    memcpy (slicer->mod_name, &mod[1], slicer->mod_name_size);
+    slicer->mod_value = (char *) &mod[1] + slicer->mod_name_size;
+    slicer->mod_full_value_size = ntohs (mod->value_size);
+    slicer->mod_value_remaining = slicer->mod_full_value_size;
+    slicer->mod_value_size
+      = ntohs (mod->header.size) - sizeof (*mod) - slicer->mod_name_size;
+  }
+  case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MOD_CONT:
+    if (ptype == GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MOD_CONT)
+    {
+      slicer->mod_value = (char *) &msg[1];
+      slicer->mod_value_size = ntohs (msg->size) - sizeof (*msg);
+    }
+    slicer->mod_value_remaining -= slicer->mod_value_size;
+    char *name = GNUNET_malloc (slicer->mod_name_size);
+    memcpy (name, slicer->mod_name, slicer->mod_name_size);
+    do
+    {
+      struct GNUNET_HashCode key;
+      uint16_t name_len = strlen (name);
+      GNUNET_CRYPTO_hash (name, name_len, &key);
+      GNUNET_CONTAINER_multihashmap_get_multiple (slicer->modifier_handlers, 
&key,
+                                                  
slicer_modifier_handler_notify,
+                                                  slicer);
+      char *p = strrchr (name, '_');
+      if (NULL == p)
+        break;
+      *p = '\0';
+    } while (1);
+    GNUNET_free (name);
+  }
+
+  /* try-and-slice method */
+
   char *name = GNUNET_malloc (slicer->method_name_size);
   memcpy (name, slicer->method_name, slicer->method_name_size);
   do
@@ -493,8 +604,9 @@
     struct GNUNET_HashCode key;
     uint16_t name_len = strlen (name);
     GNUNET_CRYPTO_hash (name, name_len, &key);
-    GNUNET_CONTAINER_multihashmap_get_multiple (slicer->handlers, &key,
-                                                &slicer_handler_notify, 
slicer);
+    GNUNET_CONTAINER_multihashmap_get_multiple (slicer->method_handlers, &key,
+                                                slicer_method_handler_notify,
+                                                slicer);
     char *p = strrchr (name, '_');
     if (NULL == p)
       break;
@@ -501,10 +613,21 @@
     *p = '\0';
   } while (1);
   GNUNET_free (name);
-  slicer->msg = NULL;
 
   if (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_END <= ptype)
     GNUNET_free (slicer->method_name);
+
+  if (0 == slicer->mod_value_remaining && NULL != slicer->mod_name)
+  {
+    GNUNET_free (slicer->mod_name);
+    slicer->mod_name = NULL;
+    slicer->mod_name_size = 0;
+    slicer->mod_value_size = 0;
+    slicer->mod_full_value_size = 0;
+    slicer->mod_oper = 0;
+  }
+
+  slicer->msg = NULL;
 }
 
 
@@ -511,6 +634,9 @@
 /**
  * Create a try-and-slice instance.
  *
+ * A slicer processes incoming messages and notifies callbacks about matching
+ * methods or modifiers encountered.
+ *
  * @return A new try-and-slice construct.
  */
 struct GNUNET_SOCIAL_Slicer *
@@ -517,7 +643,8 @@
 GNUNET_SOCIAL_slicer_create (void)
 {
   struct GNUNET_SOCIAL_Slicer *slicer = GNUNET_malloc (sizeof (*slicer));
-  slicer->handlers = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
+  slicer->method_handlers = GNUNET_CONTAINER_multihashmap_create (1, 
GNUNET_NO);
+  slicer->modifier_handlers = GNUNET_CONTAINER_multihashmap_create (1, 
GNUNET_NO);
   return slicer;
 }
 
@@ -525,28 +652,37 @@
 /**
  * Add a method to the try-and-slice instance.
  *
- * A slicer processes messages and calls methods that match a message. A match
- * happens whenever the method name of a message starts with the method_name
- * parameter given here.
+ * The callbacks are called for messages with a matching @a method_name prefix.
  *
- * @param slicer The try-and-slice instance to extend.
- * @param method_name Name of the given method, use empty string for default.
- * @param method Method to invoke.
- * @param method_cls Closure for method.
+ * @param slicer
+ *        The try-and-slice instance to extend.
+ * @param method_name
+ *        Name of the given method, use empty string to match all.
+ * @param method_cb
+ *        Method handler invoked upon a matching message.
+ * @param modifier_cb
+ *        Modifier handler, invoked after @a method_cb
+ *        for each modifier in the message.
+ * @param data_cb
+ *        Data handler, invoked after @a modifier_cb for each data fragment.
+ * @param eom_cb
+ *        Invoked upon reaching the end of a matching message.
+ * @param cls
+ *        Closure for the callbacks.
  */
 void
-GNUNET_SOCIAL_slicer_add (struct GNUNET_SOCIAL_Slicer *slicer,
-                          const char *method_name,
-                          GNUNET_SOCIAL_MethodCallback method_cb,
-                          GNUNET_SOCIAL_ModifierCallback modifier_cb,
-                          GNUNET_SOCIAL_DataCallback data_cb,
-                          GNUNET_SOCIAL_EndOfMessageCallback eom_cb,
-                          void *cls)
+GNUNET_SOCIAL_slicer_method_add (struct GNUNET_SOCIAL_Slicer *slicer,
+                                 const char *method_name,
+                                 GNUNET_SOCIAL_MethodCallback method_cb,
+                                 GNUNET_SOCIAL_ModifierCallback modifier_cb,
+                                 GNUNET_SOCIAL_DataCallback data_cb,
+                                 GNUNET_SOCIAL_EndOfMessageCallback eom_cb,
+                                 void *cls)
 {
   struct GNUNET_HashCode key;
   GNUNET_CRYPTO_hash (method_name, strlen (method_name), &key);
 
-  struct SlicerCallbacks *cbs = GNUNET_malloc (sizeof (*cbs));
+  struct SlicerMethodCallbacks *cbs = GNUNET_malloc (sizeof (*cbs));
   cbs->method_cb = method_cb;
   cbs->modifier_cb = modifier_cb;
   cbs->data_cb = data_cb;
@@ -553,18 +689,18 @@
   cbs->eom_cb = eom_cb;
   cbs->cls = cls;
 
-  GNUNET_CONTAINER_multihashmap_put (slicer->handlers, &key, cbs,
+  GNUNET_CONTAINER_multihashmap_put (slicer->method_handlers, &key, cbs,
                                      
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
 }
 
 
 int
-slicer_remove_handler (void *cls, const struct GNUNET_HashCode *key, void 
*value)
+slicer_method_remove (void *cls, const struct GNUNET_HashCode *key, void 
*value)
 {
-  struct SlicerRemoveClosure *rm_cls = cls;
+  struct SlicerMethodRemoveClosure *rm_cls = cls;
   struct GNUNET_SOCIAL_Slicer *slicer = rm_cls->slicer;
-  struct SlicerCallbacks *rm_cbs = &rm_cls->rm_cbs;
-  struct SlicerCallbacks *cbs = value;
+  struct SlicerMethodCallbacks *rm_cbs = &rm_cls->rm_cbs;
+  struct SlicerMethodCallbacks *cbs = value;
 
   if (cbs->method_cb == rm_cbs->method_cb
       && cbs->modifier_cb == rm_cbs->modifier_cb
@@ -571,7 +707,7 @@
       && cbs->data_cb == rm_cbs->data_cb
       && cbs->eom_cb == rm_cbs->eom_cb)
   {
-    GNUNET_CONTAINER_multihashmap_remove (slicer->handlers, key, cbs);
+    GNUNET_CONTAINER_multihashmap_remove (slicer->method_handlers, key, cbs);
     GNUNET_free (cbs);
     return GNUNET_NO;
   }
@@ -582,29 +718,39 @@
 /**
  * Remove a registered method from the try-and-slice instance.
  *
- * Removes the first matching handler registered with @a method and the given 
callbacks.
+ * Removes one matching handler registered with the given
+ * @a method_name and  callbacks.
  *
- * @param slicer The try-and-slice instance.
- * @param method_name Name of the method to remove.
- * @param method Method handler.
+ * @param slicer
+ *        The try-and-slice instance.
+ * @param method_name
+ *        Name of the method to remove.
+ * @param method_cb
+ *        Method handler.
+ * @param modifier_cb
+ *        Modifier handler.
+ * @param data_cb
+ *        Data handler.
+ * @param eom_cb
+ *        End of message handler.
  *
  * @return #GNUNET_OK if a method handler was removed,
  *         #GNUNET_NO if no handler matched the given method name and 
callbacks.
  */
 int
-GNUNET_SOCIAL_slicer_remove (struct GNUNET_SOCIAL_Slicer *slicer,
-                             const char *method_name,
-                             GNUNET_SOCIAL_MethodCallback method_cb,
-                             GNUNET_SOCIAL_ModifierCallback modifier_cb,
-                             GNUNET_SOCIAL_DataCallback data_cb,
-                             GNUNET_SOCIAL_EndOfMessageCallback eom_cb)
+GNUNET_SOCIAL_slicer_method_remove (struct GNUNET_SOCIAL_Slicer *slicer,
+                                    const char *method_name,
+                                    GNUNET_SOCIAL_MethodCallback method_cb,
+                                    GNUNET_SOCIAL_ModifierCallback modifier_cb,
+                                    GNUNET_SOCIAL_DataCallback data_cb,
+                                    GNUNET_SOCIAL_EndOfMessageCallback eom_cb)
 {
   struct GNUNET_HashCode key;
   GNUNET_CRYPTO_hash (method_name, strlen (method_name), &key);
 
-  struct SlicerRemoveClosure rm_cls;
+  struct SlicerMethodRemoveClosure rm_cls;
   rm_cls.slicer = slicer;
-  struct SlicerCallbacks *rm_cbs = &rm_cls.rm_cbs;
+  struct SlicerMethodCallbacks *rm_cbs = &rm_cls.rm_cbs;
   rm_cbs->method_cb = method_cb;
   rm_cbs->modifier_cb = modifier_cb;
   rm_cbs->data_cb = data_cb;
@@ -612,8 +758,8 @@
 
   return
     (GNUNET_SYSERR
-     == GNUNET_CONTAINER_multihashmap_get_multiple (slicer->handlers, &key,
-                                                    &slicer_remove_handler,
+     == GNUNET_CONTAINER_multihashmap_get_multiple (slicer->method_handlers, 
&key,
+                                                    slicer_method_remove,
                                                     &rm_cls))
     ? GNUNET_NO
     : GNUNET_OK;
@@ -620,10 +766,93 @@
 }
 
 
+/**
+ * Watch a place for changed objects.
+ *
+ * @param slicer
+ *        The try-and-slice instance.
+ * @param object_filter
+ *        Object prefix to match.
+ * @param modifier_cb
+ *        Function to call when encountering a state modifier.
+ * @param cls
+ *        Closure for callback.
+ */
+void
+GNUNET_SOCIAL_slicer_modifier_add (struct GNUNET_SOCIAL_Slicer *slicer,
+                                   const char *object_filter,
+                                   GNUNET_SOCIAL_ModifierCallback modifier_cb,
+                                   void *cls)
+{
+  struct SlicerModifierCallbacks *cbs = GNUNET_malloc (sizeof *cbs);
+  cbs->modifier_cb = modifier_cb;
+  cbs->cls = cls;
+
+  struct GNUNET_HashCode key;
+  GNUNET_CRYPTO_hash (object_filter, strlen (object_filter), &key);
+  GNUNET_CONTAINER_multihashmap_put (slicer->modifier_handlers, &key, cbs,
+                                     
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
+}
+
+
 int
-slicer_free_handler (void *cls, const struct GNUNET_HashCode *key, void *value)
+slicer_modifier_remove (void *cls, const struct GNUNET_HashCode *key, void 
*value)
 {
-  struct SlicerCallbacks *cbs = value;
+  struct SlicerModifierRemoveClosure *rm_cls = cls;
+  struct GNUNET_SOCIAL_Slicer *slicer = rm_cls->slicer;
+  struct SlicerModifierCallbacks *rm_cbs = &rm_cls->rm_cbs;
+  struct SlicerModifierCallbacks *cbs = value;
+
+  if (cbs->modifier_cb == rm_cbs->modifier_cb)
+  {
+    GNUNET_CONTAINER_multihashmap_remove (slicer->modifier_handlers, key, cbs);
+    GNUNET_free (cbs);
+    return GNUNET_NO;
+  }
+  return GNUNET_YES;
+}
+
+
+/**
+ * Remove a registered modifier from the try-and-slice instance.
+ *
+ * Removes one matching handler registered with the given
+ * @a object_filter and @a modifier_cb.
+ *
+ * @param slicer
+ *        The try-and-slice instance.
+ * @param object_filter
+ *        Object prefix to match.
+ * @param modifier_cb
+ *        Function to call when encountering a state modifier changes.
+ */
+int
+GNUNET_SOCIAL_slicer_modifier_remove (struct GNUNET_SOCIAL_Slicer *slicer,
+                                      const char *object_filter,
+                                      GNUNET_SOCIAL_ModifierCallback 
modifier_cb)
+{
+  struct GNUNET_HashCode key;
+  GNUNET_CRYPTO_hash (object_filter, strlen (object_filter), &key);
+
+  struct SlicerModifierRemoveClosure rm_cls;
+  rm_cls.slicer = slicer;
+  struct SlicerModifierCallbacks *rm_cbs = &rm_cls.rm_cbs;
+  rm_cbs->modifier_cb = modifier_cb;
+
+  return
+    (GNUNET_SYSERR
+     == GNUNET_CONTAINER_multihashmap_get_multiple (slicer->modifier_handlers, 
&key,
+                                                    slicer_modifier_remove,
+                                                    &rm_cls))
+    ? GNUNET_NO
+    : GNUNET_OK;
+ }
+
+
+int
+slicer_method_free (void *cls, const struct GNUNET_HashCode *key, void *value)
+{
+  struct SlicerMethodCallbacks *cbs = value;
   GNUNET_free (cbs);
   return GNUNET_YES;
 }
@@ -638,9 +867,9 @@
 void
 GNUNET_SOCIAL_slicer_destroy (struct GNUNET_SOCIAL_Slicer *slicer)
 {
-  GNUNET_CONTAINER_multihashmap_iterate (slicer->handlers, 
&slicer_free_handler,
-                                         NULL);
-  GNUNET_CONTAINER_multihashmap_destroy (slicer->handlers);
+  GNUNET_CONTAINER_multihashmap_iterate (slicer->method_handlers,
+                                         slicer_method_free, NULL);
+  GNUNET_CONTAINER_multihashmap_destroy (slicer->method_handlers);
   GNUNET_free (slicer);
 }
 
@@ -1598,32 +1827,38 @@
   struct GuestEnterRequest *
     req = (struct GuestEnterRequest *) plc->connect_msg;
   uint16_t req_size = ntohs (req->header.size);
-
-  struct GNUNET_PeerIdentity *relays = NULL;
   uint16_t relay_count = ntohs (rec->relay_count);
 
   if (0 < relay_count)
   {
-    uint16_t relay_size = relay_count * sizeof (struct GNUNET_PeerIdentity);
-    struct GuestEnterRequest *
-      req2 = GNUNET_malloc (req_size + relay_size);
+    if (rd->data_size == sizeof (*rec) + relay_count * sizeof (struct 
GNUNET_PeerIdentity))
+    {
+      struct GNUNET_PeerIdentity *relays = (struct GNUNET_PeerIdentity *) 
&rec[1];
+      uint16_t relay_size = relay_count * sizeof (struct GNUNET_PeerIdentity);
+      struct GuestEnterRequest *
+        req2 = GNUNET_malloc (req_size + relay_size);
 
-    req2->header.size = htons (req_size + relay_size);
-    req2->header.type = req->header.type;
-    req2->guest_key = req->guest_key;
+      req2->header.size = htons (req_size + relay_size);
+      req2->header.type = req->header.type;
+      req2->guest_key = req->guest_key;
 
-    uint16_t p = sizeof (*req);
-    if (0 < relay_size)
+      uint16_t p = sizeof (*req);
+      if (0 < relay_size)
+      {
+        memcpy ((char *) req2 + p, relays, relay_size);
+        p += relay_size;
+      }
+
+      memcpy ((char *) req + p, &req[1], req_size - sizeof (*req));
+
+      plc->connect_msg = &req2->header;
+      GNUNET_free (req);
+      req = req2;
+    }
+    else
     {
-      memcpy ((char *) req2 + p, relays, relay_size);
-      p += relay_size;
+      GNUNET_break_op (0);
     }
-
-    memcpy ((char *) req + p, &req[1], req_size - sizeof (*req));
-
-    plc->connect_msg = &req2->header;
-    GNUNET_free (req);
-    req = req2;
   }
 
   req->place_key = rec->place_key;
@@ -1807,42 +2042,6 @@
 }
 
 
-/**
- * Watch a place for changed objects.
- *
- * @param place
- *        Place to watch.
- * @param object_filter
- *        Object prefix to match.
- * @param var_cb
- *        Function to call when an object/state var changes.
- * @param cls
- *        Closure for callback.
- *
- * @return Handle that can be used to cancel watching.
- */
-struct GNUNET_SOCIAL_WatchHandle *
-GNUNET_SOCIAL_place_watch (struct GNUNET_SOCIAL_Place *place,
-                           const char *object_filter,
-                           GNUNET_PSYC_StateVarCallback var_cb,
-                           void *cls)
-{
-  return NULL;
-}
-
-
-/**
- * Cancel watching a place for changed objects.
- *
- * @param wh Watch handle to cancel.
- */
-void
-GNUNET_SOCIAL_place_watch_cancel (struct GNUNET_SOCIAL_WatchHandle *wh)
-{
-
-}
-
-
 static struct GNUNET_SOCIAL_HistoryRequest *
 place_history_replay (struct GNUNET_SOCIAL_Place *plc,
                       uint64_t start_message_id,

Modified: gnunet/src/social/test_social.c
===================================================================
--- gnunet/src/social/test_social.c     2015-09-03 18:04:11 UTC (rev 36312)
+++ gnunet/src/social/test_social.c     2015-09-04 16:57:30 UTC (rev 36313)
@@ -36,7 +36,7 @@
 #include "gnunet_core_service.h"
 #include "gnunet_identity_service.h"
 
-#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300)
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
 
 #define DATA2ARG(data) data, sizeof (data)
 
@@ -101,7 +101,7 @@
 
 struct ResultClosure {
   uint32_t n;
-};
+} mod_foo_bar_rcls;
 
 uint8_t join_req_count;
 struct GNUNET_PSYC_Message *join_resp;
@@ -504,26 +504,47 @@
               "Test #%u: Guest received method for message ID %" PRIu64 ":\n"
               "%s (flags: %x)\n",
               test, message_id, method_name, flags);
-  /* FIXME: check message */
+  /** @todo FIXME: check message */
 }
 
 
 static void
 guest_recv_modifier (void *cls,
-                    const struct GNUNET_PSYC_MessageModifier *mod,
-                    uint64_t message_id,
-                    enum GNUNET_ENV_Operator oper,
-                    const char *name,
-                    const void *value,
-                    uint16_t value_size)
+                     const struct GNUNET_MessageHeader *msg,
+                     uint64_t message_id,
+                     enum GNUNET_ENV_Operator oper,
+                     const char *name,
+                     const void *value,
+                     uint16_t value_size,
+                     uint16_t full_value_size)
 {
   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
               "Test #%u: Guest received modifier for message ID %" PRIu64 ":\n"
-              "%c%s: %.*s\n",
-              test, message_id, oper, name, value_size, value);
+              "%c%s: %.*s (size: %u)\n",
+              test, message_id, oper, name, value_size, value, value_size);
+  /** @todo FIXME: check modifier */
 }
 
+static void
+guest_recv_mod_foo_bar (void *cls,
+                        const struct GNUNET_MessageHeader *msg,
+                        uint64_t message_id,
+                        enum GNUNET_ENV_Operator oper,
+                        const char *name,
+                        const void *value,
+                        uint16_t value_size,
+                        uint16_t full_value_size)
+{
+  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+              "Test #%u: Guest received modifier matching _foo_bar for message 
ID %" PRIu64 ":\n"
+              "%c%s: %.*s (size: %u)\n",
+              test, message_id, oper, name, value_size, value, value_size);
+  struct ResultClosure *rc = cls;
+  rc->n++;
+  /** @todo FIXME: check modifier */
+}
 
+
 static void
 guest_recv_data (void *cls,
                 const struct GNUNET_MessageHeader *msg,
@@ -536,6 +557,7 @@
               "Test #%u: Guest received data for message ID %" PRIu64 ":\n"
               "%.*s\n",
               test, message_id, data_size, data);
+  /** @todo FIXME: check data */
 }
 
 
@@ -592,18 +614,19 @@
               "Test #%u: Host received method for message ID %" PRIu64 ":\n"
               "%s\n",
               test, message_id, method_name);
-  /* FIXME: check message */
+  /** @todo FIXME: check message */
 }
 
 
 static void
 host_recv_modifier (void *cls,
-                    const struct GNUNET_PSYC_MessageModifier *mod,
+                    const struct GNUNET_MessageHeader *msg,
                     uint64_t message_id,
                     enum GNUNET_ENV_Operator oper,
                     const char *name,
                     const void *value,
-                    uint16_t value_size)
+                    uint16_t value_size,
+                    uint16_t full_value_size)
 {
   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
               "Test #%u: Host received modifier for message ID %" PRIu64 ":\n"
@@ -657,7 +680,7 @@
     break;
 
   case TEST_GUEST_TALK:
-      guest_history_replay ();
+    guest_history_replay ();
     break;
 
   default:
@@ -695,6 +718,9 @@
 {
   test = TEST_HOST_ANNOUNCE;
 
+  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+              "Test #%u: Host announcement.\n", test);
+
   tmit = (struct TransmitClosure) {};
   tmit.env = GNUNET_ENV_environment_create ();
   GNUNET_ENV_environment_add (tmit.env, GNUNET_ENV_OP_ASSIGN,
@@ -720,8 +746,15 @@
 static void
 host_announce2 ()
 {
+  GNUNET_assert (2 == mod_foo_bar_rcls.n);
+  GNUNET_SOCIAL_slicer_modifier_remove (guest_slicer, "_foo_bar",
+                                        guest_recv_mod_foo_bar);
+
   test = TEST_HOST_ANNOUNCE2;
 
+  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+              "Test #%u: Host announcement.\n", test);
+
   tmit = (struct TransmitClosure) {};
   tmit.env = GNUNET_ENV_environment_create ();
   GNUNET_ENV_environment_add (tmit.env, GNUNET_ENV_OP_ASSIGN,
@@ -748,8 +781,8 @@
                            const struct GNUNET_PSYC_Message *entry_resp)
 {
   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-              "Guest received entry decision (try %u): %d.\n",
-              join_req_count, is_admitted);
+              "Test #%u: Guest received entry decision (try %u): %d.\n",
+              test, join_req_count, is_admitted);
 
   if (NULL != entry_resp)
   {
@@ -762,7 +795,7 @@
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "%s\n%.*s\n",
                 method_name, data_size, data);
-    /* FIXME: check response message */
+    /** @todo FIXME: check response message */
   }
 
   switch (test)
@@ -795,8 +828,8 @@
   join_req_count++;
 
   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                "Host received entry request from guest (try %u).\n",
-                join_req_count);
+              "Test #%u: Host received entry request from guest (try %u).\n",
+              test, join_req_count);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "%s\n%.*s\n",
               method_name, data_size, data);
@@ -827,7 +860,8 @@
 static void
 guest_recv_local_enter (void *cls, int result, uint64_t max_message_id)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Guest entered to local place.\n");
+  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+              "Test #%u: Guest entered to local place.\n", test);
 
 }
 
@@ -835,7 +869,8 @@
 static void
 guest_enter ()
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Entering to place as guest.\n");
+  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+              "Test #%u: Entering to place as guest.\n", test);
 
   struct GuestEnterMessage *emsg = &guest_enter_msg;
 
@@ -865,11 +900,13 @@
   guest_ego = ego;
 
   guest_slicer = GNUNET_SOCIAL_slicer_create ();
-  GNUNET_SOCIAL_slicer_add (guest_slicer, "",
-                            &guest_recv_method, &guest_recv_modifier,
-                            &guest_recv_data, &guest_recv_eom, NULL);
+  GNUNET_SOCIAL_slicer_method_add (guest_slicer, "",
+                                   guest_recv_method, guest_recv_modifier,
+                                   guest_recv_data, guest_recv_eom, NULL);
+  GNUNET_SOCIAL_slicer_modifier_add (guest_slicer, "_foo_bar",
+                                     guest_recv_mod_foo_bar, 
&mod_foo_bar_rcls);
   test = TEST_HOST_ANSWER_DOOR_ADMIT;
-  //host_announce ();
+
   guest_enter ();
 }
 
@@ -906,9 +943,9 @@
   host_ego = ego;
 
   host_slicer = GNUNET_SOCIAL_slicer_create ();
-  GNUNET_SOCIAL_slicer_add (host_slicer, "",
-                            &host_recv_method, &host_recv_modifier,
-                            &host_recv_data, &host_recv_eom, NULL);
+  GNUNET_SOCIAL_slicer_method_add (host_slicer, "",
+                                   &host_recv_method, &host_recv_modifier,
+                                   &host_recv_data, &host_recv_eom, NULL);
 
   GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Entering to place as host.\n");
   hst = GNUNET_SOCIAL_host_enter (cfg, host_ego, place_key,




reply via email to

[Prev in Thread] Current Thread [Next in Thread]