2 * Browser D-Bus Bridge, JavaScriptCore version
4 * Copyright © 2008 Movial Creative Technologies Inc
5 * Contact: Movial Creative Technologies Inc, <info@movial.com>
6 * Authors: Kalle Vahlman, <kalle.vahlman@movial.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
24 #include <dbus/dbus.h>
25 #include <JavaScriptCore/JavaScript.h>
27 #include "jscorebus-classfactory.h"
28 #include "jscorebus-marshal.h"
30 gboolean jsvalue_typeof(JSContextRef context,
34 const JSClassDefinition *jsclassdef;
37 jsclassdef = jsclassdef_lookup(type);
38 if (G_UNLIKELY(jsclassdef == NULL))
40 jsclass = jsclass_lookup(jsclassdef);
42 return JSValueIsObjectOfClass(context, jsvalue, jsclass);
45 gboolean jsvalue_instanceof(JSContextRef context,
47 const char *constructor)
52 property = JSStringCreateWithUTF8CString(constructor);
53 ctor = JSValueToObject(context,
54 JSObjectGetProperty(context,
55 JSContextGetGlobalObject(context),
59 JSStringRelease(property);
61 return JSValueIsInstanceOfConstructor(context, jsvalue, ctor, NULL);
64 char *jsvalue_to_signature(JSContextRef context,
67 char *signature = NULL;
69 switch (JSValueGetType(context, jsvalue))
73 signature = g_strdup(DBUS_TYPE_BOOLEAN_AS_STRING);
78 /* JavaScript numbers are always doubles */
79 signature = g_strdup(DBUS_TYPE_DOUBLE_AS_STRING);
84 signature = g_strdup(DBUS_TYPE_STRING_AS_STRING);
90 char *dict_signature = NULL;
91 JSPropertyNameArrayRef propnames;
93 /* Check for number types */
94 for (i = 0; i < JSCOREBUS_N_NUMBER_CLASSES; i++)
96 if (jsvalue_typeof(context, jsvalue, jscorebus_number_class_names[i]))
98 switch (jscorebus_number_class_types[i])
100 #define NUMBER_SIGNATURE(t) \
101 case DBUS_TYPE_## t: \
102 signature = g_strdup(DBUS_TYPE_## t ##_AS_STRING); \
104 NUMBER_SIGNATURE(UINT32)
105 NUMBER_SIGNATURE(INT32)
106 NUMBER_SIGNATURE(BYTE)
107 NUMBER_SIGNATURE(UINT64)
108 NUMBER_SIGNATURE(INT64)
109 NUMBER_SIGNATURE(UINT16)
110 NUMBER_SIGNATURE(INT16)
118 /* Check for arrays */
119 if (jsvalue_instanceof(context, jsvalue, "Array"))
121 JSPropertyNameArrayRef propnames;
122 char *array_signature;
124 propnames = JSObjectCopyPropertyNames(context, (JSObjectRef)jsvalue);
125 if (!jsarray_get_signature(context, jsvalue, propnames, &array_signature))
127 g_warning("Could not create array signature");
130 signature = g_strdup_printf("a%s", array_signature);
131 g_free(array_signature);
136 if (jsvalue_typeof(context, jsvalue, "DBusVariant"))
138 signature = g_strdup("v");
142 if (jsvalue_typeof(context, jsvalue, "DBusObjectPath"))
144 signature = g_strdup(DBUS_TYPE_OBJECT_PATH_AS_STRING);
148 if (jsvalue_typeof(context, jsvalue, "DBusSignature"))
150 signature = g_strdup(DBUS_TYPE_SIGNATURE_AS_STRING);
155 if (jsvalue_typeof(context, jsvalue, "DBusStruct"))
157 JSPropertyNameArrayRef propnames;
158 JSObjectRef value = (JSObjectRef)JSObjectGetPrivate((JSObjectRef)jsvalue);
159 propnames = JSObjectCopyPropertyNames(context, value);
160 jsstruct_get_signature(context, value, propnames, &signature);
164 /* Default conversion is to dict */
165 propnames = JSObjectCopyPropertyNames(context, jsvalue);
166 jsdict_get_signature(context, jsvalue, propnames, &dict_signature);
167 if (dict_signature != NULL)
169 signature = g_strdup_printf("a%s", dict_signature);
170 g_free(dict_signature);
175 case kJSTypeUndefined:
178 g_warning("Signature lookup failed for unsupported type %i", JSValueGetType(context, jsvalue));
185 jsarray_get_signature(JSContextRef context,
187 JSPropertyNameArrayRef propNames,
193 props = JSPropertyNameArrayGetCount(propNames);
194 /* Arrays are restricted to single complete types so we only need to look
195 * at the first property
199 *signature = jsvalue_to_signature(context,
200 JSObjectGetPropertyAtIndex(context, (JSObjectRef)jsvalue, 0, NULL));
202 return *signature == NULL ? FALSE : TRUE;
206 jsdict_get_signature(JSContextRef context,
208 JSPropertyNameArrayRef propNames,
214 props = JSPropertyNameArrayGetCount(propNames);
215 /* Dicts support only string keys currently, though numbers would be another
220 char **signatures = g_new0(char*, 5);
222 signatures[0] = g_strdup(DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING);
223 signatures[1] = g_strdup(DBUS_TYPE_STRING_AS_STRING);
224 signatures[2] = jsvalue_to_signature(context,
225 JSObjectGetProperty(context, (JSObjectRef)jsvalue,
226 JSPropertyNameArrayGetNameAtIndex(propNames, 0), NULL));
227 signatures[3] = g_strdup(DBUS_DICT_ENTRY_END_CHAR_AS_STRING);
229 *signature = g_strjoinv(NULL, signatures);
230 g_strfreev(signatures);
232 return *signature == NULL ? FALSE : TRUE;
236 jsstruct_get_signature(JSContextRef context,
238 JSPropertyNameArrayRef propNames,
244 props = JSPropertyNameArrayGetCount(propNames);
247 char **signatures = g_new0(char*, props + 2);
249 signatures[i] = g_strdup(DBUS_STRUCT_BEGIN_CHAR_AS_STRING);
252 signatures[i+1] = jsvalue_to_signature(context,
253 JSObjectGetProperty(context, (JSObjectRef)jsvalue,
254 JSPropertyNameArrayGetNameAtIndex(propNames, i++), NULL));
256 signatures[props + 1] = g_strdup(DBUS_STRUCT_END_CHAR_AS_STRING);
258 *signature = g_strjoinv(NULL, signatures);
259 g_strfreev(signatures);
261 return *signature == NULL ? FALSE : TRUE;