Revert merge of master (dbus-1.5) into dbus-1.4
[platform/upstream/dbus.git] / dbus / dbus-marshal-basic.c
index b983ae5..3cbc721 100644 (file)
@@ -1,4 +1,4 @@
-/* -*- mode: C; c-file-style: "gnu" -*- */
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 /* dbus-marshal-basic.c  Marshalling routines for basic (primitive) types
  *
  * Copyright (C) 2002 CodeFactory AB
  *
  * 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  *
  */
 
+#include <config.h>
 #include "dbus-internals.h"
 #include "dbus-marshal-basic.h"
 #include "dbus-signature.h"
@@ -414,6 +415,7 @@ _dbus_marshal_set_basic (DBusString       *str,
     case DBUS_TYPE_BOOLEAN:
     case DBUS_TYPE_INT32:
     case DBUS_TYPE_UINT32:
+    case DBUS_TYPE_UNIX_FD:
       pos = _DBUS_ALIGN_VALUE (pos, 4);
       set_4_octets (str, pos, vp->u32, byte_order);
       if (old_end_pos)
@@ -508,59 +510,75 @@ _dbus_marshal_read_basic (const DBusString      *str,
                           int                   *new_pos)
 {
   const char *str_data;
-  DBusBasicValue *vp;
 
   _dbus_assert (dbus_type_is_basic (type));
 
   str_data = _dbus_string_get_const_data (str);
-  vp = value;
 
+  /* Below we volatile types to avoid aliasing issues;
+   * see http://bugs.freedesktop.org/show_bug.cgi?id=20137
+   */
+  
   switch (type)
     {
     case DBUS_TYPE_BYTE:
-      vp->byt = _dbus_string_get_byte (str, pos);
+      {
+      volatile unsigned char *vp = value;
+      *vp = (unsigned char) _dbus_string_get_byte (str, pos);
       (pos)++;
+      }
       break;
     case DBUS_TYPE_INT16:
     case DBUS_TYPE_UINT16:
+      {
+      volatile dbus_uint16_t *vp = value;
       pos = _DBUS_ALIGN_VALUE (pos, 2);
-      vp->u16 = *(dbus_uint16_t *)(str_data + pos);
+      *vp = *(dbus_uint16_t *)(str_data + pos);
       if (byte_order != DBUS_COMPILER_BYTE_ORDER)
-       vp->u16 = DBUS_UINT16_SWAP_LE_BE (vp->u16);
+       *vp = DBUS_UINT16_SWAP_LE_BE (*vp);
       pos += 2;
+      }
       break;
     case DBUS_TYPE_INT32:
     case DBUS_TYPE_UINT32:
     case DBUS_TYPE_BOOLEAN:
+    case DBUS_TYPE_UNIX_FD:
+      {
+      volatile dbus_uint32_t *vp = value;
       pos = _DBUS_ALIGN_VALUE (pos, 4);
-      vp->u32 = *(dbus_uint32_t *)(str_data + pos);
+      *vp = *(dbus_uint32_t *)(str_data + pos);
       if (byte_order != DBUS_COMPILER_BYTE_ORDER)
-       vp->u32 = DBUS_UINT32_SWAP_LE_BE (vp->u32);
+       *vp = DBUS_UINT32_SWAP_LE_BE (*vp);
       pos += 4;
+      }
       break;
     case DBUS_TYPE_INT64:
     case DBUS_TYPE_UINT64:
     case DBUS_TYPE_DOUBLE:
+      {
+      volatile dbus_uint64_t *vp = value;
       pos = _DBUS_ALIGN_VALUE (pos, 8);
 #ifdef DBUS_HAVE_INT64
       if (byte_order != DBUS_COMPILER_BYTE_ORDER)
-        vp->u64 = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t*)(str_data + pos));
+        *vp = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t*)(str_data + pos));
       else
-        vp->u64 = *(dbus_uint64_t*)(str_data + pos);
+        *vp = *(dbus_uint64_t*)(str_data + pos);
 #else
-      vp->u64 = *(DBus8ByteStruct*) (str_data + pos);
+      *vp = *(DBus8ByteStruct*) (str_data + pos);
       swap_8_octets (vp, byte_order);
 #endif
       pos += 8;
+      }
       break;
     case DBUS_TYPE_STRING:
     case DBUS_TYPE_OBJECT_PATH:
       {
         int len;
+        volatile char **vp = value;
 
         len = _dbus_marshal_read_uint32 (str, pos, byte_order, &pos);
 
-        vp->str = (char*) str_data + pos;
+        *vp = (char*) str_data + pos;
 
         pos += len + 1; /* length plus nul */
       }
@@ -568,18 +586,19 @@ _dbus_marshal_read_basic (const DBusString      *str,
     case DBUS_TYPE_SIGNATURE:
       {
         int len;
+        volatile char **vp = value;
 
         len = _dbus_string_get_byte (str, pos);
         pos += 1;
 
-        vp->str = (char*) str_data + pos;
+        *vp = (char*) str_data + pos;
 
         pos += len + 1; /* length plus nul */
       }
       break;
     default:
-      _dbus_warn ("type %s %d not a basic type\n",
-                  _dbus_type_to_string (type), type);
+      _dbus_warn_check_failed ("type %s %d not a basic type\n",
+                               _dbus_type_to_string (type), type);
       _dbus_assert_not_reached ("not a basic type");
       break;
     }
@@ -588,57 +607,6 @@ _dbus_marshal_read_basic (const DBusString      *str,
     *new_pos = pos;
 }
 
-/**
- * Reads a block of fixed-length basic values, as an optimization
- * vs. reading each one individually into a new buffer.
- *
- * This function returns the data in-place; it does not make a copy,
- * and it does not swap the bytes.
- *
- * If you ask for #DBUS_TYPE_DOUBLE you will get a "const double*" back
- * and the "value" argument should be a "const double**" and so on.
- *
- * @todo we aren't using this function (except in the test suite)
- * 
- * @param str the string to read from
- * @param pos position to read from
- * @param element_type type of array elements
- * @param value place to return the array
- * @param n_elements number of array elements to read
- * @param byte_order the byte order, used to read the array length
- * @param new_pos #NULL or location to store a position after the elements
- */
-void
-_dbus_marshal_read_fixed_multi  (const DBusString *str,
-                                 int               pos,
-                                 int               element_type,
-                                 void             *value,
-                                 int               n_elements,
-                                 int               byte_order,
-                                 int              *new_pos)
-{
-  int array_len;
-  int alignment;
-
-  _dbus_assert (dbus_type_is_fixed (element_type));
-  _dbus_assert (dbus_type_is_basic (element_type));
-
-#if 0
-  _dbus_verbose ("reading %d elements of %s\n",
-                 n_elements, _dbus_type_to_string (element_type));
-#endif
-  
-  alignment = _dbus_type_get_alignment (element_type);
-
-  pos = _DBUS_ALIGN_VALUE (pos, alignment);
-  
-  array_len = n_elements * alignment;
-
-  *(const DBusBasicValue**) value = (void*) _dbus_string_get_const_data_len (str, pos, array_len);
-  if (new_pos)
-    *new_pos = pos + array_len;
-}
-
 static dbus_bool_t
 marshal_2_octets (DBusString   *str,
                   int           insert_at,
@@ -874,6 +842,7 @@ _dbus_marshal_write_basic (DBusString *str,
       break;
     case DBUS_TYPE_INT32:
     case DBUS_TYPE_UINT32:
+    case DBUS_TYPE_UNIX_FD:
       return marshal_4_octets (str, insert_at, vp->u32,
                                byte_order, pos_after);
       break;
@@ -1096,11 +1065,10 @@ _dbus_marshal_write_fixed_multi (DBusString *str,
     case DBUS_TYPE_INT16:
     case DBUS_TYPE_UINT16:
       return marshal_fixed_multi (str, insert_at, vp, n_elements, byte_order, 2, pos_after);
-      /* FIXME: we canonicalize to 0 or 1 for the single boolean case
-       * should we here too ? */
     case DBUS_TYPE_BOOLEAN:
     case DBUS_TYPE_INT32:
     case DBUS_TYPE_UINT32:
+    case DBUS_TYPE_UNIX_FD:
       return marshal_fixed_multi (str, insert_at, vp, n_elements, byte_order, 4, pos_after);
       break;
     case DBUS_TYPE_INT64:
@@ -1149,6 +1117,7 @@ _dbus_marshal_skip_basic (const DBusString      *str,
     case DBUS_TYPE_BOOLEAN:
     case DBUS_TYPE_INT32:
     case DBUS_TYPE_UINT32:
+    case DBUS_TYPE_UNIX_FD:
       *pos = _DBUS_ALIGN_VALUE (*pos, 4);
       *pos += 4;
       break;
@@ -1237,6 +1206,7 @@ _dbus_type_get_alignment (int typecode)
     case DBUS_TYPE_BOOLEAN:
     case DBUS_TYPE_INT32:
     case DBUS_TYPE_UINT32:
+    case DBUS_TYPE_UNIX_FD:
       /* this stuff is 4 since it starts with a length */
     case DBUS_TYPE_STRING:
     case DBUS_TYPE_OBJECT_PATH:
@@ -1291,6 +1261,7 @@ _dbus_type_is_valid (int typecode)
     case DBUS_TYPE_STRUCT:
     case DBUS_TYPE_DICT_ENTRY:
     case DBUS_TYPE_VARIANT:
+    case DBUS_TYPE_UNIX_FD:
       return TRUE;
 
     default:
@@ -1351,6 +1322,8 @@ _dbus_type_to_string (int typecode)
       return "begin_dict_entry";
     case DBUS_DICT_ENTRY_END_CHAR:
       return "end_dict_entry";
+    case DBUS_TYPE_UNIX_FD:
+      return "unix_fd";
     default:
       return "unknown";
     }
@@ -1359,8 +1332,6 @@ _dbus_type_to_string (int typecode)
 /**
  * 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
@@ -1375,6 +1346,9 @@ _dbus_verbose_bytes (const unsigned char *data,
 
   _dbus_assert (len >= 0);
 
+  if (!_dbus_is_verbose())
+    return;
+
   /* Print blanks on first row if appropriate */
   aligned = _DBUS_ALIGN_ADDRESS (data, 4);
   if (aligned > data)
@@ -1383,7 +1357,7 @@ _dbus_verbose_bytes (const unsigned char *data,
 
   if (aligned != data)
     {
-      _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned);
+      _dbus_verbose ("%4ld\t%p: ", - (long)(data - aligned), aligned);
       while (aligned != data)
         {
           _dbus_verbose ("    ");
@@ -1420,16 +1394,10 @@ _dbus_verbose_bytes (const unsigned char *data,
           if (i > 7 &&
               _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
             {
-#ifdef DBUS_HAVE_INT64
-              /* I think I probably mean "GNU libc printf" and not "GNUC"
-               * but we'll wait until someone complains. If you hit this,
-               * just turn off verbose mode as a workaround.
-               */
-#if __GNUC__
-              _dbus_verbose (" u64: 0x%llx",
+#ifdef DBUS_INT64_PRINTF_MODIFIER
+              _dbus_verbose (" u64: 0x%" DBUS_INT64_PRINTF_MODIFIER "x",
                              *(dbus_uint64_t*)&data[i-8]);
 #endif
-#endif
               _dbus_verbose (" dbl: %g",
                              *(double*)&data[i-8]);
             }
@@ -1532,6 +1500,55 @@ _dbus_first_type_in_signature_c_str (const char       *str,
 #include "dbus-test.h"
 #include <stdio.h>
 
+/**
+ * Reads a block of fixed-length basic values, as an optimization
+ * vs. reading each one individually into a new buffer.
+ *
+ * This function returns the data in-place; it does not make a copy,
+ * and it does not swap the bytes.
+ *
+ * If you ask for #DBUS_TYPE_DOUBLE you will get a "const double*" back
+ * and the "value" argument should be a "const double**" and so on.
+ *
+ * @param str the string to read from
+ * @param pos position to read from
+ * @param element_type type of array elements
+ * @param value place to return the array
+ * @param n_elements number of array elements to read
+ * @param byte_order the byte order, used to read the array length
+ * @param new_pos #NULL or location to store a position after the elements
+ */
+void
+_dbus_marshal_read_fixed_multi  (const DBusString *str,
+                                 int               pos,
+                                 int               element_type,
+                                 void             *value,
+                                 int               n_elements,
+                                 int               byte_order,
+                                 int              *new_pos)
+{
+  int array_len;
+  int alignment;
+
+  _dbus_assert (dbus_type_is_fixed (element_type));
+  _dbus_assert (dbus_type_is_basic (element_type));
+
+#if 0
+  _dbus_verbose ("reading %d elements of %s\n",
+                 n_elements, _dbus_type_to_string (element_type));
+#endif
+  
+  alignment = _dbus_type_get_alignment (element_type);
+
+  pos = _DBUS_ALIGN_VALUE (pos, alignment);
+  
+  array_len = n_elements * alignment;
+
+  *(const DBusBasicValue**) value = (void*) _dbus_string_get_const_data_len (str, pos, array_len);
+  if (new_pos)
+    *new_pos = pos + array_len;
+}
+
 static void
 swap_test_array (void *array,
                  int   len_bytes,
@@ -1663,7 +1680,6 @@ _dbus_marshal_test (void)
   dbus_uint16_t *v_ARRAY_UINT16;
   dbus_int32_t *v_ARRAY_INT32;
   dbus_uint32_t *v_ARRAY_UINT32;
-  double *v_ARRAY_DOUBLE;
   DBusString t;
   double v_DOUBLE;
   double t_DOUBLE;