[gjs: 1/3] GLib: add GLib.Variant.recursiveUnpack()
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs: 1/3] GLib: add GLib.Variant.recursiveUnpack()
- Date: Mon, 5 Aug 2019 00:01:19 +0000 (UTC)
commit 979e28ddbdad8e5eea803c099d16a022fe36457f
Author: Philip Chimento <philip chimento gmail com>
Date: Fri Aug 2 17:45:31 2019 -0700
GLib: add GLib.Variant.recursiveUnpack()
This function is useful if you want to entirely unpack a GVariant into
a JS object, and you don't care about any type information contained in
any 'v' elements. (This is a common case when unpacking 'a{sv}'
dictionaries from DBus.)
Based on code by Fabian Orccon <cfoch fabian gmail com>
Closes: GNOME/gjs#225
installed-tests/js/testGLib.js | 16 ++++++++++++++++
modules/overrides/GLib.js | 23 +++++++++++++++++------
2 files changed, 33 insertions(+), 6 deletions(-)
---
diff --git a/installed-tests/js/testGLib.js b/installed-tests/js/testGLib.js
index 66b7afb9..cd7f6ec0 100644
--- a/installed-tests/js/testGLib.js
+++ b/installed-tests/js/testGLib.js
@@ -71,6 +71,22 @@ describe('GVariant constructor', function () {
});
});
+describe('GVariant unpack', function () {
+ let v;
+ beforeEach(function () {
+ v = new GLib.Variant('a{sv}', {foo: new GLib.Variant('s', 'bar')});
+ });
+
+ it('preserves type information if the unpacked object contains variants', function () {
+ expect(v.deep_unpack().foo instanceof GLib.Variant).toBeTruthy();
+ });
+
+ it('recursive leaves no variants in the unpacked object', function () {
+ expect(v.recursiveUnpack().foo instanceof GLib.Variant).toBeFalsy();
+ expect(v.recursiveUnpack().foo).toEqual('bar');
+ });
+});
+
describe('GVariantDict lookup', function () {
let variantDict;
beforeEach(function () {
diff --git a/modules/overrides/GLib.js b/modules/overrides/GLib.js
index e57555da..5b46bf12 100644
--- a/modules/overrides/GLib.js
+++ b/modules/overrides/GLib.js
@@ -178,7 +178,7 @@ function _pack_variant(signature, value) {
}
}
-function _unpack_variant(variant, deep) {
+function _unpack_variant(variant, deep, recursive = false) {
switch (String.fromCharCode(variant.classify())) {
case 'b':
return variant.get_boolean();
@@ -205,12 +205,16 @@ function _unpack_variant(variant, deep) {
case 's':
// g_variant_get_string has length as out argument
return variant.get_string()[0];
- case 'v':
- return variant.get_variant();
+ case 'v': {
+ const ret = variant.get_variant();
+ if (deep && recursive && ret instanceof GLib.Variant)
+ return _unpack_variant(ret, deep, recursive);
+ return ret;
+ }
case 'm':
let val = variant.get_maybe();
if (deep && val)
- return _unpack_variant(val, deep);
+ return _unpack_variant(val, deep, recursive);
else
return val;
case 'a':
@@ -221,7 +225,8 @@ function _unpack_variant(variant, deep) {
for (let i = 0; i < nElements; i++) {
// always unpack the dictionary entry, and always unpack
// the key (or it cannot be added as a key)
- let val = _unpack_variant(variant.get_child_value(i), deep);
+ let val = _unpack_variant(variant.get_child_value(i), deep,
+ recursive);
let key;
if (!deep)
key = _unpack_variant(val[0], true);
@@ -244,7 +249,7 @@ function _unpack_variant(variant, deep) {
for (let i = 0; i < nElements; i++) {
let val = variant.get_child_value(i);
if (deep)
- ret.push(_unpack_variant(val, deep));
+ ret.push(_unpack_variant(val, deep, recursive));
else
ret.push(val);
}
@@ -284,6 +289,12 @@ function _init() {
this.Variant.prototype.deep_unpack = function() {
return _unpack_variant(this, true);
};
+
+ // Note: discards type information, if the variant contains any 'v' types
+ this.Variant.prototype.recursiveUnpack = function () {
+ return _unpack_variant(this, true, true);
+ };
+
this.Variant.prototype.toString = function() {
return '[object variant of type "' + this.get_type_string() + '"]';
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]