Anonymous avatar Anonymous committed 6bef8d2

fix up ben's abuse of the NIF api

Comments (0)

Files changed (1)

c_src/skerl_nifs.c

 #include "skein_api.h"
 
 static ErlNifResourceType* skein_hashstate;
-static ErlNifResourceType* skein_hashval;
 
 typedef struct
 {
 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[] =
 {
     {"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"));
     
     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]));
     }
 }
     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]));
     }
 }
     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]));
     }   
 }
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.