2004-12-19 Havoc Pennington <hp@redhat.com>
authorHavoc Pennington <hp@redhat.com>
Sun, 19 Dec 2004 16:23:09 +0000 (16:23 +0000)
committerHavoc Pennington <hp@redhat.com>
Sun, 19 Dec 2004 16:23:09 +0000 (16:23 +0000)
* dbus/dbus-string.c (_dbus_string_insert_4_aligned)
(_dbus_string_insert_8_aligned): new functions

* dbus/dbus-string.c (_dbus_string_alloc_space): new function

ChangeLog
dbus/dbus-marshal-basic.c
dbus/dbus-marshal-basic.h
dbus/dbus-marshal-recursive.c
dbus/dbus-marshal-recursive.h
dbus/dbus-protocol-new.h
dbus/dbus-string.c
dbus/dbus-string.h

index dfe5c6c..b2f2c74 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2004-12-19  Havoc Pennington  <hp@redhat.com>
+
+       * dbus/dbus-string.c (_dbus_string_insert_4_aligned) 
+       (_dbus_string_insert_8_aligned): new functions
+
+       * dbus/dbus-string.c (_dbus_string_alloc_space): new function
+
 2004-12-18  Havoc Pennington  <hp@redhat.com>
 
        * dbus/dbus-string.c (_dbus_string_validate_ascii): use ISASCII
index 7647727..d325d5f 100644 (file)
  *
  */
 
-#include "dbus-marshal-basic.h"
 #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>
 
 /**
@@ -85,7 +86,7 @@ typedef union
 {
 #ifdef DBUS_HAVE_INT64
   dbus_int64_t  s; /**< 64-bit integer */
-  dbus_uint64_t u; /**< 64-bit unsinged integer */
+  dbus_uint64_t u; /**< 64-bit unsigned integer */
 #endif
   double d;        /**< double */
 } DBusOctets8;
@@ -462,6 +463,7 @@ _dbus_marshal_set_object_path (DBusString         *str,
 
 static dbus_bool_t
 marshal_4_octets (DBusString   *str,
+                  int           insert_at,
                   int           byte_order,
                   dbus_uint32_t value)
 {
@@ -470,12 +472,13 @@ marshal_4_octets (DBusString   *str,
   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
     value = DBUS_UINT32_SWAP_LE_BE (value);
 
-  return _dbus_string_append_4_aligned (str,
+  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)
 {
@@ -484,7 +487,7 @@ marshal_8_octets (DBusString *str,
   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
     pack_8_octets (value, byte_order, (unsigned char*) &value); /* pack into self, swapping as we go */
 
-  return _dbus_string_append_8_aligned (str,
+  return _dbus_string_insert_8_aligned (str, insert_at,
                                         (const unsigned char *)&value);
 }
 
@@ -503,7 +506,8 @@ _dbus_marshal_double (DBusString *str,
 {
   DBusOctets8 r;
   r.d = value;
-  return marshal_8_octets (str, byte_order, r);
+  return marshal_8_octets (str, _dbus_string_get_length (str),
+                           byte_order, r);
 }
 
 /**
@@ -519,7 +523,8 @@ _dbus_marshal_int32  (DBusString   *str,
                      int           byte_order,
                      dbus_int32_t  value)
 {
-  return marshal_4_octets (str, byte_order, (dbus_uint32_t) value);
+  return marshal_4_octets (str, _dbus_string_get_length (str),
+                           byte_order, (dbus_uint32_t) value);
 }
 
 /**
@@ -531,11 +536,12 @@ _dbus_marshal_int32  (DBusString   *str,
  * @returns #TRUE on success
  */
 dbus_bool_t
-_dbus_marshal_uint32 (DBusString    *str,
-                     int            byte_order,
-                     dbus_uint32_t  value)
+_dbus_marshal_uint32 (DBusString   *str,
+                      int           byte_order,
+                      dbus_uint32_t value)
 {
-  return marshal_4_octets (str, byte_order, value);
+  return marshal_4_octets (str, _dbus_string_get_length (str),
+                           byte_order, value);
 }
 
 
@@ -555,7 +561,8 @@ _dbus_marshal_int64  (DBusString   *str,
 {
   DBusOctets8 r;
   r.s = value;
-  return marshal_8_octets (str, byte_order, r);
+  return marshal_8_octets (str, _dbus_string_get_length (str),
+                           byte_order, r);
 }
 
 /**
@@ -573,7 +580,8 @@ _dbus_marshal_uint64 (DBusString    *str,
 {
   DBusOctets8 r;
   r.u = value;
-  return marshal_8_octets (str, byte_order, r);
+  return marshal_8_octets (str, _dbus_string_get_length (str),
+                           byte_order, r);
 }
 
 #endif /* DBUS_HAVE_INT64 */
@@ -930,7 +938,7 @@ _dbus_marshal_string_array (DBusString  *str,
  * @param path_len length of the path
  * @returns #TRUE on success
  */
-dbus_bool_t
+static dbus_bool_t
 _dbus_marshal_object_path (DBusString            *str,
                            int                    byte_order,
                            const char           **path,
@@ -1160,7 +1168,15 @@ _dbus_demarshal_basic_type (const DBusString      *str,
 #endif
       *pos += 8;
       break;
+    case DBUS_TYPE_STRING:
+      _dbus_assert_not_reached ("FIXME string is a basic type");
+      break;
+    case DBUS_TYPE_OBJECT_PATH:
+      _dbus_assert_not_reached ("FIXME object path is a basic type");
+      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;
     }
@@ -1746,6 +1762,74 @@ _dbus_demarshal_object_path (const DBusString *str,
   return TRUE;
 }
 
+/**
+ * Skips over a basic type, reporting the following position.
+ *
+ * @param str the string containing the data
+ * @param type type of value to demarshal
+ * @param byte_order the byte order
+ * @param pos pointer to position in the string,
+ *            updated on return to new position
+ **/
+void
+_dbus_marshal_skip_basic_type (const DBusString      *str,
+                               int                    type,
+                               int                    byte_order,
+                               int                   *pos)
+{
+  switch (type)
+    {
+    case DBUS_TYPE_BYTE:
+    case DBUS_TYPE_BOOLEAN:
+      (*pos)++;
+      break;
+    case DBUS_TYPE_INT32:
+    case DBUS_TYPE_UINT32:
+      *pos = _DBUS_ALIGN_VALUE (*pos, 4);
+      *pos += 4;
+      break;
+#ifdef DBUS_HAVE_INT64
+    case DBUS_TYPE_INT64:
+    case DBUS_TYPE_UINT64: 
+#endif /* DBUS_HAVE_INT64 */
+    case DBUS_TYPE_DOUBLE:
+      *pos = _DBUS_ALIGN_VALUE (*pos, 8);
+      *pos += 8;
+      break;
+    case DBUS_TYPE_STRING:
+      _dbus_assert_not_reached ("FIXME string is a basic type");
+      break;
+    case DBUS_TYPE_OBJECT_PATH:
+      _dbus_assert_not_reached ("FIXME object path is a basic type");
+      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;
+    }
+}
+
+/**
+ * Skips an array, returning the next position.
+ *
+ * @param str the string containing the data
+ * @param byte_order the byte order
+ * @param pos pointer to position in the string,
+ *            updated on return to new position
+ */
+void
+_dbus_marshal_skip_array (const DBusString  *str,
+                          int                byte_order,
+                          int               *pos)
+{
+  int len;
+
+  len = _dbus_demarshal_uint32 (str, byte_order, *pos, pos);
+
+  *pos += len;
+}
+
 /** 
  * Returns the position right after the end of an argument.  PERFORMS
  * NO VALIDATION WHATSOEVER. The message must have been previously
@@ -1775,10 +1859,6 @@ _dbus_marshal_get_arg_end_pos (const DBusString *str,
       return FALSE;
       break;
 
-    case DBUS_TYPE_NIL:
-      *end_pos = pos;
-      break;
-
     case DBUS_TYPE_BYTE:
       *end_pos = pos + 1;
       break;
@@ -1810,22 +1890,6 @@ _dbus_marshal_get_arg_end_pos (const DBusString *str,
        *end_pos = pos + len + 1;
       }
       break;
-
-    case DBUS_TYPE_CUSTOM:
-      {
-       int len;
-       
-       /* Demarshal the string length */
-       len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
-
-       pos += len + 1;
-       
-       /* Demarshal the data length */
-       len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
-
-       *end_pos = pos + len;
-      }
-      break;
       
     case DBUS_TYPE_ARRAY:
       {
@@ -2002,12 +2066,8 @@ validate_array_data (const DBusString *str,
       return FALSE;
       break;
 
-    case DBUS_TYPE_NIL:
-      break;
-
     case DBUS_TYPE_OBJECT_PATH:
     case DBUS_TYPE_STRING:
-    case DBUS_TYPE_CUSTOM:
     case DBUS_TYPE_ARRAY:
     case DBUS_TYPE_DICT:
       /* This clean recursion to validate_arg is what we
@@ -2127,10 +2187,6 @@ _dbus_marshal_validate_arg (const DBusString *str,
       return FALSE;
       break;
 
-    case DBUS_TYPE_NIL:
-      *end_pos = pos;
-      break;
-
     case DBUS_TYPE_BYTE:
       if (1 > _dbus_string_get_length (str) - pos)
        {
@@ -2220,29 +2276,6 @@ _dbus_marshal_validate_arg (const DBusString *str,
           }
       }
       break;
-
-    case DBUS_TYPE_CUSTOM:
-      {
-       int len;
-
-       /* Demarshal the string length, which does NOT include
-         * nul termination
-         */
-       len = demarshal_and_validate_len (str, byte_order, pos, &pos);
-        if (len < 0)
-          return FALSE;
-
-        if (!validate_string (str, pos, len, &pos))
-          return FALSE;
-
-       /* Validate data */
-       len = demarshal_and_validate_len (str, byte_order, pos, &pos);
-        if (len < 0)
-          return FALSE;
-
-       *end_pos = pos + len;
-      }
-      break;
       
     case DBUS_TYPE_ARRAY:
       {
@@ -2261,16 +2294,6 @@ _dbus_marshal_validate_arg (const DBusString *str,
                    _dbus_verbose ("invalid array type\n");
                    return FALSE;
                  }
-               
-               /* NIL values take up no space, so you couldn't iterate over an array of them.
-                * array of nil seems useless anyway; the useful thing might be array of
-                * (nil OR string) but we have no framework for that.
-                */
-               if (array_type == DBUS_TYPE_NIL)
-                 {
-                   _dbus_verbose ("array of NIL is not allowed\n");
-                   return FALSE;
-                 }
              }
            while (array_type == DBUS_TYPE_ARRAY);
          }
@@ -2397,7 +2420,6 @@ _dbus_type_is_valid (int typecode)
 {
   switch (typecode)
     {
-    case DBUS_TYPE_NIL:
     case DBUS_TYPE_BYTE:
     case DBUS_TYPE_BOOLEAN:
     case DBUS_TYPE_INT32:
@@ -2406,7 +2428,6 @@ _dbus_type_is_valid (int typecode)
     case DBUS_TYPE_UINT64:
     case DBUS_TYPE_DOUBLE:
     case DBUS_TYPE_STRING:
-    case DBUS_TYPE_CUSTOM:
     case DBUS_TYPE_ARRAY:
     case DBUS_TYPE_DICT:
     case DBUS_TYPE_OBJECT_PATH:
@@ -2457,7 +2478,7 @@ _dbus_verbose_bytes (const unsigned char *data,
       if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
         {
           _dbus_verbose ("%4d\t%p: ",
-                   i, &data[i]);
+                         i, &data[i]);
         }
       
       if (data[i] >= 32 &&
@@ -2465,7 +2486,7 @@ _dbus_verbose_bytes (const unsigned char *data,
         _dbus_verbose (" '%c' ", data[i]);
       else
         _dbus_verbose ("0x%s%x ",
-                 data[i] <= 0xf ? "0" : "", data[i]);
+                       data[i] <= 0xf ? "0" : "", data[i]);
 
       ++i;
 
@@ -2532,6 +2553,7 @@ _dbus_verbose_bytes_of_string (const DBusString    *str,
  * Marshals a basic type
  *
  * @param str string to marshal to
+ * @param insert_at where to insert the value
  * @param type type of value
  * @param value pointer to value
  * @param byte_order byte order
@@ -2539,8 +2561,9 @@ _dbus_verbose_bytes_of_string (const DBusString    *str,
  **/
 dbus_bool_t
 _dbus_marshal_basic_type (DBusString *str,
+                          int         insert_at,
                          char        type,
-                         void       *value,
+                         const void *value,
                          int         byte_order)
 {
   dbus_bool_t retval;
@@ -2549,20 +2572,28 @@ _dbus_marshal_basic_type (DBusString *str,
     {
     case DBUS_TYPE_BYTE:
     case DBUS_TYPE_BOOLEAN:
-      retval = _dbus_string_append_byte (str, *(unsigned char *)value);
+      retval = _dbus_string_insert_byte (str, insert_at, *(const unsigned char *)value);
       break;
     case DBUS_TYPE_INT32:
     case DBUS_TYPE_UINT32:
-      return marshal_4_octets (str, byte_order, *(dbus_uint32_t *)value);
+      return marshal_4_octets (str, insert_at, byte_order, *(const dbus_uint32_t *)value);
       break;
 #ifdef DBUS_HAVE_INT64
     case DBUS_TYPE_INT64:
-    case DBUS_TYPE_UINT64: 
-      retval = _dbus_marshal_uint64 (str, byte_order, *(dbus_uint64_t *)value);
+    case DBUS_TYPE_UINT64:
+      {
+        DBusOctets8 r;
+        r.u = *(const dbus_uint64_t *)value;
+        retval = marshal_8_octets (str, insert_at, byte_order, r);
+      }
       break;
 #endif /* DBUS_HAVE_INT64 */
     case DBUS_TYPE_DOUBLE:
-      retval = _dbus_marshal_double (str, byte_order, *(double *)value);
+      {
+        DBusOctets8 r;
+        r.d = *(const double *)value;
+        retval = marshal_8_octets (str, insert_at, byte_order, r);
+      }
       break;
     default:
       _dbus_assert_not_reached ("not a basic type");
@@ -2576,6 +2607,7 @@ _dbus_marshal_basic_type (DBusString *str,
  * Marshals a basic type array
  *
  * @param str string to marshal to
+ * @param insert_at where to insert the value
  * @param element_type type of array elements
  * @param value pointer to value
  * @param len length of value data in elements
@@ -2584,11 +2616,14 @@ _dbus_marshal_basic_type (DBusString *str,
  **/
 dbus_bool_t
 _dbus_marshal_basic_type_array (DBusString *str,
+                                int         insert_at,
                                char        element_type,
                                const void *value,
                                int         len,
                                int         byte_order)
 {
+  /* FIXME use the insert_at arg */
+  
   switch (element_type)
     {
     case DBUS_TYPE_BOOLEAN:
index 25db7cc..e8c0b3f 100644 (file)
@@ -37,6 +37,8 @@
 
 /****************************************************** Remove later */
 #undef DBUS_TYPE_INVALID
+#undef DBUS_TYPE_NIL
+#undef DBUS_TYPE_CUSTOM
 #undef DBUS_TYPE_BYTE
 #undef DBUS_TYPE_INT32
 #undef DBUS_TYPE_UINT32
 /* characters other than typecodes that appear in type signatures */
 #define DBUS_STRUCT_BEGIN_CHAR   ((int) '(')
 #define DBUS_STRUCT_END_CHAR     ((int) ')')
-#define DBUS_NAME_DELIMITER_CHAR ((int) '\'')
+
+static const char *
+_hack_dbus_type_to_string (int type)
+{
+  switch (type)
+    {
+    case DBUS_TYPE_INVALID:
+      return "invalid";
+    case DBUS_TYPE_BOOLEAN:
+      return "boolean";
+    case DBUS_TYPE_INT32:
+      return "int32";
+    case DBUS_TYPE_UINT32:
+      return "uint32";
+    case DBUS_TYPE_DOUBLE:
+      return "double";
+    case DBUS_TYPE_STRING:
+      return "string";
+    case DBUS_TYPE_STRUCT:
+      return "struct";
+    case DBUS_TYPE_ARRAY:
+      return "array";
+    case DBUS_TYPE_DICT:
+      return "dict";
+    case DBUS_TYPE_VARIANT:
+      return "variant";
+    case DBUS_STRUCT_BEGIN_CHAR:
+      return "begin_struct";
+    case DBUS_STRUCT_END_CHAR:
+      return "end_struct";
+    default:
+      return "unknown";
+    }
+}
+
+#define _dbus_type_to_string(t) _hack_dbus_type_to_string(t)
+
 /****************************************************** Remove later */
 
 #ifdef WORDS_BIGENDIAN
@@ -222,6 +260,7 @@ dbus_bool_t   _dbus_marshal_int32          (DBusString            *str,
 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,
@@ -233,6 +272,7 @@ dbus_bool_t   _dbus_marshal_uint64         (DBusString            *str,
 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);
@@ -240,10 +280,18 @@ 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,
-                                           void                  *value,
+                                           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,
@@ -270,21 +318,10 @@ dbus_bool_t   _dbus_marshal_double_array   (DBusString            *str,
                                            int                    byte_order,
                                            const double          *value,
                                            int                    len);
-dbus_bool_t   _dbus_marshal_basic_type_array (DBusString            *str,
-                                             char                   element_type,
-                                             const void            *value,
-                                             int                    len,
-                                             int                    byte_order);
-
 dbus_bool_t   _dbus_marshal_string_array   (DBusString            *str,
                                            int                    byte_order,
                                            const char           **value,
                                            int                    len);
-dbus_bool_t   _dbus_marshal_object_path    (DBusString            *str,
-                                           int                    byte_order,
-                                            const char           **path,
-                                            int                    path_len);
-
 double        _dbus_demarshal_double       (const DBusString      *str,
                                            int                    byte_order,
                                            int                    pos,
@@ -378,6 +415,14 @@ dbus_bool_t   _dbus_demarshal_object_path  (const DBusString      *str,
                                             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,
index eb85a2c..1962e62 100644 (file)
@@ -37,76 +37,197 @@ _dbus_type_reader_init (DBusTypeReader    *reader,
                         const DBusString  *value_str,
                         int                value_pos)
 {
-     
+  reader->byte_order = byte_order;
+  reader->type_str = type_str;
+  reader->type_pos = type_pos;
+  reader->value_str = value_str;
+  reader->value_pos = value_pos;
 
+  _dbus_verbose ("type reader %p init 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));
 }
 
 int
-_dbus_type_reader_get_value_end (DBusTypeReader    *reader)
+_dbus_type_reader_get_current_type (DBusTypeReader *reader)
 {
+  int t;
 
+  t = _dbus_string_get_byte (reader->type_str,
+                             reader->type_pos);
 
-}
-
-int
-_dbus_type_reader_get_type_end (DBusTypeReader    *reader)
-{
+  if (t == DBUS_STRUCT_BEGIN_CHAR)
+    t = DBUS_TYPE_STRUCT;
 
+  /* this should never be a stopping place */
+  _dbus_assert (t != DBUS_STRUCT_END_CHAR);
 
+#if 0
+  _dbus_verbose ("type reader %p current type_pos = %d type = %s\n",
+                 reader, reader->type_pos,
+                 _dbus_type_to_string (t));
+#endif
+  
+  return t;
 }
 
 int
-_dbus_type_reader_get_current_type (DBusTypeReader *reader)
+_dbus_type_reader_get_array_type (DBusTypeReader *reader)
 {
+  int t;
 
+  t = _dbus_type_reader_get_current_type (reader);
 
-}
-
-int
-_dbus_type_reader_get_array_type (DBusTypeReader    *reader)
-{
-
+  if (t != DBUS_TYPE_ARRAY)
+    return DBUS_TYPE_INVALID;
 
+  t = _dbus_string_get_byte (reader->type_str,
+                             reader->type_pos + 1);  
+  
+  return t;
 }
 
 void
 _dbus_type_reader_read_basic (DBusTypeReader    *reader,
                               void              *value)
 {
+  int t;
+  int next;
 
+  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);
+
+  _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_string_get_const_data_len (reader->type_str, reader->type_pos, 0));
+
+  _dbus_verbose_bytes_of_string (reader->value_str,
+                                 reader->value_pos,
+                                 MIN (16,
+                                      _dbus_string_get_length (reader->value_str) - reader->value_pos));
 }
 
 dbus_bool_t
-_dbus_type_reader_read_array (DBusTypeReader    *reader,
-                              int                type,
-                              void             **array,
-                              int               *array_len)
+_dbus_type_reader_read_array_of_basic (DBusTypeReader    *reader,
+                                       int                type,
+                                       void             **array,
+                                       int               *array_len)
 {
-
-
+  
+  
 }
 
+/**
+ * Initialize a new reader pointing to the first type and
+ * corresponding value that's a child of the current container. It's
+ * an error to call this if the current type is a non-container.
+ *
+ * @param reader the reader
+ * @param sub a reader to init pointing to the first child
+ */
 void
-_dbus_type_reader_recurse (DBusTypeReader    *reader)
+_dbus_type_reader_recurse (DBusTypeReader *reader,
+                           DBusTypeReader *sub)
 {
+  int t;
 
+  t = _dbus_string_get_byte (reader->type_str, reader->type_pos);
+  
+  /* point subreader at the same place as reader */
+  _dbus_type_reader_init (sub,
+                          reader->byte_order,
+                          reader->type_str,
+                          reader->type_pos,
+                          reader->value_str,
+                          reader->value_pos);
 
-}
-
-void
-_dbus_type_reader_unrecurse (DBusTypeReader    *reader)
-{
+  _dbus_assert (t == DBUS_STRUCT_BEGIN_CHAR); /* only this works right now */
+  
+  sub->type_pos += 1;
 
+  /* no value_pos increment since the struct itself doesn't take up value space */
 
+  _dbus_verbose ("type reader %p recursed type_pos = %d value_pos = %d remaining sig '%s'\n",
+                 sub, sub->type_pos, sub->value_pos,
+                 _dbus_string_get_const_data_len (sub->type_str, sub->type_pos, 0));
 }
 
+/**
+ * Skip to the next value on this "level". e.g. the next field in a
+ * struct, the next value in an array, the next key or value in a
+ * dict. Returns FALSE at the end of the current container.
+ *
+ * @param reader the reader
+ * @returns FALSE if nothing more to read at or below this level
+ */
 dbus_bool_t
-_dbus_type_reader_next (DBusTypeReader    *reader)
+_dbus_type_reader_next (DBusTypeReader *reader)
 {
+  int t;
 
+  /* FIXME handled calling next when there's no next */
+  
+  t = _dbus_string_get_byte (reader->type_str, reader->type_pos);
+  
+  _dbus_verbose ("type reader %p next() { 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));
+  
+  switch (t)
+    {
+    case DBUS_STRUCT_BEGIN_CHAR:
+      /* Scan forward over the entire container contents */
+      {
+        DBusTypeReader sub;
+
+        /* Recurse into the struct */
+        _dbus_type_reader_recurse (reader, &sub);
+
+        /* Skip everything in this subreader */
+        while (_dbus_type_reader_next (&sub))
+          {
+            /* nothing */;
+          }
+
+        /* Now we are at the end of this container */
+        reader->type_pos = sub.type_pos;
+        reader->value_pos = sub.value_pos;
+      }
+      break;
+
+    default:
+      /* FIXME for array etc. this is more complicated */
+      _dbus_marshal_skip_basic_type (reader->value_str,
+                                     t, reader->byte_order,
+                                     &reader->value_pos);
+      reader->type_pos += 1;
+      break;
+    }
 
+  _dbus_verbose ("type reader %p }  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));
 
+  /* FIXME this is wrong; we need to return FALSE when we finish the
+   * container we've recursed into; even if the signature continues.
+   */
+  
+  t = _dbus_string_get_byte (reader->type_str, reader->type_pos);
+
+  if (t == DBUS_STRUCT_END_CHAR)
+    {
+      reader->type_pos += 1;
+      return FALSE;
+    }
+  if (t == DBUS_TYPE_INVALID)
+    return FALSE;
+  
+  return TRUE;
 }
 
 void
@@ -117,8 +238,12 @@ _dbus_type_writer_init (DBusTypeWriter *writer,
                         DBusString     *value_str,
                         int             value_pos)
 {
-
-
+  writer->byte_order = byte_order;
+  writer->type_str = type_str;
+  writer->type_pos = type_pos;
+  writer->value_str = value_str;
+  writer->value_pos = value_pos;
+  writer->container_type = DBUS_TYPE_INVALID;
 }
 
 dbus_bool_t
@@ -126,8 +251,38 @@ _dbus_type_writer_write_basic (DBusTypeWriter *writer,
                                int             type,
                                const void     *value)
 {
+  dbus_bool_t retval;
+  int old_value_len;
 
+  old_value_len = _dbus_string_get_length (writer->value_str);
+  
+  /* First ensure that our type realloc will succeed */
+  if (!_dbus_string_alloc_space (writer->type_str, 1))
+    return FALSE;
 
+  retval = FALSE;
+        
+  if (!_dbus_marshal_basic_type (writer->value_str,
+                                 writer->value_pos,
+                                 type,
+                                 value,
+                                 writer->byte_order))
+    goto out;
+
+  writer->value_pos += _dbus_string_get_length (writer->value_str) - old_value_len;
+  
+  /* Now insert the type */
+  if (!_dbus_string_insert_byte (writer->type_str,
+                                 writer->type_pos,
+                                 type))
+    _dbus_assert_not_reached ("failed to insert byte after prealloc");
+
+  writer->type_pos += 1;
+  
+  retval = TRUE;
+  
+ out:
+  return retval;
 }
 
 dbus_bool_t
@@ -142,17 +297,57 @@ _dbus_type_writer_write_array (DBusTypeWriter *writer,
 
 dbus_bool_t
 _dbus_type_writer_recurse (DBusTypeWriter *writer,
-                           int             container_type)
-{
-
-
+                           int             container_type,
+                           DBusTypeWriter *sub)
+{
+  _dbus_type_writer_init (sub,
+                          writer->byte_order,
+                          writer->type_str,
+                          writer->type_pos,
+                          writer->value_str,
+                          writer->value_pos);
+  sub->container_type = container_type;
+  
+  switch (container_type)
+    {
+    case DBUS_TYPE_STRUCT:
+      {
+        if (!_dbus_string_insert_byte (sub->type_str,
+                                       sub->type_pos,
+                                       DBUS_STRUCT_BEGIN_CHAR))
+          return FALSE;
+
+        sub->type_pos += 1;
+      }
+      break;
+    default:
+      _dbus_assert_not_reached ("container_type unhandled");
+      break;
+    }
+  
+  return TRUE;
 }
 
 dbus_bool_t
-_dbus_type_writer_unrecurse (DBusTypeWriter *writer)
+_dbus_type_writer_unrecurse (DBusTypeWriter *writer,
+                             DBusTypeWriter *sub)
 {
+  _dbus_assert (sub->type_pos > 0); /* can't be recursed if this fails */
 
+  if (sub->container_type == DBUS_TYPE_STRUCT)
+    {
+      if (!_dbus_string_insert_byte (sub->type_str,
+                                     sub->type_pos, 
+                                     DBUS_STRUCT_END_CHAR))
+        return FALSE;
+      sub->type_pos += 1;
+    }
 
+  /* Jump the parent writer to the new location */
+  writer->type_pos = sub->type_pos;
+  writer->value_pos = sub->value_pos;
+  
+  return TRUE;
 }
 
 /** @} */ /* end of DBusMarshal group */
@@ -266,6 +461,12 @@ check_expected_type (DBusTypeReader *reader,
       _dbus_warn ("Read type %s while expecting %s\n",
                   _dbus_type_to_string (t),
                   _dbus_type_to_string (expected));
+
+      _dbus_verbose_bytes_of_string (reader->type_str, 0,
+                                     _dbus_string_get_length (reader->type_str));
+      _dbus_verbose_bytes_of_string (reader->value_str, 0,
+                                     _dbus_string_get_length (reader->value_str));
+      
       exit (1);
     }
 }
@@ -292,15 +493,17 @@ write_struct_with_int32s (DataBlock      *block,
 {
   dbus_int32_t v;
   DataBlockState saved;
+  DBusTypeWriter sub;
 
   data_block_save (block, &saved);
   
   if (!_dbus_type_writer_recurse (writer,
-                                  DBUS_TYPE_STRUCT))
+                                  DBUS_TYPE_STRUCT,
+                                  &sub))
     return FALSE;
 
   v = SAMPLE_INT32;
-  if (!_dbus_type_writer_write_basic (writer,
+  if (!_dbus_type_writer_write_basic (&sub,
                                       DBUS_TYPE_INT32,
                                       &v))
     {
@@ -309,7 +512,7 @@ write_struct_with_int32s (DataBlock      *block,
     }
 
   v = SAMPLE_INT32_ALTERNATE;
-  if (!_dbus_type_writer_write_basic (writer,
+  if (!_dbus_type_writer_write_basic (&sub,
                                       DBUS_TYPE_INT32,
                                       &v))
     {
@@ -317,7 +520,7 @@ write_struct_with_int32s (DataBlock      *block,
       return FALSE;
     }
 
-  if (!_dbus_type_writer_unrecurse (writer))
+  if (!_dbus_type_writer_unrecurse (writer, &sub))
     {
       data_block_restore (block, &saved);
       return FALSE;
@@ -331,27 +534,26 @@ read_struct_with_int32s (DataBlock      *block,
                          DBusTypeReader *reader)
 {
   dbus_int32_t v;
+  DBusTypeReader sub;
 
   check_expected_type (reader, DBUS_TYPE_STRUCT);
   
-  _dbus_type_reader_recurse (reader);
+  _dbus_type_reader_recurse (reader, &sub);
 
-  check_expected_type (reader, DBUS_TYPE_INT32);
+  check_expected_type (&sub, DBUS_TYPE_INT32);
   
-  _dbus_type_reader_read_basic (reader,
+  _dbus_type_reader_read_basic (&sub,
                                 (dbus_int32_t*) &v);
 
   _dbus_assert (v == SAMPLE_INT32);
 
-  _dbus_type_reader_next (reader);
-  check_expected_type (reader, DBUS_TYPE_INT32);
+  _dbus_type_reader_next (&sub);
+  check_expected_type (&sub, DBUS_TYPE_INT32);
   
-  _dbus_type_reader_read_basic (reader,
+  _dbus_type_reader_read_basic (&sub,
                                 (dbus_int32_t*) &v);
 
   _dbus_assert (v == SAMPLE_INT32_ALTERNATE);
-
-  _dbus_type_reader_unrecurse (reader);
   
   return TRUE;
 }
@@ -361,30 +563,32 @@ write_struct_of_structs (DataBlock      *block,
                          DBusTypeWriter *writer)
 {
   DataBlockState saved;
+  DBusTypeWriter sub;
 
   data_block_save (block, &saved);
   
   if (!_dbus_type_writer_recurse (writer,
-                                  DBUS_TYPE_STRUCT))
+                                  DBUS_TYPE_STRUCT,
+                                  &sub))
     return FALSE;
 
-  if (!write_struct_with_int32s (block, writer))
+  if (!write_struct_with_int32s (block, &sub))
     {
       data_block_restore (block, &saved);
       return FALSE;
     }
-  if (!write_struct_with_int32s (block, writer))
+  if (!write_struct_with_int32s (block, &sub))
     {
       data_block_restore (block, &saved);
       return FALSE;
     }
-  if (!write_struct_with_int32s (block, writer))
+  if (!write_struct_with_int32s (block, &sub))
     {
       data_block_restore (block, &saved);
       return FALSE;
     }
 
-  if (!_dbus_type_writer_unrecurse (writer))
+  if (!_dbus_type_writer_unrecurse (writer, &sub))
     {
       data_block_restore (block, &saved);
       return FALSE;
@@ -397,20 +601,20 @@ static dbus_bool_t
 read_struct_of_structs (DataBlock      *block,
                         DBusTypeReader *reader)
 {
+  DBusTypeReader sub;
+  
   check_expected_type (reader, DBUS_TYPE_STRUCT);
   
-  _dbus_type_reader_recurse (reader);
+  _dbus_type_reader_recurse (reader, &sub);
 
-  if (!read_struct_with_int32s (block, reader))
+  if (!read_struct_with_int32s (block, &sub))
     return FALSE;
-  _dbus_type_reader_next (reader);
-  if (!read_struct_with_int32s (block, reader))
+  _dbus_type_reader_next (&sub);
+  if (!read_struct_with_int32s (block, &sub))
     return FALSE;
-  _dbus_type_reader_next (reader);
-  if (!read_struct_with_int32s (block, reader))
+  _dbus_type_reader_next (&sub);
+  if (!read_struct_with_int32s (block, &sub))
     return FALSE;
-
-  _dbus_type_reader_unrecurse (reader);
   
   return TRUE;
 }
@@ -420,25 +624,27 @@ write_struct_of_structs_of_structs (DataBlock      *block,
                                     DBusTypeWriter *writer)
 {
   DataBlockState saved;
+  DBusTypeWriter sub;
 
   data_block_save (block, &saved);
   
   if (!_dbus_type_writer_recurse (writer,
-                                  DBUS_TYPE_STRUCT))
+                                  DBUS_TYPE_STRUCT,
+                                  &sub))
     return FALSE;
 
-  if (!write_struct_of_structs (block, writer))
+  if (!write_struct_of_structs (block, &sub))
     {
       data_block_restore (block, &saved);
       return FALSE;
     }
-  if (!write_struct_of_structs (block, writer))
+  if (!write_struct_of_structs (block, &sub))
     {
       data_block_restore (block, &saved);
       return FALSE;
     }
 
-  if (!_dbus_type_writer_unrecurse (writer))
+  if (!_dbus_type_writer_unrecurse (writer, &sub))
     {
       data_block_restore (block, &saved);
       return FALSE;
@@ -451,17 +657,17 @@ static dbus_bool_t
 read_struct_of_structs_of_structs (DataBlock      *block,
                                    DBusTypeReader *reader)
 {
+  DBusTypeReader sub;
+  
   check_expected_type (reader, DBUS_TYPE_STRUCT);
   
-  _dbus_type_reader_recurse (reader);
+  _dbus_type_reader_recurse (reader, &sub);
 
-  if (!read_struct_of_structs (block, reader))
+  if (!read_struct_of_structs (block, &sub))
     return FALSE;
-  _dbus_type_reader_next (reader);
-  if (!read_struct_of_structs (block, reader))
+  _dbus_type_reader_next (&sub);
+  if (!read_struct_of_structs (block, &sub))
     return FALSE;
-
-  _dbus_type_reader_unrecurse (reader);
   
   return TRUE;
 }
@@ -483,16 +689,21 @@ typedef dbus_bool_t (* ReadItemFunc)  (DataBlock      *block,
 
 typedef struct
 {
+  const char *desc;
   WhichItem which;
   WriteItemFunc write_item_func;
   ReadItemFunc read_item_func;
 } CheckMarshalItem;
 
 static CheckMarshalItem items[] = {
-  { ITEM_INT32, write_int32, read_int32 },
-  { ITEM_STRUCT_WITH_INT32S, write_struct_with_int32s, read_struct_with_int32s },
-  { ITEM_STRUCT_OF_STRUCTS, write_struct_of_structs, read_struct_of_structs },
-  { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS,
+  { "int32",
+    ITEM_INT32, write_int32, read_int32 },
+  { "struct with two int32",
+    ITEM_STRUCT_WITH_INT32S, write_struct_with_int32s, read_struct_with_int32s },
+  { "struct with three structs of two int32",
+    ITEM_STRUCT_OF_STRUCTS, write_struct_of_structs, read_struct_of_structs },
+  { "struct of two structs of three structs of two int32",
+    ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS,
     write_struct_of_structs_of_structs,
     read_struct_of_structs_of_structs }
 };
@@ -559,6 +770,9 @@ perform_one_run (DataBlock *block,
   while (run->items[i] != ITEM_INVALID)
     {
       CheckMarshalItem *item = &items[run->items[i]];
+
+      _dbus_verbose ("writing %s\n", item->desc);
+      
       if (!(* item->write_item_func) (block, &writer))
         goto out;
       ++i;
@@ -568,6 +782,8 @@ perform_one_run (DataBlock *block,
   while (run->items[i] != ITEM_INVALID)
     {
       CheckMarshalItem *item = &items[run->items[i]];
+
+      _dbus_verbose ("reading %s\n", item->desc);
       
       if (!(* item->read_item_func) (block, &reader))
         goto out;
index 19960ec..ed70a82 100644 (file)
@@ -67,30 +67,28 @@ struct DBusTypeWriter
   int type_pos;
   DBusString *value_str;
   int value_pos;
+  int container_type;
 };
 
 typedef struct DBusTypeWriter DBusTypeWriter;
 
-void        _dbus_type_reader_init             (DBusTypeReader    *reader,
-                                                int                byte_order,
-                                                const DBusString  *type_str,
-                                                int                type_pos,
-                                                const DBusString  *value_str,
-                                                int                value_pos);
-int         _dbus_type_reader_get_value_end    (DBusTypeReader    *reader);
-int         _dbus_type_reader_get_type_end     (DBusTypeReader    *reader);
-int         _dbus_type_reader_get_current_type (DBusTypeReader    *reader);
-int         _dbus_type_reader_get_array_type   (DBusTypeReader    *reader);
-void        _dbus_type_reader_read_basic       (DBusTypeReader    *reader,
-                                                void              *value);
-dbus_bool_t _dbus_type_reader_read_array       (DBusTypeReader    *reader,
-                                                int                type,
-                                                void             **array,
-                                                int               *array_len);
-void        _dbus_type_reader_recurse          (DBusTypeReader    *reader);
-void        _dbus_type_reader_unrecurse        (DBusTypeReader    *reader);
-dbus_bool_t _dbus_type_reader_next             (DBusTypeReader    *reader);
-
+void        _dbus_type_reader_init                (DBusTypeReader    *reader,
+                                                   int                byte_order,
+                                                   const DBusString  *type_str,
+                                                   int                type_pos,
+                                                   const DBusString  *value_str,
+                                                   int                value_pos);
+int         _dbus_type_reader_get_current_type    (DBusTypeReader    *reader);
+int         _dbus_type_reader_get_array_type      (DBusTypeReader    *reader);
+void        _dbus_type_reader_read_basic          (DBusTypeReader    *reader,
+                                                   void              *value);
+dbus_bool_t _dbus_type_reader_read_array_of_basic (DBusTypeReader    *reader,
+                                                   int                type,
+                                                   void             **array,
+                                                   int               *array_len);
+void        _dbus_type_reader_recurse             (DBusTypeReader    *reader,
+                                                   DBusTypeReader    *subreader);
+dbus_bool_t _dbus_type_reader_next                (DBusTypeReader    *reader);
 
 void        _dbus_type_writer_init        (DBusTypeWriter *writer,
                                            int             byte_order,
@@ -106,7 +104,9 @@ dbus_bool_t _dbus_type_writer_write_array (DBusTypeWriter *writer,
                                            const void     *array,
                                            int             array_len);
 dbus_bool_t _dbus_type_writer_recurse     (DBusTypeWriter *writer,
-                                           int             container_type);
-dbus_bool_t _dbus_type_writer_unrecurse   (DBusTypeWriter *writer);
+                                           int             container_type,
+                                           DBusTypeWriter *sub);
+dbus_bool_t _dbus_type_writer_unrecurse   (DBusTypeWriter *writer,
+                                           DBusTypeWriter *sub);
 
 #endif /* DBUS_MARSHAL_RECURSIVE_H */
index b029f0f..9d8c4b6 100644 (file)
@@ -58,7 +58,7 @@ extern "C" {
 
 /* Compound types */
 #define DBUS_TYPE_ARRAY         ((int) 'a')
-#define DBUS_TYPE_DICT          ((int) 'm')
+#define DBUS_TYPE_DICT          ((int) 'm') /* not parameterized; always map<string,variant> */
 #define DBUS_TYPE_VARIANT       ((int) 'v')
 
 /* STRUCT is sort of special since its code can't appear in a type string,
@@ -72,7 +72,6 @@ extern "C" {
 /* characters other than typecodes that appear in type signatures */
 #define DBUS_STRUCT_BEGIN_CHAR   ((int) '(')
 #define DBUS_STRUCT_END_CHAR     ((int) ')')
-#define DBUS_NAME_DELIMITER_CHAR ((int) '\'')
 
 /* Max length in bytes of a service or interface or member name */
 #define DBUS_MAXIMUM_NAME_LENGTH 256
index 1188c6c..b4e626b 100644 (file)
@@ -612,6 +612,31 @@ _dbus_string_insert_bytes (DBusString   *str,
 }
 
 /**
+ * Inserts a single byte at the given position.
+ *
+ * @param str the string
+ * @param i the position
+ * @param byte the value to insert
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+_dbus_string_insert_byte (DBusString   *str,
+                          int           i,
+                          unsigned char byte)
+{
+  DBUS_STRING_PREAMBLE (str);
+  _dbus_assert (i <= real->len);
+  _dbus_assert (i >= 0);
+  
+  if (!open_gap (1, real, i))
+    return FALSE;
+
+  real->str[i] = byte;
+
+  return TRUE;
+}
+
+/**
  * Like _dbus_string_get_data(), but removes the
  * gotten data from the original string. The caller
  * must free the data returned. This function may
@@ -875,43 +900,68 @@ _dbus_string_set_length (DBusString *str,
 }
 
 static dbus_bool_t
-align_length_then_lengthen (DBusString *str,
-                            int         alignment,
-                            int         then_lengthen_by)
+align_insert_point_then_open_gap (DBusString *str,
+                                  int        *insert_at_p,
+                                  int         alignment,
+                                  int         gap_size)
 {
   unsigned long new_len; /* ulong to avoid _DBUS_ALIGN_VALUE overflow */
+  unsigned long gap_pos;
+  int insert_at;
   int delta;
   DBUS_STRING_PREAMBLE (str);
   _dbus_assert (alignment >= 1);
   _dbus_assert (alignment <= 8); /* it has to be a bug if > 8 */
 
-  new_len = _DBUS_ALIGN_VALUE (real->len, alignment);
-  if (_DBUS_UNLIKELY (new_len > (unsigned long) real->max_length - then_lengthen_by))
+  insert_at = *insert_at_p;
+
+  _dbus_assert (insert_at <= real->len);
+  
+  gap_pos = _DBUS_ALIGN_VALUE (insert_at, alignment);
+  new_len = real->len + (gap_pos - insert_at) + gap_size;
+  
+  if (_DBUS_UNLIKELY (new_len > (unsigned long) real->max_length))
     return FALSE;
-  new_len += then_lengthen_by;
   
   delta = new_len - real->len;
   _dbus_assert (delta >= 0);
 
-  if (delta == 0)
-    return TRUE;
+  if (delta == 0) /* only happens if gap_size == 0 and insert_at is aligned already */
+    {
+      _dbus_assert (((unsigned long) *insert_at_p) == gap_pos);
+      return TRUE;
+    }
 
-  if (_DBUS_UNLIKELY (!set_length (real, new_len)))
+  if (_DBUS_UNLIKELY (!open_gap (new_len - real->len,
+                                 real, insert_at)))
     return FALSE;
 
-  /* delta == padding + then_lengthen_by
-   * new_len == old_len + padding + then_lengthen_by
-   * nul the padding if we had to add any padding
-   */
-  if (then_lengthen_by < delta)
+  /* nul the padding if we had to add any padding */
+  if (gap_size < delta)
     {
-      memset (&real->str[new_len - delta], '\0',
-              delta - then_lengthen_by);
+      memset (&real->str[insert_at], '\0',
+              gap_pos - insert_at);
     }
-      
+
+  *insert_at_p = gap_pos;
+  
   return TRUE;
 }
 
+static dbus_bool_t
+align_length_then_lengthen (DBusString *str,
+                            int         alignment,
+                            int         then_lengthen_by)
+{
+  int insert_at;
+
+  insert_at = _dbus_string_get_length (str);
+  
+  return align_insert_point_then_open_gap (str,
+                                           &insert_at,
+                                           alignment, then_lengthen_by);
+}
+
 /**
  * Align the length of a string to a specific alignment (typically 4 or 8)
  * by appending nul bytes to the string.
@@ -927,6 +977,26 @@ _dbus_string_align_length (DBusString *str,
   return align_length_then_lengthen (str, alignment, 0);
 }
 
+/**
+ * Preallocate extra_bytes such that a future lengthening of the
+ * string by extra_bytes is guaranteed to succeed without an out of
+ * memory error.
+ *
+ * @param str a string
+ * @param extra_bytes bytes to alloc
+ * @returns #FALSE if no memory
+ */
+dbus_bool_t
+_dbus_string_alloc_space (DBusString        *str,
+                          int                extra_bytes)
+{
+  if (!_dbus_string_lengthen (str, extra_bytes))
+    return FALSE;
+  _dbus_string_shorten (str, extra_bytes);
+
+  return TRUE;
+}
+
 static dbus_bool_t
 append (DBusRealString *real,
         const char     *buffer,
@@ -968,6 +1038,31 @@ _dbus_string_append (DBusString *str,
   return append (real, buffer, buffer_len);
 }
 
+#define ASSIGN_4_OCTETS(p, octets) \
+  *((dbus_uint32_t*)(p)) = *((dbus_uint32_t*)(octets));
+
+#ifdef DBUS_HAVE_INT64
+#define ASSIGN_8_OCTETS(p, octets) \
+  *((dbus_uint64_t*)(p)) = *((dbus_uint64_t*)(octets));
+#else
+#define ASSIGN_8_OCTETS(p, octets)              \
+do {                                            \
+  unsigned char *b;                             \
+                                                \
+  b = p;                                        \
+                                                \
+  *b++ = octets[0];                             \
+  *b++ = octets[1];                             \
+  *b++ = octets[2];                             \
+  *b++ = octets[3];                             \
+  *b++ = octets[4];                             \
+  *b++ = octets[5];                             \
+  *b++ = octets[6];                             \
+  *b++ = octets[7];                             \
+  _dbus_assert (b == p + 8);                    \
+} while (0)
+#endif /* DBUS_HAVE_INT64 */
+
 /**
  * Appends 4 bytes aligned on a 4 byte boundary
  * with any alignment padding initialized to 0.
@@ -980,14 +1075,12 @@ dbus_bool_t
 _dbus_string_append_4_aligned (DBusString         *str,
                                const unsigned char octets[4])
 {
-  dbus_uint32_t *p;
   DBUS_STRING_PREAMBLE (str);
   
   if (!align_length_then_lengthen (str, 4, 4))
     return FALSE;
 
-  p = (dbus_uint32_t*) (real->str + (real->len - 4));
-  *p = *((dbus_uint32_t*)octets);
+  ASSIGN_4_OCTETS (real->str + (real->len - 4), octets);
 
   return TRUE;
 }
@@ -997,41 +1090,65 @@ _dbus_string_append_4_aligned (DBusString         *str,
  * with any alignment padding initialized to 0.
  *
  * @param str the DBusString
- * @param octets 4 bytes to append
+ * @param octets 8 bytes to append
  * @returns #FALSE if not enough memory.
  */
 dbus_bool_t
 _dbus_string_append_8_aligned (DBusString         *str,
                                const unsigned char octets[8])
 {
-#ifdef DBUS_HAVE_INT64
-  dbus_uint64_t *p;
   DBUS_STRING_PREAMBLE (str);
   
   if (!align_length_then_lengthen (str, 8, 8))
     return FALSE;
 
-  p = (dbus_uint64_t*) (real->str + (real->len - 8));
-  *p = *((dbus_uint64_t*)octets);
-#else
-  unsigned char *p;
+  ASSIGN_8_OCTETS (real->str + (real->len - 8), octets);
+
+  return TRUE;
+}
+
+/**
+ * Inserts 4 bytes aligned on a 4 byte boundary
+ * with any alignment padding initialized to 0.
+ *
+ * @param str the DBusString
+ * @param octets 4 bytes to insert
+ * @returns #FALSE if not enough memory.
+ */
+dbus_bool_t
+_dbus_string_insert_4_aligned (DBusString         *str,
+                               int                 insert_at,
+                               const unsigned char octets[4])
+{
   DBUS_STRING_PREAMBLE (str);
   
-  if (!align_length_then_lengthen (str, 8, 8))
+  if (!align_insert_point_then_open_gap (str, &insert_at, 4, 4))
     return FALSE;
 
-  p = real->str + (real->len - 8);
-  
-  *p++ = octets[0];
-  *p++ = octets[1];
-  *p++ = octets[2];
-  *p++ = octets[3];
-  *p++ = octets[4];
-  *p++ = octets[5];
-  *p++ = octets[6];
-  *p++ = octets[7];
-  _dbus_assert (p == (real->str + real->len));
-#endif
+  ASSIGN_4_OCTETS (real->str + insert_at, octets);
+
+  return TRUE;
+}
+
+/**
+ * Inserts 8 bytes aligned on an 8 byte boundary
+ * with any alignment padding initialized to 0.
+ *
+ * @param str the DBusString
+ * @param octets 8 bytes to insert
+ * @returns #FALSE if not enough memory.
+ */
+dbus_bool_t
+_dbus_string_insert_8_aligned (DBusString         *str,
+                               int                 insert_at,
+                               const unsigned char octets[8])
+{
+  DBUS_STRING_PREAMBLE (str);
+  
+  if (!align_insert_point_then_open_gap (str, &insert_at, 8, 8))
+    return FALSE;
+
+  ASSIGN_8_OCTETS (real->str + insert_at, octets);
 
   return TRUE;
 }
index c30a63f..2b8b09f 100644 (file)
@@ -90,6 +90,9 @@ dbus_bool_t   _dbus_string_insert_bytes          (DBusString        *str,
                                                   int                i,
                                                  int                n_bytes,
                                                   unsigned char      byte);
+dbus_bool_t   _dbus_string_insert_byte           (DBusString        *str,
+                                                  int                i,
+                                                  unsigned char      byte);
 dbus_bool_t   _dbus_string_steal_data            (DBusString        *str,
                                                   char             **data_return);
 dbus_bool_t   _dbus_string_steal_data_len        (DBusString        *str,
@@ -117,6 +120,8 @@ dbus_bool_t   _dbus_string_set_length            (DBusString        *str,
                                                   int                length);
 dbus_bool_t   _dbus_string_align_length          (DBusString        *str,
                                                   int                alignment);
+dbus_bool_t   _dbus_string_alloc_space           (DBusString        *str,
+                                                  int                extra_bytes);
 dbus_bool_t   _dbus_string_append                (DBusString        *str,
                                                   const char        *buffer);
 dbus_bool_t   _dbus_string_append_len            (DBusString        *str,
@@ -142,6 +147,12 @@ dbus_bool_t   _dbus_string_append_printf         (DBusString        *str,
 dbus_bool_t   _dbus_string_append_printf_valist  (DBusString        *str,
                                                   const char        *format,
                                                   va_list            args);
+dbus_bool_t   _dbus_string_insert_4_aligned      (DBusString        *str,
+                                                  int                insert_at,
+                                                  const unsigned char octets[4]);
+dbus_bool_t   _dbus_string_insert_8_aligned      (DBusString        *str,
+                                                  int                insert_at,
+                                                  const unsigned char octets[8]);
 void          _dbus_string_delete                (DBusString        *str,
                                                   int                start,
                                                   int                len);