27#include "dbus-object-tree.h"
28#include "dbus-connection-internal.h"
29#include "dbus-internals.h"
31#include "dbus-protocol.h"
32#include "dbus-string.h"
33#include <dbus/dbus-test-tap.h>
110 tree->
root = _dbus_object_subtree_new (
"/",
NULL,
NULL);
163#define VERBOSE_FIND 0
168 dbus_bool_t create_if_not_found,
169 int *index_in_parent,
170 dbus_bool_t *exact_match)
173 dbus_bool_t return_deepest_match;
175 return_deepest_match = exact_match !=
NULL;
177 _dbus_assert (!(return_deepest_match && create_if_not_found));
182 _dbus_verbose (
" path exhausted, returning %s\n",
185 if (exact_match !=
NULL)
191 _dbus_verbose (
" searching children of %s for %s\n",
192 subtree->
name, path[0]);
205 _dbus_verbose (
" %s cmp %s = %d\n",
215 _dbus_verbose (
" storing parent index %d\n", k);
217 *index_in_parent = k;
220 if (return_deepest_match)
224 next = find_subtree_recurse (subtree->
subtrees[k],
225 &path[1], create_if_not_found,
226 index_in_parent, exact_match);
231 _dbus_verbose (
" no deeper match found, returning %s\n",
234 if (exact_match !=
NULL)
235 *exact_match =
FALSE;
242 return find_subtree_recurse (subtree->
subtrees[k],
243 &path[1], create_if_not_found,
244 index_in_parent, exact_match);
257 _dbus_verbose (
" no match found, current tree %s, create_if_not_found = %d\n",
258 subtree->
name, create_if_not_found);
261 if (create_if_not_found)
264 int child_pos, new_n_subtrees;
267 _dbus_verbose (
" creating subtree %s\n",
271 child = _dbus_object_subtree_new (path[0],
279 int new_max_subtrees;
285 if (new_subtrees ==
NULL)
287 _dbus_object_subtree_unref (child);
298 new_n_subtrees <= subtree->max_subtrees);
299 if (child_pos + 1 < new_n_subtrees)
301 memmove (&subtree->
subtrees[child_pos+1],
303 (new_n_subtrees - child_pos - 1) *
306 subtree->
subtrees[child_pos] = child;
309 *index_in_parent = child_pos;
313 return find_subtree_recurse (child,
314 &path[1], create_if_not_found,
315 index_in_parent, exact_match);
319 if (exact_match !=
NULL)
320 *exact_match =
FALSE;
325#ifdef DBUS_ENABLE_EMBEDDED_TESTS
329 int *index_in_parent)
334 _dbus_verbose (
"Looking for exact registered subtree\n");
337 subtree = find_subtree_recurse (tree->
root, path,
FALSE, index_in_parent,
NULL);
351 _dbus_verbose (
"Looking for subtree\n");
359 dbus_bool_t *exact_match)
362 _dbus_verbose (
"Looking for deepest handler\n");
366 *exact_match =
FALSE;
368 return find_subtree_recurse (tree->
root, path,
FALSE,
NULL, exact_match);
376 _dbus_verbose (
"Ensuring subtree\n");
381static char *flatten_path (
const char **path);
397 dbus_bool_t fallback,
409 subtree = ensure_subtree (tree, path);
412 _DBUS_SET_OOM (error);
420 char *complete_path = flatten_path (path);
423 "A handler is already registered for %s",
424 complete_path ? complete_path
425 :
"(cannot represent path: out of memory!)");
455 void **user_data_out)
505 _dbus_assert (child_index >= 0 && child_index < parent->n_subtrees);
507 candidate = parent->
subtrees[child_index];
517 memmove (&parent->
subtrees[child_index],
525 _dbus_object_subtree_unref (candidate);
570unregister_and_free_path_recurse
573 dbus_bool_t *continue_removal_attempts,
575 void **user_data_out)
585 return unregister_subtree (subtree, unregister_function_out, user_data_out);
599 freed = unregister_and_free_path_recurse (subtree->
subtrees[k],
601 continue_removal_attempts,
602 unregister_function_out,
604 if (freed && *continue_removal_attempts)
605 *continue_removal_attempts = attempt_child_removal (subtree, k);
631 dbus_bool_t found_subtree;
632 dbus_bool_t continue_removal_attempts;
640 continue_removal_attempts =
TRUE;
641 unregister_function =
NULL;
644 found_subtree = unregister_and_free_path_recurse (tree->
root,
646 &continue_removal_attempts,
647 &unregister_function,
650#ifndef DBUS_DISABLE_CHECKS
651 if (found_subtree ==
FALSE)
653 _dbus_warn (
"Attempted to unregister path (path[0] = %s path[1] = %s) which isn't registered",
654 path[0] ? path[0] :
"null",
655 (path[0] && path[1]) ? path[1] :
"null");
666#ifdef DBUS_ENABLE_EMBEDDED_TESTS
671 _dbus_verbose (
"unlock\n");
675 if (unregister_function)
676 (* unregister_function) (connection, user_data);
678#ifdef DBUS_ENABLE_EMBEDDED_TESTS
700 free_subtree_recurse (connection, child);
713 _dbus_object_subtree_unref (subtree);
733 const char **parent_path,
734 char ***child_entries)
742 *child_entries =
NULL;
744 subtree = lookup_subtree (tree, parent_path);
756 while (i < subtree->n_subtrees)
759 if (retval[i] ==
NULL)
771 *child_entries = retval;
772 return retval !=
NULL;
786 const char *v_STRING;
787 dbus_bool_t already_unlocked;
791 already_unlocked =
FALSE;
793 _dbus_verbose (
" considering default Introspect() handler...\n");
801#ifdef DBUS_ENABLE_EMBEDDED_TESTS
805 _dbus_verbose (
"unlock\n");
812 _dbus_verbose (
" using default Introspect() handler!\n");
816#ifdef DBUS_ENABLE_EMBEDDED_TESTS
820 _dbus_verbose (
"unlock\n");
830 if (!_dbus_object_tree_list_registered_unlocked (tree, path, &children))
840 while (children[i] !=
NULL)
857 v_STRING = _dbus_string_get_const_data (&xml);
861#ifdef DBUS_ENABLE_EMBEDDED_TESTS
865 already_unlocked =
TRUE;
874#ifdef DBUS_ENABLE_EMBEDDED_TESTS
878 if (!already_unlocked)
880 _dbus_verbose (
"unlock\n");
910 dbus_bool_t *found_object)
913 dbus_bool_t exact_match;
920 _dbus_verbose (
"Dispatch of message by object path\n");
926#ifdef DBUS_ENABLE_EMBEDDED_TESTS
930 _dbus_verbose (
"unlock\n");
934 _dbus_verbose (
"No memory to get decomposed path\n");
941#ifdef DBUS_ENABLE_EMBEDDED_TESTS
945 _dbus_verbose (
"unlock\n");
949 _dbus_verbose (
"No path field in message\n");
954 subtree = find_handler (tree, (
const char**) path, &exact_match);
957 *found_object = !!subtree;
963 while (subtree !=
NULL)
967 _dbus_object_subtree_ref (subtree);
973 _dbus_object_subtree_unref (subtree);
974 goto free_and_return;
979 subtree = subtree->
parent;
982 _dbus_verbose (
"%d handlers in the path tree for this message\n",
993 subtree = link->
data;
1007 _dbus_verbose (
" (invoking a handler)\n");
1010#ifdef DBUS_ENABLE_EMBEDDED_TESTS
1014 _dbus_verbose (
"unlock\n");
1023 result = (* message_function) (tree->
connection,
1027#ifdef DBUS_ENABLE_EMBEDDED_TESTS
1033 goto free_and_return;
1045 result = handle_default_introspect_and_unlock (tree, message,
1046 (
const char**) path);
1050#ifdef DBUS_ENABLE_EMBEDDED_TESTS
1054 _dbus_verbose (
"unlock\n");
1059 while (list !=
NULL)
1062 _dbus_object_subtree_unref (link->
data);
1083 dbus_bool_t exact_match;
1090 subtree = find_handler (tree, (
const char**) path, &exact_match);
1092 if ((subtree ==
NULL) || !exact_match)
1094 _dbus_verbose (
"No object at specified path found\n");
1108allocate_subtree_object (
const char *name)
1116 len = strlen (name);
1120 if (subtree ==
NULL)
1123 memcpy (subtree->
name, name, len + 1);
1129_dbus_object_subtree_new (
const char *name,
1135 subtree = allocate_subtree_object (name);
1136 if (subtree ==
NULL)
1170#ifdef DBUS_DISABLE_ASSERT
1173 dbus_int32_t old_value;
1185 dbus_int32_t old_value;
1212 const char **parent_path,
1213 char ***child_entries)
1217 result = _dbus_object_tree_list_registered_unlocked (tree,
1221#ifdef DBUS_ENABLE_EMBEDDED_TESTS
1225 _dbus_verbose (
"unlock\n");
1234#define VERBOSE_DECOMPOSE 0
1259#if VERBOSE_DECOMPOSE
1260 _dbus_verbose (
"Decomposing path \"%s\"\n",
1277 retval =
dbus_new0 (
char*, n_components + 1);
1283 if (n_components == 0)
1287 while (comp < n_components)
1295 while (j < len && data[j] !=
'/')
1303#if VERBOSE_DECOMPOSE
1304 _dbus_verbose (
" (component in [%d,%d))\n",
1309 if (retval[comp] ==
NULL)
1314 retval[comp][j-i] =
'\0';
1315#if VERBOSE_DECOMPOSE
1316 _dbus_verbose (
" (component %d = \"%s\")\n",
1317 comp, retval[comp]);
1327 *path_len = n_components;
1335flatten_path (
const char **path)
1343 if (path[0] ==
NULL)
1378#ifdef DBUS_ENABLE_EMBEDDED_TESTS
1380#ifndef DOXYGEN_SHOULD_SKIP_THIS
1382#include "dbus-test.h"
1395path_contains (
const char **container,
1401 while (child[i] !=
NULL)
1405 if (container[i] ==
NULL)
1414 v = strcmp (container[i], child[i]);
1417 return STR_DIFFERENT;
1427 if (container[i] ==
NULL)
1430 return STR_DIFFERENT;
1443 _dbus_verbose (
" ");
1447 _dbus_verbose (
"%s (%d children)\n",
1451 while (i < subtree->n_subtrees)
1453 spew_subtree_recurse (subtree->
subtrees[i], indent + 2);
1462 spew_subtree_recurse (tree->
root, 0);
1472 dbus_bool_t handler_fallback;
1473 dbus_bool_t message_handled;
1474 dbus_bool_t handler_unregistered;
1482 TreeTestData *ttd = user_data;
1484 ttd->handler_unregistered =
TRUE;
1492 TreeTestData *ttd = user_data;
1494 ttd->message_handled =
TRUE;
1502 dbus_bool_t fallback,
1504 TreeTestData *tree_test_data)
1507 test_message_function,
NULL };
1509 tree_test_data[i].message_handled =
FALSE;
1510 tree_test_data[i].handler_unregistered =
FALSE;
1511 tree_test_data[i].handler_fallback = fallback;
1512 tree_test_data[i].path = path;
1521 &tree_test_data[i]);
1530 TreeTestData *tree_test_data,
1540 flat = flatten_path (path);
1546 "org.freedesktop.TestInterface",
1549 if (message ==
NULL)
1553 while (j < n_test_data)
1555 tree_test_data[j].message_handled =
FALSE;
1566 while (j < n_test_data)
1568 if (tree_test_data[j].message_handled)
1570 if (tree_test_data[j].handler_fallback)
1572 path) != STR_DIFFERENT);
1574 _dbus_assert (path_contains (tree_test_data[j].path, path) == STR_EQUAL);
1578 if (tree_test_data[j].handler_fallback)
1580 path) == STR_DIFFERENT);
1582 _dbus_assert (path_contains (tree_test_data[j].path, path) != STR_EQUAL);
1601 const char *result[20];
1604static DecomposePathTest decompose_tests[] = {
1605 {
"/foo", {
"foo",
NULL } },
1606 {
"/foo/bar", {
"foo",
"bar",
NULL } },
1608 {
"/a/b", {
"a",
"b",
NULL } },
1609 {
"/a/b/c", {
"a",
"b",
"c",
NULL } },
1610 {
"/a/b/c/d", {
"a",
"b",
"c",
"d",
NULL } },
1611 {
"/foo/bar/q", {
"foo",
"bar",
"q",
NULL } },
1612 {
"/foo/bar/this/is/longer", {
"foo",
"bar",
"this",
"is",
"longer",
NULL } }
1618run_decompose_tests (
void)
1630 strlen (decompose_tests[i].path),
1631 &result, &result_len))
1637 expected_len != result_len ||
1638 path_contains (decompose_tests[i].result,
1639 (
const char**) result) != STR_EQUAL)
1642 _dbus_warn (
"Expected decompose of %s to have len %d, returned %d, appears to have %d",
1643 decompose_tests[i].path, expected_len, result_len,
1645 _dbus_warn (
"Decompose resulted in elements: { ");
1647 while (i < real_len)
1650 (i + 1) == real_len ?
"" :
", ");
1654 _dbus_test_fatal (
"path decompose failed");
1670 _dbus_verbose (
"Looking for exact subtree, registered or unregistered\n");
1679object_tree_test_iteration (
void *data,
1680 dbus_bool_t have_memory)
1682 const char *path0[] = {
NULL };
1683 const char *path1[] = {
"foo",
NULL };
1684 const char *path2[] = {
"foo",
"bar",
NULL };
1685 const char *path3[] = {
"foo",
"bar",
"baz",
NULL };
1686 const char *path4[] = {
"foo",
"bar",
"boo",
NULL };
1687 const char *path5[] = {
"blah",
NULL };
1688 const char *path6[] = {
"blah",
"boof",
NULL };
1689 const char *path7[] = {
"blah",
"boof",
"this",
"is",
"really",
"long",
NULL };
1690 const char *path8[] = {
"childless",
NULL };
1691 const char *path9[] = {
"blah",
"a",
NULL };
1692 const char *path10[] = {
"blah",
"b",
NULL };
1693 const char *path11[] = {
"blah",
"c",
NULL };
1694 const char *path12[] = {
"blah",
"a",
"d",
NULL };
1695 const char *path13[] = {
"blah",
"b",
"d",
NULL };
1696 const char *path14[] = {
"blah",
"c",
"d",
NULL };
1699 TreeTestData tree_test_data[9];
1701 dbus_bool_t exact_match;
1703 if (!run_decompose_tests ())
1712 if (!do_register (tree, path0,
TRUE, 0, tree_test_data))
1725 _dbus_assert (find_handler (tree, path0, &exact_match) && exact_match);
1726 _dbus_assert (find_handler (tree, path1, &exact_match) == tree->
root && !exact_match);
1727 _dbus_assert (find_handler (tree, path2, &exact_match) == tree->
root && !exact_match);
1728 _dbus_assert (find_handler (tree, path3, &exact_match) == tree->
root && !exact_match);
1729 _dbus_assert (find_handler (tree, path4, &exact_match) == tree->
root && !exact_match);
1730 _dbus_assert (find_handler (tree, path5, &exact_match) == tree->
root && !exact_match);
1731 _dbus_assert (find_handler (tree, path6, &exact_match) == tree->
root && !exact_match);
1732 _dbus_assert (find_handler (tree, path7, &exact_match) == tree->
root && !exact_match);
1733 _dbus_assert (find_handler (tree, path8, &exact_match) == tree->
root && !exact_match);
1735 if (!do_register (tree, path1,
TRUE, 1, tree_test_data))
1748 _dbus_assert (find_handler (tree, path0, &exact_match) && exact_match);
1749 _dbus_assert (find_handler (tree, path1, &exact_match) && exact_match);
1750 _dbus_assert (find_handler (tree, path2, &exact_match) && !exact_match);
1751 _dbus_assert (find_handler (tree, path3, &exact_match) && !exact_match);
1752 _dbus_assert (find_handler (tree, path4, &exact_match) && !exact_match);
1753 _dbus_assert (find_handler (tree, path5, &exact_match) == tree->
root && !exact_match);
1754 _dbus_assert (find_handler (tree, path6, &exact_match) == tree->
root && !exact_match);
1755 _dbus_assert (find_handler (tree, path7, &exact_match) == tree->
root && !exact_match);
1756 _dbus_assert (find_handler (tree, path8, &exact_match) == tree->
root && !exact_match);
1758 if (!do_register (tree, path2,
TRUE, 2, tree_test_data))
1770 if (!do_register (tree, path3,
TRUE, 3, tree_test_data))
1783 if (!do_register (tree, path4,
TRUE, 4, tree_test_data))
1796 if (!do_register (tree, path5,
TRUE, 5, tree_test_data))
1809 _dbus_assert (find_handler (tree, path0, &exact_match) == tree->
root && exact_match);
1810 _dbus_assert (find_handler (tree, path1, &exact_match) != tree->
root && exact_match);
1811 _dbus_assert (find_handler (tree, path2, &exact_match) != tree->
root && exact_match);
1812 _dbus_assert (find_handler (tree, path3, &exact_match) != tree->
root && exact_match);
1813 _dbus_assert (find_handler (tree, path4, &exact_match) != tree->
root && exact_match);
1814 _dbus_assert (find_handler (tree, path5, &exact_match) != tree->
root && exact_match);
1815 _dbus_assert (find_handler (tree, path6, &exact_match) != tree->
root && !exact_match);
1816 _dbus_assert (find_handler (tree, path7, &exact_match) != tree->
root && !exact_match);
1817 _dbus_assert (find_handler (tree, path8, &exact_match) == tree->
root && !exact_match);
1819 if (!do_register (tree, path6,
TRUE, 6, tree_test_data))
1832 if (!do_register (tree, path7,
TRUE, 7, tree_test_data))
1845 if (!do_register (tree, path8,
TRUE, 8, tree_test_data))
1858 _dbus_assert (find_handler (tree, path0, &exact_match) == tree->
root && exact_match);
1859 _dbus_assert (find_handler (tree, path1, &exact_match) != tree->
root && exact_match);
1860 _dbus_assert (find_handler (tree, path2, &exact_match) != tree->
root && exact_match);
1861 _dbus_assert (find_handler (tree, path3, &exact_match) != tree->
root && exact_match);
1862 _dbus_assert (find_handler (tree, path4, &exact_match) != tree->
root && exact_match);
1863 _dbus_assert (find_handler (tree, path5, &exact_match) != tree->
root && exact_match);
1864 _dbus_assert (find_handler (tree, path6, &exact_match) != tree->
root && exact_match);
1865 _dbus_assert (find_handler (tree, path7, &exact_match) != tree->
root && exact_match);
1866 _dbus_assert (find_handler (tree, path8, &exact_match) != tree->
root && exact_match);
1871 const char *root[] = {
NULL };
1872 char **child_entries;
1875 _dbus_object_tree_list_registered_unlocked (tree, path1, &child_entries);
1876 if (child_entries !=
NULL)
1883 _dbus_object_tree_list_registered_unlocked (tree, path2, &child_entries);
1884 if (child_entries !=
NULL)
1891 _dbus_object_tree_list_registered_unlocked (tree, path8, &child_entries);
1892 if (child_entries !=
NULL)
1899 _dbus_object_tree_list_registered_unlocked (tree, root, &child_entries);
1900 if (child_entries !=
NULL)
1924 if (!do_register (tree, path0,
TRUE, 0, tree_test_data))
1926 if (!do_register (tree, path1,
TRUE, 1, tree_test_data))
1928 if (!do_register (tree, path2,
TRUE, 2, tree_test_data))
1930 if (!do_register (tree, path3,
TRUE, 3, tree_test_data))
1932 if (!do_register (tree, path4,
TRUE, 4, tree_test_data))
1934 if (!do_register (tree, path5,
TRUE, 5, tree_test_data))
1936 if (!do_register (tree, path6,
TRUE, 6, tree_test_data))
1938 if (!do_register (tree, path7,
TRUE, 7, tree_test_data))
1940 if (!do_register (tree, path8,
TRUE, 8, tree_test_data))
2069 if (!do_register (tree, path2,
TRUE, 2, tree_test_data))
2073 _dbus_assert (!find_subtree_registered_or_unregistered (tree, path2));
2074 _dbus_assert (!find_subtree_registered_or_unregistered (tree, path1));
2075 _dbus_assert (find_subtree_registered_or_unregistered (tree, path0));
2079 if (!do_register (tree, path2,
TRUE, 2, tree_test_data))
2083 _dbus_assert (find_subtree_registered_or_unregistered (tree, path1));
2084 _dbus_assert (find_subtree_registered_or_unregistered (tree, path0));
2092 _dbus_assert (find_subtree_registered_or_unregistered (tree, path1));
2093 _dbus_assert (find_subtree_registered_or_unregistered (tree, path0));
2097 _dbus_assert (!find_subtree_registered_or_unregistered (tree, path2));
2098 _dbus_assert (!find_subtree_registered_or_unregistered (tree, path1));
2099 _dbus_assert (find_subtree_registered_or_unregistered (tree, path0));
2104 if (!do_register (tree, path1,
TRUE, 1, tree_test_data))
2106 if (!do_register (tree, path2,
TRUE, 2, tree_test_data))
2115 _dbus_assert (find_subtree_registered_or_unregistered (tree, path1));
2116 _dbus_assert (find_subtree_registered_or_unregistered (tree, path0));
2120 _dbus_assert (!find_subtree_registered_or_unregistered (tree, path1));
2122 _dbus_assert (!find_subtree_registered_or_unregistered (tree, path2));
2123 _dbus_assert (find_subtree_registered_or_unregistered (tree, path0));
2135 _dbus_assert (!find_subtree_registered_or_unregistered (tree, path2));
2136 _dbus_assert (!find_subtree_registered_or_unregistered (tree, path1));
2137 _dbus_assert (find_subtree_registered_or_unregistered (tree, path0));
2140 if (!do_register (tree, path3,
TRUE, 3, tree_test_data))
2145 _dbus_assert (!find_subtree_registered_or_unregistered (tree, path3));
2146 _dbus_assert (!find_subtree_registered_or_unregistered (tree, path2));
2147 _dbus_assert (!find_subtree_registered_or_unregistered (tree, path1));
2148 _dbus_assert (find_subtree_registered_or_unregistered (tree, path0));
2151 if (!do_register (tree, path3,
TRUE, 3, tree_test_data))
2153 if (!do_register (tree, path4,
TRUE, 4, tree_test_data))
2161 _dbus_assert (!find_subtree_registered_or_unregistered (tree, path3));
2163 _dbus_assert (find_subtree_registered_or_unregistered (tree, path4));
2164 _dbus_assert (find_subtree_registered_or_unregistered (tree, path2));
2165 _dbus_assert (find_subtree_registered_or_unregistered (tree, path1));
2169 _dbus_assert (!find_subtree_registered_or_unregistered (tree, path4));
2171 _dbus_assert (!find_subtree_registered_or_unregistered (tree, path3));
2172 _dbus_assert (!find_subtree_registered_or_unregistered (tree, path2));
2173 _dbus_assert (!find_subtree_registered_or_unregistered (tree, path1));
2202 _dbus_assert (!find_subtree_registered_or_unregistered (tree, path12));
2205 _dbus_assert (!find_subtree_registered_or_unregistered (tree, path9));
2206 _dbus_assert (find_subtree_registered_or_unregistered (tree, path5));
2219 _dbus_assert (!find_subtree_registered_or_unregistered (tree, path13));
2221 _dbus_assert (!find_subtree_registered_or_unregistered (tree, path10));
2222 _dbus_assert (find_subtree_registered_or_unregistered (tree, path5));
2236 _dbus_assert (!find_subtree_registered_or_unregistered (tree, path14));
2237 _dbus_assert (!find_subtree_registered_or_unregistered (tree, path11));
2238 _dbus_assert (find_subtree_registered_or_unregistered (tree, path5));
2242 _dbus_assert (!find_subtree_registered_or_unregistered (tree, path12));
2243 _dbus_assert (!find_subtree_registered_or_unregistered (tree, path9));
2244 _dbus_assert (find_subtree_registered_or_unregistered (tree, path5));
2248 _dbus_assert (!find_subtree_registered_or_unregistered (tree, path13));
2249 _dbus_assert (!find_subtree_registered_or_unregistered (tree, path10));
2250 _dbus_assert (!find_subtree_registered_or_unregistered (tree, path5));
2264 if (!do_register (tree, path0,
TRUE, 0, tree_test_data))
2266 if (!do_register (tree, path1,
FALSE, 1, tree_test_data))
2268 if (!do_register (tree, path2,
TRUE, 2, tree_test_data))
2270 if (!do_register (tree, path3,
TRUE, 3, tree_test_data))
2272 if (!do_register (tree, path4,
TRUE, 4, tree_test_data))
2274 if (!do_register (tree, path5,
TRUE, 5, tree_test_data))
2276 if (!do_register (tree, path6,
FALSE, 6, tree_test_data))
2278 if (!do_register (tree, path7,
TRUE, 7, tree_test_data))
2280 if (!do_register (tree, path8,
TRUE, 8, tree_test_data))
2287 if (!do_test_dispatch (tree, path0, 0, tree_test_data,
_DBUS_N_ELEMENTS (tree_test_data)))
2289 if (!do_test_dispatch (tree, path1, 1, tree_test_data,
_DBUS_N_ELEMENTS (tree_test_data)))
2291 if (!do_test_dispatch (tree, path2, 2, tree_test_data,
_DBUS_N_ELEMENTS (tree_test_data)))
2293 if (!do_test_dispatch (tree, path3, 3, tree_test_data,
_DBUS_N_ELEMENTS (tree_test_data)))
2295 if (!do_test_dispatch (tree, path4, 4, tree_test_data,
_DBUS_N_ELEMENTS (tree_test_data)))
2297 if (!do_test_dispatch (tree, path5, 5, tree_test_data,
_DBUS_N_ELEMENTS (tree_test_data)))
2299 if (!do_test_dispatch (tree, path6, 6, tree_test_data,
_DBUS_N_ELEMENTS (tree_test_data)))
2301 if (!do_test_dispatch (tree, path7, 7, tree_test_data,
_DBUS_N_ELEMENTS (tree_test_data)))
2303 if (!do_test_dispatch (tree, path8, 8, tree_test_data,
_DBUS_N_ELEMENTS (tree_test_data)))
2324_dbus_object_tree_test (
const char *test_data_dir _DBUS_GNUC_UNUSED)
2326 return _dbus_test_oom_handling (
"object tree",
2327 object_tree_test_iteration,
dbus_bool_t _dbus_connection_send_and_unlock(DBusConnection *connection, DBusMessage *message, dbus_uint32_t *client_serial)
Like dbus_connection_send(), but assumes the connection is already locked on function entry,...
DBUS_PRIVATE_EXPORT void _dbus_connection_unlock(DBusConnection *connection)
Releases the connection lock.
DBUS_PRIVATE_EXPORT void _dbus_connection_lock(DBusConnection *connection)
Acquires the connection lock.
DBUS_PRIVATE_EXPORT DBusConnection * _dbus_connection_ref_unlocked(DBusConnection *connection)
Increments the reference count of a DBusConnection.
DBusHandlerResult(* DBusObjectPathMessageFunction)(DBusConnection *connection, DBusMessage *message, void *user_data)
Called when a message is sent to a registered object path.
void(* DBusObjectPathUnregisterFunction)(DBusConnection *connection, void *user_data)
Called when a DBusObjectPathVTable is unregistered (or its connection is freed).
void dbus_connection_unref(DBusConnection *connection)
Decrements the reference count of a DBusConnection, and finalizes it if the count reaches zero.
void dbus_set_error(DBusError *error, const char *name, const char *format,...)
Assigns an error name and message to a DBusError.
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
char * _dbus_strdup(const char *str)
Duplicates a string.
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
#define _DBUS_N_ELEMENTS(array)
Computes the number of elements in a fixed-size array using sizeof().
size_t _dbus_string_array_length(const char **array)
Returns the size of a string array.
void * _dbus_memdup(const void *mem, size_t n_bytes)
Duplicates a block of memory.
DBusList * _dbus_list_get_first_link(DBusList **list)
Gets the first link in the list.
void _dbus_list_remove_link(DBusList **list, DBusList *link)
Removes a link from the list.
int _dbus_list_get_length(DBusList **list)
Gets the length of a list.
dbus_bool_t _dbus_list_append(DBusList **list, void *data)
Appends a value to the list.
#define _dbus_list_get_next_link(list, link)
Gets the next link in the list, or NULL if there are no more links.
#define NULL
A null pointer, defined appropriately for C or C++.
#define TRUE
Expands to "1".
#define FALSE
Expands to "0".
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
void * dbus_realloc(void *memory, size_t bytes)
Resizes a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
void * dbus_malloc0(size_t bytes)
Allocates the given number of bytes, as with standard malloc(), but all bytes are initialized to zero...
#define dbus_new0(type, count)
Safe macro for using dbus_malloc0().
void dbus_free_string_array(char **str_array)
Frees a NULL-terminated array of strings.
dbus_bool_t dbus_message_iter_append_basic(DBusMessageIter *iter, int type, const void *value)
Appends a basic-typed value to the message.
DBusMessage * dbus_message_new_method_return(DBusMessage *method_call)
Constructs a message that is a reply to a method call.
DBusMessage * dbus_message_new_method_call(const char *destination, const char *path, const char *iface, const char *method)
Constructs a new message to invoke a method on a remote object.
void dbus_message_unref(DBusMessage *message)
Decrements the reference count of a DBusMessage, freeing the message if the count reaches 0.
dbus_bool_t dbus_message_is_method_call(DBusMessage *message, const char *iface, const char *method)
Checks whether the message is a method call with the given interface and member fields.
dbus_bool_t dbus_message_get_path_decomposed(DBusMessage *message, char ***path)
Gets the object path this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitt...
void dbus_message_iter_init_append(DBusMessage *message, DBusMessageIter *iter)
Initializes a DBusMessageIter for appending arguments to the end of a message.
void _dbus_object_tree_free_all_unlocked(DBusObjectTree *tree)
Free all the handlers in the tree.
void _dbus_object_tree_unregister_and_unlock(DBusObjectTree *tree, const char **path)
Unregisters an object subtree that was registered with the same path.
void _dbus_object_tree_unref(DBusObjectTree *tree)
Decrement the reference count.
dbus_bool_t _dbus_object_tree_list_registered_and_unlock(DBusObjectTree *tree, const char **parent_path, char ***child_entries)
Lists the registered fallback handlers and object path handlers at the given parent_path.
dbus_bool_t _dbus_decompose_path(const char *data, int len, char ***path, int *path_len)
Decompose an object path.
dbus_bool_t _dbus_object_tree_register(DBusObjectTree *tree, dbus_bool_t fallback, const char **path, const DBusObjectPathVTable *vtable, void *user_data, DBusError *error)
Registers a new subtree in the global object tree.
void * _dbus_object_tree_get_user_data_unlocked(DBusObjectTree *tree, const char **path)
Looks up the data passed to _dbus_object_tree_register() for a handler at the given path.
DBusHandlerResult _dbus_object_tree_dispatch_and_unlock(DBusObjectTree *tree, DBusMessage *message, dbus_bool_t *found_object)
Tries to dispatch a message by directing it to handler for the object path listed in the message head...
DBusObjectTree * _dbus_object_tree_ref(DBusObjectTree *tree)
Increment the reference count.
DBusObjectTree * _dbus_object_tree_new(DBusConnection *connection)
Creates a new object tree, representing a mapping from paths to handler vtables.
#define DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
XML document type declaration of the introspection format version 1.0.
#define DBUS_ERROR_OBJECT_PATH_IN_USE
There's already an object with the requested object path.
#define DBUS_TYPE_STRING
Type code marking a UTF-8 encoded, nul-terminated Unicode string.
DBusHandlerResult
Results that a message handler can return.
#define DBUS_INTERFACE_INTROSPECTABLE
The interface supported by introspectable objects.
@ DBUS_HANDLER_RESULT_NEED_MEMORY
Need more memory in order to return DBUS_HANDLER_RESULT_HANDLED or DBUS_HANDLER_RESULT_NOT_YET_HANDLE...
@ DBUS_HANDLER_RESULT_HANDLED
Message has had its effect - no need to run more handlers.
@ DBUS_HANDLER_RESULT_NOT_YET_HANDLED
Message has not had any effect - see if other handlers want it.
dbus_bool_t _dbus_string_append(DBusString *str, const char *buffer)
Appends a nul-terminated C-style string to a DBusString.
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
dbus_bool_t _dbus_string_steal_data(DBusString *str, char **data_return)
Like _dbus_string_get_data(), but removes the gotten data from the original string.
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init(), and fills it with the same contents as _DBUS_STRING_IN...
dbus_bool_t _dbus_string_append_byte(DBusString *str, unsigned char byte)
Appends a single byte to the string, returning FALSE if not enough memory.
dbus_bool_t _dbus_string_append_printf(DBusString *str, const char *format,...)
Appends a printf-style formatted string to the DBusString.
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer.
dbus_int32_t _dbus_atomic_inc(DBusAtomic *atomic)
Atomically increments an integer.
An atomic integer safe to increment or decrement from multiple threads.
Implementation details of DBusConnection.
Object representing an exception.
void * data
Data stored at this element.
DBusMessageIter struct; contains no public fields.
Internals of DBusMessage.
Virtual table that must be implemented to handle a portion of the object path hierarchy.
DBusObjectPathMessageFunction message_function
Function to handle messages.
DBusObjectPathUnregisterFunction unregister_function
Function to unregister this handler.
Struct representing a single registered subtree handler, or node that's a parent of a registered subt...
DBusObjectSubtree * parent
Parent node.
DBusAtomic refcount
Reference count.
DBusObjectPathMessageFunction message_function
Function to handle messages.
DBusObjectPathUnregisterFunction unregister_function
Function to call on unregister.
int n_subtrees
Number of child nodes.
unsigned int invoke_as_fallback
Whether to invoke message_function when child nodes don't handle the message.
int max_subtrees
Number of allocated entries in subtrees.
void * user_data
Data for functions.
char name[1]
Allocated as large as necessary.
DBusObjectSubtree ** subtrees
Child nodes.
Internals of DBusObjectTree.
DBusConnection * connection
Connection this tree belongs to.
int refcount
Reference count.
DBusObjectSubtree * root
Root of the tree ("/" node)