Skip to content
Browse files

Finish uuid v4 support.

  • Loading branch information...
1 parent 8927a3f commit 4a0eb20aaa84ea7fbc0702ffebf1ac3c68debdc6 @kellymclaughlin committed Nov 26, 2011
Showing with 129 additions and 35 deletions.
  1. +88 −22 c_src/druid.cc
  2. +41 −13 src/druuid.erl
View
110 c_src/druid.cc
@@ -1,44 +1,93 @@
-#include "erl_nif.h"
+/********************************************************************
+ Copyright (C) 2011 by Kelly L. McLaughlin
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*********************************************************************/
+
+#include "erl_nif.h"
#include "uuid.h"
-static ErlNifResourceType* druuid_RESOURCE;
-// typedef struct
-// {
-// } druuid_handle;
+static ErlNifResourceType* druuid_RESOURCE;
// Prototypes
-static ERL_NIF_TERM druuid_uuid(ErlNifEnv* env, int argc,
+static ERL_NIF_TERM druuid_uuid_v4(ErlNifEnv* env, int argc,
const ERL_NIF_TERM argv[]);
+static ERL_NIF_TERM error_tuple(ErlNifEnv* env,
+ ERL_NIF_TERM reason,
+ uuid_rc_t rc);
+
+// Atoms (initialized in on_load)
+static ERL_NIF_TERM ATOM_OK;
+static ERL_NIF_TERM ATOM_ERROR;
+static ERL_NIF_TERM ATOM_UUID_CREATE_FAILED;
+static ERL_NIF_TERM ATOM_UUID_MAKE_FAILED;
+static ERL_NIF_TERM ATOM_UUID_EXPORT_FAILED;
+static ERL_NIF_TERM ATOM_UUID_DESTROY_FAILED;
static ErlNifFunc nif_funcs[] =
{
- {"uuid", 1, druuid_uuid}
+ {"v4", 0, druuid_uuid_v4}
};
-// static ERL_NIF_TERM druuid_new(ErlNifEnv* env, int argc,
-// const ERL_NIF_TERM argv[])
-// {
-// druuid_handle* handle = enif_alloc_resource(druuid_RESOURCE,
-// sizeof(druuid_handle));
-// ERL_NIF_TERM result = enif_make_resource(env, handle);
-// enif_release_resource(handle);
-// return enif_make_tuple2(env, enif_make_atom(env, "ok"), result);
-// }
-
-
-static ERL_NIF_TERM druuid_uuid(ErlNifEnv* env, int argc,
+static ERL_NIF_TERM druuid_uuid_v4(ErlNifEnv* env, int argc,
const ERL_NIF_TERM argv[])
{
- return enif_make_atom(env, "ok");
+ uuid_t *uuid;
+ uuid_rc_t rc;
+ void *vp = NULL;
+ size_t n;
+
+ if ((rc = uuid_create(&uuid)) != UUID_RC_OK)
+ {
+ return error_tuple(env, ATOM_UUID_CREATE_FAILED, rc);
+ }
+
+ if ((rc = uuid_make(uuid, UUID_MAKE_V4)) != UUID_RC_OK)
+ {
+ return error_tuple(env, ATOM_UUID_MAKE_FAILED, rc);
+ }
+
+ if ((rc = uuid_export(uuid, UUID_FMT_STR, &vp, &n)) != UUID_RC_OK)
+ {
+ return error_tuple(env, ATOM_UUID_EXPORT_FAILED, rc);
+ }
+
+ ERL_NIF_TERM value_bin;
+ unsigned char* value = enif_make_new_binary(env, UUID_LEN_STR, &value_bin);
+ memcpy(value, vp, UUID_LEN_STR);
+
+ free(vp);
+
+ if ((rc = uuid_destroy(uuid)) != UUID_RC_OK)
+ {
+ return error_tuple(env, ATOM_UUID_DESTROY_FAILED, rc);
+ }
+
+ return value_bin;
}
static void druuid_resource_cleanup(ErlNifEnv* env, void* arg)
{
- /* Delete any dynamically allocated memory stored in druuid_handle */
- /* druuid_handle* handle = (druuid_handle*)arg; */
}
+#define ATOM(Id, Value) { Id = enif_make_atom(env, Value); }
+
static int on_load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
{
ErlNifResourceFlags flags = (ErlNifResourceFlags)(ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER);
@@ -47,9 +96,26 @@ static int on_load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
&druuid_resource_cleanup,
flags, NULL);
if (druuid_RESOURCE == NULL)
+ {
return -1;
+ }
+
+ // Initialize common atoms
+ ATOM(ATOM_OK, "ok");
+ ATOM(ATOM_ERROR, "error")
+ ATOM(ATOM_UUID_CREATE_FAILED, "uuid_create_failed");
+ ATOM(ATOM_UUID_MAKE_FAILED, "uuid_make_failed");
+ ATOM(ATOM_UUID_EXPORT_FAILED, "uuid_export_failed");
+ ATOM(ATOM_UUID_DESTROY_FAILED, "uuid_destroy_failed");
return 0;
}
+ERL_NIF_TERM error_tuple(ErlNifEnv* env, ERL_NIF_TERM reason, uuid_rc_t rc)
+{
+ ERL_NIF_TERM return_code = enif_make_int(env, rc);
+ return enif_make_tuple2(env, ATOM_ERROR,
+ enif_make_tuple2(env, reason, return_code));
+}
+
ERL_NIF_INIT(druuid, nif_funcs, &on_load, NULL, NULL, NULL);
View
54 src/druuid.erl
@@ -1,14 +1,34 @@
+%% -------------------------------------------------------------------
+%% Copyright (C) 2011 by Kelly L. McLaughlin
+%%
+%% Permission is hereby granted, free of charge, to any person obtaining a copy
+%% of this software and associated documentation files (the "Software"), to deal
+%% in the Software without restriction, including without limitation the rights
+%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+%% copies of the Software, and to permit persons to whom the Software is
+%% furnished to do so, subject to the following conditions:
+%%
+%% The above copyright notice and this permission notice shall be included in
+%% all copies or substantial portions of the Software.
+%%
+%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+%% THE SOFTWARE.
+%% -------------------------------------------------------------------
+
-module(druuid).
--export([new/0,
- uuid/1]).
+-export([v1/0,
+ v2/0,
+ v3/0,
+ v4/0]).
-on_load(init/0).
--define(nif_stub, nif_stub_error(?LINE)).
-nif_stub_error(Line) ->
- erlang:nif_error({nif_not_loaded,module,?MODULE,line,Line}).
-
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
-endif.
@@ -18,7 +38,7 @@ init() ->
{error, bad_name} ->
case code:which(?MODULE) of
Filename when is_list(Filename) ->
- filename:join([filename:dirname(Filename),"../priv", "druuid"]);
+ filename:join([filename:dirname(Filename), "../priv", "druuid"]);
_ ->
filename:join("../priv", "druuid")
end;
@@ -27,19 +47,27 @@ init() ->
end,
erlang:load_nif(SoName, 0).
-new() ->
- ?nif_stub.
+v1() ->
+ %% @TODO Not yet implemented
+ erlang:nif_error({error, not_loaded}).
+
+v2() ->
+ %% @TODO Not yet implemented
+ erlang:nif_error({error, not_loaded}).
+
+v3() ->
+ %% @TODO Not yet implemented
+ erlang:nif_error({error, not_loaded}).
-uuid(_Ref) ->
- ?nif_stub.
+v4() ->
+ erlang:nif_error({error, not_loaded}).
%% ===================================================================
%% EUnit tests
%% ===================================================================
-ifdef(TEST).
basic_test() ->
- {ok, Ref} = new(),
- ?assertEqual(ok, uuid(Ref)).
+ ?assertEqual(36, size(v4())).
-endif.

0 comments on commit 4a0eb20

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