#include "dbus-internals.h"
#include "dbus-marshal-recursive.h"
#include "dbus-marshal-validate.h"
+#include "dbus-marshal-byteswap.h"
#include "dbus-marshal-header.h"
#include "dbus-message-private.h"
#include "dbus-object-tree.h"
} u; /**< the type writer or reader that does all the work */
};
+static void
+get_const_signature (DBusHeader *header,
+ const DBusString **type_str_p,
+ int *type_pos_p)
+{
+ if (_dbus_header_get_field_raw (header,
+ DBUS_HEADER_FIELD_SIGNATURE,
+ type_str_p,
+ type_pos_p))
+ {
+ *type_pos_p += 1; /* skip the signature length which is 1 byte */
+ }
+ else
+ {
+ *type_str_p = &_dbus_empty_signature_str;
+ *type_pos_p = 0;
+ }
+}
+
+/**
+ * Swaps the message to compiler byte order if required
+ *
+ * @param message the message
+ */
+static void
+_dbus_message_byteswap (DBusMessage *message)
+{
+ const DBusString *type_str;
+ int type_pos;
+
+ if (message->byte_order == DBUS_COMPILER_BYTE_ORDER)
+ return;
+
+ _dbus_verbose ("Swapping message into compiler byte order\n");
+
+ get_const_signature (&message->header, &type_str, &type_pos);
+
+ _dbus_marshal_byteswap (type_str, type_pos,
+ message->byte_order,
+ DBUS_COMPILER_BYTE_ORDER,
+ &message->body, 0);
+
+ message->byte_order = DBUS_COMPILER_BYTE_ORDER;
+
+ _dbus_header_byteswap (&message->header, DBUS_COMPILER_BYTE_ORDER);
+}
+
+#define ensure_byte_order(message) \
+ if (message->byte_order != DBUS_COMPILER_BYTE_ORDER) \
+ _dbus_message_byteswap (message)
+
/**
* Gets the data to be sent over the network for this message.
* The header and then the body should be written out.
&value);
}
-static void
-get_const_signature (DBusHeader *header,
- const DBusString **type_str_p,
- int *type_pos_p)
-{
- if (_dbus_header_get_field_raw (header,
- DBUS_HEADER_FIELD_SIGNATURE,
- type_str_p,
- type_pos_p))
- {
- *type_pos_p += 1; /* skip the signature length which is 1 byte */
- }
- else
- {
- *type_str_p = &_dbus_empty_signature_str;
- *type_pos_p = 0;
- }
-}
-
#if 0
/* Probably we don't need to use this */
/**
{
_dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
+ /* Since the iterator will read or write who-knows-what from the
+ * message, we need to get in the right byte order
+ */
+ ensure_byte_order (message);
+
real->message = message;
real->changed_stamp = message->changed_stamp;
real->iter_type = iter_type;
&message->body,
0);
- return _dbus_type_reader_has_next (&real->u.reader);
+ return _dbus_type_reader_get_current_type (&real->u.reader) != DBUS_TYPE_INVALID;
}
#ifndef DBUS_DISABLE_CHECKS
_dbus_warn ("dbus message changed byte order since iterator was created\n");
return FALSE;
}
+ /* because we swap the message into compiler order when you init an iter */
+ _dbus_assert (iter->u.reader.byte_order == DBUS_COMPILER_BYTE_ORDER);
}
else if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER)
{
_dbus_warn ("dbus message changed byte order since append iterator was created\n");
return FALSE;
}
+ /* because we swap the message into compiler order when you init an iter */
+ _dbus_assert (iter->u.writer.byte_order == DBUS_COMPILER_BYTE_ORDER);
}
else
{
* dbus_message_iter_close_container(). Container types are for
* example struct, variant, and array. For variants, the
* contained_signature should be the type of the single value inside
- * the variant. For structs, contained_signature should be #NULL; it
- * will be set to whatever types you write into the struct. For
- * arrays, contained_signature should be the type of the array
- * elements.
+ * the variant. For structs and dict entries, contained_signature
+ * should be #NULL; it will be set to whatever types you write into
+ * the struct. For arrays, contained_signature should be the type of
+ * the array elements.
*
* @todo If this fails due to lack of memory, the message is hosed and
* you have to start over building the whole message.
_dbus_return_val_if_fail (sub != NULL, FALSE);
_dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
contained_signature == NULL) ||
+ (type == DBUS_TYPE_DICT_ENTRY &&
+ contained_signature == NULL) ||
contained_signature != NULL, FALSE);
+ _dbus_return_val_if_fail (type != DBUS_TYPE_DICT_ENTRY ||
+ dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY,
+ FALSE);
+
+#if 0
+ /* FIXME this would fail if the contained_signature is a dict entry,
+ * since dict entries are invalid signatures standalone (they must be in
+ * an array)
+ */
+ _dbus_return_val_if_fail (contained_signature == NULL ||
+ _dbus_check_is_valid_signature (contained_signature));
+#endif
if (!_dbus_message_iter_open_signature (real))
return FALSE;