Line data Source code
1 : /*
2 : * GPAC - Multimedia Framework C SDK
3 : *
4 : * Authors: Jean Le Feuvre
5 : * Copyright (c) Telecom ParisTech 2007-2020
6 : * All rights reserved
7 : *
8 : * This file is part of GPAC / JavaScript libgpac Core bindings
9 : *
10 : * GPAC is free software; you can redistribute it and/or modify
11 : * it under the terms of the GNU Lesser General Public License as published by
12 : * the Free Software Foundation; either version 2, or (at your option)
13 : * any later version.
14 : *
15 : * GPAC is distributed in the hope that it will be useful,
16 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : * GNU Lesser General Public License for more details.
19 : *
20 : * You should have received a copy of the GNU Lesser General Public
21 : * License along with this library; see the file COPYING. If not, write to
22 : * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 : *
24 : */
25 :
26 : /*
27 : ANY CHANGE TO THE API MUST BE REFLECTED IN THE DOCUMENTATION IN gpac/share/doc/idl/storage.js
28 : (no way to define inline JS doc with doxygen)
29 : */
30 :
31 : #include <gpac/setup.h>
32 :
33 : #ifdef GPAC_HAS_QJS
34 : #include <gpac/bitstream.h>
35 : #include <gpac/network.h>
36 : #include <gpac/base_coding.h>
37 :
38 : #include "../scenegraph/qjs_common.h"
39 :
40 : #define JS_CGETSET_MAGIC_DEF_ENUM(name, fgetter, fsetter, magic) { name, JS_PROP_CONFIGURABLE|JS_PROP_ENUMERABLE, JS_DEF_CGETSET_MAGIC, magic, .u = { .getset = { .get = { .getter_magic = fgetter }, .set = { .setter_magic = fsetter } } } }
41 :
42 :
43 : static JSClassID bitstream_class_id = 0;
44 : static JSClassID sha1_class_id = 0;
45 : static JSClassID file_class_id = 0;
46 :
47 : typedef struct
48 : {
49 : GF_BitStream *bs;
50 : JSValue buf_ref;
51 : } JSBitstream;
52 :
53 : #define GET_JSBS \
54 : JSBitstream *jbs = JS_GetOpaque(this_val, bitstream_class_id); \
55 : GF_BitStream *bs = jbs ? jbs->bs : NULL;
56 :
57 :
58 6 : static void js_gpac_free(JSRuntime *rt, void *opaque, void *ptr)
59 : {
60 6 : gf_free(ptr);
61 6 : }
62 :
63 43 : static void js_bs_finalize(JSRuntime *rt, JSValue this_val)
64 : {
65 43 : GET_JSBS
66 4 : if (!bs) return;
67 4 : gf_bs_del(bs);
68 : JS_FreeValueRT(rt, jbs->buf_ref);
69 4 : gf_free(jbs);
70 : }
71 188 : static void js_bs_gc_mark(JSRuntime *rt, JSValueConst this_val, JS_MarkFunc *mark_func)
72 : {
73 188 : GET_JSBS
74 0 : if (!bs) return;
75 0 : JS_MarkValue(rt, jbs->buf_ref, mark_func);
76 : }
77 :
78 : JSClassDef bitstreamClass = {
79 : "Bitstream",
80 : .finalizer = js_bs_finalize,
81 : .gc_mark = js_bs_gc_mark
82 : };
83 :
84 :
85 1 : static JSValue js_bs_get_u8(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
86 : {
87 1 : GET_JSBS
88 1 : if (!bs) return JS_EXCEPTION;
89 1 : return JS_NewInt32(ctx, gf_bs_read_u8(bs) );
90 : }
91 1 : static JSValue js_bs_get_s8(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
92 : {
93 : s8 v;
94 1 : GET_JSBS
95 1 : if (!bs) return JS_EXCEPTION;
96 1 : v = (s8) gf_bs_read_u8(bs);
97 1 : return JS_NewInt32(ctx, v );
98 : }
99 1 : static JSValue js_bs_get_u16(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
100 : {
101 1 : GET_JSBS
102 1 : if (!bs) return JS_EXCEPTION;
103 1 : return JS_NewInt32(ctx, gf_bs_read_u16(bs) );
104 : }
105 1 : static JSValue js_bs_get_u16_le(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
106 : {
107 1 : GET_JSBS
108 1 : if (!bs) return JS_EXCEPTION;
109 1 : return JS_NewInt32(ctx, gf_bs_read_u16_le(bs) );
110 : }
111 1 : static JSValue js_bs_get_s16(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
112 : {
113 : s16 v;
114 1 : GET_JSBS
115 1 : if (!bs) return JS_EXCEPTION;
116 1 : v = (s16) gf_bs_read_u16(bs);
117 1 : return JS_NewInt32(ctx, v );
118 : }
119 1 : static JSValue js_bs_get_u24(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
120 : {
121 1 : GET_JSBS
122 1 : if (!bs) return JS_EXCEPTION;
123 1 : return JS_NewInt32(ctx, gf_bs_read_u24(bs) );
124 : }
125 1 : static JSValue js_bs_get_s32(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
126 : {
127 : s32 v;
128 1 : GET_JSBS
129 1 : if (!bs) return JS_EXCEPTION;
130 1 : v = (s32) gf_bs_read_u32(bs);
131 : return JS_NewInt32(ctx, v);
132 : }
133 1 : static JSValue js_bs_get_u32(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
134 : {
135 1 : GET_JSBS
136 1 : if (!bs) return JS_EXCEPTION;
137 1 : return JS_NewInt32(ctx, gf_bs_read_u32(bs) );
138 : }
139 1 : static JSValue js_bs_get_u32_le(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
140 : {
141 1 : GET_JSBS
142 1 : if (!bs) return JS_EXCEPTION;
143 1 : return JS_NewInt32(ctx, gf_bs_read_u32_le(bs) );
144 : }
145 1 : static JSValue js_bs_get_u64(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
146 : {
147 1 : GET_JSBS
148 1 : if (!bs) return JS_EXCEPTION;
149 1 : return JS_NewInt64(ctx, gf_bs_read_u64(bs) );
150 : }
151 1 : static JSValue js_bs_get_u64_le(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
152 : {
153 1 : GET_JSBS
154 1 : if (!bs) return JS_EXCEPTION;
155 1 : return JS_NewInt64(ctx, gf_bs_read_u64_le(bs) );
156 : }
157 1 : static JSValue js_bs_get_s64(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
158 : {
159 : s64 v;
160 1 : GET_JSBS
161 1 : if (!bs) return JS_EXCEPTION;
162 1 : v = (s64) gf_bs_read_u64(bs);
163 : return JS_NewInt64(ctx, v );
164 : }
165 1 : static JSValue js_bs_get_float(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
166 : {
167 1 : GET_JSBS
168 1 : if (!bs) return JS_EXCEPTION;
169 1 : return JS_NewFloat64(ctx, gf_bs_read_float(bs) );
170 : }
171 1 : static JSValue js_bs_get_double(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
172 : {
173 1 : GET_JSBS
174 1 : if (!bs) return JS_EXCEPTION;
175 1 : return JS_NewFloat64(ctx, gf_bs_read_double(bs) );
176 : }
177 2 : static JSValue js_bs_get_bits(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
178 : {
179 : s32 nb_bits;
180 2 : GET_JSBS
181 2 : if (!bs || !argc) return JS_EXCEPTION;
182 2 : if (JS_ToInt32(ctx, &nb_bits, argv[0])) return JS_EXCEPTION;
183 2 : if (nb_bits<=32)
184 1 : return JS_NewInt32(ctx, gf_bs_read_int(bs, nb_bits) );
185 1 : return JS_NewInt64(ctx, gf_bs_read_long_int(bs, nb_bits) );
186 : }
187 :
188 3 : static JSValue js_bs_data_io(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, u32 mode)
189 : {
190 3 : s32 nb_bytes=0;
191 3 : s64 offset=0;
192 : size_t data_size;
193 : u8 *data=NULL;
194 3 : GET_JSBS
195 3 : if (!bs) return JS_EXCEPTION;
196 3 : if (argc<1) return JS_EXCEPTION;
197 :
198 6 : if (JS_IsObject(argv[0])) {
199 3 : data = JS_GetArrayBuffer(ctx, &data_size, argv[0]);
200 3 : if (argc>1) {
201 0 : if (JS_ToInt32(ctx, &nb_bytes, argv[1])) return JS_EXCEPTION;
202 0 : if ((mode==2) && (argc>2)) {
203 0 : if (JS_ToInt64(ctx, &offset, argv[2])) return JS_EXCEPTION;
204 :
205 : }
206 : }
207 : }
208 3 : if (!data) return JS_EXCEPTION;
209 :
210 3 : if (nb_bytes> (s32) data_size) nb_bytes = (s32) data_size;
211 3 : else if (!nb_bytes) nb_bytes = (s32) data_size;
212 :
213 3 : if (mode==1) {
214 1 : data_size = gf_bs_write_data(bs, data, nb_bytes);
215 2 : } else if (mode==2) {
216 1 : GF_Err e = gf_bs_insert_data(bs, data, nb_bytes, offset);
217 1 : if (e) js_throw_err(ctx, e);
218 1 : return JS_UNDEFINED;
219 : } else {
220 1 : data_size = gf_bs_read_data(bs, data, nb_bytes);
221 : }
222 2 : return JS_NewInt32(ctx, (s32) data_size);
223 : }
224 :
225 1 : static JSValue js_bs_get_data(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
226 : {
227 1 : return js_bs_data_io(ctx, this_val, argc, argv, 0);
228 : }
229 1 : static JSValue js_bs_skip_bytes(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
230 : {
231 : s32 nb_bytes;
232 1 : GET_JSBS
233 1 : if (!bs || !argc) return JS_EXCEPTION;
234 1 : if (JS_ToInt32(ctx, &nb_bytes, argv[0])) return JS_EXCEPTION;
235 1 : gf_bs_skip_bytes(bs, nb_bytes);
236 1 : return JS_UNDEFINED;
237 : }
238 1 : static JSValue js_bs_is_align(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
239 : {
240 1 : GET_JSBS
241 1 : if (!bs) return JS_EXCEPTION;
242 1 : if (gf_bs_is_align(bs)) return JS_TRUE;
243 1 : return JS_FALSE;
244 : }
245 2 : static JSValue js_bs_align(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
246 : {
247 2 : GET_JSBS
248 2 : if (!bs) return JS_EXCEPTION;
249 2 : gf_bs_align(bs);
250 2 : return JS_UNDEFINED;
251 : }
252 1 : static JSValue js_bs_truncate(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
253 : {
254 1 : GET_JSBS
255 1 : if (!bs) return JS_EXCEPTION;
256 1 : gf_bs_truncate(bs);
257 1 : return JS_UNDEFINED;
258 : }
259 2 : static JSValue js_bs_flush(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
260 : {
261 2 : GET_JSBS
262 2 : if (!bs) return JS_EXCEPTION;
263 2 : gf_bs_flush(bs);
264 2 : return JS_UNDEFINED;
265 : }
266 1 : static JSValue js_bs_epb_mode(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
267 : {
268 1 : GET_JSBS
269 1 : if (!bs || !argc) return JS_EXCEPTION;
270 1 : gf_bs_enable_emulation_byte_removal(bs, (JS_ToBool(ctx, argv[0])) ? GF_TRUE : GF_FALSE);
271 1 : return JS_UNDEFINED;
272 : }
273 :
274 1 : static JSValue js_bs_peek(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
275 : {
276 1 : u64 byte_offset=0;
277 : s32 nb_bits;
278 1 : GET_JSBS
279 1 : if (!bs || !argc) return JS_EXCEPTION;
280 1 : if (JS_ToInt32(ctx, &nb_bits, argv[0])) return JS_EXCEPTION;
281 1 : if (argc>1) {
282 0 : if (JS_ToInt64(ctx, &byte_offset, argv[1])) return JS_EXCEPTION;
283 : }
284 1 : return JS_NewInt32(ctx, gf_bs_peek_bits(bs, nb_bits, byte_offset));
285 : }
286 :
287 13 : static JSValue js_bs_put_val(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, u32 mode)
288 : {
289 : s64 val;
290 13 : GET_JSBS
291 13 : if (!bs || !argc) return JS_EXCEPTION;
292 13 : if (JS_ToInt64(ctx, &val, argv[0])) return JS_EXCEPTION;
293 13 : switch (mode) {
294 1 : case 0: gf_bs_write_u8(bs, (u32) val); break;
295 1 : case 1: gf_bs_write_u8(bs, (u32) val); break;
296 1 : case 2: gf_bs_write_u16(bs, (u32) val); break;
297 1 : case 3: gf_bs_write_u16_le(bs, (u32) val); break;
298 1 : case 4: gf_bs_write_u16(bs, (u32) val); break;
299 1 : case 5: gf_bs_write_u24(bs, (u32) val); break;
300 2 : case 6: gf_bs_write_u32(bs, (u32) val); break;
301 1 : case 7: gf_bs_write_u32_le(bs, (u32) val); break;
302 1 : case 8: gf_bs_write_u32(bs, (u32) val); break;
303 1 : case 9: gf_bs_write_u64(bs, (u64) val); break;
304 1 : case 10: gf_bs_write_u64_le(bs, (u64) val); break;
305 1 : case 11: gf_bs_write_u64(bs, (u64) val); break;
306 : }
307 13 : return JS_UNDEFINED;
308 : }
309 1 : static JSValue js_bs_put_u8(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
310 : {
311 1 : return js_bs_put_val(ctx, this_val, argc, argv, 0);
312 : }
313 1 : static JSValue js_bs_put_s8(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
314 : {
315 1 : return js_bs_put_val(ctx, this_val, argc, argv, 1);
316 : }
317 1 : static JSValue js_bs_put_u16(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
318 : {
319 1 : return js_bs_put_val(ctx, this_val, argc, argv, 2);
320 : }
321 1 : static JSValue js_bs_put_u16_le(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
322 : {
323 1 : return js_bs_put_val(ctx, this_val, argc, argv, 3);
324 : }
325 1 : static JSValue js_bs_put_s16(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
326 : {
327 1 : return js_bs_put_val(ctx, this_val, argc, argv, 4);
328 : }
329 1 : static JSValue js_bs_put_u24(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
330 : {
331 1 : return js_bs_put_val(ctx, this_val, argc, argv, 5);
332 : }
333 2 : static JSValue js_bs_put_u32(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
334 : {
335 2 : return js_bs_put_val(ctx, this_val, argc, argv, 6);
336 : }
337 1 : static JSValue js_bs_put_u32_le(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
338 : {
339 1 : return js_bs_put_val(ctx, this_val, argc, argv, 7);
340 : }
341 1 : static JSValue js_bs_put_s32(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
342 : {
343 1 : return js_bs_put_val(ctx, this_val, argc, argv, 8);
344 : }
345 1 : static JSValue js_bs_put_u64(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
346 : {
347 1 : return js_bs_put_val(ctx, this_val, argc, argv, 9);
348 : }
349 1 : static JSValue js_bs_put_u64_le(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
350 : {
351 1 : return js_bs_put_val(ctx, this_val, argc, argv, 10);
352 : }
353 1 : static JSValue js_bs_put_s64(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
354 : {
355 1 : return js_bs_put_val(ctx, this_val, argc, argv, 11);
356 : }
357 2 : static JSValue js_bs_put_bits(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
358 : {
359 : s64 val;
360 : s32 nb_bits;
361 2 : GET_JSBS
362 2 : if (!bs || (argc!=2)) return JS_EXCEPTION;
363 2 : if (JS_ToInt64(ctx, &val, argv[0])) return JS_EXCEPTION;
364 2 : if (JS_ToInt32(ctx, &nb_bits, argv[1])) return JS_EXCEPTION;
365 2 : if (nb_bits<=32)
366 1 : gf_bs_write_int(bs, (u32) val, nb_bits);
367 : else
368 1 : gf_bs_write_long_int(bs, val, nb_bits);
369 2 : return JS_UNDEFINED;
370 : }
371 1 : static JSValue js_bs_put_float(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
372 : {
373 : Double val;
374 1 : GET_JSBS
375 1 : if (!bs || (argc!=1)) return JS_EXCEPTION;
376 1 : if (JS_ToFloat64(ctx, &val, argv[0])) return JS_EXCEPTION;
377 1 : gf_bs_write_float(bs, (Float) val);
378 1 : return JS_UNDEFINED;
379 : }
380 1 : static JSValue js_bs_put_double(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
381 : {
382 : Double val;
383 1 : GET_JSBS
384 1 : if (!bs || (argc!=1)) return JS_EXCEPTION;
385 1 : if (JS_ToFloat64(ctx, &val, argv[0])) return JS_EXCEPTION;
386 1 : gf_bs_write_double(bs, val);
387 1 : return JS_UNDEFINED;
388 : }
389 1 : static JSValue js_bs_put_data(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
390 : {
391 1 : return js_bs_data_io(ctx, this_val, argc, argv, 1);
392 : }
393 1 : static JSValue js_bs_insert_data(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
394 : {
395 1 : return js_bs_data_io(ctx, this_val, argc, argv, 2);
396 : }
397 :
398 1 : static JSValue js_bs_get_content(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
399 : {
400 : u8 *data;
401 : u32 size;
402 : JSValue res;
403 1 : GET_JSBS
404 1 : if (!bs) return JS_EXCEPTION;
405 1 : gf_bs_get_content(bs, &data, &size);
406 :
407 1 : if (data) {
408 1 : res = JS_NewArrayBuffer(ctx, data, size, js_gpac_free, NULL, 0);
409 : } else {
410 0 : res = JS_NULL;
411 : }
412 1 : return res;
413 : }
414 :
415 1 : static JSValue js_bs_transfer(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
416 : {
417 : Bool keep_src=GF_FALSE;
418 : GF_Err e;
419 : JSBitstream *jssrcbs;
420 1 : GET_JSBS
421 1 : if (!bs || !argc) return JS_EXCEPTION;
422 :
423 1 : jssrcbs = JS_GetOpaque(argv[0], bitstream_class_id);
424 1 : if (!jssrcbs || !jssrcbs->bs) return JS_EXCEPTION;
425 1 : if (argc>1) {
426 0 : keep_src = JS_ToBool(ctx, argv[1]);
427 : }
428 1 : e = gf_bs_transfer(bs, jssrcbs->bs, keep_src);
429 1 : if (e) return js_throw_err(ctx, e);
430 1 : return JS_UNDEFINED;
431 : }
432 :
433 : enum
434 : {
435 : JS_BS_POS=0,
436 : JS_BS_SIZE,
437 : JS_BS_BIT_OFFSET,
438 : JS_BS_BIT_POS,
439 : JS_BS_AVAILABLE,
440 : JS_BS_BITS_AVAILABLE,
441 : JS_BS_REFRESH_SIZE,
442 : };
443 :
444 6 : static JSValue js_bs_prop_get(JSContext *ctx, JSValueConst this_val, int magic)
445 : {
446 6 : GET_JSBS
447 6 : if (!bs) return JS_EXCEPTION;
448 6 : switch (magic) {
449 1 : case JS_BS_POS:
450 1 : return JS_NewInt64(ctx, gf_bs_get_position(bs));
451 2 : case JS_BS_SIZE:
452 2 : return JS_NewInt64(ctx, gf_bs_get_size(bs));
453 1 : case JS_BS_REFRESH_SIZE:
454 1 : return JS_NewInt64(ctx, gf_bs_get_refreshed_size(bs));
455 1 : case JS_BS_BIT_OFFSET:
456 1 : return JS_NewInt64(ctx, gf_bs_get_bit_offset(bs));
457 0 : case JS_BS_BIT_POS:
458 0 : return JS_NewInt64(ctx, gf_bs_get_bit_position(bs));
459 0 : case JS_BS_AVAILABLE:
460 0 : return JS_NewInt64(ctx, gf_bs_available(bs));
461 1 : case JS_BS_BITS_AVAILABLE:
462 1 : return JS_NewInt32(ctx, gf_bs_bits_available(bs));
463 : }
464 0 : return JS_UNDEFINED;
465 :
466 : }
467 1 : static JSValue js_bs_prop_set(JSContext *ctx, JSValueConst this_val, JSValueConst value, int magic)
468 : {
469 : s64 ival;
470 1 : GET_JSBS
471 1 : if (!bs) return JS_EXCEPTION;
472 :
473 1 : switch (magic) {
474 1 : case JS_BS_POS:
475 1 : if (JS_ToInt64(ctx, &ival, value)) return JS_EXCEPTION;
476 1 : gf_bs_seek(bs, ival);
477 1 : break;
478 : }
479 1 : return JS_UNDEFINED;
480 : }
481 :
482 : static const JSCFunctionListEntry bitstream_funcs[] = {
483 : JS_CGETSET_MAGIC_DEF_ENUM("pos", js_bs_prop_get, js_bs_prop_set, JS_BS_POS),
484 : JS_CGETSET_MAGIC_DEF_ENUM("size", js_bs_prop_get, NULL, JS_BS_SIZE),
485 : JS_CGETSET_MAGIC_DEF_ENUM("bit_offset", js_bs_prop_get, NULL, JS_BS_BIT_OFFSET),
486 : JS_CGETSET_MAGIC_DEF_ENUM("bit_pos", js_bs_prop_get, NULL, JS_BS_BIT_POS),
487 : JS_CGETSET_MAGIC_DEF_ENUM("available", js_bs_prop_get, NULL, JS_BS_AVAILABLE),
488 : JS_CGETSET_MAGIC_DEF_ENUM("bits_available", js_bs_prop_get, NULL, JS_BS_BITS_AVAILABLE),
489 : JS_CGETSET_MAGIC_DEF_ENUM("refreshed_size", js_bs_prop_get, NULL, JS_BS_REFRESH_SIZE),
490 :
491 : JS_CFUNC_DEF("skip", 0, js_bs_skip_bytes),
492 : JS_CFUNC_DEF("is_align", 0, js_bs_is_align),
493 : JS_CFUNC_DEF("align", 0, js_bs_align),
494 : JS_CFUNC_DEF("truncate", 0, js_bs_truncate),
495 : JS_CFUNC_DEF("peek", 0, js_bs_peek),
496 : JS_CFUNC_DEF("flush", 0, js_bs_flush),
497 : JS_CFUNC_DEF("epb_mode", 0, js_bs_epb_mode),
498 :
499 : JS_CFUNC_DEF("get_u8", 0, js_bs_get_u8),
500 : JS_CFUNC_DEF("get_s8", 0, js_bs_get_s8),
501 : JS_CFUNC_DEF("get_u16", 0, js_bs_get_u16),
502 : JS_CFUNC_DEF("get_u16_le", 0, js_bs_get_u16_le),
503 : JS_CFUNC_DEF("get_s16", 0, js_bs_get_s16),
504 : JS_CFUNC_DEF("get_u24", 0, js_bs_get_u24),
505 : JS_CFUNC_DEF("get_u32", 0, js_bs_get_u32),
506 : JS_CFUNC_DEF("get_u32_le", 0, js_bs_get_u32_le),
507 : JS_CFUNC_DEF("get_s32", 0, js_bs_get_s32),
508 : JS_CFUNC_DEF("get_u64", 0, js_bs_get_u64),
509 : JS_CFUNC_DEF("get_u64_le", 0, js_bs_get_u64_le),
510 : JS_CFUNC_DEF("get_s64", 0, js_bs_get_s64),
511 : JS_CFUNC_DEF("get_bits", 0, js_bs_get_bits),
512 : JS_CFUNC_DEF("get_float", 0, js_bs_get_float),
513 : JS_CFUNC_DEF("get_double", 0, js_bs_get_double),
514 : JS_CFUNC_DEF("get_data", 0, js_bs_get_data),
515 : JS_CFUNC_DEF("put_u8", 0, js_bs_put_u8),
516 : JS_CFUNC_DEF("put_s8", 0, js_bs_put_s8),
517 : JS_CFUNC_DEF("put_u16", 0, js_bs_put_u16),
518 : JS_CFUNC_DEF("put_u16_le", 0, js_bs_put_u16_le),
519 : JS_CFUNC_DEF("put_s16", 0, js_bs_put_s16),
520 : JS_CFUNC_DEF("put_u24", 0, js_bs_put_u24),
521 : JS_CFUNC_DEF("put_u32", 0, js_bs_put_u32),
522 : JS_CFUNC_DEF("put_u32_le", 0, js_bs_put_u32_le),
523 : JS_CFUNC_DEF("put_s32", 0, js_bs_put_s32),
524 : JS_CFUNC_DEF("put_u64", 0, js_bs_put_u64),
525 : JS_CFUNC_DEF("put_u64_le", 0, js_bs_put_u64_le),
526 : JS_CFUNC_DEF("put_s64", 0, js_bs_put_s64),
527 : JS_CFUNC_DEF("put_bits", 0, js_bs_put_bits),
528 : JS_CFUNC_DEF("put_float", 0, js_bs_put_float),
529 : JS_CFUNC_DEF("put_double", 0, js_bs_put_double),
530 : JS_CFUNC_DEF("put_data", 0, js_bs_put_data),
531 : JS_CFUNC_DEF("insert_data", 0, js_bs_insert_data),
532 : JS_CFUNC_DEF("get_content", 0, js_bs_get_content),
533 : JS_CFUNC_DEF("transfer", 0, js_bs_transfer),
534 : };
535 :
536 4 : static JSValue bitstream_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv)
537 : {
538 : JSValue anobj;
539 : JSBitstream *jbs;
540 : GF_BitStream *bs = NULL;
541 :
542 4 : if (!argc) {
543 2 : bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
544 4 : } else if (JS_IsObject(argv[0])){
545 2 : FILE *f = JS_GetOpaque(argv[0], file_class_id);
546 2 : if (f) {
547 1 : if ((argc>1) && JS_ToBool(ctx, argv[1])) {
548 1 : bs = gf_bs_from_file(f, GF_BITSTREAM_WRITE);
549 : } else {
550 0 : bs = gf_bs_from_file(f, GF_BITSTREAM_READ);
551 : }
552 : } else {
553 : u8 *data;
554 : size_t data_size;
555 :
556 1 : data = JS_GetArrayBuffer(ctx, &data_size, argv[0]);
557 1 : if (!data) return JS_EXCEPTION;
558 1 : if ((argc>1) && JS_ToBool(ctx, argv[1])) {
559 0 : bs = gf_bs_new(data, data_size, GF_BITSTREAM_WRITE);
560 : } else {
561 1 : bs = gf_bs_new(data, data_size, GF_BITSTREAM_READ);
562 : }
563 : }
564 : } else {
565 0 : return JS_EXCEPTION;
566 : }
567 4 : GF_SAFEALLOC(jbs, JSBitstream);
568 4 : if (!jbs) {
569 0 : gf_bs_del(bs);
570 0 : return js_throw_err(ctx, GF_OUT_OF_MEM);
571 : }
572 4 : anobj = JS_NewObjectClass(ctx, bitstream_class_id);
573 4 : if (JS_IsException(anobj)) {
574 0 : gf_bs_del(bs);
575 0 : gf_free(jbs);
576 0 : return anobj;
577 : }
578 4 : jbs->bs = bs;
579 4 : jbs->buf_ref = JS_UNDEFINED;
580 4 : if (argc)
581 2 : jbs->buf_ref = JS_DupValue(ctx, argv[0]);
582 :
583 4 : JS_SetOpaque(anobj, jbs);
584 4 : return anobj;
585 : }
586 :
587 : enum
588 : {
589 : JS_SYS_NB_CORES = 1,
590 : JS_SYS_SAMPLE_DUR,
591 : JS_SYS_TOTAL_CPU,
592 : JS_SYS_PROCESS_CPU,
593 : JS_SYS_TOTAL_CPU_DIFF,
594 : JS_SYS_PROCESS_CPU_DIFF,
595 : JS_SYS_CPU_IDLE,
596 : JS_SYS_TOTAL_CPU_USAGE,
597 : JS_SYS_PROCESS_CPU_USAGE,
598 : JS_SYS_PID,
599 : JS_SYS_THREADS,
600 : JS_SYS_PROCESS_MEM,
601 : JS_SYS_TOTAL_MEM,
602 : JS_SYS_TOTAL_MEM_AVAIL,
603 : JS_SYS_GPAC_MEM,
604 :
605 : JS_SYS_BATTERY_ON,
606 : JS_SYS_BATTERY_CHARGE,
607 : JS_SYS_BATTERY_PERCENT,
608 : JS_SYS_BATTERY_LIFETIME,
609 : JS_SYS_BATTERY_LIFETIME_FULL,
610 : JS_SYS_HOSTNAME,
611 : JS_SYS_LAST_WORK_DIR,
612 : JS_SYS_TEST_MODE,
613 : JS_SYS_OLD_ARCH,
614 : JS_SYS_LOG_COLOR,
615 : JS_SYS_QUIET,
616 : JS_SYS_USERNAME,
617 : JS_SYS_TIMEZONE,
618 : JS_SYS_FILES_OPEN,
619 : JS_SYS_CACHE_DIR,
620 : JS_SYS_SHARED_DIR,
621 : JS_SYS_VERSION,
622 : JS_SYS_VERSION_FULL,
623 : JS_SYS_COPYRIGHT,
624 : JS_SYS_V_MAJOR,
625 : JS_SYS_V_MINOR,
626 : JS_SYS_V_MICRO,
627 : };
628 :
629 : #define RTI_REFRESH_MS 200
630 53 : static JSValue js_sys_prop_get(JSContext *ctx, JSValueConst this_val, int magic)
631 : {
632 : u32 uval;
633 : Bool bval;
634 : const char *res;
635 : GF_SystemRTInfo rti;
636 :
637 53 : if (magic<=JS_SYS_GPAC_MEM) {
638 25 : gf_sys_get_rti(RTI_REFRESH_MS, &rti, 0);
639 25 : switch (magic) {
640 2 : case JS_SYS_NB_CORES:
641 2 : return JS_NewInt32(ctx, rti.nb_cores);
642 1 : case JS_SYS_SAMPLE_DUR:
643 1 : return JS_NewInt32(ctx, rti.sampling_period_duration);
644 1 : case JS_SYS_TOTAL_CPU:
645 1 : return JS_NewInt32(ctx, rti.total_cpu_time);
646 1 : case JS_SYS_PROCESS_CPU:
647 1 : return JS_NewInt32(ctx, rti.process_cpu_time);
648 1 : case JS_SYS_TOTAL_CPU_DIFF:
649 1 : return JS_NewInt32(ctx, rti.total_cpu_time_diff);
650 1 : case JS_SYS_PROCESS_CPU_DIFF:
651 1 : return JS_NewInt32(ctx, rti.process_cpu_time_diff);
652 1 : case JS_SYS_CPU_IDLE:
653 1 : return JS_NewInt32(ctx, rti.cpu_idle_time);
654 1 : case JS_SYS_TOTAL_CPU_USAGE:
655 1 : return JS_NewInt32(ctx, rti.total_cpu_time);
656 5 : case JS_SYS_PROCESS_CPU_USAGE:
657 5 : return JS_NewInt32(ctx, rti.process_cpu_usage);
658 1 : case JS_SYS_PID:
659 1 : return JS_NewInt32(ctx, rti.pid);
660 1 : case JS_SYS_THREADS:
661 1 : return JS_NewInt32(ctx, rti.thread_count);
662 1 : case JS_SYS_PROCESS_MEM:
663 1 : return JS_NewInt64(ctx, rti.process_memory);
664 2 : case JS_SYS_TOTAL_MEM:
665 2 : return JS_NewInt64(ctx, rti.physical_memory);
666 1 : case JS_SYS_TOTAL_MEM_AVAIL:
667 1 : return JS_NewInt64(ctx, rti.physical_memory_avail);
668 5 : case JS_SYS_GPAC_MEM:
669 5 : return JS_NewInt64(ctx, rti.gpac_memory);
670 : }
671 0 : return JS_UNDEFINED;
672 : }
673 :
674 28 : switch (magic) {
675 1 : case JS_SYS_BATTERY_ON:
676 1 : bval = GF_FALSE;
677 1 : gf_sys_get_battery_state(&bval, NULL, NULL, NULL, NULL);
678 1 : return JS_NewBool(ctx, bval);
679 :
680 1 : case JS_SYS_BATTERY_CHARGE:
681 1 : uval = 0;
682 1 : gf_sys_get_battery_state(NULL, &uval, NULL, NULL, NULL);
683 1 : return JS_NewBool(ctx, uval ? 1 : 0);
684 :
685 1 : case JS_SYS_BATTERY_PERCENT:
686 1 : uval=0;
687 1 : gf_sys_get_battery_state(NULL, NULL, &uval, NULL, NULL);
688 1 : return JS_NewInt32(ctx, uval);
689 :
690 1 : case JS_SYS_BATTERY_LIFETIME:
691 1 : uval=0;
692 1 : gf_sys_get_battery_state(NULL, NULL, NULL, &uval, NULL);
693 1 : return JS_NewInt32(ctx, uval);
694 :
695 1 : case JS_SYS_BATTERY_LIFETIME_FULL:
696 1 : uval=0;
697 1 : gf_sys_get_battery_state(NULL, NULL, NULL, NULL, &uval);
698 1 : return JS_NewInt32(ctx, uval);
699 :
700 1 : case JS_SYS_HOSTNAME:
701 : {
702 : char hostname[100];
703 1 : gf_sk_get_host_name((char*)hostname);
704 1 : return JS_NewString(ctx, hostname);
705 : }
706 : break;
707 2 : case JS_SYS_LAST_WORK_DIR:
708 2 : res = gf_opts_get_key("General", "LastWorkingDir");
709 : #ifdef WIN32
710 : if (!res) res = getenv("HOMEPATH");
711 : if (!res) res = "C:\\";
712 : #elif defined(GPAC_CONFIG_DARWIN)
713 : if (!res) res = getenv("HOME");
714 : if (!res) res = "/Users";
715 : #elif defined(GPAC_CONFIG_ANDROID)
716 : if (!res) res = getenv("EXTERNAL_STORAGE");
717 : if (!res) res = "/sdcard";
718 : #elif defined(GPAC_CONFIG_IOS)
719 : if (!res) res = (char *) gf_opts_get_key("General", "iOSDocumentsDir");
720 : #else
721 2 : if (!res) res = getenv("HOME");
722 2 : if (!res) res = "/home/";
723 : #endif
724 2 : return JS_NewString(ctx, res);
725 :
726 1 : case JS_SYS_TEST_MODE:
727 1 : return JS_NewBool(ctx, gf_sys_is_test_mode() );
728 1 : case JS_SYS_OLD_ARCH:
729 1 : return JS_NewBool(ctx, gf_sys_old_arch_compat() );
730 1 : case JS_SYS_LOG_COLOR:
731 : #ifdef GPAC_DISABLE_LOG
732 : return JS_NewBool(ctx, GF_FALSE );
733 : #else
734 1 : return JS_NewBool(ctx, gf_log_use_color() );
735 : #endif
736 1 : case JS_SYS_QUIET:
737 1 : return JS_NewBool(ctx, gf_sys_is_quiet() );
738 1 : case JS_SYS_USERNAME:
739 : {
740 : char username[1024];
741 1 : gf_get_user_name((char*)username);
742 1 : return JS_NewString(ctx, username);
743 : }
744 1 : case JS_SYS_TIMEZONE:
745 1 : return JS_NewInt32(ctx, gf_net_get_timezone());
746 :
747 1 : case JS_SYS_FILES_OPEN:
748 1 : return JS_NewInt32(ctx, gf_file_handles_count());
749 :
750 1 : case JS_SYS_CACHE_DIR:
751 1 : res = gf_get_default_cache_directory();
752 1 : if (res) return JS_NewString(ctx, res);
753 0 : return JS_NULL;
754 :
755 1 : case JS_SYS_SHARED_DIR:
756 : {
757 : char szDir[GF_MAX_PATH];
758 1 : if (! gf_opts_default_shared_directory(szDir)) return JS_NULL;
759 1 : return JS_NewString(ctx, szDir);
760 : }
761 :
762 1 : case JS_SYS_VERSION:
763 1 : return JS_NewString(ctx, GPAC_VERSION );
764 6 : case JS_SYS_VERSION_FULL:
765 6 : return JS_NewString(ctx, gf_gpac_version() );
766 1 : case JS_SYS_COPYRIGHT:
767 1 : return JS_NewString(ctx, gf_gpac_copyright() );
768 :
769 : case JS_SYS_V_MAJOR:
770 : return JS_NewInt32(ctx, GPAC_VERSION_MAJOR );
771 : case JS_SYS_V_MINOR:
772 : return JS_NewInt32(ctx, GPAC_VERSION_MINOR );
773 : case JS_SYS_V_MICRO:
774 : return JS_NewInt32(ctx, GPAC_VERSION_MICRO );
775 : }
776 :
777 0 : return JS_UNDEFINED;
778 : }
779 :
780 1 : static JSValue js_sys_prop_set(JSContext *ctx, JSValueConst this_val, JSValueConst value, int magic)
781 : {
782 : const char *prop_val;
783 1 : switch (magic) {
784 1 : case JS_SYS_LAST_WORK_DIR:
785 1 : if (!JS_IsString(value)) return JS_EXCEPTION;
786 : prop_val = JS_ToCString(ctx, value);
787 1 : gf_opts_set_key("General", "LastWorkingDir", prop_val);
788 1 : JS_FreeCString(ctx, prop_val);
789 1 : break;
790 : }
791 1 : return JS_UNDEFINED;
792 : }
793 :
794 10 : static JSValue js_sys_set_arg_used(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
795 : {
796 : u32 idx;
797 : Bool used;
798 10 : if (argc < 2) return JS_EXCEPTION;
799 :
800 10 : if (JS_ToInt32(ctx, &idx, argv[0]))
801 0 : return JS_EXCEPTION;
802 10 : used = JS_ToBool(ctx, argv[1]);
803 :
804 10 : gf_sys_mark_arg_used(idx, used);
805 10 : return JS_UNDEFINED;
806 : }
807 :
808 :
809 : typedef struct
810 : {
811 : JSContext *c;
812 : JSValue array;
813 : Bool is_dir;
814 : u32 idx;
815 : } enum_dir_cbk;
816 :
817 54 : static Bool js_enum_dir_fct(void *cbck, char *file_name, char *file_path, GF_FileEnumInfo *file_info)
818 : {
819 : u32 i, len;
820 : char *sep;
821 : JSValue s;
822 : JSValue obj;
823 : enum_dir_cbk *cbk = (enum_dir_cbk*)cbck;
824 :
825 54 : if (file_name && (file_name[0]=='.')) return 0;
826 :
827 54 : obj = JS_NewObject(cbk->c);
828 54 : JS_SetPropertyStr(cbk->c, obj, "name", JS_NewString(cbk->c, file_name) );
829 :
830 : sep=NULL;
831 54 : len = (u32) strlen(file_path);
832 421 : for (i=0; i<len; i++) {
833 421 : sep = strchr("/\\", file_path[len-i-1]);
834 421 : if (sep) {
835 54 : sep = file_path+len-i-1;
836 54 : break;
837 : }
838 : }
839 54 : if (sep) {
840 54 : sep[0] = '/';
841 54 : sep[1] = 0;
842 54 : s = JS_NewString(cbk->c, file_path);
843 : } else {
844 0 : s = JS_NewString(cbk->c, file_path);
845 : }
846 54 : JS_SetPropertyStr(cbk->c, obj, "path", s);
847 :
848 108 : JS_SetPropertyStr(cbk->c, obj, "directory", JS_NewBool(cbk->c, cbk->is_dir) );
849 108 : JS_SetPropertyStr(cbk->c, obj, "drive", JS_NewBool(cbk->c, file_info->drive) );
850 108 : JS_SetPropertyStr(cbk->c, obj, "hidden", JS_NewBool(cbk->c, file_info->hidden) );
851 108 : JS_SetPropertyStr(cbk->c, obj, "system", JS_NewBool(cbk->c, file_info->system) );
852 108 : JS_SetPropertyStr(cbk->c, obj, "size", JS_NewInt64(cbk->c, file_info->size) );
853 108 : JS_SetPropertyStr(cbk->c, obj, "last_modified", JS_NewInt64(cbk->c, file_info->last_modified) );
854 :
855 54 : JS_SetPropertyUint32(cbk->c, cbk->array, cbk->idx, obj);
856 54 : cbk->idx++;
857 54 : return 0;
858 : }
859 :
860 5 : static JSValue js_sys_enum_directory(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
861 : {
862 : GF_Err err;
863 : enum_dir_cbk cbk;
864 : char *url = NULL;
865 : const char *dir = NULL;
866 : const char *filter = NULL;
867 : Bool dir_only = 0;
868 : Bool browse_root = 0;
869 :
870 10 : if ((argc >= 1) && JS_IsString(argv[0])) {
871 : dir = JS_ToCString(ctx, argv[0]);
872 5 : if (!strcmp(dir, "/")) browse_root = 1;
873 : }
874 8 : if ((argc >= 2) && JS_IsString(argv[1])) {
875 : filter = JS_ToCString(ctx, argv[1]);
876 3 : if (!strcmp(filter, "dir")) {
877 : dir_only = 1;
878 : filter = NULL;
879 3 : } else if (!strlen(filter)) {
880 0 : JS_FreeCString(ctx, filter);
881 : filter=NULL;
882 : }
883 : }
884 8 : if ((argc >= 3) && JS_IsBool(argv[2])) {
885 0 : if (JS_ToBool(ctx, argv[2])) {
886 0 : url = gf_url_concatenate(dir, "..");
887 0 : if (dir && ( !strcmp(url, "..") || (url[0]==0) )) {
888 0 : if ((dir[1]==':') && ((dir[2]=='/') || (dir[2]=='\\')) ) browse_root = 1;
889 0 : else if (!strcmp(dir, "/")) browse_root = 1;
890 : }
891 0 : if (!strcmp(url, "/")) browse_root = 1;
892 : }
893 : }
894 :
895 5 : if ( (!dir || !strlen(dir) ) && (!url || !strlen(url))) browse_root = 1;
896 :
897 5 : if (browse_root) {
898 1 : cbk.c = ctx;
899 1 : cbk.idx = 0;
900 1 : cbk.array = JS_NewArray(ctx);
901 2 : if (JS_IsException(cbk.array)) return cbk.array;
902 1 : cbk.is_dir = 1;
903 1 : gf_enum_directory("/", 1, js_enum_dir_fct, &cbk, NULL);
904 1 : if (url) gf_free(url);
905 1 : JS_FreeCString(ctx, dir);
906 1 : JS_FreeCString(ctx, filter);
907 1 : return cbk.array;
908 : }
909 :
910 4 : cbk.c = ctx;
911 4 : cbk.array = JS_NewArray(ctx);
912 8 : if (JS_IsException(cbk.array)) return cbk.array;
913 4 : cbk.is_dir = 1;
914 4 : cbk.idx = 0;
915 :
916 : #if 0
917 : compositor = scenejs_get_compositor(ctx, this_val);
918 :
919 : /*concatenate with service url*/
920 : char *an_url = gf_url_concatenate(compositor->root_scene->root_od->scene_ns->url, url ? url : dir);
921 : if (an_url) {
922 : gf_free(url);
923 : url = an_url;
924 : }
925 : #endif
926 :
927 4 : err = gf_enum_directory(url ? url : dir, 1, js_enum_dir_fct, &cbk, NULL);
928 4 : if (err) return JS_EXCEPTION;
929 :
930 4 : if (!dir_only) {
931 4 : cbk.is_dir = 0;
932 4 : err = gf_enum_directory(url ? url : dir, 0, js_enum_dir_fct, &cbk, filter);
933 4 : if (err) return JS_EXCEPTION;
934 : }
935 :
936 4 : if (url) gf_free(url);
937 4 : JS_FreeCString(ctx, dir);
938 4 : JS_FreeCString(ctx, filter);
939 4 : return cbk.array;
940 : }
941 :
942 :
943 1 : static JSValue js_sys_error_string(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
944 : {
945 : GF_Err e;
946 1 : if (argc < 1) return JS_EXCEPTION;
947 1 : if (JS_ToInt32(ctx, (int32_t *) &e, argv[0]))
948 0 : return JS_EXCEPTION;
949 1 : return JS_NewString(ctx, gf_error_to_string(e) );
950 : }
951 :
952 1 : static JSValue js_sys_prompt_input(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
953 : {
954 : char in_char[2];
955 :
956 1 : if (!gf_prompt_has_input())
957 1 : return JS_NULL;
958 0 : in_char[0] = gf_prompt_get_char();
959 0 : in_char[1] = 0;
960 0 : return JS_NewString(ctx, in_char);
961 : }
962 :
963 1 : static JSValue js_sys_prompt_string(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
964 : {
965 : char input[4096], *read;
966 : u32 len;
967 : //#ifdef GPAC_ENABLE_COVERAGE
968 1 : if (argc) {
969 1 : return JS_NewString(ctx, "Coverage OK");
970 : }
971 : //#endif // GPAC_ENABLE_COVERAGE
972 :
973 0 : read = fgets(input, 4095, stdin);
974 0 : if (!read) return JS_NULL;
975 0 : input[4095]=0;
976 0 : len = (u32) strlen(input);
977 0 : if (len && (input[len-1] == '\n')) {
978 0 : input[len-1] = 0;
979 : len--;
980 : }
981 0 : if (!len) return JS_NULL;
982 0 : return JS_NewString(ctx, input);
983 : }
984 :
985 2 : static JSValue js_sys_prompt_echo_off(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
986 : {
987 : Bool echo_off;
988 2 : if (!argc) return JS_EXCEPTION;
989 2 : echo_off = JS_ToBool(ctx, argv[0]);
990 2 : if (argc<2)
991 0 : gf_prompt_set_echo_off(echo_off);
992 2 : return JS_UNDEFINED;
993 : }
994 2 : static JSValue js_sys_prompt_code(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
995 : {
996 : s32 code;
997 2 : if (!argc) return JS_EXCEPTION;
998 2 : if (JS_ToInt32(ctx, &code, argv[0])) return JS_EXCEPTION;
999 :
1000 2 : gf_sys_set_console_code(stderr, code);
1001 2 : return JS_UNDEFINED;
1002 : }
1003 1 : static JSValue js_sys_prompt_size(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1004 : {
1005 : u32 w, h;
1006 : JSValue res;
1007 1 : GF_Err e = gf_prompt_get_size(&w, &h);
1008 1 : if (e) return JS_NULL;
1009 1 : res = JS_NewObject(ctx);
1010 2 : JS_SetPropertyStr(ctx, res, "w", JS_NewInt32(ctx, w));
1011 2 : JS_SetPropertyStr(ctx, res, "h", JS_NewInt32(ctx, h));
1012 1 : return res;
1013 : }
1014 :
1015 : const char *gf_dom_get_friendly_name(u32 key_identifier);
1016 :
1017 0 : static JSValue js_sys_keyname(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1018 : {
1019 : u32 code;
1020 0 : if (JS_ToInt32(ctx, &code, argv[0])) return JS_EXCEPTION;
1021 0 : return JS_NewString(ctx, gf_dom_get_friendly_name(code));
1022 : }
1023 :
1024 :
1025 1 : static JSValue js_sys_gc(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1026 : {
1027 1 : JS_RunGC(JS_GetRuntime(ctx));
1028 1 : return JS_UNDEFINED;
1029 : }
1030 :
1031 1 : static JSValue js_sys_clock(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1032 : {
1033 2 : return JS_NewInt32(ctx, gf_sys_clock() );
1034 : }
1035 1 : static JSValue js_sys_clock_high_res(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1036 : {
1037 2 : return JS_NewInt64(ctx, gf_sys_clock_high_res() );
1038 : }
1039 1 : static JSValue js_sys_4cc_to_str(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1040 : {
1041 : u64 val;
1042 1 : if (!argc) return JS_EXCEPTION;
1043 1 : if (JS_ToInt64(ctx, &val, argv[0])) return JS_EXCEPTION;
1044 1 : return JS_NewString(ctx, gf_4cc_to_str((u32) val) );
1045 : }
1046 :
1047 1 : static JSValue js_sys_rand_init(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1048 : {
1049 : Bool reset=GF_FALSE;
1050 1 : if (argc) reset = JS_ToBool(ctx, argv[0]);
1051 1 : gf_rand_init(reset);
1052 1 : return JS_UNDEFINED;
1053 : }
1054 1 : static JSValue js_sys_rand(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1055 : {
1056 2 : return JS_NewInt32(ctx, gf_rand());
1057 : }
1058 1 : static JSValue js_sys_rand64(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1059 : {
1060 1 : u64 lrand = (u64) gf_rand();
1061 1 : lrand<<=32;
1062 1 : lrand |= gf_rand();
1063 2 : return JS_NewInt64(ctx, lrand);
1064 : }
1065 :
1066 1 : static JSValue js_sys_getenv(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1067 : {
1068 : const char *str, *val;
1069 1 : if (!argc) return JS_EXCEPTION;
1070 : str = JS_ToCString(ctx, argv[0]);
1071 1 : if (!str) return JS_EXCEPTION;
1072 1 : val = getenv(str);
1073 1 : JS_FreeCString(ctx, str);
1074 1 : return val ? JS_NewString(ctx, val) : JS_NULL;
1075 : }
1076 :
1077 3 : static JSValue js_sys_get_utc(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1078 : {
1079 : u32 y, mo, d, h, m, s;
1080 3 : if (!argc) return JS_NewInt64(ctx, gf_net_get_utc() );
1081 2 : if (argc==1) {
1082 : u64 time;
1083 : const char *date = JS_ToCString(ctx, argv[0]);
1084 1 : if (!date) return JS_EXCEPTION;
1085 1 : time = gf_net_parse_date(date);
1086 1 : JS_FreeCString(ctx, date);
1087 1 : return JS_NewInt64(ctx, time);
1088 : }
1089 :
1090 1 : if (argc != 6) return JS_EXCEPTION;
1091 1 : if (JS_ToInt32(ctx, &y, argv[0])) return JS_EXCEPTION;
1092 1 : if (JS_ToInt32(ctx, &mo, argv[1])) return JS_EXCEPTION;
1093 1 : if (JS_ToInt32(ctx, &d, argv[2])) return JS_EXCEPTION;
1094 1 : if (JS_ToInt32(ctx, &h, argv[3])) return JS_EXCEPTION;
1095 1 : if (JS_ToInt32(ctx, &m, argv[4])) return JS_EXCEPTION;
1096 1 : if (JS_ToInt32(ctx, &s, argv[5])) return JS_EXCEPTION;
1097 :
1098 1 : return JS_NewInt64(ctx, gf_net_get_utc_ts(y, mo, d, h, m, s) );
1099 : }
1100 :
1101 0 : static JSValue js_sys_get_ntp(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1102 : {
1103 : u32 sec, frac;
1104 0 : gf_net_get_ntp(&sec, &frac);
1105 0 : JSValue ret = JS_NewObject(ctx);
1106 0 : if (JS_IsException(ret)) return ret;
1107 0 : JS_SetPropertyStr(ctx, ret, "n", JS_NewInt64(ctx, sec));
1108 0 : JS_SetPropertyStr(ctx, ret, "d", JS_NewInt64(ctx, frac));
1109 0 : return ret;
1110 : }
1111 :
1112 0 : static JSValue js_sys_ntp_shift(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1113 : {
1114 : JSValue v;
1115 : u64 sec, frac, shift;
1116 : s64 frac_usec;
1117 0 : if ((argc<2) || !JS_IsObject(argv[0]))
1118 0 : return JS_EXCEPTION;
1119 :
1120 0 : v = JS_GetPropertyStr(ctx, argv[0], "n");
1121 0 : if (JS_IsNull(v)) return JS_EXCEPTION;
1122 0 : JS_ToInt64(ctx, &sec, v);
1123 : JS_FreeValue(ctx, v);
1124 :
1125 0 : v = JS_GetPropertyStr(ctx, argv[0], "d");
1126 0 : if (JS_IsNull(v)) return JS_EXCEPTION;
1127 0 : JS_ToInt64(ctx, &frac, v);
1128 : JS_FreeValue(ctx, v);
1129 :
1130 0 : JS_ToInt64(ctx, &shift, argv[1]);
1131 0 : frac_usec = (s64) (frac * 1000000) / 0xFFFFFFFFULL;
1132 0 : frac_usec += shift;
1133 0 : while (frac_usec<0) {
1134 0 : frac_usec += 1000000;
1135 0 : sec -= 1;
1136 : }
1137 0 : while (frac_usec>1000000) {
1138 0 : frac_usec -= 1000000;
1139 0 : sec += 1;
1140 : }
1141 0 : frac = (frac_usec * 0xFFFFFFFFULL) / 1000000;
1142 0 : v = JS_NewObject(ctx);
1143 0 : if (JS_IsException(v)) return v;
1144 0 : JS_SetPropertyStr(ctx, v, "n", JS_NewInt64(ctx, sec));
1145 0 : JS_SetPropertyStr(ctx, v, "d", JS_NewInt64(ctx, frac));
1146 0 : return v;
1147 : }
1148 :
1149 :
1150 1 : static JSValue js_sys_crc32(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1151 : {
1152 : const u8 *data;
1153 : size_t data_size;
1154 :
1155 2 : if (!argc || !JS_IsObject(argv[0])) return JS_EXCEPTION;
1156 1 : data = JS_GetArrayBuffer(ctx, &data_size, argv[0] );
1157 1 : if (!data) return JS_EXCEPTION;
1158 1 : return JS_NewInt32(ctx, gf_crc_32(data, (u32) data_size) );
1159 : }
1160 :
1161 2 : static JSValue js_sys_sha1(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1162 : {
1163 : u8 csum[GF_SHA1_DIGEST_SIZE];
1164 : const u8 *data;
1165 : size_t data_size;
1166 :
1167 2 : if (!argc) return JS_EXCEPTION;
1168 4 : if (JS_IsString(argv[0])) {
1169 : const char *filename = JS_ToCString(ctx, argv[0]);
1170 1 : if (!filename) return JS_EXCEPTION;
1171 1 : gf_sha1_file(filename, csum);
1172 1 : JS_FreeCString(ctx, filename);
1173 1 : return JS_NewArrayBufferCopy(ctx, csum, GF_SHA1_DIGEST_SIZE);
1174 1 : } else if (JS_IsObject(argv[0])) {
1175 1 : data = JS_GetArrayBuffer(ctx, &data_size, argv[0] );
1176 1 : if (!data) return JS_EXCEPTION;
1177 :
1178 1 : gf_sha1_csum((u8 *) data, (u32) data_size, csum);
1179 1 : return JS_NewArrayBufferCopy(ctx, csum, GF_SHA1_DIGEST_SIZE);
1180 : }
1181 0 : return JS_EXCEPTION;
1182 : }
1183 :
1184 :
1185 1 : static JSValue js_sys_file_data(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1186 : {
1187 : const char *filename;
1188 : u8 *data;
1189 : u32 data_size;
1190 : GF_Err e;
1191 : JSValue res;
1192 2 : if (!argc || !JS_IsString(argv[0])) return JS_EXCEPTION;
1193 : filename = JS_ToCString(ctx, argv[0]);
1194 1 : if (!filename) return JS_EXCEPTION;
1195 :
1196 1 : e = gf_file_load_data(filename, &data, &data_size);
1197 1 : if (!data) res = js_throw_err_msg(ctx, e, "Failed to load file %s", filename);
1198 1 : else res = JS_NewArrayBuffer(ctx, data, data_size, js_gpac_free, NULL, 0);
1199 1 : JS_FreeCString(ctx, filename);
1200 1 : return res;
1201 : }
1202 :
1203 2 : static JSValue js_sys_compress_ex(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, Bool is_decomp)
1204 : {
1205 : const u8 *data;
1206 : size_t data_size;
1207 2 : u32 out_size=0;
1208 2 : u8 *out_ptr = NULL;
1209 : JSValue res;
1210 : GF_Err e;
1211 4 : if (!argc || !JS_IsObject(argv[0])) return JS_EXCEPTION;
1212 2 : data = JS_GetArrayBuffer(ctx, &data_size, argv[0] );
1213 2 : if (!data) return JS_EXCEPTION;
1214 2 : if (is_decomp) {
1215 1 : e = gf_gz_decompress_payload((u8*) data, (u32) data_size, &out_ptr, &out_size);
1216 : } else {
1217 1 : e = gf_gz_compress_payload_ex((u8 **)&data, (u32) data_size, &out_size, 0, GF_FALSE, &out_ptr);
1218 : }
1219 :
1220 2 : if (e) return js_throw_err(ctx, e);
1221 2 : res = JS_NewArrayBuffer(ctx, out_ptr, out_size, js_gpac_free, NULL, 0);
1222 2 : return res;
1223 : }
1224 1 : static JSValue js_sys_compress(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1225 : {
1226 1 : return js_sys_compress_ex(ctx, this_val, argc, argv, GF_FALSE);
1227 : }
1228 1 : static JSValue js_sys_decompress(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1229 : {
1230 1 : return js_sys_compress_ex(ctx, this_val, argc, argv, GF_TRUE);
1231 : }
1232 :
1233 : enum
1234 : {
1235 : OPT_RMDIR,
1236 : OPT_MKDIR,
1237 : OPT_DIREXISTS,
1238 : OPT_DIRCLEAN,
1239 : OPT_FILEBASENAME,
1240 : OPT_FILEEXT,
1241 : OPT_FILEDEL,
1242 : OPT_FILEMODTIME,
1243 : OPT_FILEEXISTS,
1244 : OPT_FILEMOVE,
1245 : };
1246 :
1247 10 : static JSValue js_sys_file_opt(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, u32 file_opt)
1248 : {
1249 : const char *dirname, *newfile;
1250 : char *ext;
1251 : GF_Err e;
1252 : JSValue res;
1253 20 : if (!argc || !JS_IsString(argv[0])) return JS_EXCEPTION;
1254 : dirname = JS_ToCString(ctx, argv[0]);
1255 10 : if (!dirname) return JS_EXCEPTION;
1256 :
1257 10 : res = JS_UNDEFINED;
1258 10 : switch (file_opt) {
1259 1 : case OPT_RMDIR:
1260 1 : e = gf_rmdir(dirname);
1261 1 : if (e) res = js_throw_err_msg(ctx, e, "Failed to remove dir %s", dirname);
1262 : break;
1263 1 : case OPT_MKDIR:
1264 1 : e = gf_mkdir(dirname);
1265 1 : if (e) res = js_throw_err_msg(ctx, e, "Failed to create dir %s", dirname);
1266 : break;
1267 1 : case OPT_DIREXISTS:
1268 1 : res = JS_NewBool(ctx, gf_dir_exists(dirname) );
1269 : break;
1270 1 : case OPT_DIRCLEAN:
1271 1 : e = gf_dir_cleanup(dirname);
1272 1 : if (e) res = js_throw_err_msg(ctx, e, "Failed to clean dir %s", dirname);
1273 : break;
1274 1 : case OPT_FILEBASENAME:
1275 1 : res = JS_NewString(ctx, gf_file_basename(dirname) );
1276 : break;
1277 1 : case OPT_FILEEXT:
1278 1 : ext = gf_file_ext_start(dirname);
1279 1 : res = ext ? JS_NewString(ctx, ext) : JS_NULL;
1280 : break;
1281 1 : case OPT_FILEDEL:
1282 1 : e = gf_file_delete(dirname);
1283 1 : if (e) res = js_throw_err_msg(ctx, e, "Failed to delete file %s", dirname);
1284 : break;
1285 1 : case OPT_FILEMODTIME:
1286 1 : res = JS_NewInt64(ctx, gf_file_modification_time(dirname) );
1287 : break;
1288 1 : case OPT_FILEEXISTS:
1289 1 : res = JS_NewBool(ctx, gf_file_exists(dirname) );
1290 : break;
1291 1 : case OPT_FILEMOVE:
1292 1 : newfile = (argc<2) ? NULL : JS_ToCString(ctx, argv[1]);
1293 1 : if (!newfile) res = js_throw_err_msg(ctx, GF_BAD_PARAM, "Missing new file name");
1294 : else {
1295 1 : e = gf_file_move(dirname, newfile);
1296 1 : if (e) res = js_throw_err_msg(ctx, e, "Failed to move file %s to %s", dirname, newfile);
1297 1 : JS_FreeCString(ctx, newfile);
1298 : }
1299 : break;
1300 : }
1301 :
1302 10 : JS_FreeCString(ctx, dirname);
1303 10 : return res;
1304 : }
1305 :
1306 1 : static JSValue js_sys_rmdir(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1307 : {
1308 1 : return js_sys_file_opt(ctx, this_val, argc, argv, OPT_RMDIR);
1309 : }
1310 1 : static JSValue js_sys_mkdir(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1311 : {
1312 1 : return js_sys_file_opt(ctx, this_val, argc, argv, OPT_MKDIR);
1313 : }
1314 1 : static JSValue js_sys_dir_exists(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1315 : {
1316 1 : return js_sys_file_opt(ctx, this_val, argc, argv, OPT_DIREXISTS);
1317 : }
1318 1 : static JSValue js_sys_dir_clean(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1319 : {
1320 1 : return js_sys_file_opt(ctx, this_val, argc, argv, OPT_DIRCLEAN);
1321 : }
1322 1 : static JSValue js_sys_basename(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1323 : {
1324 1 : return js_sys_file_opt(ctx, this_val, argc, argv, OPT_FILEBASENAME);
1325 : }
1326 1 : static JSValue js_sys_file_ext(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1327 : {
1328 1 : return js_sys_file_opt(ctx, this_val, argc, argv, OPT_FILEEXT);
1329 : }
1330 1 : static JSValue js_sys_file_exists(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1331 : {
1332 1 : return js_sys_file_opt(ctx, this_val, argc, argv, OPT_FILEEXISTS);
1333 : }
1334 1 : static JSValue js_sys_file_del(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1335 : {
1336 1 : return js_sys_file_opt(ctx, this_val, argc, argv, OPT_FILEDEL);
1337 : }
1338 1 : static JSValue js_sys_file_modtime(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1339 : {
1340 1 : return js_sys_file_opt(ctx, this_val, argc, argv, OPT_FILEMODTIME);
1341 : }
1342 1 : static JSValue js_sys_file_move(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1343 : {
1344 1 : return js_sys_file_opt(ctx, this_val, argc, argv, OPT_FILEMOVE);
1345 : }
1346 :
1347 :
1348 1 : static JSValue js_sys_get_opt(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1349 : {
1350 : const char *sec, *key, *val;
1351 : JSValue res;
1352 1 : if (argc!=2) return JS_EXCEPTION;
1353 : sec = JS_ToCString(ctx, argv[0]);
1354 1 : if (!sec) return JS_EXCEPTION;
1355 : key = JS_ToCString(ctx, argv[1]);
1356 1 : if (!key) {
1357 0 : JS_FreeCString(ctx, sec);
1358 0 : return JS_EXCEPTION;
1359 : }
1360 1 : val = gf_opts_get_key_restricted(sec, key);
1361 1 : res = val ? JS_NewString(ctx, val) : JS_NULL;
1362 1 : JS_FreeCString(ctx, sec);
1363 1 : JS_FreeCString(ctx, key);
1364 1 : return res;
1365 : }
1366 :
1367 1 : static JSValue js_sys_set_opt(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1368 : {
1369 : const char *sec, *key, *val;
1370 1 : if (argc<2) return JS_EXCEPTION;
1371 : sec = JS_ToCString(ctx, argv[0]);
1372 1 : if (!sec) return JS_EXCEPTION;
1373 : key = JS_ToCString(ctx, argv[1]);
1374 1 : if (!key) {
1375 0 : JS_FreeCString(ctx, sec);
1376 0 : return JS_EXCEPTION;
1377 : }
1378 : val = NULL;
1379 1 : if (argc>2)
1380 : val = JS_ToCString(ctx, argv[2]);
1381 :
1382 1 : gf_opts_set_key(sec, key, val);
1383 :
1384 1 : JS_FreeCString(ctx, sec);
1385 1 : JS_FreeCString(ctx, key);
1386 1 : if (val)
1387 1 : JS_FreeCString(ctx, val);
1388 1 : return JS_UNDEFINED;
1389 : }
1390 1 : static JSValue js_sys_discard_opts(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1391 : {
1392 1 : gf_opts_discard_changes();
1393 1 : return JS_UNDEFINED;
1394 : }
1395 :
1396 4 : static JSValue js_sys_basecode_ex(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, Bool is_dec, Bool is_16)
1397 : {
1398 : u32 out_size=0;
1399 : u8 *out_ptr = NULL;
1400 : JSValue res;
1401 : GF_Err e;
1402 4 : if (!argc) return JS_EXCEPTION;
1403 :
1404 4 : if (is_dec) {
1405 : u32 len;
1406 : const char *str = JS_ToCString(ctx, argv[0]);
1407 2 : if (!str) return JS_EXCEPTION;
1408 2 : len = (u32) strlen(str);
1409 2 : out_ptr = gf_malloc(sizeof(u8) * len);
1410 2 : if (!out_ptr) {
1411 : e = GF_OUT_OF_MEM;
1412 2 : } else if (is_16) {
1413 1 : out_size = gf_base16_decode((u8*) str, (u32) len, out_ptr, len);
1414 1 : e = out_size ? GF_OK : GF_NON_COMPLIANT_BITSTREAM;
1415 : } else {
1416 1 : out_size = gf_base64_decode((u8*) str, (u32) len, out_ptr, len);
1417 1 : e = out_size ? GF_OK : GF_NON_COMPLIANT_BITSTREAM;
1418 : }
1419 2 : JS_FreeCString(ctx, str);
1420 : } else {
1421 : const u8 *data;
1422 : size_t data_size;
1423 2 : data = JS_GetArrayBuffer(ctx, &data_size, argv[0] );
1424 2 : if (!data) return JS_EXCEPTION;
1425 2 : out_ptr = gf_malloc(sizeof(u8) * (1 + data_size * 2) );
1426 2 : if (!out_ptr) {
1427 : e = GF_OUT_OF_MEM;
1428 2 : } else if (is_16) {
1429 1 : out_size = gf_base16_encode((u8*) data, (u32) data_size, out_ptr, 1 + (u32) data_size * 2);
1430 1 : e = out_size ? GF_OK : GF_NON_COMPLIANT_BITSTREAM;
1431 : } else {
1432 1 : out_size = gf_base64_encode((u8*) data, (u32) data_size, out_ptr, 1 + (u32) data_size * 2);
1433 1 : e = out_size ? GF_OK : GF_NON_COMPLIANT_BITSTREAM;
1434 : }
1435 : }
1436 :
1437 4 : if (e) return js_throw_err(ctx, e);
1438 4 : if (is_dec) {
1439 2 : res = JS_NewArrayBuffer(ctx, out_ptr, out_size, js_gpac_free, NULL, 0);
1440 : } else {
1441 2 : out_ptr[out_size] = 0;
1442 2 : res = JS_NewString(ctx, out_ptr);
1443 2 : gf_free(out_ptr);
1444 : }
1445 4 : return res;
1446 : }
1447 1 : static JSValue js_sys_base64enc(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1448 : {
1449 1 : return js_sys_basecode_ex(ctx, this_val, argc, argv, GF_FALSE, GF_FALSE);
1450 : }
1451 1 : static JSValue js_sys_base64dec(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1452 : {
1453 1 : return js_sys_basecode_ex(ctx, this_val, argc, argv, GF_TRUE, GF_FALSE);
1454 : }
1455 1 : static JSValue js_sys_base16enc(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1456 : {
1457 1 : return js_sys_basecode_ex(ctx, this_val, argc, argv, GF_FALSE, GF_TRUE);
1458 : }
1459 1 : static JSValue js_sys_base16dec(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1460 : {
1461 1 : return js_sys_basecode_ex(ctx, this_val, argc, argv, GF_TRUE, GF_TRUE);
1462 : }
1463 1 : static JSValue js_sys_ntohl(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1464 : {
1465 : s64 val;
1466 1 : if (!argc) return JS_EXCEPTION;
1467 1 : if (JS_ToInt64(ctx, &val, argv[0])) return JS_EXCEPTION;
1468 1 : return JS_NewInt32(ctx, gf_ntohl((u32) val));
1469 : }
1470 1 : static JSValue js_sys_ntohs(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1471 : {
1472 : s64 val;
1473 1 : if (!argc) return JS_EXCEPTION;
1474 1 : if (JS_ToInt64(ctx, &val, argv[0])) return JS_EXCEPTION;
1475 1 : return JS_NewInt32(ctx, gf_ntohs((u16) val));
1476 : }
1477 1 : static JSValue js_sys_htonl(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1478 : {
1479 : s64 val;
1480 1 : if (!argc) return JS_EXCEPTION;
1481 1 : if (JS_ToInt64(ctx, &val, argv[0])) return JS_EXCEPTION;
1482 1 : return JS_NewInt32(ctx, gf_htonl((u32) val));
1483 : }
1484 1 : static JSValue js_sys_htons(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1485 : {
1486 : s64 val;
1487 1 : if (!argc) return JS_EXCEPTION;
1488 1 : if (JS_ToInt64(ctx, &val, argv[0])) return JS_EXCEPTION;
1489 1 : return JS_NewInt32(ctx, gf_htons((u16) val));
1490 : }
1491 :
1492 : static const JSCFunctionListEntry sys_funcs[] = {
1493 : JS_CGETSET_MAGIC_DEF_ENUM("nb_cores", js_sys_prop_get, NULL, JS_SYS_NB_CORES),
1494 : JS_CGETSET_MAGIC_DEF_ENUM("sampling_period_duration", js_sys_prop_get, NULL, JS_SYS_SAMPLE_DUR),
1495 : JS_CGETSET_MAGIC_DEF_ENUM("total_cpu_time", js_sys_prop_get, NULL, JS_SYS_TOTAL_CPU),
1496 : JS_CGETSET_MAGIC_DEF_ENUM("process_cpu_time", js_sys_prop_get, NULL, JS_SYS_PROCESS_CPU),
1497 : JS_CGETSET_MAGIC_DEF_ENUM("total_cpu_time_diff", js_sys_prop_get, NULL, JS_SYS_TOTAL_CPU_DIFF),
1498 : JS_CGETSET_MAGIC_DEF_ENUM("process_cpu_time_diff", js_sys_prop_get, NULL, JS_SYS_PROCESS_CPU_DIFF),
1499 : JS_CGETSET_MAGIC_DEF_ENUM("cpu_idle_time", js_sys_prop_get, NULL, JS_SYS_CPU_IDLE),
1500 : JS_CGETSET_MAGIC_DEF_ENUM("total_cpu_usage", js_sys_prop_get, NULL, JS_SYS_TOTAL_CPU_USAGE),
1501 : JS_CGETSET_MAGIC_DEF_ENUM("process_cpu_usage", js_sys_prop_get, NULL, JS_SYS_PROCESS_CPU_USAGE),
1502 : JS_CGETSET_MAGIC_DEF_ENUM("pid", js_sys_prop_get, NULL, JS_SYS_PID),
1503 : JS_CGETSET_MAGIC_DEF_ENUM("thread_count", js_sys_prop_get, NULL, JS_SYS_THREADS),
1504 : JS_CGETSET_MAGIC_DEF_ENUM("process_memory", js_sys_prop_get, NULL, JS_SYS_PROCESS_MEM),
1505 : JS_CGETSET_MAGIC_DEF_ENUM("physical_memory", js_sys_prop_get, NULL, JS_SYS_TOTAL_MEM),
1506 : JS_CGETSET_MAGIC_DEF_ENUM("physical_memory_avail", js_sys_prop_get, NULL, JS_SYS_TOTAL_MEM_AVAIL),
1507 : JS_CGETSET_MAGIC_DEF_ENUM("gpac_memory", js_sys_prop_get, NULL, JS_SYS_GPAC_MEM),
1508 :
1509 : JS_CGETSET_MAGIC_DEF_ENUM("last_wdir", js_sys_prop_get, js_sys_prop_set, JS_SYS_LAST_WORK_DIR),
1510 : JS_CGETSET_MAGIC_DEF_ENUM("batteryOn", js_sys_prop_get, NULL, JS_SYS_BATTERY_ON),
1511 : JS_CGETSET_MAGIC_DEF_ENUM("batteryCharging", js_sys_prop_get, NULL, JS_SYS_BATTERY_CHARGE),
1512 : JS_CGETSET_MAGIC_DEF_ENUM("batteryPercent", js_sys_prop_get, NULL, JS_SYS_BATTERY_PERCENT),
1513 : JS_CGETSET_MAGIC_DEF_ENUM("batteryLifeTime", js_sys_prop_get, NULL, JS_SYS_BATTERY_LIFETIME),
1514 : JS_CGETSET_MAGIC_DEF_ENUM("batteryFullLifeTime", js_sys_prop_get, NULL, JS_SYS_BATTERY_LIFETIME_FULL),
1515 : JS_CGETSET_MAGIC_DEF_ENUM("hostname", js_sys_prop_get, NULL, JS_SYS_HOSTNAME),
1516 : JS_CGETSET_MAGIC_DEF_ENUM("username", js_sys_prop_get, NULL, JS_SYS_USERNAME),
1517 :
1518 : JS_CGETSET_MAGIC_DEF_ENUM("test_mode", js_sys_prop_get, NULL, JS_SYS_TEST_MODE),
1519 : JS_CGETSET_MAGIC_DEF_ENUM("old_arch", js_sys_prop_get, NULL, JS_SYS_OLD_ARCH),
1520 : JS_CGETSET_MAGIC_DEF_ENUM("log_color", js_sys_prop_get, NULL, JS_SYS_LOG_COLOR),
1521 :
1522 : JS_CGETSET_MAGIC_DEF_ENUM("quiet", js_sys_prop_get, NULL, JS_SYS_QUIET),
1523 : JS_CGETSET_MAGIC_DEF_ENUM("timezone", js_sys_prop_get, NULL, JS_SYS_TIMEZONE),
1524 : JS_CGETSET_MAGIC_DEF_ENUM("nb_files_open", js_sys_prop_get, NULL, JS_SYS_FILES_OPEN),
1525 : JS_CGETSET_MAGIC_DEF_ENUM("cache_dir", js_sys_prop_get, NULL, JS_SYS_CACHE_DIR),
1526 : JS_CGETSET_MAGIC_DEF_ENUM("shared_dir", js_sys_prop_get, NULL, JS_SYS_SHARED_DIR),
1527 : JS_CGETSET_MAGIC_DEF_ENUM("version", js_sys_prop_get, NULL, JS_SYS_VERSION),
1528 : JS_CGETSET_MAGIC_DEF_ENUM("version_full", js_sys_prop_get, NULL, JS_SYS_VERSION_FULL),
1529 : JS_CGETSET_MAGIC_DEF_ENUM("copyright", js_sys_prop_get, NULL, JS_SYS_COPYRIGHT),
1530 : JS_CGETSET_MAGIC_DEF_ENUM("version_major", js_sys_prop_get, NULL, JS_SYS_V_MAJOR),
1531 : JS_CGETSET_MAGIC_DEF_ENUM("version_minor", js_sys_prop_get, NULL, JS_SYS_V_MINOR),
1532 : JS_CGETSET_MAGIC_DEF_ENUM("version_micro", js_sys_prop_get, NULL, JS_SYS_V_MICRO),
1533 :
1534 : JS_CFUNC_DEF("set_arg_used", 0, js_sys_set_arg_used),
1535 : JS_CFUNC_DEF("error_string", 0, js_sys_error_string),
1536 : JS_CFUNC_DEF("prompt_input", 0, js_sys_prompt_input),
1537 : JS_CFUNC_DEF("prompt_string", 0, js_sys_prompt_string),
1538 : JS_CFUNC_DEF("prompt_echo_off", 0, js_sys_prompt_echo_off),
1539 : JS_CFUNC_DEF("prompt_code", 0, js_sys_prompt_code),
1540 : JS_CFUNC_DEF("prompt_size", 0, js_sys_prompt_size),
1541 :
1542 : JS_CFUNC_DEF("keyname", 0, js_sys_keyname),
1543 : JS_CFUNC_DEF("gc", 0, js_sys_gc),
1544 :
1545 : JS_CFUNC_DEF("enum_directory", 0, js_sys_enum_directory),
1546 : JS_CFUNC_DEF("clock_ms", 0, js_sys_clock),
1547 : JS_CFUNC_DEF("clock_us", 0, js_sys_clock_high_res),
1548 : JS_CFUNC_DEF("fcc_to_str", 0, js_sys_4cc_to_str),
1549 : JS_CFUNC_DEF("rand_init", 0, js_sys_rand_init),
1550 : JS_CFUNC_DEF("rand", 0, js_sys_rand),
1551 : JS_CFUNC_DEF("rand64", 0, js_sys_rand64),
1552 : JS_CFUNC_DEF("getenv", 0, js_sys_getenv),
1553 : JS_CFUNC_DEF("get_utc", 0, js_sys_get_utc),
1554 : JS_CFUNC_DEF("get_ntp", 0, js_sys_get_ntp),
1555 : JS_CFUNC_DEF("ntp_shift", 0, js_sys_ntp_shift),
1556 : JS_CFUNC_DEF("crc32", 0, js_sys_crc32),
1557 : JS_CFUNC_DEF("sha1", 0, js_sys_sha1),
1558 : JS_CFUNC_DEF("load_file", 0, js_sys_file_data),
1559 : JS_CFUNC_DEF("compress", 0, js_sys_compress),
1560 : JS_CFUNC_DEF("decompress", 0, js_sys_decompress),
1561 : JS_CFUNC_DEF("rmdir", 0, js_sys_rmdir),
1562 : JS_CFUNC_DEF("mkdir", 0, js_sys_mkdir),
1563 : JS_CFUNC_DEF("dir_exists", 0, js_sys_dir_exists),
1564 : JS_CFUNC_DEF("dir_clean", 0, js_sys_dir_clean),
1565 : JS_CFUNC_DEF("basename", 0, js_sys_basename),
1566 : JS_CFUNC_DEF("file_ext", 0, js_sys_file_ext),
1567 : JS_CFUNC_DEF("file_exists", 0, js_sys_file_exists),
1568 : JS_CFUNC_DEF("del", 0, js_sys_file_del),
1569 : JS_CFUNC_DEF("mod_time", 0, js_sys_file_modtime),
1570 : JS_CFUNC_DEF("move", 0, js_sys_file_move),
1571 : JS_CFUNC_DEF("get_opt", 0, js_sys_get_opt),
1572 : JS_CFUNC_DEF("set_opt", 0, js_sys_set_opt),
1573 : JS_CFUNC_DEF("discard_opts", 0, js_sys_discard_opts),
1574 :
1575 : JS_CFUNC_DEF("base64enc", 0, js_sys_base64enc),
1576 : JS_CFUNC_DEF("base64dec", 0, js_sys_base64dec),
1577 : JS_CFUNC_DEF("base16enc", 0, js_sys_base16enc),
1578 : JS_CFUNC_DEF("base16dec", 0, js_sys_base16dec),
1579 :
1580 : JS_CFUNC_DEF("ntohl", 0, js_sys_ntohl),
1581 : JS_CFUNC_DEF("ntohs", 0, js_sys_ntohs),
1582 : JS_CFUNC_DEF("htonl", 0, js_sys_htonl),
1583 : JS_CFUNC_DEF("htons", 0, js_sys_htons),
1584 :
1585 : };
1586 :
1587 :
1588 40 : static void js_sha1_finalize(JSRuntime *rt, JSValue obj)
1589 : {
1590 40 : GF_SHA1Context *sha1 = JS_GetOpaque(obj, sha1_class_id);
1591 40 : if (!sha1) return;
1592 0 : gf_free(sha1);
1593 : }
1594 :
1595 : JSClassDef sha1Class = {
1596 : "SHA1",
1597 : .finalizer = js_sha1_finalize,
1598 : };
1599 :
1600 1 : static JSValue js_sha1_push(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1601 : {
1602 : const u8 *data;
1603 : size_t data_size;
1604 1 : GF_SHA1Context *sha1 = JS_GetOpaque(this_val, sha1_class_id);
1605 1 : if (!sha1) {
1606 0 : sha1 = gf_sha1_starts();
1607 0 : if (!sha1) {
1608 0 : return js_throw_err(ctx, GF_OUT_OF_MEM);
1609 : }
1610 0 : JS_SetOpaque(this_val, sha1);
1611 : }
1612 1 : if (!argc) return JS_EXCEPTION;
1613 1 : data = JS_GetArrayBuffer(ctx, &data_size, argv[0]);
1614 1 : gf_sha1_update(sha1, (u8 *) data, (u32) data_size);
1615 :
1616 1 : return JS_UNDEFINED;
1617 : }
1618 1 : static JSValue js_sha1_get(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1619 : {
1620 : u8 output[GF_SHA1_DIGEST_SIZE];
1621 1 : GF_SHA1Context *sha1 = JS_GetOpaque(this_val, sha1_class_id);
1622 1 : if (!sha1) return JS_EXCEPTION;
1623 1 : gf_sha1_finish(sha1, output);
1624 1 : JS_SetOpaque(this_val, NULL);
1625 1 : return JS_NewArrayBufferCopy(ctx, output, GF_SHA1_DIGEST_SIZE);
1626 : }
1627 :
1628 : static const JSCFunctionListEntry sha1_funcs[] = {
1629 : JS_CFUNC_DEF("push", 0, js_sha1_push),
1630 : JS_CFUNC_DEF("get", 0, js_sha1_get),
1631 : };
1632 :
1633 1 : static JSValue sha1_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv)
1634 : {
1635 : JSValue anobj;
1636 : GF_SHA1Context *sha1;
1637 :
1638 1 : sha1 = gf_sha1_starts();
1639 1 : if (!sha1) {
1640 0 : return js_throw_err(ctx, GF_OUT_OF_MEM);
1641 : }
1642 1 : anobj = JS_NewObjectClass(ctx, sha1_class_id);
1643 1 : if (JS_IsException(anobj)) {
1644 0 : gf_free(sha1);
1645 0 : return anobj;
1646 : }
1647 1 : JS_SetOpaque(anobj, sha1);
1648 1 : return anobj;
1649 : }
1650 :
1651 :
1652 42 : static void js_file_finalize(JSRuntime *rt, JSValue obj)
1653 : {
1654 42 : FILE *f = JS_GetOpaque(obj, file_class_id);
1655 42 : if (!f) return;
1656 0 : gf_fclose(f);
1657 : }
1658 :
1659 : JSClassDef fileClass = {
1660 : "FILE",
1661 : .finalizer = js_file_finalize,
1662 : };
1663 :
1664 : enum
1665 : {
1666 : JS_FILE_POS = 0,
1667 : JS_FILE_EOF,
1668 : JS_FILE_ERROR,
1669 : JS_FILE_SIZE,
1670 : JS_FILE_IS_GFIO,
1671 : };
1672 :
1673 5 : static JSValue js_file_prop_get(JSContext *ctx, JSValueConst this_val, int magic)
1674 : {
1675 5 : FILE *f = JS_GetOpaque(this_val, file_class_id);
1676 5 : if (!f) return JS_EXCEPTION;
1677 :
1678 5 : switch (magic) {
1679 1 : case JS_FILE_POS:
1680 1 : return JS_NewInt64(ctx, gf_ftell(f));
1681 1 : case JS_FILE_EOF:
1682 1 : return JS_NewBool(ctx, gf_feof(f));
1683 1 : case JS_FILE_ERROR:
1684 1 : return JS_NewInt32(ctx, gf_ferror(f) );
1685 1 : case JS_FILE_SIZE:
1686 1 : return JS_NewInt64(ctx, gf_fsize(f) );
1687 1 : case JS_FILE_IS_GFIO:
1688 1 : return JS_NewBool(ctx, gf_fileio_check(f));
1689 : }
1690 0 : return JS_UNDEFINED;
1691 : }
1692 :
1693 1 : static JSValue js_file_prop_set(JSContext *ctx, JSValueConst this_val, JSValueConst value, int magic)
1694 : {
1695 : s64 lival;
1696 1 : FILE *f = JS_GetOpaque(this_val, file_class_id);
1697 1 : if (!f) return JS_EXCEPTION;
1698 :
1699 1 : switch (magic) {
1700 1 : case JS_FILE_POS:
1701 1 : if (JS_ToInt64(ctx, &lival, value)) return JS_EXCEPTION;
1702 1 : gf_fseek(f, lival, SEEK_SET);
1703 1 : break;
1704 : }
1705 1 : return JS_UNDEFINED;
1706 : }
1707 1 : static JSValue js_file_flush(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1708 : {
1709 1 : FILE *f = JS_GetOpaque(this_val, file_class_id);
1710 1 : if (!f) return JS_EXCEPTION;
1711 1 : gf_fflush(f);
1712 1 : return JS_UNDEFINED;
1713 : }
1714 3 : static JSValue js_file_close(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1715 : {
1716 3 : FILE *f = JS_GetOpaque(this_val, file_class_id);
1717 3 : if (!f) return JS_EXCEPTION;
1718 3 : gf_fclose(f);
1719 3 : JS_SetOpaque(this_val, NULL);
1720 3 : return JS_UNDEFINED;
1721 : }
1722 1 : static JSValue js_file_read(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1723 : {
1724 : const u8 *data;
1725 : size_t size;
1726 : u32 read;
1727 1 : s32 nb_bytes=0;
1728 1 : FILE *f = JS_GetOpaque(this_val, file_class_id);
1729 1 : if (!f) return JS_EXCEPTION;
1730 1 : if (!argc) return JS_EXCEPTION;
1731 :
1732 1 : data = JS_GetArrayBuffer(ctx, &size, argv[0]);
1733 1 : if (!data) return JS_EXCEPTION;
1734 1 : if (argc>1) {
1735 0 : if (JS_ToInt32(ctx, &nb_bytes, argv[1])) return JS_EXCEPTION;
1736 : }
1737 1 : if (!nb_bytes) nb_bytes = (s32) size;
1738 0 : else if (nb_bytes > (s32) size) nb_bytes = (s32) size;
1739 :
1740 1 : read = (u32) gf_fread((void *) data, nb_bytes, f);
1741 1 : return JS_NewInt64(ctx, read);
1742 : }
1743 1 : static JSValue js_file_gets(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1744 : {
1745 1 : char *data=NULL;
1746 : char temp[1025];
1747 : JSValue res;
1748 1 : FILE *f = JS_GetOpaque(this_val, file_class_id);
1749 1 : if (!f) return JS_EXCEPTION;
1750 :
1751 1 : temp[1024] = 0;
1752 : while (1) {
1753 : u32 rlen;
1754 1 : temp[0] = 0;
1755 1 : const char *read = gf_fgets(temp, 1024, f);
1756 1 : if (!read) break;
1757 1 : gf_dynstrcat(&data, temp, NULL);
1758 1 : if (!data) return js_throw_err(ctx, GF_OUT_OF_MEM);
1759 1 : rlen = (u32) strlen(temp);
1760 1 : if (rlen <= 1024)
1761 : break;
1762 0 : if (temp[rlen-1] == '\n')
1763 : break;
1764 : }
1765 1 : res = JS_NewString(ctx, data);
1766 1 : gf_free(data);
1767 1 : return res;
1768 : }
1769 :
1770 1 : static JSValue js_file_getc(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1771 : {
1772 : char res[2];
1773 1 : FILE *f = JS_GetOpaque(this_val, file_class_id);
1774 1 : if (!f) return JS_EXCEPTION;
1775 :
1776 1 : res[0] = gf_fgetc(f);
1777 1 : res[1] = 0;
1778 1 : return JS_NewString(ctx, res);
1779 : }
1780 :
1781 1 : static JSValue js_file_write(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1782 : {
1783 : const u8 *data;
1784 : size_t size;
1785 : u32 read;
1786 1 : s32 nb_bytes=0;
1787 1 : FILE *f = JS_GetOpaque(this_val, file_class_id);
1788 1 : if (!f) return JS_EXCEPTION;
1789 1 : if (!argc) return JS_EXCEPTION;
1790 :
1791 1 : data = JS_GetArrayBuffer(ctx, &size, argv[0]);
1792 1 : if (!data) return JS_EXCEPTION;
1793 1 : if (argc>1) {
1794 0 : if (JS_ToInt32(ctx, &nb_bytes, argv[1])) return JS_EXCEPTION;
1795 : }
1796 1 : if (!nb_bytes) nb_bytes = (u32) size;
1797 0 : else if (nb_bytes > (s32) size) nb_bytes = (u32) size;
1798 :
1799 1 : read = (u32) gf_fwrite((void *) data, nb_bytes, f);
1800 1 : return JS_NewInt64(ctx, read);
1801 : }
1802 1 : static JSValue js_file_puts(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1803 : {
1804 : const char *string;
1805 1 : FILE *f = JS_GetOpaque(this_val, file_class_id);
1806 1 : if (!f || !argc) return JS_EXCEPTION;
1807 :
1808 : string = JS_ToCString(ctx, argv[0]);
1809 1 : if (!string) return JS_EXCEPTION;
1810 1 : gf_fputs(string, f);
1811 1 : JS_FreeCString(ctx, string);
1812 1 : return JS_UNDEFINED;
1813 : }
1814 :
1815 1 : static JSValue js_file_putc(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
1816 : {
1817 1 : int val=0;
1818 1 : FILE *f = JS_GetOpaque(this_val, file_class_id);
1819 1 : if (!f || !argc) return JS_EXCEPTION;
1820 :
1821 2 : if (JS_IsString(argv[0])) {
1822 : const char *string = JS_ToCString(ctx, argv[0]);
1823 1 : if (!string) return JS_EXCEPTION;
1824 1 : val = string[0];
1825 1 : JS_FreeCString(ctx, string);
1826 : } else {
1827 0 : if (JS_ToInt32(ctx, &val, argv[0])) return JS_EXCEPTION;
1828 : }
1829 1 : gf_fputc(val, f);
1830 1 : return JS_UNDEFINED;
1831 : }
1832 :
1833 : static const JSCFunctionListEntry file_funcs[] = {
1834 : JS_CGETSET_MAGIC_DEF_ENUM("pos", js_file_prop_get, js_file_prop_set, JS_FILE_POS),
1835 : JS_CGETSET_MAGIC_DEF_ENUM("eof", js_file_prop_get, NULL, JS_FILE_EOF),
1836 : JS_CGETSET_MAGIC_DEF_ENUM("error", js_file_prop_get, NULL, JS_FILE_ERROR),
1837 : JS_CGETSET_MAGIC_DEF_ENUM("size", js_file_prop_get, NULL, JS_FILE_SIZE),
1838 : JS_CGETSET_MAGIC_DEF_ENUM("gfio", js_file_prop_get, NULL, JS_FILE_IS_GFIO),
1839 :
1840 : JS_CFUNC_DEF("flush", 0, js_file_flush),
1841 : JS_CFUNC_DEF("close", 0, js_file_close),
1842 : JS_CFUNC_DEF("read", 0, js_file_read),
1843 : JS_CFUNC_DEF("gets", 0, js_file_gets),
1844 : JS_CFUNC_DEF("getc", 0, js_file_getc),
1845 : JS_CFUNC_DEF("write", 0, js_file_write),
1846 : JS_CFUNC_DEF("puts", 0, js_file_puts),
1847 : JS_CFUNC_DEF("putc", 0, js_file_putc),
1848 : };
1849 :
1850 3 : static JSValue file_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv)
1851 : {
1852 : JSValue anobj;
1853 : FILE *f=NULL;
1854 :
1855 3 : if (!argc) {
1856 1 : f = gf_file_temp(NULL);
1857 1 : if (!f) {
1858 0 : return js_throw_err(ctx, GF_OUT_OF_MEM);
1859 : }
1860 : } else {
1861 : GF_Err e = GF_OK;
1862 : const char *name=NULL, *mode=NULL, *parent_io=NULL;
1863 : name = JS_ToCString(ctx, argv[0] );
1864 2 : if (argc>1) {
1865 : mode = JS_ToCString(ctx, argv[1] );
1866 2 : if (argc>2) {
1867 : parent_io = JS_ToCString(ctx, argv[2] );
1868 : }
1869 : }
1870 :
1871 2 : if (!name || !mode) {
1872 : e = GF_BAD_PARAM;
1873 : } else {
1874 2 : f = gf_fopen_ex(name, parent_io, mode);
1875 2 : if (!f) e = GF_URL_ERROR;
1876 : }
1877 2 : if (name) JS_FreeCString(ctx, name);
1878 2 : if (mode) JS_FreeCString(ctx, mode);
1879 2 : if (parent_io) JS_FreeCString(ctx, parent_io);
1880 :
1881 2 : if (e) {
1882 0 : return js_throw_err(ctx, e);
1883 : }
1884 : }
1885 :
1886 3 : anobj = JS_NewObjectClass(ctx, file_class_id);
1887 3 : if (JS_IsException(anobj)) {
1888 0 : gf_fclose(f);
1889 0 : return anobj;
1890 : }
1891 3 : JS_SetOpaque(anobj, f);
1892 3 : return anobj;
1893 : }
1894 :
1895 :
1896 39 : static int js_gpaccore_init(JSContext *ctx, JSModuleDef *m)
1897 : {
1898 : JSValue proto, ctor;
1899 39 : if (!bitstream_class_id) {
1900 39 : JS_NewClassID(&bitstream_class_id);
1901 39 : JS_NewClass(JS_GetRuntime(ctx), bitstream_class_id, &bitstreamClass);
1902 :
1903 39 : JS_NewClassID(&sha1_class_id);
1904 39 : JS_NewClass(JS_GetRuntime(ctx), sha1_class_id, &sha1Class);
1905 :
1906 39 : JS_NewClassID(&file_class_id);
1907 39 : JS_NewClass(JS_GetRuntime(ctx), file_class_id, &fileClass);
1908 : }
1909 :
1910 39 : JSValue core_o = JS_NewObject(ctx);
1911 39 : JS_SetPropertyFunctionList(ctx, core_o, sys_funcs, countof(sys_funcs));
1912 39 : JS_SetModuleExport(ctx, m, "Sys", core_o);
1913 :
1914 39 : JSValue args = JS_NewArray(ctx);
1915 39 : u32 i, nb_args = gf_sys_get_argc();
1916 415 : for (i=0; i<nb_args; i++) {
1917 376 : JS_SetPropertyUint32(ctx, args, i, JS_NewString(ctx, gf_sys_get_arg(i)));
1918 : }
1919 39 : JS_SetPropertyStr(ctx, core_o, "args", args);
1920 :
1921 : #define DEF_CONST( _val ) \
1922 : JS_SetPropertyStr(ctx, core_o, #_val, JS_NewInt32(ctx, _val));
1923 :
1924 39 : DEF_CONST(GF_CONSOLE_RESET)
1925 39 : DEF_CONST(GF_CONSOLE_RED)
1926 39 : DEF_CONST(GF_CONSOLE_GREEN)
1927 39 : DEF_CONST(GF_CONSOLE_BLUE)
1928 39 : DEF_CONST(GF_CONSOLE_YELLOW)
1929 39 : DEF_CONST(GF_CONSOLE_CYAN)
1930 39 : DEF_CONST(GF_CONSOLE_WHITE)
1931 39 : DEF_CONST(GF_CONSOLE_MAGENTA)
1932 39 : DEF_CONST(GF_CONSOLE_CLEAR)
1933 39 : DEF_CONST(GF_CONSOLE_SAVE)
1934 39 : DEF_CONST(GF_CONSOLE_RESTORE)
1935 39 : DEF_CONST(GF_CONSOLE_BOLD)
1936 39 : DEF_CONST(GF_CONSOLE_ITALIC)
1937 39 : DEF_CONST(GF_CONSOLE_UNDERLINED)
1938 39 : DEF_CONST(GF_CONSOLE_STRIKE)
1939 :
1940 : #undef DEF_CONST
1941 :
1942 :
1943 : //bitstream constructor
1944 39 : proto = JS_NewObjectClass(ctx, bitstream_class_id);
1945 39 : JS_SetPropertyFunctionList(ctx, proto, bitstream_funcs, countof(bitstream_funcs));
1946 39 : JS_SetClassProto(ctx, bitstream_class_id, proto);
1947 39 : ctor = JS_NewCFunction2(ctx, bitstream_constructor, "Bitstream", 1, JS_CFUNC_constructor, 0);
1948 39 : JS_SetModuleExport(ctx, m, "Bitstream", ctor);
1949 :
1950 : //sha1 constructor
1951 39 : proto = JS_NewObjectClass(ctx, sha1_class_id);
1952 39 : JS_SetPropertyFunctionList(ctx, proto, sha1_funcs, countof(sha1_funcs));
1953 39 : JS_SetClassProto(ctx, sha1_class_id, proto);
1954 39 : ctor = JS_NewCFunction2(ctx, sha1_constructor, "SHA1", 1, JS_CFUNC_constructor, 0);
1955 39 : JS_SetModuleExport(ctx, m, "SHA1", ctor);
1956 :
1957 : //FILE constructor
1958 39 : proto = JS_NewObjectClass(ctx, file_class_id);
1959 39 : JS_SetPropertyFunctionList(ctx, proto, file_funcs, countof(file_funcs));
1960 39 : JS_SetClassProto(ctx, file_class_id, proto);
1961 39 : ctor = JS_NewCFunction2(ctx, file_constructor, "File", 1, JS_CFUNC_constructor, 0);
1962 39 : JS_SetModuleExport(ctx, m, "File", ctor);
1963 :
1964 39 : return 0;
1965 : }
1966 :
1967 :
1968 468 : void qjs_module_init_gpaccore(JSContext *ctx)
1969 : {
1970 : JSModuleDef *m;
1971 468 : m = JS_NewCModule(ctx, "gpaccore", js_gpaccore_init);
1972 468 : if (!m) return;
1973 :
1974 468 : JS_AddModuleExport(ctx, m, "Sys");
1975 468 : JS_AddModuleExport(ctx, m, "Bitstream");
1976 468 : JS_AddModuleExport(ctx, m, "SHA1");
1977 468 : JS_AddModuleExport(ctx, m, "File");
1978 468 : return;
1979 : }
1980 :
1981 :
1982 : #endif
1983 :
|