summaryrefslogtreecommitdiffstats
path: root/dbus/dbus-objectid.c
diff options
context:
space:
mode:
Diffstat (limited to 'dbus/dbus-objectid.c')
-rw-r--r--dbus/dbus-objectid.c288
1 files changed, 219 insertions, 69 deletions
diff --git a/dbus/dbus-objectid.c b/dbus/dbus-objectid.c
index 55ae0d48..f2b27b61 100644
--- a/dbus/dbus-objectid.c
+++ b/dbus/dbus-objectid.c
@@ -25,12 +25,34 @@
#include "dbus-internals.h"
#ifdef DBUS_HAVE_INT64
-#define VALUE(objid) ((objid)->dbus_do_not_use_dummy1)
-#define HIGH_BITS(objid) ((dbus_uint32_t) (VALUE (obj_id) >> 32))
-#define LOW_BITS(objid) ((dbus_uint32_t) (VALUE (obj_id) & DBUS_UINT64_CONSTANT (0x00000000ffffffff)))
+#define VALUE(objid) ((objid)->dbus_do_not_use_dummy1)
+#define SERVER_MASK DBUS_UINT64_CONSTANT (0xffff000000000000)
+#define CLIENT_MASK DBUS_UINT64_CONSTANT (0x0000ffff00000000)
+#define IS_SERVER_MASK DBUS_UINT64_CONSTANT (0x0000000080000000)
+#define INSTANCE_MASK DBUS_UINT64_CONSTANT (0x000000007fffffff)
+#define SERVER_BITS(objid) ((dbus_uint16_t) (VALUE (obj_id) >> 48))
+#define CLIENT_BITS(objid) ((dbus_uint16_t) ((VALUE (obj_id) & CLIENT_MASK) >> 32))
+#define IS_SERVER_BIT(objid) ((VALUE (obj_id) & IS_SERVER_MASK) != 0)
+#define INSTANCE_BITS(objid) ((dbus_uint32_t) (VALUE (obj_id) & INSTANCE_MASK))
#else
-#define HIGH_BITS(objid) ((objid)->dbus_do_not_use_dummy1)
-#define LOW_BITS(objid) ((objid)->dbus_do_not_use_dummy2)
+/* We care about the exact packing since in dbus-marshal.c we
+ * just use the DBusObjectID struct as-is.
+ */
+#ifdef WORDS_BIGENDIAN
+#define HIGH_VALUE(objid) ((objid)->dbus_do_not_use_dummy2)
+#define LOW_VALUE(objid) ((objid)->dbus_do_not_use_dummy3)
+#else
+#define HIGH_VALUE(objid) ((objid)->dbus_do_not_use_dummy3)
+#define LOW_VALUE(objid) ((objid)->dbus_do_not_use_dummy2)
+#endif
+#define SERVER_MASK (0xffff0000)
+#define CLIENT_MASK (0x0000ffff)
+#define IS_SERVER_MASK (0x80000000)
+#define INSTANCE_MASK (0x7fffffff)
+#define SERVER_BITS(objid) ((HIGH_VALUE (objid) & SERVER_MASK) >> 16)
+#define CLIENT_BITS(objid) (HIGH_VALUE (objid) & CLIENT_MASK)
+#define IS_SERVER_BIT(objid) ((LOW_VALUE (objid) & IS_SERVER_MASK) != 0)
+#define INSTANCE_BITS(objid) (LOW_VALUE (objid) & INSTANCE_MASK)
#endif
/**
@@ -41,6 +63,20 @@
* Value type representing an object ID, i.e. an object in the remote
* application that can be communicated with.
*
+ * An object ID has three parts. 16 bits are provided by the server
+ * side of a connection, and used for the high 16 bits of all object
+ * IDs created by the client. 16 bits are provided by the client side
+ * and used as the next 16 bits of all object IDs created by the
+ * client. The next single bit is 1 if the object ID represents an
+ * object on the server side of the connection and 0 otherwise. Then
+ * 31 bits are provided by the side creating an object instance and
+ * differ for each instance created (each app should make a best
+ * effort to avoid recycling the instance values).
+ *
+ * 0 is an invalid value for the server bits, the client bits,
+ * and the object instance bits. An object ID is the null ID
+ * if all 64 bits are 0.
+ *
* @{
*/
@@ -58,8 +94,7 @@ dbus_object_id_equal (const DBusObjectID *a,
#ifdef DBUS_HAVE_INT64
return VALUE (a) == VALUE (b);
#else
- return HIGH_BITS (a) == HIGH_BITS (b) &&
- LOW_BITS (a) == LOW_BITS (b);
+ return LOW_VALUE (a) == LOW_VALUE (b) && HIGH_VALUE (a) == HIGH_VALUE (b);
#endif
}
@@ -85,95 +120,168 @@ dbus_object_id_compare (const DBusObjectID *a,
else
return 0;
#else
- if (HIGH_BITS (a) > HIGH_BITS (b))
+ if (HIGH_VALUE (a) > HIGH_VALUE (b))
return 1;
- else if (HIGH_BITS (a) < HIGH_BITS (b))
+ else if (HIGH_VALUE (a) < HIGH_VALUE (b))
return -1;
- else if (LOW_BITS (a) > LOW_BITS (b))
+ else if (LOW_VALUE (a) > LOW_VALUE (b))
return 1;
- else if (LOW_BITS (a) < LOW_BITS (b))
+ else if (LOW_VALUE (a) < LOW_VALUE (b))
return -1;
else
return 0;
#endif
}
+
/**
* An object ID contains 64 bits of data. This function
- * returns half of those bits. If you are willing to limit
- * portability to compilers with a 64-bit type (this includes
- * C99 compilers and almost all other compilers) consider
- * dbus_object_id_get_as_integer() instead.
+ * returns the 16 bits that were provided by the server
+ * side of the connection.
*
* @param obj_id the object ID
- * @returns the high bits of the ID
+ * @returns the server bits of the ID
*
*/
-dbus_uint32_t
-dbus_object_id_get_high_bits (const DBusObjectID *obj_id)
+dbus_uint16_t
+dbus_object_id_get_server_bits (const DBusObjectID *obj_id)
{
- return HIGH_BITS (obj_id);
+ return SERVER_BITS (obj_id);
}
/**
* An object ID contains 64 bits of data. This function
- * returns half of those bits. If you are willing to limit
- * portability to compilers with a 64-bit type (this includes
- * C99 compilers and almost all other compilers) consider
- * dbus_object_id_get_as_integer() instead.
+ * returns the 16 bits that were provided by the client
+ * side of the connection.
*
* @param obj_id the object ID
- * @returns the low bits of the ID
+ * @returns the client bits of the ID
*
*/
-dbus_uint32_t
-dbus_object_id_get_low_bits (const DBusObjectID *obj_id)
+dbus_uint16_t
+dbus_object_id_get_client_bits (const DBusObjectID *obj_id)
+{
+ return CLIENT_BITS (obj_id);
+}
+
+/**
+ * An object ID contains 64 bits of data. This function
+ * returns the bit flagging whether the object ID comes
+ * from the client or the server side of the connection.
+ *
+ * There is no secure guarantee that the bit is accurate;
+ * object ID values are simply conventional, to make
+ * collisions relatively unlikely.
+ *
+ * @param obj_id the object ID
+ * @returns the server-side bit of the ID
+ *
+ */
+dbus_bool_t
+dbus_object_id_get_is_server_bit (const DBusObjectID *obj_id)
{
- return LOW_BITS (obj_id);
+ return IS_SERVER_BIT (obj_id);
}
/**
* An object ID contains 64 bits of data. This function
- * sets half of those bits. If you are willing to limit
- * portability to compilers with a 64-bit type (this includes
- * C99 compilers and almost all other compilers) consider
- * dbus_object_id_set_as_integer() instead.
+ * returns the 31 bits that identify the object instance.
*
* @param obj_id the object ID
- * @param value the new value of the high bits
+ * @returns the instance bits of the ID
+ *
+ */
+dbus_uint32_t
+dbus_object_id_get_instance_bits (const DBusObjectID *obj_id)
+{
+ return INSTANCE_BITS (obj_id);
+}
+
+/**
+ * An object ID contains 64 bits of data. This function sets the 16
+ * bits provided by the server side of a connection.
+ *
+ * @param obj_id the object ID
+ * @param value the new value of the server bits
*
*/
void
-dbus_object_id_set_high_bits (DBusObjectID *obj_id,
- dbus_uint32_t value)
+dbus_object_id_set_server_bits (DBusObjectID *obj_id,
+ dbus_uint16_t value)
{
#ifdef DBUS_HAVE_INT64
- VALUE (obj_id) = (((dbus_uint64_t) value) << 32) | LOW_BITS (obj_id);
+ VALUE (obj_id) &= ~ SERVER_MASK;
+ VALUE (obj_id) |= ((dbus_uint64_t) value) << 48;
#else
- HIGH_BITS (obj_id) = value;
+ HIGH_VALUE (obj_id) &= ~ SERVER_MASK;
+ HIGH_VALUE (obj_id) |= ((dbus_uint32_t) value) << 16;
#endif
}
/**
- * An object ID contains 64 bits of data. This function
- * sets half of those bits. If you are willing to limit
- * portability to compilers with a 64-bit type (this includes
- * C99 compilers and almost all other compilers) consider
- * dbus_object_id_set_as_integer() instead.
+ * An object ID contains 64 bits of data. This function sets the 16
+ * bits provided by the client side of a connection.
*
* @param obj_id the object ID
- * @param value the new value of the low bits
+ * @param value the new value of the client bits
*
*/
void
-dbus_object_id_set_low_bits (DBusObjectID *obj_id,
- dbus_uint32_t value)
+dbus_object_id_set_client_bits (DBusObjectID *obj_id,
+ dbus_uint16_t value)
{
#ifdef DBUS_HAVE_INT64
- VALUE (obj_id) = ((dbus_uint64_t) value) |
- (((dbus_uint64_t) HIGH_BITS (obj_id)) << 32);
+ VALUE (obj_id) &= ~ CLIENT_MASK;
+ VALUE (obj_id) |= ((dbus_uint64_t) value) << 32;
#else
- LOW_BITS (obj_id) = value;
+ HIGH_VALUE (obj_id) &= ~ CLIENT_MASK;
+ HIGH_VALUE (obj_id) |= (dbus_uint32_t) value;
+#endif
+}
+
+/**
+ * An object ID contains 64 bits of data. This function sets the
+ * single bit that flags an instance as server-side or client-side.
+ *
+ * @param obj_id the object ID
+ * @param value the new value of the server-side bit
+ *
+ */
+void
+dbus_object_id_set_is_server_bit (DBusObjectID *obj_id,
+ dbus_bool_t value)
+{
+#ifdef DBUS_HAVE_INT64
+ if (value)
+ VALUE (obj_id) |= IS_SERVER_MASK;
+ else
+ VALUE (obj_id) &= ~ IS_SERVER_MASK;
+#else
+ if (value)
+ LOW_VALUE (obj_id) |= IS_SERVER_MASK;
+ else
+ LOW_VALUE (obj_id) &= ~ IS_SERVER_MASK;
+#endif
+}
+
+/**
+ * An object ID contains 64 bits of data. This function sets the 31
+ * bits identifying the object instance.
+ *
+ * @param obj_id the object ID
+ * @param value the new value of the instance bits
+ *
+ */
+void
+dbus_object_id_set_instance_bits (DBusObjectID *obj_id,
+ dbus_uint32_t value)
+{
+#ifdef DBUS_HAVE_INT64
+ VALUE (obj_id) &= ~ INSTANCE_MASK;
+ VALUE (obj_id) |= (dbus_uint64_t) value;
+#else
+ LOW_VALUE (obj_id) &= ~ INSTANCE_MASK;
+ LOW_VALUE (obj_id) |= (dbus_uint32_t) value;
#endif
}
@@ -201,7 +309,7 @@ dbus_object_id_is_null (const DBusObjectID *obj_id)
#ifdef DBUS_HAVE_INT64
return VALUE (obj_id) == 0;
#else
- return HIGH_BITS (obj_id) == 0 && LOW_BITS (obj_id) == 0;
+ return HIGH_VALUE (obj_id) == 0 && LOW_VALUE (obj_id) == 0;
#endif
}
@@ -263,28 +371,49 @@ _dbus_object_id_test (void)
DBusObjectID tmp;
DBusObjectID tmp2;
- dbus_object_id_set_high_bits (&tmp, 340);
- _dbus_assert (dbus_object_id_get_high_bits (&tmp) == 340);
-
- dbus_object_id_set_low_bits (&tmp, 1492);
- _dbus_assert (dbus_object_id_get_low_bits (&tmp) == 1492);
- _dbus_assert (dbus_object_id_get_high_bits (&tmp) == 340);
+ /* Check basic get/set */
+ dbus_object_id_set_server_bits (&tmp, 340);
+ _dbus_assert (dbus_object_id_get_server_bits (&tmp) == 340);
+
+ dbus_object_id_set_client_bits (&tmp, 1492);
+ _dbus_assert (dbus_object_id_get_client_bits (&tmp) == 1492);
+ _dbus_assert (dbus_object_id_get_server_bits (&tmp) == 340);
+
+ dbus_object_id_set_is_server_bit (&tmp, TRUE);
+ _dbus_assert (dbus_object_id_get_client_bits (&tmp) == 1492);
+ _dbus_assert (dbus_object_id_get_server_bits (&tmp) == 340);
+ _dbus_assert (dbus_object_id_get_is_server_bit (&tmp) == TRUE);
+
+ dbus_object_id_set_instance_bits (&tmp, 2001);
+ _dbus_assert (dbus_object_id_get_client_bits (&tmp) == 1492);
+ _dbus_assert (dbus_object_id_get_server_bits (&tmp) == 340);
+ _dbus_assert (dbus_object_id_get_is_server_bit (&tmp) == TRUE);
+ _dbus_assert (dbus_object_id_get_instance_bits (&tmp) == 2001);
+
+ /* check equality check */
tmp2 = tmp;
_dbus_assert (dbus_object_id_equal (&tmp, &tmp2));
-
+
+ /* check get/set as integer */
#ifdef DBUS_HAVE_INT64
_dbus_assert (dbus_object_id_get_as_integer (&tmp) ==
- ((DBUS_UINT64_CONSTANT (340) << 32) |
- DBUS_UINT64_CONSTANT (1492)));
+ ((DBUS_UINT64_CONSTANT (340) << 48) |
+ (DBUS_UINT64_CONSTANT (1492) << 32) |
+ (DBUS_UINT64_CONSTANT (1) << 31) |
+ (DBUS_UINT64_CONSTANT (2001))));
dbus_object_id_set_as_integer (&tmp, _DBUS_UINT64_MAX);
_dbus_assert (dbus_object_id_get_as_integer (&tmp) ==
_DBUS_UINT64_MAX);
- _dbus_assert (dbus_object_id_get_high_bits (&tmp) ==
- _DBUS_UINT_MAX);
- _dbus_assert (dbus_object_id_get_low_bits (&tmp) ==
- _DBUS_UINT_MAX);
+ _dbus_assert (dbus_object_id_get_server_bits (&tmp) ==
+ 0xffff);
+ _dbus_assert (dbus_object_id_get_client_bits (&tmp) ==
+ 0xffff);
+ _dbus_assert (dbus_object_id_get_is_server_bit (&tmp) ==
+ TRUE);
+ _dbus_assert (dbus_object_id_get_instance_bits (&tmp) ==
+ 0x7fffffff);
dbus_object_id_set_as_integer (&tmp, 1);
dbus_object_id_set_as_integer (&tmp2, 2);
@@ -295,24 +424,45 @@ _dbus_object_id_test (void)
_dbus_assert (dbus_object_id_compare (&tmp, &tmp2) == 0);
#endif
+ /* Check comparison */
tmp2 = tmp;
- dbus_object_id_set_high_bits (&tmp, 1);
- dbus_object_id_set_high_bits (&tmp2, 2);
+ dbus_object_id_set_server_bits (&tmp, 1);
+ dbus_object_id_set_server_bits (&tmp2, 2);
_dbus_assert (dbus_object_id_compare (&tmp, &tmp2) == -1);
- dbus_object_id_set_high_bits (&tmp2, 0);
+ dbus_object_id_set_server_bits (&tmp2, 0);
_dbus_assert (dbus_object_id_compare (&tmp, &tmp2) == 1);
- dbus_object_id_set_high_bits (&tmp2, 1);
+ dbus_object_id_set_server_bits (&tmp2, 1);
_dbus_assert (dbus_object_id_compare (&tmp, &tmp2) == 0);
- dbus_object_id_set_low_bits (&tmp, 1);
+ dbus_object_id_set_client_bits (&tmp, 1);
- dbus_object_id_set_low_bits (&tmp2, 2);
+ dbus_object_id_set_client_bits (&tmp2, 2);
_dbus_assert (dbus_object_id_compare (&tmp, &tmp2) == -1);
- dbus_object_id_set_low_bits (&tmp2, 0);
+ dbus_object_id_set_client_bits (&tmp2, 0);
_dbus_assert (dbus_object_id_compare (&tmp, &tmp2) == 1);
- dbus_object_id_set_low_bits (&tmp2, 1);
+ dbus_object_id_set_client_bits (&tmp2, 1);
_dbus_assert (dbus_object_id_compare (&tmp, &tmp2) == 0);
+
+ /* Check get/set again with high-limit numbers */
+
+ dbus_object_id_set_server_bits (&tmp, 0xf0f0);
+ _dbus_assert (dbus_object_id_get_server_bits (&tmp) == 0xf0f0);
+
+ dbus_object_id_set_client_bits (&tmp, 0xf00f);
+ _dbus_assert (dbus_object_id_get_client_bits (&tmp) == 0xf00f);
+ _dbus_assert (dbus_object_id_get_server_bits (&tmp) == 0xf0f0);
+
+ dbus_object_id_set_is_server_bit (&tmp, TRUE);
+ _dbus_assert (dbus_object_id_get_client_bits (&tmp) == 0xf00f);
+ _dbus_assert (dbus_object_id_get_server_bits (&tmp) == 0xf0f0);
+ _dbus_assert (dbus_object_id_get_is_server_bit (&tmp) == TRUE);
+
+ dbus_object_id_set_instance_bits (&tmp, 0x7fffffff);
+ _dbus_assert (dbus_object_id_get_client_bits (&tmp) == 0xf00f);
+ _dbus_assert (dbus_object_id_get_server_bits (&tmp) == 0xf0f0);
+ _dbus_assert (dbus_object_id_get_is_server_bit (&tmp) == TRUE);
+ _dbus_assert (dbus_object_id_get_instance_bits (&tmp) == 0x7fffffff);
return TRUE;
}