ERL_NIF_TERM _hh_same(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int64_t a = 0; int64_t b = 0; hh_ctx_t* ctx = NULL; ErlNifResourceType* ctx_type = get_hh_ctx_type(env); if (argc != 3 || ctx_type == NULL || !enif_get_resource(env, argv[0], ctx_type, (void **)&ctx) || ctx->data == NULL || !enif_get_int64(env, argv[1], &a) || !enif_get_int64(env, argv[2], &b)) { return enif_make_badarg(env); } if (ctx != NULL) { return hdr_values_are_equivalent(ctx->data,a,b) ? ATOM_TRUE : ATOM_FALSE; } return make_error(env, "bad_hdr_histogram_nif_impl"); }
ERL_NIF_TERM _hh_record_many(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { long value = 0; long count = 0; hh_ctx_t* ctx = NULL; ErlNifResourceType* ctx_type = get_hh_ctx_type(env); if(argc != 3 || !enif_get_resource(env, argv[0], ctx_type, (void **)&ctx) || !enif_get_int64(env, argv[1], &value) || !enif_get_int64(env, argv[2], &count)) { return enif_make_badarg(env); } if ( value < 0 || value > ctx->data->highest_trackable_value) { return make_error(env, "value_out_of_range"); } if (ctx != NULL) { hdr_record_values(ctx->data, value, count); } return ATOM_OK; }
ERL_NIF_TERM _hh_record_corrected(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int64_t value = 0; int64_t expected_interval = 0; hh_ctx_t* ctx = NULL; ErlNifResourceType* ctx_type = get_hh_ctx_type(env); if(argc != 3 || !enif_get_resource(env, argv[0], ctx_type, (void **)&ctx) || ctx->data == NULL || !enif_get_int64(env, argv[1], &value) || !enif_get_int64(env, argv[2], &expected_interval)) { return enif_make_badarg(env); } if (value < 0 || value > ctx->highest_trackable_value) { return make_error(env, "value_out_of_range"); } if (ctx != NULL && ctx->data != NULL) { hdr_record_corrected_value(ctx->data, value, expected_interval); } return ATOM_OK; }
static ERL_NIF_TERM divide(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary bin; ERL_NIF_TERM r; ErlNifSInt64* vs; ErlNifSInt64 m; ErlNifSInt64* target; int count; if (argc != 2) return enif_make_badarg(env); GET_BIN(0, bin, count, vs); if (!enif_get_int64(env, argv[1], &m)) return enif_make_badarg(env); if (!m) return enif_make_badarg(env); if (! (target = (ErlNifSInt64*) enif_make_new_binary(env, bin.size, &r))) return enif_make_badarg(env); // TODO return propper error for (int i = 0; i < count; i++) { if (IS_SET(vs[i])) { target[i] = TO_DDB(FROM_DDB(vs[i]) / m); } else { target[i] = 0; } } return r; }
static ERL_NIF_TERM multiply_with_scalar(ErlNifEnv *env, int argc, const ERL_NIF_TERM *argv) { ErlNifBinary matrix; ERL_NIF_TERM result; double large_scalar; float scalar; float *matrix_data, *result_data; int32_t data_size; size_t result_size; (void)(argc); if (!enif_inspect_binary(env, argv[0], &matrix)) return enif_make_badarg(env); if (enif_get_double(env, argv[1], &large_scalar) == 0) { long long_element; enif_get_int64(env, argv[1], &long_element); large_scalar = (double) long_element; } scalar = (float) large_scalar; matrix_data = (float *) matrix.data; data_size = (int32_t) (matrix_data[0] * matrix_data[1] + 2); result_size = sizeof(float) * data_size; result_data = (float *) enif_make_new_binary(env, result_size, &result); matrix_multiply_with_scalar(matrix_data, scalar, result_data); return result; }
static ERL_NIF_TERM mul_r(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary bin; ERL_NIF_TERM r; ErlNifSInt64* vs; ErlNifSInt64 m; ErlNifSInt64* target; int count; if (argc != 2) return enif_make_badarg(env); GET_BIN(0, bin, count, vs); if (!enif_get_int64(env, argv[1], &m)) return enif_make_badarg(env); if (! (target = (ErlNifSInt64*) enif_make_new_binary(env, bin.size, &r))) return enif_make_badarg(env); // TODO return propper error for (int i = 0; i < count; i++) { target[i] = vs[i] * m; } return r; }
static ERL_NIF_TERM seek_nif_impl(efile_data_t *d, ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { Sint64 new_position, offset; enum efile_seek_t seek; ASSERT(argc == 2); if(!enif_get_int64(env, argv[1], &offset)) { return enif_make_badarg(env); } if(enif_is_identical(argv[0], am_bof)) { seek = EFILE_SEEK_BOF; } else if(enif_is_identical(argv[0], am_cur)) { seek = EFILE_SEEK_CUR; } else if(enif_is_identical(argv[0], am_eof)) { seek = EFILE_SEEK_EOF; } else { return enif_make_badarg(env); } if(!efile_seek(d, seek, offset, &new_position)) { return posix_error_to_tuple(env, d->posix_errno); } return enif_make_tuple2(env, am_ok, enif_make_uint64(env, new_position)); }
static ERL_NIF_TERM pwrite_nif_impl(efile_data_t *d, ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { ErlNifIOVec vec, *input = &vec; Sint64 bytes_written, offset; ERL_NIF_TERM tail; if(argc != 2 || !enif_is_number(env, argv[0]) || !enif_inspect_iovec(env, 64, argv[1], &tail, &input)) { return enif_make_badarg(env); } if(!enif_get_int64(env, argv[0], &offset) || offset < 0) { return posix_error_to_tuple(env, EINVAL); } bytes_written = efile_pwritev(d, offset, input->iov, input->iovcnt); if(bytes_written < 0) { return posix_error_to_tuple(env, d->posix_errno); } if(!enif_is_empty_list(env, tail)) { ASSERT(bytes_written > 0); return enif_make_tuple3(env, am_continue, enif_make_int64(env, bytes_written), tail); } return am_ok; }
ERL_NIF_TERM _hh_lowest_at(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int64_t value = 0; hh_ctx_t* ctx = NULL; ErlNifResourceType* ctx_type = get_hh_ctx_type(env); if (argc != 2 || ctx_type == NULL || !enif_get_resource(env, argv[0], ctx_type, (void **)&ctx) || ctx->data == NULL || !enif_get_int64(env, argv[1], &value)) { return enif_make_badarg(env); } if (ctx != NULL) { return enif_make_int64( env, hdr_lowest_equivalent_value(ctx->data, value) ); } return make_error(env, "bad_hdr_histogram_nif_impl"); }
static ERL_NIF_TERM allocate_nif_impl(efile_data_t *d, ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { Sint64 offset, length; if(argc != 2 || !enif_is_number(env, argv[0]) || !enif_is_number(env, argv[1])) { return enif_make_badarg(env); } if(!enif_get_int64(env, argv[0], &offset) || !enif_get_int64(env, argv[1], &length) || (offset < 0 || length < 0)) { return posix_error_to_tuple(env, EINVAL); } if(!efile_allocate(d, offset, length)) { return posix_error_to_tuple(env, d->posix_errno); } return am_ok; }
static ERL_NIF_TERM set_time_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { posix_errno_t posix_errno; Sint64 accessed, modified, created; efile_path_t path; if(argc != 4 || !enif_get_int64(env, argv[1], &accessed) || !enif_get_int64(env, argv[2], &modified) || !enif_get_int64(env, argv[3], &created)) { 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_time(&path, accessed, modified, created))) { return posix_error_to_tuple(env, posix_errno); } return am_ok; }
static int test_int64(ErlNifEnv* env, ErlNifSInt64 i1) { ErlNifSInt64 i2 = 0; ERL_NIF_TERM int_term = enif_make_int64(env, i1); if (!enif_get_int64(env,int_term, &i2) || i1 != i2) { fprintf(stderr, "test_int64(%ld) ...FAILED i2=%ld\r\n", (long)i1, (long)i2); return 0; } return 1; }
static int bind_cell(ErlNifEnv *env, const ERL_NIF_TERM cell, sqlite3_stmt *stmt, unsigned int i) { int the_int; ErlNifSInt64 the_long_int; double the_double; char the_atom[MAX_ATOM_LENGTH+1]; ErlNifBinary the_blob; int arity; const ERL_NIF_TERM* tuple; if(enif_get_int(env, cell, &the_int)) return sqlite3_bind_int(stmt, i, the_int); if(enif_get_int64(env, cell, &the_long_int)) return sqlite3_bind_int64(stmt, i, the_long_int); if(enif_get_double(env, cell, &the_double)) return sqlite3_bind_double(stmt, i, the_double); if(enif_get_atom(env, cell, the_atom, sizeof(the_atom), ERL_NIF_LATIN1)) { if(strcmp("undefined", the_atom) == 0) { return sqlite3_bind_null(stmt, i); } return sqlite3_bind_text(stmt, i, the_atom, strlen(the_atom), SQLITE_TRANSIENT); } /* Bind as text assume it is utf-8 encoded text */ if(enif_inspect_iolist_as_binary(env, cell, &the_blob)) return sqlite3_bind_text(stmt, i, (char *) the_blob.data, the_blob.size, SQLITE_TRANSIENT); /* Check for blob tuple */ if(enif_get_tuple(env, cell, &arity, &tuple)) { if(arity != 2) return -1; /* length 2! */ if(enif_get_atom(env, tuple[0], the_atom, sizeof(the_atom), ERL_NIF_LATIN1)) { /* its a blob... */ if(0 == strncmp("blob", the_atom, strlen("blob"))) { /* with a iolist as argument */ if(enif_inspect_iolist_as_binary(env, tuple[1], &the_blob)) { /* kaboom... get the blob */ return sqlite3_bind_blob(stmt, i, the_blob.data, the_blob.size, SQLITE_TRANSIENT); } } } } return -1; }
static ERL_NIF_TERM pread_nif_impl(efile_data_t *d, ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { Sint64 bytes_read, block_size, offset; SysIOVec read_vec[1]; ErlNifBinary result; ASSERT(argc == 2); if(!enif_is_number(env, argv[0]) || !enif_is_number(env, argv[1])) { return enif_make_badarg(env); } if(!enif_get_int64(env, argv[0], &offset) || !enif_get_int64(env, argv[1], &block_size) || (offset < 0 || block_size < 0)) { return posix_error_to_tuple(env, EINVAL); } if(!enif_alloc_binary(block_size, &result)) { return posix_error_to_tuple(env, ENOMEM); } read_vec[0].iov_base = result.data; read_vec[0].iov_len = result.size; bytes_read = efile_preadv(d, offset, read_vec, 1); if(bytes_read < 0) { enif_release_binary(&result); return posix_error_to_tuple(env, d->posix_errno); } else if(bytes_read == 0) { enif_release_binary(&result); return am_eof; } if(bytes_read < block_size && !enif_realloc_binary(&result, bytes_read)) { ERTS_INTERNAL_ERROR("Failed to shrink pread result."); } return enif_make_tuple2(env, am_ok, enif_make_binary(env, &result)); }
static ERL_NIF_TERM advise_nif_impl(efile_data_t *d, ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { enum efile_advise_t advise; Sint64 offset, length; if(argc != 3 || !enif_is_number(env, argv[0]) || !enif_is_number(env, argv[1])) { return enif_make_badarg(env); } if(!enif_get_int64(env, argv[0], &offset) || !enif_get_int64(env, argv[1], &length) || (offset < 0 || length < 0)) { return posix_error_to_tuple(env, EINVAL); } if(enif_is_identical(argv[2], am_normal)) { advise = EFILE_ADVISE_NORMAL; } else if(enif_is_identical(argv[2], am_random)) { advise = EFILE_ADVISE_RANDOM; } else if(enif_is_identical(argv[2], am_sequential)) { advise = EFILE_ADVISE_SEQUENTIAL; } else if(enif_is_identical(argv[2], am_will_need)) { advise = EFILE_ADVISE_WILL_NEED; } else if(enif_is_identical(argv[2], am_dont_need)) { advise = EFILE_ADVISE_DONT_NEED; } else if(enif_is_identical(argv[2], am_no_reuse)) { advise = EFILE_ADVISE_NO_REUSE; } else { /* The tests check for EINVAL instead of badarg. Sigh. */ return posix_error_to_tuple(env, EINVAL); } if(!efile_advise(d, offset, length, advise)) { return posix_error_to_tuple(env, d->posix_errno); } return am_ok; }
/** * Erlang Wrapper for geonum_precision */ ERL_NIF_TERM erl_geonum_precision(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int precision[1]; long long geonum; if(!enif_get_int64(env, argv[0], &geonum)) { return enif_make_badarg(env); } geonum_precision(geonum, precision); return make_ok(env, enif_make_int(env, precision[0])); }
/** * Erlang Wrapper for geonum_neighbor */ ERL_NIF_TERM erl_geonum_neighbor(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { long long bin_neighbor[1]; long long geonum; char dir[2]; int dir_val; unsigned int dir_len; if(!enif_get_int64(env, argv[0], &geonum)) { return enif_make_badarg(env); } if(!enif_get_atom_length(env, argv[1], &dir_len, ERL_NIF_LATIN1)) { return enif_make_badarg(env); } if(dir_len > sizeof(dir)) { return enif_make_badarg(env); } if(!enif_get_atom(env, argv[1], dir, sizeof(dir), ERL_NIF_LATIN1)) { return enif_make_badarg(env); } switch (dir[0]) { case 'w': dir_val = 0; break; case 'e': dir_val = 1; break; case 'n': dir_val = 2; break; case 's': dir_val = 3; break; default: return enif_make_badarg(env); } geonum_neighbor(geonum, dir_val, bin_neighbor); return make_ok(env, enif_make_int64(env, bin_neighbor[0])); }
ERL_NIF_TERM update_counter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { mzc_ctx_t* ctx = NULL; int64_t value; ErlNifResourceType* ctx_type = get_mzc_ctx_type(env); if (argc != 2 || !enif_get_resource(env, argv[0], ctx_type, (void **)&ctx) || !enif_get_int64(env, argv[1], (ErlNifSInt64*)&value)) { return enif_make_badarg(env); } atomic_add(&ctx->value, value); return ATOM_OK; }
static inline int match_int64(ErlNifEnv* env, ERL_NIF_TERM term, State *st){ ErlNifSInt64 ip; int n; if(!enif_get_int64(env, term, &ip)) return 0; b_reserve(24, st); #if (defined(__WIN32__) || defined(_WIN32) || defined(_WIN32_)) n = sprintf((char*)st->cur, "%ld", ip); #elif SIZEOF_LONG == 8 n = sprintf((char*)st->cur, "%ld", ip); #else n = sprintf((char*)st->cur, "%lld", ip); #endif b_seek(n, st); return 1; }
/** * Erlang Wrapper for geonum_decode */ ERL_NIF_TERM erl_geonum_decode(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { double point[2]; long long geonum; if(!enif_get_int64(env, argv[0], &geonum)) { return enif_make_badarg(env); } geonum_decode(geonum, point); ERL_NIF_TERM point_tuple = enif_make_tuple2(env, enif_make_double(env, point[0]), enif_make_double(env, point[1])); return make_ok(env, point_tuple); }
/*-----------------------------------------------------------------------------------------------------------------------*/ static ERL_NIF_TERM set_double_field(ErlNifEnv* env, int32_t argc, ERL_NIF_TERM const argv[]) { ERL_NIF_TERM parser_res; ERL_NIF_TERM msg_res; ERL_NIF_TERM group_res; ParserRes* parser = NULL; FIXMsg* msg = NULL; FIXGroup* group = NULL; ERL_NIF_TERM res = get_parser_msg_group(env, argv[0], &parser_res, &msg_res, &group_res, &parser, &msg, &group); if (res != ok_atom) { return res; } int32_t tagNum = 0; if (!enif_get_int(env, argv[1], &tagNum)) { return make_error(env, FIX_FAILED, "Wrong tag num."); } if (!enif_is_number(env, argv[2])) { return make_error(env, FIX_FAILED, "Value is not a double."); } double val = 0.0; if (!enif_get_double(env, argv[2], &val)) { int64_t lval = 0; enif_get_int64(env, argv[2], &lval); val = lval; } ERL_NIF_TERM ret = ok_atom; FIXError* error = NULL; pthread_rwlock_wrlock(&parser->lock); FIXErrCode err = fix_msg_set_double(msg, group, tagNum, val, &error); pthread_rwlock_unlock(&parser->lock); if (err == FIX_FAILED) { ret = make_parser_error(env, fix_error_get_code(error), fix_error_get_text(error)); fix_error_free(error); } return ret; }
/** * Erlang Wrapper for geonum_decode_bbox */ ERL_NIF_TERM erl_geonum_decode_bbox(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { double tl[2], br[2]; long long geonum; if(!enif_get_int64(env, argv[0], &geonum)) { return enif_make_badarg(env); } geonum_decode_bbox(geonum, tl, br); ERL_NIF_TERM top_left = enif_make_tuple2(env, enif_make_double(env, tl[0]), enif_make_double(env, tl[1])); ERL_NIF_TERM bottom_right = enif_make_tuple2(env, enif_make_double(env, br[0]), enif_make_double(env, br[1])); ERL_NIF_TERM bbox = enif_make_tuple2(env, top_left, bottom_right); return make_ok(env, bbox); }
ERL_NIF_TERM _hh_open(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { long highest_trackable_value = 0; int significant_figures = 0; if (argc != 2 || !enif_get_int64(env, argv[0], &highest_trackable_value) || !enif_get_int(env, argv[1], &significant_figures)) { return enif_make_badarg(env); } hdr_histogram_t* raw_histogram; int rc = 0; rc = hdr_alloc(highest_trackable_value, significant_figures, &raw_histogram); if (EINVAL == rc) { return make_error(env, "bad_significant_factor"); } if (ENOMEM == rc) { return make_error(env, "not_enough_memory"); } ErlNifResourceType* ctx_type = get_hh_ctx_type(env); hh_ctx_t* ctx = (hh_ctx_t*)enif_alloc_resource(ctx_type, sizeof(hh_ctx_t)); ctx->data = raw_histogram; ctx->highest_trackable_value = highest_trackable_value; ctx->significant_figures = significant_figures; ERL_NIF_TERM result = enif_make_resource(env, ctx); enif_release_resource(ctx); return enif_make_tuple2(env, ATOM_OK, result); }
/** * Erlang Wrapper for binary geonum_neighbor */ ERL_NIF_TERM erl_geonum_all_neighbors(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { long long neighbors[8]; long long geonum; if(!enif_get_int64(env, argv[0], &geonum)) { return enif_make_badarg(env); } geonum_all_neighbors(geonum, neighbors); return make_ok(env, enif_make_list8(env, enif_make_int64(env, neighbors[0]), enif_make_int64(env, neighbors[1]), enif_make_int64(env, neighbors[2]), enif_make_int64(env, neighbors[3]), enif_make_int64(env, neighbors[4]), enif_make_int64(env, neighbors[5]), enif_make_int64(env, neighbors[6]), enif_make_int64(env, neighbors[7]) )); }
static ERL_NIF_TERM create_batch_data(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) { BatchData *batch_data; WorkerData *worker_data; ERL_NIF_TERM result; int64_t batch_length; (void)(argc); if (!enif_get_resource(env, argv[0], WORKER_DATA, (void **)(&worker_data))) return enif_make_badarg(env); if (!enif_get_int64(env, argv[1], &batch_length)) return enif_make_badarg(env); batch_data = enif_alloc_resource(BATCH_DATA, sizeof(BatchData)); batch_data_initialize(batch_data, worker_data, batch_length); shuffle_batch_data_indices(batch_data); result = enif_make_resource(env, batch_data); enif_release_resource(&batch_data); return result; }
void* cb_arithmetic_args(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { arithmetic_args_t* args = (arithmetic_args_t*)enif_alloc(sizeof(arithmetic_args_t)); ErlNifBinary key_binary; if (!enif_inspect_iolist_as_binary(env, argv[0], &key_binary)) goto error0; args->key = malloc(sizeof(char) * key_binary.size); memcpy(args->key, key_binary.data, key_binary.size); args->nkey = key_binary.size; if (!enif_get_int64(env, argv[1], (ErlNifSInt64*)&args->delta)) goto error1; if (!enif_get_uint64(env, argv[2], (ErlNifUInt64 *)&args->exp)) goto error1; if (!enif_get_int(env, argv[3], &args->create)) goto error1; if (!enif_get_uint64(env, argv[4], (ErlNifUInt64 *)&args->initial)) goto error1; return (void*)args; error1: free(args->key); error0: enif_free(args); return NULL; }
/* This undocumented function reads a pointer and then reads the data block * described by said pointer. It was reverse-engineered from the old * implementation so while all tests pass it may not be entirely correct. Our * current understanding is as follows: * * Pointer layout: * * <<Size:1/integer-unit:32, Offset:1/integer-unit:32>> * * Where Offset is the -absolute- address to the data block. * * *) If we fail to read the pointer block in its entirety, we return eof. * *) If the provided max_payload_size is larger than Size, we return eof. * *) If we fail to read any data whatsoever at Offset, we return * {ok, {Size, Offset, eof}} * *) Otherwise, we return {ok, {Size, Offset, Data}}. Note that the size * of Data may be smaller than Size if we encounter EOF before we could * read the entire block. * * On errors we'll return {error, posix()} regardless of whether they * happened before or after reading the pointer block. */ static ERL_NIF_TERM ipread_s32bu_p32bu_nif_impl(efile_data_t *d, ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { Sint64 payload_offset, payload_size; SysIOVec read_vec[1]; Sint64 bytes_read; ErlNifBinary payload; if(argc != 2 || !enif_is_number(env, argv[0]) || !enif_is_number(env, argv[1])) { return enif_make_badarg(env); } { Sint64 max_payload_size, pointer_offset; unsigned char pointer_block[8]; if(!enif_get_int64(env, argv[0], &pointer_offset) || !enif_get_int64(env, argv[1], &max_payload_size) || (pointer_offset < 0 || max_payload_size >= 1u << 31)) { return posix_error_to_tuple(env, EINVAL); } read_vec[0].iov_base = pointer_block; read_vec[0].iov_len = sizeof(pointer_block); bytes_read = efile_preadv(d, pointer_offset, read_vec, 1); if(bytes_read < 0) { return posix_error_to_tuple(env, d->posix_errno); } else if(bytes_read < sizeof(pointer_block)) { return am_eof; } payload_size = (Uint32)get_int32(&pointer_block[0]); payload_offset = (Uint32)get_int32(&pointer_block[4]); if(payload_size > max_payload_size) { return am_eof; } } if(!enif_alloc_binary(payload_size, &payload)) { return posix_error_to_tuple(env, ENOMEM); } read_vec[0].iov_base = payload.data; read_vec[0].iov_len = payload.size; bytes_read = efile_preadv(d, payload_offset, read_vec, 1); if(bytes_read < 0) { return posix_error_to_tuple(env, d->posix_errno); } else if(bytes_read == 0) { enif_release_binary(&payload); return enif_make_tuple2(env, am_ok, enif_make_tuple3(env, enif_make_uint(env, payload_size), enif_make_uint(env, payload_offset), am_eof)); } if(bytes_read < payload.size && !enif_realloc_binary(&payload, bytes_read)) { ERTS_INTERNAL_ERROR("Failed to shrink ipread payload."); } return enif_make_tuple2(env, am_ok, enif_make_tuple3(env, enif_make_uint(env, payload_size), enif_make_uint(env, payload_offset), enif_make_binary(env, &payload))); }
static void ks_selector_arg(ks_returner_t *ret, ks_pattern_t *pattern, ERL_NIF_TERM arg) { unsigned size; char *string; int result; ErlNifSInt64 integer; if (ret->ready != B_TRUE) { if (enif_is_atom(ret->env, arg)) { enif_get_atom_length(ret->env, arg, &size, ERL_NIF_LATIN1); string = (char *)(malloc(sizeof (char) * (size + 1))); if (string == NULL) { ret->term = EKSTAT_ERROR("atom malloc"); ret->ready = B_TRUE; return; } result = enif_get_atom(ret->env, arg, string, size + 1, ERL_NIF_LATIN1); if (result == 0) { ret->term = enif_make_badarg(ret->env); ret->ready = B_TRUE; } else { if (strncmp(string, "_", result) == 0) { pattern->pstr = "*"; pattern->free = B_FALSE; } else { ret->term = enif_make_badarg(ret->env); ret->ready = B_TRUE; } free(string); } } else if (enif_is_list(ret->env, arg)) { enif_get_list_length(ret->env, arg, &size); string = (char *)(malloc(sizeof (char) * (size + 1))); if (string == NULL) { ret->term = EKSTAT_ERROR("list malloc"); ret->ready = B_TRUE; return; } result = enif_get_string(ret->env, arg, string, size + 1, ERL_NIF_LATIN1); if (result == 0) { ret->term = enif_make_badarg(ret->env); ret->ready = B_TRUE; } else { pattern->pstr = (char *)(ks_safe_strdup(ret, string)); pattern->free = B_TRUE; } free(string); } else if (enif_is_number(ret->env, arg)) { if (enif_get_int64(ret->env, arg, &integer)) { (void) asprintf(&string, "%d", integer); pattern->pstr = (char *)(ks_safe_strdup(ret, string)); pattern->free = B_TRUE; } else { ret->term = enif_make_badarg(ret->env); ret->ready = B_TRUE; } free(string); } else { ret->term = enif_make_badarg(ret->env); ret->ready = B_TRUE; } } }
ERL_NIF_TERM encode(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { Encoder enc; Encoder* e = &enc; ErlNifBinary bin; ERL_NIF_TERM ret; ERL_NIF_TERM stack; ERL_NIF_TERM curr; ERL_NIF_TERM item; const ERL_NIF_TERM* tuple; int arity; ErlNifSInt64 lval; double dval; if(argc != 2) { return enif_make_badarg(env); } if(!enc_init(e, env, argv[1], &bin)) { return enif_make_badarg(env); } stack = enif_make_list(env, 1, argv[0]); while(!enif_is_empty_list(env, stack)) { if(!enif_get_list_cell(env, stack, &curr, &stack)) { ret = enc_error(e, "internal_error"); goto done; } if(enif_is_identical(curr, e->atoms->ref_object)) { if(!enif_get_list_cell(env, stack, &curr, &stack)) { ret = enc_error(e, "internal_error"); goto done; } if(enif_is_empty_list(env, curr)) { if(!enc_end_object(e)) { ret = enc_error(e, "internal_error"); goto done; } continue; } if(!enif_get_list_cell(env, curr, &item, &curr)) { ret = enc_error(e, "internal_error"); goto done; } if(!enif_get_tuple(env, item, &arity, &tuple)) { ret = enc_error(e, "invalid_object_pair"); goto done; } if(arity != 2) { ret = enc_error(e, "invalid_object_pair"); goto done; } if(!enc_comma(e)) { ret = enc_error(e, "internal_error"); goto done; } if(!enc_string(e, tuple[0])) { ret = enc_error(e, "invalid_object_key"); goto done; } if(!enc_colon(e)) { ret = enc_error(e, "internal_error"); goto done; } stack = enif_make_list_cell(env, curr, stack); stack = enif_make_list_cell(env, e->atoms->ref_object, stack); stack = enif_make_list_cell(env, tuple[1], stack); } else if(enif_is_identical(curr, e->atoms->ref_array)) { if(!enif_get_list_cell(env, stack, &curr, &stack)) { ret = enc_error(e, "internal_error"); goto done; } if(enif_is_empty_list(env, curr)) { if(!enc_end_array(e)) { ret = enc_error(e, "internal_error"); goto done; } continue; } if(!enc_comma(e)) { ret = enc_error(e, "internal_error"); goto done; } if(!enif_get_list_cell(env, curr, &item, &curr)) { ret = enc_error(e, "internal_error"); goto done; } stack = enif_make_list_cell(env, curr, stack); stack = enif_make_list_cell(env, e->atoms->ref_array, stack); stack = enif_make_list_cell(env, item, stack); } else if(enif_compare(curr, e->atoms->atom_null) == 0) { if(!enc_literal(e, "null", 4)) { ret = enc_error(e, "null"); goto done; } } else if(enif_compare(curr, e->atoms->atom_true) == 0) { if(!enc_literal(e, "true", 4)) { ret = enc_error(e, "true"); goto done; } } else if(enif_compare(curr, e->atoms->atom_false) == 0) { if(!enc_literal(e, "false", 5)) { ret = enc_error(e, "false"); goto done; } } else if(enif_is_binary(env, curr)) { if(!enc_string(e, curr)) { ret = enc_error(e, "invalid_string"); goto done; } } else if(enif_is_atom(env, curr)) { if(!enc_string(e, curr)) { ret = enc_error(e, "invalid_string"); goto done; } } else if(enif_get_int64(env, curr, &lval)) { if(!enc_long(e, lval)) { ret = enc_error(e, "internal_error"); goto done; } } else if(enif_get_double(env, curr, &dval)) { if(!enc_double(e, dval)) { ret = enc_error(e, "internal_error"); goto done; } } else if(enif_get_tuple(env, curr, &arity, &tuple)) { if(arity != 1) { ret = enc_error(e, "invalid_ejson"); goto done; } if(!enif_is_list(env, tuple[0])) { ret = enc_error(e, "invalid_object"); goto done; } if(!enc_start_object(e)) { ret = enc_error(e, "internal_error"); goto done; } if(enif_is_empty_list(env, tuple[0])) { if(!enc_end_object(e)) { ret = enc_error(e, "internal_error"); goto done; } continue; } if(!enif_get_list_cell(env, tuple[0], &item, &curr)) { ret = enc_error(e, "internal_error"); goto done; } if(!enif_get_tuple(env, item, &arity, &tuple)) { ret = enc_error(e, "invalid_object_member"); goto done; } if(arity != 2) { ret = enc_error(e, "invalid_object_member_arity"); goto done; } if(!enc_string(e, tuple[0])) { ret = enc_error(e, "invalid_object_member_key"); goto done; } if(!enc_colon(e)) { ret = enc_error(e, "internal_error"); goto done; } stack = enif_make_list_cell(env, curr, stack); stack = enif_make_list_cell(env, e->atoms->ref_object, stack); stack = enif_make_list_cell(env, tuple[1], stack); } else if(enif_is_list(env, curr)) { if(!enc_start_array(e)) { ret = enc_error(e, "internal_error"); goto done; } if(enif_is_empty_list(env, curr)) { if(!enc_end_array(e)) { ret = enc_error(e, "internal_error"); goto done; } continue; } if(!enif_get_list_cell(env, curr, &item, &curr)) { ret = enc_error(e, "internal_error"); goto done; } stack = enif_make_list_cell(env, curr, stack); stack = enif_make_list_cell(env, e->atoms->ref_array, stack); stack = enif_make_list_cell(env, item, stack); } else { if(!enc_unknown(e, curr)) { ret = enc_error(e, "internal_error"); goto done; } } } if(!enc_done(e, &item)) { ret = enc_error(e, "internal_error"); goto done; } if(e->iolen == 0) { ret = item; } else { ret = enif_make_tuple2(env, e->atoms->atom_partial, item); } done: enc_destroy(e); return ret; }
static mrb_value erl2mruby(ErlNifEnv* env, mrb_state* mrb, ERL_NIF_TERM term) { if (enif_is_atom(env, term)) { unsigned len; enif_get_atom_length(env, term, &len, ERL_NIF_LATIN1); char * atom_str = (char *)malloc(sizeof(char)*(len+1)); int r = enif_get_atom(env, term, atom_str, len+1, ERL_NIF_LATIN1); mrb_value value; if(strncmp(atom_str, "nil", r) == 0){ value = mrb_nil_value(); }else if(strncmp(atom_str, "true", r) == 0){ value = mrb_true_value(); }else if(strncmp(atom_str, "false", r) == 0){ value = mrb_false_value(); }else{ value = mrb_symbol_value(mrb_intern_cstr(mrb, atom_str)); } free(atom_str); return value; } else if (enif_is_binary(env, term)) { ErlNifBinary bin; enif_inspect_binary(env, term, &bin); return mrb_str_new(mrb, (const char *)bin.data, bin.size); } else if (enif_is_number(env, term)) { double d; if (enif_get_double(env, term, &d)) { return mrb_float_value(mrb, (mrb_float)d); } else { ErlNifSInt64 i; enif_get_int64(env, term, &i); return mrb_fixnum_value((mrb_int)i); } } else if (enif_is_empty_list(env, term)) { return mrb_ary_new(mrb); } else if (enif_is_list(env, term)) { unsigned len; enif_get_list_length(env, term, &len); mrb_value ary = mrb_ary_new(mrb); ERL_NIF_TERM cur; for (cur = term; !enif_is_empty_list(env, cur); ) { ERL_NIF_TERM head, tail; enif_get_list_cell(env, cur, &head, &tail); mrb_ary_push(mrb, ary, erl2mruby(env, mrb, head)); cur = tail; } return ary; } else if (enif_is_tuple(env, term)) { int arity; const ERL_NIF_TERM * array; enif_get_tuple(env, term, &arity, &array); unsigned len = 0; enif_get_list_length(env, array[0], &len); mrb_value hash = mrb_hash_new(mrb); ERL_NIF_TERM cur; for(cur = array[0]; !enif_is_empty_list(env, cur); ){ ERL_NIF_TERM head, tail; enif_get_list_cell(env, cur, &head, &tail); const ERL_NIF_TERM * array0; int arity0; enif_get_tuple(env, head, &arity0, &array0); mrb_hash_set(mrb, hash, erl2mruby(env, mrb, array0[0]), erl2mruby(env, mrb, array0[1])); cur = tail; } return hash; } else { return mrb_nil_value(); } }