/* Creates a term which can be parsed by get_rsa_private_key(). This is a list of plain integer binaries (not mpints). */ static ERL_NIF_TERM put_rsa_private_key(ErlNifEnv* env, const RSA *rsa) { ERL_NIF_TERM result[8]; const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp; /* Return at least [E,N,D] */ n = NULL; e = NULL; d = NULL; RSA_get0_key(rsa, &n, &e, &d); result[0] = bin_from_bn(env, e); // Exponent E result[1] = bin_from_bn(env, n); // Modulus N = p*q result[2] = bin_from_bn(env, d); // Exponent D /* Check whether the optional additional parameters are available */ p = NULL; q = NULL; RSA_get0_factors(rsa, &p, &q); dmp1 = NULL; dmq1 = NULL; iqmp = NULL; RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); if (p && q && dmp1 && dmq1 && iqmp) { result[3] = bin_from_bn(env, p); // Factor p result[4] = bin_from_bn(env, q); // Factor q result[5] = bin_from_bn(env, dmp1); // D mod (p-1) result[6] = bin_from_bn(env, dmq1); // D mod (q-1) result[7] = bin_from_bn(env, iqmp); // (1/q) mod p return enif_make_list_from_array(env, result, 8); } else { return enif_make_list_from_array(env, result, 3); } }
ERL_NIF_TERM algorithms(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { #ifdef FIPS_SUPPORT int fips_mode = FIPS_mode(); unsigned int hash_cnt = fips_mode ? algo_hash_fips_cnt : algo_hash_cnt; unsigned int pubkey_cnt = fips_mode ? algo_pubkey_fips_cnt : algo_pubkey_cnt; unsigned int mac_cnt = fips_mode ? algo_mac_fips_cnt : algo_mac_cnt; unsigned int curve_cnt = fips_mode ? algo_curve_fips_cnt : algo_curve_cnt; unsigned int rsa_opts_cnt = fips_mode ? algo_rsa_opts_fips_cnt : algo_rsa_opts_cnt; #else unsigned int hash_cnt = algo_hash_cnt; unsigned int pubkey_cnt = algo_pubkey_cnt; unsigned int mac_cnt = algo_mac_cnt; unsigned int curve_cnt = algo_curve_cnt; unsigned int rsa_opts_cnt = algo_rsa_opts_cnt; #endif return enif_make_tuple6(env, enif_make_list_from_array(env, algo_hash, hash_cnt), enif_make_list_from_array(env, algo_pubkey, pubkey_cnt), cipher_types_as_list(env), enif_make_list_from_array(env, algo_mac, mac_cnt), enif_make_list_from_array(env, algo_curve, curve_cnt), enif_make_list_from_array(env, algo_rsa_opts, rsa_opts_cnt) ); }
ERL_NIF_TERM geom_to_eterm_polygon_coords(ErlNifEnv *env, const GEOSGeometry *geom) { unsigned int inner_num, i; const GEOSGeometry *outer, *inner; const GEOSCoordSequence *coords_seq; ERL_NIF_TERM coords; ERL_NIF_TERM *rings; inner_num = GEOSGetNumInteriorRings(geom); // all rings, outer + inner rings = malloc(sizeof(ERL_NIF_TERM)*inner_num+1); outer = GEOSGetExteriorRing(geom); coords_seq = GEOSGeom_getCoordSeq(outer); rings[0] = GEOSCoordSequence_to_eterm_list(env, coords_seq, GEOSGetNumCoordinates(outer)); for (i=0; i<inner_num; i++) { inner = GEOSGetInteriorRingN(geom, i); coords_seq = GEOSGeom_getCoordSeq(inner); rings[i+1] = GEOSCoordSequence_to_eterm_list(env, coords_seq, GEOSGetNumCoordinates(inner)); } coords = enif_make_list_from_array(env, rings, inner_num+1); free(rings); return coords; }
int to_erl_array(ErlNifEnv* env, JSContext* cx, JSObject* obj, ERL_NIF_TERM* term) { ERL_NIF_TERM* array = NULL; int ret = ERROR; unsigned int length; jsval v; int i; if(!JS_GetArrayLength(cx, obj, &length)) return ERROR; array = (ERL_NIF_TERM*) enif_alloc(length * sizeof(ERL_NIF_TERM)); if(array == NULL) goto done; for(i = 0; i < length; i++) { if(!JS_GetElement(cx, obj, i, &v)) goto done; if(!to_erl_intern(env, cx, v, array+i)) goto done; } *term = enif_make_list_from_array(env, array, length); ret = OK; done: if(array != NULL) enif_free(array); return ret; }
// Retrieves dataspace dimension size and maximum size. ERL_NIF_TERM h5sget_simple_extent_dims(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { hid_t dataspace_id; hsize_t *dims = NULL; hsize_t *maxdims = NULL; int status; ERL_NIF_TERM dims_list; ERL_NIF_TERM maxdims_list; ERL_NIF_TERM* dims_arr; ERL_NIF_TERM* maxdims_arr; int rank; // parse arguments check(argc == 2, "Incorrent number of arguments"); check(enif_get_int(env, argv[0], &dataspace_id), "Can't get resource from argv"); check(enif_get_int(env, argv[1], &rank), "Can't get rank from argv"); // allocate space for dims array to store a number of dimensions dims = malloc(rank * sizeof(hsize_t)); maxdims = malloc(rank * sizeof(hsize_t)); // get a number of dims from dataspace status = H5Sget_simple_extent_dims(dataspace_id, dims, maxdims); check(status > 0, "Failed to get dims."); // allocate mem for arrays of ERL_NIF_TERM so we could convert dims_arr = (ERL_NIF_TERM*)enif_alloc(sizeof(ERL_NIF_TERM) * rank); maxdims_arr = (ERL_NIF_TERM*)enif_alloc(sizeof(ERL_NIF_TERM) * rank); // convert arrays into array of ERL_NIF_TERM check(!convert_array_to_nif_array(env, rank, dims, dims_arr), "can't convert array"); check(!convert_array_to_nif_array(env, rank, maxdims, maxdims_arr), "can't convert array"); // convert arrays to list dims_list = enif_make_list_from_array(env, dims_arr, rank); maxdims_list = enif_make_list_from_array(env, maxdims_arr, rank); // cleanup free(dims); free(maxdims); return enif_make_tuple3(env, ATOM_OK, dims_list, maxdims_list); error: if(dims) free(dims); if(maxdims) free(maxdims); return error_tuple(env, "Can not get dims"); };
static ERL_NIF_TERM make_term_list_from_array(struct make_term_info* mti, int n) { ERL_NIF_TERM t[3]; t[0] = pull_term(mti); t[1] = pull_term(mti); t[2] = pull_term(mti); return enif_make_list_from_array(mti->dst_env, t, 3); }
static ERL_NIF_TERM _receive_can_messages (ErlNifEnv* env, CAN_handle* handle, unsigned int chunk_size, long timeout) { int length = 0, i = 0, chunks = 0; ERL_NIF_TERM *list, result; canmsg_t buffer[sizeof(canmsg_t) * BUFFER_LIMIT]; do { int status = _wait_for_input(handle, timeout); if (status == 0) break; if (status == -1) { result = enif_make_int(env, errno); goto end; } length = read(handle->device, &buffer[chunks], sizeof(canmsg_t) * chunk_size); if (length < 0) break; chunks += length / sizeof(canmsg_t) ; } while (length > 0 && chunks <= BUFFER_LIMIT && chunks < chunk_size); if (chunks > 0) { if (handle->raw) { void* data = enif_make_new_binary(env, chunks * sizeof(canmsg_t), &result); memcpy(data, buffer, chunks * sizeof(canmsg_t)); } else { list = enif_alloc(sizeof(ERL_NIF_TERM) * chunks); // rewrite canmsgs to list of tuples for (i = 0; i < chunks; i++) { canmsg_t* can_msg = buffer + i; ERL_NIF_TERM bin; void* data = enif_make_new_binary(env, can_msg->length, &bin); memcpy(data, can_msg->data, can_msg->length); list[i] = enif_make_tuple3(env, enif_make_int(env, can_msg->id), enif_make_tuple2(env, enif_make_long(env, can_msg->timestamp.tv_sec), enif_make_long(env, can_msg->timestamp.tv_usec)), bin); } result = enif_make_list_from_array(env, list, chunks); enif_free(list); } } else if (length == 0) result = enif_make_int(env, 0); else result = enif_make_int(env, errno); end: return result; }
int to_erl_object(ErlNifEnv* env, JSContext* cx, JSObject* obj, ERL_NIF_TERM* term) { ERL_NIF_TERM* array = NULL; ERL_NIF_TERM list; ERL_NIF_TERM keyterm; ERL_NIF_TERM valterm; JSObject* iter; jsid idp; jsval val; int length; int index; int ret = ERROR; iter = JS_NewPropertyIterator(cx, obj); if(iter == NULL) goto done; length = 0; while(JS_NextProperty(cx, iter, &idp)) { if(idp == JSID_VOID) break; length += 1; } array = enif_alloc(length * sizeof(ERL_NIF_TERM)); if(array == NULL) goto done; iter = JS_NewPropertyIterator(cx, obj); if(iter == NULL) goto done; index = 0; while(JS_NextProperty(cx, iter, &idp)) { if(idp == JSID_VOID) { list = enif_make_list_from_array(env, array, length); *term = enif_make_tuple1(env, list); ret = OK; goto done; } if(!JS_IdToValue(cx, idp, &val)) goto done; if(!to_erl_string(env, cx, val, &keyterm)) goto done; if(!JS_GetPropertyById(cx, obj, idp, &val)) goto done; if(!to_erl_intern(env, cx, val, &valterm)) goto done; array[index] = enif_make_tuple2(env, keyterm, valterm); index += 1; } done: if(array != NULL) enif_free(array); return ret; }
static ERL_NIF_TERM tuple_2_list_and_tuple(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { const ERL_NIF_TERM* arr; int arity; if (!enif_get_tuple(env,argv[0],&arity,&arr)) { return enif_make_badarg(env); } return enif_make_tuple2(env, enif_make_list_from_array(env, arr, arity), enif_make_tuple_from_array(env, arr, arity)); }
static ERL_NIF_TERM make_array(ErlNifEnv* env, mrb_state* mrb, mrb_value o) { size_t len = (int) RARRAY(o)->len; ERL_NIF_TERM list = enif_make_list_from_array(env, NULL, 0); for(int i = len; i>0; --i) { ERL_NIF_TERM term = mruby2erl(env, mrb, mrb_ary_ref(mrb, o, (mrb_int)i - 1)); list = enif_make_list_cell(env, term, list); } return list; }
static ERL_NIF_TERM call_dirty_nif_zero_args(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int i; ERL_NIF_TERM result[1000]; ERL_NIF_TERM ok = enif_make_atom(env, "ok"); assert(argc == 0); for (i = 0; i < sizeof(result)/sizeof(*result); i++) { result[i] = ok; } return enif_make_list_from_array(env, result, i); }
// convert a python object to an erlang term, return the atom 'unknown' if // the type can't be converted static ERL_NIF_TERM pynerl_obj_to_term(ErlNifEnv* env, PyObject* obj) { ERL_NIF_TERM term; if (obj == Py_False) { term = enif_make_atom(env, "false"); } else if (obj == Py_True) { term = enif_make_atom(env, "true"); } else if (PyLong_Check(obj)) { // TODO: make ints when the size allows to. term = enif_make_long(env, PyLong_AsLong(obj)); } else if (PyFloat_Check(obj)) { term = enif_make_double(env, PyFloat_AsDouble(obj)); } else if (PyTuple_Check(obj)) { Py_ssize_t i, arity = PyTuple_Size(obj); ERL_NIF_TERM *terms = (ERL_NIF_TERM*) malloc(sizeof(ERL_NIF_TERM) * (int)arity); for (i = 0; i < arity; i++) { terms[(int)i] = pynerl_obj_to_term(env, PyTuple_GetItem(obj, i)); } term = enif_make_tuple_from_array(env, terms, (unsigned int)arity); } else if (PyBytes_Check(obj)) { // XXX: the encoding must be latin1 term = enif_make_string(env, PyBytes_AsString(obj), ERL_NIF_LATIN1); } else if (PyUnicode_Check(obj)) { // XXX: the encoding must be latin1 term = enif_make_string(env, PyBytes_AsString(PyUnicode_AsLatin1String(obj)), ERL_NIF_LATIN1); } else if (PyList_Check(obj)) { Py_ssize_t i, arity = PyList_Size(obj); ERL_NIF_TERM *terms = (ERL_NIF_TERM*) malloc(sizeof(ERL_NIF_TERM) * (int)arity); for (i = 0; i < arity; i++) { terms[(int)i] = pynerl_obj_to_term(env, PyList_GetItem(obj, i)); } term = enif_make_list_from_array(env, terms, (unsigned int)arity); } else if (obj == Py_None) { term = enif_make_atom(env, "none"); } else { term = enif_make_atom(env, "unknown"); } return term; }
ERL_NIF_TERM engine_get_all_methods_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {/* () */ #ifdef HAS_ENGINE_SUPPORT ERL_NIF_TERM method_array[12]; unsigned int i = 0; ASSERT(argc == 0); #ifdef ENGINE_METHOD_RSA method_array[i++] = atom_engine_method_rsa; #endif #ifdef ENGINE_METHOD_DSA method_array[i++] = atom_engine_method_dsa; #endif #ifdef ENGINE_METHOD_DH method_array[i++] = atom_engine_method_dh; #endif #ifdef ENGINE_METHOD_RAND method_array[i++] = atom_engine_method_rand; #endif #ifdef ENGINE_METHOD_ECDH method_array[i++] = atom_engine_method_ecdh; #endif #ifdef ENGINE_METHOD_ECDSA method_array[i++] = atom_engine_method_ecdsa; #endif #ifdef ENGINE_METHOD_STORE method_array[i++] = atom_engine_method_store; #endif #ifdef ENGINE_METHOD_CIPHERS method_array[i++] = atom_engine_method_ciphers; #endif #ifdef ENGINE_METHOD_DIGESTS method_array[i++] = atom_engine_method_digests; #endif #ifdef ENGINE_METHOD_PKEY_METHS method_array[i++] = atom_engine_method_pkey_meths; #endif #ifdef ENGINE_METHOD_PKEY_ASN1_METHS method_array[i++] = atom_engine_method_pkey_asn1_meths; #endif #ifdef ENGINE_METHOD_EC method_array[i++] = atom_engine_method_ec; #endif return enif_make_list_from_array(env, method_array, i); #else return atom_notsup; #endif }
static ERL_NIF_TERM do_multi_step(ErlNifEnv *env, sqlite3 *db, sqlite3_stmt *stmt, const ERL_NIF_TERM arg) { ERL_NIF_TERM status; ERL_NIF_TERM rows = enif_make_list_from_array(env, NULL, 0); ERL_NIF_TERM *rowBuffer = NULL; int rowBufferSize = 0; int chunk_size = 0; enif_get_int(env, arg, &chunk_size); int rc = sqlite3_step(stmt); while (rc == SQLITE_ROW && chunk_size-- > 0) { if (!rowBufferSize) rowBufferSize = sqlite3_column_count(stmt); if (rowBuffer == NULL) rowBuffer = (ERL_NIF_TERM *) enif_alloc(sizeof(ERL_NIF_TERM)*rowBufferSize); rows = enif_make_list_cell(env, make_row(env, stmt, rowBuffer, rowBufferSize), rows); if (chunk_size > 0) rc = sqlite3_step(stmt); } switch(rc) { case SQLITE_ROW: status = make_atom(env, "rows"); break; case SQLITE_BUSY: status = make_atom(env, "$busy"); break; case SQLITE_DONE: /* * Automatically reset the statement after a done so * column_names will work after the statement is done. * * Not resetting the statement can lead to vm crashes. */ sqlite3_reset(stmt); status = make_atom(env, "$done"); break; default: /* We use prepare_v2, so any error code can be returned. */ return make_sqlite3_error_tuple(env, rc, db); } enif_free(rowBuffer); return enif_make_tuple2(env, status, rows); }
static ERL_NIF_TERM make_hash(ErlNifEnv* env, mrb_state* mrb, mrb_value o) { mrb_value keys = mrb_hash_keys(mrb, o); size_t len = (int) RARRAY(keys)->len; ERL_NIF_TERM list = enif_make_list_from_array(env, NULL, 0); for(int i = len; i>0; --i) { mrb_value k = mrb_ary_ref(mrb, keys, (mrb_int)i - 1); ERL_NIF_TERM key = mruby2erl(env, mrb, k); ERL_NIF_TERM value = mruby2erl(env, mrb, mrb_hash_get(mrb, o, k)); list = enif_make_list_cell(env, enif_make_tuple2(env, key, value), list); } return enif_make_tuple1(env, list); }
static ERL_NIF_TERM seg(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary bin; enif_inspect_binary(env, argv[0], &bin); char *text = (char*) bin.data; size_t size = bin.size; rmmseg::Algorithm algo(text, size); std::vector<ERL_NIF_TERM> terms; for (rmmseg::Token tok = algo.next_token(); tok.length != 0; tok = algo.next_token()) { ErlNifBinary binText; enif_alloc_binary(tok.length, &binText); memcpy(binText.data, tok.text, tok.length); terms.push_back(enif_make_binary(env, &binText)); } return enif_make_list_from_array(env, &terms[0], terms.size()); }
/* Currently support for 2 dimensions only */ ERL_NIF_TERM GEOSCoordSequence_to_eterm_list(ErlNifEnv *env, const GEOSCoordSequence *coords_seq, unsigned int len) { int i = 0; double coordx, coordy; ERL_NIF_TERM coords_list[len]; ERL_NIF_TERM coords; for(i=0; i<len; i++) { GEOSCoordSeq_getX(coords_seq, i, &coordx); GEOSCoordSeq_getY(coords_seq, i, &coordy); coords = enif_make_list2(env, enif_make_double(env, coordx), enif_make_double(env, coordy)); coords_list[i] = coords; } return enif_make_list_from_array(env, coords_list, len); }
static int handle_end(void *ctx, int array) { state_t *st = (state_t *)ctx; container_t *c = st->c; /* unlink container struct from state */ st->c = c->next; /* create and add container term */ if (array) { add_element(st, enif_make_tuple_from_array(st->env, c->array, c->count)); } else { add_element(st, enif_make_list_from_array(st->env, c->array, c->count)); } /* decallocate used container struct */ enif_free(st->env, c); return 1; }
// Creates the coordinates for a multi-geometry. static ERL_NIF_TERM geom_to_eterm_multi_coords(ErlNifEnv *env, const GEOSGeometry *multi_geom, ERL_NIF_TERM(*geom_to_eterm_coords)(ErlNifEnv *env, const GEOSGeometry *geom)) { int geom_num, i; const GEOSGeometry *geom; ERL_NIF_TERM coords; ERL_NIF_TERM *coords_multi; geom_num = GEOSGetNumGeometries(multi_geom); coords_multi = malloc(sizeof(ERL_NIF_TERM)*geom_num); for (i=0; i<geom_num; i++) { geom = GEOSGetGeometryN(multi_geom, i); coords_multi[i] = (*geom_to_eterm_coords)(env, geom); } coords = enif_make_list_from_array(env, coords_multi, geom_num); free(coords_multi); return coords; }
static ERL_NIF_TERM bf_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary state; uint32_t i, k, m; uint16_t j; uint8_t ciphertext[4 * BCRYPT_WORDS] = "OrpheanBeholderScryDoubt"; uint32_t cdata[BCRYPT_WORDS]; ERL_NIF_TERM encrypted[4 * BCRYPT_WORDS]; /* Initialize our data from argv */ if (argc != 1 || !enif_inspect_binary(env, argv[0], &state)) return enif_make_badarg(env); /* This can be precomputed later */ j = 0; for (i = 0; i < BCRYPT_WORDS; i++) cdata[i] = Blowfish_stream2word(ciphertext, 4 * BCRYPT_WORDS, &j); /* Now do the encryption */ for (k = 0; k < 64; k++) blf_enc((blf_ctx *) state.data, cdata, BCRYPT_WORDS / 2); for (i = 0; i < BCRYPT_WORDS; i++) { ciphertext[4 * i + 3] = cdata[i] & 0xff; cdata[i] = cdata[i] >> 8; ciphertext[4 * i + 2] = cdata[i] & 0xff; cdata[i] = cdata[i] >> 8; ciphertext[4 * i + 1] = cdata[i] & 0xff; cdata[i] = cdata[i] >> 8; ciphertext[4 * i + 0] = cdata[i] & 0xff; } for (m = 0; m < BCRYPT_HASHLEN; m++) { encrypted[m] = enif_make_uint(env, ciphertext[m]); } secure_bzero(state.data, state.size); enif_release_binary(&state); secure_bzero(ciphertext, sizeof(ciphertext)); secure_bzero(cdata, sizeof(cdata)); return enif_make_list_from_array(env, encrypted, BCRYPT_HASHLEN); }
ERL_NIF_TERM as_ldt_lset_get(ErlNifEnv* env, handle_t* handle, void* obj) { ldt_get_args_t* args = (ldt_get_args_t*)obj; as_status res; as_error err; as_list* p_list = NULL; res = aerospike_lset_filter(&handle->instance, &err, NULL, &args->key, &args->ldt, NULL, NULL, &p_list); as_ldt_clean_get_args(env, args); if(res != AEROSPIKE_OK) return A_AS_ERROR(env, err); ERL_NIF_TERM* results; uint32_t nresults = as_list_size(p_list); results = malloc(sizeof(ERL_NIF_TERM) * nresults); as_arraylist_iterator it; as_arraylist_iterator_init(&it, (const as_arraylist*)p_list); int i = 0; // See if the elements match what we expect. while (as_arraylist_iterator_has_next(&it)) { const as_val* p_val = as_arraylist_iterator_next(&it); results[i++] = make_nif_term_from_as_val(env, p_val); } as_list_destroy(p_list); p_list = NULL; ERL_NIF_TERM returnValue; returnValue = enif_make_list_from_array(env, results, nresults); free(results); return A_OK_VALUE(env, returnValue); }
ERL_NIF_TERM murmurhash_x64_128_impl(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary binary; uint64_t hash[2]; uint32_t seed; ERL_NIF_TERM parts[2]; // check for valid key arg if( !check_and_unpack_data(env, argv[0], &binary) ) { return enif_make_badarg(env); } // check for valid seed arg if( !enif_get_uint(env, argv[1], &seed) ) { return enif_make_badarg(env); } MurmurHash3_x64_128(binary.data, binary.size, seed, &hash); parts[0] = hash[0]; parts[1] = hash[1]; return enif_make_list_from_array(env, parts, 2); }
static bool decode_visit_array(const bson_iter_t *iter, const char *key, const bson_t *v_array, void *data) { decode_state *ds = data; decode_state cs; vec_term_t vec; bson_iter_t child; ERL_NIF_TERM out; LOG("visit array: %s \r\n", key); if(ds->depth >= MAX_DEPTHS) { return true; } init_child_state(ds, &cs); cs.keys = false; cs.depth = ds->depth + 1; if(!bson_iter_init(&child, v_array)) { return true; } vec_init(&vec); cs.vec = &vec; if(bson_iter_visit_all(&child, &decode_visitors, &cs) || child.err_off) { vec_deinit(&vec); return true; } out = enif_make_list_from_array(cs.env, cs.vec->data, cs.vec->length); vec_deinit(&vec); vec_push(ds->vec, out); return false; }
ERL_NIF_TERM murmurhash_x86_128_impl(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary binary; uint32_t hash[4] = { 0, 0, 0, 0 }; uint32_t seed; ERL_NIF_TERM parts[4]; // check for valid key arg if( !check_and_unpack_data(env, argv[0], &binary) ) { return enif_make_badarg(env); } // check for valid seed arg if( !enif_get_uint(env, argv[1], &seed) ) { return enif_make_badarg(env); } MurmurHash3_x86_128(binary.data, binary.size, seed, &hash); for( int i = 0; i < 4; i++ ) { parts[i] = enif_make_uint(env, hash[i]); } return enif_make_list_from_array(env, parts, 4); }
// frame_to_tuple/1 :: (frame) -> {ok, {W, H, NChannels, ImageSize, ImageData}} static ERL_NIF_TERM frame_to_tuple(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ERL_NIF_TERM result; frame_t* frame; if (!enif_get_resource(env, argv[0], frame_res, (void**) &frame)) { return enif_make_badarg(env); } ERL_NIF_TERM* arr = (ERL_NIF_TERM*) malloc(sizeof(ERL_NIF_TERM) * frame->_frame->imageSize); int i; for (i = 0; i < frame->_frame->imageSize; i++) { arr[i] = enif_make_int(env, frame->_frame->imageData[i]); } ERL_NIF_TERM list = enif_make_list_from_array(env, arr, frame->_frame->imageSize); result = enif_make_tuple5(env, enif_make_int(env, frame->_frame->width), enif_make_int(env, frame->_frame->height), enif_make_int(env, frame->_frame->nChannels), enif_make_int(env, frame->_frame->imageSize), list); return result; }
// c_soc:op_update(Index, Term) => {ripe, Frame} | ok | error static ERL_NIF_TERM op_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { soc::State* st = (soc::State*) enif_priv_data(env); int index; if(enif_get_int(env, argv[0], &index) == 0) { printf("[op_alloc] error: failed to initialize index\n"); return -1; } printf("update start \n"); const soc::Operation* op = st->Update(index, &argv[1]); soc::Frame* frame = op->GetFrame(); printf("update end\n"); if (frame->IsRipe()) { printf("frame->IsRipe()\n"); ERL_NIF_TERM values = enif_make_list_from_array(env, frame->GetValues(), frame->GetLimit()); return enif_make_tuple2(env, enif_make_atom(env, "ripe"), values); } else { return enif_make_atom(env, "ok"); } }
ERL_NIF_TERM blake2bp_hash(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES]; blake2b_state S[PARALLELISM_DEGREE][1]; blake2b_state FS[1]; ErlNifBinary input, key, salt, personal; uint8_t out[BLAKE2B_OUTBYTES] = {0}; unsigned int outlen; int i; ERL_NIF_TERM tmphash[BLAKE2B_OUTBYTES]; if (argc != 5 || !enif_inspect_binary(env, argv[0], &input) || !enif_inspect_binary(env, argv[1], &key) || !enif_get_uint(env, argv[2], &outlen) || !enif_inspect_binary(env, argv[3], &salt) || !enif_inspect_binary(env, argv[4], &personal)) return enif_make_badarg(env); if (!outlen || outlen > BLAKE2B_OUTBYTES) return -1; if( key.size > BLAKE2B_KEYBYTES ) return -1; for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) if( blake2bp_init_leaf( S[i], outlen, key.size, i, salt.data, personal.data, salt.size, personal.size) < 0 ) return -1; S[PARALLELISM_DEGREE - 1]->last_node = 1; // mark last node if( key.size > 0 ) { uint8_t block[BLAKE2B_BLOCKBYTES]; memset( block, 0, BLAKE2B_BLOCKBYTES ); memcpy( block, key.data, key.size ); for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) blake2b_update( S[i], block, BLAKE2B_BLOCKBYTES ); secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ } #if defined(_OPENMP) #pragma omp parallel shared(S,hash), num_threads(PARALLELISM_DEGREE) #else for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ ) #endif { #if defined(_OPENMP) size_t id__ = omp_get_thread_num(); #endif uint64_t inlen__ = input.size; const uint8_t *in__ = ( const uint8_t * )input.data; in__ += id__ * BLAKE2B_BLOCKBYTES; while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ) { blake2b_update( S[id__], in__, BLAKE2B_BLOCKBYTES ); in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; } if( inlen__ > id__ * BLAKE2B_BLOCKBYTES ) { const size_t left = inlen__ - id__ * BLAKE2B_BLOCKBYTES; const size_t len = left <= BLAKE2B_BLOCKBYTES ? left : BLAKE2B_BLOCKBYTES; blake2b_update( S[id__], in__, len ); } blake2b_final( S[id__], hash[id__], BLAKE2B_OUTBYTES ); } if( blake2bp_init_root( FS, outlen, key.size, salt.data, personal.data, salt.size, personal.size) < 0 ) return -1; FS->last_node = 1; // Mark as last node for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) blake2b_update( FS, hash[i], BLAKE2B_OUTBYTES ); blake2b_final( FS, out, outlen );; for (i = 0; i < outlen; i++) { tmphash[i] = enif_make_uint(env, out[i]); } return enif_make_list_from_array(env, tmphash, outlen); }
ERL_NIF_TERM cb_mtouch(ErlNifEnv* env, handle_t* handle, void* obj) { mtouch_args_t* args = (mtouch_args_t*)obj; struct libcouchbase_callback_m cb; int i = 0; lcb_error_t ret; ERL_NIF_TERM* results; ERL_NIF_TERM returnValue; ErlNifBinary key_binary; cb.currKey = 0; cb.ret = malloc(sizeof(struct libcouchbase_callback*) * args->numkeys); const lcb_touch_cmd_t* commands[args->numkeys]; i = 0; for (; i < args->numkeys; i++) { lcb_touch_cmd_t* touch = calloc(1, sizeof(*touch)); touch->version = 0; touch->v.v0.key = args->keys[i]; touch->v.v0.nkey = args->nkeys[i]; touch->v.v0.exptime = args->exp[i]; commands[i] = touch; } ret = lcb_touch(handle->instance, &cb, args->numkeys, commands); if (ret != LCB_SUCCESS) { return return_lcb_error(env, ret); } lcb_wait(handle->instance); results = malloc(sizeof(ERL_NIF_TERM) * args->numkeys); i = 0; for(; i < args->numkeys; i++) { enif_alloc_binary(cb.ret[i]->nkey, &key_binary); memcpy(key_binary.data, cb.ret[i]->key, cb.ret[i]->nkey); ERL_NIF_TERM key = enif_make_binary(env, &key_binary); if (cb.ret[i]->error == LCB_SUCCESS) { results[i] = enif_make_tuple2(env, key, A_OK(env)); } else { results[i] = enif_make_tuple2(env, key, return_lcb_error(env, cb.ret[i]->error)); } free(cb.ret[i]->key); free(cb.ret[i]); free(args->keys[i]); free((lcb_touch_cmd_t*) commands[i]); } returnValue = enif_make_list_from_array(env, results, args->numkeys); free(results); free(cb.ret); free(args->keys); free(args->exp); free(args->nkeys); return enif_make_tuple2(env, A_OK(env), returnValue); }
ERL_NIF_TERM cb_mget(ErlNifEnv* env, handle_t* handle, void* obj) { mget_args_t* args = (mget_args_t*)obj; struct libcouchbase_callback_m cb; lcb_error_t ret; ERL_NIF_TERM* results; ERL_NIF_TERM returnValue; ErlNifBinary databin; ErlNifBinary key_binary; unsigned int numkeys = args->numkeys; void** keys = args->keys; size_t* nkeys = args->nkeys; int exp = args->exp; int lock = args->lock; int i = 0; cb.currKey = 0; cb.ret = malloc(sizeof(struct libcouchbase_callback*) * numkeys); const lcb_get_cmd_t* commands[numkeys]; i = 0; for (; i < numkeys; i++) { lcb_get_cmd_t *get = calloc(1, sizeof(*get)); get->version = 0; get->v.v0.key = keys[i]; get->v.v0.nkey = nkeys[i]; get->v.v0.exptime = exp; get->v.v0.lock = lock; commands[i] = get; } ret = lcb_get(handle->instance, &cb, numkeys, commands); if (ret != LCB_SUCCESS) { return return_lcb_error(env, ret); } lcb_wait(handle->instance); results = malloc(sizeof(ERL_NIF_TERM) * numkeys); i = 0; for(; i < numkeys; i++) { enif_alloc_binary(cb.ret[i]->nkey, &key_binary); memcpy(key_binary.data, cb.ret[i]->key, cb.ret[i]->nkey); if (cb.ret[i]->error == LCB_SUCCESS) { enif_alloc_binary(cb.ret[i]->size, &databin); memcpy(databin.data, cb.ret[i]->data, cb.ret[i]->size); results[i] = enif_make_tuple4(env, enif_make_uint64(env, cb.ret[i]->cas), enif_make_int(env, cb.ret[i]->flag), enif_make_binary(env, &key_binary), enif_make_binary(env, &databin)); free(cb.ret[i]->data); } else { results[i] = enif_make_tuple2(env, enif_make_binary(env, &key_binary), return_lcb_error(env, cb.ret[i]->error)); } free(cb.ret[i]->key); free(cb.ret[i]); free(keys[i]); free((lcb_get_cmd_t*) commands[i]); } returnValue = enif_make_list_from_array(env, results, numkeys); free(results); free(cb.ret); free(keys); free(nkeys); return enif_make_tuple2(env, A_OK(env), returnValue); }
ERL_NIF_TERM reverse_tokens(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { decode_ctx ctx; yajl_parser_config conf = {0, 1}; // No comments, check utf8 yajl_handle handle = yajl_alloc(&decoder_callbacks, &conf, NULL, &ctx); yajl_status status; unsigned int used; ErlNifBinary bin; ERL_NIF_TERM ret; ctx.env = env; ctx.head = enif_make_list_from_array(env, NULL, 0); if(!enif_inspect_iolist_as_binary(env, argv[0], &bin)) { ret = enif_make_badarg(env); goto done; } status = yajl_parse(handle, bin.data, bin.size); used = handle->bytesConsumed; // Parsing something like "2.0" (without quotes) will // cause a spurious semi-error. We add the extra size // check so that "2008-20-10" doesn't pass. if(status == yajl_status_insufficient_data && used == bin.size) { status = yajl_parse_complete(handle); } if(status == yajl_status_ok && used != bin.size) { if(check_rest(bin.data, bin.size, used) == CANCEL) { ret = enif_make_tuple(env, 2, enif_make_atom(env, "error"), enif_make_atom(env, "garbage_after_value") ); goto done; } } switch(status) { case yajl_status_ok: ret = enif_make_tuple(env, 2, enif_make_atom(env, "ok"), ctx.head); goto done; case yajl_status_error: ret = make_error(handle, env); goto done; case yajl_status_insufficient_data: ret = enif_make_tuple(env, 2, enif_make_atom(env, "error"), enif_make_atom(env, "insufficient_data") ); goto done; case yajl_status_client_canceled: /* the only time we do this is when we can't allocate a binary. */ ret = enif_make_tuple(env, 2, enif_make_atom(env, "error"), enif_make_atom(env, "insufficient_memory") ); goto done; default: ret = enif_make_tuple(env, 2, enif_make_atom(env, "error"), enif_make_atom(env, "unknown") ); goto done; } done: if(handle != NULL) yajl_free(handle); return ret; }