db-move: moved webkitgtk-6.0 from [testing] to [extra] (x86_64)
[arch-packages.git] / seed / trunk / GLib.js
blob5aec39a73ba2fb98f061fc331e86c433ce2fa19b
1 GLib = imports.gi.GLib;
3 (function() {
5 /* Variant Sugar
6 * Provide commodities methods to convert Variant from/to javascript object.
7 * variant.toJS() : returns a javascript object representing the Variant
8 # @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;
26 try {
27 JSONGLib = imports.gi.Json;
29 catch (e) {}
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);
45 return variant;
48 GLib.Variant.prototype.toString = function() {
49 return '[object variant of type "' + this.get_type_string() + '"]';
52 /// End Variant Sugar ///
53 }).apply();
55 function _toVariantNative(signature, object)
57 if (!object || object == '')
58 return null;
59 if (!signature || signature == '')
60 signature = null;
62 return JSONGLib.gvariant_deserialize_data (JSON.stringify (object),
63 -1, signature);
66 function _toJSNative(signature, variant)
68 if (!variant)
69 return;
71 var jsonStr = JSONGLib.gvariant_serialize_data (variant, signature);
72 if (!jsonStr)
73 return;
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();
85 var isSimple = false;
87 if (SIMPLE_TYPES.indexOf(char) == -1) {
88 if (forceSimple)
89 throw new TypeError('Invalid GVariant signature (a simple type was expected)');
90 } else
91 isSimple = true;
93 if (char == 'm' || char == 'a')
94 return [char].concat(_read_single_type(signature, false));
95 if (char == '{') {
96 var key = _read_single_type(signature, true);
97 var val = _read_single_type(signature, false);
98 var close = signature.shift();
99 if (close != '}')
100 throw new TypeError('Invalid GVariant signature for type DICT_ENTRY (expected "}"');
101 return [char].concat(key, val, close);
103 if (char == '(') {
104 var res = [char];
105 while (true) {
106 if (signature.length == 0)
107 throw new TypeError('Invalid GVariant signature for type TUPLE (expected ")")');
108 var next = signature[0];
109 if (next == ')') {
110 signature.shift();
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)');
122 return [char];
126 function _toVariant(signature, value) {
127 if (signature.length == 0)
128 throw new TypeError('GVariant signature cannot be empty');
130 var char = signature.shift();
131 switch (char) {
132 case 'b':
133 return GLib.Variant.new_boolean(value);
134 case 'y':
135 return GLib.Variant.new_byte(value);
136 case 'n':
137 return GLib.Variant.new_int16(value);
138 case 'q':
139 return GLib.Variant.new_uint16(value);
140 case 'i':
141 return GLib.Variant.new_int32(value);
142 case 'u':
143 return GLib.Variant.new_uint32(value);
144 case 'x':
145 return GLib.Variant.new_int64(value);
146 case 't':
147 return GLib.Variant.new_uint64(value);
148 case 'h':
149 return GLib.Variant.new_handle(value);
150 case 'd':
151 return GLib.Variant.new_double(value);
152 case 's':
153 return GLib.Variant.new_string(value);
154 case 'o':
155 return GLib.Variant.new_object_path(value);
156 case 'g':
157 return GLib.Variant.new_signature(value);
158 case 'v':
159 return GLib.Variant.new_variant(value);
160 case 'm':
161 if (value != null)
162 return GLib.Variant.new_maybe(null, _pack_variant(signature, value))
163 else
164 return GLib.Variant.new_maybe(GLib.VariantType.new(_read_single_type(signature, false).join('')), null);
165 case 'a':
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);
180 var arrayValue = [];
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);
188 } else {
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);
196 case '(':
197 var children = [ ];
198 for (var i = 0; i < value.length; i++) {
199 var next = signature[0];
200 if (next == ')')
201 break;
202 children.push(_pack_variant(signature, value[i]));
205 if (signature[0] != ')')
206 throw new TypeError('Invalid GVariant signature for type TUPLE (expected ")")');
207 signature.shift();
208 return GLib.Variant.new_tuple(children, children.length);
209 case '{':
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 "}")');
215 signature.shift();
217 return GLib.Variant.new_dict_entry(key, child);
218 default:
219 throw new TypeError('Invalid GVariant signature (unexpected character ' + char + ')');
223 function _toJS(signature, variant) {
224 switch (String.fromCharCode(variant.classify())) {
225 case 'b':
226 return variant.get_boolean();
227 case 'y':
228 return variant.get_byte();
229 case 'n':
230 return variant.get_int16();
231 case 'q':
232 return variant.get_uint16();
233 case 'i':
234 return variant.get_int32();
235 case 'u':
236 return variant.get_uint32();
237 case 'x':
238 return variant.get_int64();
239 case 't':
240 return variant.get_uint64();
241 case 'h':
242 return variant.get_handle();
243 case 'd':
244 return variant.get_double();
245 case 'o':
246 case 'g':
247 case 's':
248 // g_variant_get_string has length as out argument
249 return variant.get_string();
250 case 'v':
251 return variant.get_variant();
252 case 'm':
253 var val = variant.get_maybe();
254 return _toJS(val);
255 case 'a':
256 if (variant.is_container()) {
257 // special case containers
258 var ret = { };
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]
267 return ret;
269 // fall through
270 case '(':
271 case '{':
272 var ret = [ ];
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));
278 return ret;
281 throw new Error('Assertion failure: this code should not be reached');