2005-01-27 Havoc Pennington <hp@redhat.com>
authorHavoc Pennington <hp@redhat.com>
Thu, 27 Jan 2005 23:39:26 +0000 (23:39 +0000)
committerHavoc Pennington <hp@redhat.com>
Thu, 27 Jan 2005 23:39:26 +0000 (23:39 +0000)
        * dbus/dbus-message.c: byteswap the message if you init an
iterator to read/write from it

* dbus/dbus-marshal-byteswap.c: new file implementing
_dbus_marshal_byteswap()

* dbus/dbus-marshal-basic.c: add _dbus_swap_array()

16 files changed:
ChangeLog
dbus/Makefile.am
dbus/dbus-marshal-basic.c
dbus/dbus-marshal-basic.h
dbus/dbus-marshal-byteswap-util.c [new file with mode: 0644]
dbus/dbus-marshal-byteswap.c [new file with mode: 0644]
dbus/dbus-marshal-byteswap.h [new file with mode: 0644]
dbus/dbus-marshal-header.c
dbus/dbus-marshal-header.h
dbus/dbus-marshal-recursive-util.c
dbus/dbus-marshal-recursive.h
dbus/dbus-marshal-validate.c
dbus/dbus-marshal-validate.h
dbus/dbus-message.c
dbus/dbus-test.c
dbus/dbus-test.h

index 3a11130..c1d2465 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2005-01-27  Havoc Pennington  <hp@redhat.com>
+
+        * dbus/dbus-message.c: byteswap the message if you init an
+       iterator to read/write from it
+       
+       * dbus/dbus-marshal-byteswap.c: new file implementing 
+       _dbus_marshal_byteswap()
+
+       * dbus/dbus-marshal-basic.c: add _dbus_swap_array()
+
 2005-01-26  Havoc Pennington  <hp@redhat.com>
        
        * dbus/dbus-marshal-validate-util.c: break this out (and fix
index 36a6ec8..2d08be6 100644 (file)
@@ -56,6 +56,8 @@ DBUS_LIB_SOURCES=                             \
        dbus-keyring.h                          \
        dbus-marshal-header.c                   \
        dbus-marshal-header.h                   \
+       dbus-marshal-byteswap.c                 \
+       dbus-marshal-byteswap.h                 \
        dbus-marshal-recursive.c                \
        dbus-marshal-recursive.h                \
        dbus-marshal-validate.c                 \
@@ -125,6 +127,7 @@ DBUS_UTIL_SOURCES=                          \
        dbus-auth-util.c                        \
        dbus-mainloop.c                         \
        dbus-mainloop.h                         \
+       dbus-marshal-byteswap-util.c            \
        dbus-marshal-recursive-util.c           \
        dbus-marshal-validate-util.c            \
        dbus-message-factory.c                  \
index 5cb43b8..cd5d4e4 100644 (file)
@@ -820,6 +820,53 @@ marshal_1_octets_array (DBusString          *str,
   return TRUE;
 }
 
+/**
+ * Swaps the elements of an array to the opposite byte order
+ *
+ * @param data start of array
+ * @param n_elements number of elements
+ * @param alignment size of each element
+ */
+void
+_dbus_swap_array (unsigned char *data,
+                  int            n_elements,
+                  int            alignment)
+{
+  unsigned char *d;
+  unsigned char *end;
+
+  _dbus_assert (_DBUS_ALIGN_ADDRESS (data, alignment) == data);
+
+  /* we use const_data and cast it off so DBusString can be a const string
+   * for the unit tests. don't ask.
+   */
+  d = data;
+  end = d + (n_elements * alignment);
+  
+  if (alignment == 8)
+    {
+      while (d != end)
+        {
+#ifdef DBUS_HAVE_INT64
+          *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d));
+#else
+          swap_8_bytes ((DBusBasicValue*) d);
+#endif
+          d += 8;
+        }
+    }
+  else
+    {
+      _dbus_assert (alignment == 4);
+      
+      while (d != end)
+        {
+          *((dbus_uint32_t*)d) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)d));
+          d += 4;
+        }
+    }
+}
+
 static void
 swap_array (DBusString *str,
             int         array_start,
@@ -831,37 +878,11 @@ swap_array (DBusString *str,
 
   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
     {
-      unsigned char *d;
-      unsigned char *end;
-
       /* we use const_data and cast it off so DBusString can be a const string
        * for the unit tests. don't ask.
        */
-      d = (unsigned char*) _dbus_string_get_const_data (str) + array_start;
-      end = d + n_elements * alignment;
-
-      if (alignment == 8)
-        {
-          while (d != end)
-            {
-#ifdef DBUS_HAVE_INT64
-              *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d));
-#else
-              swap_8_bytes ((DBusBasicValue*) d);
-#endif
-              d += 8;
-            }
-        }
-      else
-        {
-          _dbus_assert (alignment == 4);
-
-          while (d != end)
-            {
-              *((dbus_uint32_t*)d) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)d));
-              d += 4;
-            }
-        }
+      _dbus_swap_array ((unsigned char*) (_dbus_string_get_const_data (str) + array_start),
+                        n_elements, alignment);
     }
 }
 
index d8ded1c..375f2a3 100644 (file)
@@ -218,4 +218,8 @@ const char*   _dbus_type_to_string            (int               typecode);
 int           _dbus_first_type_in_signature   (const DBusString *str,
                                                int               pos);
 
+void _dbus_swap_array (unsigned char *data,
+                       int            n_elements,
+                       int            alignment);
+
 #endif /* DBUS_MARSHAL_BASIC_H */
diff --git a/dbus/dbus-marshal-byteswap-util.c b/dbus/dbus-marshal-byteswap-util.c
new file mode 100644 (file)
index 0000000..eeea539
--- /dev/null
@@ -0,0 +1,105 @@
+/* -*- mode: C; c-file-style: "gnu" -*- */
+/* dbus-marshal-byteswap-util.c  Would be in dbus-marshal-byteswap.c but tests/bus only
+ *
+ * Copyright (C) 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
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * 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
+ *
+ */
+
+#include <config.h>
+
+#ifdef DBUS_BUILD_TESTS 
+#include "dbus-marshal-byteswap.h"
+#include "dbus-test.h"
+#include <stdio.h>
+
+static void
+do_byteswap_test (int byte_order)
+{
+  int sequence;
+  DBusString signature;
+  DBusString body;
+  int opposite_order;
+
+  if (!_dbus_string_init (&signature) || !_dbus_string_init (&body))
+    _dbus_assert_not_reached ("oom");
+
+  opposite_order = byte_order == DBUS_LITTLE_ENDIAN ? DBUS_BIG_ENDIAN : DBUS_LITTLE_ENDIAN;
+  
+  sequence = 0;
+  while (dbus_internal_do_not_use_generate_bodies (sequence,
+                                                   byte_order,
+                                                   &signature, &body))
+    {
+      DBusString copy;
+      DBusTypeReader body_reader;
+      DBusTypeReader copy_reader;
+
+      if (!_dbus_string_init (&copy))
+        _dbus_assert_not_reached ("oom");
+
+      if (!_dbus_string_copy (&body, 0, &copy, 0))
+        _dbus_assert_not_reached ("oom");
+
+      _dbus_marshal_byteswap (&signature, 0,
+                              byte_order,
+                              opposite_order,
+                              &copy, 0);
+
+      _dbus_type_reader_init (&body_reader, byte_order, &signature, 0,
+                              &body, 0);
+      _dbus_type_reader_init (&copy_reader, opposite_order, &signature, 0,
+                              &copy, 0);
+      
+      if (!_dbus_type_reader_equal_values (&body_reader, &copy_reader))
+        {
+          _dbus_verbose_bytes_of_string (&signature, 0,
+                                         _dbus_string_get_length (&signature));
+          _dbus_verbose_bytes_of_string (&body, 0,
+                                         _dbus_string_get_length (&body));
+          _dbus_verbose_bytes_of_string (&copy, 0,
+                                         _dbus_string_get_length (&copy));
+
+          _dbus_warn ("Byte-swapped data did not have same values as original data\n");
+          _dbus_assert_not_reached ("test failed");
+        }
+      
+      _dbus_string_free (&copy);
+      
+      _dbus_string_set_length (&signature, 0);
+      _dbus_string_set_length (&body, 0);
+      ++sequence;
+    }
+
+  _dbus_string_free (&signature);
+  _dbus_string_free (&body);
+
+  printf ("  %d blocks swapped from order '%c' to '%c'\n",
+          sequence, byte_order, opposite_order);
+}
+
+dbus_bool_t
+_dbus_marshal_byteswap_test (void)
+{
+  do_byteswap_test (DBUS_LITTLE_ENDIAN);
+  do_byteswap_test (DBUS_BIG_ENDIAN);
+
+  return TRUE;
+}
+
+#endif /* DBUS_BUILD_TESTS */
diff --git a/dbus/dbus-marshal-byteswap.c b/dbus/dbus-marshal-byteswap.c
new file mode 100644 (file)
index 0000000..434d7e4
--- /dev/null
@@ -0,0 +1,232 @@
+/* -*- mode: C; c-file-style: "gnu" -*- */
+/* dbus-marshal-byteswap.c  Swap a block of marshaled data
+ *
+ * Copyright (C) 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
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * 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
+ *
+ */
+
+#include "dbus-marshal-byteswap.h"
+#include "dbus-marshal-basic.h"
+
+/**
+ * @addtogroup DBusMarshal
+ * @{
+ */
+
+static void
+byteswap_body_helper (DBusTypeReader       *reader,
+                      dbus_bool_t           walk_reader_to_end,
+                      int                   old_byte_order,
+                      int                   new_byte_order,
+                      unsigned char        *p,
+                      unsigned char       **new_p)
+{
+  int current_type;
+
+  while ((current_type = _dbus_type_reader_get_current_type (reader)) != DBUS_TYPE_INVALID)
+    {
+      switch (current_type)
+        {
+        case DBUS_TYPE_BYTE:
+          ++p;
+          break;
+
+        case DBUS_TYPE_BOOLEAN:
+        case DBUS_TYPE_INT32:
+        case DBUS_TYPE_UINT32:
+          {
+            p = _DBUS_ALIGN_ADDRESS (p, 4);
+            *((dbus_uint32_t*)p) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)p));
+            p += 4;
+          }
+          break;
+          
+        case DBUS_TYPE_INT64:
+        case DBUS_TYPE_UINT64:
+        case DBUS_TYPE_DOUBLE:
+          {
+            p = _DBUS_ALIGN_ADDRESS (p, 8);
+#ifdef DBUS_HAVE_INT64
+            *((dbus_uint64_t*)p) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)p));
+#else
+            _dbus_swap_array (p, 1, 8);
+#endif
+            p += 8;
+          }
+          break;
+
+        case DBUS_TYPE_ARRAY:
+        case DBUS_TYPE_STRING:
+        case DBUS_TYPE_OBJECT_PATH:
+          {
+            dbus_uint32_t array_len;
+            
+            p = _DBUS_ALIGN_ADDRESS (p, 4);
+
+            array_len = _dbus_unpack_uint32 (old_byte_order, p);
+            
+            *((dbus_uint32_t*)p) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)p));
+            p += 4;
+
+            if (current_type == DBUS_TYPE_ARRAY)
+              {
+                int elem_type;
+                int alignment;
+
+                elem_type = _dbus_type_reader_get_element_type (reader);
+                alignment = _dbus_type_get_alignment (elem_type);
+
+                p = _DBUS_ALIGN_ADDRESS (p, alignment);
+                
+                if (_dbus_type_is_fixed (elem_type))
+                  {
+                    if (alignment > 1)
+                      _dbus_swap_array (p, array_len / alignment, alignment);
+                  }
+                else
+                  {
+                    DBusTypeReader sub;
+                    const unsigned char *array_end;
+
+                    array_end = p + array_len;
+                    
+                    _dbus_type_reader_recurse (reader, &sub);
+
+                    while (p < array_end)
+                      {
+                        byteswap_body_helper (&sub,
+                                              FALSE,
+                                              old_byte_order,
+                                              new_byte_order,
+                                              p, &p);
+                      }
+                  }
+              }
+            else
+              {
+                _dbus_assert (current_type == DBUS_TYPE_STRING ||
+                              current_type == DBUS_TYPE_OBJECT_PATH);
+                
+                p += (array_len + 1); /* + 1 for nul */
+              }
+          }
+          break;
+
+        case DBUS_TYPE_SIGNATURE:
+          {
+            dbus_uint32_t sig_len;
+
+            sig_len = *p;
+            
+            p += (sig_len + 2); /* +2 for len and nul */
+          }
+          break;
+
+        case DBUS_TYPE_VARIANT:
+          {
+            /* 1 byte sig len, sig typecodes, align to
+             * contained-type-boundary, values.
+             */
+            dbus_uint32_t sig_len;
+            DBusString sig;
+            DBusTypeReader sub;
+            int contained_alignment;
+
+            sig_len = *p;
+            ++p;
+
+            _dbus_string_init_const_len (&sig, p, sig_len);
+
+            p += (sig_len + 1); /* 1 for nul */
+
+            contained_alignment = _dbus_type_get_alignment (_dbus_first_type_in_signature (&sig, 0));
+            
+            p = _DBUS_ALIGN_ADDRESS (p, contained_alignment);
+
+            _dbus_type_reader_init_types_only (&sub, &sig, 0);
+
+            byteswap_body_helper (&sub, FALSE, old_byte_order, new_byte_order, p, &p);
+          }
+          break;
+
+        case DBUS_TYPE_STRUCT:
+          {
+            DBusTypeReader sub;
+
+            p = _DBUS_ALIGN_ADDRESS (p, 8);
+            
+            _dbus_type_reader_recurse (reader, &sub);
+            
+            byteswap_body_helper (&sub, TRUE, old_byte_order, new_byte_order, p, &p);
+          }
+          break;
+
+        default:
+          _dbus_assert_not_reached ("invalid typecode in supposedly-validated signature");
+          break;
+        }
+
+      if (walk_reader_to_end)
+        _dbus_type_reader_next (reader);
+      else
+        break;
+    }
+
+  if (new_p)
+    *new_p = p;
+}
+
+/**
+ * Byteswaps the marshaled data in the given value_str.
+ *
+ * @param signature the types in the value_str
+ * @param signature_start where in signature is the signature
+ * @param old_byte_order the old byte order
+ * @param new_byte_order the new byte order
+ * @param value_str the string containing the body
+ * @param value_pos where the values start
+ */
+void
+_dbus_marshal_byteswap (const DBusString *signature,
+                        int               signature_start,
+                        int               old_byte_order,
+                        int               new_byte_order,
+                        DBusString       *value_str,
+                        int               value_pos)
+{
+  DBusTypeReader reader;
+
+  _dbus_assert (value_pos >= 0);
+  _dbus_assert (value_pos <= _dbus_string_get_length (value_str));
+
+  if (old_byte_order == new_byte_order)
+    return;
+  
+  _dbus_type_reader_init_types_only (&reader,
+                                     signature, signature_start);
+
+  byteswap_body_helper (&reader, TRUE,
+                        old_byte_order, new_byte_order,
+                        _dbus_string_get_data_len (value_str, value_pos, 0),
+                        NULL);
+}
+
+/** @} */
+
+/* Tests in dbus-marshal-byteswap-util.c */
diff --git a/dbus/dbus-marshal-byteswap.h b/dbus/dbus-marshal-byteswap.h
new file mode 100644 (file)
index 0000000..e33cd74
--- /dev/null
@@ -0,0 +1,42 @@
+/* -*- mode: C; c-file-style: "gnu" -*- */
+/* dbus-marshal-byteswap.h  Swap a block of marshaled data
+ *
+ * Copyright (C) 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
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * 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
+ *
+ */
+
+#ifndef DBUS_MARSHAL_BYTESWAP_H
+#define DBUS_MARSHAL_BYTESWAP_H
+
+#include <config.h>
+#include <dbus/dbus-protocol.h>
+#include <dbus/dbus-marshal-recursive.h>
+
+#ifndef PACKAGE
+#error "config.h not included here"
+#endif
+
+void _dbus_marshal_byteswap (const DBusString *signature,
+                             int               signature_start,
+                             int               old_byte_order,
+                             int               new_byte_order,
+                             DBusString       *value_str,
+                             int               value_pos);
+
+#endif /* DBUS_MARSHAL_BYTESWAP_H */
index 6102b6f..b5a8d3d 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "dbus-marshal-header.h"
 #include "dbus-marshal-recursive.h"
+#include "dbus-marshal-byteswap.h"
 
 /**
  * @addtogroup DBusMarshal
@@ -1448,6 +1449,27 @@ _dbus_header_get_flag (DBusHeader   *header,
   return (*flags_p & flag) != 0;
 }
 
+/**
+ * Swaps the header into the given order if required.
+ *
+ * @param header the header
+ * @param new_order the new byte order
+ */
+void
+_dbus_header_byteswap (DBusHeader *header,
+                       int         new_order)
+{
+  if (header->byte_order == new_order)
+    return;
+
+  _dbus_marshal_byteswap (&_dbus_header_signature_str,
+                          0, header->byte_order,
+                          new_order,
+                          &header->data, 0);
+
+  header->byte_order = new_order;
+}
+
 /** @} */
 
 #ifdef DBUS_BUILD_TESTS
index fed2888..837c937 100644 (file)
@@ -125,7 +125,8 @@ dbus_bool_t   _dbus_header_load                   (DBusHeader        *header,
                                                    const DBusString  *str,
                                                    int                start,
                                                    int                len);
-
+void          _dbus_header_byteswap               (DBusHeader        *header,
+                                                   int                new_order);
 
 
 
index 493672b..08d030a 100644 (file)
  *
  */
 
+#include <config.h>
+
+#ifdef DBUS_BUILD_TESTS
+
 #include "dbus-marshal-recursive.h"
 #include "dbus-marshal-basic.h"
 #include "dbus-internals.h"
+#include <string.h>
 
-#ifdef DBUS_BUILD_TESTS
+static void
+basic_value_zero (DBusBasicValue *value)
+{
+
+#ifdef DBUS_HAVE_INT64
+  value->u64 = 0;
+#else
+  value->u64.first32 = 0;
+  value->u64.second32 = 0;
+#endif
+}
+
+static dbus_bool_t
+basic_value_equal (int             type,
+                   DBusBasicValue *lhs,
+                   DBusBasicValue *rhs)
+{
+  if (type == DBUS_TYPE_STRING ||
+      type == DBUS_TYPE_SIGNATURE ||
+      type == DBUS_TYPE_OBJECT_PATH)
+    {
+      return strcmp (lhs->str, rhs->str) == 0;
+    }
+  else
+    {
+#ifdef DBUS_HAVE_INT64
+      return lhs->u64 == rhs->u64;
+#else
+      return lhs->u64.first32 == rhs->u64.first32 &&
+        lhs->u64.second32 == rhs->u64.second32;
+#endif
+    }
+}
+
+static dbus_bool_t
+equal_values_helper (DBusTypeReader *lhs,
+                     DBusTypeReader *rhs)
+{
+  int lhs_type;
+  int rhs_type;
+
+  lhs_type = _dbus_type_reader_get_current_type (lhs);
+  rhs_type = _dbus_type_reader_get_current_type (rhs);
+
+  if (lhs_type != rhs_type)
+    return FALSE;
+
+  if (lhs_type == DBUS_TYPE_INVALID)
+    return TRUE;
+
+  if (_dbus_type_is_basic (lhs_type))
+    {
+      DBusBasicValue lhs_value;
+      DBusBasicValue rhs_value;
+
+      basic_value_zero (&lhs_value);
+      basic_value_zero (&rhs_value);
+      
+      _dbus_type_reader_read_basic (lhs, &lhs_value);
+      _dbus_type_reader_read_basic (rhs, &rhs_value);
+
+      return basic_value_equal (lhs_type, &lhs_value, &rhs_value);
+    }
+  else
+    {
+      DBusTypeReader lhs_sub;
+      DBusTypeReader rhs_sub;
+
+      _dbus_type_reader_recurse (lhs, &lhs_sub);
+      _dbus_type_reader_recurse (rhs, &rhs_sub);
+
+      return equal_values_helper (&lhs_sub, &rhs_sub);
+    }
+}
+
+/**
+ * See whether the two readers point to identical data blocks.
+ *
+ * @param lhs reader 1
+ * @param rhs reader 2
+ * @returns #TRUE if the data blocks have the same values
+ */
+dbus_bool_t
+_dbus_type_reader_equal_values (const DBusTypeReader *lhs,
+                                const DBusTypeReader *rhs)
+{
+  DBusTypeReader copy_lhs = *lhs;
+  DBusTypeReader copy_rhs = *rhs;
+
+  return equal_values_helper (&copy_lhs, &copy_rhs);
+}
+
+/* TESTS */
 #include "dbus-test.h"
 #include "dbus-list.h"
 #include <stdio.h>
index 2e8317f..45deeb5 100644 (file)
@@ -27,7 +27,6 @@
 #include <config.h>
 #include <dbus/dbus-protocol.h>
 #include <dbus/dbus-list.h>
-#include <dbus/dbus-marshal-basic.h> /* this can vanish when we merge */
 
 #ifndef PACKAGE
 #error "config.h not included here"
@@ -168,6 +167,9 @@ dbus_bool_t _dbus_type_reader_delete                    (DBusTypeReader        *
 dbus_bool_t _dbus_type_reader_greater_than              (const DBusTypeReader  *lhs,
                                                          const DBusTypeReader  *rhs);
 
+dbus_bool_t _dbus_type_reader_equal_values              (const DBusTypeReader *lhs,
+                                                         const DBusTypeReader *rhs);
+
 void        _dbus_type_writer_init                 (DBusTypeWriter        *writer,
                                                     int                    byte_order,
                                                     DBusString            *type_str,
index e06add5..f15d281 100644 (file)
@@ -24,6 +24,8 @@
 #include "dbus-internals.h"
 #include "dbus-marshal-validate.h"
 #include "dbus-marshal-recursive.h"
+#include "dbus-marshal-basic.h"
+#include "dbus-string.h"
 
 /**
  * @addtogroup DBusMarshal
@@ -254,6 +256,11 @@ validate_body_helper (DBusTypeReader       *reader,
 
                 while (p < array_end)
                   {
+                    /* FIXME we are calling a function per array element! very bad
+                     * need if (dbus_type_is_fixed(elem_type)) here to just skip
+                     * big blocks of ints/bytes/etc.
+                     */                     
+                    
                     validity = validate_body_helper (&sub, byte_order, FALSE, p, end, &p);
                     if (validity != DBUS_VALID)
                       return validity;
index 195f46d..94b7798 100644 (file)
@@ -25,7 +25,6 @@
 #define DBUS_MARSHAL_VALIDATE_H
 
 #include <config.h>
-#include <dbus/dbus-marshal-basic.h>
 
 #ifndef PACKAGE
 #error "config.h not included here"
index cf15109..38ae317 100644 (file)
@@ -25,6 +25,7 @@
 #include "dbus-internals.h"
 #include "dbus-marshal-recursive.h"
 #include "dbus-marshal-validate.h"
+#include "dbus-marshal-byteswap.h"
 #include "dbus-marshal-header.h"
 #include "dbus-message-private.h"
 #include "dbus-object-tree.h"
@@ -76,6 +77,57 @@ struct DBusMessageRealIter
   } u; /**< the type writer or reader that does all the work */
 };
 
+static void
+get_const_signature (DBusHeader        *header,
+                     const DBusString **type_str_p,
+                     int               *type_pos_p)
+{
+  if (_dbus_header_get_field_raw (header,
+                                  DBUS_HEADER_FIELD_SIGNATURE,
+                                  type_str_p,
+                                  type_pos_p))
+    {
+      *type_pos_p += 1; /* skip the signature length which is 1 byte */
+    }
+  else
+    {
+      *type_str_p = &_dbus_empty_signature_str;
+      *type_pos_p = 0;
+    }
+}
+
+/**
+ * Swaps the message to compiler byte order if required
+ *
+ * @param message the message
+ */
+static void
+_dbus_message_byteswap (DBusMessage *message)
+{
+  const DBusString *type_str;
+  int type_pos;
+  
+  if (message->byte_order == DBUS_COMPILER_BYTE_ORDER)
+    return;
+
+  _dbus_verbose ("Swapping message into compiler byte order\n");
+  
+  get_const_signature (&message->header, &type_str, &type_pos);
+  
+  _dbus_marshal_byteswap (type_str, type_pos,
+                          message->byte_order,
+                          DBUS_COMPILER_BYTE_ORDER,
+                          &message->body, 0);
+
+  message->byte_order = DBUS_COMPILER_BYTE_ORDER;
+  
+  _dbus_header_byteswap (&message->header, DBUS_COMPILER_BYTE_ORDER);
+}
+
+#define ensure_byte_order(message)                      \
+ if (message->byte_order != DBUS_COMPILER_BYTE_ORDER)   \
+   _dbus_message_byteswap (message)
+
 /**
  * Gets the data to be sent over the network for this message.
  * The header and then the body should be written out.
@@ -250,25 +302,6 @@ set_or_delete_string_field (DBusMessage *message,
                                          &value);
 }
 
-static void
-get_const_signature (DBusHeader        *header,
-                     const DBusString **type_str_p,
-                     int               *type_pos_p)
-{
-  if (_dbus_header_get_field_raw (header,
-                                  DBUS_HEADER_FIELD_SIGNATURE,
-                                  type_str_p,
-                                  type_pos_p))
-    {
-      *type_pos_p += 1; /* skip the signature length which is 1 byte */
-    }
-  else
-    {
-      *type_str_p = &_dbus_empty_signature_str;
-      *type_pos_p = 0;
-    }
-}
-
 #if 0
 /* Probably we don't need to use this */
 /**
@@ -1345,6 +1378,11 @@ _dbus_message_iter_init_common (DBusMessage         *message,
 {
   _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
 
+  /* Since the iterator will read or write who-knows-what from the
+   * message, we need to get in the right byte order
+   */
+  ensure_byte_order (message);
+  
   real->message = message;
   real->changed_stamp = message->changed_stamp;
   real->iter_type = iter_type;
@@ -1401,6 +1439,8 @@ _dbus_message_iter_check (DBusMessageRealIter *iter)
           _dbus_warn ("dbus message changed byte order since iterator was created\n");
           return FALSE;
         }
+      /* because we swap the message into compiler order when you init an iter */
+      _dbus_assert (iter->u.reader.byte_order == DBUS_COMPILER_BYTE_ORDER);
     }
   else if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER)
     {
@@ -1409,6 +1449,8 @@ _dbus_message_iter_check (DBusMessageRealIter *iter)
           _dbus_warn ("dbus message changed byte order since append iterator was created\n");
           return FALSE;
         }
+      /* because we swap the message into compiler order when you init an iter */
+      _dbus_assert (iter->u.writer.byte_order == DBUS_COMPILER_BYTE_ORDER);
     }
   else
     {
index 5f51832..eb2b878 100644 (file)
@@ -128,6 +128,12 @@ dbus_internal_do_not_use_run_tests (const char *test_data_dir)
   _dbus_warn ("recursive marshal tests disabled\n");
 #endif
 
+  printf ("%s: running byteswap tests\n", "dbus-test");
+  if (!_dbus_marshal_byteswap_test ())
+    die ("byteswap marshaled data");
+
+  check_memleaks ();
+  
   printf ("%s: running memory tests\n", "dbus-test");
   if (!_dbus_memory_test ())
     die ("memory");
index 9a63914..3a87afb 100644 (file)
@@ -33,6 +33,7 @@ dbus_bool_t _dbus_dict_test              (void);
 dbus_bool_t _dbus_list_test              (void);
 dbus_bool_t _dbus_marshal_test           (void);
 dbus_bool_t _dbus_marshal_recursive_test (void);
+dbus_bool_t _dbus_marshal_byteswap_test  (void);
 dbus_bool_t _dbus_marshal_header_test    (void);
 dbus_bool_t _dbus_marshal_validate_test  (void);
 dbus_bool_t _dbus_mem_pool_test          (void);