frida 16.7.13 → 16.7.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -10
- package/build/BSDmakefile +6 -0
- package/build/Makefile +10 -0
- package/build/src/frida.d.ts +364 -0
- package/build/src/frida.js +962 -0
- package/build/src/frida_binding.d.ts +938 -0
- package/meson.build +34 -67
- package/package.json +30 -20
- package/scripts/fetch-abi-bits.py +15 -65
- package/scripts/install.js +5 -4
- package/src/addon.def +3 -0
- package/src/addon.symbols +2 -1
- package/src/addon.version +4 -0
- package/src/frida_bindgen/__init__.py +0 -0
- package/src/frida_bindgen/__main__.py +4 -0
- package/src/frida_bindgen/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/frida_bindgen/__pycache__/__main__.cpython-312.pyc +0 -0
- package/src/frida_bindgen/__pycache__/cli.cpython-312.pyc +0 -0
- package/src/frida_bindgen/__pycache__/codegen.cpython-312.pyc +0 -0
- package/src/frida_bindgen/__pycache__/customization.cpython-312.pyc +0 -0
- package/src/frida_bindgen/__pycache__/loader.cpython-312.pyc +0 -0
- package/src/frida_bindgen/__pycache__/model.cpython-312.pyc +0 -0
- package/src/frida_bindgen/assets/codegen_helpers.c +1970 -0
- package/src/frida_bindgen/assets/codegen_helpers.ts +100 -0
- package/src/frida_bindgen/assets/codegen_prototypes.h +78 -0
- package/src/frida_bindgen/assets/codegen_types.h +57 -0
- package/src/frida_bindgen/assets/customization_facade.exports +13 -0
- package/src/frida_bindgen/assets/customization_facade.ts +157 -0
- package/src/frida_bindgen/assets/customization_helpers.imports +2 -0
- package/src/frida_bindgen/assets/customization_helpers.ts +396 -0
- package/src/frida_bindgen/cli.py +96 -0
- package/src/frida_bindgen/codegen.py +2233 -0
- package/src/frida_bindgen/customization.py +924 -0
- package/src/frida_bindgen/loader.py +60 -0
- package/src/frida_bindgen/model.py +1357 -0
- package/src/meson.build +92 -27
- package/{lib/build.py → src/tsc.py} +12 -12
- package/src/win_delay_load_hook.c +56 -0
- package/subprojects/frida-core.wrap +1 -1
- package/test/data/index.ts +2 -2
- package/test/device.ts +1 -2
- package/test/device_manager.ts +1 -2
- package/test/labrat.ts +2 -2
- package/test/script.ts +12 -12
- package/test/session.ts +3 -3
- package/tsconfig.json +6 -11
- package/dist/application.d.ts +0 -81
- package/dist/application.js +0 -2
- package/dist/authentication.d.ts +0 -3
- package/dist/authentication.js +0 -2
- package/dist/bus.d.ts +0 -16
- package/dist/bus.js +0 -23
- package/dist/cancellable.d.ts +0 -15
- package/dist/cancellable.js +0 -41
- package/dist/child.d.ts +0 -16
- package/dist/child.js +0 -9
- package/dist/crash.d.ts +0 -10
- package/dist/crash.js +0 -2
- package/dist/device.d.ts +0 -156
- package/dist/device.js +0 -188
- package/dist/device_manager.d.ts +0 -25
- package/dist/device_manager.js +0 -42
- package/dist/endpoint_parameters.d.ts +0 -26
- package/dist/endpoint_parameters.js +0 -24
- package/dist/icon.d.ts +0 -14
- package/dist/icon.js +0 -2
- package/dist/index.d.ts +0 -161
- package/dist/index.js +0 -170
- package/dist/iostream.d.ts +0 -13
- package/dist/iostream.js +0 -73
- package/dist/native.d.ts +0 -1
- package/dist/native.js +0 -11
- package/dist/portal_membership.d.ts +0 -6
- package/dist/portal_membership.js +0 -12
- package/dist/portal_service.d.ts +0 -48
- package/dist/portal_service.js +0 -52
- package/dist/process.d.ts +0 -47
- package/dist/process.js +0 -2
- package/dist/relay.d.ts +0 -22
- package/dist/relay.js +0 -32
- package/dist/script.d.ts +0 -70
- package/dist/script.js +0 -266
- package/dist/service.d.ts +0 -16
- package/dist/service.js +0 -26
- package/dist/session.d.ts +0 -45
- package/dist/session.js +0 -73
- package/dist/signals.d.ts +0 -20
- package/dist/signals.js +0 -40
- package/dist/socket_address.d.ts +0 -25
- package/dist/socket_address.js +0 -2
- package/dist/spawn.d.ts +0 -4
- package/dist/spawn.js +0 -2
- package/dist/system_parameters.d.ts +0 -84
- package/dist/system_parameters.js +0 -2
- package/lib/application.ts +0 -98
- package/lib/authentication.ts +0 -3
- package/lib/bus.ts +0 -30
- package/lib/cancellable.ts +0 -48
- package/lib/child.ts +0 -15
- package/lib/crash.ts +0 -11
- package/lib/device.ts +0 -331
- package/lib/device_manager.ts +0 -69
- package/lib/endpoint_parameters.ts +0 -56
- package/lib/icon.ts +0 -15
- package/lib/index.ts +0 -316
- package/lib/iostream.ts +0 -78
- package/lib/meson.build +0 -53
- package/lib/native.ts +0 -9
- package/lib/portal_membership.ts +0 -10
- package/lib/portal_service.ts +0 -105
- package/lib/process.ts +0 -57
- package/lib/relay.ts +0 -44
- package/lib/script.ts +0 -361
- package/lib/service.ts +0 -34
- package/lib/session.ts +0 -113
- package/lib/signals.ts +0 -45
- package/lib/socket_address.ts +0 -35
- package/lib/spawn.ts +0 -4
- package/lib/system_parameters.ts +0 -103
- package/meson.options +0 -11
- package/src/addon.cc +0 -78
- package/src/application.cc +0 -148
- package/src/application.h +0 -31
- package/src/authentication.cc +0 -174
- package/src/authentication.h +0 -24
- package/src/bus.cc +0 -167
- package/src/bus.h +0 -33
- package/src/cancellable.cc +0 -117
- package/src/cancellable.h +0 -31
- package/src/child.cc +0 -150
- package/src/child.h +0 -32
- package/src/crash.cc +0 -122
- package/src/crash.h +0 -30
- package/src/device.cc +0 -1350
- package/src/device.h +0 -56
- package/src/device_manager.cc +0 -362
- package/src/device_manager.h +0 -35
- package/src/endpoint_parameters.cc +0 -171
- package/src/endpoint_parameters.h +0 -28
- package/src/glib_context.cc +0 -62
- package/src/glib_context.h +0 -29
- package/src/glib_object.cc +0 -25
- package/src/glib_object.h +0 -37
- package/src/iostream.cc +0 -243
- package/src/iostream.h +0 -30
- package/src/operation.h +0 -94
- package/src/portal_membership.cc +0 -100
- package/src/portal_membership.h +0 -26
- package/src/portal_service.cc +0 -401
- package/src/portal_service.h +0 -40
- package/src/process.cc +0 -135
- package/src/process.h +0 -30
- package/src/relay.cc +0 -139
- package/src/relay.h +0 -31
- package/src/runtime.cc +0 -568
- package/src/runtime.h +0 -69
- package/src/script.cc +0 -301
- package/src/script.h +0 -36
- package/src/service.cc +0 -224
- package/src/service.h +0 -36
- package/src/session.cc +0 -860
- package/src/session.h +0 -42
- package/src/signals.cc +0 -334
- package/src/signals.h +0 -47
- package/src/spawn.cc +0 -95
- package/src/spawn.h +0 -27
- package/src/usage_monitor.h +0 -117
- package/src/uv_context.cc +0 -118
- package/src/uv_context.h +0 -40
- package/src/win_delay_load_hook.cc +0 -63
- package/subprojects/nan.wrap +0 -9
- package/subprojects/packagefiles/nan.patch +0 -13
|
@@ -0,0 +1,1970 @@
|
|
|
1
|
+
static gboolean
|
|
2
|
+
fdn_is_null (napi_env env,
|
|
3
|
+
napi_value value)
|
|
4
|
+
{
|
|
5
|
+
napi_valuetype type;
|
|
6
|
+
|
|
7
|
+
napi_typeof (env, value, &type);
|
|
8
|
+
|
|
9
|
+
return type == napi_null;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
static gboolean
|
|
13
|
+
fdn_is_undefined_or_null (napi_env env,
|
|
14
|
+
napi_value value)
|
|
15
|
+
{
|
|
16
|
+
napi_valuetype type;
|
|
17
|
+
|
|
18
|
+
napi_typeof (env, value, &type);
|
|
19
|
+
|
|
20
|
+
return type == napi_undefined || type == napi_null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
static gboolean
|
|
24
|
+
fdn_is_function (napi_env env,
|
|
25
|
+
napi_value value)
|
|
26
|
+
{
|
|
27
|
+
napi_valuetype type;
|
|
28
|
+
|
|
29
|
+
napi_typeof (env, value, &type);
|
|
30
|
+
|
|
31
|
+
return type == napi_function;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
static gboolean
|
|
35
|
+
fdn_boolean_from_value (napi_env env,
|
|
36
|
+
napi_value value,
|
|
37
|
+
gboolean * b)
|
|
38
|
+
{
|
|
39
|
+
bool napi_b;
|
|
40
|
+
|
|
41
|
+
if (napi_get_value_bool (env, value, &napi_b) != napi_ok)
|
|
42
|
+
goto invalid_argument;
|
|
43
|
+
|
|
44
|
+
*b = napi_b;
|
|
45
|
+
return TRUE;
|
|
46
|
+
|
|
47
|
+
invalid_argument:
|
|
48
|
+
{
|
|
49
|
+
napi_throw_error (env, NULL, "expected a boolean");
|
|
50
|
+
return FALSE;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static napi_value
|
|
55
|
+
fdn_boolean_to_value (napi_env env,
|
|
56
|
+
gboolean b)
|
|
57
|
+
{
|
|
58
|
+
napi_value result;
|
|
59
|
+
napi_get_boolean (env, b, &result);
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
static gboolean
|
|
64
|
+
fdn_size_from_value (napi_env env,
|
|
65
|
+
napi_value value,
|
|
66
|
+
gsize * s)
|
|
67
|
+
{
|
|
68
|
+
double d;
|
|
69
|
+
|
|
70
|
+
if (napi_get_value_double (env, value, &d) != napi_ok)
|
|
71
|
+
goto invalid_argument;
|
|
72
|
+
|
|
73
|
+
if (d < 0 || d > G_MAXSIZE)
|
|
74
|
+
goto invalid_argument;
|
|
75
|
+
|
|
76
|
+
*s = d;
|
|
77
|
+
return TRUE;
|
|
78
|
+
|
|
79
|
+
invalid_argument:
|
|
80
|
+
{
|
|
81
|
+
napi_throw_error (env, NULL, "expected an unsigned integer");
|
|
82
|
+
return FALSE;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
static napi_value
|
|
87
|
+
fdn_size_to_value (napi_env env,
|
|
88
|
+
gsize s)
|
|
89
|
+
{
|
|
90
|
+
return fdn_ssize_to_value (env, s);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
static napi_value
|
|
94
|
+
fdn_ssize_to_value (napi_env env,
|
|
95
|
+
gssize s)
|
|
96
|
+
{
|
|
97
|
+
napi_value result;
|
|
98
|
+
napi_create_int64 (env, s, &result);
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
static gboolean
|
|
103
|
+
fdn_int_from_value (napi_env env,
|
|
104
|
+
napi_value value,
|
|
105
|
+
gint * i)
|
|
106
|
+
{
|
|
107
|
+
int32_t napi_i;
|
|
108
|
+
|
|
109
|
+
if (napi_get_value_int32 (env, value, &napi_i) != napi_ok)
|
|
110
|
+
goto invalid_argument;
|
|
111
|
+
|
|
112
|
+
*i = napi_i;
|
|
113
|
+
return TRUE;
|
|
114
|
+
|
|
115
|
+
invalid_argument:
|
|
116
|
+
{
|
|
117
|
+
napi_throw_error (env, NULL, "expected an integer");
|
|
118
|
+
return FALSE;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
static napi_value
|
|
123
|
+
fdn_int_to_value (napi_env env,
|
|
124
|
+
gint i)
|
|
125
|
+
{
|
|
126
|
+
napi_value result;
|
|
127
|
+
napi_create_int32 (env, i, &result);
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
static gboolean
|
|
132
|
+
fdn_uint_from_value (napi_env env,
|
|
133
|
+
napi_value value,
|
|
134
|
+
guint * u)
|
|
135
|
+
{
|
|
136
|
+
uint32_t napi_u;
|
|
137
|
+
|
|
138
|
+
if (napi_get_value_uint32 (env, value, &napi_u) != napi_ok)
|
|
139
|
+
goto invalid_argument;
|
|
140
|
+
|
|
141
|
+
*u = napi_u;
|
|
142
|
+
return TRUE;
|
|
143
|
+
|
|
144
|
+
invalid_argument:
|
|
145
|
+
{
|
|
146
|
+
napi_throw_error (env, NULL, "expected an unsigned integer");
|
|
147
|
+
return FALSE;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
static napi_value
|
|
152
|
+
fdn_uint_to_value (napi_env env,
|
|
153
|
+
guint u)
|
|
154
|
+
{
|
|
155
|
+
napi_value result;
|
|
156
|
+
napi_create_uint32 (env, u, &result);
|
|
157
|
+
return result;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
static gboolean
|
|
161
|
+
fdn_uint16_from_value (napi_env env,
|
|
162
|
+
napi_value value,
|
|
163
|
+
guint16 * u)
|
|
164
|
+
{
|
|
165
|
+
uint32_t napi_u;
|
|
166
|
+
|
|
167
|
+
if (napi_get_value_uint32 (env, value, &napi_u) != napi_ok)
|
|
168
|
+
goto invalid_argument;
|
|
169
|
+
|
|
170
|
+
if (napi_u > G_MAXUINT16)
|
|
171
|
+
goto invalid_argument;
|
|
172
|
+
|
|
173
|
+
*u = napi_u;
|
|
174
|
+
return TRUE;
|
|
175
|
+
|
|
176
|
+
invalid_argument:
|
|
177
|
+
{
|
|
178
|
+
napi_throw_error (env, NULL, "expected an unsigned 16-bit integer");
|
|
179
|
+
return FALSE;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
static napi_value
|
|
184
|
+
fdn_uint16_to_value (napi_env env,
|
|
185
|
+
guint16 u)
|
|
186
|
+
{
|
|
187
|
+
return fdn_uint32_to_value (env, u);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
static napi_value
|
|
191
|
+
fdn_uint32_to_value (napi_env env,
|
|
192
|
+
guint32 u)
|
|
193
|
+
{
|
|
194
|
+
napi_value result;
|
|
195
|
+
napi_create_uint32 (env, u, &result);
|
|
196
|
+
return result;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
static gboolean
|
|
200
|
+
fdn_int64_from_value (napi_env env,
|
|
201
|
+
napi_value value,
|
|
202
|
+
gint64 * i)
|
|
203
|
+
{
|
|
204
|
+
int64_t napi_i;
|
|
205
|
+
|
|
206
|
+
if (napi_get_value_int64 (env, value, &napi_i) != napi_ok)
|
|
207
|
+
goto invalid_argument;
|
|
208
|
+
|
|
209
|
+
*i = napi_i;
|
|
210
|
+
return TRUE;
|
|
211
|
+
|
|
212
|
+
invalid_argument:
|
|
213
|
+
{
|
|
214
|
+
napi_throw_error (env, NULL, "expected an integer");
|
|
215
|
+
return FALSE;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
static napi_value
|
|
220
|
+
fdn_int64_to_value (napi_env env,
|
|
221
|
+
gint64 i)
|
|
222
|
+
{
|
|
223
|
+
napi_value result;
|
|
224
|
+
napi_create_int64 (env, i, &result);
|
|
225
|
+
return result;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
static napi_value
|
|
229
|
+
fdn_uint64_to_value (napi_env env,
|
|
230
|
+
guint64 u)
|
|
231
|
+
{
|
|
232
|
+
napi_value result;
|
|
233
|
+
napi_create_double (env, u, &result);
|
|
234
|
+
return result;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
static gboolean
|
|
238
|
+
fdn_ulong_from_value (napi_env env,
|
|
239
|
+
napi_value value,
|
|
240
|
+
gulong * u)
|
|
241
|
+
{
|
|
242
|
+
double d;
|
|
243
|
+
|
|
244
|
+
if (napi_get_value_double (env, value, &d) != napi_ok)
|
|
245
|
+
goto invalid_argument;
|
|
246
|
+
|
|
247
|
+
if (d < 0 || d > G_MAXULONG)
|
|
248
|
+
goto invalid_argument;
|
|
249
|
+
|
|
250
|
+
*u = d;
|
|
251
|
+
return TRUE;
|
|
252
|
+
|
|
253
|
+
invalid_argument:
|
|
254
|
+
{
|
|
255
|
+
napi_throw_error (env, NULL, "expected an unsigned integer");
|
|
256
|
+
return FALSE;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
static gboolean
|
|
261
|
+
fdn_double_from_value (napi_env env,
|
|
262
|
+
napi_value value,
|
|
263
|
+
gdouble * d)
|
|
264
|
+
{
|
|
265
|
+
if (napi_get_value_double (env, value, d) != napi_ok)
|
|
266
|
+
goto invalid_argument;
|
|
267
|
+
|
|
268
|
+
return TRUE;
|
|
269
|
+
|
|
270
|
+
invalid_argument:
|
|
271
|
+
{
|
|
272
|
+
napi_throw_error (env, NULL, "expected a number");
|
|
273
|
+
return FALSE;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
static napi_value
|
|
278
|
+
fdn_double_to_value (napi_env env,
|
|
279
|
+
gdouble d)
|
|
280
|
+
{
|
|
281
|
+
napi_value result;
|
|
282
|
+
napi_create_double (env, d, &result);
|
|
283
|
+
return result;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
static gboolean
|
|
287
|
+
fdn_enum_from_value (napi_env env,
|
|
288
|
+
GType enum_type,
|
|
289
|
+
napi_value value,
|
|
290
|
+
gint * e)
|
|
291
|
+
{
|
|
292
|
+
gboolean success = FALSE;
|
|
293
|
+
gchar * nick;
|
|
294
|
+
GEnumClass * enum_class;
|
|
295
|
+
guint i;
|
|
296
|
+
|
|
297
|
+
if (!fdn_utf8_from_value (env, value, &nick))
|
|
298
|
+
return FALSE;
|
|
299
|
+
|
|
300
|
+
enum_class = G_ENUM_CLASS (g_type_class_ref (enum_type));
|
|
301
|
+
|
|
302
|
+
for (i = 0; i != enum_class->n_values; i++)
|
|
303
|
+
{
|
|
304
|
+
GEnumValue * enum_value = &enum_class->values[i];
|
|
305
|
+
if (strcmp (enum_value->value_nick, nick) == 0)
|
|
306
|
+
{
|
|
307
|
+
*e = enum_value->value;
|
|
308
|
+
success = TRUE;
|
|
309
|
+
break;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
g_type_class_unref (enum_class);
|
|
314
|
+
|
|
315
|
+
g_free (nick);
|
|
316
|
+
|
|
317
|
+
if (!success)
|
|
318
|
+
napi_throw_error (env, NULL, "invalid enumeration value");
|
|
319
|
+
|
|
320
|
+
return success;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
static napi_value
|
|
324
|
+
fdn_enum_to_value (napi_env env,
|
|
325
|
+
GType enum_type,
|
|
326
|
+
gint e)
|
|
327
|
+
{
|
|
328
|
+
napi_value result;
|
|
329
|
+
GEnumClass * enum_class;
|
|
330
|
+
GEnumValue * enum_value;
|
|
331
|
+
|
|
332
|
+
enum_class = G_ENUM_CLASS (g_type_class_ref (enum_type));
|
|
333
|
+
|
|
334
|
+
enum_value = g_enum_get_value (enum_class, e);
|
|
335
|
+
g_assert (enum_value != NULL);
|
|
336
|
+
|
|
337
|
+
result = fdn_utf8_to_value (env, enum_value->value_nick);
|
|
338
|
+
|
|
339
|
+
g_type_class_unref (enum_class);
|
|
340
|
+
|
|
341
|
+
return result;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
static gboolean
|
|
345
|
+
fdn_utf8_from_value (napi_env env,
|
|
346
|
+
napi_value value,
|
|
347
|
+
gchar ** str)
|
|
348
|
+
{
|
|
349
|
+
gchar * result = NULL;
|
|
350
|
+
size_t length;
|
|
351
|
+
|
|
352
|
+
if (napi_get_value_string_utf8 (env, value, NULL, 0, &length) != napi_ok)
|
|
353
|
+
goto invalid_argument;
|
|
354
|
+
|
|
355
|
+
result = g_malloc (length + 1);
|
|
356
|
+
if (napi_get_value_string_utf8 (env, value, result, length + 1, &length) != napi_ok)
|
|
357
|
+
goto invalid_argument;
|
|
358
|
+
|
|
359
|
+
*str = result;
|
|
360
|
+
return TRUE;
|
|
361
|
+
|
|
362
|
+
invalid_argument:
|
|
363
|
+
{
|
|
364
|
+
napi_throw_error (env, NULL, "expected a string");
|
|
365
|
+
g_free (result);
|
|
366
|
+
return FALSE;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
static napi_value
|
|
371
|
+
fdn_utf8_to_value (napi_env env,
|
|
372
|
+
const gchar * str)
|
|
373
|
+
{
|
|
374
|
+
napi_value result;
|
|
375
|
+
napi_create_string_utf8 (env, str, NAPI_AUTO_LENGTH, &result);
|
|
376
|
+
return result;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
static gboolean
|
|
380
|
+
fdn_strv_from_value (napi_env env,
|
|
381
|
+
napi_value value,
|
|
382
|
+
gchar *** strv)
|
|
383
|
+
{
|
|
384
|
+
uint32_t length, i;
|
|
385
|
+
gchar ** vector = NULL;
|
|
386
|
+
|
|
387
|
+
if (napi_get_array_length (env, value, &length) != napi_ok)
|
|
388
|
+
goto invalid_argument;
|
|
389
|
+
|
|
390
|
+
vector = g_new0 (gchar *, length + 1);
|
|
391
|
+
|
|
392
|
+
for (i = 0; i != length; i++)
|
|
393
|
+
{
|
|
394
|
+
napi_value js_str;
|
|
395
|
+
|
|
396
|
+
if (napi_get_element (env, value, i, &js_str) != napi_ok)
|
|
397
|
+
goto invalid_argument;
|
|
398
|
+
|
|
399
|
+
if (!fdn_utf8_from_value (env, js_str, &vector[i]))
|
|
400
|
+
goto invalid_argument;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
*strv = vector;
|
|
404
|
+
return TRUE;
|
|
405
|
+
|
|
406
|
+
invalid_argument:
|
|
407
|
+
{
|
|
408
|
+
napi_throw_error (env, NULL, "expected an array of strings");
|
|
409
|
+
g_strfreev (vector);
|
|
410
|
+
return FALSE;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
static napi_value
|
|
415
|
+
fdn_strv_to_value (napi_env env,
|
|
416
|
+
gchar ** strv)
|
|
417
|
+
{
|
|
418
|
+
napi_value result;
|
|
419
|
+
uint32_t length, i;
|
|
420
|
+
|
|
421
|
+
length = g_strv_length (strv);
|
|
422
|
+
|
|
423
|
+
napi_create_array_with_length (env, length, &result);
|
|
424
|
+
|
|
425
|
+
for (i = 0; i != length; i++)
|
|
426
|
+
napi_set_element (env, result, i, fdn_utf8_to_value (env, strv[i]));
|
|
427
|
+
|
|
428
|
+
return result;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
static napi_value
|
|
432
|
+
fdn_buffer_to_value (napi_env env,
|
|
433
|
+
const guint8 * data,
|
|
434
|
+
gsize size)
|
|
435
|
+
{
|
|
436
|
+
napi_value result;
|
|
437
|
+
napi_create_buffer_copy (env, size, data, NULL, &result);
|
|
438
|
+
return result;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
static gboolean
|
|
442
|
+
fdn_bytes_from_value (napi_env env,
|
|
443
|
+
napi_value value,
|
|
444
|
+
GBytes ** bytes)
|
|
445
|
+
{
|
|
446
|
+
void * data;
|
|
447
|
+
size_t size;
|
|
448
|
+
|
|
449
|
+
if (napi_get_buffer_info (env, value, &data, &size) != napi_ok)
|
|
450
|
+
goto invalid_argument;
|
|
451
|
+
|
|
452
|
+
*bytes = g_bytes_new (data, size);
|
|
453
|
+
return TRUE;
|
|
454
|
+
|
|
455
|
+
invalid_argument:
|
|
456
|
+
{
|
|
457
|
+
napi_throw_error (env, NULL, "expected a buffer");
|
|
458
|
+
return FALSE;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
static napi_value
|
|
463
|
+
fdn_bytes_to_value (napi_env env,
|
|
464
|
+
GBytes * bytes)
|
|
465
|
+
{
|
|
466
|
+
const guint8 * data;
|
|
467
|
+
gsize size;
|
|
468
|
+
|
|
469
|
+
data = g_bytes_get_data (bytes, &size);
|
|
470
|
+
|
|
471
|
+
return fdn_buffer_to_value (env, data, size);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
static gboolean
|
|
475
|
+
fdn_vardict_from_value (napi_env env,
|
|
476
|
+
napi_value value,
|
|
477
|
+
GHashTable ** vardict)
|
|
478
|
+
{
|
|
479
|
+
napi_value keys;
|
|
480
|
+
uint32_t length, i;
|
|
481
|
+
GHashTable * dict = NULL;
|
|
482
|
+
gchar * key = NULL;
|
|
483
|
+
|
|
484
|
+
if (napi_get_property_names (env, value, &keys) != napi_ok)
|
|
485
|
+
goto invalid_argument;
|
|
486
|
+
if (napi_get_array_length (env, keys, &length) != napi_ok)
|
|
487
|
+
goto propagate_error;
|
|
488
|
+
|
|
489
|
+
dict = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref);
|
|
490
|
+
|
|
491
|
+
for (i = 0; i != length; i++)
|
|
492
|
+
{
|
|
493
|
+
napi_value js_key, js_val;
|
|
494
|
+
GVariant * val;
|
|
495
|
+
|
|
496
|
+
if (napi_get_element (env, keys, i, &js_key) != napi_ok)
|
|
497
|
+
goto propagate_error;
|
|
498
|
+
if (!fdn_utf8_from_value (env, js_key, &key))
|
|
499
|
+
goto invalid_argument;
|
|
500
|
+
|
|
501
|
+
if (napi_get_property (env, value, js_key, &js_val) != napi_ok)
|
|
502
|
+
goto propagate_error;
|
|
503
|
+
if (!fdn_variant_from_value (env, js_val, &val))
|
|
504
|
+
goto propagate_error;
|
|
505
|
+
|
|
506
|
+
g_hash_table_insert (dict, g_steal_pointer (&key), g_variant_ref_sink (val));
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
*vardict = dict;
|
|
510
|
+
return TRUE;
|
|
511
|
+
|
|
512
|
+
invalid_argument:
|
|
513
|
+
{
|
|
514
|
+
napi_throw_error (env, NULL, "expected a vardict");
|
|
515
|
+
goto propagate_error;
|
|
516
|
+
}
|
|
517
|
+
propagate_error:
|
|
518
|
+
{
|
|
519
|
+
g_free (key);
|
|
520
|
+
g_clear_pointer (&dict, g_hash_table_unref);
|
|
521
|
+
return FALSE;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
static napi_value
|
|
526
|
+
fdn_vardict_to_value (napi_env env,
|
|
527
|
+
GHashTable * vardict)
|
|
528
|
+
{
|
|
529
|
+
napi_value result;
|
|
530
|
+
GHashTableIter iter;
|
|
531
|
+
gpointer key, value;
|
|
532
|
+
|
|
533
|
+
napi_create_object (env, &result);
|
|
534
|
+
|
|
535
|
+
g_hash_table_iter_init (&iter, vardict);
|
|
536
|
+
while (g_hash_table_iter_next (&iter, &key, &value))
|
|
537
|
+
{
|
|
538
|
+
napi_value js_key, js_value;
|
|
539
|
+
|
|
540
|
+
js_key = fdn_utf8_to_value (env, key);
|
|
541
|
+
js_value = fdn_variant_to_value (env, value);
|
|
542
|
+
|
|
543
|
+
napi_set_property (env, result, js_key, js_value);
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
return result;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
static gboolean
|
|
550
|
+
fdn_variant_from_value (napi_env env,
|
|
551
|
+
napi_value value,
|
|
552
|
+
GVariant ** variant)
|
|
553
|
+
{
|
|
554
|
+
napi_valuetype type;
|
|
555
|
+
|
|
556
|
+
napi_typeof (env, value, &type);
|
|
557
|
+
|
|
558
|
+
switch (type)
|
|
559
|
+
{
|
|
560
|
+
case napi_boolean:
|
|
561
|
+
{
|
|
562
|
+
gboolean b;
|
|
563
|
+
|
|
564
|
+
if (!fdn_boolean_from_value (env, value, &b))
|
|
565
|
+
return FALSE;
|
|
566
|
+
|
|
567
|
+
*variant = g_variant_new_boolean (b);
|
|
568
|
+
return TRUE;
|
|
569
|
+
}
|
|
570
|
+
case napi_number:
|
|
571
|
+
{
|
|
572
|
+
gint64 i;
|
|
573
|
+
|
|
574
|
+
if (!fdn_int64_from_value (env, value, &i))
|
|
575
|
+
return FALSE;
|
|
576
|
+
|
|
577
|
+
*variant = g_variant_new_int64 (i);
|
|
578
|
+
return TRUE;
|
|
579
|
+
}
|
|
580
|
+
case napi_string:
|
|
581
|
+
{
|
|
582
|
+
gchar * str;
|
|
583
|
+
|
|
584
|
+
if (!fdn_utf8_from_value (env, value, &str))
|
|
585
|
+
return FALSE;
|
|
586
|
+
|
|
587
|
+
*variant = g_variant_new_take_string (str);
|
|
588
|
+
return TRUE;
|
|
589
|
+
}
|
|
590
|
+
case napi_object:
|
|
591
|
+
{
|
|
592
|
+
bool is_buffer, is_array;
|
|
593
|
+
GVariantBuilder builder;
|
|
594
|
+
napi_value keys;
|
|
595
|
+
uint32_t length, i;
|
|
596
|
+
|
|
597
|
+
if (napi_is_buffer (env, value, &is_buffer) != napi_ok)
|
|
598
|
+
return FALSE;
|
|
599
|
+
if (is_buffer)
|
|
600
|
+
{
|
|
601
|
+
void * data;
|
|
602
|
+
size_t size;
|
|
603
|
+
gpointer copy;
|
|
604
|
+
|
|
605
|
+
if (napi_get_buffer_info (env, value, &data, &size) != napi_ok)
|
|
606
|
+
return FALSE;
|
|
607
|
+
|
|
608
|
+
copy = g_memdup2 (data, size);
|
|
609
|
+
*variant = g_variant_new_from_data (G_VARIANT_TYPE_BYTESTRING, copy, size, TRUE, g_free, copy);
|
|
610
|
+
return TRUE;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
if (napi_is_array (env, value, &is_array) != napi_ok)
|
|
614
|
+
return FALSE;
|
|
615
|
+
if (is_array)
|
|
616
|
+
{
|
|
617
|
+
uint32_t length;
|
|
618
|
+
|
|
619
|
+
if (napi_get_array_length (env, value, &length) != napi_ok)
|
|
620
|
+
return FALSE;
|
|
621
|
+
|
|
622
|
+
if (length == 2)
|
|
623
|
+
{
|
|
624
|
+
napi_value first;
|
|
625
|
+
napi_valuetype first_type;
|
|
626
|
+
|
|
627
|
+
if (napi_get_element (env, value, 0, &first) != napi_ok)
|
|
628
|
+
return FALSE;
|
|
629
|
+
|
|
630
|
+
napi_typeof (env, first, &first_type);
|
|
631
|
+
|
|
632
|
+
if (first_type == napi_symbol)
|
|
633
|
+
{
|
|
634
|
+
napi_value second;
|
|
635
|
+
GVariant * val;
|
|
636
|
+
napi_value desc;
|
|
637
|
+
gchar * type;
|
|
638
|
+
GVariant * t[2];
|
|
639
|
+
|
|
640
|
+
if (napi_get_element (env, value, 1, &second) != napi_ok)
|
|
641
|
+
return FALSE;
|
|
642
|
+
|
|
643
|
+
if (!fdn_variant_from_value (env, second, &val))
|
|
644
|
+
return FALSE;
|
|
645
|
+
|
|
646
|
+
napi_coerce_to_string (env, first, &desc);
|
|
647
|
+
fdn_utf8_from_value (env, desc, &type);
|
|
648
|
+
|
|
649
|
+
t[0] = g_variant_new_take_string (type);
|
|
650
|
+
t[1] = val;
|
|
651
|
+
|
|
652
|
+
*variant = g_variant_new_tuple (t, G_N_ELEMENTS (t));
|
|
653
|
+
return TRUE;
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
g_variant_builder_init (&builder, G_VARIANT_TYPE ("av"));
|
|
658
|
+
|
|
659
|
+
for (i = 0; i != length; i++)
|
|
660
|
+
{
|
|
661
|
+
napi_value element;
|
|
662
|
+
GVariant * v;
|
|
663
|
+
|
|
664
|
+
if (napi_get_element (env, value, i, &element) != napi_ok)
|
|
665
|
+
{
|
|
666
|
+
g_variant_builder_clear (&builder);
|
|
667
|
+
return FALSE;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
if (!fdn_variant_from_value (env, element, &v))
|
|
671
|
+
{
|
|
672
|
+
g_variant_builder_clear (&builder);
|
|
673
|
+
return FALSE;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
g_variant_builder_add (&builder, "v", v);
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
*variant = g_variant_builder_end (&builder);
|
|
680
|
+
return TRUE;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
|
|
684
|
+
|
|
685
|
+
if (napi_get_property_names (env, value, &keys) != napi_ok)
|
|
686
|
+
return FALSE;
|
|
687
|
+
|
|
688
|
+
if (napi_get_array_length (env, keys, &length) != napi_ok)
|
|
689
|
+
return FALSE;
|
|
690
|
+
|
|
691
|
+
for (i = 0; i != length; i++)
|
|
692
|
+
{
|
|
693
|
+
napi_value key;
|
|
694
|
+
gchar * key_str;
|
|
695
|
+
napi_value val;
|
|
696
|
+
GVariant * v;
|
|
697
|
+
|
|
698
|
+
if (napi_get_element (env, keys, i, &key) != napi_ok)
|
|
699
|
+
return FALSE;
|
|
700
|
+
|
|
701
|
+
if (!fdn_utf8_from_value (env, key, &key_str))
|
|
702
|
+
return FALSE;
|
|
703
|
+
|
|
704
|
+
if (napi_get_property (env, value, key, &val) != napi_ok)
|
|
705
|
+
{
|
|
706
|
+
g_free (key_str);
|
|
707
|
+
return FALSE;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
if (!fdn_variant_from_value (env, val, &v))
|
|
711
|
+
{
|
|
712
|
+
g_free (key_str);
|
|
713
|
+
return FALSE;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
g_variant_builder_add (&builder, "{sv}", key_str, v);
|
|
717
|
+
g_free (key_str);
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
*variant = g_variant_builder_end (&builder);
|
|
721
|
+
return TRUE;
|
|
722
|
+
}
|
|
723
|
+
default:
|
|
724
|
+
break;
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
napi_throw_type_error (env, NULL, "expected value serializable to GVariant");
|
|
728
|
+
return FALSE;
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
static napi_value
|
|
732
|
+
fdn_variant_to_value (napi_env env,
|
|
733
|
+
GVariant * variant)
|
|
734
|
+
{
|
|
735
|
+
napi_value result;
|
|
736
|
+
|
|
737
|
+
switch (g_variant_classify (variant))
|
|
738
|
+
{
|
|
739
|
+
case G_VARIANT_CLASS_STRING:
|
|
740
|
+
{
|
|
741
|
+
const gchar * str = g_variant_get_string (variant, NULL);
|
|
742
|
+
return fdn_utf8_to_value (env, str);
|
|
743
|
+
}
|
|
744
|
+
case G_VARIANT_CLASS_INT64:
|
|
745
|
+
return fdn_int64_to_value (env, g_variant_get_int64 (variant));
|
|
746
|
+
case G_VARIANT_CLASS_UINT64:
|
|
747
|
+
return fdn_uint64_to_value (env, g_variant_get_uint64 (variant));
|
|
748
|
+
case G_VARIANT_CLASS_DOUBLE:
|
|
749
|
+
return fdn_double_to_value (env, g_variant_get_double (variant));
|
|
750
|
+
case G_VARIANT_CLASS_BOOLEAN:
|
|
751
|
+
return fdn_boolean_to_value (env, g_variant_get_boolean (variant));
|
|
752
|
+
case G_VARIANT_CLASS_ARRAY:
|
|
753
|
+
if (g_variant_is_of_type (variant, G_VARIANT_TYPE ("ay")))
|
|
754
|
+
{
|
|
755
|
+
gsize size;
|
|
756
|
+
g_variant_get_fixed_array (variant, &size, sizeof (guint8));
|
|
757
|
+
return fdn_buffer_to_value (env, g_variant_get_data (variant), size);
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
if (g_variant_is_of_type (variant, G_VARIANT_TYPE_VARDICT))
|
|
761
|
+
{
|
|
762
|
+
napi_value dict;
|
|
763
|
+
GVariantIter iter;
|
|
764
|
+
gchar * key;
|
|
765
|
+
GVariant * value;
|
|
766
|
+
|
|
767
|
+
napi_create_object (env, &dict);
|
|
768
|
+
|
|
769
|
+
g_variant_iter_init (&iter, variant);
|
|
770
|
+
while (g_variant_iter_next (&iter, "{sv}", &key, &value))
|
|
771
|
+
{
|
|
772
|
+
napi_value js_key, js_value;
|
|
773
|
+
|
|
774
|
+
js_key = fdn_utf8_to_value (env, key);
|
|
775
|
+
js_value = fdn_variant_to_value (env, value);
|
|
776
|
+
|
|
777
|
+
napi_set_property (env, dict, js_key, js_value);
|
|
778
|
+
|
|
779
|
+
g_variant_unref (value);
|
|
780
|
+
g_free (key);
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
return dict;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
if (g_variant_is_of_type (variant, G_VARIANT_TYPE_ARRAY))
|
|
787
|
+
{
|
|
788
|
+
napi_value array;
|
|
789
|
+
GVariantIter iter;
|
|
790
|
+
uint32_t i;
|
|
791
|
+
GVariant * child;
|
|
792
|
+
|
|
793
|
+
napi_create_array (env, &array);
|
|
794
|
+
|
|
795
|
+
g_variant_iter_init (&iter, variant);
|
|
796
|
+
i = 0;
|
|
797
|
+
while ((child = g_variant_iter_next_value (&iter)) != NULL)
|
|
798
|
+
{
|
|
799
|
+
napi_value element = fdn_variant_to_value (env, child);
|
|
800
|
+
napi_set_element (env, array, i++, element);
|
|
801
|
+
g_variant_unref (child);
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
return array;
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
break;
|
|
808
|
+
case G_VARIANT_CLASS_TUPLE:
|
|
809
|
+
napi_get_undefined (env, &result);
|
|
810
|
+
return result;
|
|
811
|
+
default:
|
|
812
|
+
break;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
napi_get_null (env, &result);
|
|
816
|
+
return result;
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
static gboolean
|
|
820
|
+
fdn_gvalue_from_value (napi_env env,
|
|
821
|
+
GType type,
|
|
822
|
+
napi_value js_value,
|
|
823
|
+
GValue * value)
|
|
824
|
+
{
|
|
825
|
+
g_value_init (value, type);
|
|
826
|
+
|
|
827
|
+
switch (type)
|
|
828
|
+
{
|
|
829
|
+
case G_TYPE_BOOLEAN:
|
|
830
|
+
{
|
|
831
|
+
gboolean b;
|
|
832
|
+
|
|
833
|
+
if (!fdn_boolean_from_value (env, js_value, &b))
|
|
834
|
+
return FALSE;
|
|
835
|
+
g_value_set_boolean (value, b);
|
|
836
|
+
|
|
837
|
+
break;
|
|
838
|
+
}
|
|
839
|
+
case G_TYPE_INT:
|
|
840
|
+
{
|
|
841
|
+
gint i;
|
|
842
|
+
|
|
843
|
+
if (!fdn_int_from_value (env, js_value, &i))
|
|
844
|
+
return FALSE;
|
|
845
|
+
g_value_set_int (value, i);
|
|
846
|
+
|
|
847
|
+
break;
|
|
848
|
+
}
|
|
849
|
+
case G_TYPE_UINT:
|
|
850
|
+
{
|
|
851
|
+
guint u;
|
|
852
|
+
|
|
853
|
+
if (!fdn_uint_from_value (env, js_value, &u))
|
|
854
|
+
return FALSE;
|
|
855
|
+
g_value_set_uint (value, u);
|
|
856
|
+
|
|
857
|
+
break;
|
|
858
|
+
}
|
|
859
|
+
case G_TYPE_FLOAT:
|
|
860
|
+
{
|
|
861
|
+
gdouble d;
|
|
862
|
+
|
|
863
|
+
if (!fdn_double_from_value (env, js_value, &d))
|
|
864
|
+
return FALSE;
|
|
865
|
+
g_value_set_float (value, d);
|
|
866
|
+
|
|
867
|
+
break;
|
|
868
|
+
}
|
|
869
|
+
case G_TYPE_DOUBLE:
|
|
870
|
+
{
|
|
871
|
+
gdouble d;
|
|
872
|
+
|
|
873
|
+
if (!fdn_double_from_value (env, js_value, &d))
|
|
874
|
+
return FALSE;
|
|
875
|
+
g_value_set_double (value, d);
|
|
876
|
+
|
|
877
|
+
break;
|
|
878
|
+
}
|
|
879
|
+
case G_TYPE_STRING:
|
|
880
|
+
{
|
|
881
|
+
gchar * str;
|
|
882
|
+
|
|
883
|
+
if (!fdn_utf8_from_value (env, js_value, &str))
|
|
884
|
+
return FALSE;
|
|
885
|
+
g_value_take_string (value, str);
|
|
886
|
+
|
|
887
|
+
break;
|
|
888
|
+
}
|
|
889
|
+
default:
|
|
890
|
+
{
|
|
891
|
+
gchar * msg;
|
|
892
|
+
|
|
893
|
+
if (G_TYPE_IS_ENUM (type))
|
|
894
|
+
{
|
|
895
|
+
gint e;
|
|
896
|
+
|
|
897
|
+
if (!fdn_enum_from_value (env, type, js_value, &e))
|
|
898
|
+
return FALSE;
|
|
899
|
+
g_value_set_enum (value, e);
|
|
900
|
+
|
|
901
|
+
return TRUE;
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
if (type == G_TYPE_STRV)
|
|
905
|
+
{
|
|
906
|
+
gchar ** strv;
|
|
907
|
+
|
|
908
|
+
if (!fdn_strv_from_value (env, js_value, &strv))
|
|
909
|
+
return FALSE;
|
|
910
|
+
g_value_take_boxed (value, strv);
|
|
911
|
+
|
|
912
|
+
return TRUE;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
if (type == G_TYPE_BYTES)
|
|
916
|
+
{
|
|
917
|
+
GBytes * bytes;
|
|
918
|
+
|
|
919
|
+
if (!fdn_bytes_from_value (env, js_value, &bytes))
|
|
920
|
+
return FALSE;
|
|
921
|
+
g_value_take_boxed (value, bytes);
|
|
922
|
+
|
|
923
|
+
return TRUE;
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
if (type == G_TYPE_HASH_TABLE)
|
|
927
|
+
{
|
|
928
|
+
GHashTable * vardict;
|
|
929
|
+
|
|
930
|
+
if (!fdn_vardict_from_value (env, js_value, &vardict))
|
|
931
|
+
return FALSE;
|
|
932
|
+
g_value_take_boxed (value, vardict);
|
|
933
|
+
|
|
934
|
+
return TRUE;
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
if (type == G_TYPE_TLS_CERTIFICATE)
|
|
938
|
+
{
|
|
939
|
+
GTlsCertificate * certificate;
|
|
940
|
+
|
|
941
|
+
if (!fdn_tls_certificate_from_value (env, js_value, &certificate))
|
|
942
|
+
return FALSE;
|
|
943
|
+
g_value_take_object (value, certificate);
|
|
944
|
+
|
|
945
|
+
return TRUE;
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
msg = g_strdup_printf ("unsupported property type: %s", g_type_name (type));
|
|
949
|
+
napi_throw_type_error (env, NULL, msg);
|
|
950
|
+
g_free (msg);
|
|
951
|
+
|
|
952
|
+
return FALSE;
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
return TRUE;
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
static napi_value
|
|
960
|
+
fdn_gvalue_to_value (napi_env env,
|
|
961
|
+
GValue * value)
|
|
962
|
+
{
|
|
963
|
+
GType gtype;
|
|
964
|
+
|
|
965
|
+
gtype = G_VALUE_TYPE (value);
|
|
966
|
+
|
|
967
|
+
switch (gtype)
|
|
968
|
+
{
|
|
969
|
+
case G_TYPE_BOOLEAN:
|
|
970
|
+
return fdn_boolean_to_value (env, g_value_get_boolean (value));
|
|
971
|
+
case G_TYPE_INT:
|
|
972
|
+
return fdn_int_to_value (env, g_value_get_int (value));
|
|
973
|
+
case G_TYPE_UINT:
|
|
974
|
+
return fdn_uint_to_value (env, g_value_get_uint (value));
|
|
975
|
+
case G_TYPE_FLOAT:
|
|
976
|
+
return fdn_double_to_value (env, g_value_get_float (value));
|
|
977
|
+
case G_TYPE_DOUBLE:
|
|
978
|
+
return fdn_double_to_value (env, g_value_get_double (value));
|
|
979
|
+
case G_TYPE_STRING:
|
|
980
|
+
{
|
|
981
|
+
const gchar * str;
|
|
982
|
+
|
|
983
|
+
str = g_value_get_string (value);
|
|
984
|
+
if (str == NULL)
|
|
985
|
+
{
|
|
986
|
+
napi_value result;
|
|
987
|
+
napi_get_null (env, &result);
|
|
988
|
+
return result;
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
return fdn_utf8_to_value (env, str);
|
|
992
|
+
}
|
|
993
|
+
default:
|
|
994
|
+
{
|
|
995
|
+
napi_value result;
|
|
996
|
+
|
|
997
|
+
if (G_TYPE_IS_ENUM (gtype))
|
|
998
|
+
return fdn_enum_to_value (env, gtype, g_value_get_enum (value));
|
|
999
|
+
|
|
1000
|
+
if (gtype == G_TYPE_BYTES)
|
|
1001
|
+
{
|
|
1002
|
+
GBytes * bytes = g_value_get_boxed (value);
|
|
1003
|
+
if (bytes != NULL)
|
|
1004
|
+
{
|
|
1005
|
+
return fdn_bytes_to_value (env, bytes);
|
|
1006
|
+
}
|
|
1007
|
+
else
|
|
1008
|
+
{
|
|
1009
|
+
napi_get_null (env, &result);
|
|
1010
|
+
return result;
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
if (G_TYPE_IS_OBJECT (gtype))
|
|
1015
|
+
result = fdn_object_subclass_to_value (env, g_value_get_object (value));
|
|
1016
|
+
else
|
|
1017
|
+
napi_get_null (env, &result);
|
|
1018
|
+
|
|
1019
|
+
return result;
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
static gboolean
|
|
1025
|
+
fdn_error_from_value (napi_env env,
|
|
1026
|
+
napi_value value,
|
|
1027
|
+
GError ** error)
|
|
1028
|
+
{
|
|
1029
|
+
napi_value js_message;
|
|
1030
|
+
gchar * raw_message;
|
|
1031
|
+
GString * message;
|
|
1032
|
+
|
|
1033
|
+
if (napi_get_named_property (env, value, "message", &js_message) != napi_ok)
|
|
1034
|
+
return FALSE;
|
|
1035
|
+
|
|
1036
|
+
if (!fdn_utf8_from_value (env, js_message, &raw_message))
|
|
1037
|
+
return FALSE;
|
|
1038
|
+
|
|
1039
|
+
message = g_string_new ("");
|
|
1040
|
+
g_string_append_unichar (message, g_unichar_toupper (g_utf8_get_char (raw_message)));
|
|
1041
|
+
g_string_append (message, g_utf8_offset_to_pointer (raw_message, 1));
|
|
1042
|
+
|
|
1043
|
+
*error = g_error_new_literal (FRIDA_ERROR, FRIDA_ERROR_INVALID_ARGUMENT, message->str);
|
|
1044
|
+
|
|
1045
|
+
g_free (raw_message);
|
|
1046
|
+
g_string_free (message, TRUE);
|
|
1047
|
+
|
|
1048
|
+
return TRUE;
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
static napi_value
|
|
1052
|
+
fdn_error_to_value (napi_env env,
|
|
1053
|
+
GError * error)
|
|
1054
|
+
{
|
|
1055
|
+
napi_value result;
|
|
1056
|
+
napi_create_error (env, NULL, fdn_utf8_to_value (env, error->message), &result);
|
|
1057
|
+
return result;
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
static gboolean
|
|
1061
|
+
fdn_file_from_value (napi_env env,
|
|
1062
|
+
napi_value value,
|
|
1063
|
+
GFile ** file)
|
|
1064
|
+
{
|
|
1065
|
+
gchar * path;
|
|
1066
|
+
|
|
1067
|
+
if (!fdn_utf8_from_value (env, value, &path))
|
|
1068
|
+
return FALSE;
|
|
1069
|
+
*file = g_file_new_for_path (path);
|
|
1070
|
+
g_free (path);
|
|
1071
|
+
|
|
1072
|
+
return TRUE;
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
static napi_value
|
|
1076
|
+
fdn_file_to_value (napi_env env,
|
|
1077
|
+
GFile * file)
|
|
1078
|
+
{
|
|
1079
|
+
napi_value result;
|
|
1080
|
+
gchar * path;
|
|
1081
|
+
|
|
1082
|
+
path = g_file_get_path (file);
|
|
1083
|
+
result = fdn_utf8_to_value (env, path);
|
|
1084
|
+
g_free (path);
|
|
1085
|
+
|
|
1086
|
+
return result;
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
static gboolean
|
|
1090
|
+
fdn_tls_certificate_from_value (napi_env env,
|
|
1091
|
+
napi_value value,
|
|
1092
|
+
GTlsCertificate ** certificate)
|
|
1093
|
+
{
|
|
1094
|
+
gchar * str;
|
|
1095
|
+
GError * error = NULL;
|
|
1096
|
+
|
|
1097
|
+
if (!fdn_utf8_from_value (env, value, &str))
|
|
1098
|
+
return FALSE;
|
|
1099
|
+
|
|
1100
|
+
if (strchr (str, '\n') != NULL)
|
|
1101
|
+
*certificate = g_tls_certificate_new_from_pem (str, -1, &error);
|
|
1102
|
+
else
|
|
1103
|
+
*certificate = g_tls_certificate_new_from_file (str, &error);
|
|
1104
|
+
|
|
1105
|
+
g_free (str);
|
|
1106
|
+
|
|
1107
|
+
if (error != NULL)
|
|
1108
|
+
goto invalid_argument;
|
|
1109
|
+
return TRUE;
|
|
1110
|
+
|
|
1111
|
+
invalid_argument:
|
|
1112
|
+
{
|
|
1113
|
+
napi_throw (env, fdn_error_to_value (env, error));
|
|
1114
|
+
g_error_free (error);
|
|
1115
|
+
return FALSE;
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
static napi_value
|
|
1120
|
+
fdn_tls_certificate_to_value (napi_env env,
|
|
1121
|
+
GTlsCertificate * certificate)
|
|
1122
|
+
{
|
|
1123
|
+
napi_value result;
|
|
1124
|
+
gchar * pem;
|
|
1125
|
+
|
|
1126
|
+
g_object_get (certificate, "certificate-pem", &pem, NULL);
|
|
1127
|
+
result = fdn_utf8_to_value (env, pem);
|
|
1128
|
+
g_free (pem);
|
|
1129
|
+
|
|
1130
|
+
return result;
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
static gboolean
|
|
1134
|
+
fdn_options_from_value (napi_env env,
|
|
1135
|
+
GType object_type,
|
|
1136
|
+
napi_value value,
|
|
1137
|
+
gpointer * options)
|
|
1138
|
+
{
|
|
1139
|
+
gboolean success = FALSE;
|
|
1140
|
+
napi_valuetype value_type;
|
|
1141
|
+
napi_value keys;
|
|
1142
|
+
uint32_t n_keys;
|
|
1143
|
+
guint n_properties = 0;
|
|
1144
|
+
const char ** property_names = NULL;
|
|
1145
|
+
GValue * property_values = NULL;
|
|
1146
|
+
GObjectClass * object_class = NULL;
|
|
1147
|
+
uint32_t i;
|
|
1148
|
+
gchar * gobject_property_name = NULL;
|
|
1149
|
+
|
|
1150
|
+
if (napi_typeof (env, value, &value_type) != napi_ok || value_type != napi_object)
|
|
1151
|
+
goto expected_an_object;
|
|
1152
|
+
|
|
1153
|
+
if (napi_get_property_names (env, value, &keys) != napi_ok)
|
|
1154
|
+
goto beach;
|
|
1155
|
+
|
|
1156
|
+
if (napi_get_array_length (env, keys, &n_keys) != napi_ok)
|
|
1157
|
+
goto beach;
|
|
1158
|
+
|
|
1159
|
+
property_names = g_newa (const char *, n_keys);
|
|
1160
|
+
property_values = g_newa (GValue, n_keys);
|
|
1161
|
+
|
|
1162
|
+
object_class = G_OBJECT_CLASS (g_type_class_ref (object_type));
|
|
1163
|
+
|
|
1164
|
+
for (i = 0; i != n_keys; i++)
|
|
1165
|
+
{
|
|
1166
|
+
napi_value js_key, js_value;
|
|
1167
|
+
gchar * property_name;
|
|
1168
|
+
GParamSpec * pspec;
|
|
1169
|
+
|
|
1170
|
+
if (napi_get_element (env, keys, i, &js_key) != napi_ok)
|
|
1171
|
+
goto beach;
|
|
1172
|
+
|
|
1173
|
+
if (!fdn_utf8_from_value (env, js_key, &property_name))
|
|
1174
|
+
goto beach;
|
|
1175
|
+
|
|
1176
|
+
gobject_property_name = fdn_camel_case_to_kebab_case (property_name);
|
|
1177
|
+
g_free (property_name);
|
|
1178
|
+
|
|
1179
|
+
pspec = g_object_class_find_property (object_class, gobject_property_name);
|
|
1180
|
+
if (pspec == NULL)
|
|
1181
|
+
{
|
|
1182
|
+
g_free (gobject_property_name);
|
|
1183
|
+
gobject_property_name = NULL;
|
|
1184
|
+
continue;
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1187
|
+
if (napi_get_property (env, value, js_key, &js_value) != napi_ok)
|
|
1188
|
+
goto beach;
|
|
1189
|
+
|
|
1190
|
+
if (!fdn_gvalue_from_value (env, pspec->value_type, js_value, &property_values[n_properties]))
|
|
1191
|
+
goto beach;
|
|
1192
|
+
|
|
1193
|
+
property_names[n_properties] = g_steal_pointer (&gobject_property_name);
|
|
1194
|
+
n_properties++;
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
*options = g_object_new_with_properties (object_type, n_properties, property_names, property_values);
|
|
1198
|
+
|
|
1199
|
+
success = TRUE;
|
|
1200
|
+
goto beach;
|
|
1201
|
+
|
|
1202
|
+
expected_an_object:
|
|
1203
|
+
{
|
|
1204
|
+
napi_throw_type_error (env, NULL, "expected an object");
|
|
1205
|
+
goto beach;
|
|
1206
|
+
}
|
|
1207
|
+
beach:
|
|
1208
|
+
{
|
|
1209
|
+
g_free (gobject_property_name);
|
|
1210
|
+
|
|
1211
|
+
for (i = 0; i != n_properties; i++)
|
|
1212
|
+
{
|
|
1213
|
+
g_free ((gchar *) property_names[i]);
|
|
1214
|
+
g_value_unset (&property_values[i]);
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
g_clear_pointer (&object_class, g_type_class_unref);
|
|
1218
|
+
|
|
1219
|
+
return success;
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
static napi_value
|
|
1224
|
+
fdn_object_subclass_to_value (napi_env env,
|
|
1225
|
+
GObject * object)
|
|
1226
|
+
{
|
|
1227
|
+
napi_value result;
|
|
1228
|
+
napi_ref ctor;
|
|
1229
|
+
|
|
1230
|
+
if (object == NULL)
|
|
1231
|
+
{
|
|
1232
|
+
napi_get_null (env, &result);
|
|
1233
|
+
return result;
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
ctor = g_hash_table_lookup (fdn_constructors, GSIZE_TO_POINTER (G_OBJECT_TYPE (object)));
|
|
1237
|
+
if (ctor == NULL)
|
|
1238
|
+
goto unsupported_type;
|
|
1239
|
+
|
|
1240
|
+
return fdn_object_new (env, object, ctor);
|
|
1241
|
+
|
|
1242
|
+
unsupported_type:
|
|
1243
|
+
{
|
|
1244
|
+
napi_get_null (env, &result);
|
|
1245
|
+
return result;
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
static napi_value
|
|
1250
|
+
fdn_object_new (napi_env env,
|
|
1251
|
+
GObject * handle,
|
|
1252
|
+
napi_ref constructor)
|
|
1253
|
+
{
|
|
1254
|
+
napi_value result, ctor, handle_wrapper;
|
|
1255
|
+
napi_ref wrapper_ref;
|
|
1256
|
+
|
|
1257
|
+
wrapper_ref = g_object_get_data (handle, "fdn-wrapper");
|
|
1258
|
+
if (wrapper_ref != NULL)
|
|
1259
|
+
{
|
|
1260
|
+
if (napi_get_reference_value (env, wrapper_ref, &result) == napi_ok && result != NULL)
|
|
1261
|
+
return result;
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
napi_get_reference_value (env, constructor, &ctor);
|
|
1265
|
+
|
|
1266
|
+
napi_create_external (env, handle, NULL, NULL, &handle_wrapper);
|
|
1267
|
+
napi_type_tag_object (env, handle_wrapper, &fdn_handle_wrapper_type_tag);
|
|
1268
|
+
|
|
1269
|
+
napi_new_instance (env, ctor, 1, &handle_wrapper, &result);
|
|
1270
|
+
|
|
1271
|
+
return result;
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
static gboolean
|
|
1275
|
+
fdn_object_wrap (napi_env env,
|
|
1276
|
+
napi_value wrapper,
|
|
1277
|
+
GObject * handle,
|
|
1278
|
+
napi_finalize finalizer)
|
|
1279
|
+
{
|
|
1280
|
+
napi_ref ref;
|
|
1281
|
+
|
|
1282
|
+
if (napi_type_tag_object (env, wrapper, &fdn_object_type_tag) != napi_ok)
|
|
1283
|
+
return FALSE;
|
|
1284
|
+
|
|
1285
|
+
if (napi_wrap (env, wrapper, handle, NULL, NULL, NULL) != napi_ok)
|
|
1286
|
+
return FALSE;
|
|
1287
|
+
|
|
1288
|
+
if (napi_add_finalizer (env, wrapper, handle, finalizer, NULL, NULL) != napi_ok)
|
|
1289
|
+
return FALSE;
|
|
1290
|
+
|
|
1291
|
+
napi_create_reference (env, wrapper, 0, &ref);
|
|
1292
|
+
g_object_set_data (handle, "fdn-wrapper", ref);
|
|
1293
|
+
|
|
1294
|
+
return TRUE;
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
static gboolean
|
|
1298
|
+
fdn_object_unwrap (napi_env env,
|
|
1299
|
+
napi_value wrapper,
|
|
1300
|
+
GType expected_type,
|
|
1301
|
+
GObject ** handle)
|
|
1302
|
+
{
|
|
1303
|
+
bool is_instance;
|
|
1304
|
+
GObject * obj;
|
|
1305
|
+
|
|
1306
|
+
if (napi_check_object_type_tag (env, wrapper, &fdn_object_type_tag, &is_instance) != napi_ok || !is_instance)
|
|
1307
|
+
goto invalid_tag;
|
|
1308
|
+
|
|
1309
|
+
if (napi_unwrap (env, wrapper, (void **) &obj) != napi_ok)
|
|
1310
|
+
goto invalid_tag;
|
|
1311
|
+
|
|
1312
|
+
if (!g_type_is_a (G_OBJECT_TYPE (obj), expected_type))
|
|
1313
|
+
goto invalid_type;
|
|
1314
|
+
|
|
1315
|
+
*handle = g_object_ref (obj);
|
|
1316
|
+
return TRUE;
|
|
1317
|
+
|
|
1318
|
+
invalid_tag:
|
|
1319
|
+
{
|
|
1320
|
+
gchar * msg;
|
|
1321
|
+
|
|
1322
|
+
msg = g_strdup_printf ("expected an instance of %s", g_type_name (expected_type));
|
|
1323
|
+
napi_throw_type_error (env, NULL, msg);
|
|
1324
|
+
g_free (msg);
|
|
1325
|
+
|
|
1326
|
+
return FALSE;
|
|
1327
|
+
}
|
|
1328
|
+
invalid_type:
|
|
1329
|
+
{
|
|
1330
|
+
gchar * msg;
|
|
1331
|
+
|
|
1332
|
+
msg = g_strdup_printf ("expected an instance of %s, got a %s",
|
|
1333
|
+
g_type_name (expected_type),
|
|
1334
|
+
g_type_name (G_OBJECT_TYPE (obj)));
|
|
1335
|
+
napi_throw_type_error (env, NULL, msg);
|
|
1336
|
+
g_free (msg);
|
|
1337
|
+
|
|
1338
|
+
return FALSE;
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
static void
|
|
1343
|
+
fdn_object_finalize (napi_env env,
|
|
1344
|
+
void * finalize_data,
|
|
1345
|
+
void * finalize_hint)
|
|
1346
|
+
{
|
|
1347
|
+
GObject * handle = G_OBJECT (finalize_data);
|
|
1348
|
+
|
|
1349
|
+
napi_delete_reference (env, g_object_steal_data (handle, "fdn-wrapper"));
|
|
1350
|
+
|
|
1351
|
+
g_object_unref (handle);
|
|
1352
|
+
}
|
|
1353
|
+
|
|
1354
|
+
static napi_value
|
|
1355
|
+
fdn_object_get_signal (napi_env env,
|
|
1356
|
+
napi_callback_info info,
|
|
1357
|
+
const gchar * name,
|
|
1358
|
+
const gchar * js_storage_name,
|
|
1359
|
+
FdnSignalBehavior behavior)
|
|
1360
|
+
{
|
|
1361
|
+
napi_value result, jsthis, js_storage_name_value;
|
|
1362
|
+
napi_valuetype type;
|
|
1363
|
+
|
|
1364
|
+
if (napi_get_cb_info (env, info, NULL, NULL, &jsthis, NULL) != napi_ok)
|
|
1365
|
+
return NULL;
|
|
1366
|
+
|
|
1367
|
+
js_storage_name_value = fdn_utf8_to_value (env, js_storage_name);
|
|
1368
|
+
|
|
1369
|
+
if (napi_get_property (env, jsthis, js_storage_name_value, &result) != napi_ok)
|
|
1370
|
+
return NULL;
|
|
1371
|
+
|
|
1372
|
+
if (napi_typeof (env, result, &type) != napi_ok)
|
|
1373
|
+
return NULL;
|
|
1374
|
+
|
|
1375
|
+
if (type == napi_undefined)
|
|
1376
|
+
{{
|
|
1377
|
+
GObject * handle;
|
|
1378
|
+
|
|
1379
|
+
if (napi_unwrap (env, jsthis, (void **) &handle) != napi_ok)
|
|
1380
|
+
return NULL;
|
|
1381
|
+
|
|
1382
|
+
result = fdn_signal_new (env, handle, name, behavior);
|
|
1383
|
+
napi_set_property (env, jsthis, js_storage_name_value, result);
|
|
1384
|
+
}}
|
|
1385
|
+
|
|
1386
|
+
return result;
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
static napi_value
|
|
1390
|
+
fdn_signal_new (napi_env env,
|
|
1391
|
+
GObject * handle,
|
|
1392
|
+
const gchar * name,
|
|
1393
|
+
FdnSignalBehavior behavior)
|
|
1394
|
+
{
|
|
1395
|
+
napi_value result, constructor, handle_wrapper;
|
|
1396
|
+
napi_value args[3];
|
|
1397
|
+
|
|
1398
|
+
napi_get_reference_value (env, fdn_signal_constructor, &constructor);
|
|
1399
|
+
|
|
1400
|
+
napi_create_external (env, handle, NULL, NULL, &handle_wrapper);
|
|
1401
|
+
napi_type_tag_object (env, handle_wrapper, &fdn_handle_wrapper_type_tag);
|
|
1402
|
+
|
|
1403
|
+
args[0] = handle_wrapper;
|
|
1404
|
+
args[1] = fdn_utf8_to_value (env, name);
|
|
1405
|
+
args[2] = fdn_int_to_value (env, behavior);
|
|
1406
|
+
|
|
1407
|
+
napi_new_instance (env, constructor, G_N_ELEMENTS (args), args, &result);
|
|
1408
|
+
|
|
1409
|
+
return result;
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
static void
|
|
1413
|
+
fdn_signal_register (napi_env env,
|
|
1414
|
+
napi_value exports)
|
|
1415
|
+
{
|
|
1416
|
+
napi_property_descriptor properties[] =
|
|
1417
|
+
{
|
|
1418
|
+
{ "connect", NULL, fdn_signal_connect, NULL, NULL, NULL, napi_default, NULL },
|
|
1419
|
+
{ "disconnect", NULL, fdn_signal_disconnect, NULL, NULL, NULL, napi_default, NULL },
|
|
1420
|
+
};
|
|
1421
|
+
napi_value constructor;
|
|
1422
|
+
|
|
1423
|
+
napi_define_class (env, "Signal", NAPI_AUTO_LENGTH, fdn_signal_construct, NULL, G_N_ELEMENTS (properties), properties, &constructor);
|
|
1424
|
+
napi_create_reference (env, constructor, 1, &fdn_signal_constructor);
|
|
1425
|
+
|
|
1426
|
+
napi_set_named_property (env, exports, "Signal", constructor);
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
static napi_value
|
|
1430
|
+
fdn_signal_construct (napi_env env,
|
|
1431
|
+
napi_callback_info info)
|
|
1432
|
+
{
|
|
1433
|
+
size_t argc = 3;
|
|
1434
|
+
napi_value args[3];
|
|
1435
|
+
napi_value jsthis;
|
|
1436
|
+
GObject * handle;
|
|
1437
|
+
bool is_instance;
|
|
1438
|
+
gchar * name = NULL;
|
|
1439
|
+
FdnSignalBehavior behavior;
|
|
1440
|
+
FdnSignal * sig = NULL;
|
|
1441
|
+
|
|
1442
|
+
if (napi_get_cb_info (env, info, &argc, args, &jsthis, NULL) != napi_ok)
|
|
1443
|
+
goto propagate_error;
|
|
1444
|
+
|
|
1445
|
+
if (argc != 3)
|
|
1446
|
+
goto missing_argument;
|
|
1447
|
+
|
|
1448
|
+
if (napi_check_object_type_tag (env, args[0], &fdn_handle_wrapper_type_tag, &is_instance) != napi_ok || !is_instance)
|
|
1449
|
+
goto invalid_handle;
|
|
1450
|
+
|
|
1451
|
+
if (napi_get_value_external (env, args[0], (void **) &handle) != napi_ok)
|
|
1452
|
+
goto propagate_error;
|
|
1453
|
+
|
|
1454
|
+
if (!fdn_utf8_from_value (env, args[1], &name))
|
|
1455
|
+
goto propagate_error;
|
|
1456
|
+
|
|
1457
|
+
if (!fdn_int_from_value (env, args[2], (gint *) &behavior))
|
|
1458
|
+
goto propagate_error;
|
|
1459
|
+
if (behavior != FDN_SIGNAL_ALLOW_EXIT && behavior != FDN_SIGNAL_KEEP_ALIVE)
|
|
1460
|
+
goto invalid_behavior;
|
|
1461
|
+
|
|
1462
|
+
sig = g_slice_new (FdnSignal);
|
|
1463
|
+
sig->handle = g_object_ref (handle);
|
|
1464
|
+
sig->id = g_signal_lookup (name, G_OBJECT_TYPE (sig->handle));
|
|
1465
|
+
sig->behavior = behavior;
|
|
1466
|
+
sig->closures = NULL;
|
|
1467
|
+
if (sig->id == 0)
|
|
1468
|
+
goto invalid_signal_name;
|
|
1469
|
+
|
|
1470
|
+
if (napi_wrap (env, jsthis, sig, NULL, NULL, NULL) != napi_ok)
|
|
1471
|
+
goto propagate_error;
|
|
1472
|
+
|
|
1473
|
+
if (napi_add_finalizer (env, jsthis, sig, fdn_signal_finalize, NULL, NULL) != napi_ok)
|
|
1474
|
+
goto propagate_error;
|
|
1475
|
+
|
|
1476
|
+
g_free (name);
|
|
1477
|
+
|
|
1478
|
+
return jsthis;
|
|
1479
|
+
|
|
1480
|
+
missing_argument:
|
|
1481
|
+
{
|
|
1482
|
+
napi_throw_error (env, NULL, "missing argument");
|
|
1483
|
+
goto propagate_error;
|
|
1484
|
+
}
|
|
1485
|
+
invalid_handle:
|
|
1486
|
+
{
|
|
1487
|
+
napi_throw_type_error (env, NULL, "expected an object handle");
|
|
1488
|
+
goto propagate_error;
|
|
1489
|
+
}
|
|
1490
|
+
invalid_behavior:
|
|
1491
|
+
{
|
|
1492
|
+
napi_throw_error (env, NULL, "invalid behavior");
|
|
1493
|
+
goto propagate_error;
|
|
1494
|
+
}
|
|
1495
|
+
invalid_signal_name:
|
|
1496
|
+
{
|
|
1497
|
+
napi_throw_type_error (env, NULL, "bad signal name");
|
|
1498
|
+
goto propagate_error;
|
|
1499
|
+
}
|
|
1500
|
+
propagate_error:
|
|
1501
|
+
{
|
|
1502
|
+
if (sig != NULL)
|
|
1503
|
+
fdn_signal_finalize (env, sig, NULL);
|
|
1504
|
+
|
|
1505
|
+
g_free (name);
|
|
1506
|
+
|
|
1507
|
+
return NULL;
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
static void
|
|
1512
|
+
fdn_signal_finalize (napi_env env,
|
|
1513
|
+
void * finalize_data,
|
|
1514
|
+
void * finalize_hint)
|
|
1515
|
+
{
|
|
1516
|
+
FdnSignal * sig = finalize_data;
|
|
1517
|
+
GSList * cur;
|
|
1518
|
+
|
|
1519
|
+
for (cur = sig->closures; cur != NULL; cur = cur->next)
|
|
1520
|
+
fdn_signal_disconnect_closure (sig, cur->data);
|
|
1521
|
+
g_slist_free (sig->closures);
|
|
1522
|
+
|
|
1523
|
+
g_object_unref (sig->handle);
|
|
1524
|
+
|
|
1525
|
+
g_slice_free (FdnSignal, sig);
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
static napi_value
|
|
1529
|
+
fdn_signal_connect (napi_env env,
|
|
1530
|
+
napi_callback_info info)
|
|
1531
|
+
{
|
|
1532
|
+
napi_value js_retval;
|
|
1533
|
+
FdnSignal * self;
|
|
1534
|
+
napi_value js_self, handler;
|
|
1535
|
+
FdnSignalClosure * sc;
|
|
1536
|
+
GClosure * closure;
|
|
1537
|
+
|
|
1538
|
+
if (!fdn_signal_parse_arguments (env, info, &self, &js_self, &handler))
|
|
1539
|
+
return NULL;
|
|
1540
|
+
|
|
1541
|
+
sc = fdn_signal_closure_new (env, self, js_self, handler);
|
|
1542
|
+
|
|
1543
|
+
closure = (GClosure *) sc;
|
|
1544
|
+
g_closure_ref (closure);
|
|
1545
|
+
g_closure_sink (closure);
|
|
1546
|
+
self->closures = g_slist_prepend (self->closures, sc);
|
|
1547
|
+
|
|
1548
|
+
sc->handler_id = g_signal_connect_closure_by_id (self->handle, self->id, 0, closure, TRUE);
|
|
1549
|
+
|
|
1550
|
+
napi_get_undefined (env, &js_retval);
|
|
1551
|
+
|
|
1552
|
+
return js_retval;
|
|
1553
|
+
}
|
|
1554
|
+
|
|
1555
|
+
static napi_value
|
|
1556
|
+
fdn_signal_disconnect (napi_env env,
|
|
1557
|
+
napi_callback_info info)
|
|
1558
|
+
{
|
|
1559
|
+
napi_value js_retval;
|
|
1560
|
+
FdnSignal * self;
|
|
1561
|
+
napi_value handler;
|
|
1562
|
+
GSList * cur;
|
|
1563
|
+
|
|
1564
|
+
if (!fdn_signal_parse_arguments (env, info, &self, NULL, &handler))
|
|
1565
|
+
return NULL;
|
|
1566
|
+
|
|
1567
|
+
for (cur = self->closures; cur != NULL; cur = cur->next)
|
|
1568
|
+
{
|
|
1569
|
+
FdnSignalClosure * closure = cur->data;
|
|
1570
|
+
napi_value candidate_handler;
|
|
1571
|
+
bool same_handler;
|
|
1572
|
+
|
|
1573
|
+
napi_get_reference_value (env, closure->handler, &candidate_handler);
|
|
1574
|
+
|
|
1575
|
+
napi_strict_equals (env, candidate_handler, handler, &same_handler);
|
|
1576
|
+
|
|
1577
|
+
if (same_handler)
|
|
1578
|
+
{
|
|
1579
|
+
fdn_signal_disconnect_closure (self, closure);
|
|
1580
|
+
self->closures = g_slist_delete_link (self->closures, cur);
|
|
1581
|
+
break;
|
|
1582
|
+
}
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1585
|
+
napi_get_undefined (env, &js_retval);
|
|
1586
|
+
|
|
1587
|
+
return js_retval;
|
|
1588
|
+
}
|
|
1589
|
+
|
|
1590
|
+
static void
|
|
1591
|
+
fdn_signal_disconnect_closure (FdnSignal * self,
|
|
1592
|
+
FdnSignalClosure * closure)
|
|
1593
|
+
{
|
|
1594
|
+
g_signal_handler_disconnect (self->handle, closure->handler_id);
|
|
1595
|
+
closure->handler_id = 0;
|
|
1596
|
+
|
|
1597
|
+
closure->state = FDN_SIGNAL_CLOSURE_CLOSED;
|
|
1598
|
+
|
|
1599
|
+
g_closure_unref ((GClosure *) closure);
|
|
1600
|
+
}
|
|
1601
|
+
|
|
1602
|
+
static gboolean
|
|
1603
|
+
fdn_signal_parse_arguments (napi_env env,
|
|
1604
|
+
napi_callback_info info,
|
|
1605
|
+
FdnSignal ** self,
|
|
1606
|
+
napi_value * js_self,
|
|
1607
|
+
napi_value * handler)
|
|
1608
|
+
{
|
|
1609
|
+
size_t argc = 1;
|
|
1610
|
+
napi_value jsthis;
|
|
1611
|
+
|
|
1612
|
+
if (napi_get_cb_info (env, info, &argc, handler, &jsthis, NULL) != napi_ok)
|
|
1613
|
+
goto propagate_error;
|
|
1614
|
+
|
|
1615
|
+
if (napi_unwrap (env, jsthis, (void **) self) != napi_ok)
|
|
1616
|
+
goto propagate_error;
|
|
1617
|
+
|
|
1618
|
+
if (js_self != NULL)
|
|
1619
|
+
*js_self = jsthis;
|
|
1620
|
+
|
|
1621
|
+
if (argc != 1)
|
|
1622
|
+
goto missing_handler;
|
|
1623
|
+
|
|
1624
|
+
if (!fdn_is_function (env, *handler))
|
|
1625
|
+
goto invalid_handler;
|
|
1626
|
+
|
|
1627
|
+
return TRUE;
|
|
1628
|
+
|
|
1629
|
+
missing_handler:
|
|
1630
|
+
{
|
|
1631
|
+
napi_throw_error (env, NULL, "missing argument: handler");
|
|
1632
|
+
return FALSE;
|
|
1633
|
+
}
|
|
1634
|
+
invalid_handler:
|
|
1635
|
+
{
|
|
1636
|
+
napi_throw_error (env, NULL, "expected a function");
|
|
1637
|
+
return FALSE;
|
|
1638
|
+
}
|
|
1639
|
+
propagate_error:
|
|
1640
|
+
{
|
|
1641
|
+
return FALSE;
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
|
|
1645
|
+
static FdnSignalClosure *
|
|
1646
|
+
fdn_signal_closure_new (napi_env env,
|
|
1647
|
+
FdnSignal * sig,
|
|
1648
|
+
napi_value js_sig,
|
|
1649
|
+
napi_value handler)
|
|
1650
|
+
{
|
|
1651
|
+
FdnSignalClosure * sc;
|
|
1652
|
+
GClosure * closure;
|
|
1653
|
+
|
|
1654
|
+
closure = g_closure_new_simple (sizeof (FdnSignalClosure), NULL);
|
|
1655
|
+
g_closure_add_finalize_notifier (closure, NULL, fdn_signal_closure_finalize);
|
|
1656
|
+
g_closure_set_marshal (closure, fdn_signal_closure_marshal);
|
|
1657
|
+
|
|
1658
|
+
sc = (FdnSignalClosure *) closure;
|
|
1659
|
+
sc->sig = sig;
|
|
1660
|
+
napi_create_reference (env, js_sig, 1, &sc->js_sig);
|
|
1661
|
+
sc->state = FDN_SIGNAL_CLOSURE_OPEN;
|
|
1662
|
+
napi_create_threadsafe_function (env, NULL, NULL, fdn_utf8_to_value (env, g_signal_name (sig->id)), 0, 1, NULL, NULL, sc,
|
|
1663
|
+
fdn_signal_closure_deliver, &sc->tsfn);
|
|
1664
|
+
|
|
1665
|
+
if (sig->behavior == FDN_SIGNAL_ALLOW_EXIT)
|
|
1666
|
+
napi_unref_threadsafe_function (env, sc->tsfn);
|
|
1667
|
+
|
|
1668
|
+
napi_create_reference (env, handler, 1, &sc->handler);
|
|
1669
|
+
|
|
1670
|
+
return sc;
|
|
1671
|
+
}
|
|
1672
|
+
|
|
1673
|
+
static void
|
|
1674
|
+
fdn_signal_closure_finalize (gpointer data,
|
|
1675
|
+
GClosure * closure)
|
|
1676
|
+
{
|
|
1677
|
+
FdnSignalClosure * self = (FdnSignalClosure *) closure;
|
|
1678
|
+
FdnSignalClosureMessage * message;
|
|
1679
|
+
FdnSignalClosureMessageDestroy * d;
|
|
1680
|
+
|
|
1681
|
+
if (fdn_in_cleanup)
|
|
1682
|
+
return;
|
|
1683
|
+
|
|
1684
|
+
message = g_slice_new (FdnSignalClosureMessage);
|
|
1685
|
+
message->type = FDN_SIGNAL_CLOSURE_MESSAGE_DESTROY;
|
|
1686
|
+
|
|
1687
|
+
d = &message->payload.destroy;
|
|
1688
|
+
d->js_sig = self->js_sig;
|
|
1689
|
+
d->tsfn = self->tsfn;
|
|
1690
|
+
d->handler = self->handler;
|
|
1691
|
+
|
|
1692
|
+
napi_call_threadsafe_function (self->tsfn, message, napi_tsfn_blocking);
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1695
|
+
static void
|
|
1696
|
+
fdn_signal_closure_marshal (GClosure * closure,
|
|
1697
|
+
GValue * return_gvalue,
|
|
1698
|
+
guint n_param_values,
|
|
1699
|
+
const GValue * param_values,
|
|
1700
|
+
gpointer invocation_hint,
|
|
1701
|
+
gpointer marshal_data)
|
|
1702
|
+
{
|
|
1703
|
+
FdnSignalClosure * self = (FdnSignalClosure *) closure;
|
|
1704
|
+
FdnSignalClosureMessage * message;
|
|
1705
|
+
GArray * args;
|
|
1706
|
+
guint i;
|
|
1707
|
+
|
|
1708
|
+
message = g_slice_new (FdnSignalClosureMessage);
|
|
1709
|
+
message->type = FDN_SIGNAL_CLOSURE_MESSAGE_MARSHAL;
|
|
1710
|
+
|
|
1711
|
+
g_assert (n_param_values >= 1);
|
|
1712
|
+
args = g_array_sized_new (FALSE, FALSE, sizeof (GValue), n_param_values - 1);
|
|
1713
|
+
message->payload.marshal.args = args;
|
|
1714
|
+
|
|
1715
|
+
for (i = 1; i != n_param_values; i++)
|
|
1716
|
+
{
|
|
1717
|
+
GValue val;
|
|
1718
|
+
|
|
1719
|
+
g_value_init (&val, param_values[i].g_type);
|
|
1720
|
+
g_value_copy (¶m_values[i], &val);
|
|
1721
|
+
g_array_append_val (args, val);
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
g_closure_ref (closure);
|
|
1725
|
+
napi_call_threadsafe_function (self->tsfn, message, napi_tsfn_blocking);
|
|
1726
|
+
}
|
|
1727
|
+
|
|
1728
|
+
static void
|
|
1729
|
+
fdn_signal_closure_deliver (napi_env env,
|
|
1730
|
+
napi_value js_cb,
|
|
1731
|
+
void * context,
|
|
1732
|
+
void * data)
|
|
1733
|
+
{
|
|
1734
|
+
FdnSignalClosureMessage * message = data;
|
|
1735
|
+
|
|
1736
|
+
switch (message->type)
|
|
1737
|
+
{
|
|
1738
|
+
case FDN_SIGNAL_CLOSURE_MESSAGE_DESTROY:
|
|
1739
|
+
{
|
|
1740
|
+
FdnSignalClosureMessageDestroy * d = &message->payload.destroy;
|
|
1741
|
+
napi_value js_sig;
|
|
1742
|
+
FdnSignal * sig;
|
|
1743
|
+
FdnSignalBehavior behavior;
|
|
1744
|
+
|
|
1745
|
+
napi_get_reference_value (env, d->js_sig, &js_sig);
|
|
1746
|
+
napi_unwrap (env, js_sig, (void **) &sig);
|
|
1747
|
+
behavior = sig->behavior;
|
|
1748
|
+
|
|
1749
|
+
napi_delete_reference (env, d->handler);
|
|
1750
|
+
napi_delete_reference (env, d->js_sig);
|
|
1751
|
+
if (behavior == FDN_SIGNAL_KEEP_ALIVE)
|
|
1752
|
+
napi_unref_threadsafe_function (env, d->tsfn);
|
|
1753
|
+
napi_release_threadsafe_function (d->tsfn, napi_tsfn_abort);
|
|
1754
|
+
|
|
1755
|
+
break;
|
|
1756
|
+
}
|
|
1757
|
+
case FDN_SIGNAL_CLOSURE_MESSAGE_MARSHAL:
|
|
1758
|
+
{
|
|
1759
|
+
FdnSignalClosure * self = context;
|
|
1760
|
+
GArray * args;
|
|
1761
|
+
guint i;
|
|
1762
|
+
|
|
1763
|
+
args = message->payload.marshal.args;
|
|
1764
|
+
|
|
1765
|
+
if (self->state == FDN_SIGNAL_CLOSURE_OPEN)
|
|
1766
|
+
{
|
|
1767
|
+
napi_value * js_args;
|
|
1768
|
+
napi_value global, handler, js_result;
|
|
1769
|
+
|
|
1770
|
+
js_args = g_newa (napi_value, args->len);
|
|
1771
|
+
for (i = 0; i != args->len; i++)
|
|
1772
|
+
js_args[i] = fdn_gvalue_to_value (env, &g_array_index (args, GValue, i));
|
|
1773
|
+
|
|
1774
|
+
napi_get_global (env, &global);
|
|
1775
|
+
napi_get_reference_value (env, self->handler, &handler);
|
|
1776
|
+
|
|
1777
|
+
napi_call_function (env, global, handler, args->len, js_args, &js_result);
|
|
1778
|
+
}
|
|
1779
|
+
|
|
1780
|
+
for (i = 0; i != args->len; i++)
|
|
1781
|
+
g_value_reset (&g_array_index (args, GValue, i));
|
|
1782
|
+
g_array_free (args, TRUE);
|
|
1783
|
+
|
|
1784
|
+
g_closure_unref ((GClosure *) self);
|
|
1785
|
+
|
|
1786
|
+
break;
|
|
1787
|
+
}
|
|
1788
|
+
default:
|
|
1789
|
+
g_assert_not_reached ();
|
|
1790
|
+
}
|
|
1791
|
+
|
|
1792
|
+
g_slice_free (FdnSignalClosureMessage, message);
|
|
1793
|
+
}
|
|
1794
|
+
|
|
1795
|
+
static void
|
|
1796
|
+
fdn_keep_alive_until (napi_env env,
|
|
1797
|
+
napi_value js_object,
|
|
1798
|
+
GObject * handle,
|
|
1799
|
+
FdnIsDestroyedFunc is_destroyed,
|
|
1800
|
+
const gchar * destroy_signal_name)
|
|
1801
|
+
{
|
|
1802
|
+
FdnKeepAliveContext * context;
|
|
1803
|
+
|
|
1804
|
+
context = g_slice_new (FdnKeepAliveContext);
|
|
1805
|
+
context->ref_count = 2;
|
|
1806
|
+
context->handle = g_object_ref (handle);
|
|
1807
|
+
context->signal_handler_id = 0;
|
|
1808
|
+
|
|
1809
|
+
napi_ref_threadsafe_function (env, fdn_keep_alive_tsfn);
|
|
1810
|
+
|
|
1811
|
+
napi_add_finalizer (env, js_object, context, fdn_keep_alive_on_finalize, NULL, NULL);
|
|
1812
|
+
|
|
1813
|
+
context->signal_handler_id = g_signal_connect_data (handle, destroy_signal_name, G_CALLBACK (fdn_keep_alive_on_destroy_signal), context,
|
|
1814
|
+
fdn_keep_alive_on_destroy_signal_handler_detached, 0);
|
|
1815
|
+
|
|
1816
|
+
if (is_destroyed (handle))
|
|
1817
|
+
{
|
|
1818
|
+
g_atomic_int_inc (&context->ref_count);
|
|
1819
|
+
fdn_keep_alive_schedule_cleanup (context);
|
|
1820
|
+
}
|
|
1821
|
+
}
|
|
1822
|
+
|
|
1823
|
+
static void
|
|
1824
|
+
fdn_keep_alive_on_finalize (napi_env env,
|
|
1825
|
+
void * finalize_data,
|
|
1826
|
+
void * finalize_hint)
|
|
1827
|
+
{
|
|
1828
|
+
FdnKeepAliveContext * context = finalize_data;
|
|
1829
|
+
|
|
1830
|
+
fdn_keep_alive_schedule_cleanup (context);
|
|
1831
|
+
}
|
|
1832
|
+
|
|
1833
|
+
static void
|
|
1834
|
+
fdn_keep_alive_on_destroy_signal (GObject * handle,
|
|
1835
|
+
gpointer user_data)
|
|
1836
|
+
{
|
|
1837
|
+
FdnKeepAliveContext * context = user_data;
|
|
1838
|
+
|
|
1839
|
+
g_atomic_int_inc (&context->ref_count);
|
|
1840
|
+
fdn_keep_alive_schedule_cleanup (context);
|
|
1841
|
+
}
|
|
1842
|
+
|
|
1843
|
+
static void
|
|
1844
|
+
fdn_keep_alive_on_destroy_signal_handler_detached (gpointer data,
|
|
1845
|
+
GClosure * closure)
|
|
1846
|
+
{
|
|
1847
|
+
FdnKeepAliveContext * context = data;
|
|
1848
|
+
|
|
1849
|
+
fdn_keep_alive_schedule_cleanup (context);
|
|
1850
|
+
}
|
|
1851
|
+
|
|
1852
|
+
static void
|
|
1853
|
+
fdn_keep_alive_schedule_cleanup (FdnKeepAliveContext * context)
|
|
1854
|
+
{
|
|
1855
|
+
if (fdn_in_cleanup)
|
|
1856
|
+
return;
|
|
1857
|
+
|
|
1858
|
+
napi_call_threadsafe_function (fdn_keep_alive_tsfn, context, napi_tsfn_blocking);
|
|
1859
|
+
}
|
|
1860
|
+
|
|
1861
|
+
static void
|
|
1862
|
+
fdn_keep_alive_on_tsfn_invoke (napi_env env,
|
|
1863
|
+
napi_value js_cb,
|
|
1864
|
+
void * context,
|
|
1865
|
+
void * data)
|
|
1866
|
+
{
|
|
1867
|
+
FdnKeepAliveContext * ctx = data;
|
|
1868
|
+
|
|
1869
|
+
if (ctx->signal_handler_id != 0)
|
|
1870
|
+
{
|
|
1871
|
+
g_signal_handler_disconnect (ctx->handle, ctx->signal_handler_id);
|
|
1872
|
+
ctx->signal_handler_id = 0;
|
|
1873
|
+
|
|
1874
|
+
g_object_unref (ctx->handle);
|
|
1875
|
+
ctx->handle = NULL;
|
|
1876
|
+
|
|
1877
|
+
napi_unref_threadsafe_function (env, fdn_keep_alive_tsfn);
|
|
1878
|
+
}
|
|
1879
|
+
|
|
1880
|
+
if (g_atomic_int_dec_and_test (&ctx->ref_count))
|
|
1881
|
+
g_slice_free (FdnKeepAliveContext, ctx);
|
|
1882
|
+
}
|
|
1883
|
+
|
|
1884
|
+
static void
|
|
1885
|
+
fdn_inherit_val_val (napi_env env,
|
|
1886
|
+
napi_value sub_ctor,
|
|
1887
|
+
napi_value super_ctor,
|
|
1888
|
+
napi_value object_ctor,
|
|
1889
|
+
napi_value set_proto)
|
|
1890
|
+
{
|
|
1891
|
+
napi_value argv[2], sub_proto, super_proto;
|
|
1892
|
+
|
|
1893
|
+
argv[0] = sub_ctor;
|
|
1894
|
+
argv[1] = super_ctor;
|
|
1895
|
+
napi_call_function (env, object_ctor, set_proto, G_N_ELEMENTS (argv), argv, NULL);
|
|
1896
|
+
|
|
1897
|
+
napi_get_named_property (env, sub_ctor, "prototype", &sub_proto);
|
|
1898
|
+
napi_get_named_property (env, super_ctor, "prototype", &super_proto);
|
|
1899
|
+
argv[0] = sub_proto;
|
|
1900
|
+
argv[1] = super_proto;
|
|
1901
|
+
napi_call_function (env, object_ctor, set_proto, G_N_ELEMENTS (argv), argv, NULL);
|
|
1902
|
+
}
|
|
1903
|
+
|
|
1904
|
+
static void
|
|
1905
|
+
fdn_inherit_val_ref (napi_env env,
|
|
1906
|
+
napi_value sub_ctor,
|
|
1907
|
+
napi_ref super_ctor,
|
|
1908
|
+
napi_value object_ctor,
|
|
1909
|
+
napi_value set_proto)
|
|
1910
|
+
{
|
|
1911
|
+
napi_value super_ctor_val;
|
|
1912
|
+
|
|
1913
|
+
napi_get_reference_value (env, super_ctor, &super_ctor_val);
|
|
1914
|
+
|
|
1915
|
+
fdn_inherit_val_val (env, sub_ctor, super_ctor_val, object_ctor, set_proto);
|
|
1916
|
+
}
|
|
1917
|
+
|
|
1918
|
+
static void
|
|
1919
|
+
fdn_inherit_ref_val (napi_env env,
|
|
1920
|
+
napi_ref sub_ctor,
|
|
1921
|
+
napi_value super_ctor,
|
|
1922
|
+
napi_value object_ctor,
|
|
1923
|
+
napi_value set_proto)
|
|
1924
|
+
{
|
|
1925
|
+
napi_value sub_ctor_val;
|
|
1926
|
+
|
|
1927
|
+
napi_get_reference_value (env, sub_ctor, &sub_ctor_val);
|
|
1928
|
+
|
|
1929
|
+
fdn_inherit_val_val (env, sub_ctor_val, super_ctor, object_ctor, set_proto);
|
|
1930
|
+
}
|
|
1931
|
+
|
|
1932
|
+
static void
|
|
1933
|
+
fdn_inherit_ref_ref (napi_env env,
|
|
1934
|
+
napi_ref sub_ctor,
|
|
1935
|
+
napi_ref super_ctor,
|
|
1936
|
+
napi_value object_ctor,
|
|
1937
|
+
napi_value set_proto)
|
|
1938
|
+
{
|
|
1939
|
+
napi_value sub_ctor_val, super_ctor_val;
|
|
1940
|
+
|
|
1941
|
+
napi_get_reference_value (env, sub_ctor, &sub_ctor_val);
|
|
1942
|
+
napi_get_reference_value (env, super_ctor, &super_ctor_val);
|
|
1943
|
+
|
|
1944
|
+
fdn_inherit_val_val (env, sub_ctor_val, super_ctor_val, object_ctor, set_proto);
|
|
1945
|
+
}
|
|
1946
|
+
|
|
1947
|
+
static gchar *
|
|
1948
|
+
fdn_camel_case_to_kebab_case (const gchar * name)
|
|
1949
|
+
{
|
|
1950
|
+
GString * result;
|
|
1951
|
+
const gchar * p;
|
|
1952
|
+
|
|
1953
|
+
result = g_string_new (NULL);
|
|
1954
|
+
|
|
1955
|
+
for (p = name; *p != '\0'; p++)
|
|
1956
|
+
{
|
|
1957
|
+
if (g_ascii_isupper (*p))
|
|
1958
|
+
{
|
|
1959
|
+
if (p != name)
|
|
1960
|
+
g_string_append_c (result, '-');
|
|
1961
|
+
g_string_append_c (result, g_ascii_tolower (*p));
|
|
1962
|
+
}
|
|
1963
|
+
else
|
|
1964
|
+
{
|
|
1965
|
+
g_string_append_c (result, *p);
|
|
1966
|
+
}
|
|
1967
|
+
}
|
|
1968
|
+
|
|
1969
|
+
return g_string_free (result, FALSE);
|
|
1970
|
+
}
|