Merge pull request #12 from WebFreak001/any-types
Memory & performance optimization for ubyte[]
This commit is contained in:
commit
ec2d957ad8
|
@ -60,6 +60,10 @@ void buildIter(TS...)(DBusMessageIter *iter, TS args) if(allCanDBus!TS) {
|
|||
} else if(val.type == 'a') {
|
||||
DBusMessageIter arr;
|
||||
dbus_message_iter_open_container(sub, 'a', sig[1 .. $].ptr, &arr);
|
||||
if (val.signature == ['y'])
|
||||
foreach (item; val.binaryData)
|
||||
dbus_message_iter_append_basic(&arr, 'y', &item);
|
||||
else
|
||||
foreach(item; val.array)
|
||||
buildIter(&arr, item);
|
||||
dbus_message_iter_close_container(sub, &arr);
|
||||
|
@ -170,6 +174,15 @@ T readIter(T)(DBusMessageIter *iter) if (canDBus!T) {
|
|||
auto sig = dbus_message_iter_get_signature(&sub);
|
||||
ret.signature = sig.fromStringz.dup;
|
||||
dbus_free(sig);
|
||||
if (ret.signature == ['y'])
|
||||
while(dbus_message_iter_get_arg_type(&sub) != 0) {
|
||||
ubyte b;
|
||||
assert(dbus_message_iter_get_arg_type(&sub) == 'y');
|
||||
dbus_message_iter_get_basic(&sub, &b);
|
||||
dbus_message_iter_next(&sub);
|
||||
ret.binaryData ~= b;
|
||||
}
|
||||
else
|
||||
while(dbus_message_iter_get_arg_type(&sub) != 0) {
|
||||
ret.array ~= readIter!DBusAny(&sub);
|
||||
}
|
||||
|
@ -218,7 +231,8 @@ unittest {
|
|||
Variant!DBusAny complexVar = variant(DBusAny([
|
||||
"hello world": variant(DBusAny(1337)),
|
||||
"array value": variant(DBusAny([42, 64])),
|
||||
"tuple value": variant(tupleMember)
|
||||
"tuple value": variant(tupleMember),
|
||||
"optimized binary data": variant(DBusAny(cast(ubyte[]) [1, 2, 3, 4, 5, 6]))
|
||||
]));
|
||||
complexVar.data.type.assertEqual('a');
|
||||
complexVar.data.signature.assertEqual("{sv}".dup);
|
||||
|
|
|
@ -68,6 +68,8 @@ struct DBusAny {
|
|||
DBusAny[] tuple;
|
||||
///
|
||||
DictionaryEntry!(DBusAny, DBusAny)* entry;
|
||||
///
|
||||
ubyte[] binaryData;
|
||||
}
|
||||
|
||||
/// Manually creates a DBusAny object using a type, signature and implicit specifier.
|
||||
|
@ -115,9 +117,12 @@ struct DBusAny {
|
|||
type = value.data.type;
|
||||
signature = value.data.signature;
|
||||
explicitVariant = true;
|
||||
if(type == 'a' || type == 'r')
|
||||
if(type == 'a' || type == 'r') {
|
||||
if(signature == ['y'])
|
||||
binaryData = value.data.binaryData;
|
||||
else
|
||||
array = value.data.array;
|
||||
if(type == 's')
|
||||
} else if(type == 's')
|
||||
str = value.data.str;
|
||||
else if(type == 'e')
|
||||
entry = value.data.entry;
|
||||
|
@ -138,9 +143,13 @@ struct DBusAny {
|
|||
entry.value = value.value;
|
||||
else
|
||||
entry.value = DBusAny(value.value);
|
||||
} else static if(is(T == ubyte[]) || is(T == byte[])) {
|
||||
this('a', ['y'], false);
|
||||
binaryData = cast(ubyte[]) value;
|
||||
} else static if(isInputRange!T) {
|
||||
this.type = 'a';
|
||||
static assert(!is(ElementType!T == DBusAny), "Array must consist of the same type, use Variant!DBusAny or DBusAny(tuple(...)) instead");
|
||||
static assert(typeSig!(ElementType!T) != "y");
|
||||
this.signature = typeSig!(ElementType!T).dup;
|
||||
this.explicitVariant = false;
|
||||
foreach(elem; value)
|
||||
|
@ -202,6 +211,11 @@ struct DBusAny {
|
|||
valueStr = boolean ? "true" : "false";
|
||||
break;
|
||||
case 'a':
|
||||
import std.digest.digest : toHexString;
|
||||
|
||||
if(signature == ['y'])
|
||||
valueStr = "binary(" ~ binaryData.toHexString ~ ')';
|
||||
else
|
||||
valueStr = '[' ~ array.map!(a => a.toString).join(", ") ~ ']';
|
||||
break;
|
||||
case 'r':
|
||||
|
@ -277,6 +291,11 @@ struct DBusAny {
|
|||
if(type != 'a' && type != 'r')
|
||||
throw new Exception("Can't convert type " ~ cast(char) type ~ " to an array");
|
||||
T ret;
|
||||
if(signature == ['y']) {
|
||||
static if(isIntegral!(ElementType!T))
|
||||
foreach(elem; binaryData)
|
||||
ret ~= elem.to!(ElementType!T);
|
||||
} else
|
||||
foreach(elem; array)
|
||||
ret ~= elem.to!(ElementType!T);
|
||||
return ret;
|
||||
|
@ -305,6 +324,8 @@ struct DBusAny {
|
|||
return false;
|
||||
if((type == 'a' || type == 'r') && b.signature != signature)
|
||||
return false;
|
||||
if(type == 'a' && signature == ['y'])
|
||||
return binaryData == b.binaryData;
|
||||
if(type == 'a')
|
||||
return array == b.array;
|
||||
else if(type == 'r')
|
||||
|
@ -339,6 +360,7 @@ unittest {
|
|||
test(cast(long) 184, set!"int64"(DBusAny('x', null, false), cast(long) 184));
|
||||
test(cast(ulong) 184, set!"uint64"(DBusAny('t', null, false), cast(ulong) 184));
|
||||
test(true, set!"boolean"(DBusAny('b', null, false), true));
|
||||
test(cast(ubyte[]) [1, 2, 3], set!"binaryData"(DBusAny('a', ['y'], false), cast(ubyte[]) [1, 2, 3]));
|
||||
|
||||
test(variant(cast(ubyte) 184), set!"int8"(DBusAny('y', null, true), cast(byte) 184));
|
||||
test(variant(cast(short) 184), set!"int16"(DBusAny('n', null, true), cast(short) 184));
|
||||
|
@ -348,6 +370,7 @@ unittest {
|
|||
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));
|
||||
test(variant(true), set!"boolean"(DBusAny('b', null, true), true));
|
||||
test(variant(cast(ubyte[]) [1, 2, 3]), set!"binaryData"(DBusAny('a', ['y'], true), cast(ubyte[]) [1, 2, 3]));
|
||||
|
||||
test(variant(DBusAny(5)), set!"int32"(DBusAny('i', null, true), 5));
|
||||
|
||||
|
|
Loading…
Reference in a new issue