#include <stdint.h>
|
|
#include "erl_nif.h"
|
|
|
|
#ifdef _WIN32
|
|
#define INLINE __inline
|
|
#else
|
|
#define INLINE inline
|
|
#endif
|
|
|
|
static ErlNifResourceType* ResType = NULL;
|
|
ERL_NIF_TERM null;
|
|
ERL_NIF_TERM ok;
|
|
|
|
|
|
static int load(ErlNifEnv* env, void** priv, ERL_NIF_TERM load_info)
|
|
{
|
|
ErlNifResourceFlags flags = ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER;
|
|
ResType = enif_open_resource_type(env, NULL, "_nifArray_", NULL, flags, NULL);
|
|
if(NULL == ResType)
|
|
return -1;
|
|
null = enif_make_atom(env, "null");
|
|
ok = enif_make_atom(env, "ok");
|
|
return 0;
|
|
}
|
|
|
|
static ERL_NIF_TERM new(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
|
|
{
|
|
uint32_t Size;
|
|
if(!enif_get_uint(env, argv[0], &Size)) {
|
|
return enif_make_badarg(env);
|
|
}
|
|
|
|
ErlNifBinary **ArrayPtr = (ErlNifBinary **) enif_alloc_resource(ResType, sizeof(ErlNifBinary*)*Size);
|
|
int i;
|
|
for(i = 0; i < Size; i++){
|
|
ArrayPtr[i] = NULL;
|
|
}
|
|
ERL_NIF_TERM Res = enif_make_resource(env, ArrayPtr);
|
|
enif_release_resource(ArrayPtr);
|
|
return Res;
|
|
}
|
|
|
|
static ERL_NIF_TERM get(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
|
|
{
|
|
uint32_t Index;
|
|
if(!enif_get_uint(env, argv[1], &Index)) {
|
|
return enif_make_badarg(env);
|
|
}
|
|
|
|
ErlNifBinary **ArrayPtr;
|
|
|
|
if (!enif_get_resource(env, argv[0], ResType, (void**)&ArrayPtr)){
|
|
return enif_make_badarg(env);
|
|
}
|
|
if(NULL != ArrayPtr[Index]){
|
|
ERL_NIF_TERM Ret;
|
|
enif_binary_to_term(env, ArrayPtr[Index]->data, ArrayPtr[Index]->size, &Ret, 0);
|
|
return Ret;
|
|
} else{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
static ERL_NIF_TERM put(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
|
|
{
|
|
uint32_t Index;
|
|
if(!enif_get_uint(env, argv[1], &Index)) {
|
|
return enif_make_badarg(env);
|
|
}
|
|
|
|
ErlNifBinary *Value = (ErlNifBinary *)malloc(sizeof(ErlNifBinary));
|
|
if(!enif_term_to_binary(env, argv[2], Value))
|
|
return enif_make_badarg(env);
|
|
|
|
ErlNifBinary **ArrayPtr;
|
|
|
|
if (!enif_get_resource(env, argv[0], ResType, (void**)&ArrayPtr)){
|
|
return enif_make_badarg(env);
|
|
}
|
|
if(NULL == ArrayPtr[Index]){
|
|
ArrayPtr[Index] = Value;
|
|
return ok;
|
|
} else{
|
|
enif_release_binary(ArrayPtr[Index]),
|
|
free(ArrayPtr[Index]);
|
|
ArrayPtr[Index] = Value;
|
|
return ok;
|
|
}
|
|
}
|
|
|
|
static ERL_NIF_TERM test(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
|
|
{
|
|
ErlNifBinary Value;
|
|
if(!enif_term_to_binary(env, argv[0], &Value))
|
|
return enif_make_badarg(env);
|
|
// enif_fprintf(stdout, "IMY************ %T", argv[0]);
|
|
ERL_NIF_TERM Ret;
|
|
enif_binary_to_term(env, Value.data, Value.size, &Ret, 0);
|
|
enif_release_binary(&Value);
|
|
return Ret;
|
|
}
|
|
|
|
static ErlNifFunc nifFuns[] = {
|
|
{"new", 1, new},
|
|
{"get", 2, get},
|
|
{"put", 3, put},
|
|
{"test", 1, test},
|
|
};
|
|
|
|
ERL_NIF_INIT(nifArray, nifFuns, &load, NULL, NULL, NULL)
|