aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn-Egil Dahlberg <[email protected]>2013-11-19 11:38:36 +0100
committerBjörn-Egil Dahlberg <[email protected]>2014-01-29 11:08:40 +0100
commitc71408f7184090fee077e35d0220fc021d2817fc (patch)
tree53ba5ef298de8034c7269bd3d3a1d3f6aab59137
parente0eb6d5bafcebc1c24b0a538e50a1d55a3724f01 (diff)
downloadotp-c71408f7184090fee077e35d0220fc021d2817fc.tar.gz
otp-c71408f7184090fee077e35d0220fc021d2817fc.tar.bz2
otp-c71408f7184090fee077e35d0220fc021d2817fc.zip
erts: Test Maps with NIFs
-rw-r--r--erts/emulator/test/nif_SUITE.erl25
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_SUITE.c59
2 files changed, 82 insertions, 2 deletions
diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl
index affb66289b..5b7c310aa4 100644
--- a/erts/emulator/test/nif_SUITE.erl
+++ b/erts/emulator/test/nif_SUITE.erl
@@ -29,7 +29,8 @@
init_per_group/2,end_per_group/2,
init_per_testcase/2,
end_per_testcase/2, basic/1, reload/1, upgrade/1, heap_frag/1,
- types/1, many_args/1, binaries/1, get_string/1, get_atom/1,
+ types/1, many_args/1, binaries/1, get_string/1, get_atom/1,
+ maps/1,
api_macros/1,
from_array/1, iolist_as_binary/1, resource/1, resource_binary/1,
resource_takeover/1,
@@ -58,7 +59,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[basic, reload, upgrade, heap_frag, types, many_args,
- binaries, get_string, get_atom, api_macros, from_array,
+ binaries, get_string, get_atom, maps, api_macros, from_array,
iolist_as_binary, resource, resource_binary,
resource_takeover, threading, send, send2, send3,
send_threaded, neg, is_checks, get_length, make_atom,
@@ -435,6 +436,21 @@ get_atom(Config) when is_list(Config) ->
?line {0, <<>>} = atom_to_bin('',0),
ok.
+maps(doc) -> ["Test NIF maps handling."];
+maps(suite) -> [];
+maps(Config) when is_list(Config) ->
+ TmpMem = tmpmem(),
+ Pairs = [{adam, "bert"}] ++
+ [{I,I}||I <- lists:seq(1,10)] ++
+ [{a,value},{"a","value"},{<<"a">>,<<"value">>}],
+ ok = ensure_lib_loaded(Config, 1),
+ M = maps_from_list(Pairs),
+ R = {RIs,Is} = sorted_list_from_maps(M),
+ io:format("Pairs: ~p~nMap: ~p~nReturned: ~p~n", [lists:sort(Pairs),M,R]),
+ Is = lists:sort(Pairs),
+ Is = lists:reverse(RIs),
+ ok.
+
api_macros(doc) -> ["Test macros enif_make_list<N> and enif_make_tuple<N>"];
api_macros(suite) -> [];
api_macros(Config) when is_list(Config) ->
@@ -1488,5 +1504,10 @@ otp_9668_nif(_) -> ?nif_stub.
consume_timeslice_nif(_,_) -> ?nif_stub.
call_dirty_nif(_,_,_) -> ?nif_stub.
+%% maps
+maps_from_list(_) -> ?nif_stub.
+sorted_list_from_maps(_) -> ?nif_stub.
+
+
nif_stub_error(Line) ->
exit({nif_not_loaded,module,?MODULE,line,Line}).
diff --git a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
index 6f902e186d..a0316a7861 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
+++ b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
@@ -1536,6 +1536,63 @@ static ERL_NIF_TERM call_dirty_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
}
#endif
+/* maps */
+static ERL_NIF_TERM maps_from_list(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ ERL_NIF_TERM cell = argv[0];
+ ERL_NIF_TERM map = enif_make_new_map(env);
+ ERL_NIF_TERM tuple;
+ const ERL_NIF_TERM *pair;
+ int arity = -1;
+
+ if (argc != 1 && !enif_is_list(env, cell)) return enif_make_badarg(env);
+
+ /* assume sorted keys */
+
+ while (!enif_is_empty_list(env,cell)) {
+ if (!enif_get_list_cell(env, cell, &tuple, &cell)) return enif_make_badarg(env);
+ if (enif_get_tuple(env,tuple,&arity,&pair)) {
+ enif_make_map_put(env, map, pair[0], pair[1], &map);
+ }
+ }
+
+ return map;
+}
+
+static ERL_NIF_TERM sorted_list_from_maps(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
+
+ ERL_NIF_TERM map = argv[0];
+ ERL_NIF_TERM list_f = enif_make_list(env, 0); /* NIL */
+ ERL_NIF_TERM list_b = enif_make_list(env, 0); /* NIL */
+ ERL_NIF_TERM key, value;
+ ErlNifMapIterator iter;
+
+ if (argc != 1 && !enif_is_map(env, map))
+ return enif_make_badarg(env);
+
+ if(!enif_map_iterator_create(env, map, &iter, ERL_NIF_MAP_ITERATOR_HEAD))
+ return enif_make_badarg(env);
+
+ while(enif_map_iterator_get_pair(env,&iter,&key,&value)) {
+ list_f = enif_make_list_cell(env, enif_make_tuple2(env, key, value), list_f);
+ enif_map_iterator_next(env,&iter);
+ }
+
+ enif_map_iterator_destroy(env, &iter);
+
+ if(!enif_map_iterator_create(env, map, &iter, ERL_NIF_MAP_ITERATOR_TAIL))
+ return enif_make_badarg(env);
+
+ while(enif_map_iterator_get_pair(env,&iter,&key,&value)) {
+ list_b = enif_make_list_cell(env, enif_make_tuple2(env, key, value), list_b);
+ enif_map_iterator_prev(env,&iter);
+ }
+
+ enif_map_iterator_destroy(env, &iter);
+
+ return enif_make_tuple2(env, list_f, list_b);
+}
+
static ErlNifFunc nif_funcs[] =
{
{"lib_version", 0, lib_version},
@@ -1589,6 +1646,8 @@ static ErlNifFunc nif_funcs[] =
#ifdef ERL_NIF_DIRTY_SCHEDULER_SUPPORT
{"call_dirty_nif", 3, call_dirty_nif},
#endif
+ {"maps_from_list", 1, maps_from_list},
+ {"sorted_list_from_maps", 1, sorted_list_from_maps}
};
ERL_NIF_INIT(nif_SUITE,nif_funcs,load,reload,upgrade,unload)