00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "dbus-internals.h"
00026 #include "dbus-marshal.h"
00027 #include "dbus-message.h"
00028 #include "dbus-message-internal.h"
00029 #include "dbus-memory.h"
00030 #include "dbus-list.h"
00031 #include "dbus-message-builder.h"
00032 #include "dbus-dataslot.h"
00033 #include <string.h>
00034
00048 typedef struct
00049 {
00050 int name_offset;
00051 int value_offset;
00052 } HeaderField;
00053
00055 #define BYTE_ORDER_OFFSET 0
00056
00057 #define TYPE_OFFSET 1
00058
00059 #define FLAGS_OFFSET 2
00060
00061 #define VERSION_OFFSET 3
00062
00063 #define HEADER_LENGTH_OFFSET 4
00064
00065 #define BODY_LENGTH_OFFSET 8
00066
00067 #define CLIENT_SERIAL_OFFSET 12
00068
00069
00077 struct DBusMessage
00078 {
00079 DBusAtomic refcount;
00081 DBusString header;
00086 HeaderField header_fields[DBUS_HEADER_FIELD_LAST + 1];
00090 dbus_uint32_t client_serial;
00091 dbus_uint32_t reply_serial;
00093 int header_padding;
00095 DBusString body;
00097 char byte_order;
00099 unsigned int locked : 1;
00101 DBusList *size_counters;
00102 long size_counter_delta;
00104 dbus_uint32_t changed_stamp;
00106 DBusDataSlotList slot_list;
00108 #ifndef DBUS_DISABLE_CHECKS
00109 int generation;
00110 #endif
00111 };
00112
00113 enum {
00114 DBUS_MESSAGE_ITER_TYPE_MESSAGE,
00115 DBUS_MESSAGE_ITER_TYPE_ARRAY,
00116 DBUS_MESSAGE_ITER_TYPE_DICT
00117 };
00118
00120 typedef struct DBusMessageRealIter DBusMessageRealIter;
00121
00127 struct DBusMessageRealIter
00128 {
00129 DBusMessageRealIter *parent_iter;
00130 DBusMessage *message;
00131 dbus_uint32_t changed_stamp;
00133
00134 int type;
00136 int pos;
00137 int end;
00138 int container_start;
00139 int container_length_pos;
00141 int wrote_dict_key;
00143 int array_type_pos;
00144 int array_type_done;
00145 };
00146
00157 void
00158 _dbus_message_get_network_data (DBusMessage *message,
00159 const DBusString **header,
00160 const DBusString **body)
00161 {
00162 _dbus_assert (message->locked);
00163
00164 *header = &message->header;
00165 *body = &message->body;
00166 }
00167
00168 static void
00169 clear_header_padding (DBusMessage *message)
00170 {
00171 _dbus_string_shorten (&message->header,
00172 message->header_padding);
00173 message->header_padding = 0;
00174 }
00175
00176 #ifdef DBUS_DISABLE_CHECKS
00177 #define is_valid_error_name(x) TRUE
00178 #else
00179 static dbus_bool_t
00180 is_valid_error_name (const char *error_name)
00181 {
00182 DBusString the_error_name;
00183
00184 if (error_name == NULL)
00185 return FALSE;
00186
00187 _dbus_string_init_const (&the_error_name, error_name);
00188 return _dbus_string_validate_error_name (&the_error_name, 0,
00189 _dbus_string_get_length (&the_error_name));
00190 }
00191 #endif
00192
00193 static dbus_bool_t
00194 append_header_padding (DBusMessage *message)
00195 {
00196 int old_len;
00197 old_len = _dbus_string_get_length (&message->header);
00198 if (!_dbus_string_align_length (&message->header, 8))
00199 return FALSE;
00200
00201 message->header_padding = _dbus_string_get_length (&message->header) - old_len;
00202
00203 return TRUE;
00204 }
00205
00206 #ifdef DBUS_BUILD_TESTS
00207
00208 static dbus_int32_t
00209 get_int_field (DBusMessage *message,
00210 int field)
00211 {
00212 int offset;
00213
00214 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
00215
00216 offset = message->header_fields[field].value_offset;
00217
00218 if (offset < 0)
00219 return -1;
00220
00221 return _dbus_demarshal_int32 (&message->header,
00222 message->byte_order,
00223 offset,
00224 NULL);
00225 }
00226 #endif
00227
00228 static dbus_uint32_t
00229 get_uint_field (DBusMessage *message,
00230 int field)
00231 {
00232 int offset;
00233
00234 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
00235
00236 offset = message->header_fields[field].value_offset;
00237
00238 if (offset < 0)
00239 return 0;
00240
00241 return _dbus_demarshal_uint32 (&message->header,
00242 message->byte_order,
00243 offset,
00244 NULL);
00245 }
00246
00247 static const char*
00248 get_string_field (DBusMessage *message,
00249 int field,
00250 int *len)
00251 {
00252 int offset;
00253 const char *data;
00254
00255 _dbus_return_val_if_fail (message->generation == _dbus_current_generation,
00256 NULL);
00257
00258 offset = message->header_fields[field].value_offset;
00259
00260 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
00261
00262 if (offset < 0)
00263 return NULL;
00264
00265
00266
00267
00268
00269
00270 if (len)
00271 *len = _dbus_demarshal_uint32 (&message->header,
00272 message->byte_order,
00273 offset,
00274 NULL);
00275
00276 data = _dbus_string_get_const_data (&message->header);
00277
00278 return data + (offset + 4);
00279 }
00280
00281
00282 static dbus_bool_t
00283 get_path_field_decomposed (DBusMessage *message,
00284 int field,
00285 char ***path)
00286 {
00287 int offset;
00288
00289 offset = message->header_fields[field].value_offset;
00290
00291 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
00292
00293 if (offset < 0)
00294 {
00295 *path = NULL;
00296 return TRUE;
00297 }
00298
00299 return _dbus_demarshal_object_path (&message->header,
00300 message->byte_order,
00301 offset,
00302 NULL,
00303 path, NULL);
00304 }
00305
00306 #ifdef DBUS_BUILD_TESTS
00307 static dbus_bool_t
00308 append_int_field (DBusMessage *message,
00309 int field,
00310 int value)
00311 {
00312 _dbus_assert (!message->locked);
00313
00314 clear_header_padding (message);
00315
00316 message->header_fields[field].name_offset =
00317 _dbus_string_get_length (&message->header);
00318
00319 if (!_dbus_string_append_byte (&message->header, field))
00320 goto failed;
00321
00322 if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_INT32))
00323 goto failed;
00324
00325 if (!_dbus_string_align_length (&message->header, 4))
00326 goto failed;
00327
00328 message->header_fields[field].value_offset =
00329 _dbus_string_get_length (&message->header);
00330
00331 if (!_dbus_marshal_int32 (&message->header, message->byte_order,
00332 value))
00333 goto failed;
00334
00335 if (!append_header_padding (message))
00336 goto failed;
00337
00338 return TRUE;
00339
00340 failed:
00341 _dbus_string_set_length (&message->header,
00342 message->header_fields[field].name_offset);
00343 message->header_fields[field].name_offset = -1;
00344 message->header_fields[field].value_offset = -1;
00345
00346
00347
00348
00349 if (!append_header_padding (message))
00350 _dbus_assert_not_reached ("failed to reappend header padding");
00351 return FALSE;
00352 }
00353 #endif
00354
00355 static dbus_bool_t
00356 append_uint_field (DBusMessage *message,
00357 int field,
00358 int value)
00359 {
00360 _dbus_assert (!message->locked);
00361
00362 clear_header_padding (message);
00363
00364 message->header_fields[field].name_offset =
00365 _dbus_string_get_length (&message->header);
00366
00367 if (!_dbus_string_append_byte (&message->header, field))
00368 goto failed;
00369
00370 if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_UINT32))
00371 goto failed;
00372
00373 if (!_dbus_string_align_length (&message->header, 4))
00374 goto failed;
00375
00376 message->header_fields[field].value_offset =
00377 _dbus_string_get_length (&message->header);
00378
00379 if (!_dbus_marshal_uint32 (&message->header, message->byte_order,
00380 value))
00381 goto failed;
00382
00383 if (!append_header_padding (message))
00384 goto failed;
00385
00386 return TRUE;
00387
00388 failed:
00389 _dbus_string_set_length (&message->header,
00390 message->header_fields[field].name_offset);
00391 message->header_fields[field].name_offset = -1;
00392 message->header_fields[field].value_offset = -1;
00393
00394
00395
00396
00397 if (!append_header_padding (message))
00398 _dbus_assert_not_reached ("failed to reappend header padding");
00399 return FALSE;
00400 }
00401
00405 #define MAX_BYTES_OVERHEAD_TO_APPEND_A_STRING (1 + 1 + 3 + 4 + 1 + 8)
00406
00407 static dbus_bool_t
00408 append_string_field_len (DBusMessage *message,
00409 int field,
00410 int type,
00411 const char *value,
00412 int value_len)
00413 {
00414 _dbus_assert (!message->locked);
00415
00416 clear_header_padding (message);
00417
00418 message->header_fields[field].name_offset =
00419 _dbus_string_get_length (&message->header);
00420
00421 if (!_dbus_string_append_byte (&message->header, field))
00422 goto failed;
00423
00424 if (!_dbus_string_append_byte (&message->header, type))
00425 goto failed;
00426
00427 if (!_dbus_string_align_length (&message->header, 4))
00428 goto failed;
00429
00430 message->header_fields[field].value_offset =
00431 _dbus_string_get_length (&message->header);
00432
00433 if (!_dbus_marshal_string_len (&message->header, message->byte_order,
00434 value, value_len))
00435 goto failed;
00436
00437 if (!append_header_padding (message))
00438 goto failed;
00439
00440 return TRUE;
00441
00442 failed:
00443 _dbus_string_set_length (&message->header,
00444 message->header_fields[field].name_offset);
00445 message->header_fields[field].name_offset = -1;
00446 message->header_fields[field].value_offset = -1;
00447
00448
00449
00450
00451 if (!append_header_padding (message))
00452 _dbus_assert_not_reached ("failed to reappend header padding");
00453
00454 return FALSE;
00455 }
00456
00457 static dbus_bool_t
00458 append_string_field (DBusMessage *message,
00459 int field,
00460 int type,
00461 const char *value)
00462 {
00463 int value_len;
00464
00465 value_len = strlen (value);
00466
00467 return append_string_field_len (message, field, type, value, value_len);
00468 }
00469
00470 static int
00471 get_type_alignment (int type)
00472 {
00473 int alignment;
00474
00475 switch (type)
00476 {
00477 case DBUS_TYPE_NIL:
00478 case DBUS_TYPE_BYTE:
00479 case DBUS_TYPE_BOOLEAN:
00480 alignment = 0;
00481 break;
00482
00483 case DBUS_TYPE_INT32:
00484 case DBUS_TYPE_UINT32:
00485 case DBUS_TYPE_STRING:
00486 case DBUS_TYPE_OBJECT_PATH:
00487
00488
00489
00490 case DBUS_TYPE_CUSTOM:
00491 case DBUS_TYPE_DICT:
00492 alignment = 4;
00493 break;
00494
00495 case DBUS_TYPE_INT64:
00496 case DBUS_TYPE_UINT64:
00497 case DBUS_TYPE_DOUBLE:
00498 alignment = 8;
00499 break;
00500
00501 case DBUS_TYPE_ARRAY:
00502 _dbus_assert_not_reached ("passed an ARRAY type to get_type_alignment()");
00503 alignment = 0;
00504 break;
00505
00506 case DBUS_TYPE_INVALID:
00507 default:
00508 _dbus_assert_not_reached ("passed an invalid or unknown type to get_type_alignment()");
00509 alignment = 0;
00510 break;
00511 }
00512
00513 return alignment;
00514 }
00515
00516 static dbus_bool_t
00517 iterate_one_field (const DBusString *str,
00518 int byte_order,
00519 int name_offset,
00520 int *next_offset_p,
00521 int *field_name_p,
00522 DBusString *append_copy_to,
00523 int *copy_name_offset_p,
00524 int *copy_value_offset_p)
00525 {
00526 int name, type, array_type;
00527 int alignment;
00528 int type_len;
00529 int type_pos;
00530 int value_pos;
00531 int value_len;
00532 int value_end;
00533 int pos;
00534
00535 #if 0
00536 _dbus_verbose ("%s: name_offset=%d, append to %p\n",
00537 _DBUS_FUNCTION_NAME, name_offset, append_copy_to);
00538 #endif
00539
00540 pos = name_offset;
00541
00542 name = _dbus_string_get_byte (str, name_offset);
00543 pos++;
00544
00545 type_pos = pos;
00546 type = _dbus_string_get_byte (str, type_pos);
00547 pos++;
00548 type_len = 1;
00549
00550 array_type = type;
00551
00552 while (array_type == DBUS_TYPE_ARRAY)
00553 {
00554 pos++;
00555 type_len++;
00556 array_type = _dbus_string_get_byte (str, pos);
00557 }
00558
00559 #if 0
00560 _dbus_verbose ("%s: name %s, type '%c' %d at %d len %d, array type '%c' %d\n",
00561 _DBUS_FUNCTION_NAME,
00562 _dbus_header_field_to_string (name),
00563 type, type, type_pos, type_len, array_type, array_type);
00564 #endif
00565
00566 #ifndef DBUS_DISABLE_ASSERT
00567 if (!_dbus_type_is_valid (array_type))
00568 {
00569 _dbus_warn ("type '%c' %d is not valid in %s\n",
00570 array_type, array_type, _DBUS_FUNCTION_NAME);
00571 _dbus_assert_not_reached ("invalid type");
00572 }
00573 #endif
00574
00575 alignment = get_type_alignment (array_type);
00576
00577 if (alignment > 0)
00578 pos = _DBUS_ALIGN_VALUE (pos, alignment);
00579
00580 _dbus_verbose ("%s: alignment %d value at pos %d\n",
00581 _DBUS_FUNCTION_NAME, alignment, pos);
00582
00583
00584 if (!_dbus_marshal_get_arg_end_pos (str, byte_order,
00585 type, pos, &value_end))
00586 _dbus_assert_not_reached ("failed to get the byte after this header");
00587
00588 value_pos = pos;
00589 value_len = value_end - value_pos;
00590
00591 _dbus_verbose ("%s: value_pos %d value_len %d value_end %d\n",
00592 _DBUS_FUNCTION_NAME, value_pos, value_len, value_end);
00593
00594 if (next_offset_p)
00595 *next_offset_p = pos + value_len;
00596
00597 if (field_name_p)
00598 *field_name_p = name;
00599
00600 if (append_copy_to)
00601 {
00602 int orig_len;
00603
00604 orig_len = _dbus_string_get_length (append_copy_to);
00605
00606 if (copy_name_offset_p)
00607 *copy_name_offset_p = orig_len;
00608
00609 if (!_dbus_string_append_byte (append_copy_to, name))
00610 goto failed_copy;
00611
00612 if (!_dbus_string_copy_len (str, type_pos, type_len,
00613 append_copy_to,
00614 _dbus_string_get_length (append_copy_to)))
00615 goto failed_copy;
00616
00617 if (!_dbus_string_align_length (append_copy_to, alignment))
00618 goto failed_copy;
00619
00620 if (copy_value_offset_p)
00621 *copy_value_offset_p = _dbus_string_get_length (append_copy_to);
00622
00623 if (!_dbus_string_copy_len (str, value_pos, value_len,
00624 append_copy_to,
00625 _dbus_string_get_length (append_copy_to)))
00626 goto failed_copy;
00627
00628 return TRUE;
00629
00630 failed_copy:
00631 _dbus_verbose ("%s: Failed copying old fields to new string\n",
00632 _DBUS_FUNCTION_NAME);
00633 _dbus_string_set_length (append_copy_to, orig_len);
00634 return FALSE;
00635 }
00636 else
00637 return TRUE;
00638 }
00639
00640 #ifndef DBUS_DISABLE_ASSERT
00641 static void
00642 verify_header_fields (DBusMessage *message)
00643 {
00644 int i;
00645 i = 0;
00646 while (i <= DBUS_HEADER_FIELD_LAST)
00647 {
00648 if (message->header_fields[i].name_offset >= 0)
00649 _dbus_assert (_dbus_string_get_byte (&message->header,
00650 message->header_fields[i].name_offset) ==
00651 i);
00652 ++i;
00653 }
00654 }
00655 #else
00656 #define verify_header_fields(x)
00657 #endif
00658
00659
00660
00661
00662 static dbus_bool_t
00663 delete_one_and_re_align (DBusMessage *message,
00664 int name_offset_to_delete)
00665 {
00666 DBusString copy;
00667 int new_fields_front_padding;
00668 int next_offset;
00669 int field_name;
00670 dbus_bool_t retval;
00671 HeaderField new_header_fields[DBUS_HEADER_FIELD_LAST+1];
00672
00673 _dbus_assert (name_offset_to_delete < _dbus_string_get_length (&message->header));
00674 verify_header_fields (message);
00675
00676 _dbus_verbose ("%s: Deleting one field at offset %d\n",
00677 _DBUS_FUNCTION_NAME,
00678 name_offset_to_delete);
00679
00680 retval = FALSE;
00681
00682 clear_header_padding (message);
00683
00684 if (!_dbus_string_init_preallocated (©,
00685 _dbus_string_get_length (&message->header) -
00686 name_offset_to_delete + 8))
00687 {
00688 _dbus_verbose ("%s: Failed to init string to hold copy of fields\n",
00689 _DBUS_FUNCTION_NAME);
00690 goto out_0;
00691 }
00692
00693
00694
00695
00696 new_fields_front_padding = name_offset_to_delete % 8;
00697
00698 if (!_dbus_string_insert_bytes (©, 0, new_fields_front_padding,
00699 '\0'))
00700 _dbus_assert_not_reached ("Should not have failed to insert bytes into preallocated string\n");
00701
00702 memcpy (new_header_fields, message->header_fields,
00703 sizeof (new_header_fields));
00704
00705
00706
00707
00708
00709
00710
00711 if (!iterate_one_field (&message->header,
00712 message->byte_order,
00713 name_offset_to_delete,
00714 &next_offset,
00715 &field_name, NULL, NULL, NULL))
00716 _dbus_assert_not_reached ("shouldn't have failed to alloc memory to skip the deleted field");
00717
00718 _dbus_verbose (" Skipping %s field which will be deleted; next_offset = %d\n",
00719 _dbus_header_field_to_string (field_name), next_offset);
00720
00721
00722 if (field_name <= DBUS_HEADER_FIELD_LAST)
00723 {
00724 new_header_fields[field_name].name_offset = -1;
00725 new_header_fields[field_name].value_offset = -1;
00726 }
00727
00728 while (next_offset < _dbus_string_get_length (&message->header))
00729 {
00730 int copy_name_offset;
00731 int copy_value_offset;
00732
00733 if (!iterate_one_field (&message->header,
00734 message->byte_order,
00735 next_offset,
00736 &next_offset,
00737 &field_name,
00738 ©,
00739 ©_name_offset,
00740 ©_value_offset))
00741 {
00742 _dbus_verbose ("%s: OOM iterating one field\n",
00743 _DBUS_FUNCTION_NAME);
00744 goto out_1;
00745 }
00746
00747 if (field_name <= DBUS_HEADER_FIELD_LAST)
00748 {
00749 new_header_fields[field_name].name_offset = copy_name_offset - new_fields_front_padding + name_offset_to_delete;
00750 new_header_fields[field_name].value_offset = copy_value_offset - new_fields_front_padding + name_offset_to_delete;
00751
00752 _dbus_verbose (" Re-adding %s field at name_offset = %d value_offset = %d; next_offset = %d\n",
00753 _dbus_header_field_to_string (field_name),
00754 new_header_fields[field_name].name_offset,
00755 new_header_fields[field_name].value_offset,
00756 next_offset);
00757 }
00758 }
00759
00760 if (!_dbus_string_replace_len (©,
00761 new_fields_front_padding,
00762 _dbus_string_get_length (©) - new_fields_front_padding,
00763 &message->header,
00764 name_offset_to_delete,
00765 _dbus_string_get_length (&message->header) - name_offset_to_delete))
00766 {
00767 _dbus_verbose ("%s: OOM moving copy back into header\n",
00768 _DBUS_FUNCTION_NAME);
00769 goto out_1;
00770 }
00771
00772 memcpy (message->header_fields, new_header_fields,
00773 sizeof (new_header_fields));
00774 verify_header_fields (message);
00775
00776 retval = TRUE;
00777
00778 out_1:
00779 _dbus_string_free (©);
00780
00781 out_0:
00782 if (!append_header_padding (message))
00783 _dbus_assert_not_reached ("Failed to re-append header padding in re_align_field_recurse()");
00784
00785 return retval;
00786 }
00787
00788 static dbus_bool_t
00789 delete_field (DBusMessage *message,
00790 int field,
00791 int prealloc_header_space)
00792 {
00793 int offset;
00794
00795 _dbus_assert (!message->locked);
00796
00797
00798 if (!_dbus_string_lengthen (&message->header, prealloc_header_space))
00799 {
00800 _dbus_verbose ("failed to prealloc %d bytes header space\n",
00801 prealloc_header_space);
00802 return FALSE;
00803 }
00804 _dbus_string_shorten (&message->header, prealloc_header_space);
00805
00806
00807 offset = message->header_fields[field].name_offset;
00808 if (offset < 0)
00809 {
00810 _dbus_verbose ("header field didn't exist, no need to delete\n");
00811 return TRUE;
00812 }
00813
00814 return delete_one_and_re_align (message, offset);
00815 }
00816
00817 #ifdef DBUS_BUILD_TESTS
00818 static dbus_bool_t
00819 set_int_field (DBusMessage *message,
00820 int field,
00821 int value)
00822 {
00823 int offset = message->header_fields[field].value_offset;
00824
00825 _dbus_assert (!message->locked);
00826
00827 _dbus_verbose ("set_int_field() field %d value '%d'\n",
00828 field, value);
00829
00830 if (offset < 0)
00831 {
00832
00833 return append_int_field (message, field, value);
00834 }
00835 else
00836 {
00837 _dbus_marshal_set_int32 (&message->header,
00838 message->byte_order,
00839 offset, value);
00840
00841 return TRUE;
00842 }
00843 }
00844 #endif
00845
00846 static dbus_bool_t
00847 set_uint_field (DBusMessage *message,
00848 int field,
00849 dbus_uint32_t value)
00850 {
00851 int offset = message->header_fields[field].value_offset;
00852
00853 _dbus_assert (!message->locked);
00854
00855 _dbus_verbose ("set_uint_field() field %d value '%u'\n",
00856 field, value);
00857
00858 if (offset < 0)
00859 {
00860
00861 return append_uint_field (message, field, value);
00862 }
00863 else
00864 {
00865 _dbus_marshal_set_uint32 (&message->header,
00866 message->byte_order,
00867 offset, value);
00868
00869 return TRUE;
00870 }
00871 }
00872
00873 static dbus_bool_t
00874 set_string_field (DBusMessage *message,
00875 int field,
00876 int type,
00877 const char *value)
00878 {
00879 int prealloc;
00880 int value_len;
00881
00882 _dbus_assert (!message->locked);
00883
00884 value_len = value ? strlen (value) : 0;
00885
00886
00887
00888
00889 prealloc = value_len + MAX_BYTES_OVERHEAD_TO_APPEND_A_STRING;
00890
00891 _dbus_verbose ("set_string_field() field %d prealloc %d value '%s'\n",
00892 field, prealloc, value);
00893
00894 if (!delete_field (message, field, prealloc))
00895 return FALSE;
00896
00897 if (value != NULL)
00898 {
00899
00900 if (!append_string_field_len (message, field, type, value, value_len))
00901 _dbus_assert_not_reached ("Appending string field shouldn't have failed, due to preallocation");
00902 }
00903
00904 return TRUE;
00905 }
00906
00914 void
00915 _dbus_message_set_serial (DBusMessage *message,
00916 dbus_int32_t serial)
00917 {
00918 _dbus_assert (!message->locked);
00919 _dbus_assert (dbus_message_get_serial (message) == 0);
00920
00921 _dbus_marshal_set_uint32 (&message->header,
00922 message->byte_order,
00923 CLIENT_SERIAL_OFFSET,
00924 serial);
00925
00926 message->client_serial = serial;
00927 }
00928
00937 dbus_bool_t
00938 dbus_message_set_reply_serial (DBusMessage *message,
00939 dbus_uint32_t reply_serial)
00940 {
00941 _dbus_assert (!message->locked);
00942
00943 if (set_uint_field (message,
00944 DBUS_HEADER_FIELD_REPLY_SERIAL,
00945 reply_serial))
00946 {
00947 message->reply_serial = reply_serial;
00948 return TRUE;
00949 }
00950 else
00951 return FALSE;
00952 }
00953
00964 dbus_uint32_t
00965 dbus_message_get_serial (DBusMessage *message)
00966 {
00967 return message->client_serial;
00968 }
00969
00976 dbus_uint32_t
00977 dbus_message_get_reply_serial (DBusMessage *message)
00978 {
00979 return message->reply_serial;
00980 }
00981
00994 void
00995 _dbus_message_add_size_counter_link (DBusMessage *message,
00996 DBusList *link)
00997 {
00998
00999
01000
01001
01002
01003
01004 if (message->size_counters == NULL)
01005 {
01006 message->size_counter_delta =
01007 _dbus_string_get_length (&message->header) +
01008 _dbus_string_get_length (&message->body);
01009
01010 #if 0
01011 _dbus_verbose ("message has size %ld\n",
01012 message->size_counter_delta);
01013 #endif
01014 }
01015
01016 _dbus_list_append_link (&message->size_counters, link);
01017
01018 _dbus_counter_adjust (link->data, message->size_counter_delta);
01019 }
01020
01030 dbus_bool_t
01031 _dbus_message_add_size_counter (DBusMessage *message,
01032 DBusCounter *counter)
01033 {
01034 DBusList *link;
01035
01036 link = _dbus_list_alloc_link (counter);
01037 if (link == NULL)
01038 return FALSE;
01039
01040 _dbus_counter_ref (counter);
01041 _dbus_message_add_size_counter_link (message, link);
01042
01043 return TRUE;
01044 }
01045
01054 void
01055 _dbus_message_remove_size_counter (DBusMessage *message,
01056 DBusCounter *counter,
01057 DBusList **link_return)
01058 {
01059 DBusList *link;
01060
01061 link = _dbus_list_find_last (&message->size_counters,
01062 counter);
01063 _dbus_assert (link != NULL);
01064
01065 _dbus_list_unlink (&message->size_counters,
01066 link);
01067 if (link_return)
01068 *link_return = link;
01069 else
01070 _dbus_list_free_link (link);
01071
01072 _dbus_counter_adjust (counter, - message->size_counter_delta);
01073
01074 _dbus_counter_unref (counter);
01075 }
01076
01077 static dbus_bool_t
01078 dbus_message_create_header (DBusMessage *message,
01079 int type,
01080 const char *service,
01081 const char *path,
01082 const char *interface,
01083 const char *member,
01084 const char *error_name)
01085 {
01086 unsigned int flags;
01087
01088 _dbus_assert ((interface && member) ||
01089 (error_name) ||
01090 !(interface || member || error_name));
01091 _dbus_assert (error_name == NULL || is_valid_error_name (error_name));
01092
01093 if (!_dbus_string_append_byte (&message->header, message->byte_order))
01094 return FALSE;
01095
01096 if (!_dbus_string_append_byte (&message->header, type))
01097 return FALSE;
01098
01099 flags = 0;
01100 if (!_dbus_string_append_byte (&message->header, flags))
01101 return FALSE;
01102
01103 if (!_dbus_string_append_byte (&message->header, DBUS_MAJOR_PROTOCOL_VERSION))
01104 return FALSE;
01105
01106
01107 if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0))
01108 return FALSE;
01109
01110
01111 if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0))
01112 return FALSE;
01113
01114
01115 if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0))
01116 return FALSE;
01117
01118
01119
01120 if (path != NULL)
01121 {
01122 if (!append_string_field (message,
01123 DBUS_HEADER_FIELD_PATH,
01124 DBUS_TYPE_OBJECT_PATH,
01125 path))
01126 return FALSE;
01127 }
01128
01129 if (service != NULL)
01130 {
01131 if (!append_string_field (message,
01132 DBUS_HEADER_FIELD_DESTINATION,
01133 DBUS_TYPE_STRING,
01134 service))
01135 return FALSE;
01136 }
01137
01138 if (interface != NULL)
01139 {
01140 if (!append_string_field (message,
01141 DBUS_HEADER_FIELD_INTERFACE,
01142 DBUS_TYPE_STRING,
01143 interface))
01144 return FALSE;
01145 }
01146
01147 if (member != NULL)
01148 {
01149 if (!append_string_field (message,
01150 DBUS_HEADER_FIELD_MEMBER,
01151 DBUS_TYPE_STRING,
01152 member))
01153 return FALSE;
01154 }
01155
01156 if (error_name != NULL)
01157 {
01158 if (!append_string_field (message,
01159 DBUS_HEADER_FIELD_ERROR_NAME,
01160 DBUS_TYPE_STRING,
01161 error_name))
01162 return FALSE;
01163 }
01164
01165
01166
01167
01168 if (!append_string_field (message,
01169 DBUS_HEADER_FIELD_SIGNATURE,
01170 DBUS_TYPE_STRING,
01171 ""))
01172 return FALSE;
01173
01174 return TRUE;
01175 }
01176
01186 void
01187 _dbus_message_lock (DBusMessage *message)
01188 {
01189 if (!message->locked)
01190 {
01191
01192 _dbus_marshal_set_uint32 (&message->header,
01193 message->byte_order,
01194 HEADER_LENGTH_OFFSET,
01195 _dbus_string_get_length (&message->header));
01196
01197 _dbus_marshal_set_uint32 (&message->header,
01198 message->byte_order,
01199 BODY_LENGTH_OFFSET,
01200 _dbus_string_get_length (&message->body));
01201
01202 message->locked = TRUE;
01203 }
01204 }
01205
01237 static dbus_bool_t
01238 dbus_message_set_signature (DBusMessage *message,
01239 const char *signature)
01240 {
01241 _dbus_return_val_if_fail (message != NULL, FALSE);
01242 _dbus_return_val_if_fail (!message->locked, FALSE);
01243
01244 return set_string_field (message,
01245 DBUS_HEADER_FIELD_SIGNATURE,
01246 DBUS_TYPE_STRING,
01247 signature);
01248 }
01249
01258 static dbus_bool_t
01259 dbus_message_append_to_signature (DBusMessage *message,
01260 const char *append_bytes)
01261 {
01262 const char *signature;
01263 DBusString append_str;
01264 dbus_bool_t retval;
01265
01266 _dbus_return_val_if_fail (append_bytes != NULL, FALSE);
01267 _dbus_return_val_if_fail (message != NULL, FALSE);
01268 _dbus_return_val_if_fail (!message->locked, FALSE);
01269
01270 retval = FALSE;
01271
01272
01273
01274
01275 signature = dbus_message_get_signature (message);
01276
01277 if (!_dbus_string_init (&append_str))
01278 return FALSE;
01279
01280 if (signature && !_dbus_string_append (&append_str, signature))
01281 goto out;
01282
01283 if (!_dbus_string_append (&append_str, append_bytes))
01284 goto out;
01285
01286 if (!set_string_field (message,
01287 DBUS_HEADER_FIELD_SIGNATURE,
01288 DBUS_TYPE_STRING,
01289 _dbus_string_get_const_data (&append_str)))
01290 goto out;
01291
01292 retval = TRUE;
01293
01294 out:
01295
01296 _dbus_string_free (&append_str);
01297
01298 return retval;
01299 }
01300
01309 static dbus_bool_t
01310 _dbus_message_append_byte_to_signature (DBusMessage *message,
01311 unsigned char append_byte)
01312 {
01313 char buf[2];
01314
01315 _dbus_return_val_if_fail (message != NULL, FALSE);
01316 _dbus_return_val_if_fail (!message->locked, FALSE);
01317
01318 buf[0] = append_byte;
01319 buf[1] = '\0';
01320
01321 return dbus_message_append_to_signature (message, buf);
01322 }
01323
01330 static void
01331 _dbus_message_remove_byte_from_signature (DBusMessage *message)
01332 {
01333 const char *signature;
01334
01335 _dbus_return_if_fail (message != NULL);
01336 _dbus_return_if_fail (!message->locked);
01337
01338 signature = dbus_message_get_signature (message);
01339
01340 _dbus_return_if_fail (signature != NULL);
01341
01342 if (!delete_field (message,
01343 DBUS_HEADER_FIELD_SIGNATURE,
01344 0))
01345 _dbus_assert_not_reached ("failed to delete signature field");
01346
01347
01348
01349
01350 if (!append_string_field_len (message, DBUS_HEADER_FIELD_SIGNATURE,
01351 DBUS_TYPE_STRING, signature,
01352 strlen (signature) - 1))
01353 _dbus_assert_not_reached ("reappending shorter signature shouldn't have failed");
01354 }
01355
01363 static void
01364 free_size_counter (void *element,
01365 void *data)
01366 {
01367 DBusCounter *counter = element;
01368 DBusMessage *message = data;
01369
01370 _dbus_counter_adjust (counter, - message->size_counter_delta);
01371
01372 _dbus_counter_unref (counter);
01373 }
01374
01375 static void
01376 dbus_message_finalize (DBusMessage *message)
01377 {
01378 _dbus_assert (message->refcount.value == 0);
01379
01380
01381 _dbus_data_slot_list_free (&message->slot_list);
01382
01383 _dbus_list_foreach (&message->size_counters,
01384 free_size_counter, message);
01385 _dbus_list_clear (&message->size_counters);
01386
01387 _dbus_string_free (&message->header);
01388 _dbus_string_free (&message->body);
01389
01390 dbus_free (message);
01391 }
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440 #define MAX_MESSAGE_SIZE_TO_CACHE _DBUS_ONE_MEGABYTE
01441
01442 #define MAX_MESSAGE_CACHE_SIZE 5
01443
01444 _DBUS_DEFINE_GLOBAL_LOCK (message_cache);
01445 static DBusMessage *message_cache[MAX_MESSAGE_CACHE_SIZE];
01446 static int message_cache_count = 0;
01447 static dbus_bool_t message_cache_shutdown_registered = FALSE;
01448
01449 static void
01450 dbus_message_cache_shutdown (void *data)
01451 {
01452 int i;
01453
01454 _DBUS_LOCK (message_cache);
01455
01456 i = 0;
01457 while (i < MAX_MESSAGE_CACHE_SIZE)
01458 {
01459 if (message_cache[i])
01460 dbus_message_finalize (message_cache[i]);
01461
01462 ++i;
01463 }
01464
01465 message_cache_count = 0;
01466 message_cache_shutdown_registered = FALSE;
01467
01468 _DBUS_UNLOCK (message_cache);
01469 }
01470
01478 static DBusMessage*
01479 dbus_message_get_cached (void)
01480 {
01481 DBusMessage *message;
01482 int i;
01483
01484 message = NULL;
01485
01486 _DBUS_LOCK (message_cache);
01487
01488 _dbus_assert (message_cache_count >= 0);
01489
01490 if (message_cache_count == 0)
01491 {
01492 _DBUS_UNLOCK (message_cache);
01493 return NULL;
01494 }
01495
01496
01497
01498
01499
01500 _dbus_assert (message_cache_shutdown_registered);
01501
01502 i = 0;
01503 while (i < MAX_MESSAGE_CACHE_SIZE)
01504 {
01505 if (message_cache[i])
01506 {
01507 message = message_cache[i];
01508 message_cache[i] = NULL;
01509 message_cache_count -= 1;
01510 break;
01511 }
01512 ++i;
01513 }
01514 _dbus_assert (message_cache_count >= 0);
01515 _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
01516 _dbus_assert (message != NULL);
01517
01518 _DBUS_UNLOCK (message_cache);
01519
01520 _dbus_assert (message->refcount.value == 0);
01521 _dbus_assert (message->size_counters == NULL);
01522
01523 return message;
01524 }
01525
01531 static void
01532 dbus_message_cache_or_finalize (DBusMessage *message)
01533 {
01534 dbus_bool_t was_cached;
01535 int i;
01536
01537 _dbus_assert (message->refcount.value == 0);
01538
01539
01540
01541
01542 _dbus_data_slot_list_clear (&message->slot_list);
01543
01544 _dbus_list_foreach (&message->size_counters,
01545 free_size_counter, message);
01546 _dbus_list_clear (&message->size_counters);
01547
01548 was_cached = FALSE;
01549
01550 _DBUS_LOCK (message_cache);
01551
01552 if (!message_cache_shutdown_registered)
01553 {
01554 _dbus_assert (message_cache_count == 0);
01555
01556 if (!_dbus_register_shutdown_func (dbus_message_cache_shutdown, NULL))
01557 goto out;
01558
01559 i = 0;
01560 while (i < MAX_MESSAGE_CACHE_SIZE)
01561 {
01562 message_cache[i] = NULL;
01563 ++i;
01564 }
01565
01566 message_cache_shutdown_registered = TRUE;
01567 }
01568
01569 _dbus_assert (message_cache_count >= 0);
01570
01571 if ((_dbus_string_get_length (&message->header) +
01572 _dbus_string_get_length (&message->body)) >
01573 MAX_MESSAGE_SIZE_TO_CACHE)
01574 goto out;
01575
01576 if (message_cache_count >= MAX_MESSAGE_CACHE_SIZE)
01577 goto out;
01578
01579
01580 i = 0;
01581 while (message_cache[i] != NULL)
01582 ++i;
01583
01584 _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
01585
01586 _dbus_assert (message_cache[i] == NULL);
01587 message_cache[i] = message;
01588 message_cache_count += 1;
01589 was_cached = TRUE;
01590
01591 out:
01592 _DBUS_UNLOCK (message_cache);
01593
01594 if (!was_cached)
01595 dbus_message_finalize (message);
01596 }
01597
01598 static DBusMessage*
01599 dbus_message_new_empty_header (void)
01600 {
01601 DBusMessage *message;
01602 int i;
01603 dbus_bool_t from_cache;
01604
01605 message = dbus_message_get_cached ();
01606
01607 if (message != NULL)
01608 {
01609 from_cache = TRUE;
01610 }
01611 else
01612 {
01613 from_cache = FALSE;
01614 message = dbus_new (DBusMessage, 1);
01615 if (message == NULL)
01616 return NULL;
01617 #ifndef DBUS_DISABLE_CHECKS
01618 message->generation = _dbus_current_generation;
01619 #endif
01620 }
01621
01622 message->refcount.value = 1;
01623 message->byte_order = DBUS_COMPILER_BYTE_ORDER;
01624 message->client_serial = 0;
01625 message->reply_serial = 0;
01626 message->locked = FALSE;
01627 message->header_padding = 0;
01628 message->size_counters = NULL;
01629 message->size_counter_delta = 0;
01630 message->changed_stamp = 0;
01631
01632 if (!from_cache)
01633 _dbus_data_slot_list_init (&message->slot_list);
01634
01635 i = 0;
01636 while (i <= DBUS_HEADER_FIELD_LAST)
01637 {
01638 message->header_fields[i].name_offset = -1;
01639 message->header_fields[i].value_offset = -1;
01640 ++i;
01641 }
01642
01643 if (from_cache)
01644 {
01645
01646 _dbus_string_set_length (&message->header, 0);
01647 _dbus_string_set_length (&message->body, 0);
01648 }
01649 else
01650 {
01651 if (!_dbus_string_init_preallocated (&message->header, 32))
01652 {
01653 dbus_free (message);
01654 return NULL;
01655 }
01656
01657 if (!_dbus_string_init_preallocated (&message->body, 32))
01658 {
01659 _dbus_string_free (&message->header);
01660 dbus_free (message);
01661 return NULL;
01662 }
01663 }
01664
01665 return message;
01666 }
01667
01676 DBusMessage*
01677 dbus_message_new (int message_type)
01678 {
01679 DBusMessage *message;
01680
01681 _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
01682
01683 message = dbus_message_new_empty_header ();
01684 if (message == NULL)
01685 return NULL;
01686
01687 if (!dbus_message_create_header (message,
01688 message_type,
01689 NULL, NULL, NULL, NULL, NULL))
01690 {
01691 dbus_message_unref (message);
01692 return NULL;
01693 }
01694
01695 return message;
01696 }
01697
01715 DBusMessage*
01716 dbus_message_new_method_call (const char *service,
01717 const char *path,
01718 const char *interface,
01719 const char *method)
01720 {
01721 DBusMessage *message;
01722
01723 _dbus_return_val_if_fail (path != NULL, NULL);
01724 _dbus_return_val_if_fail (method != NULL, NULL);
01725
01726 message = dbus_message_new_empty_header ();
01727 if (message == NULL)
01728 return NULL;
01729
01730 if (!dbus_message_create_header (message,
01731 DBUS_MESSAGE_TYPE_METHOD_CALL,
01732 service, path, interface, method, NULL))
01733 {
01734 dbus_message_unref (message);
01735 return NULL;
01736 }
01737
01738 return message;
01739 }
01740
01750 DBusMessage*
01751 dbus_message_new_method_return (DBusMessage *method_call)
01752 {
01753 DBusMessage *message;
01754 const char *sender;
01755
01756 _dbus_return_val_if_fail (method_call != NULL, NULL);
01757
01758 sender = get_string_field (method_call,
01759 DBUS_HEADER_FIELD_SENDER,
01760 NULL);
01761
01762
01763
01764 message = dbus_message_new_empty_header ();
01765 if (message == NULL)
01766 return NULL;
01767
01768 if (!dbus_message_create_header (message,
01769 DBUS_MESSAGE_TYPE_METHOD_RETURN,
01770 sender, NULL, NULL, NULL, NULL))
01771 {
01772 dbus_message_unref (message);
01773 return NULL;
01774 }
01775
01776 dbus_message_set_no_reply (message, TRUE);
01777
01778 if (!dbus_message_set_reply_serial (message,
01779 dbus_message_get_serial (method_call)))
01780 {
01781 dbus_message_unref (message);
01782 return NULL;
01783 }
01784
01785 return message;
01786 }
01787
01800 DBusMessage*
01801 dbus_message_new_signal (const char *path,
01802 const char *interface,
01803 const char *name)
01804 {
01805 DBusMessage *message;
01806
01807 _dbus_return_val_if_fail (path != NULL, NULL);
01808 _dbus_return_val_if_fail (interface != NULL, NULL);
01809 _dbus_return_val_if_fail (name != NULL, NULL);
01810
01811 message = dbus_message_new_empty_header ();
01812 if (message == NULL)
01813 return NULL;
01814
01815 if (!dbus_message_create_header (message,
01816 DBUS_MESSAGE_TYPE_SIGNAL,
01817 NULL, path, interface, name, NULL))
01818 {
01819 dbus_message_unref (message);
01820 return NULL;
01821 }
01822
01823 dbus_message_set_no_reply (message, TRUE);
01824
01825 return message;
01826 }
01827
01837 DBusMessage*
01838 dbus_message_new_error (DBusMessage *reply_to,
01839 const char *error_name,
01840 const char *error_message)
01841 {
01842 DBusMessage *message;
01843 const char *sender;
01844 DBusMessageIter iter;
01845
01846 _dbus_return_val_if_fail (reply_to != NULL, NULL);
01847 _dbus_return_val_if_fail (error_name != NULL, NULL);
01848 _dbus_return_val_if_fail (is_valid_error_name (error_name), NULL);
01849
01850 sender = get_string_field (reply_to,
01851 DBUS_HEADER_FIELD_SENDER,
01852 NULL);
01853
01854
01855
01856
01857
01858 message = dbus_message_new_empty_header ();
01859 if (message == NULL)
01860 return NULL;
01861
01862 if (!dbus_message_create_header (message,
01863 DBUS_MESSAGE_TYPE_ERROR,
01864 sender, NULL, NULL, NULL, error_name))
01865 {
01866 dbus_message_unref (message);
01867 return NULL;
01868 }
01869
01870 dbus_message_set_no_reply (message, TRUE);
01871
01872 if (!dbus_message_set_reply_serial (message,
01873 dbus_message_get_serial (reply_to)))
01874 {
01875 dbus_message_unref (message);
01876 return NULL;
01877 }
01878
01879 if (error_message != NULL)
01880 {
01881 dbus_message_append_iter_init (message, &iter);
01882 if (!dbus_message_iter_append_string (&iter, error_message))
01883 {
01884 dbus_message_unref (message);
01885 return NULL;
01886 }
01887 }
01888
01889 return message;
01890 }
01891
01902 DBusMessage*
01903 dbus_message_new_error_printf (DBusMessage *reply_to,
01904 const char *error_name,
01905 const char *error_format,
01906 ...)
01907 {
01908 va_list args;
01909 DBusString str;
01910 DBusMessage *message;
01911
01912 _dbus_return_val_if_fail (reply_to != NULL, NULL);
01913 _dbus_return_val_if_fail (error_name != NULL, NULL);
01914 _dbus_return_val_if_fail (is_valid_error_name (error_name), NULL);
01915
01916 if (!_dbus_string_init (&str))
01917 return NULL;
01918
01919 va_start (args, error_format);
01920
01921 if (_dbus_string_append_printf_valist (&str, error_format, args))
01922 message = dbus_message_new_error (reply_to, error_name,
01923 _dbus_string_get_const_data (&str));
01924 else
01925 message = NULL;
01926
01927 _dbus_string_free (&str);
01928
01929 va_end (args);
01930
01931 return message;
01932 }
01933
01934
01942 DBusMessage *
01943 dbus_message_copy (const DBusMessage *message)
01944 {
01945 DBusMessage *retval;
01946 int i;
01947
01948 _dbus_return_val_if_fail (message != NULL, NULL);
01949
01950 retval = dbus_new0 (DBusMessage, 1);
01951 if (retval == NULL)
01952 return NULL;
01953
01954 retval->refcount.value = 1;
01955 retval->byte_order = message->byte_order;
01956 retval->client_serial = message->client_serial;
01957 retval->reply_serial = message->reply_serial;
01958 retval->header_padding = message->header_padding;
01959 retval->locked = FALSE;
01960 #ifndef DBUS_DISABLE_CHECKS
01961 retval->generation = message->generation;
01962 #endif
01963
01964 if (!_dbus_string_init_preallocated (&retval->header,
01965 _dbus_string_get_length (&message->header)))
01966 {
01967 dbus_free (retval);
01968 return NULL;
01969 }
01970
01971 if (!_dbus_string_init_preallocated (&retval->body,
01972 _dbus_string_get_length (&message->body)))
01973 {
01974 _dbus_string_free (&retval->header);
01975 dbus_free (retval);
01976 return NULL;
01977 }
01978
01979 if (!_dbus_string_copy (&message->header, 0,
01980 &retval->header, 0))
01981 goto failed_copy;
01982
01983 if (!_dbus_string_copy (&message->body, 0,
01984 &retval->body, 0))
01985 goto failed_copy;
01986
01987 for (i = 0; i <= DBUS_HEADER_FIELD_LAST; i++)
01988 {
01989 retval->header_fields[i] = message->header_fields[i];
01990 }
01991
01992 return retval;
01993
01994 failed_copy:
01995 _dbus_string_free (&retval->header);
01996 _dbus_string_free (&retval->body);
01997 dbus_free (retval);
01998
01999 return NULL;
02000 }
02001
02002
02010 DBusMessage *
02011 dbus_message_ref (DBusMessage *message)
02012 {
02013 dbus_int32_t old_refcount;
02014
02015 _dbus_return_val_if_fail (message != NULL, NULL);
02016 _dbus_return_val_if_fail (message->generation == _dbus_current_generation, NULL);
02017
02018 old_refcount = _dbus_atomic_inc (&message->refcount);
02019 _dbus_assert (old_refcount >= 1);
02020
02021 return message;
02022 }
02023
02030 void
02031 dbus_message_unref (DBusMessage *message)
02032 {
02033 dbus_int32_t old_refcount;
02034
02035 _dbus_return_if_fail (message != NULL);
02036 _dbus_return_if_fail (message->generation == _dbus_current_generation);
02037
02038 old_refcount = _dbus_atomic_dec (&message->refcount);
02039
02040 _dbus_assert (old_refcount >= 0);
02041
02042 if (old_refcount == 1)
02043 {
02044
02045 dbus_message_cache_or_finalize (message);
02046 }
02047 }
02048
02060 int
02061 dbus_message_get_type (DBusMessage *message)
02062 {
02063 int type;
02064
02065 type = _dbus_string_get_byte (&message->header, 1);
02066 _dbus_assert (type != DBUS_MESSAGE_TYPE_INVALID);
02067
02068 return type;
02069 }
02070
02080 dbus_bool_t
02081 dbus_message_set_path (DBusMessage *message,
02082 const char *object_path)
02083 {
02084 _dbus_return_val_if_fail (message != NULL, FALSE);
02085 _dbus_return_val_if_fail (!message->locked, FALSE);
02086
02087 return set_string_field (message,
02088 DBUS_HEADER_FIELD_PATH,
02089 DBUS_TYPE_OBJECT_PATH,
02090 object_path);
02091 }
02092
02101 const char*
02102 dbus_message_get_path (DBusMessage *message)
02103 {
02104 _dbus_return_val_if_fail (message != NULL, NULL);
02105
02106 return get_string_field (message, DBUS_HEADER_FIELD_PATH, NULL);
02107 }
02108
02124 dbus_bool_t
02125 dbus_message_get_path_decomposed (DBusMessage *message,
02126 char ***path)
02127 {
02128 _dbus_return_val_if_fail (message != NULL, FALSE);
02129 _dbus_return_val_if_fail (path != NULL, FALSE);
02130
02131 return get_path_field_decomposed (message,
02132 DBUS_HEADER_FIELD_PATH,
02133 path);
02134 }
02135
02146 dbus_bool_t
02147 dbus_message_set_interface (DBusMessage *message,
02148 const char *interface)
02149 {
02150 _dbus_return_val_if_fail (message != NULL, FALSE);
02151 _dbus_return_val_if_fail (!message->locked, FALSE);
02152
02153 return set_string_field (message,
02154 DBUS_HEADER_FIELD_INTERFACE,
02155 DBUS_TYPE_STRING,
02156 interface);
02157 }
02158
02168 const char*
02169 dbus_message_get_interface (DBusMessage *message)
02170 {
02171 _dbus_return_val_if_fail (message != NULL, NULL);
02172
02173 return get_string_field (message, DBUS_HEADER_FIELD_INTERFACE, NULL);
02174 }
02175
02186 dbus_bool_t
02187 dbus_message_set_member (DBusMessage *message,
02188 const char *member)
02189 {
02190 _dbus_return_val_if_fail (message != NULL, FALSE);
02191 _dbus_return_val_if_fail (!message->locked, FALSE);
02192
02193 return set_string_field (message,
02194 DBUS_HEADER_FIELD_MEMBER,
02195 DBUS_TYPE_STRING,
02196 member);
02197 }
02198
02207 const char*
02208 dbus_message_get_member (DBusMessage *message)
02209 {
02210 _dbus_return_val_if_fail (message != NULL, NULL);
02211
02212 return get_string_field (message,
02213 DBUS_HEADER_FIELD_MEMBER,
02214 NULL);
02215 }
02216
02225 dbus_bool_t
02226 dbus_message_set_error_name (DBusMessage *message,
02227 const char *error_name)
02228 {
02229 _dbus_return_val_if_fail (message != NULL, FALSE);
02230 _dbus_return_val_if_fail (!message->locked, FALSE);
02231 _dbus_return_val_if_fail (error_name == NULL || is_valid_error_name (error_name), FALSE);
02232
02233 return set_string_field (message,
02234 DBUS_HEADER_FIELD_ERROR_NAME,
02235 DBUS_TYPE_STRING,
02236 error_name);
02237 }
02238
02245 const char*
02246 dbus_message_get_error_name (DBusMessage *message)
02247 {
02248 _dbus_return_val_if_fail (message != NULL, NULL);
02249
02250 return get_string_field (message,
02251 DBUS_HEADER_FIELD_ERROR_NAME,
02252 NULL);
02253 }
02254
02262 dbus_bool_t
02263 dbus_message_set_destination (DBusMessage *message,
02264 const char *destination)
02265 {
02266 _dbus_return_val_if_fail (message != NULL, FALSE);
02267 _dbus_return_val_if_fail (!message->locked, FALSE);
02268
02269 return set_string_field (message,
02270 DBUS_HEADER_FIELD_DESTINATION,
02271 DBUS_TYPE_STRING,
02272 destination);
02273 }
02274
02281 const char*
02282 dbus_message_get_destination (DBusMessage *message)
02283 {
02284 _dbus_return_val_if_fail (message != NULL, NULL);
02285
02286 return get_string_field (message,
02287 DBUS_HEADER_FIELD_DESTINATION,
02288 NULL);
02289 }
02290
02309 dbus_bool_t
02310 dbus_message_append_args (DBusMessage *message,
02311 int first_arg_type,
02312 ...)
02313 {
02314 dbus_bool_t retval;
02315 va_list var_args;
02316
02317 _dbus_return_val_if_fail (message != NULL, FALSE);
02318
02319 va_start (var_args, first_arg_type);
02320 retval = dbus_message_append_args_valist (message,
02321 first_arg_type,
02322 var_args);
02323 va_end (var_args);
02324
02325 return retval;
02326 }
02327
02328
02329
02330
02331
02332 static void
02333 _dbus_message_ensure_our_byte_order (DBusMessage *message)
02334 {
02335 if (message->byte_order == DBUS_COMPILER_BYTE_ORDER)
02336 return;
02337
02338
02339
02340
02341 }
02342
02355 dbus_bool_t
02356 dbus_message_get_args (DBusMessage *message,
02357 DBusError *error,
02358 int first_arg_type,
02359 ...)
02360 {
02361 dbus_bool_t retval;
02362 va_list var_args;
02363
02364 _dbus_return_val_if_fail (message != NULL, FALSE);
02365 _dbus_return_val_if_error_is_set (error, FALSE);
02366
02367 va_start (var_args, first_arg_type);
02368 retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
02369 va_end (var_args);
02370
02371 return retval;
02372 }
02373
02386 dbus_bool_t
02387 dbus_message_get_args_valist (DBusMessage *message,
02388 DBusError *error,
02389 int first_arg_type,
02390 va_list var_args)
02391 {
02392 DBusMessageIter iter;
02393
02394 _dbus_return_val_if_fail (message != NULL, FALSE);
02395 _dbus_return_val_if_error_is_set (error, FALSE);
02396
02397 dbus_message_iter_init (message, &iter);
02398 return dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
02399 }
02400
02413 dbus_bool_t
02414 dbus_message_iter_get_args (DBusMessageIter *iter,
02415 DBusError *error,
02416 int first_arg_type,
02417 ...)
02418 {
02419 dbus_bool_t retval;
02420 va_list var_args;
02421
02422 _dbus_return_val_if_fail (iter != NULL, FALSE);
02423 _dbus_return_val_if_error_is_set (error, FALSE);
02424
02425 va_start (var_args, first_arg_type);
02426 retval = dbus_message_iter_get_args_valist (iter, error, first_arg_type, var_args);
02427 va_end (var_args);
02428
02429 return retval;
02430 }
02431
02440 dbus_bool_t
02441 dbus_message_iter_init (DBusMessage *message,
02442 DBusMessageIter *iter)
02443 {
02444 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02445
02446 _dbus_return_val_if_fail (message != NULL, FALSE);
02447 _dbus_return_val_if_fail (iter != NULL, FALSE);
02448
02449 _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
02450
02451 real->message = message;
02452 real->parent_iter = NULL;
02453 real->changed_stamp = message->changed_stamp;
02454
02455 real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
02456 real->pos = 0;
02457 real->end = _dbus_string_get_length (&message->body);
02458
02459 real->container_start = 0;
02460 real->container_length_pos = 0;
02461 real->wrote_dict_key = 0;
02462 real->array_type_pos = 0;
02463
02464 return real->end > real->pos;
02465 }
02466
02467 #ifndef DBUS_DISABLE_CHECKS
02468 static dbus_bool_t
02469 dbus_message_iter_check (DBusMessageRealIter *iter)
02470 {
02471 if (iter == NULL)
02472 {
02473 _dbus_warn ("dbus iterator check failed: iterator is NULL\n");
02474 return FALSE;
02475 }
02476
02477 if (iter->changed_stamp != iter->message->changed_stamp)
02478 {
02479 _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message\n");
02480 return FALSE;
02481 }
02482
02483 if (iter->pos < 0 || iter->pos > iter->end)
02484 {
02485 _dbus_warn ("dbus iterator check failed: invalid position\n");
02486 return FALSE;
02487 }
02488
02489 return TRUE;
02490 }
02491 #endif
02492
02493 static int
02494 skip_array_type (DBusMessageRealIter *iter, int pos)
02495 {
02496 const char *data;
02497
02498 do
02499 {
02500 data = _dbus_string_get_const_data_len (&iter->message->body,
02501 pos++, 1);
02502 }
02503 while (*data == DBUS_TYPE_ARRAY);
02504
02505 return pos;
02506 }
02507
02508
02509
02510
02511 static int
02512 dbus_message_iter_get_data_start (DBusMessageRealIter *iter, int *type)
02513 {
02514 const char *data;
02515 int pos, len;
02516
02517 switch (iter->type)
02518 {
02519 case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
02520 data = _dbus_string_get_const_data_len (&iter->message->body,
02521 iter->pos, 1);
02522 if (_dbus_type_is_valid (*data))
02523 *type = *data;
02524 else
02525 *type = DBUS_TYPE_INVALID;
02526
02527 return skip_array_type (iter, iter->pos);
02528
02529 case DBUS_MESSAGE_ITER_TYPE_ARRAY:
02530 data = _dbus_string_get_const_data_len (&iter->message->body,
02531 iter->array_type_pos, 1);
02532 if (_dbus_type_is_valid (*data))
02533 *type = *data;
02534 else
02535 *type = DBUS_TYPE_INVALID;
02536
02537 return iter->pos;
02538
02539 case DBUS_MESSAGE_ITER_TYPE_DICT:
02540
02541 len = _dbus_demarshal_uint32 (&iter->message->body,
02542 iter->message->byte_order,
02543 iter->pos, &pos);
02544 pos = pos + len + 1;
02545
02546 data = _dbus_string_get_const_data_len (&iter->message->body,
02547 pos, 1);
02548 if (_dbus_type_is_valid (*data))
02549 *type = *data;
02550 else
02551 *type = DBUS_TYPE_INVALID;
02552
02553 return skip_array_type (iter, pos);
02554
02555 default:
02556 _dbus_assert_not_reached ("Invalid iter type");
02557 break;
02558 }
02559 *type = DBUS_TYPE_INVALID;
02560 return iter->pos;
02561 }
02562
02563
02571 dbus_bool_t
02572 dbus_message_iter_has_next (DBusMessageIter *iter)
02573 {
02574 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02575 int end_pos;
02576 int type, pos;
02577
02578 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02579
02580 if (real->pos >= real->end)
02581 return FALSE;
02582
02583 pos = dbus_message_iter_get_data_start (real, &type);
02584
02585 if (!_dbus_marshal_get_arg_end_pos (&real->message->body,
02586 real->message->byte_order,
02587 type, pos, &end_pos))
02588 return FALSE;
02589
02590 if (end_pos >= real->end)
02591 return FALSE;
02592
02593 return TRUE;
02594 }
02595
02602 dbus_bool_t
02603 dbus_message_iter_next (DBusMessageIter *iter)
02604 {
02605 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02606 int end_pos;
02607 int type, pos;
02608
02609 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02610
02611 pos = dbus_message_iter_get_data_start (real, &type);
02612
02613 if (!_dbus_marshal_get_arg_end_pos (&real->message->body,
02614 real->message->byte_order,
02615 type, pos, &end_pos))
02616 return FALSE;
02617
02618 if (end_pos >= real->end)
02619 return FALSE;
02620
02621 real->pos = end_pos;
02622
02623 return TRUE;
02624 }
02625
02633 int
02634 dbus_message_iter_get_arg_type (DBusMessageIter *iter)
02635 {
02636 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02637 int type, pos;
02638
02639 _dbus_return_val_if_fail (dbus_message_iter_check (real), DBUS_TYPE_INVALID);
02640
02641 if (real->pos >= real->end)
02642 {
02643 _dbus_verbose (" iterator at or beyond end of message\n");
02644 return DBUS_TYPE_INVALID;
02645 }
02646
02647 pos = dbus_message_iter_get_data_start (real, &type);
02648
02649 return type;
02650 }
02651
02652
02653
02654
02655 static int
02656 iter_get_array_type (DBusMessageRealIter *iter, int *array_type_pos)
02657 {
02658 const char *data;
02659 int _array_type_pos;
02660 int len, pos;
02661
02662 switch (iter->type)
02663 {
02664 case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
02665 _array_type_pos = iter->pos + 1;
02666 break;
02667 case DBUS_MESSAGE_ITER_TYPE_ARRAY:
02668 _array_type_pos = iter->array_type_pos + 1;
02669 break;
02670 case DBUS_MESSAGE_ITER_TYPE_DICT:
02671
02672 len = _dbus_demarshal_uint32 (&iter->message->body,
02673 iter->message->byte_order,
02674 iter->pos, &pos);
02675 pos = pos + len + 1;
02676 data = _dbus_string_get_const_data_len (&iter->message->body,
02677 pos + 1, 1);
02678 _array_type_pos = pos + 1;
02679 break;
02680 default:
02681 _dbus_assert_not_reached ("wrong iter type");
02682 return DBUS_TYPE_INVALID;
02683 }
02684
02685 if (array_type_pos != NULL)
02686 *array_type_pos = _array_type_pos;
02687
02688 data = _dbus_string_get_const_data_len (&iter->message->body,
02689 _array_type_pos, 1);
02690 if (_dbus_type_is_valid (*data))
02691 return *data;
02692
02693 return DBUS_TYPE_INVALID;
02694 }
02695
02696
02706 int
02707 dbus_message_iter_get_array_type (DBusMessageIter *iter)
02708 {
02709 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02710 int type, pos;
02711
02712 _dbus_return_val_if_fail (dbus_message_iter_check (real), DBUS_TYPE_INVALID);
02713
02714 if (real->pos >= real->end)
02715 return DBUS_TYPE_INVALID;
02716
02717 pos = dbus_message_iter_get_data_start (real, &type);
02718
02719 _dbus_assert (type == DBUS_TYPE_ARRAY);
02720
02721 return iter_get_array_type (real, NULL);
02722 }
02723
02724
02734 char *
02735 dbus_message_iter_get_string (DBusMessageIter *iter)
02736 {
02737 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02738 int type, pos;
02739
02740 _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
02741 pos = dbus_message_iter_get_data_start (real, &type);
02742
02743 _dbus_assert (type == DBUS_TYPE_STRING);
02744
02745 return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
02746 pos, NULL);
02747 }
02748
02758 char *
02759 dbus_message_iter_get_object_path (DBusMessageIter *iter)
02760 {
02761 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02762 int type, pos;
02763
02764 _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
02765
02766 pos = dbus_message_iter_get_data_start (real, &type);
02767
02768 _dbus_assert (type == DBUS_TYPE_OBJECT_PATH);
02769
02770 return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
02771 pos, NULL);
02772 }
02773
02787 dbus_bool_t
02788 dbus_message_iter_get_custom (DBusMessageIter *iter,
02789 char **name,
02790 unsigned char **value,
02791 int *len)
02792 {
02793 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02794 int type, pos;
02795 char *_name;
02796
02797 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
02798
02799 pos = dbus_message_iter_get_data_start (real, &type);
02800
02801 _dbus_assert (type == DBUS_TYPE_CUSTOM);
02802
02803 _name = _dbus_demarshal_string (&real->message->body, real->message->byte_order,
02804 pos, &pos);
02805
02806 if (_name == NULL)
02807 return FALSE;
02808
02809 if (!_dbus_demarshal_byte_array (&real->message->body, real->message->byte_order,
02810 pos, NULL, value, len))
02811 {
02812 dbus_free (_name);
02813 return FALSE;
02814 }
02815
02816 *name = _name;
02817
02818 return TRUE;
02819 }
02820
02821 static void
02822 _dbus_message_iter_get_basic_type (DBusMessageIter *iter,
02823 char type,
02824 void *value)
02825 {
02826 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
02827 int item_type, pos;
02828
02829 _dbus_return_if_fail (dbus_message_iter_check (real));
02830
02831 pos = dbus_message_iter_get_data_start (real, &item_type);
02832
02833 _dbus_assert (type == item_type);
02834
02835 _dbus_demarshal_basic_type (&real->message->body,
02836 type, value,
02837 real->message->byte_order,
02838 &pos);
02839 }
02840
02841
02864 dbus_bool_t
02865 dbus_message_iter_get_args_valist (DBusMessageIter *iter,
02866 DBusError *error,
02867 int first_arg_type,
02868 va_list var_args)
02869 {
02870 int spec_type, msg_type, i;
02871 dbus_bool_t retval;
02872
02873 _dbus_return_val_if_fail (iter != NULL, FALSE);
02874 _dbus_return_val_if_error_is_set (error, FALSE);
02875
02876 retval = FALSE;
02877
02878 spec_type = first_arg_type;
02879 i = 0;
02880
02881 while (spec_type != DBUS_TYPE_INVALID)
02882 {
02883 msg_type = dbus_message_iter_get_arg_type (iter);
02884
02885 if (msg_type != spec_type)
02886 {
02887 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
02888 "Argument %d is specified to be of type \"%s\", but "
02889 "is actually of type \"%s\"\n", i,
02890 _dbus_type_to_string (spec_type),
02891 _dbus_type_to_string (msg_type));
02892
02893 goto out;
02894 }
02895
02896 switch (spec_type)
02897 {
02898 case DBUS_TYPE_NIL:
02899 break;
02900 case DBUS_TYPE_BOOLEAN:
02901 {
02902 dbus_bool_t *ptr;
02903
02904 ptr = va_arg (var_args, dbus_bool_t *);
02905
02906 *ptr = dbus_message_iter_get_boolean (iter);
02907 break;
02908 }
02909 case DBUS_TYPE_BYTE:
02910 case DBUS_TYPE_INT32:
02911 case DBUS_TYPE_UINT32:
02912 #ifdef DBUS_HAVE_INT64
02913 case DBUS_TYPE_INT64:
02914 case DBUS_TYPE_UINT64:
02915 #endif
02916 case DBUS_TYPE_DOUBLE:
02917 {
02918 void *ptr = va_arg (var_args, double *);
02919 _dbus_message_iter_get_basic_type (iter, spec_type, ptr);
02920 break;
02921 }
02922
02923 case DBUS_TYPE_STRING:
02924 {
02925 char **ptr;
02926
02927 ptr = va_arg (var_args, char **);
02928
02929 *ptr = dbus_message_iter_get_string (iter);
02930
02931 if (!*ptr)
02932 {
02933 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02934 goto out;
02935 }
02936
02937 break;
02938 }
02939
02940 case DBUS_TYPE_OBJECT_PATH:
02941 {
02942 char **ptr;
02943
02944 ptr = va_arg (var_args, char **);
02945
02946 *ptr = dbus_message_iter_get_object_path (iter);
02947
02948 if (!*ptr)
02949 {
02950 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02951 goto out;
02952 }
02953
02954 break;
02955 }
02956
02957 case DBUS_TYPE_CUSTOM:
02958 {
02959 char **name;
02960 unsigned char **data;
02961 int *len;
02962
02963 name = va_arg (var_args, char **);
02964 data = va_arg (var_args, unsigned char **);
02965 len = va_arg (var_args, int *);
02966
02967 if (!dbus_message_iter_get_custom (iter, name, data, len))
02968 {
02969 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02970 goto out;
02971 }
02972 }
02973 break;
02974 case DBUS_TYPE_ARRAY:
02975 {
02976 void **data;
02977 int *len, type;
02978 dbus_bool_t err = FALSE;
02979
02980 type = va_arg (var_args, int);
02981 data = va_arg (var_args, void *);
02982 len = va_arg (var_args, int *);
02983
02984 _dbus_return_val_if_fail (data != NULL, FALSE);
02985 _dbus_return_val_if_fail (len != NULL, FALSE);
02986
02987 if (dbus_message_iter_get_array_type (iter) != type)
02988 {
02989 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
02990 "Argument %d is specified to be of type \"array of %s\", but "
02991 "is actually of type \"array of %s\"\n", i,
02992 _dbus_type_to_string (type),
02993 _dbus_type_to_string (dbus_message_iter_get_array_type (iter)));
02994 goto out;
02995 }
02996
02997 switch (type)
02998 {
02999 case DBUS_TYPE_BYTE:
03000 err = !dbus_message_iter_get_byte_array (iter, (unsigned char **)data, len);
03001 break;
03002 case DBUS_TYPE_BOOLEAN:
03003 err = !dbus_message_iter_get_boolean_array (iter, (unsigned char **)data, len);
03004 break;
03005 case DBUS_TYPE_INT32:
03006 err = !dbus_message_iter_get_int32_array (iter, (dbus_int32_t **)data, len);
03007 break;
03008 case DBUS_TYPE_UINT32:
03009 err = !dbus_message_iter_get_uint32_array (iter, (dbus_uint32_t **)data, len);
03010 break;
03011 #ifdef DBUS_HAVE_INT64
03012 case DBUS_TYPE_INT64:
03013 err = !dbus_message_iter_get_int64_array (iter, (dbus_int64_t **)data, len);
03014 break;
03015 case DBUS_TYPE_UINT64:
03016 err = !dbus_message_iter_get_uint64_array (iter, (dbus_uint64_t **)data, len);
03017 break;
03018 #endif
03019 case DBUS_TYPE_DOUBLE:
03020 err = !dbus_message_iter_get_double_array (iter, (double **)data, len);
03021 break;
03022 case DBUS_TYPE_STRING:
03023 err = !dbus_message_iter_get_string_array (iter, (char ***)data, len);
03024 break;
03025 case DBUS_TYPE_OBJECT_PATH:
03026 err = !dbus_message_iter_get_object_path_array (iter, (char ***)data, len);
03027 break;
03028
03029 case DBUS_TYPE_NIL:
03030 case DBUS_TYPE_ARRAY:
03031 case DBUS_TYPE_CUSTOM:
03032 case DBUS_TYPE_DICT:
03033 _dbus_warn ("dbus_message_get_args_valist doesn't support recursive arrays\n");
03034 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
03035 goto out;
03036 default:
03037 _dbus_warn ("Unknown field type %d\n", type);
03038 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
03039 goto out;
03040 }
03041 if (err)
03042 {
03043 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
03044 goto out;
03045 }
03046 }
03047 break;
03048 case DBUS_TYPE_DICT:
03049 _dbus_warn ("dbus_message_get_args_valist doesn't support dicts\n");
03050 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
03051 goto out;
03052 default:
03053 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
03054 _dbus_warn ("Unknown field type %d\n", spec_type);
03055 goto out;
03056 }
03057
03058 spec_type = va_arg (var_args, int);
03059 if (!dbus_message_iter_next (iter) && spec_type != DBUS_TYPE_INVALID)
03060 {
03061 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
03062 "Message has only %d arguments, but more were expected", i);
03063 goto out;
03064 }
03065
03066 i++;
03067 }
03068
03069 retval = TRUE;
03070
03071 out:
03072
03073 return retval;
03074 }
03075
03085 unsigned char
03086 dbus_message_iter_get_byte (DBusMessageIter *iter)
03087 {
03088 unsigned char value = 0;
03089
03090 _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_BYTE, &value);
03091
03092 return value;
03093 }
03094
03104 dbus_bool_t
03105 dbus_message_iter_get_boolean (DBusMessageIter *iter)
03106 {
03107 unsigned char value = 0;
03108
03109 _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_BOOLEAN, &value);
03110
03111 return (value != FALSE);
03112 }
03113
03123 dbus_int32_t
03124 dbus_message_iter_get_int32 (DBusMessageIter *iter)
03125 {
03126 dbus_int32_t value = 0;
03127
03128 _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_INT32, &value);
03129
03130 return value;
03131 }
03132
03142 dbus_uint32_t
03143 dbus_message_iter_get_uint32 (DBusMessageIter *iter)
03144 {
03145 dbus_int32_t value = 0;
03146
03147 _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_UINT32, &value);
03148
03149 return value;
03150 }
03151
03152 #ifdef DBUS_HAVE_INT64
03153
03165 dbus_int64_t
03166 dbus_message_iter_get_int64 (DBusMessageIter *iter)
03167 {
03168 dbus_int64_t value = 0;
03169
03170 _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_INT64, &value);
03171
03172 return value;
03173 }
03174
03186 dbus_uint64_t
03187 dbus_message_iter_get_uint64 (DBusMessageIter *iter)
03188 {
03189 dbus_uint64_t value = 0;
03190
03191 _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_UINT64, &value);
03192
03193 return value;
03194 }
03195
03196 #endif
03197
03207 double
03208 dbus_message_iter_get_double (DBusMessageIter *iter)
03209 {
03210 double value = 0.0;
03211
03212 _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_DOUBLE, &value);
03213
03214 return value;
03215 }
03216
03230 dbus_bool_t
03231 dbus_message_iter_init_array_iterator (DBusMessageIter *iter,
03232 DBusMessageIter *array_iter,
03233 int *array_type)
03234 {
03235 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03236 DBusMessageRealIter *array_real = (DBusMessageRealIter *)array_iter;
03237 int type, pos, len_pos, len, array_type_pos;
03238 int _array_type;
03239
03240 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03241
03242 pos = dbus_message_iter_get_data_start (real, &type);
03243
03244 _dbus_assert (type == DBUS_TYPE_ARRAY);
03245
03246 _array_type = iter_get_array_type (real, &array_type_pos);
03247
03248 len_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
03249 len = _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order,
03250 pos, &pos);
03251
03252 array_real->parent_iter = real;
03253 array_real->message = real->message;
03254 array_real->changed_stamp = real->message->changed_stamp;
03255
03256 array_real->type = DBUS_MESSAGE_ITER_TYPE_ARRAY;
03257 array_real->pos = pos;
03258 array_real->end = pos + len;
03259
03260 array_real->container_start = pos;
03261 array_real->container_length_pos = len_pos;
03262 array_real->wrote_dict_key = 0;
03263 array_real->array_type_pos = array_type_pos;
03264 array_real->array_type_done = TRUE;
03265
03266 if (array_type != NULL)
03267 *array_type = _array_type;
03268
03269 return len > 0;
03270 }
03271
03272
03282 dbus_bool_t
03283 dbus_message_iter_init_dict_iterator (DBusMessageIter *iter,
03284 DBusMessageIter *dict_iter)
03285 {
03286 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03287 DBusMessageRealIter *dict_real = (DBusMessageRealIter *)dict_iter;
03288 int type, pos, len_pos, len;
03289
03290 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03291
03292 pos = dbus_message_iter_get_data_start (real, &type);
03293
03294 _dbus_assert (type == DBUS_TYPE_DICT);
03295
03296 len_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
03297 len = _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order,
03298 pos, &pos);
03299
03300 dict_real->parent_iter = real;
03301 dict_real->message = real->message;
03302 dict_real->changed_stamp = real->message->changed_stamp;
03303
03304 dict_real->type = DBUS_MESSAGE_ITER_TYPE_DICT;
03305 dict_real->pos = pos;
03306 dict_real->end = pos + len;
03307
03308 dict_real->container_start = pos;
03309 dict_real->container_length_pos = len_pos;
03310 dict_real->wrote_dict_key = 0;
03311
03312 return len > 0;
03313 }
03314
03315 static dbus_bool_t
03316 _dbus_message_iter_get_basic_type_array (DBusMessageIter *iter,
03317 char type,
03318 void **array,
03319 int *array_len)
03320 {
03321 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03322 int item_type, pos;
03323
03324 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03325
03326 pos = dbus_message_iter_get_data_start (real, &item_type);
03327
03328 _dbus_assert (item_type == DBUS_TYPE_ARRAY);
03329
03330 item_type = iter_get_array_type (real, NULL);
03331
03332 _dbus_assert (type == item_type);
03333
03334 return _dbus_demarshal_basic_type_array (&real->message->body,
03335 item_type, array, array_len,
03336 real->message->byte_order, &pos);
03337 }
03338
03349 dbus_bool_t
03350 dbus_message_iter_get_byte_array (DBusMessageIter *iter,
03351 unsigned char **value,
03352 int *len)
03353 {
03354 return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_BYTE,
03355 (void **) value, len);
03356 }
03357
03368 dbus_bool_t
03369 dbus_message_iter_get_boolean_array (DBusMessageIter *iter,
03370 unsigned char **value,
03371 int *len)
03372 {
03373 return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_BOOLEAN,
03374 (void **) value, len);
03375 }
03376
03387 dbus_bool_t
03388 dbus_message_iter_get_int32_array (DBusMessageIter *iter,
03389 dbus_int32_t **value,
03390 int *len)
03391 {
03392 return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT32,
03393 (void **) value, len);
03394 }
03395
03406 dbus_bool_t
03407 dbus_message_iter_get_uint32_array (DBusMessageIter *iter,
03408 dbus_uint32_t **value,
03409 int *len)
03410 {
03411 return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT32,
03412 (void **) value, len);
03413 }
03414
03415 #ifdef DBUS_HAVE_INT64
03416
03429 dbus_bool_t
03430 dbus_message_iter_get_int64_array (DBusMessageIter *iter,
03431 dbus_int64_t **value,
03432 int *len)
03433 {
03434 return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT64,
03435 (void **) value, len);
03436 }
03437
03450 dbus_bool_t
03451 dbus_message_iter_get_uint64_array (DBusMessageIter *iter,
03452 dbus_uint64_t **value,
03453 int *len)
03454 {
03455 return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT64,
03456 (void **) value, len);
03457 }
03458
03459 #endif
03460
03471 dbus_bool_t
03472 dbus_message_iter_get_double_array (DBusMessageIter *iter,
03473 double **value,
03474 int *len)
03475 {
03476 return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_DOUBLE,
03477 (void **) value, len);
03478 }
03479
03495 dbus_bool_t
03496 dbus_message_iter_get_string_array (DBusMessageIter *iter,
03497 char ***value,
03498 int *len)
03499 {
03500 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03501 int type, pos;
03502
03503 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03504
03505 pos = dbus_message_iter_get_data_start (real, &type);
03506
03507 _dbus_assert (type == DBUS_TYPE_ARRAY);
03508
03509 type = iter_get_array_type (real, NULL);
03510 _dbus_assert (type == DBUS_TYPE_STRING);
03511
03512 if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03513 pos, NULL, value, len))
03514 return FALSE;
03515 else
03516 return TRUE;
03517 }
03518
03534 dbus_bool_t
03535 dbus_message_iter_get_object_path_array (DBusMessageIter *iter,
03536 char ***value,
03537 int *len)
03538 {
03539 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03540 int type, pos;
03541
03542 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
03543
03544 pos = dbus_message_iter_get_data_start (real, &type);
03545
03546 _dbus_assert (type == DBUS_TYPE_ARRAY);
03547
03548 type = iter_get_array_type (real, NULL);
03549 _dbus_assert (type == DBUS_TYPE_OBJECT_PATH);
03550
03551 if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
03552 pos, NULL, value, len))
03553 return FALSE;
03554 else
03555 return TRUE;
03556 }
03557
03567 char *
03568 dbus_message_iter_get_dict_key (DBusMessageIter *iter)
03569 {
03570 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03571
03572 _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
03573
03574 _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
03575
03576 return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
03577 real->pos, NULL);
03578 }
03579
03588 void
03589 dbus_message_append_iter_init (DBusMessage *message,
03590 DBusMessageIter *iter)
03591 {
03592 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03593
03594 _dbus_return_if_fail (message != NULL);
03595 _dbus_return_if_fail (iter != NULL);
03596
03597 real->message = message;
03598 real->parent_iter = NULL;
03599 real->changed_stamp = message->changed_stamp;
03600
03601 real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
03602 real->end = _dbus_string_get_length (&real->message->body);
03603 real->pos = real->end;
03604
03605 real->container_length_pos = 0;
03606 real->wrote_dict_key = 0;
03607 }
03608
03609 #ifndef DBUS_DISABLE_CHECKS
03610 static dbus_bool_t
03611 dbus_message_iter_append_check (DBusMessageRealIter *iter)
03612 {
03613 if (iter == NULL)
03614 {
03615 _dbus_warn ("dbus iterator check failed: NULL iterator\n");
03616 return FALSE;
03617 }
03618
03619 if (iter->message->locked)
03620 {
03621 _dbus_warn ("dbus iterator check failed: message is locked (has already been sent)\n");
03622 return FALSE;
03623 }
03624
03625 if (iter->changed_stamp != iter->message->changed_stamp)
03626 {
03627 _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message");
03628 return FALSE;
03629 }
03630
03631 if (iter->pos != iter->end)
03632 {
03633 _dbus_warn ("dbus iterator check failed: can only append at end of message");
03634 return FALSE;
03635 }
03636
03637 if (iter->pos != _dbus_string_get_length (&iter->message->body))
03638 {
03639 _dbus_warn ("dbus iterator check failed: append pos not at end of message string");
03640 return FALSE;
03641 }
03642
03643 return TRUE;
03644 }
03645 #endif
03646
03647 static dbus_bool_t
03648 dbus_message_iter_append_type (DBusMessageRealIter *iter,
03649 int type)
03650 {
03651 const char *data;
03652
03653 switch (iter->type)
03654 {
03655 case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
03656 if (!_dbus_string_append_byte (&iter->message->body, type))
03657 return FALSE;
03658
03659 if (!_dbus_message_append_byte_to_signature (iter->message, type))
03660 {
03661 _dbus_string_shorten (&iter->message->body, 1);
03662 return FALSE;
03663 }
03664 break;
03665
03666 case DBUS_MESSAGE_ITER_TYPE_ARRAY:
03667 data = _dbus_string_get_const_data_len (&iter->message->body,
03668 iter->array_type_pos, 1);
03669 if (type != *data)
03670 {
03671 _dbus_warn ("Appended element of wrong type for array\n");
03672 return FALSE;
03673 }
03674 break;
03675
03676 case DBUS_MESSAGE_ITER_TYPE_DICT:
03677 if (!iter->wrote_dict_key)
03678 {
03679 _dbus_warn ("Appending dict data before key name\n");
03680 return FALSE;
03681 }
03682
03683 if (!_dbus_string_append_byte (&iter->message->body, type))
03684 return FALSE;
03685
03686 break;
03687
03688 default:
03689 _dbus_assert_not_reached ("Invalid iter type");
03690 break;
03691 }
03692
03693 return TRUE;
03694 }
03695
03696 static void
03697 dbus_message_iter_update_after_change (DBusMessageRealIter *iter)
03698 {
03699 iter->changed_stamp = iter->message->changed_stamp;
03700
03701
03702 iter->end = _dbus_string_get_length (&iter->message->body);
03703 iter->pos = iter->end;
03704
03705
03706 if (iter->type == DBUS_MESSAGE_ITER_TYPE_DICT ||
03707 (iter->type == DBUS_MESSAGE_ITER_TYPE_ARRAY && iter->array_type_done))
03708 _dbus_marshal_set_uint32 (&iter->message->body,
03709 iter->message->byte_order,
03710 iter->container_length_pos,
03711 iter->end - iter->container_start);
03712
03713 if (iter->parent_iter)
03714 dbus_message_iter_update_after_change (iter->parent_iter);
03715 }
03716
03717 static void
03718 dbus_message_iter_append_done (DBusMessageRealIter *iter)
03719 {
03720 iter->message->changed_stamp++;
03721 dbus_message_iter_update_after_change (iter);
03722 iter->wrote_dict_key = FALSE;
03723 }
03724
03731 dbus_bool_t
03732 dbus_message_iter_append_nil (DBusMessageIter *iter)
03733 {
03734 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03735
03736 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03737
03738 if (!dbus_message_iter_append_type (real, DBUS_TYPE_NIL))
03739 return FALSE;
03740
03741 dbus_message_iter_append_done (real);
03742
03743 return TRUE;
03744 }
03745
03746 static dbus_bool_t
03747 dbus_message_iter_append_basic (DBusMessageIter *iter,
03748 char type,
03749 void *value)
03750 {
03751 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03752
03753 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03754
03755 if (!dbus_message_iter_append_type (real, type))
03756 return FALSE;
03757
03758 if (!_dbus_marshal_basic_type (&real->message->body,
03759 type, value,
03760 real->message->byte_order))
03761 {
03762 _dbus_string_set_length (&real->message->body, real->pos);
03763 return FALSE;
03764 }
03765
03766 dbus_message_iter_append_done (real);
03767
03768 return TRUE;
03769 }
03770
03778 dbus_bool_t
03779 dbus_message_iter_append_boolean (DBusMessageIter *iter,
03780 dbus_bool_t value)
03781 {
03782 unsigned char val = (value != FALSE);
03783 return dbus_message_iter_append_basic (iter, DBUS_TYPE_BOOLEAN, &val);
03784 }
03785
03793 dbus_bool_t
03794 dbus_message_iter_append_byte (DBusMessageIter *iter,
03795 unsigned char value)
03796 {
03797 return dbus_message_iter_append_basic (iter, DBUS_TYPE_BYTE, &value);
03798 }
03799
03807 dbus_bool_t
03808 dbus_message_iter_append_int32 (DBusMessageIter *iter,
03809 dbus_int32_t value)
03810 {
03811 return dbus_message_iter_append_basic (iter, DBUS_TYPE_INT32, &value);
03812 }
03813
03821 dbus_bool_t
03822 dbus_message_iter_append_uint32 (DBusMessageIter *iter,
03823 dbus_uint32_t value)
03824 {
03825 return dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT32, &value);
03826 }
03827
03828 #ifdef DBUS_HAVE_INT64
03829
03839 dbus_bool_t
03840 dbus_message_iter_append_int64 (DBusMessageIter *iter,
03841 dbus_int64_t value)
03842 {
03843 return dbus_message_iter_append_basic (iter, DBUS_TYPE_INT64, &value);
03844 }
03845
03855 dbus_bool_t
03856 dbus_message_iter_append_uint64 (DBusMessageIter *iter,
03857 dbus_uint64_t value)
03858 {
03859 return dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT64, &value);
03860 }
03861
03862 #endif
03863
03871 dbus_bool_t
03872 dbus_message_iter_append_double (DBusMessageIter *iter,
03873 double value)
03874 {
03875 return dbus_message_iter_append_basic (iter, DBUS_TYPE_DOUBLE, &value);
03876 }
03877
03887 dbus_bool_t
03888 dbus_message_iter_append_string (DBusMessageIter *iter,
03889 const char *value)
03890 {
03891 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03892
03893 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03894
03895 if (!dbus_message_iter_append_type (real, DBUS_TYPE_STRING))
03896 return FALSE;
03897
03898 if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, value))
03899 {
03900 _dbus_string_set_length (&real->message->body, real->pos);
03901 return FALSE;
03902 }
03903
03904 dbus_message_iter_append_done (real);
03905
03906 return TRUE;
03907 }
03908
03918 dbus_bool_t
03919 dbus_message_iter_append_object_path (DBusMessageIter *iter,
03920 const char *value)
03921 {
03922 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03923
03924 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03925
03926 if (!dbus_message_iter_append_type (real, DBUS_TYPE_OBJECT_PATH))
03927 return FALSE;
03928
03929 if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, value))
03930 {
03931 _dbus_string_set_length (&real->message->body, real->pos);
03932 return FALSE;
03933 }
03934
03935 dbus_message_iter_append_done (real);
03936
03937 return TRUE;
03938 }
03939
03952 dbus_bool_t
03953 dbus_message_iter_append_custom (DBusMessageIter *iter,
03954 const char *name,
03955 const unsigned char *data,
03956 int len)
03957 {
03958 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03959
03960 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03961
03962 if (!dbus_message_iter_append_type (real, DBUS_TYPE_CUSTOM))
03963 return FALSE;
03964
03965 if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, name))
03966 {
03967 _dbus_string_set_length (&real->message->body, real->pos);
03968 return FALSE;
03969 }
03970
03971 if (!_dbus_marshal_byte_array (&real->message->body, real->message->byte_order, data, len))
03972 {
03973 _dbus_string_set_length (&real->message->body, real->pos);
03974 return FALSE;
03975 }
03976
03977 dbus_message_iter_append_done (real);
03978
03979 return TRUE;
03980 }
03981
03982
03991 dbus_bool_t
03992 dbus_message_iter_append_dict_key (DBusMessageIter *iter,
03993 const char *value)
03994 {
03995 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
03996
03997 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
03998 _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
03999
04000 if (real->wrote_dict_key)
04001 {
04002 _dbus_warn ("Appending multiple dict key names\n");
04003 return FALSE;
04004 }
04005
04006 if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, value))
04007 {
04008 return FALSE;
04009 }
04010
04011 dbus_message_iter_append_done (real);
04012 real->wrote_dict_key = TRUE;
04013
04014 return TRUE;
04015 }
04016
04017 static dbus_bool_t
04018 array_iter_type_mark_done (DBusMessageRealIter *iter)
04019 {
04020 int len_pos;
04021
04022 if (iter->type == DBUS_MESSAGE_ITER_TYPE_ARRAY)
04023 array_iter_type_mark_done (iter->parent_iter);
04024 else
04025 return TRUE;
04026
04027 len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&iter->message->body),
04028 sizeof (dbus_uint32_t));
04029
04030
04031 if (!_dbus_marshal_uint32 (&iter->message->body, iter->message->byte_order, 0))
04032 {
04033 _dbus_string_set_length (&iter->message->body, iter->pos);
04034 return FALSE;
04035 }
04036
04037 iter->container_start = _dbus_string_get_length (&iter->message->body);
04038 iter->container_length_pos = len_pos;
04039 iter->array_type_done = TRUE;
04040
04041 return TRUE;
04042 }
04043
04044 static dbus_bool_t
04045 append_array_type (DBusMessageRealIter *real,
04046 int element_type,
04047 dbus_bool_t *array_type_done,
04048 int *array_type_pos)
04049 {
04050 int existing_element_type;
04051
04052 if (!dbus_message_iter_append_type (real, DBUS_TYPE_ARRAY))
04053 return FALSE;
04054
04055 if (real->type == DBUS_MESSAGE_ITER_TYPE_ARRAY &&
04056 real->array_type_done)
04057 {
04058 existing_element_type = iter_get_array_type (real, array_type_pos);
04059 if (existing_element_type != element_type)
04060 {
04061 _dbus_warn ("Appending array of %s, when expecting array of %s\n",
04062 _dbus_type_to_string (element_type),
04063 _dbus_type_to_string (existing_element_type));
04064 _dbus_string_set_length (&real->message->body, real->pos);
04065 return FALSE;
04066 }
04067 if (array_type_done != NULL)
04068 *array_type_done = TRUE;
04069 }
04070 else
04071 {
04072 if (array_type_pos != NULL)
04073 *array_type_pos = _dbus_string_get_length (&real->message->body);
04074
04075
04076 if (!_dbus_message_append_byte_to_signature (real->message, element_type))
04077 {
04078 _dbus_string_set_length (&real->message->body, real->pos);
04079 return FALSE;
04080 }
04081
04082
04083 if (!_dbus_string_append_byte (&real->message->body, element_type))
04084 {
04085 _dbus_message_remove_byte_from_signature (real->message);
04086 _dbus_string_set_length (&real->message->body, real->pos);
04087 return FALSE;
04088 }
04089
04090 if (array_type_done != NULL)
04091 *array_type_done = element_type != DBUS_TYPE_ARRAY;
04092
04093 if (element_type != DBUS_TYPE_ARRAY &&
04094 !array_iter_type_mark_done (real))
04095 {
04096 _dbus_message_remove_byte_from_signature (real->message);
04097 return FALSE;
04098 }
04099 }
04100
04101 return TRUE;
04102 }
04103
04113 dbus_bool_t
04114 dbus_message_iter_append_array (DBusMessageIter *iter,
04115 DBusMessageIter *array_iter,
04116 int element_type)
04117 {
04118 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
04119 DBusMessageRealIter *array_real = (DBusMessageRealIter *)array_iter;
04120 int len_pos;
04121 int array_type_pos;
04122 dbus_bool_t array_type_done;
04123
04124 if (element_type == DBUS_TYPE_NIL)
04125 {
04126 _dbus_warn ("Can't create NIL arrays\n");
04127 return FALSE;
04128 }
04129
04130 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
04131
04132 if (!append_array_type (real, element_type, &array_type_done, &array_type_pos))
04133 return FALSE;
04134
04135 len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&real->message->body), sizeof (dbus_uint32_t));
04136
04137 if (array_type_done)
04138 {
04139
04140 if (!_dbus_marshal_uint32 (&real->message->body, real->message->byte_order, 0))
04141 {
04142 _dbus_string_set_length (&real->message->body, real->pos);
04143 return FALSE;
04144 }
04145 }
04146
04147 array_real->parent_iter = real;
04148 array_real->message = real->message;
04149 array_real->changed_stamp = real->message->changed_stamp;
04150
04151 array_real->type = DBUS_MESSAGE_ITER_TYPE_ARRAY;
04152 array_real->pos = _dbus_string_get_length (&real->message->body);
04153 array_real->end = array_real->end;
04154
04155 array_real->container_start = array_real->pos;
04156 array_real->container_length_pos = len_pos;
04157 array_real->wrote_dict_key = 0;
04158 array_real->array_type_done = array_type_done;
04159 array_real->array_type_pos = array_type_pos;
04160
04161 dbus_message_iter_append_done (array_real);
04162
04163 return TRUE;
04164 }
04165
04174 dbus_bool_t
04175 dbus_message_iter_append_dict (DBusMessageIter *iter,
04176 DBusMessageIter *dict_iter)
04177 {
04178 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
04179 DBusMessageRealIter *dict_real = (DBusMessageRealIter *)dict_iter;
04180 int len_pos;
04181
04182 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
04183
04184 if (!dbus_message_iter_append_type (real, DBUS_TYPE_DICT))
04185 return FALSE;
04186
04187 len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&real->message->body), sizeof (dbus_uint32_t));
04188
04189
04190 if (!_dbus_marshal_uint32 (&real->message->body, real->message->byte_order, 0))
04191 {
04192 _dbus_string_set_length (&real->message->body, real->pos);
04193 return FALSE;
04194 }
04195
04196 dict_real->parent_iter = real;
04197 dict_real->message = real->message;
04198 dict_real->changed_stamp = real->message->changed_stamp;
04199
04200 dict_real->type = DBUS_MESSAGE_ITER_TYPE_DICT;
04201 dict_real->pos = _dbus_string_get_length (&real->message->body);
04202 dict_real->end = dict_real->end;
04203
04204 dict_real->container_start = dict_real->pos;
04205 dict_real->container_length_pos = len_pos;
04206 dict_real->wrote_dict_key = 0;
04207
04208 dbus_message_iter_append_done (dict_real);
04209
04210 real->wrote_dict_key = FALSE;
04211
04212 return TRUE;
04213 }
04214
04215 static dbus_bool_t
04216 _dbus_message_iter_append_basic_array (DBusMessageIter *iter,
04217 char type,
04218 const void *value,
04219 int len)
04220 {
04221 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
04222
04223 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
04224
04225 if (!append_array_type (real, type, NULL, NULL))
04226 return FALSE;
04227
04228 if (!_dbus_marshal_basic_type_array (&real->message->body,
04229 type, value, len,
04230 real->message->byte_order))
04231 {
04232 _dbus_string_set_length (&real->message->body, real->pos);
04233 return FALSE;
04234 }
04235
04236 dbus_message_iter_append_done (real);
04237
04238 return TRUE;
04239 }
04240
04241
04255 dbus_bool_t
04256 dbus_message_append_args_valist (DBusMessage *message,
04257 int first_arg_type,
04258 va_list var_args)
04259 {
04260 int type, old_len;
04261 DBusMessageIter iter;
04262
04263 _dbus_return_val_if_fail (message != NULL, FALSE);
04264
04265 old_len = _dbus_string_get_length (&message->body);
04266
04267 type = first_arg_type;
04268
04269 dbus_message_append_iter_init (message, &iter);
04270
04271 while (type != DBUS_TYPE_INVALID)
04272 {
04273 switch (type)
04274 {
04275 case DBUS_TYPE_NIL:
04276 if (!dbus_message_iter_append_nil (&iter))
04277 goto errorout;
04278 break;
04279 case DBUS_TYPE_BYTE:
04280
04281
04282 if (!dbus_message_iter_append_byte (&iter, va_arg (var_args, int)))
04283 goto errorout;
04284 break;
04285 case DBUS_TYPE_BOOLEAN:
04286 if (!dbus_message_iter_append_boolean (&iter, va_arg (var_args, dbus_bool_t)))
04287 goto errorout;
04288 break;
04289 case DBUS_TYPE_INT32:
04290
04291
04292
04293 if (!dbus_message_iter_append_int32 (&iter, va_arg (var_args, dbus_int32_t)))
04294 goto errorout;
04295 break;
04296 case DBUS_TYPE_UINT32:
04297
04298
04299
04300 if (!dbus_message_iter_append_uint32 (&iter, va_arg (var_args, dbus_uint32_t)))
04301 goto errorout;
04302 break;
04303 #ifdef DBUS_HAVE_INT64
04304 case DBUS_TYPE_INT64:
04305 if (!dbus_message_iter_append_int64 (&iter, va_arg (var_args, dbus_int64_t)))
04306 goto errorout;
04307 break;
04308 case DBUS_TYPE_UINT64:
04309 if (!dbus_message_iter_append_uint64 (&iter, va_arg (var_args, dbus_uint64_t)))
04310 goto errorout;
04311 break;
04312 #endif
04313 case DBUS_TYPE_DOUBLE:
04314 if (!dbus_message_iter_append_double (&iter, va_arg (var_args, double)))
04315 goto errorout;
04316 break;
04317 case DBUS_TYPE_STRING:
04318 if (!dbus_message_iter_append_string (&iter, va_arg (var_args, const char *)))
04319 goto errorout;
04320 break;
04321 case DBUS_TYPE_OBJECT_PATH:
04322 if (!dbus_message_iter_append_object_path (&iter, va_arg (var_args, const char*)))
04323 goto errorout;
04324 break;
04325 case DBUS_TYPE_CUSTOM:
04326 {
04327 const char *name;
04328 unsigned char *data;
04329 int len;
04330
04331 name = va_arg (var_args, const char *);
04332 data = va_arg (var_args, unsigned char *);
04333 len = va_arg (var_args, int);
04334
04335 if (!dbus_message_iter_append_custom (&iter, name, data, len))
04336 goto errorout;
04337 break;
04338 }
04339 case DBUS_TYPE_ARRAY:
04340 {
04341 void *data;
04342 int len, type;
04343
04344 type = va_arg (var_args, int);
04345 data = va_arg (var_args, void *);
04346 len = va_arg (var_args, int);
04347
04348 switch (type)
04349 {
04350 case DBUS_TYPE_BYTE:
04351 case DBUS_TYPE_BOOLEAN:
04352 case DBUS_TYPE_INT32:
04353 case DBUS_TYPE_UINT32:
04354 #ifdef DBUS_HAVE_INT64
04355 case DBUS_TYPE_INT64:
04356 case DBUS_TYPE_UINT64:
04357 #endif
04358 case DBUS_TYPE_DOUBLE:
04359 if (!_dbus_message_iter_append_basic_array (&iter, type, data, len))
04360 goto errorout;
04361 break;
04362 case DBUS_TYPE_STRING:
04363 if (!dbus_message_iter_append_string_array (&iter, (const char **)data, len))
04364 goto errorout;
04365 break;
04366 case DBUS_TYPE_OBJECT_PATH:
04367 if (!dbus_message_iter_append_object_path_array (&iter, (const char **)data, len))
04368 goto errorout;
04369 break;
04370 case DBUS_TYPE_NIL:
04371 case DBUS_TYPE_ARRAY:
04372 case DBUS_TYPE_CUSTOM:
04373 case DBUS_TYPE_DICT:
04374 _dbus_warn ("dbus_message_append_args_valist doesn't support recursive arrays\n");
04375 goto errorout;
04376 default:
04377 _dbus_warn ("Unknown field type %d\n", type);
04378 goto errorout;
04379 }
04380 }
04381 break;
04382
04383 case DBUS_TYPE_DICT:
04384 _dbus_warn ("dbus_message_append_args_valist doesn't support dicts\n");
04385 goto errorout;
04386 default:
04387 _dbus_warn ("Unknown field type %d\n", type);
04388 goto errorout;
04389 }
04390
04391 type = va_arg (var_args, int);
04392 }
04393
04394 return TRUE;
04395
04396 errorout:
04397 return FALSE;
04398 }
04399
04408 dbus_bool_t
04409 dbus_message_iter_append_boolean_array (DBusMessageIter *iter,
04410 unsigned const char *value,
04411 int len)
04412 {
04413 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_BOOLEAN,
04414 value, len);
04415 }
04416
04425 dbus_bool_t
04426 dbus_message_iter_append_int32_array (DBusMessageIter *iter,
04427 const dbus_int32_t *value,
04428 int len)
04429 {
04430 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_INT32,
04431 value, len);
04432 }
04433
04442 dbus_bool_t
04443 dbus_message_iter_append_uint32_array (DBusMessageIter *iter,
04444 const dbus_uint32_t *value,
04445 int len)
04446 {
04447 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_UINT32,
04448 value, len);
04449 }
04450
04451 #ifdef DBUS_HAVE_INT64
04452
04463 dbus_bool_t
04464 dbus_message_iter_append_int64_array (DBusMessageIter *iter,
04465 const dbus_int64_t *value,
04466 int len)
04467 {
04468 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_INT64,
04469 value, len);
04470 }
04471
04482 dbus_bool_t
04483 dbus_message_iter_append_uint64_array (DBusMessageIter *iter,
04484 const dbus_uint64_t *value,
04485 int len)
04486 {
04487 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_UINT64,
04488 value, len);
04489 }
04490 #endif
04491
04500 dbus_bool_t
04501 dbus_message_iter_append_double_array (DBusMessageIter *iter,
04502 const double *value,
04503 int len)
04504 {
04505 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_DOUBLE,
04506 value, len);
04507 }
04508
04517 dbus_bool_t
04518 dbus_message_iter_append_byte_array (DBusMessageIter *iter,
04519 unsigned const char *value,
04520 int len)
04521 {
04522 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_BYTE,
04523 value, len);
04524 }
04525
04534 dbus_bool_t
04535 dbus_message_iter_append_string_array (DBusMessageIter *iter,
04536 const char **value,
04537 int len)
04538 {
04539 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
04540
04541 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
04542
04543 if (!append_array_type (real, DBUS_TYPE_STRING, NULL, NULL))
04544 return FALSE;
04545
04546 if (!_dbus_marshal_string_array (&real->message->body, real->message->byte_order, value, len))
04547 {
04548 _dbus_string_set_length (&real->message->body, real->pos);
04549 return FALSE;
04550 }
04551
04552 dbus_message_iter_append_done (real);
04553
04554 return TRUE;
04555 }
04556
04565 dbus_bool_t
04566 dbus_message_iter_append_object_path_array (DBusMessageIter *iter,
04567 const char **value,
04568 int len)
04569 {
04570 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
04571
04572 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
04573
04574 if (!append_array_type (real, DBUS_TYPE_OBJECT_PATH, NULL, NULL))
04575 return FALSE;
04576
04577 if (!_dbus_marshal_string_array (&real->message->body, real->message->byte_order, value, len))
04578 {
04579 _dbus_string_set_length (&real->message->body, real->pos);
04580 return FALSE;
04581 }
04582
04583 dbus_message_iter_append_done (real);
04584
04585 return TRUE;
04586 }
04587
04595 dbus_bool_t
04596 dbus_message_set_sender (DBusMessage *message,
04597 const char *sender)
04598 {
04599 _dbus_return_val_if_fail (message != NULL, FALSE);
04600 _dbus_return_val_if_fail (!message->locked, FALSE);
04601
04602 return set_string_field (message,
04603 DBUS_HEADER_FIELD_SENDER,
04604 DBUS_TYPE_STRING,
04605 sender);
04606 }
04607
04618 void
04619 dbus_message_set_no_reply (DBusMessage *message,
04620 dbus_bool_t no_reply)
04621 {
04622 char *header;
04623
04624 _dbus_return_if_fail (message != NULL);
04625 _dbus_return_if_fail (!message->locked);
04626
04627 header = _dbus_string_get_data_len (&message->header, FLAGS_OFFSET, 1);
04628
04629 if (no_reply)
04630 *header |= DBUS_HEADER_FLAG_NO_REPLY_EXPECTED;
04631 else
04632 *header &= ~DBUS_HEADER_FLAG_NO_REPLY_EXPECTED;
04633 }
04634
04642 dbus_bool_t
04643 dbus_message_get_no_reply (DBusMessage *message)
04644 {
04645 const char *header;
04646
04647 _dbus_return_val_if_fail (message != NULL, FALSE);
04648
04649 header = _dbus_string_get_const_data_len (&message->header, FLAGS_OFFSET, 1);
04650
04651 return (*header & DBUS_HEADER_FLAG_NO_REPLY_EXPECTED) != 0;
04652 }
04653
04654
04664 void
04665 dbus_message_set_auto_activation (DBusMessage *message,
04666 dbus_bool_t auto_activation)
04667 {
04668 char *header;
04669
04670 _dbus_return_if_fail (message != NULL);
04671 _dbus_return_if_fail (!message->locked);
04672
04673 header = _dbus_string_get_data_len (&message->header, FLAGS_OFFSET, 1);
04674
04675 if (auto_activation)
04676 *header |= DBUS_HEADER_FLAG_AUTO_ACTIVATION;
04677 else
04678 *header &= ~DBUS_HEADER_FLAG_AUTO_ACTIVATION;
04679 }
04680
04688 dbus_bool_t
04689 dbus_message_get_auto_activation (DBusMessage *message)
04690 {
04691 const char *header;
04692
04693 _dbus_return_val_if_fail (message != NULL, FALSE);
04694
04695 header = _dbus_string_get_const_data_len (&message->header, FLAGS_OFFSET, 1);
04696
04697 return (*header & DBUS_HEADER_FLAG_AUTO_ACTIVATION) != 0;
04698 }
04699
04707 const char*
04708 dbus_message_get_sender (DBusMessage *message)
04709 {
04710 _dbus_return_val_if_fail (message != NULL, NULL);
04711
04712 return get_string_field (message,
04713 DBUS_HEADER_FIELD_SENDER,
04714 NULL);
04715 }
04716
04732 const char*
04733 dbus_message_get_signature (DBusMessage *message)
04734 {
04735 _dbus_return_val_if_fail (message != NULL, NULL);
04736
04737 return get_string_field (message,
04738 DBUS_HEADER_FIELD_SIGNATURE,
04739 NULL);
04740 }
04741
04742 static dbus_bool_t
04743 _dbus_message_has_type_interface_member (DBusMessage *message,
04744 int type,
04745 const char *interface,
04746 const char *method)
04747 {
04748 const char *n;
04749
04750 _dbus_assert (message != NULL);
04751 _dbus_assert (interface != NULL);
04752 _dbus_assert (method != NULL);
04753
04754 if (dbus_message_get_type (message) != type)
04755 return FALSE;
04756
04757
04758
04759
04760
04761 n = dbus_message_get_member (message);
04762
04763 if (n && strcmp (n, method) == 0)
04764 {
04765 n = dbus_message_get_interface (message);
04766
04767 if (n && strcmp (n, interface) == 0)
04768 return TRUE;
04769 }
04770
04771 return FALSE;
04772 }
04773
04786 dbus_bool_t
04787 dbus_message_is_method_call (DBusMessage *message,
04788 const char *interface,
04789 const char *method)
04790 {
04791 _dbus_return_val_if_fail (message != NULL, FALSE);
04792 _dbus_return_val_if_fail (interface != NULL, FALSE);
04793 _dbus_return_val_if_fail (method != NULL, FALSE);
04794
04795 return _dbus_message_has_type_interface_member (message,
04796 DBUS_MESSAGE_TYPE_METHOD_CALL,
04797 interface, method);
04798 }
04799
04812 dbus_bool_t
04813 dbus_message_is_signal (DBusMessage *message,
04814 const char *interface,
04815 const char *signal_name)
04816 {
04817 _dbus_return_val_if_fail (message != NULL, FALSE);
04818 _dbus_return_val_if_fail (interface != NULL, FALSE);
04819 _dbus_return_val_if_fail (signal_name != NULL, FALSE);
04820
04821 return _dbus_message_has_type_interface_member (message,
04822 DBUS_MESSAGE_TYPE_SIGNAL,
04823 interface, signal_name);
04824 }
04825
04836 dbus_bool_t
04837 dbus_message_is_error (DBusMessage *message,
04838 const char *error_name)
04839 {
04840 const char *n;
04841
04842 _dbus_return_val_if_fail (message != NULL, FALSE);
04843 _dbus_return_val_if_fail (error_name != NULL, FALSE);
04844 _dbus_return_val_if_fail (is_valid_error_name (error_name), FALSE);
04845
04846 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
04847 return FALSE;
04848
04849 n = dbus_message_get_error_name (message);
04850
04851 if (n && strcmp (n, error_name) == 0)
04852 return TRUE;
04853 else
04854 return FALSE;
04855 }
04856
04867 dbus_bool_t
04868 dbus_message_has_destination (DBusMessage *message,
04869 const char *service)
04870 {
04871 const char *s;
04872
04873 _dbus_return_val_if_fail (message != NULL, FALSE);
04874 _dbus_return_val_if_fail (service != NULL, FALSE);
04875
04876 s = dbus_message_get_destination (message);
04877
04878 if (s && strcmp (s, service) == 0)
04879 return TRUE;
04880 else
04881 return FALSE;
04882 }
04883
04898 dbus_bool_t
04899 dbus_message_has_sender (DBusMessage *message,
04900 const char *service)
04901 {
04902 const char *s;
04903
04904 _dbus_return_val_if_fail (message != NULL, FALSE);
04905 _dbus_return_val_if_fail (service != NULL, FALSE);
04906
04907 s = dbus_message_get_sender (message);
04908
04909 if (s && strcmp (s, service) == 0)
04910 return TRUE;
04911 else
04912 return FALSE;
04913 }
04914
04924 dbus_bool_t
04925 dbus_message_has_signature (DBusMessage *message,
04926 const char *signature)
04927 {
04928 const char *s;
04929
04930 _dbus_return_val_if_fail (message != NULL, FALSE);
04931 _dbus_return_val_if_fail (signature != NULL, FALSE);
04932
04933 s = dbus_message_get_signature (message);
04934
04935 if (s && strcmp (s, signature) == 0)
04936 return TRUE;
04937 else
04938 return FALSE;
04939 }
04940
04958 dbus_bool_t
04959 dbus_set_error_from_message (DBusError *error,
04960 DBusMessage *message)
04961 {
04962 char *str;
04963
04964 _dbus_return_val_if_fail (message != NULL, FALSE);
04965 _dbus_return_val_if_error_is_set (error, FALSE);
04966
04967 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
04968 return FALSE;
04969
04970 str = NULL;
04971 dbus_message_get_args (message, NULL,
04972 DBUS_TYPE_STRING, &str,
04973 DBUS_TYPE_INVALID);
04974
04975 dbus_set_error (error, dbus_message_get_error_name (message),
04976 str ? "%s" : NULL, str);
04977
04978 dbus_free (str);
04979
04980 return TRUE;
04981 }
04982
05007
05008
05009
05010
05011
05015 #define MAX_SANE_MESSAGE_SIZE (_DBUS_INT_MAX/16)
05016
05021 struct DBusMessageLoader
05022 {
05023 int refcount;
05025 DBusString data;
05027 DBusList *messages;
05029 long max_message_size;
05031 unsigned int buffer_outstanding : 1;
05033 unsigned int corrupted : 1;
05034 };
05035
05046 #define INITIAL_LOADER_DATA_LEN 32
05047
05054 DBusMessageLoader*
05055 _dbus_message_loader_new (void)
05056 {
05057 DBusMessageLoader *loader;
05058
05059 loader = dbus_new0 (DBusMessageLoader, 1);
05060 if (loader == NULL)
05061 return NULL;
05062
05063 loader->refcount = 1;
05064
05065
05066
05067
05068 loader->max_message_size = _DBUS_ONE_MEGABYTE * 32;
05069
05070 if (!_dbus_string_init (&loader->data))
05071 {
05072 dbus_free (loader);
05073 return NULL;
05074 }
05075
05076
05077 _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
05078 _dbus_string_set_length (&loader->data, 0);
05079
05080 return loader;
05081 }
05082
05089 DBusMessageLoader *
05090 _dbus_message_loader_ref (DBusMessageLoader *loader)
05091 {
05092 loader->refcount += 1;
05093
05094 return loader;
05095 }
05096
05103 void
05104 _dbus_message_loader_unref (DBusMessageLoader *loader)
05105 {
05106 loader->refcount -= 1;
05107 if (loader->refcount == 0)
05108 {
05109 _dbus_list_foreach (&loader->messages,
05110 (DBusForeachFunction) dbus_message_unref,
05111 NULL);
05112 _dbus_list_clear (&loader->messages);
05113 _dbus_string_free (&loader->data);
05114 dbus_free (loader);
05115 }
05116 }
05117
05136 void
05137 _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
05138 DBusString **buffer)
05139 {
05140 _dbus_assert (!loader->buffer_outstanding);
05141
05142 *buffer = &loader->data;
05143
05144 loader->buffer_outstanding = TRUE;
05145 }
05146
05151 #define DBUS_MINIMUM_HEADER_SIZE 16
05152
05153 static dbus_bool_t
05154 decode_string_field (const DBusString *data,
05155 int field,
05156 HeaderField *header_field,
05157 DBusString *field_data,
05158 int pos,
05159 int type)
05160 {
05161 int string_data_pos;
05162
05163 _dbus_assert (header_field != NULL);
05164 _dbus_assert (field_data != NULL);
05165
05166 if (header_field->name_offset >= 0)
05167 {
05168 _dbus_verbose ("%s field provided twice\n",
05169 _dbus_header_field_to_string (field));
05170 return FALSE;
05171 }
05172
05173 if (type != DBUS_TYPE_STRING)
05174 {
05175 _dbus_verbose ("%s field has wrong type %s\n",
05176 _dbus_header_field_to_string (field),
05177 _dbus_type_to_string (type));
05178 return FALSE;
05179 }
05180
05181
05182
05183
05184
05185 string_data_pos = _DBUS_ALIGN_VALUE (pos, 4) + 4;
05186 _dbus_assert (string_data_pos < _dbus_string_get_length (data));
05187
05188 _dbus_string_init_const (field_data,
05189 _dbus_string_get_const_data (data) + string_data_pos);
05190
05191 header_field->name_offset = pos - 2;
05192 header_field->value_offset = _DBUS_ALIGN_VALUE (pos, 4);
05193
05194 #if 0
05195 _dbus_verbose ("Found field %s at offset %d\n",
05196 _dbus_header_field_to_string (field),
05197 header_field->value_offset);
05198 #endif
05199
05200 return TRUE;
05201 }
05202
05203
05204
05205
05206
05207
05208
05209 static dbus_bool_t
05210 decode_header_data (const DBusString *data,
05211 int header_len,
05212 int byte_order,
05213 int message_type,
05214 HeaderField fields[DBUS_HEADER_FIELD_LAST + 1],
05215 int *message_padding)
05216 {
05217 DBusString field_data;
05218 int pos, new_pos;
05219 int i;
05220 int field;
05221 int type;
05222 dbus_bool_t signature_required;
05223
05224 if (header_len < 16)
05225 {
05226 _dbus_verbose ("Header length %d is too short\n", header_len);
05227 return FALSE;
05228 }
05229
05230 i = 0;
05231 while (i <= DBUS_HEADER_FIELD_LAST)
05232 {
05233 fields[i].name_offset = -1;
05234 fields[i].value_offset = -1;
05235 ++i;
05236 }
05237
05238 pos = 16;
05239 while (pos < header_len)
05240 {
05241 field = _dbus_string_get_byte (data, pos);
05242 if (field == DBUS_HEADER_FIELD_INVALID)
05243 break;
05244 pos++;
05245
05246 if (!_dbus_marshal_validate_type (data, pos, &type, &pos))
05247 {
05248 _dbus_verbose ("Failed to validate type of named header field pos = %d\n",
05249 pos);
05250 return FALSE;
05251 }
05252
05253 if (!_dbus_marshal_validate_arg (data, byte_order, 0, type, -1, pos, &new_pos))
05254 {
05255 _dbus_verbose ("Failed to validate argument to named header field pos = %d\n",
05256 pos);
05257 return FALSE;
05258 }
05259
05260 if (new_pos > header_len)
05261 {
05262 _dbus_verbose ("Named header field tries to extend beyond header length\n");
05263 return FALSE;
05264 }
05265
05266 switch (field)
05267 {
05268 case DBUS_HEADER_FIELD_DESTINATION:
05269 if (!decode_string_field (data, field, &fields[field],
05270 &field_data, pos, type))
05271 return FALSE;
05272
05273 if (!_dbus_string_validate_service (&field_data, 0,
05274 _dbus_string_get_length (&field_data)))
05275 {
05276 _dbus_verbose ("service field has invalid content \"%s\"\n",
05277 _dbus_string_get_const_data (&field_data));
05278 return FALSE;
05279 }
05280 break;
05281
05282 case DBUS_HEADER_FIELD_INTERFACE:
05283 if (!decode_string_field (data, field, &fields[field],
05284 &field_data, pos, type))
05285 return FALSE;
05286
05287 if (!_dbus_string_validate_interface (&field_data, 0,
05288 _dbus_string_get_length (&field_data)))
05289 {
05290 _dbus_verbose ("interface field has invalid content \"%s\"\n",
05291 _dbus_string_get_const_data (&field_data));
05292 return FALSE;
05293 }
05294
05295 if (_dbus_string_equal_c_str (&field_data,
05296 DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL))
05297 {
05298 _dbus_verbose ("Message is on the local interface\n");
05299 return FALSE;
05300 }
05301 break;
05302
05303 case DBUS_HEADER_FIELD_MEMBER:
05304 if (!decode_string_field (data, field, &fields[field],
05305 &field_data, pos, type))
05306 return FALSE;
05307
05308 if (!_dbus_string_validate_member (&field_data, 0,
05309 _dbus_string_get_length (&field_data)))
05310 {
05311 _dbus_verbose ("member field has invalid content \"%s\"\n",
05312 _dbus_string_get_const_data (&field_data));
05313 return FALSE;
05314 }
05315 break;
05316
05317 case DBUS_HEADER_FIELD_ERROR_NAME:
05318 if (!decode_string_field (data, field, &fields[field],
05319 &field_data, pos, type))
05320 return FALSE;
05321
05322 if (!_dbus_string_validate_error_name (&field_data, 0,
05323 _dbus_string_get_length (&field_data)))
05324 {
05325 _dbus_verbose ("error-name field has invalid content \"%s\"\n",
05326 _dbus_string_get_const_data (&field_data));
05327 return FALSE;
05328 }
05329 break;
05330
05331 case DBUS_HEADER_FIELD_SENDER:
05332 if (!decode_string_field (data, field, &fields[field],
05333 &field_data, pos, type))
05334 return FALSE;
05335
05336 if (!_dbus_string_validate_service (&field_data, 0,
05337 _dbus_string_get_length (&field_data)))
05338 {
05339 _dbus_verbose ("sender-service field has invalid content \"%s\"\n",
05340 _dbus_string_get_const_data (&field_data));
05341 return FALSE;
05342 }
05343 break;
05344
05345 case DBUS_HEADER_FIELD_PATH:
05346
05347
05348
05349
05350
05351
05352 if (fields[field].name_offset >= 0)
05353 {
05354 _dbus_verbose ("path field provided twice\n");
05355 return FALSE;
05356 }
05357 if (type != DBUS_TYPE_OBJECT_PATH)
05358 {
05359 _dbus_verbose ("path field has wrong type\n");
05360 return FALSE;
05361 }
05362
05363 fields[field].name_offset = pos - 2;
05364 fields[field].value_offset = _DBUS_ALIGN_VALUE (pos, 4);
05365
05366
05367 {
05368 const char *s;
05369 s = _dbus_string_get_const_data_len (data,
05370 fields[field].value_offset,
05371 _dbus_string_get_length (data) -
05372 fields[field].value_offset);
05373 if (strcmp (s, DBUS_PATH_ORG_FREEDESKTOP_LOCAL) == 0)
05374 {
05375 _dbus_verbose ("Message is on the local path\n");
05376 return FALSE;
05377 }
05378 }
05379
05380 _dbus_verbose ("Found path at offset %d\n",
05381 fields[field].value_offset);
05382 break;
05383
05384 case DBUS_HEADER_FIELD_REPLY_SERIAL:
05385 if (fields[field].name_offset >= 0)
05386 {
05387 _dbus_verbose ("reply field provided twice\n");
05388 return FALSE;
05389 }
05390
05391 if (type != DBUS_TYPE_UINT32)
05392 {
05393 _dbus_verbose ("reply field has wrong type\n");
05394 return FALSE;
05395 }
05396
05397 fields[field].name_offset = pos - 2;
05398 fields[field].value_offset = _DBUS_ALIGN_VALUE (pos, 4);
05399
05400 _dbus_verbose ("Found reply serial %u at offset %d\n",
05401 _dbus_demarshal_uint32 (data,
05402 byte_order,
05403 fields[field].value_offset,
05404 NULL),
05405 fields[field].value_offset);
05406 break;
05407
05408 case DBUS_HEADER_FIELD_SIGNATURE:
05409 if (!decode_string_field (data, field, &fields[field],
05410 &field_data, pos, type))
05411 return FALSE;
05412
05413 if (!_dbus_string_validate_signature (&field_data, 0,
05414 _dbus_string_get_length (&field_data)))
05415 {
05416 _dbus_verbose ("signature field has invalid content \"%s\"\n",
05417 _dbus_string_get_const_data (&field_data));
05418 return FALSE;
05419 }
05420 break;
05421
05422 default:
05423 _dbus_verbose ("Ignoring an unknown header field: %d at offset %d\n",
05424 field, pos);
05425 }
05426
05427 pos = new_pos;
05428 }
05429
05430 if (pos < header_len)
05431 {
05432
05433 if ((header_len - pos) >= 8)
05434 {
05435 _dbus_verbose ("too much header alignment padding\n");
05436 return FALSE;
05437 }
05438
05439 if (!_dbus_string_validate_nul (data,
05440 pos, (header_len - pos)))
05441 {
05442 _dbus_verbose ("header alignment padding is not nul\n");
05443 return FALSE;
05444 }
05445 }
05446
05447
05448 signature_required = TRUE;
05449
05450 switch (message_type)
05451 {
05452 case DBUS_MESSAGE_TYPE_SIGNAL:
05453 case DBUS_MESSAGE_TYPE_METHOD_CALL:
05454 if (fields[DBUS_HEADER_FIELD_PATH].value_offset < 0)
05455 {
05456 _dbus_verbose ("No path field provided\n");
05457 return FALSE;
05458 }
05459
05460 if (fields[DBUS_HEADER_FIELD_INTERFACE].value_offset < 0)
05461 {
05462 _dbus_verbose ("No interface field provided\n");
05463 return FALSE;
05464 }
05465 if (fields[DBUS_HEADER_FIELD_MEMBER].value_offset < 0)
05466 {
05467 _dbus_verbose ("No member field provided\n");
05468 return FALSE;
05469 }
05470 break;
05471 case DBUS_MESSAGE_TYPE_ERROR:
05472 if (fields[DBUS_HEADER_FIELD_ERROR_NAME].value_offset < 0)
05473 {
05474 _dbus_verbose ("No error-name field provided\n");
05475 return FALSE;
05476 }
05477 if (fields[DBUS_HEADER_FIELD_REPLY_SERIAL].value_offset < 0)
05478 {
05479 _dbus_verbose ("No reply serial field provided in error\n");
05480 return FALSE;
05481 }
05482 break;
05483 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
05484 if (fields[DBUS_HEADER_FIELD_REPLY_SERIAL].value_offset < 0)
05485 {
05486 _dbus_verbose ("No reply serial field provided in method return\n");
05487 return FALSE;
05488 }
05489 break;
05490 default:
05491
05492 signature_required = FALSE;
05493 break;
05494 }
05495
05496
05497 if (signature_required)
05498 {
05499 if (fields[DBUS_HEADER_FIELD_SIGNATURE].value_offset < 0)
05500 {
05501 _dbus_verbose ("No signature field provided\n");
05502 return FALSE;
05503 }
05504 }
05505
05506 if (message_padding)
05507 *message_padding = header_len - pos;
05508
05509 return TRUE;
05510 }
05511
05522 void
05523 _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
05524 DBusString *buffer,
05525 int bytes_read)
05526 {
05527 _dbus_assert (loader->buffer_outstanding);
05528 _dbus_assert (buffer == &loader->data);
05529
05530 loader->buffer_outstanding = FALSE;
05531 }
05532
05533 static dbus_bool_t
05534 load_one_message (DBusMessageLoader *loader,
05535 int byte_order,
05536 int message_type,
05537 int header_len,
05538 int body_len)
05539 {
05540 DBusMessage *message;
05541 HeaderField fields[DBUS_HEADER_FIELD_LAST + 1];
05542 int i;
05543 int next_arg;
05544 dbus_bool_t oom;
05545 int header_padding;
05546
05547 message = NULL;
05548 oom = FALSE;
05549
05550 #if 0
05551 _dbus_verbose_bytes_of_string (&loader->data, 0, header_len );
05552 #endif
05553
05554 if (!decode_header_data (&loader->data,
05555 header_len, byte_order,
05556 message_type,
05557 fields, &header_padding))
05558 {
05559 _dbus_verbose ("Header was invalid\n");
05560 loader->corrupted = TRUE;
05561 goto failed;
05562 }
05563
05564 next_arg = header_len;
05565 while (next_arg < (header_len + body_len))
05566 {
05567 int type;
05568 int prev = next_arg;
05569
05570 if (!_dbus_marshal_validate_type (&loader->data, next_arg,
05571 &type, &next_arg))
05572 {
05573 _dbus_verbose ("invalid typecode at offset %d\n", prev);
05574 loader->corrupted = TRUE;
05575 goto failed;
05576 }
05577
05578 if (!_dbus_marshal_validate_arg (&loader->data,
05579 byte_order,
05580 0,
05581 type, -1,
05582 next_arg,
05583 &next_arg))
05584 {
05585 _dbus_verbose ("invalid type data at %d, next_arg\n", next_arg);
05586 loader->corrupted = TRUE;
05587 goto failed;
05588 }
05589
05590 _dbus_assert (next_arg > prev);
05591 }
05592
05593 if (next_arg > (header_len + body_len))
05594 {
05595 _dbus_verbose ("end of last arg at %d but message has len %d+%d=%d\n",
05596 next_arg, header_len, body_len,
05597 header_len + body_len);
05598 loader->corrupted = TRUE;
05599 goto failed;
05600 }
05601
05602 message = dbus_message_new_empty_header ();
05603 if (message == NULL)
05604 {
05605 _dbus_verbose ("Failed to allocate empty message\n");
05606 oom = TRUE;
05607 goto failed;
05608 }
05609
05610 message->byte_order = byte_order;
05611 message->header_padding = header_padding;
05612
05613
05614 i = 0;
05615 while (i <= DBUS_HEADER_FIELD_LAST)
05616 {
05617 message->header_fields[i] = fields[i];
05618 ++i;
05619 }
05620
05621 if (!_dbus_list_append (&loader->messages, message))
05622 {
05623 _dbus_verbose ("Failed to append new message to loader queue\n");
05624 oom = TRUE;
05625 goto failed;
05626 }
05627
05628 _dbus_assert (_dbus_string_get_length (&message->header) == 0);
05629 _dbus_assert (_dbus_string_get_length (&message->body) == 0);
05630
05631 _dbus_assert (_dbus_string_get_length (&loader->data) >=
05632 (header_len + body_len));
05633
05634 if (!_dbus_string_move_len (&loader->data, 0, header_len, &message->header, 0))
05635 {
05636 _dbus_verbose ("Failed to move header into new message\n");
05637 oom = TRUE;
05638 goto failed;
05639 }
05640
05641 if (!_dbus_string_move_len (&loader->data, 0, body_len, &message->body, 0))
05642 {
05643 _dbus_verbose ("Failed to move body into new message\n");
05644
05645 oom = TRUE;
05646 goto failed;
05647 }
05648
05649 _dbus_assert (_dbus_string_get_length (&message->header) == header_len);
05650 _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
05651
05652
05653
05654
05655 message->reply_serial = get_uint_field (message,
05656 DBUS_HEADER_FIELD_REPLY_SERIAL);
05657
05658 message->client_serial = _dbus_demarshal_uint32 (&message->header,
05659 message->byte_order,
05660 CLIENT_SERIAL_OFFSET,
05661 NULL);
05662 if (message->client_serial == 0 ||
05663 (message->header_fields[DBUS_HEADER_FIELD_REPLY_SERIAL].value_offset >= 0 && message->reply_serial == 0))
05664 {
05665 _dbus_verbose ("client_serial = %d reply_serial = %d, one of these no good\n",
05666 message->client_serial,
05667 message->reply_serial);
05668
05669 loader->corrupted = TRUE;
05670 goto failed;
05671 }
05672
05673 _dbus_verbose ("Loaded message %p\n", message);
05674
05675 _dbus_assert (!oom);
05676 _dbus_assert (!loader->corrupted);
05677
05678 return TRUE;
05679
05680 failed:
05681
05682
05683
05684 if (message != NULL)
05685 {
05686
05687 if (_dbus_string_get_length (&message->body) > 0)
05688 {
05689 dbus_bool_t result;
05690
05691 result = _dbus_string_copy_len (&message->body, 0, body_len,
05692 &loader->data, 0);
05693
05694 _dbus_assert (result);
05695 }
05696
05697 if (_dbus_string_get_length (&message->header) > 0)
05698 {
05699 dbus_bool_t result;
05700
05701 result = _dbus_string_copy_len (&message->header, 0, header_len,
05702 &loader->data, 0);
05703
05704 _dbus_assert (result);
05705 }
05706
05707
05708 _dbus_list_remove_last (&loader->messages, message);
05709
05710 dbus_message_unref (message);
05711 }
05712
05713
05714 return !oom;
05715 }
05716
05730 dbus_bool_t
05731 _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
05732 {
05733 while (!loader->corrupted && _dbus_string_get_length (&loader->data) >= 16)
05734 {
05735 const char *header_data;
05736 int byte_order, message_type, header_len, body_len;
05737 dbus_uint32_t header_len_unsigned, body_len_unsigned;
05738
05739 header_data = _dbus_string_get_const_data_len (&loader->data, 0, 16);
05740
05741 _dbus_assert (_DBUS_ALIGN_ADDRESS (header_data, 4) == header_data);
05742
05743 if (header_data[VERSION_OFFSET] != DBUS_MAJOR_PROTOCOL_VERSION)
05744 {
05745 _dbus_verbose ("Message has protocol version %d ours is %d\n",
05746 (int) header_data[VERSION_OFFSET], DBUS_MAJOR_PROTOCOL_VERSION);
05747 loader->corrupted = TRUE;
05748 return TRUE;
05749 }
05750
05751 byte_order = header_data[BYTE_ORDER_OFFSET];
05752
05753 if (byte_order != DBUS_LITTLE_ENDIAN &&
05754 byte_order != DBUS_BIG_ENDIAN)
05755 {
05756 _dbus_verbose ("Message with bad byte order '%c' received\n",
05757 byte_order);
05758 loader->corrupted = TRUE;
05759 return TRUE;
05760 }
05761
05762
05763
05764
05765 message_type = header_data[TYPE_OFFSET];
05766 if (message_type == DBUS_MESSAGE_TYPE_INVALID)
05767 {
05768 _dbus_verbose ("Message with bad type '%d' received\n",
05769 message_type);
05770 loader->corrupted = TRUE;
05771 return TRUE;
05772 }
05773
05774 header_len_unsigned = _dbus_unpack_uint32 (byte_order,
05775 (const unsigned char *) header_data + 4);
05776 body_len_unsigned = _dbus_unpack_uint32 (byte_order,
05777 (const unsigned char *) header_data + 8);
05778
05779 if (header_len_unsigned < 16)
05780 {
05781 _dbus_verbose ("Message had broken too-small header length %u\n",
05782 header_len_unsigned);
05783 loader->corrupted = TRUE;
05784 return TRUE;
05785 }
05786
05787 if (header_len_unsigned > (unsigned) MAX_SANE_MESSAGE_SIZE ||
05788 body_len_unsigned > (unsigned) MAX_SANE_MESSAGE_SIZE)
05789 {
05790 _dbus_verbose ("Header or body length too large (%u %u)\n",
05791 header_len_unsigned,
05792 body_len_unsigned);
05793 loader->corrupted = TRUE;
05794 return TRUE;
05795 }
05796
05797
05798
05799
05800 header_len = header_len_unsigned;
05801 body_len = body_len_unsigned;
05802
05803 if (_DBUS_ALIGN_VALUE (header_len, 8) != header_len_unsigned)
05804 {
05805
05806 _dbus_verbose ("header length %d is not aligned to 8 bytes\n",
05807 header_len);
05808 loader->corrupted = TRUE;
05809 return TRUE;
05810 }
05811
05812 if (header_len + body_len > loader->max_message_size)
05813 {
05814 _dbus_verbose ("Message claimed length header = %d body = %d exceeds max message length %ld\n",
05815 header_len, body_len, loader->max_message_size);
05816 loader->corrupted = TRUE;
05817 return TRUE;
05818 }
05819
05820 if (_dbus_string_get_length (&loader->data) >= (header_len + body_len))
05821 {
05822 if (!load_one_message (loader, byte_order, message_type,
05823 header_len, body_len))
05824 return FALSE;
05825 }
05826 else
05827 return TRUE;
05828 }
05829
05830 return TRUE;
05831 }
05832
05840 DBusMessage*
05841 _dbus_message_loader_peek_message (DBusMessageLoader *loader)
05842 {
05843 if (loader->messages)
05844 return loader->messages->data;
05845 else
05846 return NULL;
05847 }
05848
05857 DBusMessage*
05858 _dbus_message_loader_pop_message (DBusMessageLoader *loader)
05859 {
05860 return _dbus_list_pop_first (&loader->messages);
05861 }
05862
05871 DBusList*
05872 _dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
05873 {
05874 return _dbus_list_pop_first_link (&loader->messages);
05875 }
05876
05883 void
05884 _dbus_message_loader_putback_message_link (DBusMessageLoader *loader,
05885 DBusList *link)
05886 {
05887 _dbus_list_prepend_link (&loader->messages, link);
05888 }
05889
05899 dbus_bool_t
05900 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
05901 {
05902 return loader->corrupted;
05903 }
05904
05911 void
05912 _dbus_message_loader_set_max_message_size (DBusMessageLoader *loader,
05913 long size)
05914 {
05915 if (size > MAX_SANE_MESSAGE_SIZE)
05916 {
05917 _dbus_verbose ("clamping requested max message size %ld to %d\n",
05918 size, MAX_SANE_MESSAGE_SIZE);
05919 size = MAX_SANE_MESSAGE_SIZE;
05920 }
05921 loader->max_message_size = size;
05922 }
05923
05930 long
05931 _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader)
05932 {
05933 return loader->max_message_size;
05934 }
05935
05936 static DBusDataSlotAllocator slot_allocator;
05937 _DBUS_DEFINE_GLOBAL_LOCK (message_slots);
05938
05953 dbus_bool_t
05954 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
05955 {
05956 return _dbus_data_slot_allocator_alloc (&slot_allocator,
05957 _DBUS_LOCK_NAME (message_slots),
05958 slot_p);
05959 }
05960
05972 void
05973 dbus_message_free_data_slot (dbus_int32_t *slot_p)
05974 {
05975 _dbus_return_if_fail (*slot_p >= 0);
05976
05977 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
05978 }
05979
05993 dbus_bool_t
05994 dbus_message_set_data (DBusMessage *message,
05995 dbus_int32_t slot,
05996 void *data,
05997 DBusFreeFunction free_data_func)
05998 {
05999 DBusFreeFunction old_free_func;
06000 void *old_data;
06001 dbus_bool_t retval;
06002
06003 _dbus_return_val_if_fail (message != NULL, FALSE);
06004 _dbus_return_val_if_fail (slot >= 0, FALSE);
06005
06006 retval = _dbus_data_slot_list_set (&slot_allocator,
06007 &message->slot_list,
06008 slot, data, free_data_func,
06009 &old_free_func, &old_data);
06010
06011 if (retval)
06012 {
06013
06014 if (old_free_func)
06015 (* old_free_func) (old_data);
06016 }
06017
06018 return retval;
06019 }
06020
06029 void*
06030 dbus_message_get_data (DBusMessage *message,
06031 dbus_int32_t slot)
06032 {
06033 void *res;
06034
06035 _dbus_return_val_if_fail (message != NULL, NULL);
06036
06037 res = _dbus_data_slot_list_get (&slot_allocator,
06038 &message->slot_list,
06039 slot);
06040
06041 return res;
06042 }
06043
06057 int
06058 dbus_message_type_from_string (const char *type_str)
06059 {
06060 if (strcmp (type_str, "method_call") == 0)
06061 return DBUS_MESSAGE_TYPE_METHOD_CALL;
06062 if (strcmp (type_str, "method_return") == 0)
06063 return DBUS_MESSAGE_TYPE_METHOD_RETURN;
06064 else if (strcmp (type_str, "signal") == 0)
06065 return DBUS_MESSAGE_TYPE_SIGNAL;
06066 else if (strcmp (type_str, "error") == 0)
06067 return DBUS_MESSAGE_TYPE_ERROR;
06068 else
06069 return DBUS_MESSAGE_TYPE_INVALID;
06070 }
06071
06085 const char *
06086 dbus_message_type_to_string (int type)
06087 {
06088 switch (type)
06089 {
06090 case DBUS_MESSAGE_TYPE_METHOD_CALL:
06091 return "method_call";
06092 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
06093 return "method_return";
06094 case DBUS_MESSAGE_TYPE_SIGNAL:
06095 return "signal";
06096 case DBUS_MESSAGE_TYPE_ERROR:
06097 return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return "error";
06098 default:
0609="keywordflow">return