Merge pull request #17 from thaven/feature/object-path
Add support for DBus object path type
This commit is contained in:
commit
8410fc21a8
|
@ -14,6 +14,9 @@ void buildIter(TS...)(DBusMessageIter *iter, TS args) if(allCanDBus!TS) {
|
||||||
static if(is(T == string)) {
|
static if(is(T == string)) {
|
||||||
immutable(char)* cStr = arg.toStringz();
|
immutable(char)* cStr = arg.toStringz();
|
||||||
dbus_message_iter_append_basic(iter,typeCode!T,&cStr);
|
dbus_message_iter_append_basic(iter,typeCode!T,&cStr);
|
||||||
|
} else static if(is(T == ObjectPath)) {
|
||||||
|
immutable(char)* cStr = arg.toString().toStringz();
|
||||||
|
dbus_message_iter_append_basic(iter,typeCode!T,&cStr);
|
||||||
} else static if(is(T==bool)) {
|
} else static if(is(T==bool)) {
|
||||||
dbus_bool_t longerBool = arg; // dbus bools are ints
|
dbus_bool_t longerBool = arg; // dbus bools are ints
|
||||||
dbus_message_iter_append_basic(iter,typeCode!T,&longerBool);
|
dbus_message_iter_append_basic(iter,typeCode!T,&longerBool);
|
||||||
|
@ -71,6 +74,8 @@ void buildIter(TS...)(DBusMessageIter *iter, TS args) if(allCanDBus!TS) {
|
||||||
dbus_message_iter_open_container(iter, 'v', sig.ptr, sub);
|
dbus_message_iter_open_container(iter, 'v', sig.ptr, sub);
|
||||||
if(val.type == 's') {
|
if(val.type == 's') {
|
||||||
buildIter(sub, val.str);
|
buildIter(sub, val.str);
|
||||||
|
} else if(val.type == 'o') {
|
||||||
|
buildIter(sub, val.obj);
|
||||||
} else if(val.type == 'b') {
|
} else if(val.type == 'b') {
|
||||||
buildIter(sub,val.boolean);
|
buildIter(sub,val.boolean);
|
||||||
} else if(dbus_type_is_basic(val.type)) {
|
} else if(dbus_type_is_basic(val.type)) {
|
||||||
|
@ -136,10 +141,14 @@ T readIter(T)(DBusMessageIter *iter) if (canDBus!T) {
|
||||||
} else static if(!is(T == DBusAny) && !is(T == Variant!DBusAny)) {
|
} else static if(!is(T == DBusAny) && !is(T == Variant!DBusAny)) {
|
||||||
assert(dbus_message_iter_get_arg_type(iter) == typeCode!T());
|
assert(dbus_message_iter_get_arg_type(iter) == typeCode!T());
|
||||||
}
|
}
|
||||||
static if(is(T==string)) {
|
static if(is(T==string) || is(T==ObjectPath)) {
|
||||||
const(char)* cStr;
|
const(char)* cStr;
|
||||||
dbus_message_iter_get_basic(iter, &cStr);
|
dbus_message_iter_get_basic(iter, &cStr);
|
||||||
ret = cStr.fromStringz().idup; // copy string
|
string str = cStr.fromStringz().idup; // copy string
|
||||||
|
static if(is(T==string))
|
||||||
|
ret = str;
|
||||||
|
else
|
||||||
|
ret = ObjectPath(str);
|
||||||
} else static if(is(T==bool)) {
|
} else static if(is(T==bool)) {
|
||||||
dbus_bool_t longerBool;
|
dbus_bool_t longerBool;
|
||||||
dbus_message_iter_get_basic(iter, &longerBool);
|
dbus_message_iter_get_basic(iter, &longerBool);
|
||||||
|
@ -183,6 +192,9 @@ T readIter(T)(DBusMessageIter *iter) if (canDBus!T) {
|
||||||
if(ret.type == 's') {
|
if(ret.type == 's') {
|
||||||
ret.str = readIter!string(iter);
|
ret.str = readIter!string(iter);
|
||||||
return ret;
|
return ret;
|
||||||
|
} else if(ret.type == 'o') {
|
||||||
|
ret.obj = readIter!ObjectPath(iter);
|
||||||
|
return ret;
|
||||||
} else if(ret.type == 'b') {
|
} else if(ret.type == 'b') {
|
||||||
ret.boolean = readIter!bool(iter);
|
ret.boolean = readIter!bool(iter);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -30,6 +30,43 @@ T wrapErrors(T)(T delegate(DBusError *err) del) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ObjectPath {
|
||||||
|
private string _value;
|
||||||
|
|
||||||
|
this(string objPath) {
|
||||||
|
enforce(_isValid(objPath));
|
||||||
|
_value = objPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
string toString() const {
|
||||||
|
return _value;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t toHash() const pure nothrow @trusted {
|
||||||
|
return hashOf(_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool opEquals(ref const typeof(this) b) const pure nothrow @safe {
|
||||||
|
return _value == b._value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool _isValid(string objPath) {
|
||||||
|
import std.regex : matchFirst, ctRegex;
|
||||||
|
return cast(bool) objPath.matchFirst(ctRegex!("^((/[0-9A-Za-z_]+)+|/)$"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest {
|
||||||
|
import dunit.toolkit;
|
||||||
|
|
||||||
|
ObjectPath("some.invalid/object_path").assertThrow();
|
||||||
|
ObjectPath("/path/with/TrailingSlash/").assertThrow();
|
||||||
|
string path = "/org/freedesktop/DBus";
|
||||||
|
auto obj = ObjectPath(path);
|
||||||
|
obj.toString().assertEqual(path);
|
||||||
|
obj.toHash().assertEqual(path.hashOf);
|
||||||
|
}
|
||||||
|
|
||||||
/// Structure allowing typeless parameters
|
/// Structure allowing typeless parameters
|
||||||
struct DBusAny {
|
struct DBusAny {
|
||||||
/// DBus type of the value (never 'v'), see typeSig!T
|
/// DBus type of the value (never 'v'), see typeSig!T
|
||||||
|
@ -63,6 +100,8 @@ struct DBusAny {
|
||||||
///
|
///
|
||||||
bool boolean;
|
bool boolean;
|
||||||
///
|
///
|
||||||
|
ObjectPath obj;
|
||||||
|
///
|
||||||
DBusAny[] array;
|
DBusAny[] array;
|
||||||
///
|
///
|
||||||
DBusAny[] tuple;
|
DBusAny[] tuple;
|
||||||
|
@ -112,6 +151,9 @@ struct DBusAny {
|
||||||
} else static if(is(T == bool)) {
|
} else static if(is(T == bool)) {
|
||||||
this(typeCode!bool, null, false);
|
this(typeCode!bool, null, false);
|
||||||
boolean = cast(bool) value;
|
boolean = cast(bool) value;
|
||||||
|
} else static if(is(T == ObjectPath)) {
|
||||||
|
this(typeCode!ObjectPath, null, false);
|
||||||
|
obj = value;
|
||||||
} else static if(is(T == Variant!R, R)) {
|
} else static if(is(T == Variant!R, R)) {
|
||||||
static if(is(R == DBusAny)) {
|
static if(is(R == DBusAny)) {
|
||||||
type = value.data.type;
|
type = value.data.type;
|
||||||
|
@ -207,6 +249,9 @@ struct DBusAny {
|
||||||
case typeCode!string:
|
case typeCode!string:
|
||||||
valueStr = '"' ~ str ~ '"';
|
valueStr = '"' ~ str ~ '"';
|
||||||
break;
|
break;
|
||||||
|
case typeCode!ObjectPath:
|
||||||
|
valueStr = '"' ~ obj.to!string ~ '"';
|
||||||
|
break;
|
||||||
case typeCode!bool:
|
case typeCode!bool:
|
||||||
valueStr = boolean ? "true" : "false";
|
valueStr = boolean ? "true" : "false";
|
||||||
break;
|
break;
|
||||||
|
@ -285,6 +330,13 @@ struct DBusAny {
|
||||||
} else static if(isSomeString!T) {
|
} else static if(isSomeString!T) {
|
||||||
if(type == 's')
|
if(type == 's')
|
||||||
return str.to!T;
|
return str.to!T;
|
||||||
|
else if(type == 'o')
|
||||||
|
return obj.toString();
|
||||||
|
else
|
||||||
|
throw new Exception("Can't convert type " ~ cast(char) type ~ " to " ~ T.stringof);
|
||||||
|
} else static if(is(T == ObjectPath)) {
|
||||||
|
if(type == 'o')
|
||||||
|
return obj;
|
||||||
else
|
else
|
||||||
throw new Exception("Can't convert type " ~ cast(char) type ~ " to " ~ T.stringof);
|
throw new Exception("Can't convert type " ~ cast(char) type ~ " to " ~ T.stringof);
|
||||||
} else static if(isDynamicArray!T) {
|
} else static if(isDynamicArray!T) {
|
||||||
|
@ -332,6 +384,8 @@ struct DBusAny {
|
||||||
return tuple == b.tuple;
|
return tuple == b.tuple;
|
||||||
else if(type == 's')
|
else if(type == 's')
|
||||||
return str == b.str;
|
return str == b.str;
|
||||||
|
else if(type == 'o')
|
||||||
|
return obj == b.obj;
|
||||||
else if(type == 'e')
|
else if(type == 'e')
|
||||||
return entry == b.entry || (entry && b.entry && *entry == *b.entry);
|
return entry == b.entry || (entry && b.entry && *entry == *b.entry);
|
||||||
else
|
else
|
||||||
|
|
|
@ -44,7 +44,8 @@ template allCanDBus(TS...) {
|
||||||
template basicDBus(T) {
|
template basicDBus(T) {
|
||||||
static if(is(T == byte) || is(T == short) || is (T == ushort) || is (T == int)
|
static if(is(T == byte) || is(T == short) || is (T == ushort) || is (T == int)
|
||||||
|| is (T == uint) || is (T == long) || is (T == ulong)
|
|| is (T == uint) || is (T == long) || is (T == ulong)
|
||||||
|| is (T == double) || is (T == string) || is(T == bool)) {
|
|| is (T == double) || is (T == string) || is(T == bool)
|
||||||
|
|| is (T == ObjectPath)) {
|
||||||
enum basicDBus = true;
|
enum basicDBus = true;
|
||||||
} else {
|
} else {
|
||||||
enum basicDBus = false;
|
enum basicDBus = false;
|
||||||
|
@ -101,6 +102,8 @@ string typeSig(T)() if(canDBus!T) {
|
||||||
return "d";
|
return "d";
|
||||||
} else static if(is(T == string)) {
|
} else static if(is(T == string)) {
|
||||||
return "s";
|
return "s";
|
||||||
|
} else static if(is(T == ObjectPath)) {
|
||||||
|
return "o";
|
||||||
} else static if(isVariant!T) {
|
} else static if(isVariant!T) {
|
||||||
return "v";
|
return "v";
|
||||||
} else static if(is(T == DBusAny)) {
|
} else static if(is(T == DBusAny)) {
|
||||||
|
|
Loading…
Reference in a new issue