forked from ArweaveTeam/jiffy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathobjects.cc
77 lines (63 loc) · 1.92 KB
/
objects.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// 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