Skip to content
Browse files

fix up ben's abuse of the NIF api

  • Loading branch information...
1 parent dadf0d0 commit cb8bacc3ae039be1f507464759d58a955b4b7c72 Cliff Moon committed
Showing with 23 additions and 21 deletions.
  1. +23 −21 c_src/skerl_nifs.c
View
44 c_src/skerl_nifs.c
@@ -3,7 +3,6 @@
#include "skein_api.h"
static ErlNifResourceType* skein_hashstate;
-static ErlNifResourceType* skein_hashval;
typedef struct
{
@@ -14,6 +13,8 @@ ERL_NIF_TERM skein_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
ERL_NIF_TERM skein_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
ERL_NIF_TERM skein_final(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
ERL_NIF_TERM skein_hash(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+// lifecycle
+int load(ErlNifEnv* env, void ** priv_data, ERL_NIF_TERM load_info);
static ErlNifFunc nif_funcs[] =
{
@@ -23,22 +24,29 @@ static ErlNifFunc nif_funcs[] =
{"hash", 2, skein_hash}
};
-ERL_NIF_INIT(skerl, nif_funcs, NULL, NULL, NULL, NULL);
+ERL_NIF_INIT(skerl, nif_funcs, load, NULL, NULL, NULL);
static char *hash_return_strings[] = {"success", "fail", "bad_hashlen"};
+int load(ErlNifEnv* env, void ** priv_data, ERL_NIF_TERM load_info)
+{
+ skein_hashstate = enif_open_resource_type(env, "hashstate", enif_free, ERL_NIF_RT_CREATE, NULL);
+ return 0;
+}
+
ERL_NIF_TERM skein_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
+ ERL_NIF_TERM hash_state_term;
int bits = 0;
if(!enif_get_int(env, argv[0], &bits))
return enif_make_badarg(env);
- hashState *state = enif_alloc_resource(env, skein_hashstate, sizeof(hashState));
+ hashState *state = (hashState*) enif_alloc_resource(env, skein_hashstate, sizeof(hashState));
HashReturn r = Init(state, bits);
if (r == SUCCESS) {
- enif_make_resource(env, state);
+ hash_state_term = enif_make_resource(env, state);
enif_release_resource(env, state);
- return enif_make_tuple2(env, enif_make_atom(env, "ok"), state);
+ return enif_make_tuple2(env, enif_make_atom(env, "ok"), hash_state_term);
} else {
enif_release_resource(env, state);
return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_atom(env, "fail"));
@@ -55,10 +63,8 @@ ERL_NIF_TERM skein_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
HashReturn r = Update(state, (BitSequence *)(bin.data), bin.size * 8);
if (r == SUCCESS) {
- enif_release_resource(env, state);
- return enif_make_tuple2(env, enif_make_atom(env, "ok"), state);
+ return enif_make_tuple2(env, enif_make_atom(env, "ok"), enif_make_resource(env, state));
} else {
- enif_release_resource(env, state);
return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_atom(env, hash_return_strings[r]));
}
}
@@ -68,14 +74,13 @@ ERL_NIF_TERM skein_final(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
hashState *state = NULL;
enif_get_resource(env, argv[0], skein_hashstate, (void**)&state);
- BitSequence *hashval = enif_alloc_resource(env, skein_hashval, sizeof(state->statebits / 8));
- HashReturn r = Final(state, hashval);
+ ErlNifBinary out;
+ enif_alloc_binary(env, (size_t)(state->statebits/8), &out);
+
+ HashReturn r = Final(state, (BitSequence *)out.data);
if (r == SUCCESS) {
- enif_make_resource(env, hashval);
- enif_release_resource(env, hashval);
- return enif_make_tuple2(env, enif_make_atom(env, "ok"), hashval);
+ return enif_make_tuple2(env, enif_make_atom(env, "ok"), enif_make_binary(env, &out));
} else {
- enif_release_resource(env, hashval);
return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_atom(env, hash_return_strings[r]));
}
}
@@ -85,17 +90,14 @@ ERL_NIF_TERM skein_hash(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
int bits = 0;
enif_get_int(env, argv[0], &bits);
- ErlNifBinary bin;
+ ErlNifBinary bin, out;
enif_inspect_binary(env, argv[1], &bin);
+ enif_alloc_binary(env, (size_t)(bits/8), &out);
- BitSequence *hashval = enif_alloc_resource(env, skein_hashval, sizeof(bits / 8));
- HashReturn r = Hash(bits, (BitSequence *)(bin.data), bin.size * 8, hashval);
+ HashReturn r = Hash(bits, (BitSequence *)(bin.data), bin.size * 8, (BitSequence *)out.data);
if (r == SUCCESS) {
- enif_make_resource(env, hashval);
- enif_release_resource(env, hashval);
- return enif_make_tuple2(env, enif_make_atom(env, "ok"), hashval);
+ return enif_make_tuple2(env, enif_make_atom(env, "ok"), enif_make_binary(env, &out));
} else {
- enif_release_resource(env, hashval);
return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_atom(env, hash_return_strings[r]));
}
}

0 comments on commit cb8bacc

Please sign in to comment.
Something went wrong with that request. Please try again.