25 #include "dbus-object-tree.h"    26 #include "dbus-connection-internal.h"    27 #include "dbus-internals.h"    28 #include "dbus-hash.h"    29 #include "dbus-protocol.h"    30 #include "dbus-string.h"   107   tree->
root = _dbus_object_subtree_new (
"/", 
NULL, 
NULL);
   160 #define VERBOSE_FIND 0   166                       int                *index_in_parent,
   172   return_deepest_match = exact_match != 
NULL;
   174   _dbus_assert (!(return_deepest_match && create_if_not_found));
   179       _dbus_verbose (
"  path exhausted, returning %s\n",
   182       if (exact_match != 
NULL)
   188   _dbus_verbose (
"  searching children of %s for %s\n",
   189                  subtree->
name, path[0]);
   202       _dbus_verbose (
"  %s cmp %s = %d\n",
   212               _dbus_verbose (
"  storing parent index %d\n", k);
   214               *index_in_parent = k;
   217           if (return_deepest_match)
   221               next = find_subtree_recurse (subtree->
subtrees[k],
   222                                            &path[1], create_if_not_found, 
   223                                            index_in_parent, exact_match);
   228                   _dbus_verbose (
"  no deeper match found, returning %s\n",
   231                   if (exact_match != 
NULL)
   232                     *exact_match = 
FALSE;
   239             return find_subtree_recurse (subtree->
subtrees[k],
   240                                          &path[1], create_if_not_found, 
   241                                          index_in_parent, exact_match);
   254   _dbus_verbose (
"  no match found, current tree %s, create_if_not_found = %d\n",
   255                  subtree->
name, create_if_not_found);
   258   if (create_if_not_found)
   261       int child_pos, new_n_subtrees;
   264       _dbus_verbose (
"  creating subtree %s\n",
   268       child = _dbus_object_subtree_new (path[0],
   276           int new_max_subtrees;
   282           if (new_subtrees == 
NULL)
   284               _dbus_object_subtree_unref (child);
   295                     new_n_subtrees <= subtree->max_subtrees);
   296       if (child_pos + 1 < new_n_subtrees)
   298           memmove (&subtree->
subtrees[child_pos+1], 
   300                    (new_n_subtrees - child_pos - 1) * 
   303       subtree->
subtrees[child_pos] = child;
   306         *index_in_parent = child_pos;
   310       return find_subtree_recurse (child,
   311                                    &path[1], create_if_not_found, 
   312                                    index_in_parent, exact_match);
   316       if (exact_match != 
NULL)
   317         *exact_match = 
FALSE;
   322 #ifdef DBUS_ENABLE_EMBEDDED_TESTS   326               int            *index_in_parent)
   331   _dbus_verbose (
"Looking for exact registered subtree\n");
   334   subtree = find_subtree_recurse (tree->
root, path, 
FALSE, index_in_parent, 
NULL);
   348   _dbus_verbose (
"Looking for subtree\n");
   359   _dbus_verbose (
"Looking for deepest handler\n");
   363   *exact_match = 
FALSE; 
   365   return find_subtree_recurse (tree->
root, path, 
FALSE, 
NULL, exact_match);
   373   _dbus_verbose (
"Ensuring subtree\n");
   378 static char *flatten_path (
const char **path);
   406   subtree = ensure_subtree (tree, path);
   409       _DBUS_SET_OOM (error);
   417           char *complete_path = flatten_path (path);
   420                           "A handler is already registered for %s",
   421                           complete_path ? complete_path
   422                                         : 
"(cannot represent path: out of memory!)");
   452                     void                             **user_data_out)
   502   _dbus_assert (child_index >= 0 && child_index < parent->n_subtrees);
   504   candidate = parent->
subtrees[child_index];
   514       memmove (&parent->
subtrees[child_index],
   522       _dbus_object_subtree_unref (candidate);
   567 unregister_and_free_path_recurse
   572  void                             **user_data_out)
   582     return unregister_subtree (subtree, unregister_function_out, user_data_out);
   596           freed = unregister_and_free_path_recurse (subtree->
subtrees[k],
   598                                                     continue_removal_attempts,
   599                                                     unregister_function_out,
   601           if (freed && *continue_removal_attempts)
   602             *continue_removal_attempts = attempt_child_removal (subtree, k);
   637   continue_removal_attempts = 
TRUE;
   638   unregister_function = 
NULL;
   641   found_subtree = unregister_and_free_path_recurse (tree->
root,
   643                                                     &continue_removal_attempts,
   644                                                     &unregister_function,
   647 #ifndef DBUS_DISABLE_CHECKS   648   if (found_subtree == 
FALSE)
   650       _dbus_warn (
"Attempted to unregister path (path[0] = %s path[1] = %s) which isn't registered",
   651                   path[0] ? path[0] : 
"null",
   652                   (path[0] && path[1]) ? path[1] : 
"null");
   663 #ifdef DBUS_ENABLE_EMBEDDED_TESTS   668       _dbus_verbose (
"unlock\n");
   672   if (unregister_function)
   673     (* unregister_function) (connection, user_data);
   675 #ifdef DBUS_ENABLE_EMBEDDED_TESTS   697       free_subtree_recurse (connection, child);
   710   _dbus_object_subtree_unref (subtree);
   730                                             const char    **parent_path,
   731                                             char         ***child_entries)
   739   *child_entries = 
NULL;
   741   subtree = lookup_subtree (tree, parent_path);
   753       while (i < subtree->n_subtrees)
   756           if (retval[i] == 
NULL)
   768   *child_entries = retval;
   769   return retval != 
NULL;
   783   const char *v_STRING;
   788   already_unlocked = 
FALSE;
   790   _dbus_verbose (
" considering default Introspect() handler...\n");
   798 #ifdef DBUS_ENABLE_EMBEDDED_TESTS   802           _dbus_verbose (
"unlock\n");
   809   _dbus_verbose (
" using default Introspect() handler!\n");
   813 #ifdef DBUS_ENABLE_EMBEDDED_TESTS   817           _dbus_verbose (
"unlock\n");
   827   if (!_dbus_object_tree_list_registered_unlocked (tree, path, &children))
   837   while (children[i] != 
NULL)
   854   v_STRING = _dbus_string_get_const_data (&xml);
   858 #ifdef DBUS_ENABLE_EMBEDDED_TESTS   862       already_unlocked = 
TRUE;
   871 #ifdef DBUS_ENABLE_EMBEDDED_TESTS   875       if (!already_unlocked)
   877           _dbus_verbose (
"unlock\n");
   917   _dbus_verbose (
"Dispatch of message by object path\n");
   923 #ifdef DBUS_ENABLE_EMBEDDED_TESTS   927           _dbus_verbose (
"unlock\n");
   931       _dbus_verbose (
"No memory to get decomposed path\n");
   938 #ifdef DBUS_ENABLE_EMBEDDED_TESTS   942           _dbus_verbose (
"unlock\n");
   946       _dbus_verbose (
"No path field in message\n");
   951   subtree = find_handler (tree, (
const char**) path, &exact_match);
   954     *found_object = !!subtree;
   960   while (subtree != 
NULL)
   964           _dbus_object_subtree_ref (subtree);
   970               _dbus_object_subtree_unref (subtree);
   971               goto free_and_return;
   976       subtree = subtree->
parent;
   979   _dbus_verbose (
"%d handlers in the path tree for this message\n",
   990       subtree = link->
data;
  1004           _dbus_verbose (
"  (invoking a handler)\n");
  1007 #ifdef DBUS_ENABLE_EMBEDDED_TESTS  1011               _dbus_verbose (
"unlock\n");
  1020           result = (* message_function) (tree->
connection,
  1024 #ifdef DBUS_ENABLE_EMBEDDED_TESTS  1030             goto free_and_return;
  1042       result = handle_default_introspect_and_unlock (tree, message,
  1043                                                      (
const char**) path);
  1047 #ifdef DBUS_ENABLE_EMBEDDED_TESTS  1051           _dbus_verbose (
"unlock\n");
  1056   while (list != 
NULL)
  1059       _dbus_object_subtree_unref (link->
data);
  1087   subtree = find_handler (tree, (
const char**) path, &exact_match);
  1089   if ((subtree == 
NULL) || !exact_match)
  1091       _dbus_verbose (
"No object at specified path found\n");
  1105 allocate_subtree_object (
const char *name)
  1113   len = strlen (name);
  1117   if (subtree == 
NULL)
  1120   memcpy (subtree->
name, name, len + 1);
  1126 _dbus_object_subtree_new (
const char                  *name,
  1132   subtree = allocate_subtree_object (name);
  1133   if (subtree == 
NULL)
  1167 #ifdef DBUS_DISABLE_ASSERT  1209                                               const char    **parent_path,
  1210                                               char         ***child_entries)
  1214   result = _dbus_object_tree_list_registered_unlocked (tree,
  1218 #ifdef DBUS_ENABLE_EMBEDDED_TESTS  1222       _dbus_verbose (
"unlock\n");
  1231 #define VERBOSE_DECOMPOSE 0  1256 #if VERBOSE_DECOMPOSE  1257   _dbus_verbose (
"Decomposing path \"%s\"\n",
  1274   retval = 
dbus_new0 (
char*, n_components + 1);
  1280   if (n_components == 0)
  1284   while (comp < n_components)
  1292       while (j < len && data[j] != 
'/')
  1300 #if VERBOSE_DECOMPOSE  1301       _dbus_verbose (
"  (component in [%d,%d))\n",
  1306       if (retval[comp] == 
NULL)
  1311       retval[comp][j-i] = 
'\0';
  1312 #if VERBOSE_DECOMPOSE  1313       _dbus_verbose (
"  (component %d = \"%s\")\n",
  1314                      comp, retval[comp]);
  1324     *path_len = n_components;
  1332 flatten_path (
const char **path)
  1340   if (path[0] == 
NULL)
  1375 #ifdef DBUS_ENABLE_EMBEDDED_TESTS  1377 #ifndef DOXYGEN_SHOULD_SKIP_THIS  1379 #include "dbus-test.h"  1391 static StrComparison
  1392 path_contains (
const char **container,
  1398   while (child[i] != 
NULL)
  1402       if (container[i] == 
NULL)
  1411       v = strcmp (container[i], child[i]);
  1414         return STR_DIFFERENT; 
  1424   if (container[i] == 
NULL)
  1427     return STR_DIFFERENT;
  1440       _dbus_verbose (
" ");
  1444   _dbus_verbose (
"%s (%d children)\n",
  1448   while (i < subtree->n_subtrees)
  1450       spew_subtree_recurse (subtree->
subtrees[i], indent + 2);
  1459   spew_subtree_recurse (tree->
root, 0);
  1479   TreeTestData *ttd = user_data;
  1481   ttd->handler_unregistered = 
TRUE;
  1489   TreeTestData *ttd = user_data;
  1491   ttd->message_handled = 
TRUE;
  1501              TreeTestData   *tree_test_data)
  1504                                   test_message_function, 
NULL };
  1506   tree_test_data[i].message_handled = 
FALSE;
  1507   tree_test_data[i].handler_unregistered = 
FALSE;
  1508   tree_test_data[i].handler_fallback = fallback;
  1509   tree_test_data[i].path = path;
  1518                 &tree_test_data[i]);
  1527                   TreeTestData   *tree_test_data,
  1537   flat = flatten_path (path);
  1543                                           "org.freedesktop.TestInterface",
  1546   if (message == 
NULL)
  1550   while (j < n_test_data)
  1552       tree_test_data[j].message_handled = 
FALSE;
  1563   while (j < n_test_data)
  1565       if (tree_test_data[j].message_handled)
  1567           if (tree_test_data[j].handler_fallback)
  1569                                          path) != STR_DIFFERENT);
  1571             _dbus_assert (path_contains (tree_test_data[j].path, path) == STR_EQUAL);
  1575           if (tree_test_data[j].handler_fallback)
  1577                                          path) == STR_DIFFERENT);
  1579             _dbus_assert (path_contains (tree_test_data[j].path, path) != STR_EQUAL);
  1598   const char *result[20];
  1599 } DecomposePathTest;
  1601 static DecomposePathTest decompose_tests[] = {
  1602   { 
"/foo", { 
"foo", 
NULL } },
  1603   { 
"/foo/bar", { 
"foo", 
"bar", 
NULL } },
  1605   { 
"/a/b", { 
"a", 
"b", 
NULL } },
  1606   { 
"/a/b/c", { 
"a", 
"b", 
"c", 
NULL } },
  1607   { 
"/a/b/c/d", { 
"a", 
"b", 
"c", 
"d", 
NULL } },
  1608   { 
"/foo/bar/q", { 
"foo", 
"bar", 
"q", 
NULL } },
  1609   { 
"/foo/bar/this/is/longer", { 
"foo", 
"bar", 
"this", 
"is", 
"longer", 
NULL } }
  1615 run_decompose_tests (
void)
  1627                                  strlen (decompose_tests[i].path),
  1628                                  &result, &result_len))
  1634           expected_len != result_len ||
  1635           path_contains (decompose_tests[i].result,
  1636                          (
const char**) result) != STR_EQUAL)
  1639           _dbus_warn (
"Expected decompose of %s to have len %d, returned %d, appears to have %d",
  1640                       decompose_tests[i].path, expected_len, result_len,
  1642           _dbus_warn (
"Decompose resulted in elements: { ");
  1644           while (i < real_len)
  1647                           (i + 1) == real_len ? 
"" : 
", ");
  1667   _dbus_verbose (
"Looking for exact subtree, registered or unregistered\n");
  1676 object_tree_test_iteration (
void *data)
  1678   const char *path0[] = { 
NULL };
  1679   const char *path1[] = { 
"foo", 
NULL };
  1680   const char *path2[] = { 
"foo", 
"bar", 
NULL };
  1681   const char *path3[] = { 
"foo", 
"bar", 
"baz", 
NULL };
  1682   const char *path4[] = { 
"foo", 
"bar", 
"boo", 
NULL };
  1683   const char *path5[] = { 
"blah", 
NULL };
  1684   const char *path6[] = { 
"blah", 
"boof", 
NULL };
  1685   const char *path7[] = { 
"blah", 
"boof", 
"this", 
"is", 
"really", 
"long", 
NULL };
  1686   const char *path8[] = { 
"childless", 
NULL };
  1687   const char *path9[] = { 
"blah", 
"a", 
NULL };
  1688   const char *path10[] = { 
"blah", 
"b", 
NULL };
  1689   const char *path11[] = { 
"blah", 
"c", 
NULL };
  1690   const char *path12[] = { 
"blah", 
"a", 
"d", 
NULL };
  1691   const char *path13[] = { 
"blah", 
"b", 
"d", 
NULL };
  1692   const char *path14[] = { 
"blah", 
"c", 
"d", 
NULL };
  1695   TreeTestData tree_test_data[9];
  1699   if (!run_decompose_tests ())
  1708   if (!do_register (tree, path0, 
TRUE, 0, tree_test_data))
  1721   _dbus_assert (find_handler (tree, path0, &exact_match) && exact_match);
  1722   _dbus_assert (find_handler (tree, path1, &exact_match) == tree->
root && !exact_match);
  1723   _dbus_assert (find_handler (tree, path2, &exact_match) == tree->
root && !exact_match);
  1724   _dbus_assert (find_handler (tree, path3, &exact_match) == tree->
root && !exact_match);
  1725   _dbus_assert (find_handler (tree, path4, &exact_match) == tree->
root && !exact_match);
  1726   _dbus_assert (find_handler (tree, path5, &exact_match) == tree->
root && !exact_match);
  1727   _dbus_assert (find_handler (tree, path6, &exact_match) == tree->
root && !exact_match);
  1728   _dbus_assert (find_handler (tree, path7, &exact_match) == tree->
root && !exact_match);
  1729   _dbus_assert (find_handler (tree, path8, &exact_match) == tree->
root && !exact_match);
  1731   if (!do_register (tree, path1, 
TRUE, 1, tree_test_data))
  1744   _dbus_assert (find_handler (tree, path0, &exact_match) &&  exact_match);
  1745   _dbus_assert (find_handler (tree, path1, &exact_match) &&  exact_match);
  1746   _dbus_assert (find_handler (tree, path2, &exact_match) && !exact_match);
  1747   _dbus_assert (find_handler (tree, path3, &exact_match) && !exact_match);
  1748   _dbus_assert (find_handler (tree, path4, &exact_match) && !exact_match);
  1749   _dbus_assert (find_handler (tree, path5, &exact_match) == tree->
root && !exact_match);
  1750   _dbus_assert (find_handler (tree, path6, &exact_match) == tree->
root && !exact_match);
  1751   _dbus_assert (find_handler (tree, path7, &exact_match) == tree->
root && !exact_match);
  1752   _dbus_assert (find_handler (tree, path8, &exact_match) == tree->
root && !exact_match);
  1754   if (!do_register (tree, path2, 
TRUE, 2, tree_test_data))
  1766   if (!do_register (tree, path3, 
TRUE, 3, tree_test_data))
  1779   if (!do_register (tree, path4, 
TRUE, 4, tree_test_data))
  1792   if (!do_register (tree, path5, 
TRUE, 5, tree_test_data))
  1805   _dbus_assert (find_handler (tree, path0, &exact_match) == tree->
root &&  exact_match);
  1806   _dbus_assert (find_handler (tree, path1, &exact_match) != tree->
root &&  exact_match);
  1807   _dbus_assert (find_handler (tree, path2, &exact_match) != tree->
root &&  exact_match);
  1808   _dbus_assert (find_handler (tree, path3, &exact_match) != tree->
root &&  exact_match);
  1809   _dbus_assert (find_handler (tree, path4, &exact_match) != tree->
root &&  exact_match);
  1810   _dbus_assert (find_handler (tree, path5, &exact_match) != tree->
root &&  exact_match);
  1811   _dbus_assert (find_handler (tree, path6, &exact_match) != tree->
root && !exact_match);
  1812   _dbus_assert (find_handler (tree, path7, &exact_match) != tree->
root && !exact_match);
  1813   _dbus_assert (find_handler (tree, path8, &exact_match) == tree->
root && !exact_match);
  1815   if (!do_register (tree, path6, 
TRUE, 6, tree_test_data))
  1828   if (!do_register (tree, path7, 
TRUE, 7, tree_test_data))
  1841   if (!do_register (tree, path8, 
TRUE, 8, tree_test_data))
  1854   _dbus_assert (find_handler (tree, path0, &exact_match) == tree->
root &&  exact_match);
  1855   _dbus_assert (find_handler (tree, path1, &exact_match) != tree->
root && exact_match);
  1856   _dbus_assert (find_handler (tree, path2, &exact_match) != tree->
root && exact_match);
  1857   _dbus_assert (find_handler (tree, path3, &exact_match) != tree->
root && exact_match);
  1858   _dbus_assert (find_handler (tree, path4, &exact_match) != tree->
root && exact_match);
  1859   _dbus_assert (find_handler (tree, path5, &exact_match) != tree->
root && exact_match);
  1860   _dbus_assert (find_handler (tree, path6, &exact_match) != tree->
root && exact_match);
  1861   _dbus_assert (find_handler (tree, path7, &exact_match) != tree->
root && exact_match);
  1862   _dbus_assert (find_handler (tree, path8, &exact_match) != tree->
root && exact_match);
  1867     const char *root[] = { 
NULL };
  1868     char **child_entries;
  1871     _dbus_object_tree_list_registered_unlocked (tree, path1, &child_entries);
  1872     if (child_entries != 
NULL)
  1879     _dbus_object_tree_list_registered_unlocked (tree, path2, &child_entries);
  1880     if (child_entries != 
NULL)
  1887     _dbus_object_tree_list_registered_unlocked (tree, path8, &child_entries);
  1888     if (child_entries != 
NULL)
  1895     _dbus_object_tree_list_registered_unlocked (tree, root, &child_entries);
  1896     if (child_entries != 
NULL)
  1920   if (!do_register (tree, path0, 
TRUE, 0, tree_test_data))
  1922   if (!do_register (tree, path1, 
TRUE, 1, tree_test_data))
  1924   if (!do_register (tree, path2, 
TRUE, 2, tree_test_data))
  1926   if (!do_register (tree, path3, 
TRUE, 3, tree_test_data))
  1928   if (!do_register (tree, path4, 
TRUE, 4, tree_test_data))
  1930   if (!do_register (tree, path5, 
TRUE, 5, tree_test_data))
  1932   if (!do_register (tree, path6, 
TRUE, 6, tree_test_data))
  1934   if (!do_register (tree, path7, 
TRUE, 7, tree_test_data))
  1936   if (!do_register (tree, path8, 
TRUE, 8, tree_test_data))
  2065   if (!do_register (tree, path2, 
TRUE, 2, tree_test_data))
  2069   _dbus_assert (!find_subtree_registered_or_unregistered (tree, path2));
  2070   _dbus_assert (!find_subtree_registered_or_unregistered (tree, path1));
  2071   _dbus_assert (find_subtree_registered_or_unregistered (tree, path0));
  2075   if (!do_register (tree, path2, 
TRUE, 2, tree_test_data))
  2079   _dbus_assert (find_subtree_registered_or_unregistered (tree, path1));
  2080   _dbus_assert (find_subtree_registered_or_unregistered (tree, path0));
  2088   _dbus_assert (find_subtree_registered_or_unregistered (tree, path1));
  2089   _dbus_assert (find_subtree_registered_or_unregistered (tree, path0));
  2093   _dbus_assert (!find_subtree_registered_or_unregistered (tree, path2));
  2094   _dbus_assert (!find_subtree_registered_or_unregistered (tree, path1));
  2095   _dbus_assert (find_subtree_registered_or_unregistered (tree, path0));
  2100   if (!do_register (tree, path1, 
TRUE, 1, tree_test_data))
  2102   if (!do_register (tree, path2, 
TRUE, 2, tree_test_data))
  2111   _dbus_assert (find_subtree_registered_or_unregistered (tree, path1));
  2112   _dbus_assert (find_subtree_registered_or_unregistered (tree, path0));
  2116   _dbus_assert (!find_subtree_registered_or_unregistered (tree, path1));
  2118   _dbus_assert (!find_subtree_registered_or_unregistered (tree, path2));
  2119   _dbus_assert (find_subtree_registered_or_unregistered (tree, path0));
  2131   _dbus_assert (!find_subtree_registered_or_unregistered (tree, path2));
  2132   _dbus_assert (!find_subtree_registered_or_unregistered (tree, path1));
  2133   _dbus_assert (find_subtree_registered_or_unregistered (tree, path0));
  2136   if (!do_register (tree, path3, 
TRUE, 3, tree_test_data))
  2141   _dbus_assert (!find_subtree_registered_or_unregistered (tree, path3));
  2142   _dbus_assert (!find_subtree_registered_or_unregistered (tree, path2));
  2143   _dbus_assert (!find_subtree_registered_or_unregistered (tree, path1));
  2144   _dbus_assert (find_subtree_registered_or_unregistered (tree, path0));
  2147   if (!do_register (tree, path3, 
TRUE, 3, tree_test_data))
  2149   if (!do_register (tree, path4, 
TRUE, 4, tree_test_data))
  2157   _dbus_assert (!find_subtree_registered_or_unregistered (tree, path3));
  2159   _dbus_assert (find_subtree_registered_or_unregistered (tree, path4));
  2160   _dbus_assert (find_subtree_registered_or_unregistered (tree, path2));
  2161   _dbus_assert (find_subtree_registered_or_unregistered (tree, path1));
  2165   _dbus_assert (!find_subtree_registered_or_unregistered (tree, path4));
  2167   _dbus_assert (!find_subtree_registered_or_unregistered (tree, path3));
  2168   _dbus_assert (!find_subtree_registered_or_unregistered (tree, path2));
  2169   _dbus_assert (!find_subtree_registered_or_unregistered (tree, path1));
  2198   _dbus_assert (!find_subtree_registered_or_unregistered (tree, path12));
  2201   _dbus_assert (!find_subtree_registered_or_unregistered (tree, path9));
  2202   _dbus_assert (find_subtree_registered_or_unregistered (tree, path5));
  2215   _dbus_assert (!find_subtree_registered_or_unregistered (tree, path13));
  2217   _dbus_assert (!find_subtree_registered_or_unregistered (tree, path10));
  2218   _dbus_assert (find_subtree_registered_or_unregistered (tree, path5));
  2232   _dbus_assert (!find_subtree_registered_or_unregistered (tree, path14));
  2233   _dbus_assert (!find_subtree_registered_or_unregistered (tree, path11));
  2234   _dbus_assert (find_subtree_registered_or_unregistered (tree, path5));
  2238   _dbus_assert (!find_subtree_registered_or_unregistered (tree, path12));
  2239   _dbus_assert (!find_subtree_registered_or_unregistered (tree, path9));
  2240   _dbus_assert (find_subtree_registered_or_unregistered (tree, path5));
  2244   _dbus_assert (!find_subtree_registered_or_unregistered (tree, path13));
  2245   _dbus_assert (!find_subtree_registered_or_unregistered (tree, path10));
  2246   _dbus_assert (!find_subtree_registered_or_unregistered (tree, path5));
  2260   if (!do_register (tree, path0, 
TRUE, 0, tree_test_data))
  2262   if (!do_register (tree, path1, 
FALSE, 1, tree_test_data))
  2264   if (!do_register (tree, path2, 
TRUE, 2, tree_test_data))
  2266   if (!do_register (tree, path3, 
TRUE, 3, tree_test_data))
  2268   if (!do_register (tree, path4, 
TRUE, 4, tree_test_data))
  2270   if (!do_register (tree, path5, 
TRUE, 5, tree_test_data))
  2272   if (!do_register (tree, path6, 
FALSE, 6, tree_test_data))
  2274   if (!do_register (tree, path7, 
TRUE, 7, tree_test_data))
  2276   if (!do_register (tree, path8, 
TRUE, 8, tree_test_data))
  2283   if (!do_test_dispatch (tree, path0, 0, tree_test_data, 
_DBUS_N_ELEMENTS (tree_test_data)))
  2285   if (!do_test_dispatch (tree, path1, 1, tree_test_data, 
_DBUS_N_ELEMENTS (tree_test_data)))
  2287   if (!do_test_dispatch (tree, path2, 2, tree_test_data, 
_DBUS_N_ELEMENTS (tree_test_data)))
  2289   if (!do_test_dispatch (tree, path3, 3, tree_test_data, 
_DBUS_N_ELEMENTS (tree_test_data)))
  2291   if (!do_test_dispatch (tree, path4, 4, tree_test_data, 
_DBUS_N_ELEMENTS (tree_test_data)))
  2293   if (!do_test_dispatch (tree, path5, 5, tree_test_data, 
_DBUS_N_ELEMENTS (tree_test_data)))
  2295   if (!do_test_dispatch (tree, path6, 6, tree_test_data, 
_DBUS_N_ELEMENTS (tree_test_data)))
  2297   if (!do_test_dispatch (tree, path7, 7, tree_test_data, 
_DBUS_N_ELEMENTS (tree_test_data)))
  2299   if (!do_test_dispatch (tree, path8, 8, tree_test_data, 
_DBUS_N_ELEMENTS (tree_test_data)))
  2320 _dbus_object_tree_test (
void)
  2322   return _dbus_test_oom_handling (
"object tree",
  2323                                   object_tree_test_iteration,
 dbus_bool_t _dbus_string_append(DBusString *str, const char *buffer)
Appends a nul-terminated C-style string to a DBusString. 
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...
An atomic integer safe to increment or decrement from multiple threads. 
int max_subtrees
Number of allocated entries in subtrees. 
#define NULL
A null pointer, defined appropriately for C or C++. 
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. 
#define DBUS_INTERFACE_INTROSPECTABLE
The interface supported by introspectable objects. 
void _dbus_object_tree_free_all_unlocked(DBusObjectTree *tree)
Free all the handlers in the tree. 
void * dbus_realloc(void *memory, size_t bytes)
Resizes a block of memory previously allocated by dbus_malloc() or dbus_malloc0(). 
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0(). 
DBusConnection * connection
Connection this tree belongs to. 
DBUS_PRIVATE_EXPORT void _dbus_connection_lock(DBusConnection *connection)
Acquires the connection lock. 
void _dbus_list_remove_link(DBusList **list, DBusList *link)
Removes a link from the list. 
#define DBUS_TYPE_STRING
Type code marking a UTF-8 encoded, nul-terminated Unicode string. 
DBusObjectPathMessageFunction message_function
Function to handle messages. 
#define _dbus_assert(condition)
Aborts with an error message if the condition is false. 
void * data
Data stored at this element. 
DBusObjectPathUnregisterFunction unregister_function
Function to call on unregister. 
#define DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
XML document type declaration of the introspection format version 1.0. 
unsigned int invoke_as_fallback
Whether to invoke message_function when child nodes don't handle the message. 
Message has not had any effect - see if other handlers want it. 
void dbus_message_iter_init_append(DBusMessage *message, DBusMessageIter *iter)
Initializes a DBusMessageIter for appending arguments to the end of a message. 
Struct representing a single registered subtree handler, or node that's a parent of a registered subt...
void _dbus_object_tree_unregister_and_unlock(DBusObjectTree *tree, const char **path)
Unregisters an object subtree that was registered with the same path. 
char name[1]
Allocated as large as necessary. 
Implementation details of DBusConnection. 
DBusObjectSubtree * root
Root of the tree ("/" node) 
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string. 
DBusHandlerResult
Results that a message handler can return. 
DBusMessageIter struct; contains no public fields. 
#define _dbus_list_get_next_link(list, link)
Gets the next link in the list, or NULL if there are no more links. 
Virtual table that must be implemented to handle a portion of the object path hierarchy. 
Internals of DBusMessage. 
void(* DBusObjectPathUnregisterFunction)(DBusConnection *connection, void *user_data)
Called when a DBusObjectPathVTable is unregistered (or its connection is freed). 
int n_subtrees
Number of child nodes. 
DBusObjectPathUnregisterFunction unregister_function
Function to unregister this handler. 
#define DBUS_ERROR_OBJECT_PATH_IN_USE
There's already an object with the requested object path. 
#define dbus_new0(type, count)
Safe macro for using dbus_malloc0(). 
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE. 
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_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...
Internals of DBusObjectTree. 
void _dbus_warn(const char *format,...)
Prints a warning message to stderr. 
dbus_int32_t _dbus_atomic_inc(DBusAtomic *atomic)
Atomically increments an integer. 
DBusObjectTree * _dbus_object_tree_ref(DBusObjectTree *tree)
Increment the reference count. 
dbus_bool_t _dbus_list_append(DBusList **list, void *data)
Appends a value to the list. 
dbus_bool_t _dbus_decompose_path(const char *data, int len, char ***path, int *path_len)
Decompose an object path. 
void * _dbus_memdup(const void *mem, size_t n_bytes)
Duplicates a block of memory. 
dbus_bool_t _dbus_string_append_printf(DBusString *str, const char *format,...)
Appends a printf-style formatted string to the DBusString. 
DBusObjectSubtree ** subtrees
Child nodes. 
Object representing an exception. 
size_t _dbus_string_array_length(const char **array)
Returns the size of a string array. 
void dbus_set_error(DBusError *error, const char *name, const char *format,...)
Assigns an error name and message to a DBusError. 
DBusObjectPathMessageFunction message_function
Function to handle messages. 
void * user_data
Data for functions. 
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...
#define _DBUS_N_ELEMENTS(array)
Computes the number of elements in a fixed-size array using sizeof(). 
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. 
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. 
DBusObjectSubtree * parent
Parent node. 
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init(). 
#define TRUE
Expands to "1". 
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called. 
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...
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. 
DBusHandlerResult(* DBusObjectPathMessageFunction)(DBusConnection *connection, DBusMessage *message, void *user_data)
Called when a message is sent to a registered object path. 
int refcount
Reference count. 
DBusObjectTree * _dbus_object_tree_new(DBusConnection *connection)
Creates a new object tree, representing a mapping from paths to handler vtables. 
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer. 
void dbus_free_string_array(char **str_array)
Frees a NULL-terminated array of strings. 
DBusAtomic refcount
Reference count. 
int _dbus_list_get_length(DBusList **list)
Gets the length of a list. 
dbus_bool_t dbus_message_iter_append_basic(DBusMessageIter *iter, int type, const void *value)
Appends a basic-typed value to the message. 
DBusList * _dbus_list_get_first_link(DBusList **list)
Gets the first link in the list. 
#define FALSE
Expands to "0". 
void * dbus_malloc0(size_t bytes)
Allocates the given number of bytes, as with standard malloc(), but all bytes are initialized to zero...
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_connection_unref(DBusConnection *connection)
Decrements the reference count of a DBusConnection, and finalizes it if the count reaches zero...
void _dbus_object_tree_unref(DBusObjectTree *tree)
Decrement the reference count. 
DBUS_PRIVATE_EXPORT DBusConnection * _dbus_connection_ref_unlocked(DBusConnection *connection)
Increments the reference count of a DBusConnection. 
Message has had its effect - no need to run more handlers. 
int dbus_int32_t
A 32-bit signed integer on all platforms. 
char * _dbus_strdup(const char *str)
Duplicates a string. 
DBUS_PRIVATE_EXPORT void _dbus_connection_unlock(DBusConnection *connection)
Releases the connection lock. 
void dbus_message_unref(DBusMessage *message)
Decrements the reference count of a DBusMessage, freeing the message if the count reaches 0...
Need more memory in order to return DBUS_HANDLER_RESULT_HANDLED or DBUS_HANDLER_RESULT_NOT_YET_HANDLE...
DBusMessage * dbus_message_new_method_return(DBusMessage *method_call)
Constructs a message that is a reply to a method call.