00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "dbus-marshal-byteswap.h"
00025 #include "dbus-marshal-basic.h"
00026 #include "dbus-signature.h"
00027
00033 static void
00034 byteswap_body_helper (DBusTypeReader *reader,
00035 dbus_bool_t walk_reader_to_end,
00036 int old_byte_order,
00037 int new_byte_order,
00038 unsigned char *p,
00039 unsigned char **new_p)
00040 {
00041 int current_type;
00042
00043 while ((current_type = _dbus_type_reader_get_current_type (reader)) != DBUS_TYPE_INVALID)
00044 {
00045 switch (current_type)
00046 {
00047 case DBUS_TYPE_BYTE:
00048 ++p;
00049 break;
00050
00051 case DBUS_TYPE_INT16:
00052 case DBUS_TYPE_UINT16:
00053 {
00054 p = _DBUS_ALIGN_ADDRESS (p, 2);
00055 *((dbus_uint16_t*)p) = DBUS_UINT16_SWAP_LE_BE (*((dbus_uint16_t*)p));
00056 p += 2;
00057 }
00058 break;
00059
00060 case DBUS_TYPE_BOOLEAN:
00061 case DBUS_TYPE_INT32:
00062 case DBUS_TYPE_UINT32:
00063 {
00064 p = _DBUS_ALIGN_ADDRESS (p, 4);
00065 *((dbus_uint32_t*)p) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)p));
00066 p += 4;
00067 }
00068 break;
00069
00070 case DBUS_TYPE_INT64:
00071 case DBUS_TYPE_UINT64:
00072 case DBUS_TYPE_DOUBLE:
00073 {
00074 p = _DBUS_ALIGN_ADDRESS (p, 8);
00075 #ifdef DBUS_HAVE_INT64
00076 *((dbus_uint64_t*)p) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)p));
00077 #else
00078 _dbus_swap_array (p, 1, 8);
00079 #endif
00080 p += 8;
00081 }
00082 break;
00083
00084 case DBUS_TYPE_ARRAY:
00085 case DBUS_TYPE_STRING:
00086 case DBUS_TYPE_OBJECT_PATH:
00087 {
00088 dbus_uint32_t array_len;
00089
00090 p = _DBUS_ALIGN_ADDRESS (p, 4);
00091
00092 array_len = _dbus_unpack_uint32 (old_byte_order, p);
00093
00094 *((dbus_uint32_t*)p) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)p));
00095 p += 4;
00096
00097 if (current_type == DBUS_TYPE_ARRAY)
00098 {
00099 int elem_type;
00100 int alignment;
00101
00102 elem_type = _dbus_type_reader_get_element_type (reader);
00103 alignment = _dbus_type_get_alignment (elem_type);
00104
00105 _dbus_assert ((array_len / alignment) < DBUS_MAXIMUM_ARRAY_LENGTH);
00106
00107 p = _DBUS_ALIGN_ADDRESS (p, alignment);
00108
00109 if (dbus_type_is_fixed (elem_type))
00110 {
00111 if (alignment > 1)
00112 _dbus_swap_array (p, array_len / alignment, alignment);
00113 p += array_len;
00114 }
00115 else
00116 {
00117 DBusTypeReader sub;
00118 const unsigned char *array_end;
00119
00120 array_end = p + array_len;
00121
00122 _dbus_type_reader_recurse (reader, &sub);
00123
00124 while (p < array_end)
00125 {
00126 byteswap_body_helper (&sub,
00127 FALSE,
00128 old_byte_order,
00129 new_byte_order,
00130 p, &p);
00131 }
00132 }
00133 }
00134 else
00135 {
00136 _dbus_assert (current_type == DBUS_TYPE_STRING ||
00137 current_type == DBUS_TYPE_OBJECT_PATH);
00138
00139 p += (array_len + 1);
00140 }
00141 }
00142 break;
00143
00144 case DBUS_TYPE_SIGNATURE:
00145 {
00146 dbus_uint32_t sig_len;
00147
00148 sig_len = *p;
00149
00150 p += (sig_len + 2);
00151 }
00152 break;
00153
00154 case DBUS_TYPE_VARIANT:
00155 {
00156
00157
00158
00159 dbus_uint32_t sig_len;
00160 DBusString sig;
00161 DBusTypeReader sub;
00162 int contained_alignment;
00163
00164 sig_len = *p;
00165 ++p;
00166
00167 _dbus_string_init_const_len (&sig, p, sig_len);
00168
00169 p += (sig_len + 1);
00170
00171 contained_alignment = _dbus_type_get_alignment (_dbus_first_type_in_signature (&sig, 0));
00172
00173 p = _DBUS_ALIGN_ADDRESS (p, contained_alignment);
00174
00175 _dbus_type_reader_init_types_only (&sub, &sig, 0);
00176
00177 byteswap_body_helper (&sub, FALSE, old_byte_order, new_byte_order, p, &p);
00178 }
00179 break;
00180
00181 case DBUS_TYPE_STRUCT:
00182 case DBUS_TYPE_DICT_ENTRY:
00183 {
00184 DBusTypeReader sub;
00185
00186 p = _DBUS_ALIGN_ADDRESS (p, 8);
00187
00188 _dbus_type_reader_recurse (reader, &sub);
00189
00190 byteswap_body_helper (&sub, TRUE, old_byte_order, new_byte_order, p, &p);
00191 }
00192 break;
00193
00194 default:
00195 _dbus_assert_not_reached ("invalid typecode in supposedly-validated signature");
00196 break;
00197 }
00198
00199 if (walk_reader_to_end)
00200 _dbus_type_reader_next (reader);
00201 else
00202 break;
00203 }
00204
00205 if (new_p)
00206 *new_p = p;
00207 }
00208
00219 void
00220 _dbus_marshal_byteswap (const DBusString *signature,
00221 int signature_start,
00222 int old_byte_order,
00223 int new_byte_order,
00224 DBusString *value_str,
00225 int value_pos)
00226 {
00227 DBusTypeReader reader;
00228
00229 _dbus_assert (value_pos >= 0);
00230 _dbus_assert (value_pos <= _dbus_string_get_length (value_str));
00231
00232 if (old_byte_order == new_byte_order)
00233 return;
00234
00235 _dbus_type_reader_init_types_only (&reader,
00236 signature, signature_start);
00237
00238 byteswap_body_helper (&reader, TRUE,
00239 old_byte_order, new_byte_order,
00240 _dbus_string_get_data_len (value_str, value_pos, 0),
00241 NULL);
00242 }
00243
00246