<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"> <title>dbus-object-tree.c Source File</title> <link href="doxygen.css" rel="stylesheet" type="text/css"> </head><body> <!-- Generated by Doxygen 1.2.15 --> <center> <a class="qindex" href="index.html">Main Page</a> <a class="qindex" href="modules.html">Modules</a> <a class="qindex" href="annotated.html">Data Structures</a> <a class="qindex" href="files.html">File List</a> <a class="qindex" href="functions.html">Data Fields</a> <a class="qindex" href="pages.html">Related Pages</a> </center> <hr><h1>dbus-object-tree.c</h1><div class="fragment"><pre>00001 <font class="comment">/* -*- mode: C; c-file-style: "gnu" -*- */</font> 00002 <font class="comment">/* dbus-object-tree.c DBusObjectTree (internals of DBusConnection)</font> 00003 <font class="comment"> *</font> 00004 <font class="comment"> * Copyright (C) 2003 Red Hat Inc.</font> 00005 <font class="comment"> *</font> 00006 <font class="comment"> * Licensed under the Academic Free License version 2.0</font> 00007 <font class="comment"> *</font> 00008 <font class="comment"> * This program is free software; you can redistribute it and/or modify</font> 00009 <font class="comment"> * it under the terms of the GNU General Public License as published by</font> 00010 <font class="comment"> * the Free Software Foundation; either version 2 of the License, or</font> 00011 <font class="comment"> * (at your option) any later version.</font> 00012 <font class="comment"> *</font> 00013 <font class="comment"> * This program is distributed in the hope that it will be useful,</font> 00014 <font class="comment"> * but WITHOUT ANY WARRANTY; without even the implied warranty of</font> 00015 <font class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</font> 00016 <font class="comment"> * GNU General Public License for more details.</font> 00017 <font class="comment"> *</font> 00018 <font class="comment"> * You should have received a copy of the GNU General Public License</font> 00019 <font class="comment"> * along with this program; if not, write to the Free Software</font> 00020 <font class="comment"> * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA</font> 00021 <font class="comment"> *</font> 00022 <font class="comment"> */</font> 00023 <font class="preprocessor">#include "dbus-object-tree.h"</font> 00024 <font class="preprocessor">#include "dbus-connection-internal.h"</font> 00025 <font class="preprocessor">#include "dbus-internals.h"</font> 00026 <font class="preprocessor">#include "dbus-hash.h"</font> 00027 <font class="preprocessor">#include "dbus-protocol.h"</font> 00028 <font class="preprocessor">#include "dbus-string.h"</font> 00029 <font class="preprocessor">#include <string.h></font> 00030 <font class="preprocessor">#include <stdlib.h></font> 00031 <a name="l00044"></a><a class="code" href="group__DBusObjectTree.html#a0">00044</a> <font class="keyword">typedef</font> <font class="keyword">struct </font><a class="code" href="structDBusObjectSubtree.html">DBusObjectSubtree</a> DBusObjectSubtree; 00045 00046 <font class="keyword">static</font> DBusObjectSubtree* _dbus_object_subtree_new (<font class="keyword">const</font> <font class="keywordtype">char</font> *name, 00047 <font class="keyword">const</font> <a class="code" href="structDBusObjectPathVTable.html">DBusObjectPathVTable</a> *vtable, 00048 <font class="keywordtype">void</font> *user_data); 00049 <font class="keyword">static</font> DBusObjectSubtree* _dbus_object_subtree_ref (DBusObjectSubtree *subtree); 00050 <font class="keyword">static</font> <font class="keywordtype">void</font> _dbus_object_subtree_unref (DBusObjectSubtree *subtree); 00051 <a name="l00055"></a><a class="code" href="structDBusObjectTree.html">00055</a> <font class="keyword">struct </font><a class="code" href="structDBusObjectTree.html">DBusObjectTree</a> 00056 { <a name="l00057"></a><a class="code" href="structDBusObjectTree.html#m0">00057</a> <font class="keywordtype">int</font> <a class="code" href="structDBusObjectTree.html#m0">refcount</a>; <a name="l00058"></a><a class="code" href="structDBusObjectTree.html#m1">00058</a> <a class="code" href="structDBusConnection.html">DBusConnection</a> *<a class="code" href="structDBusObjectTree.html#m1">connection</a>; <a name="l00060"></a><a class="code" href="structDBusObjectTree.html#m2">00060</a> DBusObjectSubtree *<a class="code" href="structDBusObjectTree.html#m2">root</a>; 00061 }; 00062 <a name="l00068"></a><a class="code" href="structDBusObjectSubtree.html">00068</a> <font class="keyword">struct </font>DBusObjectSubtree 00069 { <a name="l00070"></a><a class="code" href="structDBusObjectSubtree.html#m0">00070</a> <a class="code" href="structDBusAtomic.html">DBusAtomic</a> <a class="code" href="structDBusObjectSubtree.html#m0">refcount</a>; <a name="l00071"></a><a class="code" href="structDBusObjectSubtree.html#m1">00071</a> DBusObjectSubtree *<a class="code" href="structDBusObjectSubtree.html#m1">parent</a>; <a name="l00072"></a><a class="code" href="structDBusObjectSubtree.html#m2">00072</a> DBusObjectPathUnregisterFunction <a class="code" href="structDBusObjectSubtree.html#m2">unregister_function</a>; <a name="l00073"></a><a class="code" href="structDBusObjectSubtree.html#m3">00073</a> DBusObjectPathMessageFunction <a class="code" href="structDBusObjectSubtree.html#m3">message_function</a>; <a name="l00074"></a><a class="code" href="structDBusObjectSubtree.html#m4">00074</a> <font class="keywordtype">void</font> *<a class="code" href="structDBusObjectSubtree.html#m4">user_data</a>; <a name="l00075"></a><a class="code" href="structDBusObjectSubtree.html#m5">00075</a> DBusObjectSubtree **<a class="code" href="structDBusObjectSubtree.html#m5">subtrees</a>; <a name="l00076"></a><a class="code" href="structDBusObjectSubtree.html#m6">00076</a> <font class="keywordtype">int</font> <a class="code" href="structDBusObjectSubtree.html#m6">n_subtrees</a>; <a name="l00077"></a><a class="code" href="structDBusObjectSubtree.html#m7">00077</a> <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> <a class="code" href="structDBusObjectSubtree.html#m7">subtrees_sorted</a> : 1; <a name="l00078"></a><a class="code" href="structDBusObjectSubtree.html#m8">00078</a> <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> <a class="code" href="structDBusObjectSubtree.html#m8">invoke_as_fallback</a> : 1; <a name="l00079"></a><a class="code" href="structDBusObjectSubtree.html#m9">00079</a> <font class="keywordtype">char</font> <a class="code" href="structDBusObjectSubtree.html#m9">name</a>[1]; 00080 }; 00081 00089 <a class="code" href="structDBusObjectTree.html">DBusObjectTree</a>* <a name="l00090"></a><a class="code" href="group__DBusObjectTree.html#a4">00090</a> _dbus_object_tree_new (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection) 00091 { 00092 <a class="code" href="structDBusObjectTree.html">DBusObjectTree</a> *tree; 00093 00094 <font class="comment">/* the connection passed in here isn't fully constructed,</font> 00095 <font class="comment"> * so don't do anything more than store a pointer to</font> 00096 <font class="comment"> * it</font> 00097 <font class="comment"> */</font> 00098 00099 tree = dbus_new0 (<a class="code" href="structDBusObjectTree.html">DBusObjectTree</a>, 1); 00100 <font class="keywordflow">if</font> (tree == NULL) 00101 <font class="keywordflow">goto</font> oom; 00102 00103 tree-><a class="code" href="structDBusObjectTree.html#m0">refcount</a> = 1; 00104 tree-><a class="code" href="structDBusObjectTree.html#m1">connection</a> = connection; 00105 tree-><a class="code" href="structDBusObjectTree.html#m2">root</a> = _dbus_object_subtree_new (<font class="stringliteral">"/"</font>, NULL, NULL); 00106 <font class="keywordflow">if</font> (tree-><a class="code" href="structDBusObjectTree.html#m2">root</a> == NULL) 00107 <font class="keywordflow">goto</font> oom; 00108 tree-><a class="code" href="structDBusObjectTree.html#m2">root</a>-><a class="code" href="structDBusObjectSubtree.html#m8">invoke_as_fallback</a> = TRUE; 00109 00110 <font class="keywordflow">return</font> tree; 00111 00112 oom: 00113 <font class="keywordflow">if</font> (tree) 00114 { 00115 dbus_free (tree); 00116 } 00117 00118 <font class="keywordflow">return</font> NULL; 00119 } 00120 00126 <a class="code" href="structDBusObjectTree.html">DBusObjectTree</a> * <a name="l00127"></a><a class="code" href="group__DBusObjectTree.html#a5">00127</a> _dbus_object_tree_ref (<a class="code" href="structDBusObjectTree.html">DBusObjectTree</a> *tree) 00128 { 00129 _dbus_assert (tree-><a class="code" href="structDBusObjectTree.html#m0">refcount</a> > 0); 00130 00131 tree-><a class="code" href="structDBusObjectTree.html#m0">refcount</a> += 1; 00132 00133 <font class="keywordflow">return</font> tree; 00134 } 00135 00140 <font class="keywordtype">void</font> <a name="l00141"></a><a class="code" href="group__DBusObjectTree.html#a6">00141</a> _dbus_object_tree_unref (<a class="code" href="structDBusObjectTree.html">DBusObjectTree</a> *tree) 00142 { 00143 _dbus_assert (tree-><a class="code" href="structDBusObjectTree.html#m0">refcount</a> > 0); 00144 00145 tree-><a class="code" href="structDBusObjectTree.html#m0">refcount</a> -= 1; 00146 00147 <font class="keywordflow">if</font> (tree-><a class="code" href="structDBusObjectTree.html#m0">refcount</a> == 0) 00148 { 00149 _dbus_object_tree_free_all_unlocked (tree); 00150 00151 dbus_free (tree); 00152 } 00153 } 00154 00155 <font class="keyword">static</font> <font class="keywordtype">int</font> 00156 subtree_cmp (DBusObjectSubtree *subtree_a, 00157 DBusObjectSubtree *subtree_b) 00158 { 00159 <font class="keywordflow">return</font> strcmp (subtree_a-><a class="code" href="structDBusObjectSubtree.html#m9">name</a>, subtree_b-><a class="code" href="structDBusObjectSubtree.html#m9">name</a>); 00160 } 00161 00162 <font class="keyword">static</font> <font class="keywordtype">int</font> 00163 subtree_qsort_cmp (<font class="keyword">const</font> <font class="keywordtype">void</font> *a, 00164 <font class="keyword">const</font> <font class="keywordtype">void</font> *b) 00165 { 00166 DBusObjectSubtree **subtree_a_p = (<font class="keywordtype">void</font>*) a; 00167 DBusObjectSubtree **subtree_b_p = (<font class="keywordtype">void</font>*) b; 00168 00169 <font class="keywordflow">return</font> subtree_cmp (*subtree_a_p, *subtree_b_p); 00170 } 00171 00172 <font class="keyword">static</font> <font class="keywordtype">void</font> 00173 ensure_sorted (DBusObjectSubtree *subtree) 00174 { 00175 <font class="keywordflow">if</font> (subtree-><a class="code" href="structDBusObjectSubtree.html#m5">subtrees</a> && !subtree-><a class="code" href="structDBusObjectSubtree.html#m7">subtrees_sorted</a>) 00176 { 00177 qsort (subtree-><a class="code" href="structDBusObjectSubtree.html#m5">subtrees</a>, 00178 subtree-><a class="code" href="structDBusObjectSubtree.html#m6">n_subtrees</a>, 00179 sizeof (DBusObjectSubtree*), 00180 subtree_qsort_cmp); 00181 subtree-><a class="code" href="structDBusObjectSubtree.html#m7">subtrees_sorted</a> = TRUE; 00182 } 00183 } 00184 <a name="l00188"></a><a class="code" href="group__DBusObjectTree.html#a25">00188</a> <font class="preprocessor">#define VERBOSE_FIND 0</font> 00189 <font class="preprocessor"></font> 00190 <font class="keyword">static</font> DBusObjectSubtree* 00191 find_subtree_recurse (DBusObjectSubtree *subtree, 00192 <font class="keyword">const</font> <font class="keywordtype">char</font> **path, 00193 dbus_bool_t create_if_not_found, 00194 <font class="keywordtype">int</font> *index_in_parent, 00195 dbus_bool_t *exact_match) 00196 { 00197 <font class="keywordtype">int</font> i; 00198 dbus_bool_t return_deepest_match; 00199 00200 return_deepest_match = exact_match != NULL; 00201 00202 _dbus_assert (!(return_deepest_match && create_if_not_found)); 00203 00204 <font class="keywordflow">if</font> (path[0] == NULL) 00205 { 00206 <font class="preprocessor">#if VERBOSE_FIND</font> 00207 <font class="preprocessor"></font> _dbus_verbose (<font class="stringliteral">" path exhausted, returning %s\n"</font>, 00208 subtree-><a class="code" href="structDBusObjectSubtree.html#m9">name</a>); 00209 <font class="preprocessor">#endif</font> 00210 <font class="preprocessor"></font> <font class="keywordflow">if</font> (exact_match != NULL) 00211 *exact_match = TRUE; 00212 <font class="keywordflow">return</font> subtree; 00213 } 00214 00215 <font class="preprocessor">#if VERBOSE_FIND</font> 00216 <font class="preprocessor"></font> _dbus_verbose (<font class="stringliteral">" searching children of %s for %s\n"</font>, 00217 subtree-><a class="code" href="structDBusObjectSubtree.html#m9">name</a>, path[0]); 00218 <font class="preprocessor">#endif</font> 00219 <font class="preprocessor"></font> 00220 ensure_sorted (subtree); 00221 00222 <font class="comment">/* FIXME we should do a binary search here instead</font> 00223 <font class="comment"> * of O(n)</font> 00224 <font class="comment"> */</font> 00225 00226 i = 0; 00227 <font class="keywordflow">while</font> (i < subtree-><a class="code" href="structDBusObjectSubtree.html#m6">n_subtrees</a>) 00228 { 00229 <font class="keywordtype">int</font> v; 00230 00231 v = strcmp (path[0], subtree-><a class="code" href="structDBusObjectSubtree.html#m5">subtrees</a>[i]-><a class="code" href="structDBusObjectSubtree.html#m9">name</a>); 00232 00233 <font class="preprocessor">#if VERBOSE_FIND</font> 00234 <font class="preprocessor"></font> _dbus_verbose (<font class="stringliteral">" %s cmp %s = %d\n"</font>, 00235 path[0], subtree-><a class="code" href="structDBusObjectSubtree.html#m5">subtrees</a>[i]-><a class="code" href="structDBusObjectSubtree.html#m9">name</a>, 00236 v); 00237 <font class="preprocessor">#endif</font> 00238 <font class="preprocessor"></font> 00239 <font class="keywordflow">if</font> (v == 0) 00240 { 00241 <font class="keywordflow">if</font> (index_in_parent) 00242 { 00243 <font class="preprocessor">#if VERBOSE_FIND</font> 00244 <font class="preprocessor"></font> _dbus_verbose (<font class="stringliteral">" storing parent index %d\n"</font>, i); 00245 <font class="preprocessor">#endif</font> 00246 <font class="preprocessor"></font> *index_in_parent = i; 00247 } 00248 00249 <font class="keywordflow">if</font> (return_deepest_match) 00250 { 00251 DBusObjectSubtree *next; 00252 00253 next = find_subtree_recurse (subtree-><a class="code" href="structDBusObjectSubtree.html#m5">subtrees</a>[i], 00254 &path[1], create_if_not_found, 00255 index_in_parent, exact_match); 00256 <font class="keywordflow">if</font> (next == NULL && 00257 subtree-><a class="code" href="structDBusObjectSubtree.html#m8">invoke_as_fallback</a>) 00258 { 00259 <font class="preprocessor">#if VERBOSE_FIND</font> 00260 <font class="preprocessor"></font> _dbus_verbose (<font class="stringliteral">" no deeper match found, returning %s\n"</font>, 00261 subtree-><a class="code" href="structDBusObjectSubtree.html#m9">name</a>); 00262 <font class="preprocessor">#endif</font> 00263 <font class="preprocessor"></font> <font class="keywordflow">if</font> (exact_match != NULL) 00264 *exact_match = FALSE; 00265 <font class="keywordflow">return</font> subtree; 00266 } 00267 <font class="keywordflow">else</font> 00268 <font class="keywordflow">return</font> next; 00269 } 00270 <font class="keywordflow">else</font> 00271 <font class="keywordflow">return</font> find_subtree_recurse (subtree-><a class="code" href="structDBusObjectSubtree.html#m5">subtrees</a>[i], 00272 &path[1], create_if_not_found, 00273 index_in_parent, exact_match); 00274 } 00275 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (v < 0) 00276 { 00277 <font class="keywordflow">goto</font> not_found; 00278 } 00279 00280 ++i; 00281 } 00282 00283 not_found: 00284 <font class="preprocessor">#if VERBOSE_FIND</font> 00285 <font class="preprocessor"></font> _dbus_verbose (<font class="stringliteral">" no match found, current tree %s, create_if_not_found = %d\n"</font>, 00286 subtree-><a class="code" href="structDBusObjectSubtree.html#m9">name</a>, create_if_not_found); 00287 <font class="preprocessor">#endif</font> 00288 <font class="preprocessor"></font> 00289 <font class="keywordflow">if</font> (create_if_not_found) 00290 { 00291 DBusObjectSubtree* child; 00292 DBusObjectSubtree **new_subtrees; 00293 <font class="keywordtype">int</font> new_n_subtrees; 00294 00295 <font class="preprocessor">#if VERBOSE_FIND</font> 00296 <font class="preprocessor"></font> _dbus_verbose (<font class="stringliteral">" creating subtree %s\n"</font>, 00297 path[0]); 00298 <font class="preprocessor">#endif</font> 00299 <font class="preprocessor"></font> 00300 child = _dbus_object_subtree_new (path[0], 00301 NULL, NULL); 00302 <font class="keywordflow">if</font> (child == NULL) 00303 <font class="keywordflow">return</font> NULL; 00304 00305 <font class="comment">/* FIXME we should do the "double alloc each time" standard thing */</font> 00306 new_n_subtrees = subtree-><a class="code" href="structDBusObjectSubtree.html#m6">n_subtrees</a> + 1; 00307 new_subtrees = dbus_realloc (subtree-><a class="code" href="structDBusObjectSubtree.html#m5">subtrees</a>, 00308 new_n_subtrees * sizeof (DBusObjectSubtree*)); 00309 <font class="keywordflow">if</font> (new_subtrees == NULL) 00310 { 00311 child-><a class="code" href="structDBusObjectSubtree.html#m2">unregister_function</a> = NULL; 00312 child-><a class="code" href="structDBusObjectSubtree.html#m3">message_function</a> = NULL; 00313 _dbus_object_subtree_unref (child); 00314 <font class="keywordflow">return</font> NULL; 00315 } 00316 00317 new_subtrees[subtree-><a class="code" href="structDBusObjectSubtree.html#m6">n_subtrees</a>] = child; 00318 <font class="keywordflow">if</font> (index_in_parent) 00319 *index_in_parent = subtree-><a class="code" href="structDBusObjectSubtree.html#m6">n_subtrees</a>; 00320 subtree-><a class="code" href="structDBusObjectSubtree.html#m7">subtrees_sorted</a> = FALSE; 00321 subtree-><a class="code" href="structDBusObjectSubtree.html#m6">n_subtrees</a> = new_n_subtrees; 00322 subtree-><a class="code" href="structDBusObjectSubtree.html#m5">subtrees</a> = new_subtrees; 00323 00324 child-><a class="code" href="structDBusObjectSubtree.html#m1">parent</a> = subtree; 00325 00326 <font class="keywordflow">return</font> find_subtree_recurse (child, 00327 &path[1], create_if_not_found, 00328 index_in_parent, exact_match); 00329 } 00330 <font class="keywordflow">else</font> 00331 { 00332 <font class="keywordflow">if</font> (exact_match != NULL) 00333 *exact_match = FALSE; 00334 <font class="keywordflow">return</font> (return_deepest_match && subtree-><a class="code" href="structDBusObjectSubtree.html#m8">invoke_as_fallback</a>) ? subtree : NULL; 00335 } 00336 } 00337 00338 <font class="keyword">static</font> DBusObjectSubtree* 00339 find_subtree (<a class="code" href="structDBusObjectTree.html">DBusObjectTree</a> *tree, 00340 <font class="keyword">const</font> <font class="keywordtype">char</font> **path, 00341 <font class="keywordtype">int</font> *index_in_parent) 00342 { 00343 DBusObjectSubtree *subtree; 00344 00345 <font class="preprocessor">#if VERBOSE_FIND</font> 00346 <font class="preprocessor"></font> _dbus_verbose (<font class="stringliteral">"Looking for exact registered subtree\n"</font>); 00347 <font class="preprocessor">#endif</font> 00348 <font class="preprocessor"></font> 00349 subtree = find_subtree_recurse (tree-><a class="code" href="structDBusObjectTree.html#m2">root</a>, path, FALSE, index_in_parent, NULL); 00350 00351 <font class="keywordflow">if</font> (subtree && subtree-><a class="code" href="structDBusObjectSubtree.html#m3">message_function</a> == NULL) 00352 <font class="keywordflow">return</font> NULL; 00353 <font class="keywordflow">else</font> 00354 <font class="keywordflow">return</font> subtree; 00355 } 00356 00357 <font class="keyword">static</font> DBusObjectSubtree* 00358 lookup_subtree (<a class="code" href="structDBusObjectTree.html">DBusObjectTree</a> *tree, 00359 <font class="keyword">const</font> <font class="keywordtype">char</font> **path) 00360 { 00361 <font class="preprocessor">#if VERBOSE_FIND</font> 00362 <font class="preprocessor"></font> _dbus_verbose (<font class="stringliteral">"Looking for subtree\n"</font>); 00363 <font class="preprocessor">#endif</font> 00364 <font class="preprocessor"></font> <font class="keywordflow">return</font> find_subtree_recurse (tree-><a class="code" href="structDBusObjectTree.html#m2">root</a>, path, FALSE, NULL, NULL); 00365 } 00366 00367 <font class="keyword">static</font> DBusObjectSubtree* 00368 find_handler (<a class="code" href="structDBusObjectTree.html">DBusObjectTree</a> *tree, 00369 <font class="keyword">const</font> <font class="keywordtype">char</font> **path, 00370 dbus_bool_t *exact_match) 00371 { 00372 <font class="preprocessor">#if VERBOSE_FIND</font> 00373 <font class="preprocessor"></font> _dbus_verbose (<font class="stringliteral">"Looking for deepest handler\n"</font>); 00374 <font class="preprocessor">#endif</font> 00375 <font class="preprocessor"></font> _dbus_assert (exact_match != NULL); 00376 <font class="keywordflow">return</font> find_subtree_recurse (tree-><a class="code" href="structDBusObjectTree.html#m2">root</a>, path, FALSE, NULL, exact_match); 00377 } 00378 00379 <font class="keyword">static</font> DBusObjectSubtree* 00380 ensure_subtree (<a class="code" href="structDBusObjectTree.html">DBusObjectTree</a> *tree, 00381 <font class="keyword">const</font> <font class="keywordtype">char</font> **path) 00382 { 00383 <font class="preprocessor">#if VERBOSE_FIND</font> 00384 <font class="preprocessor"></font> _dbus_verbose (<font class="stringliteral">"Ensuring subtree\n"</font>); 00385 <font class="preprocessor">#endif</font> 00386 <font class="preprocessor"></font> <font class="keywordflow">return</font> find_subtree_recurse (tree-><a class="code" href="structDBusObjectTree.html#m2">root</a>, path, TRUE, NULL, NULL); 00387 } 00388 00399 dbus_bool_t <a name="l00400"></a><a class="code" href="group__DBusObjectTree.html#a15">00400</a> _dbus_object_tree_register (<a class="code" href="structDBusObjectTree.html">DBusObjectTree</a> *tree, 00401 dbus_bool_t fallback, 00402 <font class="keyword">const</font> <font class="keywordtype">char</font> **path, 00403 <font class="keyword">const</font> <a class="code" href="structDBusObjectPathVTable.html">DBusObjectPathVTable</a> *vtable, 00404 <font class="keywordtype">void</font> *user_data) 00405 { 00406 DBusObjectSubtree *subtree; 00407 00408 _dbus_assert (tree != NULL); 00409 _dbus_assert (vtable-><a class="code" href="structDBusObjectPathVTable.html#m1">message_function</a> != NULL); 00410 _dbus_assert (path != NULL); 00411 00412 subtree = ensure_subtree (tree, path); 00413 <font class="keywordflow">if</font> (subtree == NULL) 00414 <font class="keywordflow">return</font> FALSE; 00415 00416 <font class="preprocessor">#ifndef DBUS_DISABLE_CHECKS</font> 00417 <font class="preprocessor"></font> <font class="keywordflow">if</font> (subtree-><a class="code" href="structDBusObjectSubtree.html#m3">message_function</a> != NULL) 00418 { 00419 _dbus_warn (<font class="stringliteral">"A handler is already registered for the path starting with path[0] = \"%s\"\n"</font>, 00420 path[0] ? path[0] : <font class="stringliteral">"null"</font>); 00421 <font class="keywordflow">return</font> FALSE; 00422 } 00423 <font class="preprocessor">#else</font> 00424 <font class="preprocessor"></font> _dbus_assert (subtree-><a class="code" href="structDBusObjectSubtree.html#m3">message_function</a> == NULL); 00425 <font class="preprocessor">#endif</font> 00426 <font class="preprocessor"></font> 00427 subtree-><a class="code" href="structDBusObjectSubtree.html#m3">message_function</a> = vtable-><a class="code" href="structDBusObjectPathVTable.html#m1">message_function</a>; 00428 subtree-><a class="code" href="structDBusObjectSubtree.html#m2">unregister_function</a> = vtable-><a class="code" href="structDBusObjectPathVTable.html#m0">unregister_function</a>; 00429 subtree-><a class="code" href="structDBusObjectSubtree.html#m4">user_data</a> = user_data; 00430 subtree-><a class="code" href="structDBusObjectSubtree.html#m8">invoke_as_fallback</a> = fallback != FALSE; 00431 00432 <font class="keywordflow">return</font> TRUE; 00433 } 00434 00442 <font class="keywordtype">void</font> <a name="l00443"></a><a class="code" href="group__DBusObjectTree.html#a16">00443</a> _dbus_object_tree_unregister_and_unlock (<a class="code" href="structDBusObjectTree.html">DBusObjectTree</a> *tree, 00444 <font class="keyword">const</font> <font class="keywordtype">char</font> **path) 00445 { 00446 <font class="keywordtype">int</font> i; 00447 DBusObjectSubtree *subtree; 00448 DBusObjectPathUnregisterFunction unregister_function; 00449 <font class="keywordtype">void</font> *user_data; 00450 <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection; 00451 00452 _dbus_assert (path != NULL); 00453 00454 subtree = find_subtree (tree, path, &i); 00455 00456 <font class="preprocessor">#ifndef DBUS_DISABLE_CHECKS</font> 00457 <font class="preprocessor"></font> <font class="keywordflow">if</font> (subtree == NULL) 00458 { 00459 _dbus_warn (<font class="stringliteral">"Attempted to unregister path (path[0] = %s path[1] = %s) which isn't registered\n"</font>, 00460 path[0] ? path[0] : <font class="stringliteral">"null"</font>, 00461 path[1] ? path[1] : <font class="stringliteral">"null"</font>); 00462 <font class="keywordflow">return</font>; 00463 } 00464 <font class="preprocessor">#else</font> 00465 <font class="preprocessor"></font> _dbus_assert (subtree != NULL); 00466 <font class="preprocessor">#endif</font> 00467 <font class="preprocessor"></font> 00468 _dbus_assert (subtree-><a class="code" href="structDBusObjectSubtree.html#m1">parent</a> == NULL || 00469 (i >= 0 && subtree-><a class="code" href="structDBusObjectSubtree.html#m1">parent</a>-><a class="code" href="structDBusObjectSubtree.html#m5">subtrees</a>[i] == subtree)); 00470 00471 subtree-><a class="code" href="structDBusObjectSubtree.html#m3">message_function</a> = NULL; 00472 00473 unregister_function = subtree-><a class="code" href="structDBusObjectSubtree.html#m2">unregister_function</a>; 00474 user_data = subtree-><a class="code" href="structDBusObjectSubtree.html#m4">user_data</a>; 00475 00476 subtree-><a class="code" href="structDBusObjectSubtree.html#m2">unregister_function</a> = NULL; 00477 subtree-><a class="code" href="structDBusObjectSubtree.html#m4">user_data</a> = NULL; 00478 00479 <font class="comment">/* If we have no subtrees of our own, remove from</font> 00480 <font class="comment"> * our parent (FIXME could also be more aggressive</font> 00481 <font class="comment"> * and remove our parent if it becomes empty)</font> 00482 <font class="comment"> */</font> 00483 <font class="keywordflow">if</font> (subtree-><a class="code" href="structDBusObjectSubtree.html#m1">parent</a> && subtree-><a class="code" href="structDBusObjectSubtree.html#m6">n_subtrees</a> == 0) 00484 { 00485 <font class="comment">/* assumes a 0-byte memmove is OK */</font> 00486 memmove (&subtree-><a class="code" href="structDBusObjectSubtree.html#m1">parent</a>-><a class="code" href="structDBusObjectSubtree.html#m5">subtrees</a>[i], 00487 &subtree-><a class="code" href="structDBusObjectSubtree.html#m1">parent</a>-><a class="code" href="structDBusObjectSubtree.html#m5">subtrees</a>[i+1], 00488 (subtree-><a class="code" href="structDBusObjectSubtree.html#m1">parent</a>-><a class="code" href="structDBusObjectSubtree.html#m6">n_subtrees</a> - i - 1) * 00489 sizeof (subtree-><a class="code" href="structDBusObjectSubtree.html#m1">parent</a>-><a class="code" href="structDBusObjectSubtree.html#m5">subtrees</a>[0])); 00490 subtree-><a class="code" href="structDBusObjectSubtree.html#m1">parent</a>-><a class="code" href="structDBusObjectSubtree.html#m6">n_subtrees</a> -= 1; 00491 00492 subtree-><a class="code" href="structDBusObjectSubtree.html#m1">parent</a> = NULL; 00493 00494 _dbus_object_subtree_unref (subtree); 00495 } 00496 subtree = NULL; 00497 00498 connection = tree-><a class="code" href="structDBusObjectTree.html#m1">connection</a>; 00499 00500 <font class="comment">/* Unlock and call application code */</font> 00501 <font class="preprocessor">#ifdef DBUS_BUILD_TESTS</font> 00502 <font class="preprocessor"></font> <font class="keywordflow">if</font> (connection) 00503 <font class="preprocessor">#endif</font> 00504 <font class="preprocessor"></font> { 00505 _dbus_connection_ref_unlocked (connection); 00506 _dbus_connection_unlock (connection); 00507 } 00508 00509 <font class="keywordflow">if</font> (unregister_function) 00510 (* unregister_function) (connection, user_data); 00511 00512 <font class="preprocessor">#ifdef DBUS_BUILD_TESTS</font> 00513 <font class="preprocessor"></font> <font class="keywordflow">if</font> (connection) 00514 <font class="preprocessor">#endif</font> 00515 <font class="preprocessor"></font> dbus_connection_unref (connection); 00516 } 00517 00518 <font class="keyword">static</font> <font class="keywordtype">void</font> 00519 free_subtree_recurse (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection, 00520 DBusObjectSubtree *subtree) 00521 { 00522 <font class="comment">/* Delete them from the end, for slightly</font> 00523 <font class="comment"> * more robustness against odd reentrancy.</font> 00524 <font class="comment"> */</font> 00525 <font class="keywordflow">while</font> (subtree-><a class="code" href="structDBusObjectSubtree.html#m6">n_subtrees</a> > 0) 00526 { 00527 DBusObjectSubtree *child; 00528 00529 child = subtree-><a class="code" href="structDBusObjectSubtree.html#m5">subtrees</a>[subtree-><a class="code" href="structDBusObjectSubtree.html#m6">n_subtrees</a> - 1]; 00530 subtree-><a class="code" href="structDBusObjectSubtree.html#m5">subtrees</a>[subtree-><a class="code" href="structDBusObjectSubtree.html#m6">n_subtrees</a> - 1] = NULL; 00531 subtree-><a class="code" href="structDBusObjectSubtree.html#m6">n_subtrees</a> -= 1; 00532 child-><a class="code" href="structDBusObjectSubtree.html#m1">parent</a> = NULL; 00533 00534 free_subtree_recurse (connection, child); 00535 } 00536 00537 <font class="comment">/* Call application code */</font> 00538 <font class="keywordflow">if</font> (subtree-><a class="code" href="structDBusObjectSubtree.html#m2">unregister_function</a>) 00539 { 00540 (* subtree-><a class="code" href="structDBusObjectSubtree.html#m2">unregister_function</a>) (connection, 00541 subtree-><a class="code" href="structDBusObjectSubtree.html#m4">user_data</a>); 00542 subtree-><a class="code" href="structDBusObjectSubtree.html#m3">message_function</a> = NULL; 00543 subtree-><a class="code" href="structDBusObjectSubtree.html#m2">unregister_function</a> = NULL; 00544 subtree-><a class="code" href="structDBusObjectSubtree.html#m4">user_data</a> = NULL; 00545 } 00546 00547 <font class="comment">/* Now free ourselves */</font> 00548 _dbus_object_subtree_unref (subtree); 00549 } 00550 00557 <font class="keywordtype">void</font> <a name="l00558"></a><a class="code" href="group__DBusObjectTree.html#a18">00558</a> _dbus_object_tree_free_all_unlocked (<a class="code" href="structDBusObjectTree.html">DBusObjectTree</a> *tree) 00559 { 00560 <font class="keywordflow">if</font> (tree-><a class="code" href="structDBusObjectTree.html#m2">root</a>) 00561 free_subtree_recurse (tree-><a class="code" href="structDBusObjectTree.html#m1">connection</a>, 00562 tree-><a class="code" href="structDBusObjectTree.html#m2">root</a>); 00563 tree-><a class="code" href="structDBusObjectTree.html#m2">root</a> = NULL; 00564 } 00565 00566 <font class="keyword">static</font> dbus_bool_t 00567 _dbus_object_tree_list_registered_unlocked (<a class="code" href="structDBusObjectTree.html">DBusObjectTree</a> *tree, 00568 <font class="keyword">const</font> <font class="keywordtype">char</font> **parent_path, 00569 <font class="keywordtype">char</font> ***child_entries) 00570 { 00571 DBusObjectSubtree *subtree; 00572 <font class="keywordtype">char</font> **retval; 00573 00574 _dbus_assert (parent_path != NULL); 00575 _dbus_assert (child_entries != NULL); 00576 00577 *child_entries = NULL; 00578 00579 subtree = lookup_subtree (tree, parent_path); 00580 <font class="keywordflow">if</font> (subtree == NULL) 00581 { 00582 retval = dbus_new0 (<font class="keywordtype">char</font> *, 1); 00583 } 00584 <font class="keywordflow">else</font> 00585 { 00586 <font class="keywordtype">int</font> i; 00587 retval = dbus_new0 (<font class="keywordtype">char</font>*, subtree-><a class="code" href="structDBusObjectSubtree.html#m6">n_subtrees</a> + 1); 00588 <font class="keywordflow">if</font> (retval == NULL) 00589 <font class="keywordflow">goto</font> out; 00590 i = 0; 00591 <font class="keywordflow">while</font> (i < subtree-><a class="code" href="structDBusObjectSubtree.html#m6">n_subtrees</a>) 00592 { 00593 retval[i] = _dbus_strdup (subtree-><a class="code" href="structDBusObjectSubtree.html#m5">subtrees</a>[i]-><a class="code" href="structDBusObjectSubtree.html#m9">name</a>); 00594 <font class="keywordflow">if</font> (retval[i] == NULL) 00595 { 00596 dbus_free_string_array (retval); 00597 retval = NULL; 00598 <font class="keywordflow">goto</font> out; 00599 } 00600 ++i; 00601 } 00602 } 00603 00604 out: 00605 00606 *child_entries = retval; 00607 <font class="keywordflow">return</font> retval != NULL; 00608 } 00609 00610 <font class="keyword">static</font> DBusHandlerResult 00611 handle_default_introspect_unlocked (<a class="code" href="structDBusObjectTree.html">DBusObjectTree</a> *tree, 00612 <a class="code" href="structDBusMessage.html">DBusMessage</a> *message, 00613 <font class="keyword">const</font> <font class="keywordtype">char</font> **path) 00614 { 00615 <a class="code" href="structDBusString.html">DBusString</a> xml; 00616 DBusHandlerResult result; 00617 <font class="keywordtype">char</font> **children; 00618 <font class="keywordtype">int</font> i; 00619 00620 <font class="keywordflow">if</font> (!dbus_message_is_method_call (message, 00621 DBUS_INTERFACE_ORG_FREEDESKTOP_INTROSPECTABLE, 00622 <font class="stringliteral">"Introspect"</font>)) 00623 <font class="keywordflow">return</font> DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 00624 00625 <font class="keywordflow">if</font> (!_dbus_string_init (&xml)) 00626 <font class="keywordflow">return</font> DBUS_HANDLER_RESULT_NEED_MEMORY; 00627 00628 result = DBUS_HANDLER_RESULT_NEED_MEMORY; 00629 00630 children = NULL; 00631 <font class="keywordflow">if</font> (!_dbus_object_tree_list_registered_unlocked (tree, path, &children)) 00632 <font class="keywordflow">goto</font> out; 00633 00634 <font class="keywordflow">if</font> (!_dbus_string_append (&xml, <font class="stringliteral">"<node>\n"</font>)) 00635 <font class="keywordflow">goto</font> out; 00636 00637 i = 0; 00638 <font class="keywordflow">while</font> (children[i] != NULL) 00639 { 00640 <font class="keywordflow">if</font> (!_dbus_string_append_printf (&xml, <font class="stringliteral">" <node name=\"%s\"/>\n"</font>, 00641 children[i])) 00642 <font class="keywordflow">goto</font> out; 00643 00644 ++i; 00645 } 00646 00647 <font class="keywordflow">if</font> (!_dbus_string_append (&xml, <font class="stringliteral">"</node>\n"</font>)) 00648 <font class="keywordflow">goto</font> out; 00649 00650 result = DBUS_HANDLER_RESULT_HANDLED; 00651 00652 out: 00653 _dbus_string_free (&xml); 00654 dbus_free_string_array (children); 00655 00656 <font class="keywordflow">return</font> result; 00657 } 00658 00672 DBusHandlerResult <a name="l00673"></a><a class="code" href="group__DBusObjectTree.html#a21">00673</a> _dbus_object_tree_dispatch_and_unlock (<a class="code" href="structDBusObjectTree.html">DBusObjectTree</a> *tree, 00674 <a class="code" href="structDBusMessage.html">DBusMessage</a> *message) 00675 { 00676 <font class="keywordtype">char</font> **path; 00677 dbus_bool_t exact_match; 00678 <a class="code" href="structDBusList.html">DBusList</a> *list; 00679 <a class="code" href="structDBusList.html">DBusList</a> *link; 00680 DBusHandlerResult result; 00681 DBusObjectSubtree *subtree; 00682 00683 <font class="preprocessor">#if 0</font> 00684 <font class="preprocessor"></font> _dbus_verbose (<font class="stringliteral">"Dispatch of message by object path\n"</font>); 00685 <font class="preprocessor">#endif</font> 00686 <font class="preprocessor"></font> 00687 path = NULL; 00688 <font class="keywordflow">if</font> (!dbus_message_get_path_decomposed (message, &path)) 00689 { 00690 <font class="preprocessor">#ifdef DBUS_BUILD_TESTS</font> 00691 <font class="preprocessor"></font> <font class="keywordflow">if</font> (tree-><a class="code" href="structDBusObjectTree.html#m1">connection</a>) 00692 <font class="preprocessor">#endif</font> 00693 <font class="preprocessor"></font> _dbus_connection_unlock (tree-><a class="code" href="structDBusObjectTree.html#m1">connection</a>); 00694 00695 _dbus_verbose (<font class="stringliteral">"No memory to get decomposed path\n"</font>); 00696 00697 <font class="keywordflow">return</font> DBUS_HANDLER_RESULT_NEED_MEMORY; 00698 } 00699 00700 <font class="keywordflow">if</font> (path == NULL) 00701 { 00702 <font class="preprocessor">#ifdef DBUS_BUILD_TESTS</font> 00703 <font class="preprocessor"></font> <font class="keywordflow">if</font> (tree-><a class="code" href="structDBusObjectTree.html#m1">connection</a>) 00704 <font class="preprocessor">#endif</font> 00705 <font class="preprocessor"></font> _dbus_connection_unlock (tree-><a class="code" href="structDBusObjectTree.html#m1">connection</a>); 00706 00707 _dbus_verbose (<font class="stringliteral">"No path field in message\n"</font>); 00708 <font class="keywordflow">return</font> DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 00709 } 00710 00711 <font class="comment">/* Find the deepest path that covers the path in the message */</font> 00712 subtree = find_handler (tree, (<font class="keyword">const</font> <font class="keywordtype">char</font>**) path, &exact_match); 00713 00714 <font class="comment">/* Build a list of all paths that cover the path in the message */</font> 00715 00716 list = NULL; 00717 00718 <font class="keywordflow">while</font> (subtree != NULL) 00719 { 00720 <font class="keywordflow">if</font> (subtree-><a class="code" href="structDBusObjectSubtree.html#m3">message_function</a> != NULL && (exact_match || subtree-><a class="code" href="structDBusObjectSubtree.html#m8">invoke_as_fallback</a>)) 00721 { 00722 _dbus_object_subtree_ref (subtree); 00723 00724 <font class="comment">/* run deepest paths first */</font> 00725 <font class="keywordflow">if</font> (!_dbus_list_append (&list, subtree)) 00726 { 00727 result = DBUS_HANDLER_RESULT_NEED_MEMORY; 00728 _dbus_object_subtree_unref (subtree); 00729 <font class="keywordflow">goto</font> free_and_return; 00730 } 00731 } 00732 00733 exact_match = FALSE; 00734 subtree = subtree-><a class="code" href="structDBusObjectSubtree.html#m1">parent</a>; 00735 } 00736 00737 _dbus_verbose (<font class="stringliteral">"%d handlers in the path tree for this message\n"</font>, 00738 _dbus_list_get_length (&list)); 00739 00740 <font class="comment">/* Invoke each handler in the list */</font> 00741 00742 result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 00743 00744 link = _dbus_list_get_first_link (&list); 00745 <font class="keywordflow">while</font> (link != NULL) 00746 { 00747 <a class="code" href="structDBusList.html">DBusList</a> *next = _dbus_list_get_next_link (&list, link); 00748 subtree = link-><a class="code" href="structDBusList.html#m2">data</a>; 00749 00750 <font class="comment">/* message_function is NULL if we're unregistered</font> 00751 <font class="comment"> * due to reentrancy</font> 00752 <font class="comment"> */</font> 00753 <font class="keywordflow">if</font> (subtree-><a class="code" href="structDBusObjectSubtree.html#m3">message_function</a>) 00754 { 00755 DBusObjectPathMessageFunction message_function; 00756 <font class="keywordtype">void</font> *user_data; 00757 00758 message_function = subtree-><a class="code" href="structDBusObjectSubtree.html#m3">message_function</a>; 00759 user_data = subtree-><a class="code" href="structDBusObjectSubtree.html#m4">user_data</a>; 00760 00761 <font class="preprocessor">#if 0</font> 00762 <font class="preprocessor"></font> _dbus_verbose (<font class="stringliteral">" (invoking a handler)\n"</font>); 00763 <font class="preprocessor">#endif</font> 00764 <font class="preprocessor"></font> 00765 <font class="preprocessor">#ifdef DBUS_BUILD_TESTS</font> 00766 <font class="preprocessor"></font> <font class="keywordflow">if</font> (tree-><a class="code" href="structDBusObjectTree.html#m1">connection</a>) 00767 <font class="preprocessor">#endif</font> 00768 <font class="preprocessor"></font> _dbus_connection_unlock (tree-><a class="code" href="structDBusObjectTree.html#m1">connection</a>); 00769 00770 <font class="comment">/* FIXME you could unregister the subtree in another thread</font> 00771 <font class="comment"> * before we invoke the callback, and I can't figure out a</font> 00772 <font class="comment"> * good way to solve this.</font> 00773 <font class="comment"> */</font> 00774 00775 result = (* message_function) (tree-><a class="code" href="structDBusObjectTree.html#m1">connection</a>, 00776 message, 00777 user_data); 00778 00779 <font class="preprocessor">#ifdef DBUS_BUILD_TESTS</font> 00780 <font class="preprocessor"></font> <font class="keywordflow">if</font> (tree-><a class="code" href="structDBusObjectTree.html#m1">connection</a>) 00781 <font class="preprocessor">#endif</font> 00782 <font class="preprocessor"></font> _dbus_connection_lock (tree-><a class="code" href="structDBusObjectTree.html#m1">connection</a>); 00783 00784 <font class="keywordflow">if</font> (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED) 00785 <font class="keywordflow">goto</font> free_and_return; 00786 } 00787 00788 link = next; 00789 } 00790 00791 free_and_return: 00792 00793 <font class="keywordflow">if</font> (result == DBUS_HANDLER_RESULT_NOT_YET_HANDLED) 00794 { 00795 <font class="comment">/* This hardcoded default handler does a minimal Introspect()</font> 00796 <font class="comment"> */</font> 00797 result = handle_default_introspect_unlocked (tree, message, 00798 (<font class="keyword">const</font> <font class="keywordtype">char</font>**) path); 00799 } 00800 00801 <font class="preprocessor">#ifdef DBUS_BUILD_TESTS</font> 00802 <font class="preprocessor"></font> <font class="keywordflow">if</font> (tree-><a class="code" href="structDBusObjectTree.html#m1">connection</a>) 00803 <font class="preprocessor">#endif</font> 00804 <font class="preprocessor"></font> _dbus_connection_unlock (tree-><a class="code" href="structDBusObjectTree.html#m1">connection</a>); 00805 00806 <font class="keywordflow">while</font> (list != NULL) 00807 { 00808 link = _dbus_list_get_first_link (&list); 00809 _dbus_object_subtree_unref (link-><a class="code" href="structDBusList.html#m2">data</a>); 00810 _dbus_list_remove_link (&list, link); 00811 } 00812 00813 dbus_free_string_array (path); 00814 00815 <font class="keywordflow">return</font> result; 00816 } 00817 00824 <font class="keyword">static</font> DBusObjectSubtree* 00825 allocate_subtree_object (<font class="keyword">const</font> <font class="keywordtype">char</font> *name) 00826 { 00827 <font class="keywordtype">int</font> len; 00828 DBusObjectSubtree *subtree; 00829 <font class="keyword">const</font> size_t front_padding = _DBUS_STRUCT_OFFSET (DBusObjectSubtree, name); 00830 00831 _dbus_assert (name != NULL); 00832 00833 len = strlen (name); 00834 00835 subtree = dbus_malloc (front_padding + (len + 1)); 00836 00837 <font class="keywordflow">if</font> (subtree == NULL) 00838 <font class="keywordflow">return</font> NULL; 00839 00840 memcpy (subtree-><a class="code" href="structDBusObjectSubtree.html#m9">name</a>, name, len + 1); 00841 00842 <font class="keywordflow">return</font> subtree; 00843 } 00844 00845 <font class="keyword">static</font> DBusObjectSubtree* 00846 _dbus_object_subtree_new (<font class="keyword">const</font> <font class="keywordtype">char</font> *name, 00847 <font class="keyword">const</font> <a class="code" href="structDBusObjectPathVTable.html">DBusObjectPathVTable</a> *vtable, 00848 <font class="keywordtype">void</font> *user_data) 00849 { 00850 DBusObjectSubtree *subtree; 00851 00852 subtree = allocate_subtree_object (name); 00853 <font class="keywordflow">if</font> (subtree == NULL) 00854 <font class="keywordflow">goto</font> oom; 00855 00856 _dbus_assert (name != NULL); 00857 00858 subtree-><a class="code" href="structDBusObjectSubtree.html#m1">parent</a> = NULL; 00859 00860 <font class="keywordflow">if</font> (vtable) 00861 { 00862 subtree-><a class="code" href="structDBusObjectSubtree.html#m3">message_function</a> = vtable-><a class="code" href="structDBusObjectPathVTable.html#m1">message_function</a>; 00863 subtree-><a class="code" href="structDBusObjectSubtree.html#m2">unregister_function</a> = vtable-><a class="code" href="structDBusObjectPathVTable.html#m0">unregister_function</a>; 00864 } 00865 <font class="keywordflow">else</font> 00866 { 00867 subtree-><a class="code" href="structDBusObjectSubtree.html#m3">message_function</a> = NULL; 00868 subtree-><a class="code" href="structDBusObjectSubtree.html#m2">unregister_function</a> = NULL; 00869 } 00870 00871 subtree-><a class="code" href="structDBusObjectSubtree.html#m4">user_data</a> = user_data; 00872 subtree-><a class="code" href="structDBusObjectSubtree.html#m0">refcount</a>.<a class="code" href="structDBusAtomic.html#m0">value</a> = 1; 00873 subtree-><a class="code" href="structDBusObjectSubtree.html#m5">subtrees</a> = NULL; 00874 subtree-><a class="code" href="structDBusObjectSubtree.html#m6">n_subtrees</a> = 0; 00875 subtree-><a class="code" href="structDBusObjectSubtree.html#m7">subtrees_sorted</a> = TRUE; 00876 subtree-><a class="code" href="structDBusObjectSubtree.html#m8">invoke_as_fallback</a> = FALSE; 00877 00878 <font class="keywordflow">return</font> subtree; 00879 00880 oom: 00881 <font class="keywordflow">if</font> (subtree) 00882 { 00883 dbus_free (subtree); 00884 } 00885 00886 <font class="keywordflow">return</font> NULL; 00887 } 00888 00889 <font class="keyword">static</font> DBusObjectSubtree * 00890 _dbus_object_subtree_ref (DBusObjectSubtree *subtree) 00891 { 00892 _dbus_assert (subtree-><a class="code" href="structDBusObjectSubtree.html#m0">refcount</a>.<a class="code" href="structDBusAtomic.html#m0">value</a> > 0); 00893 _dbus_atomic_inc (&subtree-><a class="code" href="structDBusObjectSubtree.html#m0">refcount</a>); 00894 00895 <font class="keywordflow">return</font> subtree; 00896 } 00897 00898 <font class="keyword">static</font> <font class="keywordtype">void</font> 00899 _dbus_object_subtree_unref (DBusObjectSubtree *subtree) 00900 { 00901 _dbus_assert (subtree-><a class="code" href="structDBusObjectSubtree.html#m0">refcount</a>.<a class="code" href="structDBusAtomic.html#m0">value</a> > 0); 00902 00903 <font class="keywordflow">if</font> (_dbus_atomic_dec (&subtree-><a class="code" href="structDBusObjectSubtree.html#m0">refcount</a>) == 1) 00904 { 00905 _dbus_assert (subtree-><a class="code" href="structDBusObjectSubtree.html#m2">unregister_function</a> == NULL); 00906 _dbus_assert (subtree-><a class="code" href="structDBusObjectSubtree.html#m3">message_function</a> == NULL); 00907 00908 dbus_free (subtree-><a class="code" href="structDBusObjectSubtree.html#m5">subtrees</a>); 00909 dbus_free (subtree); 00910 } 00911 } 00912 00923 dbus_bool_t <a name="l00924"></a><a class="code" href="group__DBusObjectTree.html#a23">00924</a> _dbus_object_tree_list_registered_and_unlock (<a class="code" href="structDBusObjectTree.html">DBusObjectTree</a> *tree, 00925 <font class="keyword">const</font> <font class="keywordtype">char</font> **parent_path, 00926 <font class="keywordtype">char</font> ***child_entries) 00927 { 00928 dbus_bool_t result; 00929 00930 result = _dbus_object_tree_list_registered_unlocked (tree, 00931 parent_path, 00932 child_entries); 00933 00934 <font class="preprocessor">#ifdef DBUS_BUILD_TESTS</font> 00935 <font class="preprocessor"></font> <font class="keywordflow">if</font> (tree-><a class="code" href="structDBusObjectTree.html#m1">connection</a>) 00936 <font class="preprocessor">#endif</font> 00937 <font class="preprocessor"></font> _dbus_connection_unlock (tree-><a class="code" href="structDBusObjectTree.html#m1">connection</a>); 00938 00939 <font class="keywordflow">return</font> result; 00940 } 00941 00944 <font class="preprocessor">#ifdef DBUS_BUILD_TESTS</font> 00945 <font class="preprocessor"></font><font class="preprocessor">#include "dbus-test.h"</font> 00946 <font class="preprocessor">#include <stdio.h></font> 00947 00948 <font class="keyword">static</font> <font class="keywordtype">char</font>* 00949 flatten_path (<font class="keyword">const</font> <font class="keywordtype">char</font> **path) 00950 { 00951 <a class="code" href="structDBusString.html">DBusString</a> str; 00952 <font class="keywordtype">int</font> i; 00953 <font class="keywordtype">char</font> *s; 00954 00955 <font class="keywordflow">if</font> (!_dbus_string_init (&str)) 00956 <font class="keywordflow">return</font> NULL; 00957 00958 i = 0; 00959 <font class="keywordflow">while</font> (path[i]) 00960 { 00961 <font class="keywordflow">if</font> (!_dbus_string_append_byte (&str, <font class="charliteral">'/'</font>)) 00962 <font class="keywordflow">goto</font> nomem; 00963 00964 <font class="keywordflow">if</font> (!_dbus_string_append (&str, path[i])) 00965 <font class="keywordflow">goto</font> nomem; 00966 00967 ++i; 00968 } 00969 00970 <font class="keywordflow">if</font> (!_dbus_string_steal_data (&str, &s)) 00971 <font class="keywordflow">goto</font> nomem; 00972 00973 _dbus_string_free (&str); 00974 00975 <font class="keywordflow">return</font> s; 00976 00977 nomem: 00978 _dbus_string_free (&str); 00979 <font class="keywordflow">return</font> NULL; 00980 } 00981 00982 00983 <font class="keyword">typedef</font> <font class="keyword">enum</font> 00984 { 00985 STR_EQUAL, 00986 STR_PREFIX, 00987 STR_DIFFERENT 00988 } StrComparison; 00989 00990 <font class="comment">/* Returns TRUE if container is a parent of child</font> 00991 <font class="comment"> */</font> 00992 <font class="keyword">static</font> StrComparison 00993 path_contains (<font class="keyword">const</font> <font class="keywordtype">char</font> **container, 00994 <font class="keyword">const</font> <font class="keywordtype">char</font> **child) 00995 { 00996 <font class="keywordtype">int</font> i; 00997 00998 i = 0; 00999 <font class="keywordflow">while</font> (child[i] != NULL) 01000 { 01001 <font class="keywordtype">int</font> v; 01002 01003 <font class="keywordflow">if</font> (container[i] == NULL) 01004 <font class="keywordflow">return</font> STR_PREFIX; <font class="comment">/* container ran out, child continues;</font> 01005 <font class="comment"> * thus the container is a parent of the</font> 01006 <font class="comment"> * child.</font> 01007 <font class="comment"> */</font> 01008 01009 _dbus_assert (container[i] != NULL); 01010 _dbus_assert (child[i] != NULL); 01011 01012 v = strcmp (container[i], child[i]); 01013 01014 <font class="keywordflow">if</font> (v != 0) 01015 <font class="keywordflow">return</font> STR_DIFFERENT; <font class="comment">/* they overlap until here and then are different,</font> 01016 <font class="comment"> * not overlapping</font> 01017 <font class="comment"> */</font> 01018 01019 ++i; 01020 } 01021 01022 <font class="comment">/* Child ran out; if container also did, they are equal;</font> 01023 <font class="comment"> * otherwise, the child is a parent of the container.</font> 01024 <font class="comment"> */</font> 01025 <font class="keywordflow">if</font> (container[i] == NULL) 01026 <font class="keywordflow">return</font> STR_EQUAL; 01027 <font class="keywordflow">else</font> 01028 <font class="keywordflow">return</font> STR_DIFFERENT; 01029 } 01030 01031 <font class="preprocessor">#if 0</font> 01032 <font class="preprocessor"></font><font class="keyword">static</font> <font class="keywordtype">void</font> 01033 spew_subtree_recurse (DBusObjectSubtree *subtree, 01034 <font class="keywordtype">int</font> indent) 01035 { 01036 <font class="keywordtype">int</font> i; 01037 01038 i = 0; 01039 <font class="keywordflow">while</font> (i < indent) 01040 { 01041 _dbus_verbose (<font class="stringliteral">" "</font>); 01042 ++i; 01043 } 01044 01045 _dbus_verbose (<font class="stringliteral">"%s (%d children)\n"</font>, 01046 subtree-><a class="code" href="structDBusObjectSubtree.html#m9">name</a>, subtree-><a class="code" href="structDBusObjectSubtree.html#m6">n_subtrees</a>); 01047 01048 i = 0; 01049 <font class="keywordflow">while</font> (i < subtree-><a class="code" href="structDBusObjectSubtree.html#m6">n_subtrees</a>) 01050 { 01051 spew_subtree_recurse (subtree-><a class="code" href="structDBusObjectSubtree.html#m5">subtrees</a>[i], indent + 2); 01052 01053 ++i; 01054 } 01055 } 01056 01057 <font class="keyword">static</font> <font class="keywordtype">void</font> 01058 spew_tree (<a class="code" href="structDBusObjectTree.html">DBusObjectTree</a> *tree) 01059 { 01060 spew_subtree_recurse (tree-><a class="code" href="structDBusObjectTree.html#m2">root</a>, 0); 01061 } 01062 <font class="preprocessor">#endif</font> 01063 <font class="preprocessor"></font> <a name="l01067"></a><a class="code" href="structTreeTestData.html">01067</a> <font class="keyword">typedef</font> <font class="keyword">struct</font> 01068 <font class="keyword"></font>{ <a name="l01069"></a><a class="code" href="structTreeTestData.html#m0">01069</a> <font class="keyword">const</font> <font class="keywordtype">char</font> **path; <a name="l01070"></a><a class="code" href="structTreeTestData.html#m1">01070</a> dbus_bool_t handler_fallback; <a name="l01071"></a><a class="code" href="structTreeTestData.html#m2">01071</a> dbus_bool_t message_handled; <a name="l01072"></a><a class="code" href="structTreeTestData.html#m3">01072</a> dbus_bool_t handler_unregistered; 01073 } <a class="code" href="structTreeTestData.html">TreeTestData</a>; 01074 01075 01076 <font class="keyword">static</font> <font class="keywordtype">void</font> 01077 test_unregister_function (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection, 01078 <font class="keywordtype">void</font> *user_data) 01079 { 01080 <a class="code" href="structTreeTestData.html">TreeTestData</a> *ttd = user_data; 01081 01082 ttd-><a class="code" href="structTreeTestData.html#m3">handler_unregistered</a> = TRUE; 01083 } 01084 01085 <font class="keyword">static</font> DBusHandlerResult 01086 test_message_function (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection, 01087 <a class="code" href="structDBusMessage.html">DBusMessage</a> *message, 01088 <font class="keywordtype">void</font> *user_data) 01089 { 01090 <a class="code" href="structTreeTestData.html">TreeTestData</a> *ttd = user_data; 01091 01092 ttd-><a class="code" href="structTreeTestData.html#m2">message_handled</a> = TRUE; 01093 01094 <font class="keywordflow">return</font> DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 01095 } 01096 01097 <font class="keyword">static</font> dbus_bool_t 01098 do_register (<a class="code" href="structDBusObjectTree.html">DBusObjectTree</a> *tree, 01099 <font class="keyword">const</font> <font class="keywordtype">char</font> **path, 01100 dbus_bool_t fallback, 01101 <font class="keywordtype">int</font> i, 01102 <a class="code" href="structTreeTestData.html">TreeTestData</a> *tree_test_data) 01103 { 01104 <a class="code" href="structDBusObjectPathVTable.html">DBusObjectPathVTable</a> vtable = { test_unregister_function, 01105 test_message_function, NULL }; 01106 01107 tree_test_data[i].<a class="code" href="structTreeTestData.html#m2">message_handled</a> = FALSE; 01108 tree_test_data[i].<a class="code" href="structTreeTestData.html#m3">handler_unregistered</a> = FALSE; 01109 tree_test_data[i].<a class="code" href="structTreeTestData.html#m1">handler_fallback</a> = fallback; 01110 tree_test_data[i].<a class="code" href="structTreeTestData.html#m0">path</a> = path; 01111 01112 <font class="keywordflow">if</font> (!_dbus_object_tree_register (tree, fallback, path, 01113 &vtable, 01114 &tree_test_data[i])) 01115 <font class="keywordflow">return</font> FALSE; 01116 01117 <font class="keywordflow">return</font> TRUE; 01118 } 01119 01120 <font class="keyword">static</font> dbus_bool_t 01121 do_test_dispatch (<a class="code" href="structDBusObjectTree.html">DBusObjectTree</a> *tree, 01122 <font class="keyword">const</font> <font class="keywordtype">char</font> **path, 01123 <font class="keywordtype">int</font> i, 01124 <a class="code" href="structTreeTestData.html">TreeTestData</a> *tree_test_data, 01125 <font class="keywordtype">int</font> n_test_data) 01126 { 01127 <a class="code" href="structDBusMessage.html">DBusMessage</a> *message; 01128 <font class="keywordtype">int</font> j; 01129 DBusHandlerResult result; 01130 <font class="keywordtype">char</font> *flat; 01131 01132 message = NULL; 01133 01134 flat = flatten_path (path); 01135 <font class="keywordflow">if</font> (flat == NULL) 01136 <font class="keywordflow">goto</font> oom; 01137 01138 message = dbus_message_new_method_call (NULL, 01139 flat, 01140 <font class="stringliteral">"org.freedesktop.TestInterface"</font>, 01141 <font class="stringliteral">"Foo"</font>); 01142 dbus_free (flat); 01143 <font class="keywordflow">if</font> (message == NULL) 01144 <font class="keywordflow">goto</font> oom; 01145 01146 j = 0; 01147 <font class="keywordflow">while</font> (j < n_test_data) 01148 { 01149 tree_test_data[j].<a class="code" href="structTreeTestData.html#m2">message_handled</a> = FALSE; 01150 ++j; 01151 } 01152 01153 result = _dbus_object_tree_dispatch_and_unlock (tree, message); 01154 <font class="keywordflow">if</font> (result == DBUS_HANDLER_RESULT_NEED_MEMORY) 01155 <font class="keywordflow">goto</font> oom; 01156 01157 _dbus_assert (tree_test_data[i].message_handled); 01158 01159 j = 0; 01160 <font class="keywordflow">while</font> (j < n_test_data) 01161 { 01162 <font class="keywordflow">if</font> (tree_test_data[j].<a class="code" href="structTreeTestData.html#m2">message_handled</a>) 01163 { 01164 <font class="keywordflow">if</font> (tree_test_data[j].<a class="code" href="structTreeTestData.html#m1">handler_fallback</a>) 01165 _dbus_assert (path_contains (tree_test_data[j].path, 01166 path) != STR_DIFFERENT); 01167 <font class="keywordflow">else</font> 01168 _dbus_assert (path_contains (tree_test_data[j].path, path) == STR_EQUAL); 01169 } 01170 <font class="keywordflow">else</font> 01171 { 01172 <font class="keywordflow">if</font> (tree_test_data[j].<a class="code" href="structTreeTestData.html#m1">handler_fallback</a>) 01173 _dbus_assert (path_contains (tree_test_data[j].path, 01174 path) == STR_DIFFERENT); 01175 <font class="keywordflow">else</font> 01176 _dbus_assert (path_contains (tree_test_data[j].path, path) != STR_EQUAL); 01177 } 01178 01179 ++j; 01180 } 01181 01182 dbus_message_unref (message); 01183 01184 <font class="keywordflow">return</font> TRUE; 01185 01186 oom: 01187 <font class="keywordflow">if</font> (message) 01188 dbus_message_unref (message); 01189 <font class="keywordflow">return</font> FALSE; 01190 } 01191 01192 <font class="keyword">static</font> size_t 01193 string_array_length (<font class="keywordtype">char</font> **array) 01194 { 01195 size_t i; 01196 <font class="keywordflow">for</font> (i = 0; array[i]; i++) ; 01197 <font class="keywordflow">return</font> i; 01198 } 01199 01200 01201 <font class="keyword">static</font> dbus_bool_t 01202 object_tree_test_iteration (<font class="keywordtype">void</font> *data) 01203 { 01204 <font class="keyword">const</font> <font class="keywordtype">char</font> *path1[] = { <font class="stringliteral">"foo"</font>, NULL }; 01205 <font class="keyword">const</font> <font class="keywordtype">char</font> *path2[] = { <font class="stringliteral">"foo"</font>, <font class="stringliteral">"bar"</font>, NULL }; 01206 <font class="keyword">const</font> <font class="keywordtype">char</font> *path3[] = { <font class="stringliteral">"foo"</font>, <font class="stringliteral">"bar"</font>, <font class="stringliteral">"baz"</font>, NULL }; 01207 <font class="keyword">const</font> <font class="keywordtype">char</font> *path4[] = { <font class="stringliteral">"foo"</font>, <font class="stringliteral">"bar"</font>, <font class="stringliteral">"boo"</font>, NULL }; 01208 <font class="keyword">const</font> <font class="keywordtype">char</font> *path5[] = { <font class="stringliteral">"blah"</font>, NULL }; 01209 <font class="keyword">const</font> <font class="keywordtype">char</font> *path6[] = { <font class="stringliteral">"blah"</font>, <font class="stringliteral">"boof"</font>, NULL }; 01210 <font class="keyword">const</font> <font class="keywordtype">char</font> *path7[] = { <font class="stringliteral">"blah"</font>, <font class="stringliteral">"boof"</font>, <font class="stringliteral">"this"</font>, <font class="stringliteral">"is"</font>, <font class="stringliteral">"really"</font>, <font class="stringliteral">"long"</font>, NULL }; 01211 <font class="keyword">const</font> <font class="keywordtype">char</font> *path8[] = { <font class="stringliteral">"childless"</font>, NULL }; 01212 <a class="code" href="structDBusObjectTree.html">DBusObjectTree</a> *tree; 01213 <a class="code" href="structTreeTestData.html">TreeTestData</a> tree_test_data[8]; 01214 <font class="keywordtype">int</font> i; 01215 dbus_bool_t exact_match; 01216 01217 tree = NULL; 01218 01219 tree = _dbus_object_tree_new (NULL); 01220 <font class="keywordflow">if</font> (tree == NULL) 01221 <font class="keywordflow">goto</font> out; 01222 01223 <font class="keywordflow">if</font> (!do_register (tree, path1, TRUE, 0, tree_test_data)) 01224 <font class="keywordflow">goto</font> out; 01225 01226 _dbus_assert (find_subtree (tree, path1, NULL)); 01227 _dbus_assert (!find_subtree (tree, path2, NULL)); 01228 _dbus_assert (!find_subtree (tree, path3, NULL)); 01229 _dbus_assert (!find_subtree (tree, path4, NULL)); 01230 _dbus_assert (!find_subtree (tree, path5, NULL)); 01231 _dbus_assert (!find_subtree (tree, path6, NULL)); 01232 _dbus_assert (!find_subtree (tree, path7, NULL)); 01233 _dbus_assert (!find_subtree (tree, path8, NULL)); 01234 01235 _dbus_assert (find_handler (tree, path1, &exact_match) && exact_match); 01236 _dbus_assert (find_handler (tree, path2, &exact_match) && !exact_match); 01237 _dbus_assert (find_handler (tree, path3, &exact_match) && !exact_match); 01238 _dbus_assert (find_handler (tree, path4, &exact_match) && !exact_match); 01239 _dbus_assert (find_handler (tree, path5, &exact_match) == tree-><a class="code" href="structDBusObjectTree.html#m2">root</a> && !exact_match); 01240 _dbus_assert (find_handler (tree, path6, &exact_match) == tree-><a class="code" href="structDBusObjectTree.html#m2">root</a> && !exact_match); 01241 _dbus_assert (find_handler (tree, path7, &exact_match) == tree-><a class="code" href="structDBusObjectTree.html#m2">root</a> && !exact_match); 01242 _dbus_assert (find_handler (tree, path8, &exact_match) == tree-><a class="code" href="structDBusObjectTree.html#m2">root</a> && !exact_match); 01243 01244 <font class="keywordflow">if</font> (!do_register (tree, path2, TRUE, 1, tree_test_data)) 01245 <font class="keywordflow">goto</font> out; 01246 01247 _dbus_assert (find_subtree (tree, path1, NULL)); 01248 _dbus_assert (find_subtree (tree, path2, NULL)); 01249 _dbus_assert (!find_subtree (tree, path3, NULL)); 01250 _dbus_assert (!find_subtree (tree, path4, NULL)); 01251 _dbus_assert (!find_subtree (tree, path5, NULL)); 01252 _dbus_assert (!find_subtree (tree, path6, NULL)); 01253 _dbus_assert (!find_subtree (tree, path7, NULL)); 01254 _dbus_assert (!find_subtree (tree, path8, NULL)); 01255 01256 <font class="keywordflow">if</font> (!do_register (tree, path3, TRUE, 2, tree_test_data)) 01257 <font class="keywordflow">goto</font> out; 01258 01259 _dbus_assert (find_subtree (tree, path1, NULL)); 01260 _dbus_assert (find_subtree (tree, path2, NULL)); 01261 _dbus_assert (find_subtree (tree, path3, NULL)); 01262 _dbus_assert (!find_subtree (tree, path4, NULL)); 01263 _dbus_assert (!find_subtree (tree, path5, NULL)); 01264 _dbus_assert (!find_subtree (tree, path6, NULL)); 01265 _dbus_assert (!find_subtree (tree, path7, NULL)); 01266 _dbus_assert (!find_subtree (tree, path8, NULL)); 01267 01268 <font class="keywordflow">if</font> (!do_register (tree, path4, TRUE, 3, tree_test_data)) 01269 <font class="keywordflow">goto</font> out; 01270 01271 _dbus_assert (find_subtree (tree, path1, NULL)); 01272 _dbus_assert (find_subtree (tree, path2, NULL)); 01273 _dbus_assert (find_subtree (tree, path3, NULL)); 01274 _dbus_assert (find_subtree (tree, path4, NULL)); 01275 _dbus_assert (!find_subtree (tree, path5, NULL)); 01276 _dbus_assert (!find_subtree (tree, path6, NULL)); 01277 _dbus_assert (!find_subtree (tree, path7, NULL)); 01278 _dbus_assert (!find_subtree (tree, path8, NULL)); 01279 01280 <font class="keywordflow">if</font> (!do_register (tree, path5, TRUE, 4, tree_test_data)) 01281 <font class="keywordflow">goto</font> out; 01282 01283 _dbus_assert (find_subtree (tree, path1, NULL)); 01284 _dbus_assert (find_subtree (tree, path2, NULL)); 01285 _dbus_assert (find_subtree (tree, path3, NULL)); 01286 _dbus_assert (find_subtree (tree, path4, NULL)); 01287 _dbus_assert (find_subtree (tree, path5, NULL)); 01288 _dbus_assert (!find_subtree (tree, path6, NULL)); 01289 _dbus_assert (!find_subtree (tree, path7, NULL)); 01290 _dbus_assert (!find_subtree (tree, path8, NULL)); 01291 01292 _dbus_assert (find_handler (tree, path1, &exact_match) != tree-><a class="code" href="structDBusObjectTree.html#m2">root</a> && exact_match); 01293 _dbus_assert (find_handler (tree, path2, &exact_match) != tree-><a class="code" href="structDBusObjectTree.html#m2">root</a> && exact_match); 01294 _dbus_assert (find_handler (tree, path3, &exact_match) != tree-><a class="code" href="structDBusObjectTree.html#m2">root</a> && exact_match); 01295 _dbus_assert (find_handler (tree, path4, &exact_match) != tree-><a class="code" href="structDBusObjectTree.html#m2">root</a> && exact_match); 01296 _dbus_assert (find_handler (tree, path5, &exact_match) != tree-><a class="code" href="structDBusObjectTree.html#m2">root</a> && exact_match); 01297 _dbus_assert (find_handler (tree, path6, &exact_match) != tree-><a class="code" href="structDBusObjectTree.html#m2">root</a> && !exact_match); 01298 _dbus_assert (find_handler (tree, path7, &exact_match) != tree-><a class="code" href="structDBusObjectTree.html#m2">root</a> && !exact_match); 01299 _dbus_assert (find_handler (tree, path8, &exact_match) == tree-><a class="code" href="structDBusObjectTree.html#m2">root</a> && !exact_match); 01300 01301 <font class="keywordflow">if</font> (!do_register (tree, path6, TRUE, 5, tree_test_data)) 01302 <font class="keywordflow">goto</font> out; 01303 01304 _dbus_assert (find_subtree (tree, path1, NULL)); 01305 _dbus_assert (find_subtree (tree, path2, NULL)); 01306 _dbus_assert (find_subtree (tree, path3, NULL)); 01307 _dbus_assert (find_subtree (tree, path4, NULL)); 01308 _dbus_assert (find_subtree (tree, path5, NULL)); 01309 _dbus_assert (find_subtree (tree, path6, NULL)); 01310 _dbus_assert (!find_subtree (tree, path7, NULL)); 01311 _dbus_assert (!find_subtree (tree, path8, NULL)); 01312 01313 <font class="keywordflow">if</font> (!do_register (tree, path7, TRUE, 6, tree_test_data)) 01314 <font class="keywordflow">goto</font> out; 01315 01316 _dbus_assert (find_subtree (tree, path1, NULL)); 01317 _dbus_assert (find_subtree (tree, path2, NULL)); 01318 _dbus_assert (find_subtree (tree, path3, NULL)); 01319 _dbus_assert (find_subtree (tree, path4, NULL)); 01320 _dbus_assert (find_subtree (tree, path5, NULL)); 01321 _dbus_assert (find_subtree (tree, path6, NULL)); 01322 _dbus_assert (find_subtree (tree, path7, NULL)); 01323 _dbus_assert (!find_subtree (tree, path8, NULL)); 01324 01325 <font class="keywordflow">if</font> (!do_register (tree, path8, TRUE, 7, tree_test_data)) 01326 <font class="keywordflow">goto</font> out; 01327 01328 _dbus_assert (find_subtree (tree, path1, NULL)); 01329 _dbus_assert (find_subtree (tree, path2, NULL)); 01330 _dbus_assert (find_subtree (tree, path3, NULL)); 01331 _dbus_assert (find_subtree (tree, path4, NULL)); 01332 _dbus_assert (find_subtree (tree, path5, NULL)); 01333 _dbus_assert (find_subtree (tree, path6, NULL)); 01334 _dbus_assert (find_subtree (tree, path7, NULL)); 01335 _dbus_assert (find_subtree (tree, path8, NULL)); 01336 01337 _dbus_assert (find_handler (tree, path1, &exact_match) != tree-><a class="code" href="structDBusObjectTree.html#m2">root</a> && exact_match); 01338 _dbus_assert (find_handler (tree, path2, &exact_match) != tree-><a class="code" href="structDBusObjectTree.html#m2">root</a> && exact_match); 01339 _dbus_assert (find_handler (tree, path3, &exact_match) != tree-><a class="code" href="structDBusObjectTree.html#m2">root</a> && exact_match); 01340 _dbus_assert (find_handler (tree, path4, &exact_match) != tree-><a class="code" href="structDBusObjectTree.html#m2">root</a> && exact_match); 01341 _dbus_assert (find_handler (tree, path5, &exact_match) != tree-><a class="code" href="structDBusObjectTree.html#m2">root</a> && exact_match); 01342 _dbus_assert (find_handler (tree, path6, &exact_match) != tree-><a class="code" href="structDBusObjectTree.html#m2">root</a> && exact_match); 01343 _dbus_assert (find_handler (tree, path7, &exact_match) != tree-><a class="code" href="structDBusObjectTree.html#m2">root</a> && exact_match); 01344 _dbus_assert (find_handler (tree, path8, &exact_match) != tree-><a class="code" href="structDBusObjectTree.html#m2">root</a> && exact_match); 01345 01346 <font class="comment">/* test the list_registered function */</font> 01347 01348 { 01349 <font class="keyword">const</font> <font class="keywordtype">char</font> *root[] = { NULL }; 01350 <font class="keywordtype">char</font> **child_entries; 01351 <font class="keywordtype">int</font> nb; 01352 01353 _dbus_object_tree_list_registered_unlocked (tree, path1, &child_entries); 01354 <font class="keywordflow">if</font> (child_entries != NULL) 01355 { 01356 nb = string_array_length (child_entries); 01357 _dbus_assert (nb == 1); 01358 dbus_free_string_array (child_entries); 01359 } 01360 01361 _dbus_object_tree_list_registered_unlocked (tree, path2, &child_entries); 01362 <font class="keywordflow">if</font> (child_entries != NULL) 01363 { 01364 nb = string_array_length (child_entries); 01365 _dbus_assert (nb == 2); 01366 dbus_free_string_array (child_entries); 01367 } 01368 01369 _dbus_object_tree_list_registered_unlocked (tree, path8, &child_entries); 01370 <font class="keywordflow">if</font> (child_entries != NULL) 01371 { 01372 nb = string_array_length (child_entries); 01373 _dbus_assert (nb == 0); 01374 dbus_free_string_array (child_entries); 01375 } 01376 01377 _dbus_object_tree_list_registered_unlocked (tree, root, &child_entries); 01378 <font class="keywordflow">if</font> (child_entries != NULL) 01379 { 01380 nb = string_array_length (child_entries); 01381 _dbus_assert (nb == 3); 01382 dbus_free_string_array (child_entries); 01383 } 01384 } 01385 01386 <font class="comment">/* Check that destroying tree calls unregister funcs */</font> 01387 _dbus_object_tree_unref (tree); 01388 01389 i = 0; 01390 <font class="keywordflow">while</font> (i < (int) _DBUS_N_ELEMENTS (tree_test_data)) 01391 { 01392 _dbus_assert (tree_test_data[i].handler_unregistered); 01393 _dbus_assert (!tree_test_data[i].message_handled); 01394 ++i; 01395 } 01396 01397 <font class="comment">/* Now start again and try the individual unregister function */</font> 01398 tree = _dbus_object_tree_new (NULL); 01399 <font class="keywordflow">if</font> (tree == NULL) 01400 <font class="keywordflow">goto</font> out; 01401 01402 <font class="keywordflow">if</font> (!do_register (tree, path1, TRUE, 0, tree_test_data)) 01403 <font class="keywordflow">goto</font> out; 01404 <font class="keywordflow">if</font> (!do_register (tree, path2, TRUE, 1, tree_test_data)) 01405 <font class="keywordflow">goto</font> out; 01406 <font class="keywordflow">if</font> (!do_register (tree, path3, TRUE, 2, tree_test_data)) 01407 <font class="keywordflow">goto</font> out; 01408 <font class="keywordflow">if</font> (!do_register (tree, path4, TRUE, 3, tree_test_data)) 01409 <font class="keywordflow">goto</font> out; 01410 <font class="keywordflow">if</font> (!do_register (tree, path5, TRUE, 4, tree_test_data)) 01411 <font class="keywordflow">goto</font> out; 01412 <font class="keywordflow">if</font> (!do_register (tree, path6, TRUE, 5, tree_test_data)) 01413 <font class="keywordflow">goto</font> out; 01414 <font class="keywordflow">if</font> (!do_register (tree, path7, TRUE, 6, tree_test_data)) 01415 <font class="keywordflow">goto</font> out; 01416 <font class="keywordflow">if</font> (!do_register (tree, path8, TRUE, 7, tree_test_data)) 01417 <font class="keywordflow">goto</font> out; 01418 01419 _dbus_object_tree_unregister_and_unlock (tree, path1); 01420 01421 _dbus_assert (!find_subtree (tree, path1, NULL)); 01422 _dbus_assert (find_subtree (tree, path2, NULL)); 01423 _dbus_assert (find_subtree (tree, path3, NULL)); 01424 _dbus_assert (find_subtree (tree, path4, NULL)); 01425 _dbus_assert (find_subtree (tree, path5, NULL)); 01426 _dbus_assert (find_subtree (tree, path6, NULL)); 01427 _dbus_assert (find_subtree (tree, path7, NULL)); 01428 _dbus_assert (find_subtree (tree, path8, NULL)); 01429 01430 _dbus_object_tree_unregister_and_unlock (tree, path2); 01431 01432 _dbus_assert (!find_subtree (tree, path1, NULL)); 01433 _dbus_assert (!find_subtree (tree, path2, NULL)); 01434 _dbus_assert (find_subtree (tree, path3, NULL)); 01435 _dbus_assert (find_subtree (tree, path4, NULL)); 01436 _dbus_assert (find_subtree (tree, path5, NULL)); 01437 _dbus_assert (find_subtree (tree, path6, NULL)); 01438 _dbus_assert (find_subtree (tree, path7, NULL)); 01439 _dbus_assert (find_subtree (tree, path8, NULL)); 01440 01441 _dbus_object_tree_unregister_and_unlock (tree, path3); 01442 01443 _dbus_assert (!find_subtree (tree, path1, NULL)); 01444 _dbus_assert (!find_subtree (tree, path2, NULL)); 01445 _dbus_assert (!find_subtree (tree, path3, NULL)); 01446 _dbus_assert (find_subtree (tree, path4, NULL)); 01447 _dbus_assert (find_subtree (tree, path5, NULL)); 01448 _dbus_assert (find_subtree (tree, path6, NULL)); 01449 _dbus_assert (find_subtree (tree, path7, NULL)); 01450 _dbus_assert (find_subtree (tree, path8, NULL)); 01451 01452 _dbus_object_tree_unregister_and_unlock (tree, path4); 01453 01454 _dbus_assert (!find_subtree (tree, path1, NULL)); 01455 _dbus_assert (!find_subtree (tree, path2, NULL)); 01456 _dbus_assert (!find_subtree (tree, path3, NULL)); 01457 _dbus_assert (!find_subtree (tree, path4, NULL)); 01458 _dbus_assert (find_subtree (tree, path5, NULL)); 01459 _dbus_assert (find_subtree (tree, path6, NULL)); 01460 _dbus_assert (find_subtree (tree, path7, NULL)); 01461 _dbus_assert (find_subtree (tree, path8, NULL)); 01462 01463 _dbus_object_tree_unregister_and_unlock (tree, path5); 01464 01465 _dbus_assert (!find_subtree (tree, path1, NULL)); 01466 _dbus_assert (!find_subtree (tree, path2, NULL)); 01467 _dbus_assert (!find_subtree (tree, path3, NULL)); 01468 _dbus_assert (!find_subtree (tree, path4, NULL)); 01469 _dbus_assert (!find_subtree (tree, path5, NULL)); 01470 _dbus_assert (find_subtree (tree, path6, NULL)); 01471 _dbus_assert (find_subtree (tree, path7, NULL)); 01472 _dbus_assert (find_subtree (tree, path8, NULL)); 01473 01474 _dbus_object_tree_unregister_and_unlock (tree, path6); 01475 01476 _dbus_assert (!find_subtree (tree, path1, NULL)); 01477 _dbus_assert (!find_subtree (tree, path2, NULL)); 01478 _dbus_assert (!find_subtree (tree, path3, NULL)); 01479 _dbus_assert (!find_subtree (tree, path4, NULL)); 01480 _dbus_assert (!find_subtree (tree, path5, NULL)); 01481 _dbus_assert (!find_subtree (tree, path6, NULL)); 01482 _dbus_assert (find_subtree (tree, path7, NULL)); 01483 _dbus_assert (find_subtree (tree, path8, NULL)); 01484 01485 _dbus_object_tree_unregister_and_unlock (tree, path7); 01486 01487 _dbus_assert (!find_subtree (tree, path1, NULL)); 01488 _dbus_assert (!find_subtree (tree, path2, NULL)); 01489 _dbus_assert (!find_subtree (tree, path3, NULL)); 01490 _dbus_assert (!find_subtree (tree, path4, NULL)); 01491 _dbus_assert (!find_subtree (tree, path5, NULL)); 01492 _dbus_assert (!find_subtree (tree, path6, NULL)); 01493 _dbus_assert (!find_subtree (tree, path7, NULL)); 01494 _dbus_assert (find_subtree (tree, path8, NULL)); 01495 01496 _dbus_object_tree_unregister_and_unlock (tree, path8); 01497 01498 _dbus_assert (!find_subtree (tree, path1, NULL)); 01499 _dbus_assert (!find_subtree (tree, path2, NULL)); 01500 _dbus_assert (!find_subtree (tree, path3, NULL)); 01501 _dbus_assert (!find_subtree (tree, path4, NULL)); 01502 _dbus_assert (!find_subtree (tree, path5, NULL)); 01503 _dbus_assert (!find_subtree (tree, path6, NULL)); 01504 _dbus_assert (!find_subtree (tree, path7, NULL)); 01505 _dbus_assert (!find_subtree (tree, path8, NULL)); 01506 01507 i = 0; 01508 <font class="keywordflow">while</font> (i < (int) _DBUS_N_ELEMENTS (tree_test_data)) 01509 { 01510 _dbus_assert (tree_test_data[i].handler_unregistered); 01511 _dbus_assert (!tree_test_data[i].message_handled); 01512 ++i; 01513 } 01514 01515 <font class="comment">/* Register it all again, and test dispatch */</font> 01516 01517 <font class="keywordflow">if</font> (!do_register (tree, path1, FALSE, 0, tree_test_data)) 01518 <font class="keywordflow">goto</font> out; 01519 <font class="keywordflow">if</font> (!do_register (tree, path2, TRUE, 1, tree_test_data)) 01520 <font class="keywordflow">goto</font> out; 01521 <font class="keywordflow">if</font> (!do_register (tree, path3, TRUE, 2, tree_test_data)) 01522 <font class="keywordflow">goto</font> out; 01523 <font class="keywordflow">if</font> (!do_register (tree, path4, TRUE, 3, tree_test_data)) 01524 <font class="keywordflow">goto</font> out; 01525 <font class="keywordflow">if</font> (!do_register (tree, path5, TRUE, 4, tree_test_data)) 01526 <font class="keywordflow">goto</font> out; 01527 <font class="keywordflow">if</font> (!do_register (tree, path6, FALSE, 5, tree_test_data)) 01528 <font class="keywordflow">goto</font> out; 01529 <font class="keywordflow">if</font> (!do_register (tree, path7, TRUE, 6, tree_test_data)) 01530 <font class="keywordflow">goto</font> out; 01531 <font class="keywordflow">if</font> (!do_register (tree, path8, TRUE, 7, tree_test_data)) 01532 <font class="keywordflow">goto</font> out; 01533 01534 <font class="preprocessor">#if 0</font> 01535 <font class="preprocessor"></font> spew_tree (tree); 01536 <font class="preprocessor">#endif</font> 01537 <font class="preprocessor"></font> 01538 <font class="keywordflow">if</font> (!do_test_dispatch (tree, path1, 0, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) 01539 <font class="keywordflow">goto</font> out; 01540 <font class="keywordflow">if</font> (!do_test_dispatch (tree, path2, 1, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) 01541 <font class="keywordflow">goto</font> out; 01542 <font class="keywordflow">if</font> (!do_test_dispatch (tree, path3, 2, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) 01543 <font class="keywordflow">goto</font> out; 01544 <font class="keywordflow">if</font> (!do_test_dispatch (tree, path4, 3, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) 01545 <font class="keywordflow">goto</font> out; 01546 <font class="keywordflow">if</font> (!do_test_dispatch (tree, path5, 4, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) 01547 <font class="keywordflow">goto</font> out; 01548 <font class="keywordflow">if</font> (!do_test_dispatch (tree, path6, 5, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) 01549 <font class="keywordflow">goto</font> out; 01550 <font class="keywordflow">if</font> (!do_test_dispatch (tree, path7, 6, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) 01551 <font class="keywordflow">goto</font> out; 01552 <font class="keywordflow">if</font> (!do_test_dispatch (tree, path8, 7, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) 01553 <font class="keywordflow">goto</font> out; 01554 01555 out: 01556 <font class="keywordflow">if</font> (tree) 01557 { 01558 <font class="comment">/* test ref */</font> 01559 _dbus_object_tree_ref (tree); 01560 _dbus_object_tree_unref (tree); 01561 _dbus_object_tree_unref (tree); 01562 } 01563 01564 <font class="keywordflow">return</font> TRUE; 01565 } 01566 01572 dbus_bool_t <a name="l01573"></a><a class="code" href="group__DBusObjectTree.html#a24">01573</a> _dbus_object_tree_test (<font class="keywordtype">void</font>) 01574 { 01575 _dbus_test_oom_handling (<font class="stringliteral">"object tree"</font>, 01576 object_tree_test_iteration, 01577 NULL); 01578 01579 <font class="keywordflow">return</font> TRUE; 01580 } 01581 01582 <font class="preprocessor">#endif </font><font class="comment">/* DBUS_BUILD_TESTS */</font> </pre></div><hr><address align="right"><small>Generated on Wed Jun 9 05:01:26 2004 for D-BUS by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border=0 width=110 height=53></a>1.2.15 </small></address> </body> </html>