2003-07-12 Havoc Pennington <hp@pobox.com>
[platform/upstream/dbus.git] / dbus / dbus-objectid.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-objectid.c  DBusObjectID type
3  *
4  * Copyright (C) 2003  Red Hat Inc.
5  *
6  * Licensed under the Academic Free License version 1.2
7  * 
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  * 
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  *
22  */
23
24 #include "dbus-objectid.h"
25 #include "dbus-internals.h"
26
27 #ifdef DBUS_HAVE_INT64
28 #define VALUE(objid) ((objid)->dbus_do_not_use_dummy1)
29 #define HIGH_BITS(objid) ((dbus_uint32_t) (VALUE (obj_id) >> 32))
30 #define LOW_BITS(objid)  ((dbus_uint32_t) (VALUE (obj_id) & DBUS_UINT64_CONSTANT (0x00000000ffffffff)))
31 #else
32 #define HIGH_BITS(objid) ((objid)->dbus_do_not_use_dummy1)
33 #define LOW_BITS(objid) ((objid)->dbus_do_not_use_dummy2)
34 #endif
35
36 /**
37  * @defgroup DBusObjectID object IDs
38  * @ingroup  DBusObjectID
39  * @brief object ID datatype
40  *
41  * Value type representing an object ID, i.e. an object in the remote
42  * application that can be communicated with.
43  *
44  * @{
45  */
46
47 /**
48  * Checks whether two object IDs have the same value.
49  *
50  * @param a the first object ID
51  * @param b the second object ID
52  * @returns #TRUE if they are equal
53  */
54 dbus_bool_t
55 dbus_object_id_equal (const DBusObjectID *a,
56                       const DBusObjectID *b)
57 {
58 #ifdef DBUS_HAVE_INT64
59   return VALUE (a) == VALUE (b);
60 #else
61   return HIGH_BITS (a) == HIGH_BITS (b) &&
62     LOW_BITS (a) == LOW_BITS (b);
63 #endif
64 }
65
66 /**
67  * Compares two object IDs, appropriate for
68  * qsort(). Higher/lower IDs have no significance,
69  * but the comparison can be used for data structures
70  * that require ordering.
71  *
72  * @param a the first object ID
73  * @param b the second object ID
74  * @returns -1, 0, 1 as with strcmp()
75  */
76 int
77 dbus_object_id_compare (const DBusObjectID *a,
78                         const DBusObjectID *b)
79 {
80 #ifdef DBUS_HAVE_INT64
81   if (VALUE (a) > VALUE (b))
82     return 1;
83   else if (VALUE (a) < VALUE (b))
84     return -1;
85   else
86     return 0;
87 #else
88   if (HIGH_BITS (a) > HIGH_BITS (b))
89     return 1;
90   else if (HIGH_BITS (a) < HIGH_BITS (b))
91     return -1;
92   else if (LOW_BITS (a) > LOW_BITS (b))
93     return 1;
94   else if (LOW_BITS (a) < LOW_BITS (b))
95     return -1;
96   else
97     return 0;
98 #endif
99 }
100
101 /**
102  * An object ID contains 64 bits of data. This function
103  * returns half of those bits. If you are willing to limit
104  * portability to compilers with a 64-bit type (this includes
105  * C99 compilers and almost all other compilers) consider
106  * dbus_object_id_get_as_integer() instead.
107  *
108  * @param obj_id the object ID
109  * @returns the high bits of the ID
110  * 
111  */
112 dbus_uint32_t
113 dbus_object_id_get_high_bits (const DBusObjectID *obj_id)
114 {
115   return HIGH_BITS (obj_id);
116 }
117
118 /**
119  * An object ID contains 64 bits of data. This function
120  * returns half of those bits. If you are willing to limit
121  * portability to compilers with a 64-bit type (this includes
122  * C99 compilers and almost all other compilers) consider
123  * dbus_object_id_get_as_integer() instead.
124  *
125  * @param obj_id the object ID
126  * @returns the low bits of the ID
127  * 
128  */
129 dbus_uint32_t
130 dbus_object_id_get_low_bits (const DBusObjectID *obj_id)
131 {
132   return LOW_BITS (obj_id);
133 }
134
135 /**
136  * An object ID contains 64 bits of data. This function
137  * sets half of those bits. If you are willing to limit
138  * portability to compilers with a 64-bit type (this includes
139  * C99 compilers and almost all other compilers) consider
140  * dbus_object_id_set_as_integer() instead.
141  *
142  * @param obj_id the object ID
143  * @param value the new value of the high bits
144  * 
145  */
146 void
147 dbus_object_id_set_high_bits (DBusObjectID       *obj_id,
148                               dbus_uint32_t       value)
149 {
150 #ifdef DBUS_HAVE_INT64
151   VALUE (obj_id) = (((dbus_uint64_t) value) << 32) | LOW_BITS (obj_id);
152 #else
153   HIGH_BITS (obj_id) = value;
154 #endif
155 }
156
157 /**
158  * An object ID contains 64 bits of data. This function
159  * sets half of those bits. If you are willing to limit
160  * portability to compilers with a 64-bit type (this includes
161  * C99 compilers and almost all other compilers) consider
162  * dbus_object_id_set_as_integer() instead.
163  *
164  * @param obj_id the object ID
165  * @param value the new value of the low bits
166  * 
167  */
168 void
169 dbus_object_id_set_low_bits (DBusObjectID       *obj_id,
170                              dbus_uint32_t       value)
171 {
172 #ifdef DBUS_HAVE_INT64
173   VALUE (obj_id) = ((dbus_uint64_t) value) |
174     (((dbus_uint64_t) HIGH_BITS (obj_id)) << 32);
175 #else
176   LOW_BITS (obj_id) = value;
177 #endif
178 }
179
180 /**
181  * Set the object ID to an invalid value that cannot
182  * correspond to a valid object.
183  *
184  * @param obj_id the object ID
185  */
186 void
187 dbus_object_id_set_null (DBusObjectID *obj_id)
188 {
189   memset (obj_id, '\0', sizeof (DBusObjectID));
190 }
191
192 /**
193  * Check whether the object ID is set to a null value
194  *
195  * @param obj_id the object ID
196  * @returns #TRUE if null
197  */
198 dbus_bool_t
199 dbus_object_id_is_null (const DBusObjectID *obj_id)
200 {
201 #ifdef DBUS_HAVE_INT64
202   return VALUE (obj_id) == 0;
203 #else
204   return HIGH_BITS (obj_id) == 0 && LOW_BITS (obj_id) == 0;
205 #endif
206 }
207
208 #ifdef DBUS_HAVE_INT64
209 /**
210  * An object ID contains 64 bits of data. This function
211  * returns all of them as a 64-bit integer.
212  *  
213  * Use this function only if you are willing to limit portability to
214  * compilers with a 64-bit type (this includes C99 compilers and
215  * almost all other compilers).
216  *
217  * This function only exists if DBUS_HAVE_INT64 is defined.
218  *
219  * @param obj_id the object ID
220  * @returns the object ID as a 64-bit integer.
221  */
222 dbus_uint64_t
223 dbus_object_id_get_as_integer (const DBusObjectID *obj_id)
224 {
225   return VALUE (obj_id);
226 }
227
228 /**
229  * An object ID contains 64 bits of data. This function sets all of
230  * them as a 64-bit integer.
231  *  
232  * Use this function only if you are willing to limit portability to
233  * compilers with a 64-bit type (this includes C99 compilers and
234  * almost all other compilers).
235  * 
236  * This function only exists if #DBUS_HAVE_INT64 is defined.
237  *
238  * @param obj_id the object ID
239  * @param value the new value of the object ID
240  */
241 void
242 dbus_object_id_set_as_integer (DBusObjectID       *obj_id,
243                                dbus_uint64_t       value)
244 {
245   VALUE (obj_id) = value;
246 }
247 #endif /* DBUS_HAVE_INT64 */
248
249 /** @} */
250
251 #ifdef DBUS_BUILD_TESTS
252 #include "dbus-test.h"
253 #include <stdio.h>
254
255 /**
256  * Test for object ID routines.
257  *
258  * @returns #TRUE on success
259  */
260 dbus_bool_t
261 _dbus_object_id_test (void)
262 {
263   DBusObjectID tmp;
264   DBusObjectID tmp2;
265
266   dbus_object_id_set_high_bits (&tmp, 340);
267   _dbus_assert (dbus_object_id_get_high_bits (&tmp) == 340);
268
269   dbus_object_id_set_low_bits (&tmp, 1492);
270   _dbus_assert (dbus_object_id_get_low_bits (&tmp) == 1492);
271   _dbus_assert (dbus_object_id_get_high_bits (&tmp) == 340);
272   
273   tmp2 = tmp;
274   _dbus_assert (dbus_object_id_equal (&tmp, &tmp2));
275   
276 #ifdef DBUS_HAVE_INT64
277   _dbus_assert (dbus_object_id_get_as_integer (&tmp) ==
278                 ((DBUS_UINT64_CONSTANT (340) << 32) |
279                  DBUS_UINT64_CONSTANT (1492)));
280
281   dbus_object_id_set_as_integer (&tmp, _DBUS_UINT64_MAX);
282   _dbus_assert (dbus_object_id_get_as_integer (&tmp) ==
283                 _DBUS_UINT64_MAX);
284   _dbus_assert (dbus_object_id_get_high_bits (&tmp) ==
285                 _DBUS_UINT_MAX);
286   _dbus_assert (dbus_object_id_get_low_bits (&tmp) ==
287                 _DBUS_UINT_MAX);
288
289   dbus_object_id_set_as_integer (&tmp, 1);
290   dbus_object_id_set_as_integer (&tmp2, 2);
291   _dbus_assert (dbus_object_id_compare (&tmp, &tmp2) == -1);
292   dbus_object_id_set_as_integer (&tmp2, 0);
293   _dbus_assert (dbus_object_id_compare (&tmp, &tmp2) == 1);
294   dbus_object_id_set_as_integer (&tmp2, 1);
295   _dbus_assert (dbus_object_id_compare (&tmp, &tmp2) == 0);
296 #endif
297
298   tmp2 = tmp;
299   
300   dbus_object_id_set_high_bits (&tmp, 1);
301   dbus_object_id_set_high_bits (&tmp2, 2);
302   _dbus_assert (dbus_object_id_compare (&tmp, &tmp2) == -1);
303   dbus_object_id_set_high_bits (&tmp2, 0);
304   _dbus_assert (dbus_object_id_compare (&tmp, &tmp2) == 1);
305   dbus_object_id_set_high_bits (&tmp2, 1);
306   _dbus_assert (dbus_object_id_compare (&tmp, &tmp2) == 0);
307
308   dbus_object_id_set_low_bits (&tmp, 1);
309   
310   dbus_object_id_set_low_bits (&tmp2, 2);
311   _dbus_assert (dbus_object_id_compare (&tmp, &tmp2) == -1);
312   dbus_object_id_set_low_bits (&tmp2, 0);
313   _dbus_assert (dbus_object_id_compare (&tmp, &tmp2) == 1);
314   dbus_object_id_set_low_bits (&tmp2, 1);
315   _dbus_assert (dbus_object_id_compare (&tmp, &tmp2) == 0);
316   
317   return TRUE;
318 }
319
320 #endif /* DBUS_BUILD_TESTS */