Пример #1
0
static ERL_NIF_TERM elibart_prefix_search(ErlNifEnv* env, int argc,
                                          const ERL_NIF_TERM argv[])
{
    art_tree* t;
    ErlNifBinary key;
    callback_data cb_data;

    // extract arguments atr_tree, key
    if (argc != 4)
        return enif_make_badarg(env);
    if(!enif_get_resource(env, argv[0], elibart_RESOURCE, (void**) &t))
        return enif_make_badarg(env);
    if (!enif_inspect_binary(env, argv[1], &key))
        return enif_make_badarg(env);

    cb_data.env = env;
    if(!enif_is_pid(env, argv[3]))
        return mk_error(env, "not_a_pid");

    if(!enif_get_local_pid(env, argv[3], &cb_data.pid))
        return mk_error(env, "not_a_local_pid");

    cb_data.caller_ref = argv[2];
   
    // TODO this should be a worker thread since it's a long opearation (?)
    if (art_iter_prefix(t, key.data, key.size, prefix_cb, &cb_data))
        return mk_error(env, "art_prefix_search");

    ErlNifEnv *msg_env = enif_alloc_env();

    if(msg_env == NULL)
        return mk_error(env, "env_alloc_error");;

    ERL_NIF_TERM caller_ref = enif_make_copy(msg_env, argv[2]);
    ERL_NIF_TERM res = enif_make_tuple2(msg_env, caller_ref, mk_atom(msg_env, "ok"));

    if (!enif_send(env, &cb_data.pid, msg_env, res))
    {
        enif_free(msg_env);

        return mk_error(env, "art_prefix_search");
    }

    enif_free(msg_env);

    return mk_atom(env, "ok");
}
Пример #2
0
/*
 * argv[0] an atom
 * argv[1] a binary
 * argv[2] a ref
 * argv[3] 'ok'
 * argv[4] a fun
 * argv[5] a pid
 * argv[6] a port
 * argv[7] an empty list
 * argv[8] a non-empty list
 * argv[9] a tuple
 */
static ERL_NIF_TERM check_is(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    ERL_NIF_TERM ok_atom = enif_make_atom(env, "ok");

    if (!enif_is_atom(env, argv[0])) return enif_make_badarg(env);
    if (!enif_is_binary(env, argv[1])) return enif_make_badarg(env);
    if (!enif_is_ref(env, argv[2])) return enif_make_badarg(env);
    if (!enif_is_identical(argv[3], ok_atom)) return enif_make_badarg(env);
    if (!enif_is_fun(env, argv[4])) return enif_make_badarg(env);
    if (!enif_is_pid(env, argv[5])) return enif_make_badarg(env);
    if (!enif_is_port(env, argv[6])) return enif_make_badarg(env);
    if (!enif_is_empty_list(env, argv[7])) return enif_make_badarg(env);
    if (!enif_is_list(env, argv[7])) return enif_make_badarg(env);
    if (!enif_is_list(env, argv[8])) return enif_make_badarg(env);
    if (!enif_is_tuple(env, argv[9])) return enif_make_badarg(env);

    return ok_atom;
}
Пример #3
0
static void push_nif_term(lua_State* lua, ERL_NIF_TERM message, ErlNifEnv* env, ErlNifResourceType* resource_type)
{
	const int top = lua_gettop(lua);

	if(enif_is_atom(env, message))
	{
		push_nif_atom(lua, message, env);
	}
	else if(enif_is_binary(env, message))
	{
		// TODO @@@ binary also seems to be the custom types
		// that erlang makes. This may be OK, but maybe we should
		// think about putting a special type for them in lua
		push_nif_binary(lua, message, env);
	}
	else if(enif_is_list(env, message))
	{
		if(enif_is_empty_list(env, message))
		{
			luaL_checkstack(lua, 1, ERROR_STACK_MESSAGE);
			lua_newtable(lua);
		}
		else
		{
			// TODO @@@ try to send it as an IO list first and
			// if that fails send it as a regular list
			push_nif_list(lua, message, env, resource_type);
		}
	}
	else if(enif_is_tuple(env, message))
	{	
		push_nif_tuple(lua, message, env, resource_type);
	}
	else if(enif_is_pid(env, message))
	{
		push_nif_pid(lua, message, env);
	}
	else if(enif_is_ref(env, message))
	{
		push_nif_ref(lua, message, env);
	}
	else if(enif_is_exception(env, message))
	{
		//printf("#exception\n");
		luaL_checkstack(lua, 1, ERROR_STACK_MESSAGE);
		lua_pushliteral(lua, "sending an exception is not supported");
	}
	else if(enif_is_fun(env, message))
	{
		//printf("#fun\n");
		luaL_checkstack(lua, 1, ERROR_STACK_MESSAGE);
		lua_pushliteral(lua, "sending a function reference is not supported");
	}
	else if(enif_is_port(env, message))
	{
		//printf("#port\n");
		luaL_checkstack(lua, 1, ERROR_STACK_MESSAGE);
		lua_pushliteral(lua, "sending a port is not supported");
	}
	else
	{
		// thank you r14 -- must be a number
		push_nif_number(lua, message, env);
	}
	assert(lua_gettop(lua) == top+1);
}