static void resource_dtor_A(ErlNifEnv* env, void* a) { const char dtor_name[] = "resource_dtor_A_v" STRINGIFY(NIF_LIB_VER); add_call_with_arg(env, priv_data(env), dtor_name, (const char*)a, enif_sizeof_resource(a)); }
static void do_load_info(ErlNifEnv* env, ERL_NIF_TERM load_info, int* retvalp) { NifModPrivData* data = priv_data(env); ERL_NIF_TERM head, tail; unsigned ix; for (ix=0; ix<RT_MAX; ix++) { data->rt_arr[ix] = NULL; } for (head = load_info; enif_get_list_cell(env, head, &head, &tail); head = tail) { const ERL_NIF_TERM* arr; int arity; CHECK(enif_get_tuple(env, head, &arity, &arr)); switch (arity) { case 6: open_resource_type(env, arr); break; case 2: CHECK(arr[0] == am_return); CHECK(enif_get_int(env, arr[1], retvalp)); break; default: CHECK(0); } } CHECK(enif_is_empty_list(env, head)); }
static ERL_NIF_TERM get_priv_data_ptr(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { NifModPrivData** bin_data; ERL_NIF_TERM res; ADD_CALL("get_priv_data_ptr"); bin_data = (NifModPrivData**)enif_make_new_binary(env, sizeof(void*), &res); *bin_data = priv_data(env); return res; }
static ERL_NIF_TERM get_resource(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { NifModPrivData* data = priv_data(env); ErlNifBinary obin; unsigned ix; void* a; if (!enif_get_uint(env, argv[0], &ix) || ix >= RT_MAX || !enif_get_resource(env, argv[1], data->rt_arr[ix], &a) || !enif_alloc_binary(enif_sizeof_resource(a), &obin)) { return enif_make_badarg(env); } memcpy(obin.data, a, obin.size); return enif_make_binary(env, &obin); }
static ERL_NIF_TERM make_new_resource(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { NifModPrivData* data = priv_data(env); ErlNifBinary ibin; char* a; ERL_NIF_TERM ret; unsigned ix; if (!enif_get_uint(env, argv[0], &ix) || ix >= RT_MAX || !enif_inspect_binary(env, argv[1], &ibin)) { return enif_make_badarg(env); } a = (char*) enif_alloc_resource(data->rt_arr[ix], ibin.size); memcpy(a, ibin.data, ibin.size); ret = enif_make_resource(env, a); enif_release_resource(a); return ret; }
/* {resource_type, Ix|null, ErlNifResourceFlags in, "TypeName", dtor(A|B|null), ErlNifResourceFlags out}*/ static void open_resource_type(ErlNifEnv* env, const ERL_NIF_TERM* arr) { NifModPrivData* data = priv_data(env); char rt_name[30]; union { ErlNifResourceFlags e; int i; } flags, exp_res, got_res; unsigned ix; ErlNifResourceDtor* dtor; ErlNifResourceType* got_ptr; CHECK(enif_is_identical(arr[0], am_resource_type)); CHECK(enif_get_int(env, arr[2], &flags.i)); CHECK(enif_get_string(env, arr[3], rt_name, sizeof(rt_name), ERL_NIF_LATIN1) > 0); CHECK(enif_get_int(env, arr[5], &exp_res.i)); if (enif_is_identical(arr[4], am_null)) { dtor = NULL; } else if (enif_is_identical(arr[4], am_resource_dtor_A)) { dtor = resource_dtor_A; } else { CHECK(enif_is_identical(arr[4], am_resource_dtor_B)); dtor = resource_dtor_B; } got_ptr = enif_open_resource_type(env, NULL, rt_name, dtor, flags.e, &got_res.e); if (enif_get_uint(env, arr[1], &ix) && ix < RT_MAX && got_ptr != NULL) { data->rt_arr[ix] = got_ptr; } else { CHECK(enif_is_identical(arr[1], am_null)); CHECK(got_ptr == NULL); } CHECK(got_res.e == exp_res.e); }
static ERL_NIF_TERM get_priv_data_ptr(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ADD_CALL("get_priv_data_ptr"); return enif_make_ulong(env, (unsigned long)priv_data(env)); }
static ERL_NIF_TERM get_priv_data_ptr(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ADD_CALL("get_priv_data_ptr"); return enif_make_uint64(env, (ErlNifUInt64)priv_data(env)); }