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;  }  | 
