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