1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25: #include "dbus-internals.h"
26: #include "dbus-marshal-basic.h"
27: #include "dbus-signature.h"
28:
29: #include <string.h>
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46: static void
47: pack_2_octets (dbus_uint16_t value,
48: int byte_order,
49: unsigned char *data)
50: {
51: _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 2) == data);
52:
53: if ((byte_order) == DBUS_LITTLE_ENDIAN)
54: *((dbus_uint16_t*)(data)) = DBUS_UINT16_TO_LE (value);
55: else
56: *((dbus_uint16_t*)(data)) = DBUS_UINT16_TO_BE (value);
57: }
58:
59: static void
60: pack_4_octets (dbus_uint32_t value,
61: int byte_order,
62: unsigned char *data)
63: {
64: _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
65:
66: if ((byte_order) == DBUS_LITTLE_ENDIAN)
67: *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value);
68: else
69: *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value);
70: }
71:
72: static void
73: pack_8_octets (DBusBasicValue value,
74: int byte_order,
75: unsigned char *data)
76: {
77: _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
78:
79: #ifdef DBUS_HAVE_INT64
80: if ((byte_order) == DBUS_LITTLE_ENDIAN)
81: *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_LE (value.u64);
82: else
83: *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_BE (value.u64);
84: #else
85: *(DBus8ByteStruct*)data = value.u64;
86: swap_8_octets ((DBusBasicValue*)data, byte_order);
87: #endif
88: }
89:
90:
91:
92:
93:
94:
95:
96:
97: void
98: _dbus_pack_uint32 (dbus_uint32_t value,
99: int byte_order,
100: unsigned char *data)
101: {
102: pack_4_octets (value, byte_order, data);
103: }
104:
105: #ifndef DBUS_HAVE_INT64
106:
107: static void
108: swap_bytes (unsigned char *data,
109: unsigned int len)
110: {
111: unsigned char *p1 = data;
112: unsigned char *p2 = data + len - 1;
113:
114: while (p1 < p2)
115: {
116: unsigned char tmp = *p1;
117: *p1 = *p2;
118: *p2 = tmp;
119:
120: --p2;
121: ++p1;
122: }
123: }
124: #endif
125:
126: static void
127: swap_8_octets (DBusBasicValue *value,
128: int byte_order)
129: {
130: if (byte_order != DBUS_COMPILER_BYTE_ORDER)
131: {
132: #ifdef DBUS_HAVE_INT64
133: value->u64 = DBUS_UINT64_SWAP_LE_BE (value->u64);
134: #else
135: swap_bytes ((unsigned char *)value, 8);
136: #endif
137: }
138: }
139:
140: #if 0
141: static DBusBasicValue
142: unpack_8_octets (int byte_order,
143: const unsigned char *data)
144: {
145: DBusBasicValue r;
146:
147: _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
148: _dbus_assert (sizeof (r) == 8);
149:
150: #ifdef DBUS_HAVE_INT64
151: if (byte_order == DBUS_LITTLE_ENDIAN)
152: r.u64 = DBUS_UINT64_FROM_LE (*(dbus_uint64_t*)data);
153: else
154: r.u64 = DBUS_UINT64_FROM_BE (*(dbus_uint64_t*)data);
155: #else
156: r.u64 = *(DBus8ByteStruct*)data;
157: swap_8_octets (&r, byte_order);
158: #endif
159:
160: return r;
161: }
162: #endif
163:
164: #ifndef _dbus_unpack_uint16
165:
166:
167:
168:
169:
170:
171:
172: dbus_uint16_t
173: _dbus_unpack_uint16 (int byte_order,
174: const unsigned char *data)
175: {
176: _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 2) == data);
177:
178: if (byte_order == DBUS_LITTLE_ENDIAN)
179: return DBUS_UINT16_FROM_LE (*(dbus_uint16_t*)data);
180: else
181: return DBUS_UINT16_FROM_BE (*(dbus_uint16_t*)data);
182: }
183: #endif
184:
185: #ifndef _dbus_unpack_uint32
186:
187:
188:
189:
190:
191:
192:
193: dbus_uint32_t
194: _dbus_unpack_uint32 (int byte_order,
195: const unsigned char *data)
196: {
197: _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
198:
199: if (byte_order == DBUS_LITTLE_ENDIAN)
200: return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)data);
201: else
202: return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)data);
203: }
204: #endif
205:
206: static void
207: set_2_octets (DBusString *str,
208: int offset,
209: dbus_uint16_t value,
210: int byte_order)
211: {
212: char *data;
213:
214: _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
215: byte_order == DBUS_BIG_ENDIAN);
216:
217: data = _dbus_string_get_data_len (str, offset, 2);
218:
219: pack_2_octets (value, byte_order, data);
220: }
221:
222: static void
223: set_4_octets (DBusString *str,
224: int offset,
225: dbus_uint32_t value,
226: int byte_order)
227: {
228: char *data;
229:
230: _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
231: byte_order == DBUS_BIG_ENDIAN);
232:
233: data = _dbus_string_get_data_len (str, offset, 4);
234:
235: pack_4_octets (value, byte_order, data);
236: }
237:
238: static void
239: set_8_octets (DBusString *str,
240: int offset,
241: DBusBasicValue value,
242: int byte_order)
243: {
244: char *data;
245:
246: _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
247: byte_order == DBUS_BIG_ENDIAN);
248:
249: data = _dbus_string_get_data_len (str, offset, 8);
250:
251: pack_8_octets (value, byte_order, data);
252: }
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264: void
265: _dbus_marshal_set_uint32 (DBusString *str,
266: int pos,
267: dbus_uint32_t value,
268: int byte_order)
269: {
270: set_4_octets (str, pos, value, byte_order);
271: }
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292: static dbus_bool_t
293: set_string (DBusString *str,
294: int pos,
295: const char *value,
296: int byte_order,
297: int *old_end_pos,
298: int *new_end_pos)
299: {
300: int old_len, new_len;
301: DBusString dstr;
302:
303: _dbus_string_init_const (&dstr, value);
304:
305: _dbus_assert (_DBUS_ALIGN_VALUE (pos, 4) == (unsigned) pos);
306: old_len = _dbus_unpack_uint32 (byte_order,
307: _dbus_string_get_const_data_len (str, pos, 4));
308:
309: new_len = _dbus_string_get_length (&dstr);
310:
311: if (!_dbus_string_replace_len (&dstr, 0, new_len,
312: str, pos + 4, old_len))
313: return FALSE;
314:
315: _dbus_marshal_set_uint32 (str, pos, new_len, byte_order);
316:
317: if (old_end_pos)
318: *old_end_pos = pos + 4 + old_len + 1;
319: if (new_end_pos)
320: *new_end_pos = pos + 4 + new_len + 1;
321:
322: return TRUE;
323: }
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
335:
336:
337:
338: static dbus_bool_t
339: set_signature (DBusString *str,
340: int pos,
341: const char *value,
342: int byte_order,
343: int *old_end_pos,
344: int *new_end_pos)
345: {
346: int old_len, new_len;
347: DBusString dstr;
348:
349: _dbus_string_init_const (&dstr, value);
350:
351: old_len = _dbus_string_get_byte (str, pos);
352: new_len = _dbus_string_get_length (&dstr);
353:
354: if (!_dbus_string_replace_len (&dstr, 0, new_len,
355: str, pos + 1, old_len))
356: return FALSE;
357:
358: _dbus_string_set_byte (str, pos, new_len);
359:
360: if (old_end_pos)
361: *old_end_pos = pos + 1 + old_len + 1;
362: if (new_end_pos)
363: *new_end_pos = pos + 1 + new_len + 1;
364:
365: return TRUE;
366: }
367:
368:
369:
370:
371:
372:
373:
374:
375:
376:
377:
378:
379:
380:
381: dbus_bool_t
382: _dbus_marshal_set_basic (DBusString *str,
383: int pos,
384: int type,
385: const void *value,
386: int byte_order,
387: int *old_end_pos,
388: int *new_end_pos)
389: {
390: const DBusBasicValue *vp;
391:
392: vp = value;
393:
394: switch (type)
395: {
396: case DBUS_TYPE_BYTE:
397: _dbus_string_set_byte (str, pos, vp->byt);
398: if (old_end_pos)
399: *old_end_pos = pos + 1;
400: if (new_end_pos)
401: *new_end_pos = pos + 1;
402: return TRUE;
403: break;
404: case DBUS_TYPE_INT16:
405: case DBUS_TYPE_UINT16:
406: pos = _DBUS_ALIGN_VALUE (pos, 2);
407: set_2_octets (str, pos, vp->u16, byte_order);
408: if (old_end_pos)
409: *old_end_pos = pos + 2;
410: if (new_end_pos)
411: *new_end_pos = pos + 2;
412: return TRUE;
413: break;
414: case DBUS_TYPE_BOOLEAN:
415: case DBUS_TYPE_INT32:
416: case DBUS_TYPE_UINT32:
417: pos = _DBUS_ALIGN_VALUE (pos, 4);
418: set_4_octets (str, pos, vp->u32, byte_order);
419: if (old_end_pos)
420: *old_end_pos = pos + 4;
421: if (new_end_pos)
422: *new_end_pos = pos + 4;
423: return TRUE;
424: break;
425: case DBUS_TYPE_INT64:
426: case DBUS_TYPE_UINT64:
427: case DBUS_TYPE_DOUBLE:
428: pos = _DBUS_ALIGN_VALUE (pos, 8);
429: set_8_octets (str, pos, *vp, byte_order);
430: if (old_end_pos)
431: *old_end_pos = pos + 8;
432: if (new_end_pos)
433: *new_end_pos = pos + 8;
434: return TRUE;
435: break;
436: case DBUS_TYPE_STRING:
437: case DBUS_TYPE_OBJECT_PATH:
438: pos = _DBUS_ALIGN_VALUE (pos, 4);
439: _dbus_assert (vp->str != NULL);
440: return set_string (str, pos, vp->str, byte_order,
441: old_end_pos, new_end_pos);
442: break;
443: case DBUS_TYPE_SIGNATURE:
444: _dbus_assert (vp->str != NULL);
445: return set_signature (str, pos, vp->str, byte_order,
446: old_end_pos, new_end_pos);
447: break;
448: default:
449: _dbus_assert_not_reached ("not a basic type");
450: return FALSE;
451: break;
452: }
453: }
454:
455:
456:
457:
458:
459:
460:
461:
462:
463:
464: dbus_uint32_t
465: _dbus_marshal_read_uint32 (const DBusString *str,
466: int pos,
467: int byte_order,
468: int *new_pos)
469: {
470: pos = _DBUS_ALIGN_VALUE (pos, 4);
471:
472: if (new_pos)
473: *new_pos = pos + 4;
474:
475: _dbus_assert (pos + 4 <= _dbus_string_get_length (str));
476:
477: return _dbus_unpack_uint32 (byte_order,
478: _dbus_string_get_const_data (str) + pos);
479: }
480:
481:
482:
483:
484:
485:
486:
487:
488:
489:
490:
491:
492:
493:
494:
495:
496:
497:
498:
499:
500:
501:
502: void
503: _dbus_marshal_read_basic (const DBusString *str,
504: int pos,
505: int type,
506: void *value,
507: int byte_order,
508: int *new_pos)
509: {
510: const char *str_data;
511: DBusBasicValue *vp;
512:
513: _dbus_assert (dbus_type_is_basic (type));
514:
515: str_data = _dbus_string_get_const_data (str);
516: vp = value;
517:
518: switch (type)
519: {
520: case DBUS_TYPE_BYTE:
521: vp->byt = _dbus_string_get_byte (str, pos);
522: (pos)++;
523: break;
524: case DBUS_TYPE_INT16:
525: case DBUS_TYPE_UINT16:
526: pos = _DBUS_ALIGN_VALUE (pos, 2);
527: vp->u16 = *(dbus_uint16_t *)(str_data + pos);
528: if (byte_order != DBUS_COMPILER_BYTE_ORDER)
529: vp->u16 = DBUS_UINT16_SWAP_LE_BE (vp->u16);
530: pos += 2;
531: break;
532: case DBUS_TYPE_INT32:
533: case DBUS_TYPE_UINT32:
534: case DBUS_TYPE_BOOLEAN:
535: pos = _DBUS_ALIGN_VALUE (pos, 4);
536: vp->u32 = *(dbus_uint32_t *)(str_data + pos);
537: if (byte_order != DBUS_COMPILER_BYTE_ORDER)
538: vp->u32 = DBUS_UINT32_SWAP_LE_BE (vp->u32);
539: pos += 4;
540: break;
541: case DBUS_TYPE_INT64:
542: case DBUS_TYPE_UINT64:
543: case DBUS_TYPE_DOUBLE:
544: pos = _DBUS_ALIGN_VALUE (pos, 8);
545: #ifdef DBUS_HAVE_INT64
546: if (byte_order != DBUS_COMPILER_BYTE_ORDER)
547: vp->u64 = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t*)(str_data + pos));
548: else
549: vp->u64 = *(dbus_uint64_t*)(str_data + pos);
550: #else
551: vp->u64 = *(DBus8ByteStruct*) (str_data + pos);
552: swap_8_octets (vp, byte_order);
553: #endif
554: pos += 8;
555: break;
556: case DBUS_TYPE_STRING:
557: case DBUS_TYPE_OBJECT_PATH:
558: {
559: int len;
560:
561: len = _dbus_marshal_read_uint32 (str, pos, byte_order, &pos);
562:
563: vp->str = (char*) str_data + pos;
564:
565: pos += len + 1;
566: }
567: break;
568: case DBUS_TYPE_SIGNATURE:
569: {
570: int len;
571:
572: len = _dbus_string_get_byte (str, pos);
573: pos += 1;
574:
575: vp->str = (char*) str_data + pos;
576:
577: pos += len + 1;
578: }
579: break;
580: default:
581: _dbus_warn_check_failed ("type %s %d not a basic type\n",
582: