1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24: #include "dbus-marshal-byteswap.h"
25: #include "dbus-marshal-basic.h"
26: #include "dbus-signature.h"
27:
28:
29:
30:
31:
32:
33: static void
34: byteswap_body_helper (DBusTypeReader *reader,
35: dbus_bool_t walk_reader_to_end,
36: int old_byte_order,
37: int new_byte_order,
38: unsigned char *p,
39: unsigned char **new_p)
40: {
41: int current_type;
42:
43: while ((current_type = _dbus_type_reader_get_current_type (reader)) != DBUS_TYPE_INVALID)
44: {
45: switch (current_type)
46: {
47: case DBUS_TYPE_BYTE:
48: ++p;
49: break;
50:
51: case DBUS_TYPE_INT16:
52: case DBUS_TYPE_UINT16:
53: {
54: p = _DBUS_ALIGN_ADDRESS (p, 2);
55: *((dbus_uint16_t*)p) = DBUS_UINT16_SWAP_LE_BE (*((dbus_uint16_t*)p));
56: p += 2;
57: }
58: break;
59:
60: case DBUS_TYPE_BOOLEAN:
61: case DBUS_TYPE_INT32:
62: case DBUS_TYPE_UINT32:
63: {
64: p = _DBUS_ALIGN_ADDRESS (p, 4);
65: *((dbus_uint32_t*)p) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)p));
66: p += 4;
67: }
68: break;
69:
70: case DBUS_TYPE_INT64:
71: case DBUS_TYPE_UINT64:
72: case DBUS_TYPE_DOUBLE:
73: {
74: p = _DBUS_ALIGN_ADDRESS (p, 8);
75: #ifdef DBUS_HAVE_INT64
76: *((dbus_uint64_t*)p) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)p));
77: #else
78: _dbus_swap_array (p, 1, 8);
79: #endif
80: p += 8;
81: }
82: break;
83:
84: case DBUS_TYPE_ARRAY:
85: case DBUS_TYPE_STRING:
86: case DBUS_TYPE_OBJECT_PATH:
87: {
88: dbus_uint32_t array_len;
89:
90: p = _DBUS_ALIGN_ADDRESS (p, 4);
91:
92: array_len = _dbus_unpack_uint32 (old_byte_order, p);
93:
94: *((dbus_uint32_t*)p) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)p));
95: p += 4;
96:
97: if (current_type == DBUS_TYPE_ARRAY)
98: {
99: int elem_type;
100: int alignment;
101:
102: elem_type = _dbus_type_reader_get_element_type (reader);
103: alignment = _dbus_type_get_alignment (elem_type);
104:
105: _dbus_assert ((array_len / alignment) < DBUS_MAXIMUM_ARRAY_LENGTH);
106:
107: p = _DBUS_ALIGN_ADDRESS (p, alignment);
108:
109: if (dbus_type_is_fixed (elem_type))
110: {
111: if (alignment > 1)
112: _dbus_swap_array (p, array_len / alignment, alignment);
113: p += array_len;
114: }
115: else
116: {
117: DBusTypeReader sub;
118: const unsigned char *array_end;
119:
120: array_end = p + array_len;
121:
122: _dbus_type_reader_recurse (reader, &sub);
123:
124: while (p < array_end)
125: {
126: byteswap_body_helper (&sub,
127: FALSE,
128: old_byte_order,
129: new_byte_order,
130: p, &p);
131: }
132: }
133: }
134: else
135: {
136: _dbus_assert (current_type == DBUS_TYPE_STRING ||
137: current_type == DBUS_TYPE_OBJECT_PATH);
138:
139: p += (array_len + 1);
140: }
141: }
142: break;
143:
144: case DBUS_TYPE_SIGNATURE:
145: {
146: dbus_uint32_t sig_len;
147:
148: sig_len = *p;
149:
150: p += (sig_len + 2);
151: }
152: break;
153:
154: case DBUS_TYPE_VARIANT:
155: {
156:
157:
158:
159: dbus_uint32_t sig_len;
160: DBusString sig;
161: DBusTypeReader sub;
162: int contained_alignment;
163:
164: sig_len = *p;
165: ++p;
166:
167: _dbus_string_init_const_len (&sig, p, sig_len);
168:
169: p += (sig_len + 1);
170:
171: contained_alignment = _dbus_type_get_alignment (_dbus_first_type_in_signature (&sig, 0));
172:
173: p = _DBUS_ALIGN_ADDRESS (p, contained_alignment);
174:
175: _dbus_type_reader_init_types_only (&sub, &sig, 0);
176:
177: byteswap_body_helper (&sub, FALSE, old_byte_order, new_byte_order, p, &p);
178: }
179: break;
180:
181: case DBUS_TYPE_STRUCT:
182: case DBUS_TYPE_DICT_ENTRY:
183: {
184: DBusTypeReader sub;
185:
186: p = _DBUS_ALIGN_ADDRESS (p, 8);
187:
188: _dbus_type_reader_recurse (reader, &sub);
189:
190: byteswap_body_helper (&sub, TRUE, old_byte_order, new_byte_order, p, &p);
191: }
192: break;
193:
194: default:
195: _dbus_assert_not_reached ("invalid typecode in supposedly-validated signature");
196: break;
197: }
198:
199: if (walk_reader_to_end)
200: _dbus_type_reader_next (reader);
201: else
202: break;
203: }
204:
205: if (new_p)
206: *new_p = p;
207: }
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219: void
220: _dbus_marshal_byteswap (const DBusString *signature,
221: int signature_start,
222: int old_byte_order,
223: int new_byte_order,
224: DBusString *value_str,
225: int value_pos)
226: {
227: DBusTypeReader reader;
228:
229: _dbus_assert (value_pos >= 0);
230: _dbus_assert (value_pos <= _dbus_string_get_length (value_str));
231:
232: if (old_byte_order == new_byte_order)
233: return;
234:
235: _dbus_type_reader_init_types_only (&reader,
236: signature, signature_start);
237:
238: byteswap_body_helper (&reader, TRUE,
239: old_byte_order, new_byte_order,
240: _dbus_string_get_data_len (value_str, value_pos, 0),
241: NULL);
242: }
243:
244:
245:
246: