| // This file is part of Jiffy released under the MIT license. |
| // See the LICENSE file for more information. |
| |
| #include <set> |
| #include <string> |
| |
| #include <assert.h> |
| |
| #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; |
| |
| std::set<std::string> seen; |
| |
| #if MAP_TYPE_PRESENT |
| |
| ERL_NIF_TERM old_val; |
| |
| 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_get_map_value(env, ret, key, &old_val)) { |
| if(!enif_make_map_put(env, ret, key, val, &ret)) { |
| return 0; |
| } |
| } |
| } |
| *out = ret; |
| return 1; |
| } |
| #endif |
| |
| 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 |