2003-02-21 Anders Carlsson <andersca@codefactory.se>
authorAnders Carlsson <andersca@codefactory.se>
Fri, 21 Feb 2003 20:51:34 +0000 (20:51 +0000)
committerAnders Carlsson <andersca@codefactory.se>
Fri, 21 Feb 2003 20:51:34 +0000 (20:51 +0000)
* dbus/dbus-marshal.c: (_dbus_demarshal_string_array):
Make string arrays NULL-terminated.

* dbus/dbus-memory.c: (dbus_free_string_array):
* dbus/dbus-memory.h:
New function for freeing NULL-terminated string arrays.

* dbus/dbus-message-builder.c: (append_quoted_string),
(_dbus_message_data_load):
Add support for array types.

* dbus/dbus-message.c: (check_message_handling):
Add more types as test cases.

* dbus/dbus-sysdeps.c: (_dbus_string_parse_int),
(_dbus_string_parse_double):
Add the start offset to the end offset.

* test/data/valid-messages/lots-of-arguments.message:
New test message with lots of arguments.

ChangeLog
dbus/dbus-marshal.c
dbus/dbus-memory.c
dbus/dbus-memory.h
dbus/dbus-message-builder.c
dbus/dbus-message.c
dbus/dbus-sysdeps.c
test/data/valid-messages/lots-of-arguments.message [new file with mode: 0644]

index 49db62a..2ba84fe 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,28 @@
 2003-02-21  Anders Carlsson  <andersca@codefactory.se>
 
+       * dbus/dbus-marshal.c: (_dbus_demarshal_string_array):
+       Make string arrays NULL-terminated.
+       
+       * dbus/dbus-memory.c: (dbus_free_string_array):
+       * dbus/dbus-memory.h:
+       New function for freeing NULL-terminated string arrays.
+       
+       * dbus/dbus-message-builder.c: (append_quoted_string),
+       (_dbus_message_data_load):
+       Add support for array types.
+       
+       * dbus/dbus-message.c: (check_message_handling):
+       Add more types as test cases.
+       
+       * dbus/dbus-sysdeps.c: (_dbus_string_parse_int),
+       (_dbus_string_parse_double):
+       Add the start offset to the end offset.
+       
+       * test/data/valid-messages/lots-of-arguments.message:
+       New test message with lots of arguments.
+       
+2003-02-21  Anders Carlsson  <andersca@codefactory.se>
+
        * dbus/dbus-message.c: (dbus_message_append_nil),
        (dbus_message_append_int32), (dbus_message_append_uint32),
        (dbus_message_append_double), (dbus_message_append_string),
index 37128a2..f32daef 100644 (file)
@@ -813,11 +813,13 @@ _dbus_demarshal_string_array (const DBusString *str,
 
   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
 
-  retval = dbus_new (char *, len);
+  retval = dbus_new (char *, len + 1);
 
   if (!retval)
     return NULL;
 
+  retval[len] = NULL;
+  
   for (i = 0; i < len; i++)
     {
       retval[i] = _dbus_demarshal_string (str, byte_order, pos, &pos);
index 11489c7..14ce23d 100644 (file)
@@ -220,4 +220,28 @@ dbus_free (void  *memory)
     free (memory);
 }
 
+/**
+ * Frees a #NULL-terminated array of strings.
+ * If passed #NULL, does nothing.
+ *
+ * @param str_array the array to be freed
+ */
+void
+dbus_free_string_array (char **str_array)
+{
+  if (str_array)
+    {
+      int i;
+
+      i = 0;
+      while (str_array[i])
+       {
+         dbus_free (str_array[i]);
+         i++;
+       }
+
+      dbus_free (str_array);
+    }
+}
+
 /** @} */
index e0b5a8b..7a0e316 100644 (file)
@@ -41,6 +41,8 @@ void  dbus_free          (void  *memory);
 #define dbus_new(type, count)  ((type*)dbus_malloc (sizeof (type) * (count)));
 #define dbus_new0(type, count) ((type*)dbus_malloc0 (sizeof (type) * (count)));
 
+void dbus_free_string_array (char **str_array);
+
 typedef void (* DBusFreeFunction) (void *memory);
 
 DBUS_END_DECLS;
index 838f261..03022ba 100644 (file)
@@ -189,12 +189,18 @@ save_offset (DBusHashTable    *hash,
 
 static dbus_bool_t
 append_quoted_string (DBusString       *dest,
-                      const DBusString *quoted)
+                      const DBusString *quoted,
+                     int               start_pos,
+                     int              *new_pos)
 {
   dbus_bool_t in_quotes = FALSE;
   int i;
 
-  i = 0;
+  /* FIXME: We might want to add escaping in case we want to put '
+   * characters in our strings.
+   */
+  
+  i = start_pos;
   while (i < _dbus_string_get_length (quoted))
     {
       unsigned char b;
@@ -204,7 +210,7 @@ append_quoted_string (DBusString       *dest,
       if (in_quotes)
         {
           if (b == '\'')
-            in_quotes = FALSE;
+           break;
           else
             {
               if (!_dbus_string_append_byte (dest, b))
@@ -227,6 +233,9 @@ append_quoted_string (DBusString       *dest,
       ++i;
     }
 
+  if (new_pos)
+    *new_pos = i;
+  
   if (!_dbus_string_append_byte (dest, '\0'))
     return FALSE;
   return TRUE;
@@ -288,6 +297,9 @@ append_saved_length (DBusString       *dest,
  *   UINT32 <N> marshals a UINT32
  *   DOUBLE <N> marshals a double
  *   STRING 'Foo' marshals a string
+ *   INT32_ARRAY { 3, 4, 5, 6} marshals an INT32 array
+ *   UINT32_ARRAY { 3, 4, 5, 6} marshals an UINT32 array
+ *   DOUBLE_ARRAY { 1.0, 2.0, 3.0, 4.0} marshals a DOUBLE array  
  * @endcode
  *
  * @todo add support for array types INT32_ARRAY { 3, 4, 5, 6 }
@@ -585,14 +597,6 @@ _dbus_message_data_load (DBusString       *dest,
             code = DBUS_TYPE_INVALID;
           else if (_dbus_string_starts_with_c_str (&line, "NIL"))
             code = DBUS_TYPE_NIL;
-          else if (_dbus_string_starts_with_c_str (&line, "INT32"))
-            code = DBUS_TYPE_INT32;
-          else if (_dbus_string_starts_with_c_str (&line, "UINT32"))
-            code = DBUS_TYPE_UINT32;
-          else if (_dbus_string_starts_with_c_str (&line, "DOUBLE"))
-            code = DBUS_TYPE_DOUBLE;
-          else if (_dbus_string_starts_with_c_str (&line, "STRING"))
-            code = DBUS_TYPE_STRING;
           else if (_dbus_string_starts_with_c_str (&line, "INT32_ARRAY"))
             code = DBUS_TYPE_INT32_ARRAY;
           else if (_dbus_string_starts_with_c_str (&line, "UINT32_ARRAY"))
@@ -603,6 +607,14 @@ _dbus_message_data_load (DBusString       *dest,
             code = DBUS_TYPE_BYTE_ARRAY;
           else if (_dbus_string_starts_with_c_str (&line, "STRING_ARRAY"))
             code = DBUS_TYPE_STRING_ARRAY;
+          else if (_dbus_string_starts_with_c_str (&line, "INT32"))
+            code = DBUS_TYPE_INT32;
+          else if (_dbus_string_starts_with_c_str (&line, "UINT32"))
+            code = DBUS_TYPE_UINT32;
+          else if (_dbus_string_starts_with_c_str (&line, "DOUBLE"))
+            code = DBUS_TYPE_DOUBLE;
+          else if (_dbus_string_starts_with_c_str (&line, "STRING"))
+            code = DBUS_TYPE_STRING;
           else
             {
               const char *s;
@@ -618,6 +630,289 @@ _dbus_message_data_load (DBusString       *dest,
             }
         }
       else if (_dbus_string_starts_with_c_str (&line,
+                                              "INT32_ARRAY"))
+       {
+         SAVE_FOR_UNALIGN (dest, 4);
+         int i, len, allocated;
+         dbus_int32_t *values;
+         long val;
+         unsigned char b;
+
+         allocated = 4;
+         values = dbus_new (dbus_int32_t, allocated);
+         if (!values)
+           {
+             _dbus_warn ("could not allocate memory for INT32_ARRAY\n");
+             goto parse_failed;
+           }
+         
+         len = 0;
+         
+         _dbus_string_delete_first_word (&line);
+         _dbus_string_skip_blank (&line, 0, &i);
+         b = _dbus_string_get_byte (&line, i++);
+
+         if (b != '{')
+           goto parse_failed;
+
+         while (i < _dbus_string_get_length (&line))
+           {
+             _dbus_string_skip_blank (&line, i, &i);
+
+             if (!_dbus_string_parse_int (&line, i, &val, &i))
+               {
+                 _dbus_warn ("could not parse integer for INT32_ARRAY\n");
+                 goto parse_failed;
+               }
+
+             values[len++] = val;
+             if (len == allocated)
+               {
+                 allocated *= 2;
+                 values = dbus_realloc (values, allocated * sizeof (dbus_int32_t));
+                 if (!values)
+                   {
+                     _dbus_warn ("could not allocate memory for INT32_ARRAY\n");
+                     goto parse_failed;
+                   }
+               }
+             
+             _dbus_string_skip_blank (&line, i, &i);
+             
+             b = _dbus_string_get_byte (&line, i++);
+
+             if (b == '}')
+               break;
+             else if (b != ',')
+               goto parse_failed;
+           }
+
+          if (!_dbus_marshal_int32_array (dest, endian, values, len))
+            {
+              _dbus_warn ("failed to append INT32_ARRAY\n");
+              goto parse_failed;
+            }
+         dbus_free (values);
+         
+         PERFORM_UNALIGN (dest);
+       }
+      else if (_dbus_string_starts_with_c_str (&line,
+                                              "UINT32_ARRAY"))
+       {
+         SAVE_FOR_UNALIGN (dest, 4);
+         int i, len, allocated;
+         dbus_uint32_t *values;
+         long val;
+         unsigned char b;
+
+         allocated = 4;
+         values = dbus_new (dbus_uint32_t, allocated);
+         if (!values)
+           {
+             _dbus_warn ("could not allocate memory for UINT32_ARRAY\n");
+             goto parse_failed;
+           }
+         
+         len = 0;
+         
+         _dbus_string_delete_first_word (&line);
+         _dbus_string_skip_blank (&line, 0, &i);
+         b = _dbus_string_get_byte (&line, i++);
+
+         if (b != '{')
+           goto parse_failed;
+
+         while (i < _dbus_string_get_length (&line))
+           {
+             _dbus_string_skip_blank (&line, i, &i);
+
+             if (!_dbus_string_parse_int (&line, i, &val, &i))
+               {
+                 _dbus_warn ("could not parse integer for UINT32_ARRAY\n");
+                 goto parse_failed;
+               }
+
+             values[len++] = val;
+             if (len == allocated)
+               {
+                 allocated *= 2;
+                 values = dbus_realloc (values, allocated * sizeof (dbus_uint32_t));
+                 if (!values)
+                   {
+                     _dbus_warn ("could not allocate memory for UINT32_ARRAY\n");
+                     goto parse_failed;
+                   }
+               }
+             
+             _dbus_string_skip_blank (&line, i, &i);
+             
+             b = _dbus_string_get_byte (&line, i++);
+
+             if (b == '}')
+               break;
+             else if (b != ',')
+               goto parse_failed;
+           }
+
+          if (!_dbus_marshal_uint32_array (dest, endian, values, len))
+            {
+              _dbus_warn ("failed to append UINT32_ARRAY\n");
+              goto parse_failed;
+            }
+         dbus_free (values);
+         
+         PERFORM_UNALIGN (dest);
+       }
+      else if (_dbus_string_starts_with_c_str (&line,
+                                              "DOUBLE_ARRAY"))
+       {
+         SAVE_FOR_UNALIGN (dest, 8);
+         int i, len, allocated;
+         double *values;
+         double val;
+         unsigned char b;
+
+         allocated = 4;
+         values = dbus_new (double, allocated);
+         if (!values)
+           {
+             _dbus_warn ("could not allocate memory for DOUBLE_ARRAY\n");
+             goto parse_failed;
+           }
+         
+         len = 0;
+         
+         _dbus_string_delete_first_word (&line);
+         _dbus_string_skip_blank (&line, 0, &i);
+         b = _dbus_string_get_byte (&line, i++);
+
+         if (b != '{')
+           goto parse_failed;
+
+         while (i < _dbus_string_get_length (&line))
+           {
+             _dbus_string_skip_blank (&line, i, &i);
+
+             if (!_dbus_string_parse_double (&line, i, &val, &i))
+               {
+                 _dbus_warn ("could not parse double for DOUBLE_ARRAY\n");
+                 goto parse_failed;
+               }
+
+             values[len++] = val;
+             if (len == allocated)
+               {
+                 allocated *= 2;
+                 values = dbus_realloc (values, allocated * sizeof (double));
+                 if (!values)
+                   {
+                     _dbus_warn ("could not allocate memory for DOUBLE_ARRAY\n");
+                     goto parse_failed;
+                   }
+               }
+             
+             _dbus_string_skip_blank (&line, i, &i);
+             
+             b = _dbus_string_get_byte (&line, i++);
+
+             if (b == '}')
+               break;
+             else if (b != ',')
+               goto parse_failed;
+           }
+
+          if (!_dbus_marshal_double_array (dest, endian, values, len))
+            {
+              _dbus_warn ("failed to append DOUBLE_ARRAY\n");
+              goto parse_failed;
+            }
+         dbus_free (values);
+         
+         PERFORM_UNALIGN (dest);
+       }
+      else if (_dbus_string_starts_with_c_str (&line,
+                                              "STRING_ARRAY"))
+       {
+         SAVE_FOR_UNALIGN (dest, 4);
+         int i, len, allocated;
+         char **values;
+         char *val;
+         DBusString val_str;
+         unsigned char b;
+
+         allocated = 4;
+         values = dbus_new (char *, allocated);
+         if (!values)
+           {
+             _dbus_warn ("could not allocate memory for DOUBLE_ARRAY\n");
+             goto parse_failed;
+           }
+         
+         len = 0;
+         
+         _dbus_string_delete_first_word (&line);
+         _dbus_string_skip_blank (&line, 0, &i);
+         b = _dbus_string_get_byte (&line, i++);
+
+         if (b != '{')
+           goto parse_failed;
+
+         _dbus_string_init (&val_str, _DBUS_INT_MAX);
+         while (i < _dbus_string_get_length (&line))
+           {
+             _dbus_string_skip_blank (&line, i, &i);
+
+             if (!append_quoted_string (&val_str, &line, i, &i))
+               {
+                 _dbus_warn ("could not parse quoted string for STRING_ARRAY\n");
+                 goto parse_failed;
+               }
+             i++;
+
+             if (!_dbus_string_steal_data (&val_str, &val))
+               {
+                 _dbus_warn ("could not allocate memory for STRING_ARRAY string\n");
+                 goto parse_failed;
+               }
+             
+             values[len++] = val;
+             if (len == allocated)
+               {
+                 allocated *= 2;
+                 values = dbus_realloc (values, allocated * sizeof (char *));
+                 if (!values)
+                   {
+                     _dbus_warn ("could not allocate memory for STRING_ARRAY\n");
+                     goto parse_failed;
+                   }
+               }
+             
+             _dbus_string_skip_blank (&line, i, &i);
+             
+             b = _dbus_string_get_byte (&line, i++);
+
+             if (b == '}')
+               break;
+             else if (b != ',')
+               {
+                 _dbus_warn ("missing comma when parsing STRING_ARRAY\n");
+                 goto parse_failed;
+               }
+           }
+         _dbus_string_free (&val_str);
+         
+          if (!_dbus_marshal_string_array (dest, endian, (const char **)values, len))
+            {
+              _dbus_warn ("failed to append STRING_ARRAY\n");
+              goto parse_failed;
+            }
+
+         values[len] = NULL;
+         dbus_free_string_array (values);
+         
+         PERFORM_UNALIGN (dest);
+       }
+      else if (_dbus_string_starts_with_c_str (&line,
                                                "INT32"))
         {
           SAVE_FOR_UNALIGN (dest, 4);
@@ -699,7 +994,7 @@ _dbus_message_data_load (DBusString       *dest,
             }
 
           old_len = _dbus_string_get_length (dest);
-          if (!append_quoted_string (dest, &line))
+          if (!append_quoted_string (dest, &line, 0, NULL))
             {
               _dbus_warn ("Failed to append quoted string\n");
               goto parse_failed;
index 0c6b72d..c7a33c2 100644 (file)
@@ -1909,9 +1909,6 @@ dbus_message_iter_get_byte_array (DBusMessageIter  *iter,
  * Note that you need to check that the iterator points
  * to a byte array prior to using this function.
  *
- * @todo this function should probably take "char **" as
- * an out param argument, and return boolean or result code.
- *
  * @param iter the iterator
  * @param len return location for length of byte array
  * @returns the byte array
@@ -2715,6 +2712,17 @@ check_message_handling (DBusMessage *message)
     {
       switch (type)
         {
+       case DBUS_TYPE_NIL:
+         break;
+       case DBUS_TYPE_INT32:
+         dbus_message_iter_get_int32 (iter);
+         break;
+       case DBUS_TYPE_UINT32:
+         dbus_message_iter_get_uint32 (iter);
+         break;
+       case DBUS_TYPE_DOUBLE:
+         dbus_message_iter_get_double (iter);
+         break;
         case DBUS_TYPE_STRING:
           {
             char *str;
@@ -2722,6 +2730,53 @@ check_message_handling (DBusMessage *message)
             dbus_free (str);
           }
           break;
+        case DBUS_TYPE_INT32_ARRAY:
+          {
+           dbus_int32_t *values;
+           int len;
+           
+            if (!dbus_message_iter_get_int32_array (iter, &values, &len))
+             return FALSE;
+
+           dbus_free (values);
+          }
+          break;
+        case DBUS_TYPE_UINT32_ARRAY:
+          {
+           dbus_uint32_t *values;
+           int len;
+           
+            if (!dbus_message_iter_get_uint32_array (iter, &values, &len))
+             return FALSE;
+
+           dbus_free (values);
+          }
+          break;
+        case DBUS_TYPE_DOUBLE_ARRAY:
+          {
+           double *values;
+           int len;
+           
+            if (!dbus_message_iter_get_double_array (iter, &values, &len))
+             return FALSE;
+
+           dbus_free (values);
+          }
+         break;
+       case DBUS_TYPE_STRING_ARRAY:
+          {
+           char **values;
+           int len;
+           
+            if (!dbus_message_iter_get_string_array (iter, &values, &len))
+             return FALSE;
+
+           dbus_free_string_array (values);
+          }
+          break;
+         
+       default:
+         break;
         }
       
       if (!dbus_message_iter_next (iter))
index 7a16eec..bcfa15f 100644 (file)
@@ -925,7 +925,7 @@ _dbus_string_parse_int (const DBusString *str,
   if (value_return)
     *value_return = v;
   if (end_return)
-    *end_return = (end - p);
+    *end_return = start + (end - p);
 
   return TRUE;
 }
@@ -970,7 +970,7 @@ _dbus_string_parse_double (const DBusString *str,
   if (value_return)
     *value_return = v;
   if (end_return)
-    *end_return = (end - p);
+    *end_return = start + (end - p);
 
   return TRUE;
 }
diff --git a/test/data/valid-messages/lots-of-arguments.message b/test/data/valid-messages/lots-of-arguments.message
new file mode 100644 (file)
index 0000000..0195cc9
--- /dev/null
@@ -0,0 +1,24 @@
+# Message with lots of different argument types
+
+VALID_HEADER
+END_LENGTH Header
+ALIGN 8
+START_LENGTH Body
+TYPE NIL
+TYPE INT32
+INT32 0x12345678
+TYPE UINT32
+UINT32 0x8765432
+TYPE DOUBLE
+DOUBLE 3.141592653589
+TYPE STRING
+STRING 'This is a string'
+TYPE INT32_ARRAY
+INT32_ARRAY { 1, -2, 3, -4, 5, -6, 7, -8, 9, -10 }
+TYPE UINT32_ARRAY
+UINT32_ARRAY { 11, 12, 314, 1911, 57692, 1237, 2834 }
+TYPE DOUBLE_ARRAY
+DOUBLE_ARRAY { 0.1, 0.2, 3.1415926, 2.7183, 10.0, 9.99 }
+TYPE STRING_ARRAY
+STRING_ARRAY { 'Hello', 'This', 'Is', 'A', 'String', 'Array!' }
+END_LENGTH Body