static ERL_NIF_TERM ex_mvprintw(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { unsigned int x, y; ErlNifBinary string; if (argc != 3) return enif_make_badarg(env); if (! enif_get_uint(env, argv[0], &y)) return enif_make_badarg(env); if (! enif_get_uint(env, argv[1], &x)) return enif_make_badarg(env); if (! enif_inspect_binary(env, argv[2], &string)) return enif_make_badarg(env); char *str = alloc_and_copy_to_cstring(&string); int code = mvprintw(y, x, str); free_cstring(str); return done(env, code); }
int map_to_color(ErlNifEnv* env, ERL_NIF_TERM map, SDL_Color* color) { ERL_NIF_TERM r, g, b, a; unsigned int ri, gi, bi, ai; if (!enif_get_map_value(env, map, atom_r, &r)) return 0; if (!enif_get_map_value(env, map, atom_g, &g)) return 0; if (!enif_get_map_value(env, map, atom_b, &b)) return 0; if (!enif_get_map_value(env, map, atom_a, &a)) return 0; if (!enif_get_uint(env, r, &ri)) return 0; if (!enif_get_uint(env, g, &gi)) return 0; if (!enif_get_uint(env, b, &bi)) return 0; if (!enif_get_uint(env, a, &ai)) return 0; color->r = ri; color->g = gi; color->b = bi; color->a = ai; return 1; }
static ERL_NIF_TERM pos(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { /* pos(Matrix, Row, Column) -> float() */ mx_t mx; unsigned i, j; if (!enif_get_resource(env, argv[0], resource_type, &mx.vp) || !enif_get_uint(env, argv[1], &i) || (--i >= mx.p->nrows) || !enif_get_uint(env, argv[2], &j) || (--j >= mx.p->ncols)) { return enif_make_badarg(env); } return enif_make_double(env, POS(mx.p, i,j)); }
static ERL_NIF_TERM set_tty_speed(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int fd = -1; unsigned int speed = 0; unsigned int new_ispeed = 0; unsigned int new_ospeed = 0; struct termios ttymodes = {0}; if (enif_get_int(env, argv[0], &fd) < 1) { return enif_make_badarg(env); } if (enif_get_uint(env, argv[1], &speed) < 1 || lookup_speed(speed, &new_ispeed) < 0) { return enif_make_badarg(env); } if (enif_get_uint(env, argv[2], &speed) < 1 || lookup_speed(speed, &new_ospeed) < 0) { return enif_make_badarg(env); } /* Get ttymodes */ if (tcgetattr(fd,&ttymodes) < 0) { return mk_errno(env, errno); } if (cfsetispeed(&ttymodes,new_ispeed) < 0) { return mk_errno(env, errno); } if (cfsetospeed(&ttymodes,new_ospeed) < 0) { return mk_errno(env, errno); } /* Apply changes */ if (tcsetattr(fd, TCSANOW, &ttymodes) < 0) { return mk_errno(env, errno); } return atom_ok; }
static ERL_NIF_TERM create(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { Example* res; ERL_NIF_TERM ret; unsigned int id; Tracker* tracker; if(argc != 1) { return enif_make_badarg(env); } if(!enif_get_uint(env, argv[0], &id)) { return enif_make_badarg(env); } res = enif_alloc_resource(RES_TYPE, sizeof(Example)); if(res == NULL) return enif_make_badarg(env); ret = enif_make_resource(env, res); enif_release_resource(res); res->id = id; tracker = (Tracker*) enif_priv_data(env); tracker->count += 1; return enif_make_tuple2(env, atom_ok, ret); }
static ERL_NIF_TERM close_1(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { unsigned int channel; if (argc != 1 || !enif_is_number(env, argv[0])) { return enif_make_badarg(env); } if (!enif_get_uint(env, argv[0], &channel)) { return enif_make_badarg(env); } switch (channel) { case 0: if (state0.fd != 0) { close(state0.fd); state0.fd = 0; } break; case 1: if (state1.fd != 0) { close(state1.fd); state1.fd = 0; } break; default: return enif_make_badarg(env); } return enif_make_atom(env, "ok"); }
static ERL_NIF_TERM mem_read(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { unsigned int err, l, i, tmp; char element; int ar; char* ptr; ERL_NIF_TERM list, head, *tpl; err = enif_get_tuple(env, argv[0], &ar, (const ERL_NIF_TERM**)(&tpl)); if (err) { err = nifty_get_ptr(env, tpl[0], (ptr_t*)&ptr); } if (!err) { goto error; } err = enif_get_uint(env, argv[1], &l); if (!err) { goto error; } list = enif_make_list(env, 0); for (i=0;i<l;i++) { element = (char)*(ptr+(l-1)-i); tmp = element & 0xff; head = enif_make_uint(env, tmp); list = enif_make_list_cell(env, head, list); } return list; error: return enif_make_badarg(env); }
static ERL_NIF_TERM utc_to_datetime(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { if(argc != 1) { return enif_make_badarg(env); } unsigned int utc; if(!enif_get_uint(env, argv[0], &utc)) { return enif_make_badarg(env); } time_t now = utc; struct tm result; gmtime_r(&now, &result); return enif_make_tuple2(env, enif_make_tuple3(env, enif_make_int(env, result.tm_year + 1900), enif_make_int(env, result.tm_mon + 1), enif_make_int(env, result.tm_mday) ), enif_make_tuple3(env, enif_make_int(env, result.tm_hour), enif_make_int(env, result.tm_min), enif_make_int(env, result.tm_sec) ) ); }
ERL_NIF_TERM _hi_open(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { uint32_t iterator_type = 0; if (argc != 1 || !enif_get_uint(env, argv[0], &iterator_type)) { return enif_make_badarg(env); } if (iterator_type != HDR_ITER_REC && iterator_type != HDR_ITER_LIN && iterator_type != HDR_ITER_LOG && iterator_type != HDR_ITER_PCT) { return make_error(env, "bad_iterator_type"); } ErlNifResourceType* ctx_type = get_hi_ctx_type(env); hi_ctx_t* ctx = (hi_ctx_t*)enif_alloc_resource(ctx_type, sizeof(hi_ctx_t)); ctx->type = iterator_type; ctx->opts = NULL; ctx->iter = NULL; ERL_NIF_TERM result = enif_make_resource(env, ctx); enif_release_resource(ctx); return enif_make_tuple2(env, ATOM_OK, result); }
static ERL_NIF_TERM hexlify_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary bin, ret; unsigned int flags = 0; unsigned i, j; const char* digits; if (argc != 2 || !enif_inspect_binary(env, argv[0], &bin) || !enif_get_uint(env, argv[1], &flags)) { return enif_make_badarg(env); } digits = (flags & HMAC_UPPER) ? UPPER : LOWER; enif_alloc_binary(bin.size*2, &ret); for (i = 0, j = 0; i < bin.size; ++i) { unsigned char c = bin.data[i]; ret.data[j++] = digits[(c & 0xF0) >> 4]; ret.data[j++] = digits[(c & 0x0F)]; } if (flags & HMAC_STRING) { const char* data = (char*)ret.data; ERL_NIF_TERM s = enif_make_string_len(env, data, ret.size, ERL_NIF_LATIN1); enif_release_binary(&ret); return s; } else { return enif_make_binary(env, &ret); } }
void* cb_store_args(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { store_args_t* args = (store_args_t*)enif_alloc(sizeof(store_args_t)); ErlNifBinary value_binary; ErlNifBinary key_binary; if (!enif_get_int(env, argv[0], &args->operation)) goto error0; if (!enif_inspect_iolist_as_binary(env, argv[1], &key_binary)) goto error0; if (!enif_inspect_iolist_as_binary(env, argv[2], &value_binary)) goto error0; args->nkey = key_binary.size; args->nbytes = value_binary.size; args->key = (char*)malloc(key_binary.size); args->bytes = (char*)malloc(value_binary.size); memcpy(args->bytes, value_binary.data, value_binary.size); memcpy(args->key, key_binary.data, key_binary.size); if (!enif_get_uint(env, argv[3], &args->flags)) goto error1; if (!enif_get_int(env, argv[4], &args->exp)) goto error1; if (!enif_get_uint64(env, argv[5], (ErlNifUInt64*)&args->cas)) goto error1; return args; error1: free(args->bytes); free(args->key); error0: enif_free(args); return NULL; }
static nif_term_t salt_random_bytes(nif_heap_t *hp, int argc, const nif_term_t argv[]) { /* salt_random_bytes(Pcb, From_pid, From_ref, Cnt) -> enqueued | congested | exiting. */ struct salt_pcb *sc; nif_pid_t pid; nif_term_t ref; uint_t cnt; if (argc != 4) return (BADARG); /* Unpack arguments, check types. */ if (! enif_get_resource(hp, argv[0], salt_pcb_type, (void **)&sc)) return (BADARG); if (! enif_get_local_pid(hp, argv[1], &pid)) return (BADARG); if (! enif_is_ref(hp, argv[2])) return (BADARG); ref = argv[2]; /* Get requested size, make sure it's in bounds. */ if (! enif_get_uint(hp, argv[3], &cnt)) return (BADARG); if (cnt < 1 || cnt > SALT_MAX_MESSAGE_SIZE) return (BADARG); return (salt_enqueue_req(hp, sc, pid, ref, SALT_MSG_RANDOMBYTES_REQ, cnt)); }
static ERL_NIF_TERM _listener (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { CAN_handle* handle; ErlNifPid pid = { 0 }; // NOTE: breaking opaque type! enif_get_resource(env, argv[0], CAN_handle_type, (void**) &handle); if (handle->threaded) // there is a thread already and some pid! { pid = handle->receiver; } if (!enif_get_local_pid(env, argv[1], &handle->receiver)) // NOTE: use lock if pid type is structural! { handle->threaded = 0; return enif_make_badarg(env); } else { enif_get_uint(env, argv[2], &handle->chunk_size); enif_get_long(env, argv[3], &handle->timeout); if (!handle->threaded) // a thread was not created already { if (enif_thread_create("can_reading_thread", &handle->tid, _reading_thread, handle, 0)) { handle->threaded = 0; return enif_make_int(env, -1004); } } } return pid.pid ? enif_make_pid(env, &pid) : enif_make_int(env, 0); }
ERL_NIF_TERM geef_index_get(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { unsigned int stage; ErlNifBinary path; geef_index *index; const git_index_entry *entry; if (!enif_get_resource(env, argv[0], geef_index_type, (void **) &index)) return enif_make_badarg(env); if (!enif_get_uint(env, argv[2], &stage)) return enif_make_badarg(env); if (!enif_inspect_iolist_as_binary(env, argv[1], &path)) return enif_make_badarg(env); if (geef_terminate_binary(&path) < 0) { enif_release_binary(&path); return geef_oom(env); } entry = git_index_get_bypath(index->index, (char *) path.data, stage); enif_release_binary(&path); if (entry == NULL) return geef_error(env); return entry_to_term(env, entry); }
ERL_NIF_TERM dlcbf_new(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { unsigned int d, b; if (!enif_get_uint(env, argv[0], &d) || !enif_get_uint(env, argv[1], &b)) { return enif_make_badarg(env); } DlcbfHandle* handle = (DlcbfHandle*)enif_alloc_resource(dlcbf_RESOURCE, sizeof(DlcbfHandle)); Dlcbf* dlcbf = dlcbf_init(d, b); handle->dlcbf = dlcbf; ERL_NIF_TERM result = enif_make_resource(env, handle); enif_release_resource(handle); return enif_make_tuple2(env, ATOM_OK, result); }
//////////////////// Matrix buffer ERL_NIF_TERM pteracuda_nifs_new_matrix_int_buffer(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { unsigned int rows; unsigned int cols; bool from_matrix = false; MatrixOrientation orientation = ROW_MAJOR; unsigned int mo; if (argc == 2) { ERL_NIF_TERM head; ERL_NIF_TERM tail; if(!enif_get_list_length(env, argv[0], &rows) || !enif_get_list_cell(env, argv[0], &head, &tail) || !enif_get_list_length(env, head, &cols) || !enif_get_uint(env, argv[1], &mo)) return enif_make_badarg(env); from_matrix = true; }else if (argc !=3 || !enif_get_uint(env, argv[0], &rows) || !enif_get_uint(env, argv[1], &cols) || !enif_get_uint(env, argv[2], &mo)) { return enif_make_badarg(env); } PCudaBufferRef *ref = (PCudaBufferRef *) enif_alloc_resource(pteracuda_buffer_resource, sizeof(PCudaBufferRef)); if (!ref) { return OOM_ERROR; } if(mo == ROW_MAJOR){ orientation = ROW_MAJOR; }else if (mo == COLUMN_MAJOR){ orientation = COLUMN_MAJOR; }else return enif_make_badarg(env); ref->buffer = new PCudaMatrixIntBuffer(rows, cols, orientation); ref->destroyed = false; if (from_matrix) ref->buffer->write(env, argv[0]); ERL_NIF_TERM res = enif_make_resource(env, ref); enif_release_resource(ref); return enif_make_tuple2(env, ATOM_OK, res); }
static ERL_NIF_TERM create(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { /* create(Nrows, Ncolumns, [[first row],[second row],...,[last row]]) -> Matrix */ unsigned nrows, ncols; unsigned i, j; ERL_NIF_TERM list, row, ret; Matrix* mx = NULL; if (!enif_get_uint(env, argv[0], &nrows) || nrows < 1 || !enif_get_uint(env, argv[1], &ncols) || ncols < 1) { goto badarg; } mx = alloc_matrix(env, nrows, ncols); list = argv[2]; for (i = 0; i<nrows; i++) { if (!enif_get_list_cell(env, list, &row, &list)) { goto badarg; } for (j = 0; j<ncols; j++) { ERL_NIF_TERM v; if (!enif_get_list_cell(env, row, &v, &row) || !get_number(env, v, &POS(mx,i,j))) { goto badarg; } } if (!enif_is_empty_list(env, row)) { goto badarg; } } if (!enif_is_empty_list(env, list)) { goto badarg; } ret = enif_make_resource(env, mx); enif_release_resource(mx); return ret; badarg: if (mx != NULL) { enif_release_resource(mx); } return enif_make_badarg(env); }
static int test_uint(ErlNifEnv* env, unsigned i1) { unsigned i2 = 0; ERL_NIF_TERM int_term = enif_make_uint(env, i1); if (!enif_get_uint(env,int_term, &i2) || i1 != i2) { fprintf(stderr, "test_uint(%u) ...FAILED i2=%u\r\n", i1, i2); return 0; } return 1; }
ERL_NIF_TERM parse_opt(ErlNifEnv* env, ERL_NIF_TERM e, hi_opts_t* o) { int arity; const ERL_NIF_TERM* opt; if (enif_get_tuple(env, e, &arity, &opt) && arity==2) { if (opt[0] == ATOM_LINEAR_VAL_UNIT) { uint32_t value_size; if (enif_get_uint(env, opt[1], &value_size)) { o->linear_value_units_per_bucket = value_size; } } if (opt[0] == ATOM_LOG_VAL_UNIT) { uint32_t value_size; if (enif_get_uint(env, opt[1], &value_size)) { o->log_value_units_first_bucket= value_size; } } if (opt[0] == ATOM_LOG_BASE) { double log_base; if (enif_get_double(env, opt[1], &log_base)) { o->log_base = log_base; } } if (opt[0] == ATOM_PERCENTILE_HALF_TICKS) { uint32_t ticks_per_half; if (enif_get_uint(env, opt[1], &ticks_per_half)) { o->percentile_ticks_per_half_distance = ticks_per_half; } } } return ATOM_OK; }
static ERL_NIF_TERM setup_2(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { unsigned int channel; unsigned long speed; int error; if (argc != 2 || !enif_is_number(env, argv[0]) || !enif_is_number(env, argv[1])) { return enif_make_badarg(env); } if (!enif_get_uint(env, argv[0], &channel)) { return enif_make_badarg(env); } if (!enif_get_ulong(env, argv[1], &speed)) { return enif_make_badarg(env); } if (speed < 500000 || speed > 32000000) { return enif_make_badarg(env); } switch (channel) { case 0: if (state0.fd != 0) { return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_string(env, "channel already opened", ERL_NIF_LATIN1)); } else { state0.env = env; state0.fd = wiringPiSPISetup(channel, speed); if (state0.fd == 0) { error = errno; return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_int(env, error)); } else { return enif_make_tuple2(env, enif_make_atom(env, "ok"), enif_make_int(env, channel)); } } break; case 1: if (state1.fd != 0) { return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_string(env, "channel already opened", ERL_NIF_LATIN1)); } else { state1.env = env; state1.fd = wiringPiSPISetup(channel, speed); if (state1.fd == 0) { error = errno; return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_int(env, error)); } else { return enif_make_tuple2(env, enif_make_atom(env, "ok"), enif_make_int(env, channel)); } } break; default: return enif_make_badarg(env); } }
static ERL_NIF_TERM _recv (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { CAN_handle* handle; unsigned int chunk_size; long timeout; ERL_NIF_TERM result; enif_get_resource(env, argv[0], CAN_handle_type, (void**) &handle); enif_get_uint(env, argv[1], &chunk_size); enif_get_long(env,argv[2], &timeout); result = _receive_can_messages(env, handle, chunk_size, timeout); return result; }
static ERL_NIF_TERM nif_sleep(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { unsigned int num; if(argc != 1) return enif_make_badarg(env); if(!enif_get_uint(env, argv[0], &num)) return enif_make_badarg(env); sleep(num); return enif_make_int(env, 0); }
unsigned int fetch_uint(ErlNifEnv* env, ERL_NIF_TERM* items) { ERL_NIF_TERM head; // Fetch head if possible if (! enif_get_list_cell(env, *items, &head, items)) return 0; unsigned int i; double d; if(enif_get_uint(env, head, &i)) return i; if(enif_get_double(env, head, &d)) return (unsigned int) abs(d); return 0; };
static ERL_NIF_TERM get_resource(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { NifModPrivData* data = priv_data(env); ErlNifBinary obin; unsigned ix; void* a; if (!enif_get_uint(env, argv[0], &ix) || ix >= RT_MAX || !enif_get_resource(env, argv[1], data->rt_arr[ix], &a) || !enif_alloc_binary(enif_sizeof_resource(a), &obin)) { return enif_make_badarg(env); } memcpy(obin.data, a, obin.size); return enif_make_binary(env, &obin); }
static ERL_NIF_TERM grow_blob(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { union { void* vp; struct make_term_info* p; }mti; ERL_NIF_TERM term; if (!enif_get_resource(env, argv[0], msgenv_resource_type, &mti.vp) || (argc>2 && !enif_get_uint(env,argv[2], &mti.p->n))) { return enif_make_badarg(env); } mti.p->caller_env = env; mti.p->other_term = argv[1]; mti.p->n %= num_of_make_funcs(); make_term_n(mti.p, mti.p->n++, &term); mti.p->blob = enif_make_list_cell(mti.p->dst_env, term, mti.p->blob); return atom_ok; }
static ERL_NIF_TERM nacl_randombytes(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) { unsigned int requested_size; ErlNifBinary result; if (!enif_get_uint(env, argv[0], &requested_size)) return enif_make_badarg(env); if (!enif_alloc_binary(requested_size, &result)) return nacl_error_tuple(env, "alloc_failed"); randombytes(result.data, result.size); return enif_make_binary(env, &result); }
ERL_NIF_TERM strong_rand_bytes_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {/* (Bytes) */ unsigned bytes; unsigned char* data; ERL_NIF_TERM ret; if (!enif_get_uint(env, argv[0], &bytes)) { return enif_make_badarg(env); } data = enif_make_new_binary(env, bytes, &ret); if ( RAND_bytes(data, bytes) != 1) { return atom_false; } ERL_VALGRIND_MAKE_MEM_DEFINED(data, bytes); return ret; }
static ERL_NIF_TERM make_new_resource(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { NifModPrivData* data = priv_data(env); ErlNifBinary ibin; char* a; ERL_NIF_TERM ret; unsigned ix; if (!enif_get_uint(env, argv[0], &ix) || ix >= RT_MAX || !enif_inspect_binary(env, argv[1], &ibin)) { return enif_make_badarg(env); } a = (char*) enif_alloc_resource(data->rt_arr[ix], ibin.size); memcpy(a, ibin.data, ibin.size); ret = enif_make_resource(env, a); enif_release_resource(a); return ret; }
int enif_get_ulong(ErlNifEnv* env, Eterm term, unsigned long* ip) { #if SIZEOF_LONG == ERTS_SIZEOF_ETERM return term_to_Uint(term, ip); #elif SIZEOF_LONG == 8 return term_to_Uint64(term, ip); #elif SIZEOF_LONG == SIZEOF_INT int ret; unsigned int tmp; ret = enif_get_uint(env,term,&tmp); if (ret) { *ip = (unsigned long) tmp; } return ret; #else # error Unknown long word size #endif }
static ERL_NIF_TERM set_permissions_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { posix_errno_t posix_errno; efile_path_t path; Uint32 permissions; if(argc != 2 || !enif_get_uint(env, argv[1], &permissions)) { return enif_make_badarg(env); } if((posix_errno = efile_marshal_path(env, argv[0], &path))) { return posix_error_to_tuple(env, posix_errno); } else if((posix_errno = efile_set_permissions(&path, permissions))) { return posix_error_to_tuple(env, posix_errno); } return am_ok; }