dbus/dbus dbus-marshal-basic.c, 1.6, 1.7 dbus-marshal-basic.h, 1.4, 1.5 dbus-marshal-recursive.c, 1.23, 1.24 dbus-marshal-recursive.h, 1.13, 1.14

Havoc Pennington hp at freedesktop.org
Sat Jan 1 13:05:51 PST 2005


Update of /cvs/dbus/dbus/dbus
In directory gabe:/tmp/cvs-serv2182

Modified Files:
	dbus-marshal-basic.c dbus-marshal-basic.h 
	dbus-marshal-recursive.c dbus-marshal-recursive.h 
Log Message:
chop dbus-marshal-basic in half and move it to be insertion rather than append based


Index: dbus-marshal-basic.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-marshal-basic.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- dbus-marshal-basic.c	1 Jan 2005 08:19:28 -0000	1.6
+++ dbus-marshal-basic.c	1 Jan 2005 21:05:48 -0000	1.7
@@ -2,10 +2,10 @@
 /* dbus-marshal-basic.c  Marshalling routines for basic (primitive) types
  *
  * Copyright (C) 2002 CodeFactory AB
- * Copyright (C) 2003, 2004 Red Hat, Inc.
+ * Copyright (C) 2003, 2004, 2005 Red Hat, Inc.
  *
  * Licensed under the Academic Free License version 2.1
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -15,7 +15,7 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
@@ -23,9 +23,6 @@
  */
 
 #include "dbus-internals.h"
-#define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
-#include "dbus-string-private.h"
-
 #include "dbus-marshal-basic.h"
 
 #include <string.h>
@@ -50,7 +47,7 @@
                  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
@@ -80,7 +77,7 @@
 
 /**
  * Union used to manipulate 8 bytes as if they
- * were various types. 
+ * were various types.
  */
 typedef union
 {
@@ -96,10 +93,10 @@
                  const unsigned char *data)
 {
   DBusOctets8 r;
-  
+
   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
   _dbus_assert (sizeof (r) == 8);
-  
+
 #ifdef DBUS_HAVE_INT64
   if (byte_order == DBUS_LITTLE_ENDIAN)
     r.u = DBUS_UINT64_FROM_LE (*(dbus_uint64_t*)data);
@@ -110,7 +107,7 @@
   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
     swap_bytes ((unsigned char*) &r, sizeof (r));
 #endif
-  
+
   return r;
 }
 
@@ -126,7 +123,7 @@
                      const unsigned char *data)
 {
   return unpack_4_octets (byte_order, data);
-}  
+}
 
 /**
  * Unpacks a 32 bit signed integer from a data pointer
@@ -155,11 +152,11 @@
                      const unsigned char *data)
 {
   DBusOctets8 r;
-  
+
   r = unpack_8_octets (byte_order, data);
 
   return r.u;
-}  
+}
 
 /**
  * Unpacks a 64 bit signed integer from a data pointer
@@ -173,7 +170,7 @@
                     const unsigned char *data)
 {
   DBusOctets8 r;
-  
+
   r = unpack_8_octets (byte_order, data);
 
   return r.s;
@@ -187,9 +184,9 @@
                unsigned char  *data)
 {
   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
-  
-  if ((byte_order) == DBUS_LITTLE_ENDIAN)                  
-    *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value);       
+
+  if ((byte_order) == DBUS_LITTLE_ENDIAN)
+    *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value);
   else
     *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value);
 }
@@ -216,8 +213,8 @@
   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
 
 #ifdef DBUS_HAVE_INT64
-  if ((byte_order) == DBUS_LITTLE_ENDIAN)                  
-    *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_LE (value.u); 
+  if ((byte_order) == DBUS_LITTLE_ENDIAN)
+    *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_LE (value.u);
   else
     *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_BE (value.u);
 #else
@@ -299,10 +296,10 @@
               dbus_uint32_t        value)
 {
   char *data;
-  
+
   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
                 byte_order == DBUS_BIG_ENDIAN);
-  
+
   data = _dbus_string_get_data_len (str, offset, 4);
 
   _dbus_pack_uint32 (value, byte_order, data);
@@ -315,10 +312,10 @@
               DBusOctets8          value)
 {
   char *data;
-  
+
   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
                 byte_order == DBUS_BIG_ENDIAN);
-  
+
   data = _dbus_string_get_data_len (str, offset, 8);
 
   pack_8_octets (value, byte_order, data);
@@ -332,7 +329,7 @@
  * @param offset the byte offset where int should be written
  * @param byte_order the byte order to use
  * @param value the value
- * 
+ *
  */
 void
 _dbus_marshal_set_int32 (DBusString          *str,
@@ -351,7 +348,7 @@
  * @param offset the byte offset where int should be written
  * @param byte_order the byte order to use
  * @param value the value
- * 
+ *
  */
 void
 _dbus_marshal_set_uint32 (DBusString          *str,
@@ -372,7 +369,7 @@
  * @param offset the byte offset where int should be written
  * @param byte_order the byte order to use
  * @param value the value
- * 
+ *
  */
 void
 _dbus_marshal_set_int64 (DBusString          *str,
@@ -393,7 +390,7 @@
  * @param offset the byte offset where int should be written
  * @param byte_order the byte order to use
  * @param value the value
- * 
+ *
  */
 void
 _dbus_marshal_set_uint64 (DBusString          *str,
@@ -423,7 +420,7 @@
  * @param value the value
  * @param len the length to use
  * @returns #TRUE on success
- * 
+ *
  */
 dbus_bool_t
 _dbus_marshal_set_string (DBusString          *str,
@@ -433,10 +430,10 @@
 			  int                  len)
 {
   int old_len;
-  
+
   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
                 byte_order == DBUS_BIG_ENDIAN);
-  
+
   old_len = _dbus_demarshal_uint32 (str, byte_order,
                                     offset, NULL);
 
@@ -450,658 +447,23 @@
   return TRUE;
 }
 
-/**
- * Sets the existing marshaled object path at the given offset to a new
- * value. The given offset must point to an existing object path or this
- * function doesn't make sense.
- *
- * @todo implement this function
- *
- * @param str the string to write the marshalled path to
- * @param offset the byte offset where path should be written
- * @param byte_order the byte order to use
- * @param path the new path
- * @param path_len number of elements in the path
- */
-void
-_dbus_marshal_set_object_path (DBusString         *str,
-                               int                 byte_order,
-                               int                 offset,
-                               const char        **path,
-                               int                 path_len)
-{
-
-  /* FIXME */
-}
-
-static dbus_bool_t
-marshal_4_octets (DBusString   *str,
-                  int           insert_at,
-                  int           byte_order,
-                  dbus_uint32_t value)
-{
-  _dbus_assert (sizeof (value) == 4);
-  
-  if (byte_order != DBUS_COMPILER_BYTE_ORDER)
-    value = DBUS_UINT32_SWAP_LE_BE (value);
-
-  return _dbus_string_insert_4_aligned (str, insert_at,
-                                        (const unsigned char *)&value);
-}
-
-static dbus_bool_t
-marshal_8_octets (DBusString *str,
-                  int         insert_at,
-                  int         byte_order,
-                  DBusOctets8 value)
-{
-  _dbus_assert (sizeof (value) == 8);
-
-  swap_8_octets (&value, byte_order);
-  
-  return _dbus_string_insert_8_aligned (str, insert_at,
-                                        (const unsigned char *)&value);
-}
-
-/**
- * Marshals a double value.
- *
- * @param str the string to append the marshalled value to
- * @param byte_order the byte order to use
- * @param value the value
- * @returns #TRUE on success
- */
-dbus_bool_t
-_dbus_marshal_double (DBusString *str,
-		      int         byte_order,
-		      double      value)
-{
-  DBusOctets8 r;
-  r.d = value;
-  return marshal_8_octets (str, _dbus_string_get_length (str),
-                           byte_order, r);
-}
-
-/**
- * Marshals a 32 bit signed integer value.
- *
- * @param str the string to append the marshalled value to
- * @param byte_order the byte order to use
- * @param value the value
- * @returns #TRUE on success
- */
-dbus_bool_t
-_dbus_marshal_int32  (DBusString   *str,
-		      int           byte_order,
-		      dbus_int32_t  value)
-{
-  return marshal_4_octets (str, _dbus_string_get_length (str),
-                           byte_order, (dbus_uint32_t) value);
-}
-
-/**
- * Marshals a 32 bit unsigned integer value.
- *
- * @param str the string to append the marshalled value to
- * @param byte_order the byte order to use
- * @param value the value
- * @returns #TRUE on success
- */
-dbus_bool_t
-_dbus_marshal_uint32 (DBusString   *str,
-                      int           byte_order,
-                      dbus_uint32_t value)
-{
-  return marshal_4_octets (str, _dbus_string_get_length (str),
-                           byte_order, value);
-}
-
-
-#ifdef DBUS_HAVE_INT64
-/**
- * Marshals a 64 bit signed integer value.
- *
- * @param str the string to append the marshalled value to
- * @param byte_order the byte order to use
- * @param value the value
- * @returns #TRUE on success
- */
-dbus_bool_t
-_dbus_marshal_int64  (DBusString   *str,
-		      int           byte_order,
-		      dbus_int64_t  value)
-{
-  DBusOctets8 r;
-  r.s = value;
-  return marshal_8_octets (str, _dbus_string_get_length (str),
-                           byte_order, r);
-}
-
-/**
- * Marshals a 64 bit unsigned integer value.
- *
- * @param str the string to append the marshalled value to
- * @param byte_order the byte order to use
- * @param value the value
- * @returns #TRUE on success
- */
-dbus_bool_t
-_dbus_marshal_uint64 (DBusString    *str,
-		      int            byte_order,
-		      dbus_uint64_t  value)
-{
-  DBusOctets8 r;
-  r.u = value;
-  return marshal_8_octets (str, _dbus_string_get_length (str),
-                           byte_order, r);
-}
-
-#endif /* DBUS_HAVE_INT64 */
-
-/**
- * Marshals a UTF-8 string
- *
- * @todo: If the string append fails we need to restore
- * the old length. (also for other marshallers)
- * 
- * @param str the string to append the marshalled value to
- * @param byte_order the byte order to use
- * @param value the string
- * @returns #TRUE on success
- */
-dbus_bool_t
-_dbus_marshal_string (DBusString    *str,
-		      int            byte_order,
-		      const char    *value)
-{
-  int len, old_string_len;
-
-  old_string_len = _dbus_string_get_length (str);
-  
-  len = strlen (value);
-
-  if (!_dbus_marshal_uint32 (str, byte_order, len))
-    {
-      /* Restore the previous length */
-      _dbus_string_set_length (str, old_string_len);
-
-      return FALSE;
-    }
-
-  return _dbus_string_append_len (str, value, len + 1);
-}
-
-/**
- * Marshals a UTF-8 string
- *
- * @todo: If the string append fails we need to restore
- * the old length. (also for other marshallers)
- * 
- * @param str the string to append the marshalled value to
- * @param byte_order the byte order to use
- * @param value the string
- * @param len length of string to marshal in bytes
- * @returns #TRUE on success
- */
-dbus_bool_t
-_dbus_marshal_string_len (DBusString    *str,
-                          int            byte_order,
-                          const char    *value,
-                          int            len)
-{
-  int old_string_len;
-
-  old_string_len = _dbus_string_get_length (str);
-
-  if (!_dbus_marshal_uint32 (str, byte_order, len))
-    {
-      /* Restore the previous length */
-      _dbus_string_set_length (str, old_string_len);
-
-      return FALSE;
-    }
-
-  if (!_dbus_string_append_len (str, value, len))
-    return FALSE;
-
-  /* add a nul byte */
-  if (!_dbus_string_lengthen (str, 1))
-    return FALSE;
-
-  return TRUE;
-}
-
-static dbus_bool_t
-_dbus_marshal_signature (DBusString    *str,
-                         const char    *value)
-{
-  int len, old_string_len;
-
-  old_string_len = _dbus_string_get_length (str);
-  
-  len = strlen (value);
-
-  _dbus_assert (len <= DBUS_MAXIMUM_SIGNATURE_LENGTH);
-  
-  if (!_dbus_string_append_byte (str, len))
-    {
-      /* Restore the previous length */
-      _dbus_string_set_length (str, old_string_len);
-
-      return FALSE;
-    }
-
-  return _dbus_string_append_len (str, value, len + 1);
-}
-
-/**
- * Marshals a byte array
- *
- * @param str the string to append the marshalled value to
- * @param byte_order the byte order to use
- * @param value the array
- * @param len number of elements in the array
- * @returns #TRUE on success
- */
-dbus_bool_t
-_dbus_marshal_byte_array (DBusString          *str,
-			  int                  byte_order,
-			  const unsigned char *value,
-			  int                  len)
-{
-  int old_string_len;
-
-  old_string_len = _dbus_string_get_length (str);
-  
-  if (!_dbus_marshal_uint32 (str, byte_order, len))
-    {
-      /* Restore the previous length */
-      _dbus_string_set_length (str, old_string_len);
-
-      return FALSE;
-    }
-
-  if (len == 0)
-    return TRUE;
-  else
-    return _dbus_string_append_len (str, value, len);
-}
-
-static dbus_bool_t
-marshal_4_octets_array (DBusString          *str,
-                        int                  byte_order,
-                        const dbus_uint32_t *value,
-                        int                  len)
-{
-  int old_string_len;
-  int array_start;
-
-  old_string_len = _dbus_string_get_length (str);
-
-  if (!_dbus_marshal_uint32 (str, byte_order, len * 4))
-    goto error;
-
-  array_start = _dbus_string_get_length (str);
-  
-  if (!_dbus_string_append_len (str, (const unsigned char*) value,
-                                len * 4))
-    goto error;
-  
-  if (byte_order != DBUS_COMPILER_BYTE_ORDER)
-    {
-      const unsigned char *d;
-      const unsigned char *end;
-      
-      d = _dbus_string_get_data (str) + array_start;
-      end = d + len * 4;
-      while (d != end)
-        {
-          *((dbus_uint32_t*)d) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)d));
-          d += 4;
-        }
-    }
-
-  return TRUE;
-  
- error:
-  /* Restore previous length */
-  _dbus_string_set_length (str, old_string_len);
-  
-  return FALSE;  
-}
-
-static dbus_bool_t
-marshal_8_octets_array (DBusString          *str,
-                        int                  byte_order,
-                        const DBusOctets8   *value,
-                        int                  len)
-{
-  int old_string_len;
-  int array_start;
-  
-  old_string_len = _dbus_string_get_length (str);
-
-  /*  The array length is the length in bytes of the array,
-   * *excluding* alignment padding.
-   */
-  if (!_dbus_marshal_uint32 (str, byte_order, len * 8))
-    goto error;
-
-  array_start = _dbus_string_get_length (str);
-
-  /* Note that we do alignment padding unconditionally
-   * even if the array is empty; this means that
-   * padding + len is always equal to the number of bytes
-   * in the array.
-   */
-  
-  if (!_dbus_string_align_length (str, 8))
-    goto error;
-  
-  if (!_dbus_string_append_len (str, (const unsigned char*) value,
-                                len * 8))
-    goto error;
-  
-  if (byte_order != DBUS_COMPILER_BYTE_ORDER)
-    {
-      const unsigned char *d;
-      const unsigned char *end;
-      
-      d = _dbus_string_get_data (str) + array_start;
-      end = d + len * 8;
-      while (d != end)
-        {
-#ifdef DBUS_HAVE_INT64
-          *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d));
-#else
-          swap_bytes ((unsigned char*) d, 8);
-#endif
-          d += 8;
-        }
-    }
-
-  return TRUE;
-  
- error:
-  /* Restore previous length */
-  _dbus_string_set_length (str, old_string_len);
-  
-  return FALSE;  
-}
-
-/**
- * Marshals a 32 bit signed integer array
- *
- * @param str the string to append the marshalled value to
- * @param byte_order the byte order to use
- * @param value the array
- * @param len the length of the array
- * @returns #TRUE on success
- */
-dbus_bool_t
-_dbus_marshal_int32_array (DBusString         *str,
-			   int                 byte_order,
-			   const dbus_int32_t *value,
-			   int                 len)
-{
-  return marshal_4_octets_array (str, byte_order,
-                                 (const dbus_uint32_t*) value,
-                                 len);
-}
-
-/**
- * Marshals a 32 bit unsigned integer array
- *
- * @param str the string to append the marshalled value to
- * @param byte_order the byte order to use
- * @param value the array
- * @param len the length of the array
- * @returns #TRUE on success
- */
-dbus_bool_t
-_dbus_marshal_uint32_array (DBusString          *str,
-			    int                  byte_order,
-			    const dbus_uint32_t  *value,
-			    int                  len)
-{
-  return marshal_4_octets_array (str, byte_order,
-                                 value,
-                                 len);
-}
-
-#ifdef DBUS_HAVE_INT64
-
-/**
- * Marshals a 64 bit signed integer array
- *
- * @param str the string to append the marshalled value to
- * @param byte_order the byte order to use
- * @param value the array
- * @param len the length of the array
- * @returns #TRUE on success
- */
-dbus_bool_t
-_dbus_marshal_int64_array (DBusString         *str,
-			   int                 byte_order,
-			   const dbus_int64_t *value,
-			   int                 len)
-{
-  return marshal_8_octets_array (str, byte_order,
-                                 (const DBusOctets8*) value,
-                                 len);
-}
-
-/**
- * Marshals a 64 bit unsigned integer array
- *
- * @param str the string to append the marshalled value to
- * @param byte_order the byte order to use
- * @param value the array
- * @param len the length of the array
- * @returns #TRUE on success
- */
-dbus_bool_t
-_dbus_marshal_uint64_array (DBusString          *str,
-			    int                  byte_order,
-			    const dbus_uint64_t  *value,
-			    int                  len)
-{
-  return marshal_8_octets_array (str, byte_order,
-                                 (const DBusOctets8*) value,
-                                 len);
-}
-
-#endif /* DBUS_HAVE_INT64 */
-
-/**
- * Marshals a double array
- *
- * @param str the string to append the marshalled value to
- * @param byte_order the byte order to use
- * @param value the array
- * @param len the length of the array
- * @returns #TRUE on success
- */
-dbus_bool_t
-_dbus_marshal_double_array (DBusString          *str,
-			    int                  byte_order,
-			    const double        *value,
-			    int                  len)
-{
-  return marshal_8_octets_array (str, byte_order,
-                                 (const DBusOctets8*) value,
-                                 len);
-}
-
-/**
- * Marshals a string array
- *
- * @param str the string to append the marshalled value to
- * @param byte_order the byte order to use
- * @param value the array
- * @param len the length of the array
- * @returns #TRUE on success
- */
-dbus_bool_t
-_dbus_marshal_string_array (DBusString  *str,
-			    int          byte_order,
-			    const char **value,
-			    int          len)
-{
-  int i, old_string_len, array_start;
-
-  old_string_len = _dbus_string_get_length (str);
-
-  /* Set the length to 0 temporarily */
-  if (!_dbus_marshal_uint32 (str, byte_order, 0))
-    goto error;
-
-  array_start = _dbus_string_get_length (str);
-  
-  for (i = 0; i < len; i++)
-    if (!_dbus_marshal_string (str, byte_order, value[i]))
-      goto error;
-
-  /* Write the length now that we know it */
-  _dbus_marshal_set_uint32 (str, byte_order,
-			    _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
-			    _dbus_string_get_length (str) - array_start);
-  
-  return TRUE;
-  
- error:
-  /* Restore previous length */
-  _dbus_string_set_length (str, old_string_len);
-  
-  return FALSE;      
-}
-
-/**
- * Marshals an object path value.
- * 
- * @param str the string to append the marshalled value to
- * @param byte_order the byte order to use
- * @param path the path
- * @param path_len length of the path
- * @returns #TRUE on success
- */
-static dbus_bool_t
-_dbus_marshal_object_path (DBusString            *str,
-                           int                    byte_order,
-                           const char           **path,
-                           int                    path_len)
-{
-  int array_start, old_string_len;
-  int i;
-  
-  old_string_len = _dbus_string_get_length (str);
-  
-  /* Set the length to 0 temporarily */
-  if (!_dbus_marshal_uint32 (str, byte_order, 0))
-    goto nomem;
-
-  array_start = _dbus_string_get_length (str);
-  
-  i = 0;
-  while (i < path_len)
-    {
-      if (!_dbus_string_append_byte (str, '/'))
-        goto nomem;
-      
-      if (!_dbus_string_append (str, path[0]))
-        goto nomem;
-
-      ++i;
-    }
-
-  /* Write the length now that we know it */
-  _dbus_marshal_set_uint32 (str, byte_order,
-			    _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
-			    _dbus_string_get_length (str) - array_start);  
-
-  return TRUE;
-
- nomem:
-  /* Restore the previous length */
-  _dbus_string_set_length (str, old_string_len);
-  
-  return FALSE;
-}
-
 static dbus_uint32_t
 demarshal_4_octets (const DBusString *str,
                     int               byte_order,
                     int               pos,
                     int              *new_pos)
 {
-  const DBusRealString *real = (const DBusRealString*) str;
-  
   pos = _DBUS_ALIGN_VALUE (pos, 4);
-  
-  if (new_pos)
-    *new_pos = pos + 4;
 
-  return unpack_4_octets (byte_order, real->str + pos);
-}
-
-static DBusOctets8
-demarshal_8_octets (const DBusString *str,
-                    int               byte_order,
-                    int               pos,
-                    int              *new_pos)
-{
-  const DBusRealString *real = (const DBusRealString*) str;
-  
-  pos = _DBUS_ALIGN_VALUE (pos, 8);
-  
   if (new_pos)
-    *new_pos = pos + 8;
-
-  return unpack_8_octets (byte_order, real->str + pos);
-}
-
-/**
- * Demarshals a double.
- *
- * @param str the string containing the data
- * @param byte_order the byte order
- * @param pos the position in the string
- * @param new_pos the new position of the string
- * @returns the demarshaled double.
- */
-double
-_dbus_demarshal_double (const DBusString  *str,
-			int                byte_order,
-			int                pos,
-			int               *new_pos)
-{
-  DBusOctets8 r;
-
-  r = demarshal_8_octets (str, byte_order, pos, new_pos);
-
-  return r.d;
-}
+    *new_pos = pos + 4;
 
-/**
- * Demarshals a 32 bit signed integer.
- *
- * @param str the string containing the data
- * @param byte_order the byte order
- * @param pos the position in the string
- * @param new_pos the new position of the string
- * @returns the demarshaled integer.
- */
-dbus_int32_t
-_dbus_demarshal_int32  (const DBusString *str,
-			int               byte_order,
-			int               pos,
-			int              *new_pos)
-{
-  return (dbus_int32_t) demarshal_4_octets (str, byte_order, pos, new_pos);
+  return unpack_4_octets (byte_order,
+                          _dbus_string_get_const_data (str) + pos);
 }
 
 /**
- * Demarshals a 32 bit unsigned integer.
+ * Convenience function to demarshal a 32 bit unsigned integer.
  *
  * @param str the string containing the data
  * @param byte_order the byte order
@@ -1111,61 +473,13 @@
  */
 dbus_uint32_t
 _dbus_demarshal_uint32  (const DBusString *str,
-			 int         byte_order,
-			 int         pos,
-			 int        *new_pos)
+			 int               byte_order,
+			 int               pos,
+			 int              *new_pos)
 {
   return demarshal_4_octets (str, byte_order, pos, new_pos);
 }
 
-#ifdef DBUS_HAVE_INT64
-
-/**
- * Demarshals a 64 bit signed integer.
- *
- * @param str the string containing the data
- * @param byte_order the byte order
- * @param pos the position in the string
- * @param new_pos the new position of the string
- * @returns the demarshaled integer.
- */
-dbus_int64_t
-_dbus_demarshal_int64  (const DBusString *str,
-			int               byte_order,
-			int               pos,
-			int              *new_pos)
-{
-  DBusOctets8 r;
-
-  r = demarshal_8_octets (str, byte_order, pos, new_pos);
-
-  return r.s;
-}
-
-/**
- * Demarshals a 64 bit unsigned integer.
- *
- * @param str the string containing the data
- * @param byte_order the byte order
- * @param pos the position in the string
- * @param new_pos the new position of the string
- * @returns the demarshaled integer.
- */
-dbus_uint64_t
-_dbus_demarshal_uint64  (const DBusString *str,
-			 int         byte_order,
-			 int         pos,
-			 int        *new_pos)
-{
-  DBusOctets8 r;
-
-  r = demarshal_8_octets (str, byte_order, pos, new_pos);
-
-  return r.u;
-}
-
-#endif /* DBUS_HAVE_INT64 */
-
 /**
  * Demarshals a basic type
  *
@@ -1173,661 +487,84 @@
  * @param type type of value to demarshal
  * @param value pointer to return value data
  * @param byte_order the byte order
- * @param pos pointer to position in the string,
- *            updated on return to new position
+ * @param pos position in the string
+ * @param new_pos pointer to update with new position, or #NULL
  **/
 void
 _dbus_demarshal_basic_type (const DBusString      *str,
 			    int                    type,
 			    void                  *value,
 			    int                    byte_order,
-			    int                   *pos)
+			    int                    pos,
+                            int                   *new_pos)
 {
-  const char *str_data = _dbus_string_get_const_data (str);
+  const char *str_data;
+
+  str_data = _dbus_string_get_const_data (str);
 
   switch (type)
     {
     case DBUS_TYPE_BYTE:
     case DBUS_TYPE_BOOLEAN:
-      *(unsigned char *) value = _dbus_string_get_byte (str, *pos);
-      (*pos)++;
+      *(unsigned char *) value = _dbus_string_get_byte (str, pos);
+      (pos)++;
       break;
     case DBUS_TYPE_INT32:
     case DBUS_TYPE_UINT32:
-      *pos = _DBUS_ALIGN_VALUE (*pos, 4);
-      *(dbus_uint32_t *) value = *(dbus_uint32_t *)(str_data + *pos);
+      pos = _DBUS_ALIGN_VALUE (pos, 4);
+      *(dbus_uint32_t *) value = *(dbus_uint32_t *)(str_data + pos);
       if (byte_order != DBUS_COMPILER_BYTE_ORDER)
 	*(dbus_uint32_t *) value = DBUS_UINT32_SWAP_LE_BE (*(dbus_uint32_t *) value);
-      *pos += 4;
+      pos += 4;
       break;
 #ifdef DBUS_HAVE_INT64
     case DBUS_TYPE_INT64:
-    case DBUS_TYPE_UINT64: 
+    case DBUS_TYPE_UINT64:
 #endif /* DBUS_HAVE_INT64 */
     case DBUS_TYPE_DOUBLE:
-      *pos = _DBUS_ALIGN_VALUE (*pos, 8);
-      memcpy (value, str_data + *pos, 8);
+      pos = _DBUS_ALIGN_VALUE (pos, 8);
+      memcpy (value, str_data + pos, 8);
       if (byte_order != DBUS_COMPILER_BYTE_ORDER)
 #ifdef DBUS_HAVE_INT64
 	*(dbus_uint64_t *) value = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t *) value);
-#else	
+#else
 	swap_bytes (value, 8);
 #endif
-      *pos += 8;
+      pos += 8;
       break;
     case DBUS_TYPE_STRING:
     case DBUS_TYPE_OBJECT_PATH:
       {
         int len;
-        
-        len = _dbus_demarshal_uint32 (str, byte_order, *pos, pos);
-        
-        *(const char**) value = str_data + *pos;
 
-        *pos += len + 1; /* length plus nul */
+        len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
+
+        *(const char**) value = str_data + pos;
+
+        pos += len + 1; /* length plus nul */
       }
       break;
     case DBUS_TYPE_SIGNATURE:
       {
         int len;
-        
-        len = _dbus_string_get_byte (str, *pos);
-        *pos += 1;
-        
-        *(const char**) value = str_data + *pos;
-
-        *pos += len + 1; /* length plus nul */
-      }
-      break;
-    default:
-      _dbus_verbose ("type %s not a basic type\n",
-                     _dbus_type_to_string (type));
-      _dbus_assert_not_reached ("not a basic type");
-      break;
-    }
-}
-
-/**
- * Demarshals an UTF-8 string.
- *
- * @todo Should we check the string to make sure
- * that it's  valid UTF-8, and maybe "fix" the string
- * if it's broken?
- *
- * @todo Should probably demarshal to a DBusString,
- * having memcpy() in here is Evil(tm).
- *
- * @param str the string containing the data
- * @param byte_order the byte order
- * @param pos the position in the string
- * @param new_pos the new position of the string
- * @returns the demarshaled string.
- */
-char *
-_dbus_demarshal_string (const DBusString *str,
-			int               byte_order,
-			int               pos,
-			int              *new_pos)
-{
-  int len;
-  char *retval;
-  const char *data;
-  
-  len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
-
-  retval = dbus_malloc (len + 1);
-
-  if (!retval)
-    return NULL;
-
-  data = _dbus_string_get_const_data_len (str, pos, len + 1);
-
-  if (!data)
-    return NULL;
-
-  memcpy (retval, data, len + 1);
-
-  if (new_pos)
-    *new_pos = pos + len + 1;
-  
-  return retval;
-}
-
-/**
- * Demarshals a byte array.
- *
- * @todo Should probably demarshal to a DBusString,
- * having memcpy() in here is Evil(tm).
- *
- * @param str the string containing the data
- * @param byte_order the byte order
- * @param pos the position in the string
- * @param new_pos the new position of the string
- * @param array the array
- * @param array_len length of the demarshaled data
- 
- * @returns #TRUE on success
- */
-dbus_bool_t
-_dbus_demarshal_byte_array (const DBusString  *str,
-			    int                byte_order,
-			    int                pos,
-			    int               *new_pos,
-			    unsigned char    **array,
-			    int               *array_len)
-{
-  int len;
-  unsigned char *retval;
-  const char *data;
-
-  len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
-
-  if (len == 0)
-    {
-      *array_len = len;
-      *array = NULL;
-
-      if (new_pos)
-	*new_pos = pos;
-      
-      return TRUE;
-    }
-  
-  retval = dbus_malloc (len);
 
-  if (!retval)
-    return FALSE;
-
-  data = _dbus_string_get_const_data_len (str, pos, len);
-
-  if (!data)
-    {
-      dbus_free (retval);
-      return FALSE;
-    }
-
-  memcpy (retval, data, len);
-
-  if (new_pos)
-    *new_pos = pos + len;
-
-  *array = retval;
-  *array_len = len;
-  
-  return TRUE;
-}
-
-static dbus_bool_t
-demarshal_4_octets_array (const DBusString  *str,
-                          int                byte_order,
-                          int                pos,
-                          int               *new_pos,
-                          dbus_uint32_t    **array,
-                          int               *array_len)
-{
-  int len, i;
-  dbus_uint32_t *retval;
-  int byte_len;
-  
-  byte_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
-  len = byte_len / 4;
-
-  if (len == 0)
-    {
-      *array_len = 0;
-      *array = NULL;
-
-      if (new_pos)
-	*new_pos = pos;
-      
-      return TRUE;
-    }
-
-  if (!_dbus_string_copy_data_len (str, (char**) &retval,
-                                   pos, byte_len))
-    return FALSE;
-  
-  if (byte_order != DBUS_COMPILER_BYTE_ORDER)
-    {
-      for (i = 0; i < len; i++)
-        retval[i] = DBUS_UINT32_SWAP_LE_BE (retval[i]);
-    }
-
-  if (new_pos)
-    *new_pos = pos + byte_len;
-
-  *array_len = len;
-  *array = retval;
-  
-  return TRUE;  
-}
-
-static dbus_bool_t
-demarshal_8_octets_array (const DBusString  *str,
-                          int                byte_order,
-                          int                pos,
-                          int               *new_pos,
-                          DBusOctets8      **array,
-                          int               *array_len)
-{
-  int len, i;
-  DBusOctets8 *retval;
-  int byte_len;
-  
-  byte_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
-
-  pos = _DBUS_ALIGN_VALUE (pos, 8);
-  
-  len = byte_len / 8;
-
-  if (len == 0)
-    {
-      *array_len = 0;
-      *array = NULL;
-
-      if (new_pos)
-	*new_pos = pos;
-      
-      return TRUE;
-    }
-
-  if (!_dbus_string_copy_data_len (str, (char**) &retval,
-                                   pos, byte_len))
-    return FALSE;
-  
-  if (byte_order != DBUS_COMPILER_BYTE_ORDER)
-    {
-      for (i = 0; i < len; i++)
-        {
-#ifdef DBUS_HAVE_INT64
-          retval[i].u = DBUS_UINT64_SWAP_LE_BE (retval[i].u);
-#else
-          swap_bytes ((unsigned char *) &retval[i], 8);
-#endif
-        }
-    }
-
-  if (new_pos)
-    *new_pos = pos + byte_len;
-
-  *array_len = len;
-  *array = retval;
-  
-  return TRUE;  
-}
-
-/**
- * Demarshals a 32 bit signed integer array.
- *
- * @param str the string containing the data
- * @param byte_order the byte order
- * @param pos the position in the string
- * @param new_pos the new position of the string
- * @param array the array
- * @param array_len length of the demarshaled data
- * @returns #TRUE on success
- */
-dbus_bool_t
-_dbus_demarshal_int32_array (const DBusString  *str,
-			     int                byte_order,
-			     int                pos,
-			     int               *new_pos,
-			     dbus_int32_t     **array,
-			     int               *array_len)
-{
-  return demarshal_4_octets_array (str, byte_order, pos, new_pos,
-                                   (dbus_uint32_t**) array, array_len);
-}
-
-/**
- * Demarshals a 32 bit unsigned integer array.
- *
- * @param str the string containing the data
- * @param byte_order the byte order
- * @param pos the position in the string
- * @param new_pos the new position of the string
- * @param array the array
- * @param array_len length of the demarshaled data
- * @returns #TRUE on success
- */
-dbus_bool_t
-_dbus_demarshal_uint32_array (const DBusString  *str,
-			      int                byte_order,
-			      int                pos,
-			      int               *new_pos,
-			      dbus_uint32_t    **array,
-			      int               *array_len)
-{
-  return demarshal_4_octets_array (str, byte_order, pos, new_pos,
-                                   array, array_len);
-}
-
-#ifdef DBUS_HAVE_INT64
-
-/**
- * Demarshals a 64 bit signed integer array.
- *
- * @param str the string containing the data
- * @param byte_order the byte order
- * @param pos the position in the string
- * @param new_pos the new position of the string
- * @param array the array
- * @param array_len length of the demarshaled data
- * @returns #TRUE on success
- */
-dbus_bool_t
-_dbus_demarshal_int64_array (const DBusString  *str,
-			     int                byte_order,
-			     int                pos,
-			     int               *new_pos,
-			     dbus_int64_t     **array,
-			     int               *array_len)
-{
-  return demarshal_8_octets_array (str, byte_order, pos, new_pos,
-                                   (DBusOctets8**) array, array_len);
-}
-
-/**
- * Demarshals a 64 bit unsigned integer array.
- *
- * @param str the string containing the data
- * @param byte_order the byte order
- * @param pos the position in the string
- * @param new_pos the new position of the string
- * @param array the array
- * @param array_len length of the demarshaled data
- * @returns #TRUE on success
- */
-dbus_bool_t
-_dbus_demarshal_uint64_array (const DBusString  *str,
-			      int                byte_order,
-			      int                pos,
-			      int               *new_pos,
-			      dbus_uint64_t    **array,
-			      int               *array_len)
-{
-  return demarshal_8_octets_array (str, byte_order, pos, new_pos,
-                                   (DBusOctets8**) array, array_len);
-}
-
-#endif /* DBUS_HAVE_INT64 */
-
-/**
- * Demarshals a double array.
- *
- * @param str the string containing the data
- * @param byte_order the byte order
- * @param pos the position in the string
- * @param new_pos the new position of the string
- * @param array the array
- * @param array_len length of the demarshaled data
- * @returns #TRUE on success
- */
-dbus_bool_t
-_dbus_demarshal_double_array (const DBusString  *str,
-			      int                byte_order,
-			      int                pos,
-			      int               *new_pos,
-			      double           **array,
-			      int               *array_len)
-{
-  return demarshal_8_octets_array (str, byte_order, pos, new_pos,
-                                   (DBusOctets8**) array, array_len);
-}
+        len = _dbus_string_get_byte (str, pos);
+        pos += 1;
 
+        *(const char**) value = str_data + pos;
 
-/**
- * Demarshals an array of basic types
- *
- * @param str the string containing the data
- * @param element_type type of array elements to demarshal
- * @param array pointer to pointer to array data
- * @param array_len pointer to array length
- * @param byte_order the byte order
- * @param pos pointer to position in the string,
- *            updated on return to new position
- **/
-dbus_bool_t
-_dbus_demarshal_basic_type_array (const DBusString      *str,
-				  int                    element_type,
-				  void                 **array,
-				  int                   *array_len,
-				  int                    byte_order,
-				  int                   *pos)
-{
-  switch (element_type)
-    {
-    case DBUS_TYPE_BOOLEAN:
-      /* FIXME: do we want to post-normalize these ? */
-    case DBUS_TYPE_BYTE:
-      return _dbus_demarshal_byte_array (str, byte_order, *pos, pos,
-					 (unsigned char **)array, array_len);
-      break;
-    case DBUS_TYPE_INT32:
-    case DBUS_TYPE_UINT32:
-      return demarshal_4_octets_array (str, byte_order, *pos, pos,
-				       (dbus_uint32_t **)array, array_len);
+        pos += len + 1; /* length plus nul */
+      }
       break;
-#ifdef DBUS_HAVE_INT64
-    case DBUS_TYPE_INT64:
-    case DBUS_TYPE_UINT64: 
-#endif /* DBUS_HAVE_INT64 */
-    case DBUS_TYPE_DOUBLE:
-      return demarshal_8_octets_array (str, byte_order, *pos, pos,
-				       (DBusOctets8**) array, array_len);
     default:
+      _dbus_warn ("type %s not a basic type\n",
+                  _dbus_type_to_string (type));
       _dbus_assert_not_reached ("not a basic type");
       break;
     }
-  return FALSE;
-}
-
-/**
- * Demarshals a string array.
- *
- * @param str the string containing the data
- * @param byte_order the byte order
- * @param pos the position in the string
- * @param new_pos the new position of the string
- * @param array the array
- * @param array_len location for length of the demarshaled data or NULL
- * @returns #TRUE on success
- */
-dbus_bool_t
-_dbus_demarshal_string_array (const DBusString   *str,
-			      int                 byte_order,
-			      int                 pos,
-			      int                *new_pos,
-			      char             ***array,
-			      int                *array_len)
-{
-  int bytes_len, i;
-  int len, allocated;
-  int end_pos;
-  char **retval;
-  
-  bytes_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
-  
-  if (bytes_len == 0)
-    {
-      *array_len = 0;
-      *array = NULL;
-
-      if (new_pos)
-	*new_pos = pos;
-      
-      return TRUE;
-    }
-
-  len = 0;
-  allocated = 4;
-  end_pos = pos + bytes_len;
-  
-  retval = dbus_new (char *, allocated);
-
-  if (!retval)
-    return FALSE;
-
-  while (pos < end_pos)
-    {
-      retval[len] = _dbus_demarshal_string (str, byte_order, pos, &pos);
-      
-      if (retval[len] == NULL)
-	goto error;
-      
-      len += 1;
-
-      if (len >= allocated - 1) /* -1 for NULL termination */
-        {
-          char **newp;
-          newp = dbus_realloc (retval,
-                               sizeof (char*) * allocated * 2);
-          if (newp == NULL)
-            goto error;
-
-          allocated *= 2;
-          retval = newp;
-        }
-    }
-      
-  retval[len] = NULL;
 
   if (new_pos)
     *new_pos = pos;
-  
-  *array = retval;
-  *array_len = len;
-  
-  return TRUE;
-
- error:
-  for (i = 0; i < len; i++)
-    dbus_free (retval[i]);
-  dbus_free (retval);
-
-  return FALSE;
-}
-
-/** Set to 1 to get a bunch of spew about disassembling the path string */
-#define VERBOSE_DECOMPOSE 0
-
-/**
- * Decompose an object path.  A path of just "/" is
- * represented as an empty vector of strings.
- * 
- * @param data the path data
- * @param len  the length of the path string
- * @param path address to store new object path
- * @param path_len length of stored path
- */
-dbus_bool_t
-_dbus_decompose_path (const char*     data,
-                      int             len,
-                      char         ***path,
-                      int            *path_len)
-{
-  char **retval;
-  int n_components;
-  int i, j, comp;
-
-  _dbus_assert (data != NULL);
-
-#if VERBOSE_DECOMPOSE
-  _dbus_verbose ("Decomposing path \"%s\"\n",
-                 data);
-#endif
-  
-  n_components = 0;
-  i = 0;
-  while (i < len)
-    {
-      if (data[i] == '/')
-        n_components += 1;
-      ++i;
-    }
-  
-  retval = dbus_new0 (char*, n_components + 1);
-
-  if (retval == NULL)
-    return FALSE;
-
-  comp = 0;
-  i = 0;
-  while (i < len)
-    {
-      if (data[i] == '/')
-        ++i;
-      j = i;
-
-      while (j < len && data[j] != '/')
-        ++j;
-
-      /* Now [i, j) is the path component */
-      _dbus_assert (i < j);
-      _dbus_assert (data[i] != '/');
-      _dbus_assert (j == len || data[j] == '/');
-
-#if VERBOSE_DECOMPOSE
-      _dbus_verbose ("  (component in [%d,%d))\n",
-                     i, j);
-#endif
-      
-      retval[comp] = _dbus_memdup (&data[i], j - i + 1);
-      if (retval[comp] == NULL)
-        {
-          dbus_free_string_array (retval);
-          return FALSE;
-        }
-      retval[comp][j-i] = '\0';
-#if VERBOSE_DECOMPOSE
-      _dbus_verbose ("  (component %d = \"%s\")\n",
-                     comp, retval[comp]);
-#endif
-
-      ++comp;
-      i = j;
-    }
-  _dbus_assert (i == len);
-  
-  *path = retval;
-  if (path_len)
-    *path_len = n_components;
-  
-  return TRUE;
-}
-
-/**
- * Demarshals an object path.  A path of just "/" is
- * represented as an empty vector of strings.
- * 
- * @param str the string containing the data
- * @param byte_order the byte order
- * @param pos the position in the string
- * @param new_pos the new position of the string
- * @param path address to store new object path
- * @param path_len length of stored path
- */
-dbus_bool_t
-_dbus_demarshal_object_path (const DBusString *str,
-                             int               byte_order,
-                             int               pos,
-                             int              *new_pos,
-                             char           ***path,
-                             int              *path_len)
-{
-  int len;
-  const char *data;
-  
-  len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
-  data = _dbus_string_get_const_data_len (str, pos, len + 1);
-
-  if (!_dbus_decompose_path (data, len, path, path_len))
-    return FALSE;
-
-  if (new_pos)
-    *new_pos = pos + len + 1;
-
-  return TRUE;
 }
 
 /**
@@ -1858,7 +595,7 @@
       break;
 #ifdef DBUS_HAVE_INT64
     case DBUS_TYPE_INT64:
-    case DBUS_TYPE_UINT64: 
+    case DBUS_TYPE_UINT64:
 #endif /* DBUS_HAVE_INT64 */
     case DBUS_TYPE_DOUBLE:
       *pos = _DBUS_ALIGN_VALUE (*pos, 8);
@@ -1868,24 +605,24 @@
     case DBUS_TYPE_OBJECT_PATH:
       {
         int len;
-        
+
         len = _dbus_demarshal_uint32 (str, byte_order, *pos, pos);
-        
+
         *pos += len + 1; /* length plus nul */
       }
       break;
     case DBUS_TYPE_SIGNATURE:
       {
         int len;
-        
+
         len = _dbus_string_get_byte (str, *pos);
-        
+
         *pos += len + 2; /* length byte plus length plus nul */
       }
       break;
     default:
-      _dbus_verbose ("type %s not a basic type\n",
-                     _dbus_type_to_string (type));
+      _dbus_warn ("type %s not a basic type\n",
+                  _dbus_type_to_string (type));
       _dbus_assert_not_reached ("not a basic type");
       break;
     }
@@ -1902,534 +639,27 @@
 void
 _dbus_marshal_skip_array (const DBusString  *str,
                           int                byte_order,
+                          int                element_type,
                           int               *pos)
 {
-  int len;
-
-  len = _dbus_demarshal_uint32 (str, byte_order, *pos, pos);
-
-  /* FIXME we need to insert alignment padding according to array type */
-  
-  *pos += len;
-}
-
-/** 
- * Returns the position right after the end of an argument.  PERFORMS
- * NO VALIDATION WHATSOEVER. The message must have been previously
- * validated.
- *
- * @param str a string
- * @param byte_order the byte order to use
- * @param type the type of the argument
- * @param pos the pos where the arg starts
- * @param end_pos pointer where the position right
- * after the end position will follow
- * @returns TRUE if more data exists after the arg
- */
-dbus_bool_t
-_dbus_marshal_get_arg_end_pos (const DBusString *str,
-                               int               byte_order,
-			       int               type,
-                               int               pos,
-                               int              *end_pos)
-{
-  if (pos >= _dbus_string_get_length (str))
-    return FALSE;
-
-  switch (type)
-    {
-    case DBUS_TYPE_INVALID:
-      return FALSE;
-      break;
-
-    case DBUS_TYPE_BYTE:
-      *end_pos = pos + 1;
-      break;
-      
-    case DBUS_TYPE_BOOLEAN:
-      *end_pos = pos + 1;
-      break;
-
-    case DBUS_TYPE_INT32:
-    case DBUS_TYPE_UINT32:
-      *end_pos = _DBUS_ALIGN_VALUE (pos, 4) + 4;
-      break;
-
-    case DBUS_TYPE_INT64:
-    case DBUS_TYPE_UINT64:
-    case DBUS_TYPE_DOUBLE:
-      
-      *end_pos = _DBUS_ALIGN_VALUE (pos, 8) + 8;
-      break;
-
-    case DBUS_TYPE_OBJECT_PATH:
-    case DBUS_TYPE_STRING:
-      {
-	int len;
-	
-	/* Demarshal the length */
-	len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
-
-	*end_pos = pos + len + 1;
-      }
-      break;
-      
-    case DBUS_TYPE_ARRAY:
-      {
-	int len;
-
-	/* Demarshal the length  */
-	len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
-
-        /* FIXME needs to align to the right boundary for the array type */
-	*end_pos = _DBUS_ALIGN_VALUE (pos, 4) + len;
-      }
-      break;
-      
-    default:
-      _dbus_warn ("Unknown message arg type %d\n", type);
-      _dbus_assert_not_reached ("Unknown message argument type\n");
-      return FALSE;
-    }
-
-  if (*end_pos > _dbus_string_get_length (str))
-    return FALSE;
-  
-  return TRUE;
-}
-
-/**
- * Demarshals and validates a length; returns < 0 if the validation
- * fails. The length is required to be small enough that
- * len*sizeof(double) will not overflow, and small enough to fit in a
- * signed integer. DOES NOT check whether the length points
- * beyond the end of the string, because it doesn't know the
- * size of array elements.
- *
- * @param str the string
- * @param byte_order the byte order
- * @param pos the unaligned string position (snap to next aligned)
- * @param new_pos return location for new position.
- */
-static int
-demarshal_and_validate_len (const DBusString *str,
-                            int               byte_order,
-                            int               pos,
-                            int              *new_pos)
-{
-  int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
-  unsigned int len;
-
-  _dbus_assert (new_pos != NULL);
-  
-  if ((align_4 + 4) > _dbus_string_get_length (str))
-    {
-      _dbus_verbose ("not enough room in message for array length\n");
-      return -1;
-    }
-  
-  if (!_dbus_string_validate_nul (str, pos,
-                                  align_4 - pos))
-    {
-      _dbus_verbose ("array length alignment padding not initialized to nul at %d\n", pos);
-      return -1;
-    }
-
-  len = _dbus_demarshal_uint32 (str, byte_order, align_4, new_pos);
-
-  /* note that the len is the number of bytes, so we need it to be
-   * at least SIZE_T_MAX, but make it smaller just to keep things
-   * sane.  We end up using ints for most sizes to avoid unsigned mess
-   * so limit to maximum 32-bit signed int divided by at least 8, more
-   * for a bit of paranoia margin. INT_MAX/32 is about 65 megabytes.
-   */  
-#define MAX_ARRAY_LENGTH (((unsigned int)_DBUS_INT_MAX) / 32)
-  if (len > MAX_ARRAY_LENGTH)
-    {
-      _dbus_verbose ("array length %u exceeds maximum of %u at pos %d\n",
-                     len, MAX_ARRAY_LENGTH, pos);
-      return -1;
-    }
-  else
-    return (int) len;
-}
-
-static dbus_bool_t
-validate_string (const DBusString *str,
-                 int               pos,
-                 int               len_without_nul,
-                 int              *end_pos)
-{
-  *end_pos = pos + len_without_nul + 1;
-  
-  if (*end_pos > _dbus_string_get_length (str))
-    {
-      _dbus_verbose ("string length outside length of the message\n");
-      return FALSE;
-    }
-  
-  if (_dbus_string_get_byte (str, pos + len_without_nul) != '\0')
-    {
-      _dbus_verbose ("string arg not nul-terminated\n");
-      return FALSE;
-    }
-  
-  if (!_dbus_string_validate_utf8 (str, pos, len_without_nul))
-    {
-      _dbus_verbose ("string is not valid UTF-8\n");
-      return FALSE;
-    }
-
-  return TRUE;
-}   
-
-/**
- * Validates and returns a typecode at a specific position
- * in the message
- *
- * @param str a string
- * @param type the type of the argument
- * @param pos the pos where the typecode starts
- * @param end_pos pointer where the position right
- * after the end position will follow
- * @returns #TRUE if the type is valid.
- */
-dbus_bool_t
-_dbus_marshal_validate_type   (const DBusString *str,
-			       int               pos,
-			       int              *type,
-			       int              *end_pos)
-{
-  const char *data;
-  
-  if (pos >= _dbus_string_get_length (str))
-    return FALSE;
-
-  data = _dbus_string_get_const_data_len (str, pos, 1);
-
-  if (_dbus_type_is_valid (*data))
-    {
-      *type = *data;
-      if (end_pos != NULL)
-	*end_pos = pos + 1;
-      return TRUE;
-    }
-
-  _dbus_verbose ("'%c' %d invalid type code\n", (int) *data, (int) *data);
-  
-  return FALSE;
-}
-
-/* Faster validator for array data that doesn't call
- * validate_arg for each value
- */
-static dbus_bool_t
-validate_array_data (const DBusString *str,
-                     int	       byte_order,
-                     int               depth,
-                     int               type,
-                     int               array_type_pos,
-                     int               pos,
-                     int              *new_pos,
-                     int               end)
-{
-  switch (type)
-    {
-    case DBUS_TYPE_INVALID:
-      return FALSE;
-      break;
-
-    case DBUS_TYPE_OBJECT_PATH:
-    case DBUS_TYPE_STRING:
-    case DBUS_TYPE_ARRAY:
-      /* 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
-       * in a byte array, so the primitive types are
-       * special-cased.
-       */
-      while (pos < end)
-        {
-          if (!_dbus_marshal_validate_arg (str, byte_order, depth,
-                                           type, array_type_pos, pos, &pos))
-            return FALSE;
-        }
-      break;
-      
-    case DBUS_TYPE_BYTE:
-      pos = end;
-      break;
-      
-    case DBUS_TYPE_BOOLEAN:
-      while (pos < end)
-        {
-          unsigned char c;
-          
-          c = _dbus_string_get_byte (str, pos);
-          
-          if (!(c == 0 || c == 1))
-            {
-              _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
-              return FALSE;
-            }
-          
-          ++pos;
-        }
-      break;
-      
-    case DBUS_TYPE_INT32:
-    case DBUS_TYPE_UINT32:
-      /* Call validate arg one time to check alignment padding
-       * at start of array
-       */
-      if (!_dbus_marshal_validate_arg (str, byte_order, depth,
-                                       type, array_type_pos, pos, &pos))
-        return FALSE;
-      pos = _DBUS_ALIGN_VALUE (end, 4);
-      break;
-
-    case DBUS_TYPE_INT64:
-    case DBUS_TYPE_UINT64:
-    case DBUS_TYPE_DOUBLE:
-      /* Call validate arg one time to check alignment padding
-       * at start of array
-       */
-      if (!_dbus_marshal_validate_arg (str, byte_order, depth,
-                                       type, array_type_pos, pos, &pos))
-        return FALSE;
-      pos = _DBUS_ALIGN_VALUE (end, 8);
-      break;
-      
-    default:
-      _dbus_verbose ("Unknown message arg type %d\n", type);
-      return FALSE;
-    }
-
-  *new_pos = pos;
-
-  return TRUE;
-}
-
-/** 
- * Validates an argument of a specific type, checking that it
- * is well-formed, for example no ludicrous length fields, strings
- * are nul-terminated, etc.
- * Returns the end position of the argument in end_pos, and
- * returns #TRUE if a valid arg begins at "pos"
- *
- * @todo security: need to audit this function.
- * 
- * @param str a string
- * @param byte_order the byte order to use
- * @param depth current recursion depth, to prevent excessive recursion
- * @param type the type of the argument
- * @param array_type_pos the position of the current array type, or
- *        -1 if not in an array
- * @param pos the pos where the arg starts
- * @param end_pos pointer where the position right
- * after the end position will follow
- * @returns #TRUE if the arg is valid.
- */
-dbus_bool_t
-_dbus_marshal_validate_arg (const DBusString *str,
-                            int	              byte_order,
-                            int               depth,
-			    int               type,
-			    int               array_type_pos,
-                            int               pos,
-                            int              *end_pos)
-{
-  if (pos > _dbus_string_get_length (str))
-    {
-      _dbus_verbose ("Validation went off the end of the message\n");
-      return FALSE;
-    }
-
-#define MAX_VALIDATION_DEPTH 32
-  
-  if (depth > MAX_VALIDATION_DEPTH)
-    {
-      _dbus_verbose ("Maximum recursion depth reached validating message\n");
-      return FALSE;
-    }
-  
-  switch (type)
-    {
-    case DBUS_TYPE_INVALID:
-      return FALSE;
-      break;
-
-    case DBUS_TYPE_BYTE:
-      if (1 > _dbus_string_get_length (str) - pos)
-	{
-	  _dbus_verbose ("no room for byte value\n");
-	  return FALSE;
-	}
-	
-      *end_pos = pos + 1;
-      break;
-      
-    case DBUS_TYPE_BOOLEAN:
-      {
-	unsigned char c;
-
-        if (1 > _dbus_string_get_length (str) - pos)
-          {
-            _dbus_verbose ("no room for boolean value\n");
-            return FALSE;
-          }
-        
-	c = _dbus_string_get_byte (str, pos);
-
-	if (!(c == 0 || c == 1))
-	  {
-	    _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
-	    return FALSE;
-	  }
-	
-        *end_pos = pos + 1;
-      }
-      break;
-      
-    case DBUS_TYPE_INT32:
-    case DBUS_TYPE_UINT32:
-      {
-        int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
-        
-        if (!_dbus_string_validate_nul (str, pos,
-                                        align_4 - pos))
-          {
-            _dbus_verbose ("int32/uint32 alignment padding not initialized to nul\n");
-            return FALSE;
-          }
-
-        *end_pos = align_4 + 4;
-      }
-      break;
-
-    case DBUS_TYPE_INT64:
-    case DBUS_TYPE_UINT64:      
-    case DBUS_TYPE_DOUBLE:
-      {
-        int align_8 = _DBUS_ALIGN_VALUE (pos, 8);
-
-        _dbus_verbose_bytes_of_string (str, pos, (align_8 + 8 - pos));
-        
-        if (!_dbus_string_validate_nul (str, pos,
-                                        align_8 - pos))
-          {
-            _dbus_verbose ("double/int64/uint64/objid alignment padding not initialized to nul at %d\n", pos);
-            return FALSE;
-          }
-
-        *end_pos = align_8 + 8;
-      }
-      break;
-
-    case DBUS_TYPE_OBJECT_PATH:
-    case DBUS_TYPE_STRING:
-      {
-	int len;
-
-	/* Demarshal the 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, end_pos))
-          return FALSE;
-
-        if (type == DBUS_TYPE_OBJECT_PATH)
-          {
-            if (!_dbus_string_validate_path (str, pos, len))
-              return FALSE;
-          }
-      }
-      break;
-      
-    case DBUS_TYPE_ARRAY:
-      {
-	int len;
-	int end;
-	int array_type;
-
-	if (array_type_pos == -1)
-	  {
-	    array_type_pos = pos;
-
-	    do
-	      {
-		if (!_dbus_marshal_validate_type (str, pos, &array_type, &pos))
-		  {
-		    _dbus_verbose ("invalid array type\n");
-		    return FALSE;
-		  }
-	      }
-	    while (array_type == DBUS_TYPE_ARRAY);
-	  }
-	else
-	  array_type_pos++;
-
-	if (!_dbus_marshal_validate_type (str, array_type_pos, &array_type, NULL))
-	  {
-	    _dbus_verbose ("invalid array type\n");
-	    return FALSE;
-	  }
-        
-	len = demarshal_and_validate_len (str, byte_order, pos, &pos);
-        if (len < 0)
-	  {
-	    _dbus_verbose ("invalid array length (<0)\n");
-	    return FALSE;
-	  }
+  dbus_uint32_t array_len;
+  int i;
+  int alignment;
 
-        if (len > _dbus_string_get_length (str) - pos)
-          {
-            _dbus_verbose ("array length outside length of the message\n");
-            return FALSE;
-          }
-	
-	end = pos + len;
+  i = _DBUS_ALIGN_VALUE (*pos, 4);
 
-        if (len > 0 && !validate_array_data (str, byte_order, depth + 1,
-					     array_type, array_type_pos,
-					     pos, &pos, end))
-	  {
-	    _dbus_verbose ("invalid array data\n");
-	    return FALSE;
-	  }
+  _dbus_demarshal_basic_type (str,
+                              DBUS_TYPE_UINT32,
+                              &array_len,
+                              byte_order,
+                              i,
+                              &i);
 
-        if (pos < end)
-          {
-            /* This should not be able to happen, as long as validate_arg moves forward;
-             * but the check is here just to be paranoid.
-             */
-            _dbus_verbose ("array length %d specified was longer than actual array contents by %d\n",
-                           len, end - pos);
-            return FALSE;
-          }
-        
-	if (pos > end)
-	  {
-	    _dbus_verbose ("array contents exceeds array length %d by %d\n", len, pos - end);
-	    return FALSE;
-	  }
+  alignment = _dbus_type_get_alignment (element_type);
 
-	*end_pos = pos;
-      }
-      break;
-      
-    default:
-      _dbus_verbose ("Unknown message arg type %d\n", type);
-      return FALSE;
-    }
+  i = _DBUS_ALIGN_VALUE (i, alignment);
 
-  if (*end_pos > _dbus_string_get_length (str))
-    return FALSE;
-  
-  return TRUE;
+  *pos = i + array_len;
 }
 
 /**
@@ -2451,11 +681,12 @@
     case DBUS_TYPE_DOUBLE:
     case DBUS_TYPE_STRING:
     case DBUS_TYPE_OBJECT_PATH:
+    case DBUS_TYPE_SIGNATURE:
     case DBUS_TYPE_ARRAY:
     case DBUS_TYPE_STRUCT:
     case DBUS_TYPE_VARIANT:
       return TRUE;
-      
+
     default:
       return FALSE;
     }
@@ -2495,7 +726,7 @@
        */
     case DBUS_TYPE_STRUCT:
       return 8;
-      
+
     default:
       _dbus_assert_not_reached ("unknown typecode in _dbus_type_get_alignment()");
       return 0;
@@ -2506,7 +737,7 @@
  * If in verbose mode, print a block of binary data.
  *
  * @todo right now it prints even if not in verbose mode
- * 
+ *
  * @param data the data
  * @param len the length of the data
  * @param offset where to start counting for byte indexes
@@ -2520,7 +751,7 @@
   const unsigned char *aligned;
 
   _dbus_assert (len >= 0);
-  
+
   /* Print blanks on first row if appropriate */
   aligned = _DBUS_ALIGN_ADDRESS (data, 4);
   if (aligned > data)
@@ -2529,7 +760,7 @@
 
   if (aligned != data)
     {
-      _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned); 
+      _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned);
       while (aligned != data)
         {
           _dbus_verbose ("    ");
@@ -2546,7 +777,7 @@
           _dbus_verbose ("%4d\t%p: ",
                          offset + i, &data[i]);
         }
-      
+
       if (data[i] >= 32 &&
           data[i] <= 126)
         _dbus_verbose (" '%c' ", data[i]);
@@ -2563,13 +794,13 @@
                            _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
                            _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
 
-          if (i > 7 && 
+          if (i > 7 &&
               _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
             {
               _dbus_verbose (" dbl: %g",
                              *(double*)&data[i-8]);
             }
-          
+
           _dbus_verbose ("\n");
         }
     }
@@ -2595,7 +826,7 @@
   real_len = _dbus_string_get_length (str);
 
   _dbus_assert (start >= 0);
-  
+
   if (start > real_len)
     {
       _dbus_verbose ("  [%d,%d) is not inside string of length %d\n",
@@ -2609,12 +840,164 @@
                      start, len, real_len);
       len = real_len - start;
     }
-  
+
   d = _dbus_string_get_const_data_len (str, start, len);
 
   _dbus_verbose_bytes (d, len, start);
 }
 
+static dbus_bool_t
+marshal_4_octets (DBusString   *str,
+                  int           insert_at,
+                  dbus_uint32_t value,
+                  int           byte_order,
+                  int          *pos_after)
+{
+  dbus_bool_t retval;
+  int orig_len;
+
+  _dbus_assert (sizeof (value) == 4);
+
+  if (byte_order != DBUS_COMPILER_BYTE_ORDER)
+    value = DBUS_UINT32_SWAP_LE_BE (value);
+
+  orig_len = _dbus_string_get_length (str);
+
+  retval = _dbus_string_insert_4_aligned (str, insert_at,
+                                          (const unsigned char *)&value);
+
+  if (pos_after)
+    {
+      *pos_after = insert_at + (_dbus_string_get_length (str) - orig_len);
+      _dbus_assert (*pos_after <= _dbus_string_get_length (str));
+    }
+
+  return retval;
+}
+
+static dbus_bool_t
+marshal_8_octets (DBusString *str,
+                  int         insert_at,
+                  DBusOctets8 value,
+                  int         byte_order,
+                  int        *pos_after)
+{
+  dbus_bool_t retval;
+  int orig_len;
+
+  _dbus_assert (sizeof (value) == 8);
+
+  swap_8_octets (&value, byte_order);
+
+  orig_len = _dbus_string_get_length (str);
+
+  retval = _dbus_string_insert_8_aligned (str, insert_at,
+                                          (const unsigned char *)&value);
+
+  if (pos_after)
+    *pos_after = insert_at + _dbus_string_get_length (str) - orig_len;
+
+  return retval;
+}
+
+enum
+  {
+    MARSHAL_AS_STRING,
+    MARSHAL_AS_SIGNATURE,
+    MARSHAL_AS_BYTE_ARRAY
+  };
+
+static dbus_bool_t
+marshal_len_followed_by_bytes (int                  marshal_as,
+                               DBusString          *str,
+                               int                  insert_at,
+                               const unsigned char *value,
+                               int                  data_len, /* doesn't include nul if any */
+                               int                  byte_order,
+                               int                 *pos_after)
+{
+  int pos;
+  DBusString value_str;
+  int value_len;
+
+  if (marshal_as == MARSHAL_AS_BYTE_ARRAY)
+    value_len = data_len;
+  else
+    value_len = data_len + 1; /* value has a nul */
+
+  /* FIXME this is probably broken for byte arrays because
+   * DBusString wants strings to be nul-terminated?
+   * Maybe I planned on this when writing init_const_len though
+   */
+  _dbus_string_init_const_len (&value_str, value, value_len);
+
+  pos = insert_at;
+
+  if (marshal_as == MARSHAL_AS_SIGNATURE)
+    {
+      if (!_dbus_string_insert_byte (str, pos, data_len))
+        goto oom;
+
+      pos += 1;
+    }
+  else
+    {
+      if (!marshal_4_octets (str, pos, data_len,
+                             byte_order, &pos))
+        goto oom;
+    }
+
+  if (!_dbus_string_copy_len (&value_str, 0, value_len,
+                              str, pos))
+    goto oom;
+
+#if 1
+  /* too expensive */
+  _dbus_assert (_dbus_string_equal_substring (&value_str, 0, value_len,
+                                              str, pos));
+  _dbus_verbose_bytes_of_string (str, pos, value_len);
+#endif
+
+  pos += value_len;
+
+  if (pos_after)
+    *pos_after = pos;
+
+  return TRUE;
+
+ oom:
+  /* Delete what we've inserted */
+  _dbus_string_delete (str, insert_at, pos - insert_at);
+
+  return FALSE;
+}
+
+static dbus_bool_t
+marshal_string (DBusString    *str,
+                int            insert_at,
+                const char    *value,
+                int            byte_order,
+                int           *pos_after)
+{
+  return marshal_len_followed_by_bytes (MARSHAL_AS_STRING,
+                                        str, insert_at, value,
+                                        strlen (value),
+                                        byte_order, pos_after);
+}
+
+static dbus_bool_t
+marshal_signature (DBusString    *str,
+                   int            insert_at,
+                   const char    *value,
+                   int           *pos_after)
+{
+  return marshal_len_followed_by_bytes (MARSHAL_AS_SIGNATURE,
+                                        str, insert_at, value,
+                                        strlen (value),
+                                        DBUS_COMPILER_BYTE_ORDER, /* irrelevant */
+                                        pos_after);
+}
+
 /**
  * Marshals a basic type
  *
@@ -2623,6 +1006,7 @@
  * @param type type of value
  * @param value pointer to value
  * @param byte_order byte order
+ * @param pos_after #NULL or the position after the type
  * @returns #TRUE on success
  **/
 dbus_bool_t
@@ -2630,19 +1014,23 @@
                           int         insert_at,
 			  char        type,
 			  const void *value,
-			  int         byte_order)
+			  int         byte_order,
+                          int        *pos_after)
 {
-  dbus_bool_t retval;
-
   switch (type)
     {
     case DBUS_TYPE_BYTE:
     case DBUS_TYPE_BOOLEAN:
-      retval = _dbus_string_insert_byte (str, insert_at, *(const unsigned char *)value);
+      if (!_dbus_string_insert_byte (str, insert_at, *(const unsigned char *)value))
+        return FALSE;
+      if (pos_after)
+        *pos_after = insert_at + 1;
+      return TRUE;
       break;
     case DBUS_TYPE_INT32:
     case DBUS_TYPE_UINT32:
-      return marshal_4_octets (str, insert_at, byte_order, *(const dbus_uint32_t *)value);
+      return marshal_4_octets (str, insert_at, *(const dbus_uint32_t *)value,
+                               byte_order, pos_after);
       break;
 #ifdef DBUS_HAVE_INT64
     case DBUS_TYPE_INT64:
@@ -2650,7 +1038,7 @@
       {
         DBusOctets8 r;
         r.u = *(const dbus_uint64_t *)value;
-        retval = marshal_8_octets (str, insert_at, byte_order, r);
+        return marshal_8_octets (str, insert_at, r, byte_order, pos_after);
       }
       break;
 #endif /* DBUS_HAVE_INT64 */
@@ -2658,22 +1046,142 @@
       {
         DBusOctets8 r;
         r.d = *(const double *)value;
-        retval = marshal_8_octets (str, insert_at, byte_order, r);
+        return marshal_8_octets (str, insert_at, r, byte_order, pos_after);
       }
       break;
     case DBUS_TYPE_STRING:
     case DBUS_TYPE_OBJECT_PATH:
-      retval = _dbus_marshal_string (str, byte_order, (const char*) value);
+      return marshal_string (str, insert_at, (const char*) value, byte_order, pos_after);
       break;
     case DBUS_TYPE_SIGNATURE:
-      retval = _dbus_marshal_signature (str, (const char*) value);
+      return marshal_signature (str, insert_at, (const char*) value, pos_after);
       break;
     default:
       _dbus_assert_not_reached ("not a basic type");
-      retval = FALSE;
+      return FALSE;
       break;
     }
-  return retval;
+}
+
+static dbus_bool_t
+marshal_1_octets_array (DBusString          *str,
+                        int                  insert_at,
+                        const unsigned char *value,
+                        int                  len,
+                        int                  byte_order,
+                        int                 *pos_after)
+{
+  return marshal_len_followed_by_bytes (MARSHAL_AS_BYTE_ARRAY,
+                                        str, insert_at, value, len,
+                                        byte_order, pos_after);
+}
+
+static dbus_bool_t
+marshal_4_octets_array (DBusString          *str,
+                        int                  insert_at,
+                        const dbus_uint32_t *value,
+                        int                  len,
+                        int                  byte_order)
+{
+  int old_string_len;
+  int array_start;
+
+  _dbus_assert_not_reached ("FIXME insert_at");
+
+  old_string_len = _dbus_string_get_length (str);
+
+  if (!marshal_4_octets (str, insert_at, len*4, byte_order, NULL))
+    goto error;
+
+  array_start = _dbus_string_get_length (str);
+
+  if (!_dbus_string_append_len (str, (const unsigned char*) value,
+                                len * 4))
+    goto error;
+
+  if (byte_order != DBUS_COMPILER_BYTE_ORDER)
+    {
+      const unsigned char *d;
+      const unsigned char *end;
+
+      d = _dbus_string_get_data (str) + array_start;
+      end = d + len * 4;
+      while (d != end)
+        {
+          *((dbus_uint32_t*)d) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)d));
+          d += 4;
+        }
+    }
+
+  return TRUE;
+
+ error:
+  /* Restore previous length */
+  _dbus_string_set_length (str, old_string_len);
+
+  return FALSE;
+}
+
+static dbus_bool_t
+marshal_8_octets_array (DBusString          *str,
+                        int                  insert_at,
+                        const DBusOctets8   *value,
+                        int                  len,
+                        int                  byte_order)
+{
+  int old_string_len;
+  int array_start;
+
+  _dbus_assert_not_reached ("FIXME insert_at");
+
+  old_string_len = _dbus_string_get_length (str);
+
+  /*  The array length is the length in bytes of the array,
+   * *excluding* alignment padding.
+   */
+  if (!marshal_4_octets (str, insert_at, len*8, byte_order, NULL))
+    goto error;
+
+  array_start = _dbus_string_get_length (str);
+
+  /* Note that we do alignment padding unconditionally
+   * even if the array is empty; this means that
+   * padding + len is always equal to the number of bytes
+   * in the array.
+   */
+
+  if (!_dbus_string_align_length (str, 8))
+    goto error;
+
+  if (!_dbus_string_append_len (str, (const unsigned char*) value,
+                                len * 8))
+    goto error;
+
+  if (byte_order != DBUS_COMPILER_BYTE_ORDER)
+    {
+      const unsigned char *d;
+      const unsigned char *end;
+
+      d = _dbus_string_get_data (str) + array_start;
+      end = d + len * 8;
+      while (d != end)
+        {
+#ifdef DBUS_HAVE_INT64
+          *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d));
+#else
+          swap_bytes ((unsigned char*) d, 8);
+#endif
+          d += 8;
+        }
+    }
+
+  return TRUE;
+
+ error:
+  /* Restore previous length */
+  _dbus_string_set_length (str, old_string_len);
+
+  return FALSE;
 }
 
 /**
@@ -2685,6 +1193,7 @@
  * @param value pointer to value
  * @param len length of value data in elements
  * @param byte_order byte order
+ * @param pos_after #NULL or the position after the type
  * @returns #TRUE on success
  **/
 dbus_bool_t
@@ -2693,33 +1202,45 @@
 				char        element_type,
 				const void *value,
 				int         len,
-				int         byte_order)
+				int         byte_order,
+                                int        *pos_after)
 {
-  /* FIXME use the insert_at arg */
-  
+  /* FIXME use the insert_at arg and fill in pos_after */
+
   switch (element_type)
     {
     case DBUS_TYPE_BOOLEAN:
-      /* FIXME: we canonicalize to 0 or 1 for the single boolean case 
+      /* FIXME: we canonicalize to 0 or 1 for the single boolean case
        * should we here too ? */
     case DBUS_TYPE_BYTE:
-      return _dbus_marshal_byte_array (str, byte_order, value, len);
+      return marshal_1_octets_array (str, insert_at, value, len, byte_order, pos_after);
       break;
     case DBUS_TYPE_INT32:
     case DBUS_TYPE_UINT32:
-      return marshal_4_octets_array (str, byte_order, value, len);
+      return marshal_4_octets_array (str, insert_at, value, len, byte_order);
       break;
 #ifdef DBUS_HAVE_INT64
     case DBUS_TYPE_INT64:
-    case DBUS_TYPE_UINT64: 
+    case DBUS_TYPE_UINT64:
 #endif /* DBUS_HAVE_INT64 */
     case DBUS_TYPE_DOUBLE:
-      return marshal_8_octets_array (str, byte_order, value, len);
+      return marshal_8_octets_array (str, insert_at, value, len, byte_order);
+      break;
+
+    case DBUS_TYPE_STRING:
+    case DBUS_TYPE_OBJECT_PATH:
+      _dbus_assert_not_reached ("handle string arrays");
       break;
+
+    case DBUS_TYPE_SIGNATURE:
+      _dbus_assert_not_reached ("handle signature");
+      break;
+
     default:
       _dbus_assert_not_reached ("non basic type in array");
       break;
     }
+
   return FALSE;
 }
 
@@ -2729,118 +1250,144 @@
 #include "dbus-test.h"
 #include <stdio.h>
 
+#define MARSHAL_BASIC(typename, byte_order, literal)                    \
+  do {                                                                  \
+     v_##typename = literal;                                            \
+     if (!_dbus_marshal_basic_type (&str, pos, DBUS_TYPE_##typename,    \
+                                    &v_##typename,                      \
+                                    byte_order, NULL))                  \
+       _dbus_assert_not_reached ("no memory");                          \
+   } while (0)
+
+#define DEMARSHAL_BASIC(typename, byte_order)                                   \
+  do {                                                                          \
+    _dbus_demarshal_basic_type (&str, DBUS_TYPE_##typename, &v_##typename,      \
+                                byte_order, pos, &pos);                         \
+  } while (0)
+
+#define DEMARSHAL_BASIC_AND_CHECK(typename, byte_order, literal)                        \
+  do {                                                                                  \
+    DEMARSHAL_BASIC (typename, byte_order);                                             \
+    if (literal != v_##typename)                                                        \
+      {                                                                                 \
+        _dbus_verbose_bytes_of_string (&str, dump_pos,                                  \
+                                     _dbus_string_get_length (&str) - dump_pos);        \
+        _dbus_assert_not_reached ("demarshaled wrong value");                           \
+      }                                                                                 \
+  } while (0)
+
+#define MARSHAL_TEST(typename, byte_order, literal)             \
+  do {                                                          \
+    MARSHAL_BASIC (typename, byte_order, literal);              \
+    dump_pos = pos;                                             \
+    DEMARSHAL_BASIC_AND_CHECK (typename, byte_order, literal);  \
+  } while (0)
+
+#define MARSHAL_TEST_STRCMP(typename, byte_order, literal)                              \
+  do {                                                                                  \
+    if (!_dbus_marshal_basic_type (&str, pos, DBUS_TYPE_##typename,                     \
+                                   literal,                                             \
+                                   byte_order, NULL))                                   \
+       _dbus_assert_not_reached ("no memory");                                          \
+    dump_pos = pos;                                                                     \
+    DEMARSHAL_BASIC (typename, byte_order);                                             \
+    if (strcmp (literal, v_##typename) != 0)                                            \
+      {                                                                                 \
+        _dbus_verbose_bytes_of_string (&str, dump_pos,                                  \
+                                       _dbus_string_get_length (&str) - dump_pos);      \
+        _dbus_warn ("literal '%s'\nvalue  '%s'\n", literal, v_##typename);              \
+        _dbus_assert_not_reached ("demarshaled wrong value");                           \
+      }                                                                                 \
+  } while (0)
+
 dbus_bool_t
 _dbus_marshal_test (void)
 {
   DBusString str;
-  char *tmp1, *tmp2;
-  int pos = 0, len;
+  int pos, dump_pos;
+#if 0
   dbus_int32_t array1[3] = { 0x123, 0x456, 0x789 }, *array2;
 #ifdef DBUS_HAVE_INT64
-  dbus_int64_t array3[3] = { DBUS_INT64_CONSTANT (0x123ffffffff), 
-                             DBUS_INT64_CONSTANT (0x456ffffffff), 
+  dbus_int64_t array3[3] = { DBUS_INT64_CONSTANT (0x123ffffffff),
+                             DBUS_INT64_CONSTANT (0x456ffffffff),
                              DBUS_INT64_CONSTANT (0x789ffffffff) }, *array4;
 #endif
-  char *s;
+#endif
   DBusString t;
-  
+  double v_DOUBLE;
+  double t_DOUBLE;
+  dbus_int32_t v_INT32;
+  dbus_uint32_t v_UINT32;
+  dbus_int64_t v_INT64;
+  dbus_uint64_t v_UINT64;
+  unsigned char v_BYTE;
+  unsigned char v_BOOLEAN;
+  const char *v_STRING;
+  const char *v_SIGNATURE;
+  const char *v_OBJECT_PATH;
+  int byte_order;
+
   if (!_dbus_string_init (&str))
     _dbus_assert_not_reached ("failed to init string");
 
+  pos = 0;
+
   /* Marshal doubles */
-  if (!_dbus_marshal_double (&str, DBUS_BIG_ENDIAN, 3.14))
-    _dbus_assert_not_reached ("could not marshal double value");
-  if (!_dbus_demarshal_double (&str, DBUS_BIG_ENDIAN, pos, &pos) == 3.14)
-    _dbus_assert_not_reached ("demarshal failed");
+  MARSHAL_BASIC (DOUBLE, DBUS_BIG_ENDIAN, 3.14);
+  DEMARSHAL_BASIC (DOUBLE, DBUS_BIG_ENDIAN);
+  t_DOUBLE = 3.14;
+  if (!_DBUS_DOUBLES_BITWISE_EQUAL (t_DOUBLE, v_DOUBLE))
+    _dbus_assert_not_reached ("got wrong double value");
+
+  MARSHAL_BASIC (DOUBLE, DBUS_LITTLE_ENDIAN, 3.14);
+  DEMARSHAL_BASIC (DOUBLE, DBUS_LITTLE_ENDIAN);
+  t_DOUBLE = 3.14;
+  if (!_DBUS_DOUBLES_BITWISE_EQUAL (t_DOUBLE, v_DOUBLE))
+    _dbus_assert_not_reached ("got wrong double value");
 
-  if (!_dbus_marshal_double (&str, DBUS_LITTLE_ENDIAN, 3.14))
-    _dbus_assert_not_reached ("could not marshal double value");
-  if (!_dbus_demarshal_double (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 3.14)
-    _dbus_assert_not_reached ("demarshal failed");
-  
   /* Marshal signed integers */
-  if (!_dbus_marshal_int32 (&str, DBUS_BIG_ENDIAN, -12345678))
-    _dbus_assert_not_reached ("could not marshal signed integer value");
-  if (!_dbus_demarshal_int32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == -12345678)
-    _dbus_assert_not_reached ("demarshal failed");
+  MARSHAL_TEST (INT32, DBUS_BIG_ENDIAN, -12345678);
+  MARSHAL_TEST (INT32, DBUS_LITTLE_ENDIAN, -12345678);
 
-  if (!_dbus_marshal_int32 (&str, DBUS_LITTLE_ENDIAN, -12345678))
-    _dbus_assert_not_reached ("could not marshal signed integer value");
-  if (!_dbus_demarshal_int32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == -12345678)
-    _dbus_assert_not_reached ("demarshal failed");
-  
   /* Marshal unsigned integers */
-  if (!_dbus_marshal_uint32 (&str, DBUS_BIG_ENDIAN, 0x12345678))
-    _dbus_assert_not_reached ("could not marshal signed integer value");
-  if (!_dbus_demarshal_uint32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == 0x12345678)
-    _dbus_assert_not_reached ("demarshal failed");
-  
-  if (!_dbus_marshal_uint32 (&str, DBUS_LITTLE_ENDIAN, 0x12345678))
-    _dbus_assert_not_reached ("could not marshal signed integer value");
-  if (!_dbus_demarshal_uint32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 0x12345678)
-    _dbus_assert_not_reached ("demarshal failed");
+  MARSHAL_TEST (UINT32, DBUS_BIG_ENDIAN, 0x12345678);
+  MARSHAL_TEST (UINT32, DBUS_LITTLE_ENDIAN, 0x12345678);
 
 #ifdef DBUS_HAVE_INT64
   /* Marshal signed integers */
-  if (!_dbus_marshal_int64 (&str, DBUS_BIG_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)))
-    _dbus_assert_not_reached ("could not marshal signed integer value");
-  if (_dbus_demarshal_int64 (&str, DBUS_BIG_ENDIAN, pos, &pos) != DBUS_INT64_CONSTANT (-0x123456789abc7))
-    _dbus_assert_not_reached ("demarshal failed");
+  MARSHAL_TEST (INT64, DBUS_BIG_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7));
+  MARSHAL_TEST (INT64, DBUS_LITTLE_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7));
 
-  if (!_dbus_marshal_int64 (&str, DBUS_LITTLE_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)))
-    _dbus_assert_not_reached ("could not marshal signed integer value");
-  if (_dbus_demarshal_int64 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) != DBUS_INT64_CONSTANT (-0x123456789abc7))
-    _dbus_assert_not_reached ("demarshal failed");
-  
   /* Marshal unsigned integers */
-  if (!_dbus_marshal_uint64 (&str, DBUS_BIG_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)))
-    _dbus_assert_not_reached ("could not marshal signed integer value");
-  if (!(_dbus_demarshal_uint64 (&str, DBUS_BIG_ENDIAN, pos, &pos) == DBUS_UINT64_CONSTANT (0x123456789abc7)))
-    _dbus_assert_not_reached ("demarshal failed");
-  
-  if (!_dbus_marshal_uint64 (&str, DBUS_LITTLE_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)))
-    _dbus_assert_not_reached ("could not marshal signed integer value");
-  if (!(_dbus_demarshal_uint64 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == DBUS_UINT64_CONSTANT (0x123456789abc7)))
-    _dbus_assert_not_reached ("demarshal failed");
+  MARSHAL_TEST (UINT64, DBUS_BIG_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7));
+  MARSHAL_TEST (UINT64, DBUS_LITTLE_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7));
 #endif /* DBUS_HAVE_INT64 */
-  
-  /* Marshal strings */
-  tmp1 = "This is the dbus test string";
-  if (!_dbus_marshal_string (&str, DBUS_BIG_ENDIAN, tmp1))
-    _dbus_assert_not_reached ("could not marshal string");
-  tmp2 = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, pos, &pos);
-  if (!strcmp (tmp1, tmp2) == 0)
-    _dbus_assert_not_reached ("demarshal failed");
-  dbus_free (tmp2);
 
-  tmp1 = "This is the dbus test string";
-  if (!_dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN, tmp1))
-    _dbus_assert_not_reached ("could not marshal string");
-  tmp2 = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, pos, &pos);
-  if (!strcmp (tmp1, tmp2) == 0)
-    _dbus_assert_not_reached ("demarshal failed");
-  dbus_free (tmp2);
+  /* Marshal byte */
+  MARSHAL_TEST (BYTE, DBUS_BIG_ENDIAN, 5);
+  MARSHAL_TEST (BYTE, DBUS_LITTLE_ENDIAN, 5);
 
-  /* Marshal signed integer arrays */
-  if (!_dbus_marshal_int32_array (&str, DBUS_BIG_ENDIAN, array1, 3))
-    _dbus_assert_not_reached ("could not marshal integer array");
-  if (!_dbus_demarshal_int32_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array2, &len))
-    _dbus_assert_not_reached ("could not demarshal integer array");
+  /* Marshal all possible bools! */
+  MARSHAL_TEST (BOOLEAN, DBUS_BIG_ENDIAN, FALSE);
+  MARSHAL_TEST (BOOLEAN, DBUS_LITTLE_ENDIAN, FALSE);
+  MARSHAL_TEST (BOOLEAN, DBUS_BIG_ENDIAN, TRUE);
+  MARSHAL_TEST (BOOLEAN, DBUS_LITTLE_ENDIAN, TRUE);
 
-  if (len != 3)
-    _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
-  dbus_free (array2);
+  /* Marshal strings */
+  MARSHAL_TEST_STRCMP (STRING, DBUS_BIG_ENDIAN, "");
+  MARSHAL_TEST_STRCMP (STRING, DBUS_LITTLE_ENDIAN, "");
+  MARSHAL_TEST_STRCMP (STRING, DBUS_BIG_ENDIAN, "This is the dbus test string");
+  MARSHAL_TEST_STRCMP (STRING, DBUS_LITTLE_ENDIAN, "This is the dbus test string");
 
-#ifdef DBUS_HAVE_INT64
-  /* Marshal 64-bit signed integer arrays */
-  if (!_dbus_marshal_int64_array (&str, DBUS_BIG_ENDIAN, array3, 3))
-    _dbus_assert_not_reached ("could not marshal integer array");
-  if (!_dbus_demarshal_int64_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array4, &len))
-    _dbus_assert_not_reached ("could not demarshal integer array");
+  /* object paths */
+  MARSHAL_TEST_STRCMP (OBJECT_PATH, DBUS_BIG_ENDIAN, "/a/b/c");
+  MARSHAL_TEST_STRCMP (OBJECT_PATH, DBUS_LITTLE_ENDIAN, "/a/b/c");
 
-  if (len != 3)
-    _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
-  dbus_free (array4);
+  /* signatures */
+  MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_BIG_ENDIAN, "");
+  MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_LITTLE_ENDIAN, "");
+  MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_BIG_ENDIAN, "a(ii)");
+  MARSHAL_TEST_STRCMP (SIGNATURE, DBUS_LITTLE_ENDIAN, "a(ii)");
 
   /* set/pack 64-bit integers */
   _dbus_string_set_length (&str, 8);
@@ -2848,7 +1395,7 @@
   /* signed little */
   _dbus_marshal_set_int64 (&str, DBUS_LITTLE_ENDIAN,
                            0, DBUS_INT64_CONSTANT (-0x123456789abc7));
-  
+
   _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
                 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
                                     _dbus_string_get_const_data (&str)));
@@ -2865,7 +1412,7 @@
   _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
                     DBUS_LITTLE_ENDIAN,
                     _dbus_string_get_data (&str));
-  
+
   _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
                 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
                                     _dbus_string_get_const_data (&str)));
@@ -2882,7 +1429,7 @@
   /* unsigned little */
   _dbus_marshal_set_uint64 (&str, DBUS_LITTLE_ENDIAN,
                             0, DBUS_UINT64_CONSTANT (0x123456789abc7));
-  
+
   _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
                 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
                                      _dbus_string_get_const_data (&str)));
@@ -2899,7 +1446,7 @@
   _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
                      DBUS_LITTLE_ENDIAN,
                      _dbus_string_get_data (&str));
-  
+
   _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
                 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
                                      _dbus_string_get_const_data (&str)));
@@ -2912,8 +1459,6 @@
   _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
                 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
                                      _dbus_string_get_const_data (&str)));
-  
-#endif
 
   /* set/pack 32-bit integers */
   _dbus_string_set_length (&str, 4);
@@ -2921,7 +1466,7 @@
   /* signed little */
   _dbus_marshal_set_int32 (&str, DBUS_LITTLE_ENDIAN,
                            0, -0x123456);
-  
+
   _dbus_assert (-0x123456 ==
                 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
                                     _dbus_string_get_const_data (&str)));
@@ -2938,7 +1483,7 @@
   _dbus_pack_int32 (-0x123456,
                     DBUS_LITTLE_ENDIAN,
                     _dbus_string_get_data (&str));
-  
+
   _dbus_assert (-0x123456 ==
                 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
                                     _dbus_string_get_const_data (&str)));
@@ -2955,7 +1500,7 @@
   /* unsigned little */
   _dbus_marshal_set_uint32 (&str, DBUS_LITTLE_ENDIAN,
                             0, 0x123456);
-  
+
   _dbus_assert (0x123456 ==
                 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
                                      _dbus_string_get_const_data (&str)));
@@ -2972,7 +1517,7 @@
   _dbus_pack_uint32 (0x123456,
                      DBUS_LITTLE_ENDIAN,
                      _dbus_string_get_data (&str));
-  
+
   _dbus_assert (0x123456 ==
                 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
                                      _dbus_string_get_const_data (&str)));
@@ -2986,67 +1531,49 @@
                 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
                                      _dbus_string_get_const_data (&str)));
 
+  /* Strings in-place set */
+  byte_order = DBUS_LITTLE_ENDIAN;
+  while (TRUE)
+    {
+      /* Init a string */
+      _dbus_string_set_length (&str, 0);
 
-  /* Strings */
-  
-  _dbus_string_set_length (&str, 0);
+      /* reset pos for the macros */
+      pos = 0;
 
-  _dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN,
-                        "Hello world");
-  
-  s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
-  _dbus_assert (strcmp (s, "Hello world") == 0);
-  dbus_free (s);
+      MARSHAL_TEST_STRCMP (STRING, byte_order, "Hello world");
 
-  _dbus_string_init_const (&t, "Hello world foo");
-  
-  _dbus_marshal_set_string (&str, DBUS_LITTLE_ENDIAN, 0,
-                            &t, _dbus_string_get_length (&t));
-  
-  s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
-  _dbus_assert (strcmp (s, "Hello world foo") == 0);
-  dbus_free (s);
+      /* Set it to something longer */
+      _dbus_string_init_const (&t, "Hello world foo");
 
-  _dbus_string_init_const (&t, "Hello");
-  
-  _dbus_marshal_set_string (&str, DBUS_LITTLE_ENDIAN, 0,
-                            &t, _dbus_string_get_length (&t));
-  
-  s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
-  _dbus_assert (strcmp (s, "Hello") == 0);
-  dbus_free (s);
+      _dbus_marshal_set_string (&str, byte_order, 0,
+                                &t, _dbus_string_get_length (&t));
 
-  /* Strings (big endian) */
-  
-  _dbus_string_set_length (&str, 0);
+      _dbus_demarshal_basic_type (&str, DBUS_TYPE_STRING,
+                                  &v_STRING, byte_order,
+                                  0, NULL);
+      _dbus_assert (strcmp (v_STRING, "Hello world foo") == 0);
 
-  _dbus_marshal_string (&str, DBUS_BIG_ENDIAN,
-                        "Hello world");
-  
-  s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
-  _dbus_assert (strcmp (s, "Hello world") == 0);
-  dbus_free (s);
+      /* Set it to something shorter */
+      _dbus_string_init_const (&t, "Hello");
 
-  _dbus_string_init_const (&t, "Hello world foo");
-  
-  _dbus_marshal_set_string (&str, DBUS_BIG_ENDIAN, 0,
-                            &t, _dbus_string_get_length (&t));
-  
-  s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
-  _dbus_assert (strcmp (s, "Hello world foo") == 0);
-  dbus_free (s);
+      _dbus_marshal_set_string (&str, byte_order, 0,
+                                &t, _dbus_string_get_length (&t));
+      _dbus_demarshal_basic_type (&str, DBUS_TYPE_STRING,
+                                  &v_STRING, byte_order,
+                                  0, NULL);
+      _dbus_assert (strcmp (v_STRING, "Hello") == 0);
 
-  _dbus_string_init_const (&t, "Hello");
-  
-  _dbus_marshal_set_string (&str, DBUS_BIG_ENDIAN, 0,
-                            &t, _dbus_string_get_length (&t));
-  
-  s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
-  _dbus_assert (strcmp (s, "Hello") == 0);
-  dbus_free (s);
-  
+      /* Do the other byte order */
+      if (byte_order == DBUS_LITTLE_ENDIAN)
+        byte_order = DBUS_BIG_ENDIAN;
+      else
+        break;
+    }
+
+  /* Clean up */
   _dbus_string_free (&str);
-      
+
   return TRUE;
 }
 

Index: dbus-marshal-basic.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-marshal-basic.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- dbus-marshal-basic.h	30 Dec 2004 22:34:17 -0000	1.4
+++ dbus-marshal-basic.h	1 Jan 2005 21:05:48 -0000	1.5
@@ -5,7 +5,7 @@
  * Copyright (C) 2004  Red Hat, Inc.
  *
  * Licensed under the Academic Free License version 2.1
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -15,7 +15,7 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
@@ -232,6 +232,7 @@
                                    unsigned char       *data);
 dbus_uint32_t _dbus_unpack_uint32 (int                  byte_order,
                                    const unsigned char *data);
+
 #ifdef DBUS_HAVE_INT64
 void          _dbus_pack_int64    (dbus_int64_t         value,
                                    int                  byte_order,
@@ -264,205 +265,43 @@
                                       dbus_uint64_t     value);
 #endif /* DBUS_HAVE_INT64 */
 
-dbus_bool_t _dbus_marshal_set_string      (DBusString         *str,
-                                           int                 byte_order,
-                                           int                 offset,
-                                           const DBusString   *value,
-                                           int                 len);
-void        _dbus_marshal_set_object_path (DBusString         *str,
-                                           int                 byte_order,
-                                           int                 offset,
-                                           const char        **path,
-                                           int                 path_len);
-
-dbus_bool_t   _dbus_marshal_int32          (DBusString            *str,
-					    int                    byte_order,
-					    dbus_int32_t           value);
-dbus_bool_t   _dbus_marshal_uint32         (DBusString            *str,
-					    int                    byte_order,
-					    dbus_uint32_t          value);
-
-#ifdef DBUS_HAVE_INT64
-dbus_bool_t   _dbus_marshal_int64          (DBusString            *str,
-					    int                    byte_order,
-					    dbus_int64_t           value);
-dbus_bool_t   _dbus_marshal_uint64         (DBusString            *str,
-					    int                    byte_order,
-					    dbus_uint64_t          value);
-#endif /* DBUS_HAVE_INT64 */
-dbus_bool_t   _dbus_marshal_double         (DBusString            *str,
-					    int                    byte_order,
-					    double                 value);
-
-dbus_bool_t   _dbus_marshal_string         (DBusString            *str,
-					    int                    byte_order,
-					    const char            *value);
-dbus_bool_t   _dbus_marshal_string_len     (DBusString            *str,
-					    int                    byte_order,
-					    const char            *value,
-                                            int                    len);
-
-dbus_bool_t   _dbus_marshal_basic_type     (DBusString            *str,
-                                            int                    insert_at,
-					    char                   type,
-					    const void            *value,
-					    int                    byte_order);
-dbus_bool_t   _dbus_marshal_basic_type_array (DBusString            *str,
-                                              int                    insert_at,
-					      char                   element_type,
-					      const void	    *value,
-					      int                    len,
-					      int                    byte_order);
-dbus_bool_t   _dbus_marshal_byte_array     (DBusString            *str,
-					    int                    byte_order,
-					    const unsigned char   *value,
-					    int                    len);
-dbus_bool_t   _dbus_marshal_int32_array    (DBusString            *str,
-					    int                    byte_order,
-					    const dbus_int32_t    *value,
-					    int                    len);
-dbus_bool_t   _dbus_marshal_uint32_array   (DBusString            *str,
-					    int                    byte_order,
-					    const dbus_uint32_t   *value,
-					    int                    len);
-#ifdef DBUS_HAVE_INT64
-dbus_bool_t   _dbus_marshal_int64_array    (DBusString            *str,
-					    int                    byte_order,
-					    const dbus_int64_t    *value,
-					    int                    len);
-dbus_bool_t   _dbus_marshal_uint64_array   (DBusString            *str,
-					    int                    byte_order,
-					    const dbus_uint64_t   *value,
-					    int                    len);
-#endif /* DBUS_HAVE_INT64 */
-dbus_bool_t   _dbus_marshal_double_array   (DBusString            *str,
-					    int                    byte_order,
-					    const double          *value,
-					    int                    len);
-dbus_bool_t   _dbus_marshal_string_array   (DBusString            *str,
-					    int                    byte_order,
-					    const char           **value,
-					    int                    len);
-double        _dbus_demarshal_double       (const DBusString      *str,
-					    int                    byte_order,
-					    int                    pos,
-					    int                   *new_pos);
-dbus_int32_t  _dbus_demarshal_int32        (const DBusString      *str,
-					    int                    byte_order,
-					    int                    pos,
-					    int                   *new_pos);
-dbus_uint32_t _dbus_demarshal_uint32       (const DBusString      *str,
-					    int                    byte_order,
-					    int                    pos,
-					    int                   *new_pos);
-#ifdef DBUS_HAVE_INT64
-dbus_int64_t  _dbus_demarshal_int64        (const DBusString      *str,
-					    int                    byte_order,
-					    int                    pos,
-					    int                   *new_pos);
-dbus_uint64_t _dbus_demarshal_uint64       (const DBusString      *str,
-					    int                    byte_order,
-					    int                    pos,
-					    int                   *new_pos);
-#endif /* DBUS_HAVE_INT64 */
-void          _dbus_demarshal_basic_type   (const DBusString      *str,
-					    int                    type,
-					    void                  *value,
-					    int                    byte_order,
-					    int                   *pos);
-char *        _dbus_demarshal_string       (const DBusString      *str,
-					    int                    byte_order,
-					    int                    pos,
-					    int                   *new_pos);
-dbus_bool_t   _dbus_demarshal_byte_array   (const DBusString      *str,
-					    int                    byte_order,
-					    int                    pos,
-					    int                   *new_pos,
-					    unsigned char        **array,
-					    int                   *array_len);
-dbus_bool_t   _dbus_demarshal_int32_array  (const DBusString      *str,
-					    int                    byte_order,
-					    int                    pos,
-					    int                   *new_pos,
-					    dbus_int32_t         **array,
-					    int                   *array_len);
-dbus_bool_t   _dbus_demarshal_uint32_array (const DBusString      *str,
-					    int                    byte_order,
-					    int                    pos,
-					    int                   *new_pos,
-					    dbus_uint32_t        **array,
-					    int                   *array_len);
-#ifdef DBUS_HAVE_INT64
-dbus_bool_t   _dbus_demarshal_int64_array  (const DBusString      *str,
-					    int                    byte_order,
-					    int                    pos,
-					    int                   *new_pos,
-					    dbus_int64_t         **array,
-					    int                   *array_len);
-dbus_bool_t   _dbus_demarshal_uint64_array (const DBusString      *str,
-					    int                    byte_order,
-					    int                    pos,
-					    int                   *new_pos,
-					    dbus_uint64_t        **array,
-					    int                   *array_len);
-#endif /* DBUS_HAVE_INT64 */
-dbus_bool_t   _dbus_demarshal_double_array (const DBusString      *str,
-					    int                    byte_order,
-					    int                    pos,
-					    int                   *new_pos,
-					    double               **array,
-					    int                   *array_len);
-dbus_bool_t   _dbus_demarshal_basic_type_array (const DBusString      *str,
-						int                    type,
-						void                 **array,
-						int                   *array_len,
-						int                    byte_order,
-						int                   *pos);
-
-dbus_bool_t   _dbus_demarshal_string_array (const DBusString      *str,
-					    int                    byte_order,
-					    int                    pos,
-					    int                   *new_pos,
-					    char                ***array,
-					    int                   *array_len);
-dbus_bool_t   _dbus_decompose_path         (const char*            data,
-					    int                    len,
-					    char                ***path,
-					    int                   *path_len);
-dbus_bool_t   _dbus_demarshal_object_path  (const DBusString      *str,
-					    int                    byte_order,
-					    int                    pos,
-                                            int                   *new_pos,
-                                            char                ***path,
-                                            int                   *path_len);
-
-void         _dbus_marshal_skip_basic_type (const DBusString      *str,
-                                            int                    type,
-                                            int                    byte_order,
-					    int                   *pos);
-void         _dbus_marshal_skip_array      (const DBusString      *str,
-                                            int                    byte_order,
-					    int                   *pos);
-
-dbus_bool_t _dbus_marshal_get_arg_end_pos (const DBusString *str,
-                                           int               byte_order,
-					   int               type,
-                                           int               pos,
-                                           int              *end_pos);
-dbus_bool_t _dbus_marshal_validate_type   (const DBusString *str,
-                                           int               pos,
-					   int              *type,
-                                           int              *end_pos);
-dbus_bool_t _dbus_marshal_validate_arg    (const DBusString *str,
-                                           int               depth,
-                                           int               byte_order,
-					   int               type,
-					   int               array_type_pos,
-                                           int               pos,
-                                           int              *end_pos);
-
-dbus_bool_t _dbus_type_is_valid           (int               typecode);
-
-int         _dbus_type_get_alignment      (int               typecode);
+dbus_bool_t   _dbus_marshal_set_string       (DBusString       *str,
+                                              int               byte_order,
+                                              int               offset,
+                                              const DBusString *value,
+                                              int               len);
+dbus_bool_t   _dbus_marshal_basic_type       (DBusString       *str,
+                                              int               insert_at,
+                                              char              type,
+                                              const void       *value,
+                                              int               byte_order,
+                                              int              *pos_after);
+dbus_bool_t   _dbus_marshal_basic_type_array (DBusString       *str,
+                                              int               insert_at,
+                                              char              element_type,
+                                              const void       *value,
+                                              int               len,
+                                              int               byte_order,
+                                              int              *pos_after);
+dbus_uint32_t _dbus_demarshal_uint32         (const DBusString *str,
+                                              int               byte_order,
+                                              int               pos,
+                                              int              *new_pos);
+void          _dbus_demarshal_basic_type     (const DBusString *str,
+                                              int               type,
+                                              void             *value,
+                                              int               byte_order,
+                                              int               pos,
+                                              int              *new_pos);
+void          _dbus_marshal_skip_basic_type  (const DBusString *str,
+                                              int               type,
+                                              int               byte_order,
+                                              int              *pos);
+void          _dbus_marshal_skip_array       (const DBusString *str,
+                                              int               byte_order,
+                                              int               element_type,
+                                              int              *pos);
+dbus_bool_t   _dbus_type_is_valid            (int               typecode);
+int           _dbus_type_get_alignment       (int               typecode);
 
 #endif /* DBUS_MARSHAL_H */

Index: dbus-marshal-recursive.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-marshal-recursive.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- dbus-marshal-recursive.c	1 Jan 2005 08:19:28 -0000	1.23
+++ dbus-marshal-recursive.c	1 Jan 2005 21:05:48 -0000	1.24
@@ -22,6 +22,7 @@
  */
 
 #include "dbus-marshal-recursive.h"
+#include "dbus-marshal-basic.h"
 #include "dbus-internals.h"
 
 /**
@@ -147,6 +148,7 @@
                               DBUS_TYPE_UINT32,
                               &array_len,
                               sub->byte_order,
+                              sub->value_pos,
                               &sub->value_pos);
 
   sub->u.array.len = array_len;
@@ -291,31 +293,6 @@
 }
 
 static void
-skip_array_values (int               element_type,
-                   const DBusString *value_str,
-                   int              *value_pos,
-                   int               byte_order)
-{
-  dbus_uint32_t array_len;
-  int pos;
-  int alignment;
-
-  pos = _DBUS_ALIGN_VALUE (*value_pos, 4);
-
-  _dbus_demarshal_basic_type (value_str,
-                              DBUS_TYPE_UINT32,
-                              &array_len,
-                              byte_order,
-                              &pos);
-
-  alignment = _dbus_type_get_alignment (element_type);
-
-  pos = _DBUS_ALIGN_VALUE (pos, alignment);
-
-  *value_pos = pos + array_len;
-}
-
-static void
 base_reader_next (DBusTypeReader *reader,
                   int             current_type)
 {
@@ -354,9 +331,10 @@
     case DBUS_TYPE_ARRAY:
       {
         if (!reader->klass->types_only)
-          skip_array_values (first_type_in_signature (reader->type_str,
-                                                      reader->type_pos + 1),
-                             reader->value_str, &reader->value_pos, reader->byte_order);
+          _dbus_marshal_skip_array (reader->value_str, reader->byte_order,
+                                    first_type_in_signature (reader->type_str,
+                                                             reader->type_pos + 1),
+                                    &reader->value_pos);
 
         skip_one_complete_type (reader->type_str, &reader->type_pos);
       }
@@ -441,9 +419,10 @@
 
     case DBUS_TYPE_ARRAY:
       {
-        skip_array_values (first_type_in_signature (reader->type_str,
-                                                    reader->type_pos + 1),
-                           reader->value_str, &reader->value_pos, reader->byte_order);
+        _dbus_marshal_skip_array (reader->value_str, reader->byte_order,
+                                  first_type_in_signature (reader->type_str,
+                                                           reader->type_pos + 1),
+                                  &reader->value_pos);
       }
       break;
 
@@ -581,18 +560,20 @@
 _dbus_type_reader_array_is_empty (DBusTypeReader *reader)
 {
   dbus_uint32_t array_len;
-  int len_pos;
 
   _dbus_assert (_dbus_type_reader_get_current_type (reader) == DBUS_TYPE_ARRAY);
   _dbus_assert (!reader->klass->types_only);
 
-  len_pos = _DBUS_ALIGN_VALUE (reader->value_pos, 4);
+  /* reader is supposed to be at an array child */
+  _dbus_verbose ("checking array len at %d\n", reader->value_pos);
 
   _dbus_demarshal_basic_type (reader->value_str,
                               DBUS_TYPE_UINT32,
                               &array_len,
                               reader->byte_order,
-                              &len_pos);
+                              reader->value_pos,
+                              NULL);
+  _dbus_verbose (" ... array len = %d\n", array_len);
 
   return array_len == 0;
 }
@@ -602,22 +583,20 @@
                               void              *value)
 {
   int t;
-  int next;
 
   _dbus_assert (!reader->klass->types_only);
 
   t = _dbus_type_reader_get_current_type (reader);
 
-  next = reader->value_pos;
   _dbus_demarshal_basic_type (reader->value_str,
                               t, value,
                               reader->byte_order,
-                              &next);
+                              reader->value_pos, NULL);
 
 
 #if RECURSIVE_MARSHAL_TRACE
-  _dbus_verbose ("  type reader %p read basic type_pos = %d value_pos = %d next = %d remaining sig '%s'\n",
-                 reader, reader->type_pos, reader->value_pos, next,
+  _dbus_verbose ("  type reader %p read basic type_pos = %d value_pos = %d remaining sig '%s'\n",
+                 reader, reader->type_pos, reader->value_pos,
                  _dbus_string_get_const_data_len (reader->type_str, reader->type_pos, 0));
 #endif
 }
@@ -765,23 +744,12 @@
                                            int             type,
                                            const void     *value)
 {
-  int old_value_len;
-  int bytes_written;
-
-  old_value_len = _dbus_string_get_length (writer->value_str);
-
-  if (!_dbus_marshal_basic_type (writer->value_str,
-                                 writer->value_pos,
-                                 type,
-                                 value,
-                                 writer->byte_order))
-    return FALSE;
-
-  bytes_written = _dbus_string_get_length (writer->value_str) - old_value_len;
-
-  writer->value_pos += bytes_written;
-
-  return TRUE;
+  return _dbus_marshal_basic_type (writer->value_str,
+                                   writer->value_pos,
+                                   type,
+                                   value,
+                                   writer->byte_order,
+                                   &writer->value_pos);
 }
 
 /* If our parent is an array, things are a little bit complicated.
@@ -1037,8 +1005,9 @@
   _dbus_assert (sub->u.array.len_pos < sub->u.array.start_pos);
 
 #if RECURSIVE_MARSHAL_TRACE
-  _dbus_verbose ("  type writer %p recurse array done remaining sig '%s'\n", sub,
-                 _dbus_string_get_const_data_len (sub->type_str, sub->type_pos, 0));
+  _dbus_verbose ("  type writer %p recurse array done remaining sig '%s' array start_pos = %d len_pos = %d\n", sub,
+                 _dbus_string_get_const_data_len (sub->type_str, sub->type_pos, 0),
+                 sub->u.array.start_pos, sub->u.array.len_pos);
 #endif
 
   return TRUE;
@@ -1928,7 +1897,9 @@
       ++i;
     }
 
-  /* FIXME type-iterate both signature and value */
+  /* FIXME type-iterate both signature and value and compare the resulting
+   * tree to the node tree
+   */
 
   return TRUE;
 }
@@ -2382,9 +2353,12 @@
 }
 
 #if 1
+dbus_bool_t _dbus_marshal_test (void);
 int
 main (int argc, char **argv)
 {
+  _dbus_marshal_test ();
+
   _dbus_marshal_recursive_test ();
 
   return 0;
@@ -2692,11 +2666,6 @@
                                         &v);
 }
 
-/* Maybe this macro should be in a real header,
- * depends on why it's needed which I don't understand yet
- */
-#define DOUBLES_BITWISE_EQUAL(a, b) \
-  (memcmp ((char*)&(a), (char*)&(b), 8) == 0)
 static dbus_bool_t
 double_read_value (TestTypeNode   *node,
                    DataBlock      *block,
@@ -2713,7 +2682,7 @@
 
   expected = double_from_seed (seed);
 
-  if (!DOUBLES_BITWISE_EQUAL (v, expected))
+  if (!_DBUS_DOUBLES_BITWISE_EQUAL (v, expected))
     {
 #ifdef DBUS_HAVE_INT64
       _dbus_warn ("Expected double %g got %g\n bits = 0x%llx vs.\n bits = 0x%llx)\n",
@@ -2748,7 +2717,7 @@
       ++i;
       buf[i] = v;
       ++i;
-      
+
       v += 1;
     }
 
@@ -2813,7 +2782,7 @@
   };
 
   s = sample_signatures[seed % _DBUS_N_ELEMENTS(sample_signatures)];
-  
+
   for (i = 0; s[i]; i++)
     {
       buf[i] = s[i];

Index: dbus-marshal-recursive.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-marshal-recursive.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- dbus-marshal-recursive.h	31 Dec 2004 00:24:24 -0000	1.13
+++ dbus-marshal-recursive.h	1 Jan 2005 21:05:48 -0000	1.14
@@ -4,7 +4,7 @@
  * Copyright (C) 2004 Red Hat, Inc.
  *
  * Licensed under the Academic Free License version 2.1
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -14,7 +14,7 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
@@ -25,12 +25,25 @@
 #define DBUS_MARSHAL_RECURSIVE_H
 
 #include <config.h>
-#include <dbus/dbus-marshal-basic.h>
+#include <dbus/dbus-marshal-basic.h> /* this can become protocol.h when we merge */
 
 #ifndef PACKAGE
 #error "config.h not included here"
 #endif
 
+/* Features we need to port dbus-message:
+ *  - memoize a position of a reader for small/fast access later
+ *  - delete an array element and re-align the remainder of the array
+ *    (not necessary yet to re-align remainder of entire string,
+ *     though that's probably just as hard/easy)
+ *  - set string, int, etc. values at a memoized position
+ *    (implement generic set of any value? changes only
+ *     value_str not type_str)
+ *  - implement has_next()
+ *  - the all-in-one-block array accessors
+ *  - validation
+ */
+
 typedef struct DBusTypeReader      DBusTypeReader;
 typedef struct DBusTypeWriter      DBusTypeWriter;
 typedef struct DBusTypeReaderClass DBusTypeReaderClass;



More information about the dbus-commit mailing list