You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

77 lines
2.2 KiB

// This file is part of Jiffy released under the MIT license.
// See the LICENSE file for more information.
#include "erl_nif.h"
#include "jiffy.h"
typedef struct {
// The Wrapper is a struct intended to be used as a resource to hold a
// binary that's been validated by jiffy to be a valid JSON value
ErlNifEnv* env; // Process independent env to hold the wrapped binary
ERL_NIF_TERM bin;
} Wrapper;
static ERL_NIF_TERM
wrap_new(ErlNifEnv* process_env, ErlNifEnv* process_independent_env, ERL_NIF_TERM binary)
{
jiffy_st* st = (jiffy_st*) enif_priv_data(process_env);
Wrapper* wrapper_p = enif_alloc_resource(st->res_wrapper, sizeof(Wrapper));
ERL_NIF_TERM wrapper_term = enif_make_resource(process_env, wrapper_p);
enif_release_resource(wrapper_p);
wrapper_p->env = process_independent_env;
wrapper_p->bin = binary;
return wrapper_term;
}
ERL_NIF_TERM
wrap_binary(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
if(argc != 1) {
return enif_make_badarg(env);
}
ERL_NIF_TERM binary = argv[0];
if(!enif_is_binary(env, binary)) {
return enif_make_badarg(env);
}
ErlNifEnv* process_independent_env = enif_alloc_env();
ERL_NIF_TERM bin_copy = enif_make_copy(process_independent_env, binary);
return wrap_new(env, process_independent_env, bin_copy);
}
ERL_NIF_TERM
wrap_enif_make_sub_binary(ErlNifEnv* env, ERL_NIF_TERM bin_term, size_t pos, size_t size)
{
ErlNifEnv* process_independent_env = enif_alloc_env();
// sub_bin must be created in the same env as the parent binary and then copied
ERL_NIF_TERM sub_bin = enif_make_sub_binary(env, bin_term, pos, size);
return wrap_new(env, process_independent_env, enif_make_copy(process_independent_env, sub_bin));
}
int
unwrap(ErlNifEnv* env, ERL_NIF_TERM wrapper_resource, ERL_NIF_TERM* bin_term_p)
{
jiffy_st* st = (jiffy_st*) enif_priv_data(env);
Wrapper* wrapper_p = NULL;
if(!enif_get_resource(env, wrapper_resource, st->res_wrapper, (void**) &wrapper_p)) {
return 0;
}
*bin_term_p = enif_make_copy(env, wrapper_p->bin);
return 1;
}
void
wrapper_destroy(ErlNifEnv* env, void* obj)
{
Wrapper* wrapper_p = (Wrapper*) obj;
enif_free_env(wrapper_p->env);
}