dbus/dbus-message-util.c, dbus/dbus-message.c, dbus/dbus-message.h:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>
Fri, 6 Apr 2007 12:13:13 +0000 (12:13 +0000)
committerSimon McVittie <simon.mcvittie@collabora.co.uk>
Fri, 6 Apr 2007 12:13:13 +0000 (12:13 +0000)
Add API to convert a DBusMessage to/from a byte array.
Patch from Dafydd Harries <dafydd.harries@collabora.co.uk>, approved by
Havoc Pennington.

ChangeLog
dbus/dbus-message-util.c
dbus/dbus-message.c
dbus/dbus-message.h

index bc0f782..beb0bd5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2007-04-06 Simon McVittie <simon.mcvittie@collabora.co.uk>
+
+       * dbus/dbus-message-util.c, dbus/dbus-message.c,
+       dbus/dbus-message.h: Add API to convert a DBusMessage to/from a
+       byte array. Patch from Dafydd Harries <dafydd.harries@collabora.co.uk>,
+       approved by Havoc Pennington.
+
 2007-04-03  Timo Hoenig  <thoenig@suse.de>
 
        * dbus/dbus-address.c (dbus_parse_address): Do not accept zero-
index 67cfffd..fb6fad8 100644 (file)
@@ -1222,6 +1222,46 @@ _dbus_message_test (const char *test_data_dir)
 
   verify_test_message (message);
 
+    {
+      /* Marshal and demarshal the message. */
+
+      DBusMessage *message2;
+      DBusError error;
+      char *marshalled = NULL;
+      int len = 0;
+
+      dbus_error_init (&error);
+
+      if (!dbus_message_marshal (message, &marshalled, &len))
+        _dbus_assert_not_reached ("failed to marshal message");
+
+      _dbus_assert (len != 0);
+      _dbus_assert (marshalled != NULL);
+
+      message2 = dbus_message_demarshal (marshalled, len, &error);
+
+      _dbus_assert (message2 != NULL);
+      _dbus_assert (!dbus_error_is_set (&error));
+      verify_test_message (message2);
+
+      dbus_message_unref (message2);
+      dbus_free (marshalled);
+
+      /* Demarshal invalid message. */
+
+      message2 = dbus_message_demarshal ("invalid", 7, &error);
+      _dbus_assert (message2 == NULL);
+      _dbus_assert (dbus_error_is_set (&error));
+      dbus_error_free (&error);
+
+      /* Demarshal invalid (empty) message. */
+
+      message2 = dbus_message_demarshal ("", 0, &error);
+      _dbus_assert (message2 == NULL);
+      _dbus_assert (dbus_error_is_set (&error));
+      dbus_error_free (&error);
+    }
+
   dbus_message_unref (message);
   _dbus_message_loader_unref (loader);
 
index 983543d..fe73bb1 100644 (file)
@@ -3890,6 +3890,110 @@ dbus_message_type_to_string (int type)
     }
 }
 
+/**
+ * Turn a DBusMessage into the marshalled form as described in the D-Bus
+ * specification.
+ *
+ * Generally, this function is only useful for encapsulating D-Bus messages in
+ * a different protocol.
+ *
+ * @param msg the DBusMessage
+ * @param marshalled_data_p the location to save the marshalled form to
+ * @param len_p the location to save the length of the marshalled form to
+ * @returns #FALSE if there was not enough memory
+ */
+dbus_bool_t
+dbus_message_marshal (DBusMessage  *msg,
+                      char        **marshalled_data_p,
+                      int          *len_p)
+{
+  DBusString tmp;
+
+  _dbus_return_val_if_fail (msg != NULL, FALSE);
+  _dbus_return_val_if_fail (marshalled_data_p != NULL, FALSE);
+  _dbus_return_val_if_fail (len_p != NULL, FALSE);
+
+  if (!_dbus_string_init (&tmp))
+    return FALSE;
+
+  if (!_dbus_string_copy (&(msg->header.data), 0, &tmp, 0))
+    goto fail;
+
+  *len_p = _dbus_string_get_length (&tmp);
+
+  if (!_dbus_string_copy (&(msg->body), 0, &tmp, *len_p))
+    goto fail;
+
+  *len_p = _dbus_string_get_length (&tmp);
+
+  if (!_dbus_string_steal_data (&tmp, marshalled_data_p))
+    goto fail;
+
+  _dbus_string_free (&tmp);
+  return TRUE;
+
+ fail:
+  _dbus_string_free (&tmp);
+  return FALSE;
+}
+
+/**
+ * Demarshal a D-Bus message from the format described in the D-Bus
+ * specification.
+ *
+ * Generally, this function is only useful for encapsulating D-Bus messages in
+ * a different protocol.
+ *
+ * @param str the marshalled DBusMessage
+ * @param len the length of str
+ * @param error the location to save errors to
+ * @returns #NULL if there was an error
+ */
+DBusMessage *
+dbus_message_demarshal (const char *str,
+                        int         len,
+                        DBusError  *error)
+{
+  DBusMessageLoader *loader;
+  DBusString *buffer;
+  DBusMessage *msg;
+
+  _dbus_return_val_if_fail (str != NULL, NULL);
+
+  loader = _dbus_message_loader_new ();
+
+  if (loader == NULL)
+    return NULL;
+
+  _dbus_message_loader_get_buffer (loader, &buffer);
+  _dbus_string_append_len (buffer, str, len);
+  _dbus_message_loader_return_buffer (loader, buffer, len);
+
+  if (!_dbus_message_loader_queue_messages (loader))
+    goto fail_oom;
+
+  if (_dbus_message_loader_get_is_corrupted (loader))
+    goto fail_corrupt;
+
+  msg = _dbus_message_loader_pop_message (loader);
+
+  if (!msg)
+    goto fail_oom;
+
+  _dbus_message_loader_unref (loader);
+  return msg;
+
+ fail_corrupt:
+  dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Message is corrupted");
+  _dbus_message_loader_unref (loader);
+  return NULL;
+
+ fail_oom:
+  _DBUS_SET_OOM (error);
+  _dbus_message_loader_unref (loader);
+  return NULL;
+}
+
 /** @} */
 
 /* tests in dbus-message-util.c */
index 8fe07d8..a3229c5 100644 (file)
@@ -210,8 +210,15 @@ dbus_bool_t dbus_message_set_data           (DBusMessage      *message,
 void*       dbus_message_get_data           (DBusMessage      *message,
                                              dbus_int32_t      slot);
 
-int dbus_message_type_from_string (const char *type_str);
-const char * dbus_message_type_to_string (int type);
+int         dbus_message_type_from_string (const char *type_str);
+const char* dbus_message_type_to_string   (int type);
+
+dbus_bool_t  dbus_message_marshal   (DBusMessage  *msg,
+                                     char        **marshalled_data_p,
+                                     int          *len_p);
+DBusMessage* dbus_message_demarshal (const char *str,
+                                     int         len,
+                                     DBusError  *error);
 
 /** @} */