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;
}
Exemple #4
0
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;
}
Exemple #5
0
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;
}
Exemple #6
0
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;
}
Exemple #7
0
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));
}
Exemple #8
0
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");
}
Exemple #10
0
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;
}
Exemple #11
0
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;
}
Exemple #12
0
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;
}
Exemple #13
0
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;
}
Exemple #14
0
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));
}
Exemple #15
0
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;
}
Exemple #16
0
/**
 * 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]));
}
Exemple #17
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]));
}
Exemple #18
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;
}
Exemple #19
0
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;  
}
Exemple #20
0
/**
 * 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);
}
Exemple #21
0
/*-----------------------------------------------------------------------------------------------------------------------*/
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;
}
Exemple #22
0
/**
 * 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);
}
Exemple #24
0
/**
 * 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])
    ));
}
Exemple #25
0
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;
}
Exemple #26
0
Fichier : cb.c Projet : muut/cberl
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;
}
Exemple #27
0
/* 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)));
}
Exemple #28
0
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;
		}
	}
}
Exemple #29
0
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;
}
Exemple #30
0
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();
  }
}