2003-01-08 Anders Carlsson <andersca@codefactory.se>
authorAnders Carlsson <andersca@codefactory.se>
Tue, 7 Jan 2003 22:22:39 +0000 (22:22 +0000)
committerAnders Carlsson <andersca@codefactory.se>
Tue, 7 Jan 2003 22:22:39 +0000 (22:22 +0000)
reviewed by: <delete if not using a buddy>

* dbus/dbus-internals.c: (_dbus_type_to_string):
New function that returns a string describing a type.

* dbus/dbus-internals.h:
* dbus/dbus-message.c: (dbus_message_append_fields),
(dbus_message_append_fields_valist), (dbus_message_get_fields),
(dbus_message_get_fields_valist), (_dbus_message_test):
* dbus/dbus-message.h:
Add new convenience functions for appending and getting message fields.
Also add a test for those.

dbus/dbus-internals.c
dbus/dbus-internals.h
dbus/dbus-message.c
dbus/dbus-message.h

index f3527eb..e24eb56 100644 (file)
@@ -21,6 +21,7 @@
  *
  */
 #include "dbus-internals.h"
+#include "dbus-protocol.h"
 #include <stdio.h>
 #include <stdarg.h>
 #include <string.h>
@@ -337,4 +338,28 @@ _dbus_set_fd_nonblocking (int             fd,
   return TRUE;
 }
 
+/**
+ * Returns a string describing the given type.
+ *
+ * @param type the type to describe
+ * @returns a constant string describing the type
+ */
+const char *
+_dbus_type_to_string (int type)
+{
+  switch (type)
+    {
+    case DBUS_TYPE_INT32:
+      return "int32";
+    case DBUS_TYPE_UINT32:
+      return "uint32";
+    case DBUS_TYPE_DOUBLE:
+      return "double";
+    case DBUS_TYPE_STRING:
+      return "string";
+    default:
+      return "unknown";
+    }
+}
+
 /** @} */
index 87dfbf1..4bdf41d 100644 (file)
@@ -119,6 +119,7 @@ void _dbus_verbose_bytes_of_string (const DBusString    *str,
                                     int                  len);
 
 
+const char* _dbus_type_to_string (int type);
 
 DBUS_END_DECLS;
 
index fb28ced..8dd7770 100644 (file)
@@ -304,6 +304,95 @@ dbus_message_get_name (DBusMessage *message)
 }
 
 /**
+ * Appends fields to a message given a variable argument
+ * list. The variable argument list should contain the type
+ * of the field followed by the value to add.
+ * The list is terminated with 0.
+ *
+ * @param message the message
+ * @param ... list of fields.
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_append_fields (DBusMessage *message,
+                           ...)
+{
+  dbus_bool_t retval;
+  va_list var_args;
+
+  va_start (var_args, message);
+  retval = dbus_message_append_fields_valist (message, var_args);
+  va_end (var_args);
+
+  return retval;
+}
+
+/**
+ * This function takes a va_list for use by language bindings
+ *
+ * @see dbus_message_append_fields.  
+ * @param message the message
+ * @param var_args list of type/value pairs
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_append_fields_valist (DBusMessage *message,
+                                  va_list      var_args)
+{
+  int type, old_len;
+
+  old_len = _dbus_string_get_length (&message->body);
+  
+  type = va_arg (var_args, int);
+
+  while (type != 0)
+    {
+      switch (type)
+       {
+       case DBUS_TYPE_INT32:
+         if (!dbus_message_append_int32 (message, va_arg (var_args, dbus_int32_t)))
+           goto enomem;
+         break;
+       case DBUS_TYPE_UINT32:
+         if (!dbus_message_append_uint32 (message, va_arg (var_args, dbus_uint32_t)))
+           goto enomem;            
+         break;
+       case DBUS_TYPE_DOUBLE:
+         if (!dbus_message_append_double (message, va_arg (var_args, double)))
+           goto enomem;
+         break;
+       case DBUS_TYPE_STRING:
+         if (!dbus_message_append_string (message, va_arg (var_args, const char *)))
+           goto enomem;
+         break;
+       case DBUS_TYPE_BYTE_ARRAY:
+         {
+           int len;
+           unsigned char *data;
+
+           data = va_arg (var_args, unsigned char *);
+           len = va_arg (var_args, int);
+
+           if (!dbus_message_append_byte_array (message, data, len))
+             goto enomem;
+
+           break;
+         }
+       default:
+         _dbus_warn ("Unknown field type %d\n", type);
+       }
+
+      type = va_arg (var_args, int);
+    }
+
+  return TRUE;
+
+ enomem:
+  _dbus_string_set_length (&message->body, old_len);
+  return FALSE;
+}
+
+/**
  * Appends a 32 bit signed integer to the message.
  *
  * @param message the message
@@ -421,6 +510,128 @@ dbus_message_append_byte_array (DBusMessage         *message,
 }
 
 /**
+ * Gets fields from a message given a variable argument list.
+ * The variable argument list should contain the type of the
+ * field followed by a pointer to where the value should be
+ * stored. The list is terminated with 0.
+ *
+ * @param message the message
+ * @param ... list of fields.
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_get_fields (DBusMessage *message,
+                        ...)
+{
+  dbus_bool_t retval;
+  va_list var_args;
+
+  va_start (var_args, message);
+  retval = dbus_message_get_fields_valist (message, var_args);
+  va_end (var_args);
+
+  return retval;
+}
+
+/**
+ * This function takes a va_list for use by language bindings
+ *
+ * @see dbus_message_get_fields
+ * @param message the message
+ * @param var_args list of type/pointer pairs
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_get_fields_valist (DBusMessage *message,
+                               va_list      var_args)
+{
+  int spec_type, msg_type, i;
+  DBusMessageIter *iter;
+
+  iter = dbus_message_get_fields_iter (message);
+
+  if (iter == NULL)
+    return FALSE;
+  
+  spec_type = va_arg (var_args, int);
+  i = 0;
+  
+  while (spec_type != 0)
+    {
+      msg_type = dbus_message_iter_get_field_type (iter);      
+
+      if (msg_type != spec_type)
+       {
+         _dbus_warn ("Field %d is specified to be of type \"%s\", but "
+                     "is actually of type \"%s\"\n", i,
+                     _dbus_type_to_string (spec_type),
+                     _dbus_type_to_string (msg_type));
+         dbus_message_iter_unref (iter);
+
+         return FALSE;
+       }
+
+      switch (spec_type)
+       {
+       case DBUS_TYPE_INT32:
+         {
+           dbus_int32_t *ptr;
+
+           ptr = va_arg (var_args, dbus_int32_t *);
+
+           *ptr = dbus_message_iter_get_int32 (iter);
+           break;
+         }
+       case DBUS_TYPE_UINT32:
+         {
+           dbus_uint32_t *ptr;
+
+           ptr = va_arg (var_args, dbus_uint32_t *);
+
+           *ptr = dbus_message_iter_get_uint32 (iter);
+           break;
+         }
+
+       case DBUS_TYPE_DOUBLE:
+         {
+           double *ptr;
+
+           ptr = va_arg (var_args, double *);
+
+           *ptr = dbus_message_iter_get_double (iter);
+           break;
+         }
+
+       case DBUS_TYPE_STRING:
+         {
+           char **ptr;
+
+           ptr = va_arg (var_args, char **);
+
+           *ptr = dbus_message_iter_get_string (iter);
+           break;
+         }
+         
+       default:
+         _dbus_warn ("Unknown field type %d\n", spec_type);
+       }
+      
+      spec_type = va_arg (var_args, int);
+      if (spec_type != 0 && !dbus_message_iter_next (iter))
+       {
+         _dbus_warn ("More fields than exists in the message were specified");
+
+         dbus_message_iter_unref (iter);         
+         return FALSE;
+       }
+      i++;
+    }
+
+  dbus_message_iter_unref (iter);
+  return TRUE;
+}
+
+/**
  * Returns a DBusMessageIter representing the fields of the
  * message passed in.
  *
@@ -989,11 +1200,38 @@ dbus_bool_t
 _dbus_message_test (void)
 {
   DBusMessage *message;
-
   DBusMessageLoader *loader;
   int i;
   const char *data;
-
+  dbus_int32_t our_int;
+  char *our_str;
+  double our_double;
+  
+  /* Test the vararg functions */
+  message = dbus_message_new ("org.freedesktop.DBus.Test", "testMessage");
+  message->client_serial = 1;
+  dbus_message_append_fields (message,
+                             DBUS_TYPE_INT32, -0x12345678,
+                             DBUS_TYPE_STRING, "Test string",
+                             DBUS_TYPE_DOUBLE, 3.14159,
+                             0);
+
+  if (!dbus_message_get_fields (message,
+                               DBUS_TYPE_INT32, &our_int,
+                               DBUS_TYPE_STRING, &our_str,
+                               DBUS_TYPE_DOUBLE, &our_double,
+                               0))
+    _dbus_assert_not_reached ("Could not get fields");
+
+  if (our_int != -0x12345678)
+    _dbus_assert_not_reached ("integers differ!");
+
+  if (our_double != 3.14159)
+    _dbus_assert_not_reached ("doubles differ!");
+
+  if (strcmp (our_str, "Test string") != 0)
+    _dbus_assert_not_reached ("strings differ!");
+  
   message = dbus_message_new ("org.freedesktop.DBus.Test", "testMessage");
   message->client_serial = 1;
   dbus_message_append_string (message, "Test string");
index b8eb0ee..1fa54e5 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <dbus/dbus-macros.h>
 #include <dbus/dbus-types.h>
+#include <stdarg.h>
 
 DBUS_BEGIN_DECLS;
 
@@ -43,20 +44,31 @@ void         dbus_message_unref (DBusMessage *message);
 
 const char*  dbus_message_get_name (DBusMessage *message);
 
-dbus_bool_t dbus_message_append_int32      (DBusMessage         *message,
-                                           dbus_int32_t         value);
-dbus_bool_t dbus_message_append_uint32     (DBusMessage         *message,
-                                           dbus_uint32_t        value);
-dbus_bool_t dbus_message_append_double     (DBusMessage         *message,
-                                           double               value);
-dbus_bool_t dbus_message_append_string     (DBusMessage         *message,
-                                           const char          *value);
-dbus_bool_t dbus_message_append_byte_array (DBusMessage         *message,
-                                           unsigned const char *value,
-                                           int                  len);
+
+dbus_bool_t dbus_message_append_fields        (DBusMessage         *message,
+                                              ...);
+dbus_bool_t dbus_message_append_fields_valist (DBusMessage         *message,
+                                              va_list              var_args);
+dbus_bool_t dbus_message_append_int32         (DBusMessage         *message,
+                                              dbus_int32_t         value);
+dbus_bool_t dbus_message_append_uint32        (DBusMessage         *message,
+                                              dbus_uint32_t        value);
+dbus_bool_t dbus_message_append_double        (DBusMessage         *message,
+                                              double               value);
+dbus_bool_t dbus_message_append_string        (DBusMessage         *message,
+                                              const char          *value);
+dbus_bool_t dbus_message_append_byte_array    (DBusMessage         *message,
+                                              unsigned const char *value,
+                                              int                  len);
+
 
 DBusMessageIter *dbus_message_get_fields_iter     (DBusMessage     *message);
 
+dbus_bool_t dbus_message_get_fields          (DBusMessage *message,
+                                             ...);
+dbus_bool_t dbus_message_get_fields_valist   (DBusMessage *message,
+                                             va_list      var_args);
+
 void        dbus_message_iter_ref            (DBusMessageIter *iter);
 void        dbus_message_iter_unref          (DBusMessageIter *iter);