// This file is part of Jiffy released under the MIT license. // See the LICENSE file for more information. #include #include #include #include "erl_nif.h" #define MAP_TYPE_PRESENT \ ((ERL_NIF_MAJOR_VERSION == 2 && ERL_NIF_MINOR_VERSION >= 6) \ || (ERL_NIF_MAJOR_VERSION > 2)) #define BEGIN_C extern "C" { #define END_C } BEGIN_C int make_object(ErlNifEnv* env, ERL_NIF_TERM pairs, ERL_NIF_TERM* out, int ret_map, int dedupe_keys) { ERL_NIF_TERM ret; ERL_NIF_TERM key; ERL_NIF_TERM val; #if MAP_TYPE_PRESENT if(ret_map) { ret = enif_make_new_map(env); while(enif_get_list_cell(env, pairs, &val, &pairs)) { if(!enif_get_list_cell(env, pairs, &key, &pairs)) { assert(0 == 1 && "Unbalanced object pairs."); } if(!enif_make_map_put(env, ret, key, val, &ret)) { return 0; } } *out = ret; return 1; } #endif std::set seen; ret = enif_make_list(env, 0); while(enif_get_list_cell(env, pairs, &val, &pairs)) { if(!enif_get_list_cell(env, pairs, &key, &pairs)) { assert(0 == 1 && "Unbalanced object pairs."); } if(dedupe_keys) { ErlNifBinary bin; if(!enif_inspect_binary(env, key, &bin)) { return 0; } std::string skey((char*) bin.data, bin.size); if(seen.count(skey) == 0) { seen.insert(skey); val = enif_make_tuple2(env, key, val); ret = enif_make_list_cell(env, val, ret); } } else { val = enif_make_tuple2(env, key, val); ret = enif_make_list_cell(env, val, ret); } } *out = enif_make_tuple1(env, ret); return 1; } END_C