1 GLib
= imports
.gi
.GLib
;
6 * Provide commodities methods to convert Variant from/to javascript object.
7 * variant.toJS() : returns a javascript object representing the Variant
9 * Variant.new(signature, value): returns a GVariant structure representing
10 * the javascript object @value
12 * This implementation uses json-glib's json <-> variant conversion facilities
13 * if presents and fallback to a javascript implementation otherwise.
14 * This javascript implementation is imported from gjs with modification for
15 * JSCore compatibility (Copyright 2011 Giovanni Campagna,
16 * see gjs/override/GLib.js for licence)
19 // Use json-glib's json <-> variant conversion if present.
20 // Defaults to javascript code imported from gjs otherwise.
21 GLib
.Variant
.prototype.to_js = function(signature
) {
22 return _toJS(signature
, this);
24 var toVariant
= _toVariant
;
27 JSONGLib
= imports
.gi
.Json
;
31 if (JSONGLib
&& JSONGLib
.gvariant_serialize_data
)
33 GLib
.Variant
.prototype.to_js = function(signature
) {
34 return _toJSNative(signature
, this);
36 toVariant
= _toVariantNative
;
39 GLib
.Variant
.new = function (value
, sig
) {
40 var signature
= Array
.prototype.slice
.call(sig
);
42 if (signature
.length
!= 0)
43 throw new TypeError('Invalid GVariant signature (more than one single complete type)');
44 var variant
= toVariant(signature
, value
);
48 GLib
.Variant
.prototype.toString = function() {
49 return '[object variant of type "' + this.get_type_string() + '"]';
52 /// End Variant Sugar ///
55 function _toVariantNative(signature
, object
)
57 if (!object
|| object
== '')
59 if (!signature
|| signature
== '')
62 return JSONGLib
.gvariant_deserialize_data (JSON
.stringify (object
),
66 function _toJSNative(signature
, variant
)
71 var jsonStr
= JSONGLib
.gvariant_serialize_data (variant
, signature
);
75 return JSON
.parse (jsonStr
);
78 // Code imported from gjs, modified for JSCore idoms.
79 // Copyright 2011 Giovanni Campagna (see gjs/override/GLib.js for licence)
81 const SIMPLE_TYPES
= ['b', 'y', 'n', 'q', 'i', 'u', 'x', 't', 'h', 'd', 's', 'o', 'g'];
83 function _read_single_type(signature
, forceSimple
) {
84 var char = signature
.shift();
87 if (SIMPLE_TYPES
.indexOf(char) == -1) {
89 throw new TypeError('Invalid GVariant signature (a simple type was expected)');
93 if (char == 'm' || char == 'a')
94 return [char].concat(_read_single_type(signature
, false));
96 var key
= _read_single_type(signature
, true);
97 var val
= _read_single_type(signature
, false);
98 var close
= signature
.shift();
100 throw new TypeError('Invalid GVariant signature for type DICT_ENTRY (expected "}"');
101 return [char].concat(key
, val
, close
);
106 if (signature
.length
== 0)
107 throw new TypeError('Invalid GVariant signature for type TUPLE (expected ")")');
108 var next
= signature
[0];
111 return res
.concat(next
);
113 var el
= _read_single_type(signature
);
114 res
= res
.concat(el
);
118 // Valid types are simple types, arrays, maybes, tuples, dictionary entries and variants
119 if (!isSimple
&& char != 'v')
120 throw new TypeError('Invalid GVariant signature (' + char + ' is not a valid type)');
126 function _toVariant(signature
, value
) {
127 if (signature
.length
== 0)
128 throw new TypeError('GVariant signature cannot be empty');
130 var char = signature
.shift();
133 return GLib
.Variant
.new_boolean(value
);
135 return GLib
.Variant
.new_byte(value
);
137 return GLib
.Variant
.new_int16(value
);
139 return GLib
.Variant
.new_uint16(value
);
141 return GLib
.Variant
.new_int32(value
);
143 return GLib
.Variant
.new_uint32(value
);
145 return GLib
.Variant
.new_int64(value
);
147 return GLib
.Variant
.new_uint64(value
);
149 return GLib
.Variant
.new_handle(value
);
151 return GLib
.Variant
.new_double(value
);
153 return GLib
.Variant
.new_string(value
);
155 return GLib
.Variant
.new_object_path(value
);
157 return GLib
.Variant
.new_signature(value
);
159 return GLib
.Variant
.new_variant(value
);
162 return GLib
.Variant
.new_maybe(null, _pack_variant(signature
, value
))
164 return GLib
.Variant
.new_maybe(GLib
.VariantType
.new(_read_single_type(signature
, false).join('')), null);
166 var arrayType
= _read_single_type(signature
, false);
167 if (arrayType
[0] == 's') {
168 // special case for array of strings
169 return GLib
.Variant
.new_strv(value
, value
.length
);
171 if (arrayType
[0] == 'y') {
172 // special case for array of bytes
173 return GLib
.Variant
.new_bytestring(value
);
175 if (arrayType
[0] == 'a' && arrayType
[1] == 'y') {
176 // special case for array of array of bytes
177 return GLib
.Variant
.new_bytestring_array(value
, value
.length
);
181 if (arrayType
[0] == '{') {
182 // special case for dictionaries
183 for (var key
in value
) {
184 var copy
= [].concat(arrayType
);
185 var child
= _pack_variant(copy
, [key
, value
[key
]]);
186 arrayValue
.push(child
);
189 for (var i
= 0; i
< value
.length
; i
++) {
190 var copy
= [].concat(arrayType
);
191 var child
= _pack_variant(copy
, value
[i
]);
192 arrayValue
.push(child
);
195 return GLib
.Variant
.new_array(GLib
.VariantType
.new(arrayType
.join('')), arrayValue
, arrayValue
.length
);
198 for (var i
= 0; i
< value
.length
; i
++) {
199 var next
= signature
[0];
202 children
.push(_pack_variant(signature
, value
[i
]));
205 if (signature
[0] != ')')
206 throw new TypeError('Invalid GVariant signature for type TUPLE (expected ")")');
208 return GLib
.Variant
.new_tuple(children
, children
.length
);
210 var key
= _pack_variant(signature
, value
[0]);
211 var child
= _pack_variant(signature
, value
[1]);
213 if (signature
[0] != '}')
214 throw new TypeError('Invalid GVariant signature for type DICT_ENTRY (expected "}")');
217 return GLib
.Variant
.new_dict_entry(key
, child
);
219 throw new TypeError('Invalid GVariant signature (unexpected character ' + char + ')');
223 function _toJS(signature
, variant
) {
224 switch (String
.fromCharCode(variant
.classify())) {
226 return variant
.get_boolean();
228 return variant
.get_byte();
230 return variant
.get_int16();
232 return variant
.get_uint16();
234 return variant
.get_int32();
236 return variant
.get_uint32();
238 return variant
.get_int64();
240 return variant
.get_uint64();
242 return variant
.get_handle();
244 return variant
.get_double();
248 // g_variant_get_string has length as out argument
249 return variant
.get_string();
251 return variant
.get_variant();
253 var val
= variant
.get_maybe();
256 if (variant
.is_container()) {
257 // special case containers
259 var nElements
= variant
.n_children();
260 for (var i
= 0; i
< nElements
; i
++) {
261 // always unpack the dictionary entry, and always unpack
262 // the key (or it cannot be added as a key)
263 var val
= _toJS(variant
.get_child_value(i
));
264 var key
= val
[0].classify
? _toJS(val
[0]) : val
[0];
265 ret
[key
] = val
[1] && val
[1].classify
? _toJS(val
[1]) : val
[1]
273 var nElements
= variant
.n_children();
274 for (var i
= 0; i
< nElements
; i
++) {
275 var val
= variant
.get_child_value(i
);
276 ret
.push(_toJS(val
));
281 throw new Error('Assertion failure: this code should not be reached');