aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/erl_nif.c
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2016-02-12 18:52:20 +0100
committerLukas Larsson <[email protected]>2016-03-29 14:57:11 +0200
commita2a86dadc648dda68b5221a7c1d83b9238be1e25 (patch)
tree6229f416cc8a8e8a4b413a3a91246e37a693ff3a /erts/emulator/beam/erl_nif.c
parent209c5cf22b5cdc70eb48e6afdcddfa7132471aab (diff)
downloadotp-a2a86dadc648dda68b5221a7c1d83b9238be1e25.tar.gz
otp-a2a86dadc648dda68b5221a7c1d83b9238be1e25.tar.bz2
otp-a2a86dadc648dda68b5221a7c1d83b9238be1e25.zip
erts: Improve enif_binary_to_term
* Accept a raw data buffer instead of ErlNifBinary * Accept option ERL_NIF_BIN2TERM_SAFE * Return number of read bytes
Diffstat (limited to 'erts/emulator/beam/erl_nif.c')
-rw-r--r--erts/emulator/beam/erl_nif.c41
1 files changed, 21 insertions, 20 deletions
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index 6ed89780b4..d8f2272c6d 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -686,17 +686,25 @@ int enif_term_to_binary(ErlNifEnv *dst_env, ERL_NIF_TERM term,
return 1;
}
-int enif_binary_to_term(ErlNifEnv *dst_env, ErlNifBinary *bin,
- ERL_NIF_TERM *term)
+size_t enif_binary_to_term(ErlNifEnv *dst_env,
+ const unsigned char* data,
+ size_t data_sz,
+ ERL_NIF_TERM *term,
+ ErlNifBinaryToTerm opts)
{
Sint size;
ErtsHeapFactory factory;
+ byte *bp = (byte*) data;
- if ((size = erts_decode_ext_size(bin->data, bin->size)) < 0)
+ ERTS_CT_ASSERT(ERL_NIF_BIN2TERM_SAFE == ERTS_DIST_EXT_BTT_SAFE);
+
+ if (opts & ~ERL_NIF_BIN2TERM_SAFE) {
+ return 0;
+ }
+ if ((size = erts_decode_ext_size(bp, data_sz)) < 0)
return 0;
if (size > 0) {
- byte *bp;
if (is_internal_pid(dst_env->proc->common.id)) {
flush_env(dst_env);
@@ -710,25 +718,18 @@ int enif_binary_to_term(ErlNifEnv *dst_env, ErlNifBinary *bin,
erts_factory_heap_frag_init(&factory, dst_env->heap_frag);
}
+ } else {
+ erts_factory_dummy_init(&factory);
+ }
- bp = bin->data;
- *term = erts_decode_ext(&factory, &bp);
-
- if (is_non_value(*term)) {
- return 0;
- }
+ *term = erts_decode_ext(&factory, &bp, (Uint32)opts);
- erts_factory_close(&factory);
- }
- else {
- erts_factory_dummy_init(&factory);
- *term = erts_decode_ext(&factory, &bin->data);
- if (is_non_value(*term)) {
- return 0;
- }
- ASSERT(is_immed(*term));
+ if (is_non_value(*term)) {
+ return 0;
}
- return 1;
+ erts_factory_close(&factory);
+ ASSERT(bp > data);
+ return bp - data;
}
int enif_is_identical(Eterm lhs, Eterm rhs)