diff options
Diffstat (limited to 'dbus/dbus-objectid.c')
-rw-r--r-- | dbus/dbus-objectid.c | 288 |
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; } |