structs, custom type
Olivier Andrieu
oliv__a@users.sourceforge.net
Thu Mar 11 18:47:35 PST 2004
--5pXtTrWZSE
Content-Type: text/plain; charset=us-ascii
Content-Description: message body and .signature
Content-Transfer-Encoding: 7bit
Hi,
Havoc Pennington [Wednesday 10 March 2004] :
>
> On Wed, 2004-03-10 at 13:51, Olivier Andrieu wrote:
> > That's a weird idea (I think) : I thought the DBUS_TYPE_CUSTOM
> > was intended for application-specific binary data. If you start
> > to put dbus typecodes in the CUSTOM data that means apps (and
> > bindings) will have to be aware of the dbus protocol (typecodes,
> > data representation, etc.)
>
> Type custom could be:
> name = org.freedesktop.Point
> type = struct of int, int
> data = 10, 20
OK. Actually right now it's quite easy to encode it just like a custom
(i.e. a name + a length + data) but with a succession of arguments in
place of a dumb byte array. It will probably be easier to move type
information at the beginning once this is done also for the whole
message.
The attached patch adds this API :
dbus_bool_t dbus_message_iter_init_tuple_iterator (DBusMessageIter *iter,
DBusMessageIter *tuple_iter,
char **name);
dbus_bool_t dbus_message_iter_append_tuple (DBusMessageIter *iter,
DBusMessageIter *tuple_iter,
const char *name);
It also fixes a bug in _dbus_marshal_get_arg_end_pos for custom types
(it passed the test because the custom value happened to be the last
one in the message !).
--
Olivier
--5pXtTrWZSE
Content-Type: text/plain
Content-Disposition: attachment;
filename="dbus-tuple.patch"
Content-Transfer-Encoding: 7bit
Index: dbus/dbus-protocol.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-protocol.h,v
retrieving revision 1.25
diff -u -u -r1.25 dbus-protocol.h
--- dbus/dbus-protocol.h 2 Dec 2003 10:44:21 -0000 1.25
+++ dbus/dbus-protocol.h 11 Mar 2004 18:16:37 -0000
@@ -54,8 +54,9 @@
#define DBUS_TYPE_ARRAY ((int) 'a')
#define DBUS_TYPE_DICT ((int) 'm')
#define DBUS_TYPE_OBJECT_PATH ((int) 'o')
+#define DBUS_TYPE_TUPLE ((int) 'p')
-#define DBUS_NUMBER_OF_TYPES (13)
+#define DBUS_NUMBER_OF_TYPES (14)
/* Max length in bytes of a service or interface or member name */
#define DBUS_MAXIMUM_NAME_LENGTH 256
Index: dbus/dbus-message.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-message.h,v
retrieving revision 1.49
diff -u -u -r1.49 dbus-message.h
--- dbus/dbus-message.h 2 Dec 2003 10:44:21 -0000 1.49
+++ dbus/dbus-message.h 11 Mar 2004 18:16:37 -0000
@@ -172,6 +172,9 @@
void dbus_message_iter_init_array_iterator (DBusMessageIter *iter,
DBusMessageIter *array_iter,
int *array_type);
+dbus_bool_t dbus_message_iter_init_tuple_iterator (DBusMessageIter *iter,
+ DBusMessageIter *tuple_iter,
+ char **name);
void dbus_message_iter_init_dict_iterator (DBusMessageIter *iter,
DBusMessageIter *dict_iter);
dbus_bool_t dbus_message_iter_get_byte_array (DBusMessageIter *iter,
@@ -235,6 +238,9 @@
dbus_bool_t dbus_message_iter_append_array (DBusMessageIter *iter,
DBusMessageIter *array_iter,
int element_type);
+dbus_bool_t dbus_message_iter_append_tuple (DBusMessageIter *iter,
+ DBusMessageIter *tuple_iter,
+ const char *name);
dbus_bool_t dbus_message_iter_append_dict (DBusMessageIter *iter,
DBusMessageIter *dict_iter);
Index: dbus/dbus-message.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-message.c,v
retrieving revision 1.119
diff -u -u -r1.119 dbus-message.c
--- dbus/dbus-message.c 8 Mar 2004 10:29:16 -0000 1.119
+++ dbus/dbus-message.c 11 Mar 2004 18:16:38 -0000
@@ -111,7 +111,8 @@
enum {
DBUS_MESSAGE_ITER_TYPE_MESSAGE,
DBUS_MESSAGE_ITER_TYPE_ARRAY,
- DBUS_MESSAGE_ITER_TYPE_DICT
+ DBUS_MESSAGE_ITER_TYPE_DICT,
+ DBUS_MESSAGE_ITER_TYPE_TUPLE
};
/** typedef for internals of message iterator */
@@ -2440,6 +2441,7 @@
switch (iter->type)
{
case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
+ case DBUS_MESSAGE_ITER_TYPE_TUPLE:
data = _dbus_string_get_const_data_len (&iter->message->body,
iter->pos, 1);
if (_dbus_type_is_valid (*data))
@@ -2584,6 +2586,7 @@
switch (iter->type)
{
+ case DBUS_MESSAGE_ITER_TYPE_TUPLE:
case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
_array_type_pos = iter->pos + 1;
break;
@@ -2989,6 +2992,58 @@
/**
+ * Initializes an iterator for the tuple that the iterator
+ * may point to. Note that you need to check that the iterator
+ * points to a tuple prior to using this function.
+ *
+ * @param iter the iterator
+ * @param tuple_iter pointer to an iterator to initialize
+ * @param name return location for the name of the tuple
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_iter_init_tuple_iterator (DBusMessageIter *iter,
+ DBusMessageIter *tuple_iter,
+ char **name)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+ DBusMessageRealIter *tuple_real = (DBusMessageRealIter *)tuple_iter;
+ int type, pos, len_pos, len;
+ char *_name;
+
+ _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
+
+ pos = dbus_message_iter_get_data_start (real, &type);
+
+ _dbus_assert (type == DBUS_TYPE_TUPLE);
+
+ _name = _dbus_demarshal_string (&real->message->body, real->message->byte_order,
+ pos, &pos);
+
+ if (_name == NULL)
+ return FALSE;
+ if (name)
+ *name = _name;
+
+ len_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
+ len = _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order,
+ pos, &pos);
+
+ tuple_real->parent_iter = real;
+ tuple_real->message = real->message;
+ tuple_real->changed_stamp = real->message->changed_stamp;
+
+ tuple_real->type = DBUS_MESSAGE_ITER_TYPE_TUPLE;
+ tuple_real->pos = pos;
+ tuple_real->end = pos + len;
+
+ tuple_real->container_start = pos;
+ tuple_real->container_length_pos = len_pos;
+
+ return TRUE;
+}
+
+/**
* Initializes an iterator for the dict that the iterator
* may point to. Note that you need to check that the iterator
* points to a dict prior to using this function.
@@ -3456,6 +3511,7 @@
const char *data;
switch (iter->type)
{
+ case DBUS_MESSAGE_ITER_TYPE_TUPLE:
case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
if (!_dbus_string_append_byte (&iter->message->signature, type))
return FALSE;
@@ -3508,6 +3564,7 @@
/* Set container length */
if (iter->type == DBUS_MESSAGE_ITER_TYPE_DICT ||
+ iter->type == DBUS_MESSAGE_ITER_TYPE_TUPLE ||
(iter->type == DBUS_MESSAGE_ITER_TYPE_ARRAY && iter->array_type_done))
_dbus_marshal_set_uint32 (&iter->message->body,
iter->message->byte_order,
@@ -4016,6 +4073,61 @@
return TRUE;
}
+
+/**
+ * Appends an tuple to the message and initializes an iterator that
+ * can be used to append to the tuple.
+ *
+ * @param iter an iterator pointing to the end of the message
+ * @param tuple_iter pointer to an iter that will be initialized
+ * @param name the name of the tuple
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_iter_append_tuple (DBusMessageIter *iter,
+ DBusMessageIter *tuple_iter,
+ const char *name)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+ DBusMessageRealIter *tuple_real = (DBusMessageRealIter *)tuple_iter;
+ int len_pos;
+
+ _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
+
+ if (!dbus_message_iter_append_type (real, DBUS_TYPE_TUPLE))
+ return FALSE;
+
+ if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, name))
+ {
+ _dbus_string_set_length (&real->message->body, real->pos);
+ return FALSE;
+ }
+
+ len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&real->message->body), sizeof (dbus_uint32_t));
+
+ /* Empty length for now, backfill later */
+ if (!_dbus_marshal_uint32 (&real->message->body, real->message->byte_order, 0))
+ {
+ _dbus_string_set_length (&real->message->body, real->pos);
+ return FALSE;
+ }
+
+ tuple_real->parent_iter = real;
+ tuple_real->message = real->message;
+ tuple_real->changed_stamp = real->message->changed_stamp;
+
+ tuple_real->type = DBUS_MESSAGE_ITER_TYPE_TUPLE;
+ tuple_real->pos = _dbus_string_get_length (&real->message->body);
+ tuple_real->end = tuple_real->end;
+
+ tuple_real->container_start = tuple_real->pos;
+ tuple_real->container_length_pos = len_pos;
+
+ dbus_message_iter_append_done (tuple_real);
+
+ return TRUE;
+}
+
/**
* Appends a dict to the message and initializes an iterator that
* can be used to append to the dict.
@@ -5860,6 +5972,57 @@
if (!dbus_message_iter_next (&iter))
_dbus_assert_not_reached ("Reached end of arguments");
+ /* tuple */
+ {
+ DBusMessageIter tuple;
+
+ if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_TUPLE)
+ _dbus_assert_not_reached ("not tuple type");
+
+ dbus_message_iter_init_tuple_iterator (&iter, &tuple, &str);
+
+ if (strcmp (str, "org.freedesktop.DBus.TestTuple") != 0)
+ _dbus_assert_not_reached ("Wrong tuple name");
+ dbus_free (str);
+
+ str = dbus_message_iter_get_string (&tuple);
+ if (strcmp (str, "Test string") != 0)
+ _dbus_assert_not_reached ("Strings differ");
+ dbus_free (str);
+
+ if (!dbus_message_iter_next (&tuple))
+ _dbus_assert_not_reached ("Reached end of arguments");
+
+ if (dbus_message_iter_get_arg_type (&tuple) != DBUS_TYPE_INT32)
+ _dbus_assert_not_reached ("Argument type isn't int32");
+
+ if (dbus_message_iter_get_int32 (&tuple) != -0x12345678)
+ _dbus_assert_not_reached ("Signed integers differ");
+
+ if (!dbus_message_iter_next (&tuple))
+ _dbus_assert_not_reached ("Reached end of fields");
+
+ if (dbus_message_iter_get_arg_type (&tuple) != DBUS_TYPE_UINT32)
+ _dbus_assert_not_reached ("Argument type isn't int32");
+
+ if (dbus_message_iter_get_uint32 (&tuple) != 0xedd1e)
+ _dbus_assert_not_reached ("Unsigned integers differ");
+
+ if (!dbus_message_iter_next (&tuple))
+ _dbus_assert_not_reached ("Reached end of arguments");
+
+ if (dbus_message_iter_get_arg_type (&tuple) != DBUS_TYPE_DOUBLE)
+ _dbus_assert_not_reached ("Argument type isn't double");
+
+ if (dbus_message_iter_get_double (&tuple) != 3.14159)
+ _dbus_assert_not_reached ("Doubles differ");
+
+ if (dbus_message_iter_next (&tuple))
+ _dbus_assert_not_reached ("Didn't reach end of tuple");
+
+ if (!dbus_message_iter_next (&iter))
+ _dbus_assert_not_reached ("Reached end of arguments");
+ }
/* dict */
@@ -6003,6 +6166,12 @@
dbus_free (str);
dbus_free (data);
+ if (!dbus_message_iter_next (&iter))
+ _dbus_assert_not_reached ("Reached end of arguments after custom");
+
+ if (dbus_message_iter_get_byte (&iter) != 0xF0)
+ _dbus_assert_not_reached ("wrong value after custom");
+
if (dbus_message_iter_next (&iter))
_dbus_assert_not_reached ("Didn't reach end of arguments");
}
@@ -6117,6 +6286,25 @@
}
}
break;
+ case DBUS_TYPE_TUPLE:
+ {
+ char *name;
+ int entry_type;
+ dbus_message_iter_init_tuple_iterator (iter, &child_iter, &name);
+
+ while ((entry_type = dbus_message_iter_get_arg_type (&child_iter)) != DBUS_TYPE_INVALID)
+ {
+ if (!check_message_handling_type (&child_iter, entry_type))
+ {
+ _dbus_warn ("error in tuple element\n");
+ return FALSE;
+ }
+
+ if (!dbus_message_iter_next (&child_iter))
+ break;
+ }
+ }
+ break;
default:
_dbus_warn ("unknown type %d\n", type);
@@ -7108,6 +7296,13 @@
dbus_message_iter_append_double (&child_iter, 1.5);
dbus_message_iter_append_double (&child_iter, 2.5);
+ /* tuple */
+ dbus_message_iter_append_tuple (&iter, &child_iter, "org.freedesktop.DBus.TestTuple");
+ dbus_message_iter_append_string (&child_iter, "Test string");
+ dbus_message_iter_append_int32 (&child_iter, -0x12345678);
+ dbus_message_iter_append_uint32 (&child_iter, 0xedd1e);
+ dbus_message_iter_append_double (&child_iter, 3.14159);
+
/* dict */
dbus_message_iter_append_dict (&iter, &child_iter);
dbus_message_iter_append_dict_key (&child_iter, "test");
@@ -7139,7 +7334,9 @@
dbus_message_iter_append_custom (&iter, "MyTypeName",
"data", 5);
-
+
+ dbus_message_iter_append_byte (&iter, 0xF0);
+
message_iter_test (message);
/* Message loader test */
Index: dbus/dbus-marshal.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-marshal.c,v
retrieving revision 1.47
diff -u -u -r1.47 dbus-marshal.c
--- dbus/dbus-marshal.c 2 Dec 2003 10:44:21 -0000 1.47
+++ dbus/dbus-marshal.c 11 Mar 2004 18:16:38 -0000
@@ -1643,6 +1643,7 @@
break;
case DBUS_TYPE_CUSTOM:
+ case DBUS_TYPE_TUPLE:
{
int len;
@@ -1652,23 +1653,13 @@
*end_pos = pos + len + 1;
/* Demarshal the data length */
- len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
+ len = _dbus_demarshal_uint32 (str, byte_order, *end_pos, &pos);
*end_pos = pos + len;
}
break;
case DBUS_TYPE_ARRAY:
- {
- int len;
-
- /* Demarshal the length */
- len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
-
- *end_pos = pos + len;
- }
- break;
-
case DBUS_TYPE_DICT:
{
int len;
@@ -1841,6 +1832,7 @@
case DBUS_TYPE_CUSTOM:
case DBUS_TYPE_ARRAY:
case DBUS_TYPE_DICT:
+ case DBUS_TYPE_TUPLE:
/* This clean recursion to validate_arg is what we
* are doing logically for all types, but we don't
* really want to call validate_arg for every byte
@@ -2197,6 +2189,52 @@
*end_pos = pos;
}
break;
+
+ case DBUS_TYPE_TUPLE:
+ {
+ int el_type;
+ int len;
+ int end;
+
+ /* Demarshal the string length, which does NOT include
+ * nul termination
+ */
+ len = demarshal_and_validate_len (str, byte_order, pos, &pos);
+ if (len < 0)
+ return FALSE;
+
+ if (!validate_string (str, pos, len, &pos))
+ return FALSE;
+
+ len = demarshal_and_validate_len (str, byte_order, pos, &pos);
+ if (len < 0)
+ return FALSE;
+
+ end = pos + len;
+
+ while (pos < end)
+ {
+ if (!_dbus_marshal_validate_type (str, pos, &el_type, &pos))
+ {
+ _dbus_verbose ("invalid tuple entry type at offset %d\n", pos);
+ return FALSE;
+ }
+
+ /* Validate element */
+ if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
+ el_type, -1, pos, &pos))
+ return FALSE;
+ }
+
+ if (pos > end)
+ {
+ _dbus_verbose ("tuple contents exceed stated tuple length\n");
+ return FALSE;
+ }
+
+ *end_pos = pos;
+ }
+ break;
default:
_dbus_verbose ("Unknown message arg type %d\n", type);
@@ -2232,6 +2270,7 @@
case DBUS_TYPE_ARRAY:
case DBUS_TYPE_DICT:
case DBUS_TYPE_OBJECT_PATH:
+ case DBUS_TYPE_TUPLE:
return TRUE;
default:
--5pXtTrWZSE--
More information about the dbus
mailing list