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/dbus-shared.h"
25: #include "dbus-marshal-header.h"
26: #include "dbus-marshal-recursive.h"
27: #include "dbus-marshal-byteswap.h"
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39: _DBUS_STRING_DEFINE_STATIC(_dbus_header_signature_str, DBUS_HEADER_SIGNATURE);
40:
41: _DBUS_STRING_DEFINE_STATIC(_dbus_local_interface_str, DBUS_INTERFACE_LOCAL);
42:
43: _DBUS_STRING_DEFINE_STATIC(_dbus_local_path_str, DBUS_PATH_LOCAL);
44:
45:
46: #define FIELDS_ARRAY_SIGNATURE_OFFSET 6
47:
48: #define FIELDS_ARRAY_ELEMENT_SIGNATURE_OFFSET 7
49:
50:
51:
52: #define BYTE_ORDER_OFFSET 0
53:
54: #define TYPE_OFFSET 1
55:
56: #define FLAGS_OFFSET 2
57:
58: #define VERSION_OFFSET 3
59:
60: #define BODY_LENGTH_OFFSET 4
61:
62: #define SERIAL_OFFSET 8
63:
64: #define FIELDS_ARRAY_LENGTH_OFFSET 12
65:
66: #define FIRST_FIELD_OFFSET 16
67:
68: typedef struct
69: {
70: unsigned char code;
71: unsigned char type;
72: } HeaderFieldType;
73:
74: static const HeaderFieldType
75: _dbus_header_field_types[DBUS_HEADER_FIELD_LAST+1] = {
76: { DBUS_HEADER_FIELD_INVALID, DBUS_TYPE_INVALID },
77: { DBUS_HEADER_FIELD_PATH, DBUS_TYPE_OBJECT_PATH },
78: { DBUS_HEADER_FIELD_INTERFACE, DBUS_TYPE_STRING },
79: { DBUS_HEADER_FIELD_MEMBER, DBUS_TYPE_STRING },
80: { DBUS_HEADER_FIELD_ERROR_NAME, DBUS_TYPE_STRING },
81: { DBUS_HEADER_FIELD_REPLY_SERIAL, DBUS_TYPE_UINT32 },
82: { DBUS_HEADER_FIELD_DESTINATION, DBUS_TYPE_STRING },
83: { DBUS_HEADER_FIELD_SENDER, DBUS_TYPE_STRING },
84: { DBUS_HEADER_FIELD_SIGNATURE, DBUS_TYPE_SIGNATURE }
85: };
86:
87:
88: #define EXPECTED_TYPE_OF_FIELD(field) (_dbus_header_field_types[field].type)
89:
90:
91: #define MAX_POSSIBLE_HEADER_PADDING 7
92: static dbus_bool_t
93: reserve_header_padding (DBusHeader *header)
94: {
95: _dbus_assert (header->padding <= MAX_POSSIBLE_HEADER_PADDING);
96:
97: if (!_dbus_string_lengthen (&header->data,
98: MAX_POSSIBLE_HEADER_PADDING - header->padding))
99: return FALSE;
100: header->padding = MAX_POSSIBLE_HEADER_PADDING;
101: return TRUE;
102: }
103:
104: static void
105: correct_header_padding (DBusHeader *header)
106: {
107: int unpadded_len;
108:
109: _dbus_assert (header->padding == 7);
110:
111: _dbus_string_shorten (&header->data, header->padding);
112: unpadded_len = _dbus_string_get_length (&header->data);
113:
114: if (!_dbus_string_align_length (&header->data, 8))
115: _dbus_assert_not_reached ("couldn't pad header though enough padding was preallocated");
116:
117: header->padding = _dbus_string_get_length (&header->data) - unpadded_len;
118: }
119:
120:
121: #define HEADER_END_BEFORE_PADDING(header) \
122: (_dbus_string_get_length (&(header)->data) - (header)->padding)
123:
124:
125:
126:
127:
128:
129:
130:
131: static void
132: _dbus_header_cache_invalidate_all (DBusHeader *header)
133: {
134: int i;
135:
136: i = 0;
137: while (i <= DBUS_HEADER_FIELD_LAST)
138: {
139: header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_UNKNOWN;
140: ++i;
141: }
142: }
143:
144:
145:
146:
147:
148:
149:
150:
151: static void
152: _dbus_header_cache_one (DBusHeader *header,
153: int field_code,
154: DBusTypeReader *variant_reader)
155: {
156: header->fields[field_code].value_pos =
157: _dbus_type_reader_get_value_pos (variant_reader);
158:
159: #if 0
160: _dbus_verbose ("cached value_pos %d for field %d\n",
161: header->fields[field_code].value_pos, field_code)
162: #endif
163: }
164:
165:
166:
167:
168:
169:
170: static void
171: _dbus_header_cache_revalidate (DBusHeader *header)
172: {
173: DBusTypeReader array;
174: DBusTypeReader reader;
175: int i;
176:
177: i = 0;
178: while (i <= DBUS_HEADER_FIELD_LAST)
179: {
180: header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT;
181: ++i;
182: }
183:
184: _dbus_type_reader_init (&reader,
185: header->byte_order,
186: &_dbus_header_signature_str,
187: FIELDS_ARRAY_SIGNATURE_OFFSET,
188: &header->data,
189: FIELDS_ARRAY_LENGTH_OFFSET);
190:
191: _dbus_type_reader_recurse (&reader, &array);
192:
193: while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
194: {
195: DBusTypeReader sub;
196: DBusTypeReader variant;
197: unsigned char field_code;
198:
199: _dbus_type_reader_recurse (&array, &sub);
200:
201: _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_BYTE);
202: _dbus_type_reader_read_basic (&sub, &field_code);
203:
204:
205: if (field_code > DBUS_HEADER_FIELD_LAST)
206: goto next_field;
207:
208: _dbus_type_reader_next (&sub);
209:
210: _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_VARIANT);
211: _dbus_type_reader_recurse (&sub, &variant);
212:
213: _dbus_header_cache_one (header, field_code, &variant);
214:
215: next_field:
216: _dbus_type_reader_next (&array);
217: }
218: }
219:
220:
221:
222:
223:
224:
225:
226:
227: static dbus_bool_t
228: _dbus_header_cache_check (DBusHeader *header,
229: int field)
230: {
231: _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
232:
233: if (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN)
234: _dbus_header_cache_revalidate (header);
235:
236: if (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT)
237: return FALSE;
238:
239: return TRUE;
240: }
241:
242:
243:
244:
245:
246:
247:
248:
249:
250: static dbus_bool_t
251: _dbus_header_cache_known_nonexistent (DBusHeader *header,
252: int field)
253: {
254: _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
255:
256: return (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT);
257: }
258:
259:
260:
261:
262:
263:
264:
265:
266:
267: static dbus_bool_t
268: write_basic_field (DBusTypeWriter *writer,
269: int field,
270: int type,
271: const void *value)
272: {
273: DBusTypeWriter sub;
274: DBusTypeWriter variant;
275: int start;
276: int padding;
277: unsigned char field_byte;
278: DBusString contained_type;
279: char buf[2];
280:
281: start = writer->value_pos;
282: padding = _dbus_string_get_length (writer->value_str) - start;
283:
284: if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_STRUCT,
285: NULL, 0, &sub))
286: goto append_failed;
287:
288: field_byte = field;
289: if (!_dbus_type_writer_write_basic (&sub, DBUS_TYPE_BYTE,
290: &field_byte))
291: goto append_failed;
292:
293: buf[0] = type;
294: buf[1] = '\0';
295: _dbus_string_init_const_len (&contained_type, buf, 1);
296:
297: if (!_dbus_type_writer_recurse (&sub, DBUS_TYPE_VARIANT,
298: &contained_type, 0, &variant))
299: goto append_failed;
300:
301: if (!_dbus_type_writer_write_basic (&variant, type, value))
302: goto append_failed;
303:
304: if (!_dbus_type_writer_unrecurse (&sub, &variant))
305: goto append_failed;
306:
307: if (!_dbus_type_writer_unrecurse (writer, &sub))
308: goto append_failed;
309:
310: return TRUE;
311:
312: append_failed:
313: _dbus_string_delete (writer->value_str,
314: start,
315: _dbus_string_get_length (writer->value_str) - start - padding);
316: return FALSE;
317: }
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328: static dbus_bool_t
329: set_basic_field (DBusTypeReader *reader,
330: int field,
331: int type,
332: const void *value,
333: const DBusTypeReader *realign_root)
334: {
335: DBusTypeReader sub;
336: DBusTypeReader variant;
337:
338: _dbus_type_reader_recurse (reader, &sub);
339:
340: _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_BYTE);
341: #ifndef DBUS_DISABLE_ASSERT
342: {
343: unsigned char v_BYTE;
344: _dbus_type_reader_read_basic (&sub, &v_BYTE);
345: _dbus_assert (((int) v_BYTE) == field);
346: }
347: #endif
348:
349: if (!_dbus_type_reader_next (&sub))
350: _dbus_assert_not_reached ("no variant field?");
351:
352: _dbus_type_reader_recurse (&sub, &variant);
353: _dbus_assert (_dbus_type_reader_get_current_type (&variant) == type);
354:
355: if (!_dbus_type_reader_set_basic (&variant, value, realign_root))
356: return FALSE;
357:
358: return TRUE;
359: }
360:
361:
362:
363:
364:
365:
366:
367: int
368: _dbus_header_get_message_type (DBusHeader *header)
369: {
370: int type;
371:
372: type = _dbus_string_get_byte (&header->data, TYPE_OFFSET);
373: _dbus_assert (type != DBUS_MESSAGE_TYPE_INVALID);
374:
375: return type;
376: }
377:
378:
379:
380:
381:
382:
383:
384:
385: void
386: _dbus_header_set_serial (DBusHeader *header,
387: dbus_uint32_t serial)
388: {
389:
390:
391:
392:
393: _dbus_assert (_dbus_header_get_serial (header) == 0 ||
394: serial == 0);
395:
396: _dbus_marshal_set_uint32 (&header->data,
397: SERIAL_OFFSET,
398: serial,
399: header->byte_order);
400: }
401:
402:
403:
404:
405:
406:
407:
408: dbus_uint32_t
409: _dbus_header_get_serial (DBusHeader *header)
410: {
411: return _dbus_marshal_read_uint32 (&header->data,
412: SERIAL_OFFSET,
413: header->byte_order,
414: NULL);
415: }
416:
417:
418:
419:
420:
421:
422:
423:
424:
425: void
426: _dbus_header_reinit (DBusHeader *header,
427: int byte_order)
428: {
429: _dbus_string_set_length (&header->data, 0);
430:
431: header->byte_order = byte_order;
432: header->padding = 0;
433:
434: _dbus_header_cache_invalidate_all (header);
435: }
436:
437:
438:
439:
440:
441:
442:
443:
444:
445: dbus_bool_t
446: _dbus_header_init (DBusHeader *header,
447: int byte_order)
448: {
449: if (!_dbus_string_init_preallocated (&header->data, 32))
450: return FALSE;
451:
452: _dbus_header_reinit (header, byte_order);
453:
454: return TRUE;
455: }
456:
457:
458:
459:
460:
461:
462: void
463: _dbus_header_free (DBusHeader *header)
464: {
465: _dbus_string_free (&header->data);
466: }
467:
468:
469:
470:
471:
472:
473:
474:
475:
476: dbus_bool_t
477: _dbus_header_copy (const DBusHeader *header,
478: DBusHeader *dest)
479: {
480: *dest = *header;
481:
482: if (!_dbus_string_init_preallocated (&dest->data,
483: _dbus_string_get_length (&header->data)))
484: return FALSE;
485:
486: if (!_dbus_string_copy (&header->data, 0, &dest->data, 0))
487: {
488: _dbus_string_free (&dest->data);
489: return FALSE;
490: }
491:
492:
493: _dbus_header_set_serial (dest, 0);
494:
495: return TRUE;
496: }
497:
498:
499:
500:
501:
502:
503:
504:
505:
506:
507:
508:
509:
510:
511:
512:
513: dbus_bool_t
514: _dbus_header_create (DBusHeader *header,
515: int message_type,
516: const char *destination,
517: const char *path,
518: const char *interface,
519: const char *member,
520: const char *error_name)
521: {
522: unsigned char v_BYTE;
523: dbus_uint32_t v_UINT32;
524: DBusTypeWriter writer;
525: DBusTypeWriter array;
526:
527: _dbus_assert (((interface || message_type != DBUS_MESSAGE_TYPE_SIGNAL) && member) ||
528: (error_name) ||
529: !(interface || member || error_name));
530: _dbus_assert (_dbus_string_get_length (&header->data) == 0);
531:
532: if (!reserve_header_padding (header))
533: return FALSE;
534:
535: _dbus_type_writer_init_values_only (&writer, header->byte_order,
536: &_dbus_header_signature_str, 0,
537: &header->data,
538: HEADER_END_BEFORE_PADDING (header));
539:
540: v_BYTE = header->byte_order;
541: if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
542: &v_BYTE))
543: goto oom;
544:
545: v_BYTE = message_type;
546: if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
547: &v_BYTE))
548: goto oom;
549:
550: v_BYTE = 0;
551: if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
552: &v_BYTE))
553: goto oom;
554:
555: v_BYTE = DBUS_MAJOR_PROTOCOL_VERSION;
556: if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
557: &v_BYTE))
558: goto oom;
559:
560: v_UINT32 = 0;
561: if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_UINT32,
562: &v_UINT32))
563: goto oom;
564:
565: v_UINT32 = 0;
566: if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_UINT32,
567: &v_UINT32))
568: goto oom;
569:
570: if (!_dbus_type_writer_recurse (&writer, DBUS_TYPE_ARRAY,
571: &_dbus_header_signature_str,
572: FIELDS_ARRAY_SIGNATURE_OFFSET,
573: &array))
574: goto oom;
575:
576:
577:
578: if (path != NULL)
579: {
580: if (!write_basic_field (&array,
581: DBUS_HEADER_FIELD_PATH,
582: DBUS_TYPE_OBJECT_PATH,
583: &path))
584: goto oom;
585: }
586:
587: if (destination != NULL)
588: {
589: if (!write_basic_field (&array,
590: DBUS_HEADER_FIELD_DESTINATION,
591: DBUS_TYPE_STRING,
592: &destination))
593: goto oom;
594: }