Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for DBus object path type #17

Merged
merged 4 commits into from
Jun 27, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions source/ddbus/conv.d
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ void buildIter(TS...)(DBusMessageIter *iter, TS args) if(allCanDBus!TS) {
static if(is(T == string)) {
immutable(char)* cStr = arg.toStringz();
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)) {
dbus_bool_t longerBool = arg; // dbus bools are ints
dbus_message_iter_append_basic(iter,typeCode!T,&longerBool);
Expand Down Expand Up @@ -71,6 +74,8 @@ void buildIter(TS...)(DBusMessageIter *iter, TS args) if(allCanDBus!TS) {
dbus_message_iter_open_container(iter, 'v', sig.ptr, sub);
if(val.type == 's') {
buildIter(sub, val.str);
} else if(val.type == 'o') {
buildIter(sub, val.obj);
} else if(val.type == 'b') {
buildIter(sub,val.boolean);
} else if(dbus_type_is_basic(val.type)) {
Expand Down Expand Up @@ -136,10 +141,14 @@ T readIter(T)(DBusMessageIter *iter) if (canDBus!T) {
} else static if(!is(T == DBusAny) && !is(T == Variant!DBusAny)) {
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;
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)) {
dbus_bool_t longerBool;
dbus_message_iter_get_basic(iter, &longerBool);
Expand Down Expand Up @@ -183,6 +192,9 @@ T readIter(T)(DBusMessageIter *iter) if (canDBus!T) {
if(ret.type == 's') {
ret.str = readIter!string(iter);
return ret;
} else if(ret.type == 'o') {
ret.obj = readIter!ObjectPath(iter);
return ret;
} else if(ret.type == 'b') {
ret.boolean = readIter!bool(iter);
return ret;
Expand Down
54 changes: 54 additions & 0 deletions source/ddbus/thin.d
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,43 @@ T wrapErrors(T)(T delegate(DBusError *err) del) {
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
struct DBusAny {
/// DBus type of the value (never 'v'), see typeSig!T
Expand Down Expand Up @@ -63,6 +100,8 @@ struct DBusAny {
///
bool boolean;
///
ObjectPath obj;
///
DBusAny[] array;
///
DBusAny[] tuple;
Expand Down Expand Up @@ -112,6 +151,9 @@ struct DBusAny {
} else static if(is(T == bool)) {
this(typeCode!bool, null, false);
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)) {
static if(is(R == DBusAny)) {
type = value.data.type;
Expand Down Expand Up @@ -207,6 +249,9 @@ struct DBusAny {
case typeCode!string:
valueStr = '"' ~ str ~ '"';
break;
case typeCode!ObjectPath:
valueStr = '"' ~ obj.to!string ~ '"';
break;
case typeCode!bool:
valueStr = boolean ? "true" : "false";
break;
Expand Down Expand Up @@ -285,6 +330,13 @@ struct DBusAny {
} else static if(isSomeString!T) {
if(type == 's')
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
throw new Exception("Can't convert type " ~ cast(char) type ~ " to " ~ T.stringof);
} else static if(isDynamicArray!T) {
Expand Down Expand Up @@ -332,6 +384,8 @@ struct DBusAny {
return tuple == b.tuple;
else if(type == 's')
return str == b.str;
else if(type == 'o')
return obj == b.obj;
else if(type == 'e')
return entry == b.entry || (entry && b.entry && *entry == *b.entry);
else
Expand Down
5 changes: 4 additions & 1 deletion source/ddbus/util.d
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ template allCanDBus(TS...) {
template basicDBus(T) {
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 == double) || is (T == string) || is(T == bool)) {
|| is (T == double) || is (T == string) || is(T == bool)
|| is (T == ObjectPath)) {
enum basicDBus = true;
} else {
enum basicDBus = false;
Expand Down Expand Up @@ -101,6 +102,8 @@ string typeSig(T)() if(canDBus!T) {
return "d";
} else static if(is(T == string)) {
return "s";
} else static if(is(T == ObjectPath)) {
return "o";
} else static if(isVariant!T) {
return "v";
} else static if(is(T == DBusAny)) {
Expand Down