AddMatch pattern for integers
User story
Some reviewers of #171 wanted it to use opaque integers, instead of opaque object paths, to identify an object.
Description
If we want to support users of D-Bus using opaque integers to identify a resource, then it should be possible to match that resource by its opaque integer value in signal arguments. For example, if this interface exists:
CreateThing(...) -> (t: opaque_id)
signal ThingUpdated(t: opaque_id, a{sv}: info)
then it should be possible for a caller of CreateThing(...) -> 42
to match ThingUpdated(42, {...})
without needing to watch for every signal affecting any other Thing.
We can do this for strings with arg0
and object paths with arg0path
, but we can't currently do this for integers.
If this functionality is important to someone, I'd be happy to review a merge request that adds this to the spec and the reference implementation. I don't intend to implement this myself; consider this to be an experiment in crowdsourcing minor feature implementations.
I do not intend to change the Containers interface (#171) to use opaque integers (#210 (closed)) unless someone steps forward in the next few weeks to say that they will be implementing this, and then follows through with spec wording and a reference implementation.
Proposed spec
A straw-man spec for this:
Callers of AddMatch
can specify a match rule with arg0int
, ..., analogous to arg0path
, for example arg0int=0,arg1int=-1,arg2int="42"
.
The pattern must be written in ASCII decimal in a canonical form: either 0
, or a strictly positive integer with no leading zeroes and an optional -
sign prefix. 0x1
, 0755
, -0
, 1e+5
are not valid patterns.
If the pattern has too many digits to be representable in D-Bus' largest types (currently signed and unsigned 64-bit), the implementation may either return an error from AddMatch
, or treat it as a pattern that does not match any messages.
These patterns can match any integer argument (types bynqiuxt
) in the corresponding position. Other types (including d
, h
, all string-like types and all containers) never match this pattern. For the purposes of matching this pattern, b
is treated as an integer in the range 0 to 1 inclusive, and y
is treated as an integer in the range 0 to 255 inclusive.
Messages are matched against the pattern as if by converting both the pattern and the argument to an arbitrarily large signed integer type and comparing their values, or equivalently, as if by writing both the pattern and the argument in the same canonical ASCII form and comparing their string values. Production-quality implementations are encouraged to use a more efficient implementation than either of these, but it must give the same results. In particular, there is no wrap-around: a pattern arg0int=-1
does not match a uint16 argument with value 65535.
(A different spec would be fine, if documented clearly and with a rationale given.)
Proposed implementation
Store the pattern as { dbus_uint64_t value; dbus_bool_t negative; }
, where value
is (dbus_uint64_t) actual_value
in the case of negative numbers, or as sign-and-magnitude, or something similar.
Acceptance
-
Reference implementation can match integer arguments in messages against a pattern -
How these match rules work is documented in dbus-specification.xml
-
Matching any message against any pattern has a single unambiguous correct result defined by the spec -
The reference implementation matches strictly: -
Patterns match exactly those messages that the spec says they should match (no non-determinism, aliasing, etc.) -
Only patterns that match the definition in the spec are accepted, all others cause AddMatch
to fail
-
-
Automated tests covering at least: positive, negative, zero, matching booleans, not matching other types, quoting being optional, rejecting invalid patterns -
Code review -
Merge to development git branch
Out of scope
- Type
d
(double) - Type
h
(the actual numeric value is an implementation detail) - Comparing other than for equality (
<
,>
,!=
, bitmasks, etc.)