| /* | |
| * GPAC - Multimedia Framework C SDK | |
| * | |
| * Authors: Jean Le Feuvre | |
| * Copyright (c) Telecom ParisTech 2021-2022 | |
| * All rights reserved | |
| * | |
| * This file is part of GPAC / NodeJS module | |
| * | |
| * GPAC is free software; you can redistribute it and/or modify | |
| * it under the terfsess of the GNU Lesser General Public License as published by | |
| * the Free Software Foundation; either version 2, or (at your option) | |
| * any later version. | |
| * | |
| * GPAC is distributed in the hope that it will be useful, | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| * GNU Lesser General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU Lesser General Public | |
| * License along with this library; see the file COPYING. If not, write to | |
| * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | |
| * | |
| */ | |
| #ifndef _GPAC_NAPI_H | |
| #define _GPAC_NAPI_H | |
| #include <node_api.h> | |
| #include <gpac/tools.h> | |
| #include <gpac/filters.h> | |
| #include <gpac/version.h> | |
| #define NAPI_CALL(_a) \ | |
| status = _a ; \ | |
| if (status != napi_ok) { \ | |
| napi_throw_error(env, NULL, "NAPI call failed"); \ | |
| return NULL;\ | |
| } | |
| #define NARG_ARGS(_N, _MIN) \ | |
| napi_status status; \ | |
| size_t argc = _N;\ | |
| napi_value argv[_N];\ | |
| status = napi_get_cb_info(env, info, &argc, argv, NULL, NULL);\ | |
| if (status != napi_ok) {\ | |
| napi_throw_error(env, NULL, "Failed to parse arguments");\ | |
| return NULL;\ | |
| }\ | |
| if (argc+1<_MIN+1) {\ | |
| napi_throw_error(env, NULL, "Not enough arguments");\ | |
| return NULL;\ | |
| }\ | |
| #define NARG_ARGS_THIS(_N, _MIN) \ | |
| napi_status status; \ | |
| napi_value this_val;\ | |
| size_t argc = _N;\ | |
| napi_value argv[_N];\ | |
| status = napi_get_cb_info(env, info, &argc, argv, &this_val, NULL);\ | |
| if (status != napi_ok) {\ | |
| napi_throw_error(env, NULL, "Failed to parse arguments");\ | |
| return NULL;\ | |
| }\ | |
| if (argc+1<_MIN+1) {\ | |
| napi_throw_error(env, NULL, "Not enough arguments");\ | |
| return NULL;\ | |
| }\ | |
| #define NARG_ARGS_THIS_MAGIC(_N, _MIN) \ | |
| napi_status status; \ | |
| napi_value this_val;\ | |
| void *magic=NULL;\ | |
| size_t argc = _N;\ | |
| napi_value argv[_N];\ | |
| status = napi_get_cb_info(env, info, &argc, argv, &this_val, &magic);\ | |
| if ((status != napi_ok) || !magic) {\ | |
| napi_throw_error(env, NULL, "Failed to parse arguments");\ | |
| return NULL;\ | |
| }\ | |
| if (argc+1<_MIN+1) {\ | |
| napi_throw_error(env, NULL, "Not enough arguments");\ | |
| return NULL;\ | |
| }\ | |
| else if (argc>_N) {\ | |
| GF_LOG(GF_LOG_WARNING, GF_LOG_SCRIPT, ("[NodeJS] Too many arguments\n"));\ | |
| }\ | |
| #define NARG_THIS\ | |
| napi_status status;\ | |
| napi_value this_val;\ | |
| NAPI_CALL(napi_get_cb_info(env, info, NULL, NULL, &this_val, NULL) ); | |
| #define NARG_U32(_val, _argidx, def_val) \ | |
| u32 _val;\ | |
| if (_argidx<argc) { \ | |
| NAPI_CALL( napi_get_value_uint32(env, argv[_argidx], &_val) ); \ | |
| } else { \ | |
| _val = def_val; \ | |
| } | |
| #define NARG_U64(_val, _argidx, def_val) \ | |
| u64 _val;\ | |
| if (_argidx<argc) { \ | |
| NAPI_CALL( napi_get_value_int64(env, argv[_argidx], (s64*) &_val) ); \ | |
| } else { \ | |
| _val = def_val; \ | |
| } | |
| #define NARG_S32(_val, _argidx, def_val) \ | |
| s32 _val;\ | |
| if (_argidx<argc) { \ | |
| NAPI_CALL( napi_get_value_int32(env, argv[_argidx], &_val) ); \ | |
| } else { \ | |
| _val = def_val; \ | |
| } | |
| #define NARG_BOOL(_val, _argidx, def_val) \ | |
| Bool _val;\ | |
| if (_argidx<argc) { \ | |
| NAPI_CALL( napi_get_value_bool(env, argv[_argidx], (bool *) &_val) ); \ | |
| } else { \ | |
| _val = def_val; \ | |
| } | |
| #define NARG_DBL(_val, _argidx, def_val) \ | |
| Double _val;\ | |
| if (_argidx<argc) { \ | |
| NAPI_CALL( napi_get_value_double(env, argv[_argidx], &_val) ); \ | |
| } else { \ | |
| _val = def_val; \ | |
| } | |
| #define NARG_STR(_val, _argidx, _def_val) \ | |
| char *_val;\ | |
| if (_argidx<argc) { \ | |
| GPAC_NAPI *gpac; \ | |
| NAPI_CALL( napi_get_instance_data(env, (void **) &gpac) ); \ | |
| size_t s;\ | |
| napi_valuetype vtype;\ | |
| NAPI_CALL( napi_typeof(env, argv[_argidx], &vtype) );\ | |
| if (vtype == napi_null) {\ | |
| _val = NULL;\ | |
| } else {\ | |
| NAPI_CALL( napi_get_value_string_utf8(env, argv[_argidx], NULL, 0, &s) ); \ | |
| if (s+1 > gpac->str_buf_alloc) {\ | |
| gpac->str_buf = gf_realloc(gpac->str_buf, sizeof(char) * (s+1)); \ | |
| if (!gpac->str_buf) {\ | |
| napi_throw_error(env, NULL, "Out of memory");\ | |
| return NULL;\ | |
| }\ | |
| gpac->str_buf_alloc = s+1;\ | |
| }\ | |
| NAPI_CALL( napi_get_value_string_utf8(env, argv[_argidx], gpac->str_buf, gpac->str_buf_alloc, &s) ); \ | |
| gpac->str_buf[s]=0;\ | |
| _val = gpac->str_buf; \ | |
| }\ | |
| } else { \ | |
| _val = _def_val; \ | |
| } | |
| #define NARG_STR_ALLOC(_val, _argidx, _def_val) \ | |
| char *_val;\ | |
| if (_argidx<argc) { \ | |
| GPAC_NAPI *gpac; \ | |
| NAPI_CALL( napi_get_instance_data(env, (void **) &gpac) ); \ | |
| size_t s;\ | |
| napi_valuetype vtype;\ | |
| NAPI_CALL( napi_typeof(env, argv[_argidx], &vtype) );\ | |
| if (vtype == napi_null) {\ | |
| _val = NULL;\ | |
| } else {\ | |
| NAPI_CALL( napi_get_value_string_utf8(env, argv[_argidx], NULL, 0, &s) ); \ | |
| _val = gf_malloc(sizeof(char) + (s+1)); \ | |
| if (!_val) {\ | |
| napi_throw_error(env, NULL, "Out of memory");\ | |
| return NULL;\ | |
| }\ | |
| status = napi_get_value_string_utf8(env, argv[_argidx], _val, s+1, &s); \ | |
| _val[s]=0;\ | |
| }\ | |
| } else { \ | |
| _val = _def_val ? gf_strdup(_def_val) : NULL; \ | |
| } | |
| #define GET_PROP_FIELD_S32(_name, _class, _target) \ | |
| status = napi_has_named_property(env, prop, _name, (bool *) &has_p); \ | |
| if (has_p) status = napi_get_named_property(env, prop, _name, &v); \ | |
| if (status==napi_ok) { \ | |
| status = napi_get_value_int32(env, v, &_target); \ | |
| if (status) return status;\ | |
| } else { \ | |
| napi_throw_error(env, NULL, _class" missing "_name" property"); \ | |
| return status; \ | |
| } | |
| #define GET_PROP_FIELD_U32(_name, _class, _target) \ | |
| status = napi_has_named_property(env, prop, _name, (bool *) &has_p); \ | |
| if (has_p) status = napi_get_named_property(env, prop, _name, &v); \ | |
| if (status==napi_ok) { \ | |
| status = napi_get_value_uint32(env, v, &_target); \ | |
| if (status) return status;\ | |
| } else { \ | |
| napi_throw_error(env, NULL, _class" missing "_name" property"); \ | |
| return status; \ | |
| } | |
| #define GET_PROP_FIELD_S64(_name, _class, _target) \ | |
| status = napi_has_named_property(env, prop, _name, (bool *) &has_p); \ | |
| if (has_p) status = napi_get_named_property(env, prop, _name, &v); \ | |
| if (status==napi_ok) { \ | |
| status = napi_get_value_int64(env, v, &_target); \ | |
| if (status) return status;\ | |
| } else { \ | |
| napi_throw_error(env, NULL, _class" missing "_name" property"); \ | |
| return status; \ | |
| } | |
| #define GET_PROP_FIELD_U64(_name, _class, _target) \ | |
| status = napi_has_named_property(env, prop, _name, (bool *) &has_p); \ | |
| if (has_p) status = napi_get_named_property(env, prop, _name, &v); \ | |
| if (status==napi_ok) { \ | |
| status = napi_get_value_int64(env, v, (s64 *) &_target); \ | |
| if (status) return status;\ | |
| } else { \ | |
| napi_throw_error(env, NULL, _class" missing "_name" property"); \ | |
| return status; \ | |
| } | |
| #define GET_PROP_FIELD_FLT(_name, _class, _target) \ | |
| status = napi_has_named_property(env, prop, _name, (bool *) &has_p); \ | |
| if (has_p) status = napi_get_named_property(env, prop, _name, &v); \ | |
| if (status==napi_ok) { \ | |
| Double n;\ | |
| status = napi_get_value_double(env, v, &n); \ | |
| if (status) return status;\ | |
| _target = FLT2FIX(n);\ | |
| } else { \ | |
| napi_throw_error(env, NULL, _class" missing "_name" property"); \ | |
| return status; \ | |
| } | |
| #endif //_GPAC_NAPI_H |