diff --git a/source/ddbus/conv.d b/source/ddbus/conv.d index 8644055..d705116 100644 --- a/source/ddbus/conv.d +++ b/source/ddbus/conv.d @@ -172,7 +172,7 @@ void buildIter(TS...)(DBusMessageIter* iter, TS args) } T readIter(T)(DBusMessageIter* iter) - if (is(T == enum) && !is(T == InterfaceName) && !is(T == BusName)) { + if (is(T == enum) && !is(T == InterfaceName) && !is(T == BusName) && !is(T == FileDescriptor)) { import std.algorithm.searching : canFind; alias OriginalType!T B; @@ -198,7 +198,8 @@ T readIter(T)(DBusMessageIter* iter) } T readIter(T)(DBusMessageIter* iter) - if (!(is(T == enum) && !is(T == InterfaceName) && !is(T == BusName)) && !isInstanceOf!(BitFlags, T) && canDBus!T) { + if (!(is(T == enum) && !is(T == InterfaceName) && !is(T == BusName) && !is(T == FileDescriptor)) + && !isInstanceOf!(BitFlags, T) && canDBus!T) { auto argType = dbus_message_iter_get_arg_type(iter); T ret; diff --git a/source/ddbus/thin.d b/source/ddbus/thin.d index 727bf59..b0fa6c4 100644 --- a/source/ddbus/thin.d +++ b/source/ddbus/thin.d @@ -171,6 +171,17 @@ InterfaceName interfaceName(string path) pure @nogc nothrow @safe { return cast(InterfaceName) path; } +/// Serving as a typesafe alias for a FileDescriptor. +enum FileDescriptor : int { + none = -1, + max = int.max +} + +/// Casts an integer to a FileDescriptor. +FileDescriptor fileDescriptor(int fileNo) pure @nogc nothrow @safe { + return cast(FileDescriptor) fileNo; +} + unittest { import dunit.toolkit; @@ -284,6 +295,9 @@ struct DBusAny { } else static if (is(T == int)) { this(typeCode!int, null, false); int32 = cast(int) value; + } else static if (is(T == FileDescriptor)) { + this(typeCode!FileDescriptor, null, false); + int32 = cast(int) value; } else static if (is(T == uint)) { this(typeCode!uint, null, false); uint32 = cast(uint) value; @@ -459,6 +473,9 @@ struct DBusAny { case 'e': valueStr = entry.key.toString ~ ": " ~ entry.value.toString; break; + case 'h': + valueStr = int32.to!string; + break; default: valueStr = "unknown"; break; @@ -488,7 +505,9 @@ struct DBusAny { "Cannot get a " ~ T.stringof ~ " from a DBusAny with" ~ " a value of DBus type '" ~ typeSig ~ "'.", typeCode!T, type)); - static if (isIntegral!T) { + static if (is(T == FileDescriptor)) { + return fileDescriptor(int32); + } else static if (isIntegral!T) { enum memberName = (isUnsigned!T ? "uint" : "int") ~ (T.sizeof * 8).to!string; return __traits(getMember, this, memberName); } else static if (is(T == double)) { @@ -730,6 +749,7 @@ unittest { test(variant(cast(short) 184), set!"int16"(DBusAny('n', null, true), cast(short) 184)); test(variant(cast(ushort) 184), set!"uint16"(DBusAny('q', null, true), cast(ushort) 184)); test(variant(cast(int) 184), set!"int32"(DBusAny('i', null, true), cast(int) 184)); + test(variant(cast(FileDescriptor) 184), set!"int32"(DBusAny('h', null, true), cast(FileDescriptor) 184)); test(variant(cast(uint) 184), set!"uint32"(DBusAny('u', null, true), cast(uint) 184)); test(variant(cast(long) 184), set!"int64"(DBusAny('x', null, true), cast(long) 184)); test(variant(cast(ulong) 184), set!"uint64"(DBusAny('t', null, true), cast(ulong) 184)); diff --git a/source/ddbus/util.d b/source/ddbus/util.d index 4d469ce..3d43eb6 100644 --- a/source/ddbus/util.d +++ b/source/ddbus/util.d @@ -55,7 +55,7 @@ template allCanDBus(TS...) { +/ package // Don't add to the API yet, 'cause I intend to move it later alias BasicTypes = AliasSeq!(bool, byte, short, ushort, int, uint, long, ulong, - double, string, ObjectPath, InterfaceName, BusName); + double, string, ObjectPath, InterfaceName, BusName, FileDescriptor); template basicDBus(T) { static if (staticIndexOf!(T, BasicTypes) >= 0) { @@ -104,6 +104,7 @@ unittest { (canDBus!(Tuple!(int[], bool, Variant!short))).assertTrue(); (canDBus!(Tuple!(int[], int[string]))).assertTrue(); (canDBus!(int[string])).assertTrue(); + (canDBus!FileDescriptor).assertTrue(); } string typeSig(T)() @@ -116,6 +117,8 @@ string typeSig(T)() return "n"; } else static if (is(T == ushort)) { return "q"; + } else static if (is(T == FileDescriptor)) { + return "h"; } else static if (is(T == int)) { return "i"; } else static if (is(T == uint)) { @@ -217,6 +220,7 @@ unittest { typeSig!bool().assertEqual("b"); typeSig!string().assertEqual("s"); typeSig!(Variant!int)().assertEqual("v"); + typeSig!FileDescriptor().assertEqual("h"); // enums enum E : byte { a, @@ -256,9 +260,10 @@ unittest { string d; S1 e; uint f; + FileDescriptor g; } - typeSig!S2.assertEqual("(vs(ids)u)"); + typeSig!S2.assertEqual("(vs(ids)uh)"); // arrays typeSig!(int[]).assertEqual("ai"); typeSig!(Variant!int[]).assertEqual("av");