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 }
0367 iter->
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 }
0367 iter->
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 }
0367 iter->
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 }
0367 iter->
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 }
0367 iter->
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 }
0367 iter->
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 }
0367 iter->
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 }
0367 iter->
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 }
0367 iter->
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 }
0367 iter->
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 }
0367 iter->
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 }
0367 iter->
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 }
0367 iter->
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 }
0367 iter->
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 }
0367 iter->
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 }
0367 iter->
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 }
0367 iter->
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),