diff options
author | Sverker Eriksson <[email protected]> | 2016-02-12 18:52:20 +0100 |
---|---|---|
committer | Lukas Larsson <[email protected]> | 2016-03-29 14:57:11 +0200 |
commit | a2a86dadc648dda68b5221a7c1d83b9238be1e25 (patch) | |
tree | 6229f416cc8a8e8a4b413a3a91246e37a693ff3a /erts/emulator/beam/erl_nif.c | |
parent | 209c5cf22b5cdc70eb48e6afdcddfa7132471aab (diff) | |
download | otp-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.c | 41 |
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) |