summaryrefslogtreecommitdiffstats
path: root/dbus/dbus-marshal.c
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2002-12-27 00:44:41 +0000
committerHavoc Pennington <hp@redhat.com>2002-12-27 00:44:41 +0000
commitff5283ab92c668453fd2f28c1715a1e0e9b949f5 (patch)
tree24cf1119e1d203dd08cd4d797ac8640d35451faa /dbus/dbus-marshal.c
parentf3729626de0093762c9d00a8d02db9c96fbd5bd2 (diff)
2002-12-26 Havoc Pennington <hp@pobox.com>
* dbus/dbus-marshal.h (DBUS_COMPILER_BYTE_ORDER): #ifdef WORDS_BIGENDIAN then compiler byte order is DBUS_BIG_ENDIAN, doh * dbus/dbus-marshal.c: Add macros to do int swapping in-place and avoid swap_bytes() overhead (ignoring possible assembly stuff for now). Main point is because I wanted unpack_uint32 to implement _dbus_verbose_bytes (_dbus_verbose_bytes): new function * dbus/dbus-string.c (_dbus_string_validate_ascii): new function * dbus/dbus-message.c (_dbus_message_loader_get_is_corrupted): add mechanism to handle a corrupt message stream (_dbus_message_loader_new): fix preallocation to only prealloc, not prelengthen * dbus/dbus-string.c (_dbus_string_skip_blank): fix this function (_dbus_string_test): enhance tests for copy/move and fix the functions * dbus/dbus-transport-unix.c: Hold references in more places to avoid reentrancy problems * dbus/dbus-transport.c: ditto * dbus/dbus-connection.c (dbus_connection_dispatch_message): don't leak reference count in no-message case * test/watch.c (do_mainloop): handle adding/removing watches during iteration over the watches. Also, ref the connection/server stored on a watch, so we don't try to mangle a destroyed one. * dbus/dbus-transport-unix.c (do_authentication): perform authentication * dbus/dbus-auth.c (get_state): add a state AUTHENTICATED_WITH_UNUSED_BYTES and return it if required (_dbus_auth_get_unused_bytes): append the unused bytes to the passed in string, rather than prepend * dbus/dbus-transport.c (_dbus_transport_init_base): create the auth conversation DBusAuth * dbus/dbus-transport-unix.c (_dbus_transport_new_for_fd) (_dbus_transport_new_for_domain_socket): when creating a transport, pass in whether it's a client-side or server-side transport so we know which DBusAuth to create
Diffstat (limited to 'dbus/dbus-marshal.c')
-rw-r--r--dbus/dbus-marshal.c147
1 files changed, 130 insertions, 17 deletions
diff --git a/dbus/dbus-marshal.c b/dbus/dbus-marshal.c
index bbcda141..9fbfb4e1 100644
--- a/dbus/dbus-marshal.c
+++ b/dbus/dbus-marshal.c
@@ -26,9 +26,37 @@
#include <string.h>
+#define DBUS_UINT32_SWAP_LE_BE_CONSTANT(val) ((dbus_uint32_t) ( \
+ (((dbus_uint32_t) (val) & (dbus_uint32_t) 0x000000ffU) << 24) | \
+ (((dbus_uint32_t) (val) & (dbus_uint32_t) 0x0000ff00U) << 8) | \
+ (((dbus_uint32_t) (val) & (dbus_uint32_t) 0x00ff0000U) >> 8) | \
+ (((dbus_uint32_t) (val) & (dbus_uint32_t) 0xff000000U) >> 24)))
+
+#define DBUS_UINT32_SWAP_LE_BE(val) (DBUS_UINT32_SWAP_LE_BE_CONSTANT (val))
+
+#ifdef WORDS_BIGENDIAN
+#define DBUS_INT32_TO_BE(val) ((dbus_int32_t) (val))
+#define DBUS_UINT32_TO_BE(val) ((dbus_uint32_t) (val))
+#define DBUS_INT32_TO_LE(val) ((dbus_int32_t) DBUS_UINT32_SWAP_LE_BE (val))
+#define DBUS_UINT32_TO_LE(val) (DBUS_UINT32_SWAP_LE_BE (val))
+#else
+#define DBUS_INT32_TO_LE(val) ((dbus_int32_t) (val))
+#define DBUS_UINT32_TO_LE(val) ((dbus_uint32_t) (val))
+#define DBUS_INT32_TO_BE(val) ((dbus_int32_t) DBUS_UINT32_SWAP_LE_BE (val))
+#define DBUS_UINT32_TO_BE(val) (DBUS_UINT32_SWAP_LE_BE (val))
+#endif
+
+/* The transformation is symmetric, so the FROM just maps to the TO. */
+#define DBUS_INT32_FROM_LE(val) (DBUS_INT32_TO_LE (val))
+#define DBUS_UINT32_FROM_LE(val) (DBUS_UINT32_TO_LE (val))
+#define DBUS_INT32_FROM_BE(val) (DBUS_INT32_TO_BE (val))
+#define DBUS_UINT32_FROM_BE(val) (DBUS_UINT32_TO_BE (val))
+
+
/* This alignment thing is from ORBit2 */
/* Align a value upward to a boundary, expressed as a number of bytes.
- E.g. align to an 8-byte boundary with argument of 8. */
+ * E.g. align to an 8-byte boundary with argument of 8.
+ */
/*
* (this + boundary - 1)
@@ -61,6 +89,41 @@ swap_bytes (unsigned char *data,
}
}
+static dbus_uint32_t
+unpack_uint32 (int byte_order,
+ const unsigned char *data)
+{
+ _dbus_assert (DBUS_ALIGN_ADDRESS (data, 4) == data);
+
+ if (byte_order == DBUS_LITTLE_ENDIAN)
+ return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)data);
+ else
+ return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)data);
+}
+
+static dbus_int32_t
+unpack_int32 (int byte_order,
+ const unsigned char *data)
+{
+ _dbus_assert (DBUS_ALIGN_ADDRESS (data, 4) == data);
+
+ if (byte_order == DBUS_LITTLE_ENDIAN)
+ return DBUS_INT32_FROM_LE (*(dbus_int32_t*)data);
+ else
+ return DBUS_INT32_FROM_BE (*(dbus_int32_t*)data);
+}
+
+/**
+ * @defgroup DBusMarshal marshaling and unmarshaling
+ * @ingroup DBusInternals
+ * @brief functions to marshal/unmarshal data from the wire
+ *
+ * Types and functions related to converting primitive data types from
+ * wire format to native machine format, and vice versa.
+ *
+ * @{
+ */
+
dbus_bool_t
_dbus_marshal_double (DBusString *str,
int byte_order,
@@ -161,20 +224,14 @@ _dbus_demarshal_int32 (DBusString *str,
int pos,
int *new_pos)
{
- dbus_int32_t retval;
const char *buffer;
_dbus_string_get_const_data_len (str, &buffer, pos, sizeof (dbus_int32_t));
- retval = *(dbus_int32_t *)buffer;
-
- if (byte_order != DBUS_COMPILER_BYTE_ORDER)
- swap_bytes ((unsigned char *)&retval, sizeof (dbus_int32_t));
-
if (new_pos)
*new_pos = pos + sizeof (dbus_int32_t);
-
- return retval;
+
+ return unpack_int32 (byte_order, buffer);
}
dbus_uint32_t
@@ -183,20 +240,14 @@ _dbus_demarshal_uint32 (DBusString *str,
int pos,
int *new_pos)
{
- dbus_uint32_t retval;
const char *buffer;
_dbus_string_get_const_data_len (str, &buffer, pos, sizeof (dbus_uint32_t));
- retval = *(dbus_uint32_t *)buffer;
-
- if (byte_order != DBUS_COMPILER_BYTE_ORDER)
- swap_bytes ((unsigned char *)&retval, sizeof (dbus_uint32_t));
-
if (new_pos)
*new_pos = pos + sizeof (dbus_uint32_t);
-
- return retval;
+
+ return unpack_uint32 (byte_order, buffer);
}
char *
@@ -229,6 +280,68 @@ _dbus_demarshal_string (DBusString *str,
return retval;
}
+/**
+ * If in verbose mode, print a block of binary data.
+ *
+ * @param data the data
+ * @param len the length of the data
+ */
+void
+_dbus_verbose_bytes (const unsigned char *data,
+ int len)
+{
+ int i;
+ const unsigned char *aligned;
+
+ /* Print blanks on first row if appropriate */
+ aligned = DBUS_ALIGN_ADDRESS (data, 4);
+ if (aligned > data)
+ aligned -= 4;
+ _dbus_assert (aligned <= data);
+
+ if (aligned != data)
+ {
+ _dbus_verbose ("%5d\t%p: ", - (data - aligned), aligned);
+ while (aligned != data)
+ {
+ _dbus_verbose (" ");
+ ++aligned;
+ }
+ }
+
+ /* now print the bytes */
+ i = 0;
+ while (i < len)
+ {
+ if (DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
+ {
+ _dbus_verbose ("%5d\t%p: ",
+ i, &data[i]);
+ }
+
+ if (data[i] >= 32 &&
+ data[i] <= 126)
+ _dbus_verbose (" '%c' ", data[i]);
+ else
+ _dbus_verbose ("0x%s%x ",
+ data[i] <= 0xf ? "0" : "", data[i]);
+
+ ++i;
+
+ if (DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
+ {
+ if (i > 3)
+ _dbus_verbose ("big: %d little: %d",
+ unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
+ unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
+
+ _dbus_verbose ("\n");
+ }
+ }
+
+ _dbus_verbose ("\n");
+}
+
/** @} */
#ifdef DBUS_BUILD_TESTS