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 
  169                      int                *index_in_parent,
 
  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");
 
  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);
 
  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
 
  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);
 
  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;
 
  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");
 
  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);
 
 
 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 
 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);
 
 1482  TreeTestData *ttd = user_data;
 
 1484  ttd->handler_unregistered = 
TRUE;
 
 1492  TreeTestData *ttd = user_data;
 
 1494  ttd->message_handled = 
TRUE;
 
 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,
 
 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];
 
 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.
int dbus_int32_t
A 32-bit signed integer on all platforms.
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
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)