Exemple #1
0
static int prefix_cb(void *data, const unsigned char *k, uint32_t k_len, void *val) 
{
    callback_data *cb_data = data;
    art_elem_struct *elem = val;
    ErlNifBinary key, value;

    enif_alloc_binary(k_len - 1, &key);
    memcpy(key.data, k, k_len - 1);

    enif_alloc_binary(elem->size, &value);
    memcpy(value.data, elem->data, elem->size);

    ErlNifEnv *msg_env = enif_alloc_env();

    if(msg_env == NULL)
        return mk_error(cb_data->env, "env_alloc_error");;

    ERL_NIF_TERM caller_ref = enif_make_copy(msg_env, cb_data->caller_ref);

    ERL_NIF_TERM res = enif_make_tuple2(msg_env, 
        caller_ref,
        enif_make_tuple2(msg_env, 
            enif_make_binary(msg_env, &key), enif_make_binary(msg_env, &value)));
    
    if(!enif_send(cb_data->env, &cb_data->pid, msg_env, res))
    {
        enif_free(msg_env);

        return -1;
    }

    enif_free(msg_env);    

    return 0;
}
Exemple #2
0
void secfile_t::read_newline()
{
	if(*get_next_line()) {
		throw mk_error("Expected newline");
	}
	++line;
}
Exemple #3
0
static ERL_NIF_TERM elibart_prefix_search(ErlNifEnv* env, int argc,
                                          const ERL_NIF_TERM argv[])
{
    art_tree* t;
    ErlNifBinary key;
    callback_data cb_data;

    // extract arguments atr_tree, key
    if (argc != 4)
        return enif_make_badarg(env);
    if(!enif_get_resource(env, argv[0], elibart_RESOURCE, (void**) &t))
        return enif_make_badarg(env);
    if (!enif_inspect_binary(env, argv[1], &key))
        return enif_make_badarg(env);

    cb_data.env = env;
    if(!enif_is_pid(env, argv[3]))
        return mk_error(env, "not_a_pid");

    if(!enif_get_local_pid(env, argv[3], &cb_data.pid))
        return mk_error(env, "not_a_local_pid");

    cb_data.caller_ref = argv[2];
   
    // TODO this should be a worker thread since it's a long opearation (?)
    if (art_iter_prefix(t, key.data, key.size, prefix_cb, &cb_data))
        return mk_error(env, "art_prefix_search");

    ErlNifEnv *msg_env = enif_alloc_env();

    if(msg_env == NULL)
        return mk_error(env, "env_alloc_error");;

    ERL_NIF_TERM caller_ref = enif_make_copy(msg_env, argv[2]);
    ERL_NIF_TERM res = enif_make_tuple2(msg_env, caller_ref, mk_atom(msg_env, "ok"));

    if (!enif_send(env, &cb_data.pid, msg_env, res))
    {
        enif_free(msg_env);

        return mk_error(env, "art_prefix_search");
    }

    enif_free(msg_env);

    return mk_atom(env, "ok");
}
Exemple #4
0
static ERL_NIF_TERM elibart_insert(ErlNifEnv* env, int argc,
                                          const ERL_NIF_TERM argv[])
{
    art_tree* t;
    ErlNifBinary key, value;
    art_elem_struct *elem;
    unsigned char buffer[BUFF_SIZE]; // 256Kb buffer
    unsigned char *key_copy = buffer;


    // extract arguments atr_tree, key, value
    if (argc != 3)
        return enif_make_badarg(env);
    if(!enif_get_resource(env, argv[0], elibart_RESOURCE, (void**) &t))
        return enif_make_badarg(env);
    if (!enif_inspect_binary(env, argv[1], &key))
        return enif_make_badarg(env);
    if (!enif_inspect_binary(env, argv[2], &value))
        return enif_make_badarg(env);

    // buffer size not enough, pay the price
    if (key.size > BUFF_SIZE)
        key_copy = malloc(key.size + 1);

    // TODO review -- is it possible not to copy the key just to add '\0'?
    memcpy(key_copy, key.data, key.size);
    key_copy[key.size] = '\0';

    //create art element
    elem = malloc(sizeof(art_elem_struct));

    if (elem == NULL)
        mk_error(env, "malloc_no_mem");

    elem->data = malloc(value.size);
    elem->size = value.size;
    memcpy(elem->data, value.data, value.size);

    // insert the element in the art_tree
    art_elem_struct *old_elem = art_insert(t, key_copy, key.size + 1, elem);

    // buffer size not enough, pay the price
    if (key.size > BUFF_SIZE)
        free(key_copy);

    // the inserted key is new
    if (!old_elem) 
        return enif_make_tuple2(env, mk_atom(env, "ok"), mk_atom(env, "empty"));

    // the inserted key already existed, return previous value
    ErlNifBinary res;
    enif_alloc_binary(old_elem->size, &res);
    memcpy(res.data, old_elem->data, old_elem->size);

    free(old_elem->data);
    free(old_elem);

    return enif_make_tuple2(env, enif_make_atom(env, "ok"), enif_make_binary(env, &res));
}
Exemple #5
0
static ERL_NIF_TERM elibart_new(ErlNifEnv* env, int argc,
                                   const ERL_NIF_TERM argv[])
{
    art_tree* t = enif_alloc_resource(elibart_RESOURCE,
                                                    sizeof(art_tree));
    
    if (init_art_tree(t) != 0)
        return mk_error(env, "init_art_tree");
    else 
    {
        ERL_NIF_TERM res = enif_make_resource(env, t);
        enif_release_resource(t);
    
        return enif_make_tuple2(env, mk_atom(env, "ok"), res);
    }
}
Exemple #6
0
static ERL_NIF_TERM elibart_destroy(ErlNifEnv* env, int argc,
                                   const ERL_NIF_TERM argv[])
{
    art_tree *t;

    if (argc != 1)
        return enif_make_badarg(env);
    if(!enif_get_resource(env, argv[0], elibart_RESOURCE, (void**) &t))
        return enif_make_badarg(env);

    art_iter(t, delete_cb, NULL);

    if (destroy_art_tree((art_tree*) argv[0]) != 0)
        return mk_error(env, "destroy_art_tree");

    return mk_atom(env, "ok");
}
Exemple #7
0
static ERL_NIF_TERM delta_init(ErlNifEnv* env, int argc,
			       const ERL_NIF_TERM argv[])
{
  state_t *state = NULL;
  rs_result res;
  
  if (!enif_get_resource(env, argv[0], state_r, (void *) &state))
    return enif_make_badarg(env);

  if (state->type != LOADSIG)
    return enif_make_badarg(env);
  
  res = rs_build_hash_table(state->sig);
  if (res != RS_DONE)
    return mk_error(env, res);
  if (state->job) rs_job_free(state->job);
  state->job = rs_delta_begin(state->sig);
  state->in_size = 0;
  state->out_size = 0;
  state->type = DELTA;
  return enif_make_atom(env, "ok");
}
Exemple #8
0
sexpr_t* eval(sexpr_t* sexpr, sexpr_t** env, sexpr_list_t* roots, error_t** error)
{
    if(sexpr == NULL) {
        return interp.nil_sym;
    }

    /* printf("[eval]\n"); */
    /* print_sexpr(sexpr); */
    /* printf("\n"); */
    roots = cons_to_roots_list(roots, sexpr);
    gc_collect(roots);
    
    if(ATOM(sexpr)) {
        if(SYM(sexpr)) {
            if(interp.t_sym == sexpr) {
                return interp.t_sym;
            }
            if(interp.nil_sym == sexpr) {
                return interp.nil_sym;
            }
            sexpr_t* val = assoc(sexpr, *env);
            if(val == NULL) {
                *error = mk_error("Undefined symbol", SYM_VAL(sexpr));
            }

            return val;
        }
        if(INT(sexpr)) {
            return sexpr;
        }
    } else if(ATOM(CAR(sexpr))) {
        if(SYM(CAR(sexpr))) {
            // quote
            if(interp.quote_sym == CAR(sexpr)) {
                if(CDR(sexpr) == NULL) {
                    *error = mk_error("Missing quote argument", "");
                    return NULL;
                }
                if(CDR(CDR(sexpr)) != NULL) {
                    *error = mk_error("Too many arguments for quote", "");
                    return NULL;
                }
                return CAR(CDR(sexpr));
            }
            // atom
            if(interp.atom_sym == CAR(sexpr)) {
                if(ATOM(eval(CAR(CDR(sexpr)), env, roots, error))) {
                    return interp.t_sym;
                }
                return interp.nil_sym;
            }
            // eq
            if(interp.eq_sym == CAR(sexpr)) {
                // TODO check nb args
                sexpr_t* e1 = eval(CAR(CDR(sexpr)), env, roots, error);
                if(*error != NULL) {
                    return NULL;
                }

                roots = cons_to_roots_list(roots, e1);
                sexpr_t* e2 = eval(CAR(CDR(CDR(sexpr))), env, roots, error);
                if(*error != NULL) {
                    return NULL;
                }
                if(INT(e1) && INT(e2)) {
                    if(INT_VAL(e1) == INT_VAL(e2)) {
                        return interp.t_sym;
                    }
                    return interp.nil_sym;
                }
                if(e1 == e2) {
                    return interp.t_sym;
                }
                return interp.nil_sym;
            }
            // if
            if(interp.if_sym == CAR(sexpr)) {
                sexpr_t* e1 = eval(CAR(CDR(sexpr)), env, roots, error);
                if(*error != NULL) {
                    return NULL;
                }
                if(e1 == interp.nil_sym) {
                    return eval(CAR(CDR(CDR(CDR(sexpr)))), env, roots, error);
                } else {
                    return eval(CAR(CDR(CDR(sexpr))), env, roots, error);
                }
            }
            // car
            if(interp.car_sym == CAR(sexpr)) {
                sexpr_t* e1 = eval(CAR(CDR(sexpr)), env, roots, error);
                if(*error != NULL) {
                    return NULL;
                }
                if(e1 == interp.nil_sym) {
                    return interp.nil_sym;
                }
                return CAR(e1);
            }
            // cdr
            if(interp.cdr_sym == CAR(sexpr)) {
                sexpr_t* e1 = eval(CAR(CDR(sexpr)), env, roots, error);

                if(*error != NULL) {
                    return NULL;
                }
                if(e1 == interp.nil_sym) {
                    return interp.nil_sym;
                }
                sexpr_t *res = CDR(e1);
                if(res == NULL) {
                    return interp.nil_sym;
                }
                return res;
            }
            // +
            if(interp.plus_sym == CAR(sexpr)) {
                sexpr_t* e1 = eval(CAR(CDR(sexpr)), env, roots, error);
                if(*error != NULL) {
                    return NULL;
                }

                roots = cons_to_roots_list(roots, e1); 
                sexpr_t* e2 = eval(CAR(CDR(CDR(sexpr))), env, roots, error);
                if(*error != NULL) {
                    return NULL;
                }
                if(INT(e1) && INT(e2)) {
                    return mk_int(INT_VAL(e1) + INT_VAL(e2));
                }

                *error = mk_error("Arguments for '+' are not integers", "");
                return NULL;
            }
            // -
            if(interp.minus_sym == CAR(sexpr)) {
                sexpr_t* e1 = eval(CAR(CDR(sexpr)), env, roots, error);
                if(*error != NULL) {
                    return NULL;
                }
                roots = cons_to_roots_list(roots, e1);
                sexpr_t* e2 = eval(CAR(CDR(CDR(sexpr))), env, roots, error);
                if(*error != NULL) {
                    return NULL;
                }
                if(INT(e1) && INT(e2)) {
                    return mk_int(INT_VAL(e1) - INT_VAL(e2));
                }

                *error = mk_error("Arguments for '-' are not integers", "");
                return NULL;
            }
            if(interp.mul_sym == CAR(sexpr)) {
                sexpr_t* e1 = eval(CAR(CDR(sexpr)), env, roots, error);
                if(*error != NULL) {
                    return NULL;
                }

                roots = cons_to_roots_list(roots, sexpr); 
                sexpr_t* e2 = eval(CAR(CDR(CDR(sexpr))), env, roots, error);
                if(*error != NULL) {
                    return NULL;
                }
                if(INT(e1) && INT(e2)) {
                    return mk_int(INT_VAL(e1) * INT_VAL(e2));
                }

                *error = mk_error("Arguments for '*' are not integers", "");
                return NULL;
            }
            // cons
            if(interp.cons_sym == CAR(sexpr)) {
                sexpr_t* e1 = eval(CAR(CDR(sexpr)), env, roots, error);
                if(*error != NULL) {
                    return NULL;
                }
                roots = cons_to_roots_list(roots, e1);
                sexpr_t* e2 = eval(CAR(CDR(CDR(sexpr))), env, roots, error);
                if(*error != NULL) {
                    return NULL;
                }
                return mk_cons(e1 == interp.nil_sym ? NULL : e1, e2 == interp.nil_sym ? NULL : e2);
            }
            // def
            if(interp.def_sym == CAR(sexpr)) {
                sexpr_t* arg = CAR(CDR(CDR(sexpr)));
                roots = cons_to_roots_list(roots, arg);
                sexpr_t* val = eval(arg, env, roots, error);
                if(*error != NULL) {
                    return NULL;
                }
                
                *env = mk_cons(mk_cons(intern(SYM_VAL(CAR(CDR(sexpr)))), val), *env);
                return val;
            }
            // print
            if(interp.print_sym == CAR(sexpr)) {
                sexpr_t* e1 = eval(CAR(CDR(sexpr)), env, roots, error);
                if(*error != NULL) {
                    return NULL;
                }
                print_sexpr(e1);
                printf("\n");

                return e1;
            }
            // fn
            if(interp.fn_sym == CAR(sexpr)) {
                return mk_fn(sexpr, *env);
            }
            // macro
            if(interp.macro_sym == CAR(sexpr)) {
                return mk_macro(sexpr);
            }
            //eval
            if(interp.eval_sym == CAR(sexpr)) {
                sexpr_t* e1 = eval(CAR(CDR(sexpr)), env, roots, error);
                if(*error != NULL) {
                    return NULL;
                }

                roots = cons_to_roots_list(roots, e1);
                return eval(e1, env, roots, error);
            }
            // else resolves first variable

            sexpr_t* fn = eval(CAR(sexpr), env, roots, error);
            if(*error != NULL) {
                return NULL;
            }

            // eval fn
            if(FN(fn)) {
                sexpr_t* fn_code = CAR(CDR(CDR(CAR(fn))));
                sexpr_t* captured_env = CDR(fn);
                sexpr_t* arguments = eval_list(CDR(sexpr), env, roots, error);
                if(*error != NULL) {
                    return NULL;
                }

                sexpr_t* pairs = pair(CAR(CDR(CAR(fn))), arguments);
                sexpr_t* eval_env = append(pairs, captured_env);

                // append the function itself to the env, roots, for recursive calls
                eval_env = mk_cons(mk_cons(CAR(sexpr), fn), eval_env);
                
                /* printf("fn code=\n"); */
                /* print_sexpr(fn_code); */
                /* printf("\n"); */
                roots = cons_to_roots_list(roots, eval_env);
                return eval(fn_code, &eval_env, roots, error);
            }

            // eval macro
            if(MACRO(fn)) {
                sexpr_t* macro_code = CAR(CDR(CDR(CAR(fn))));
                sexpr_t* pairs = pair(CAR(CDR(CAR(fn))), CDR(sexpr));
                sexpr_t* eval_env = append(pairs, *env);

                roots = cons_to_roots_list(roots, eval_env);
                sexpr_t* transformed_code = eval(macro_code, &eval_env, roots, error);

                if(*error != NULL) {
                    return NULL;
                }

                return eval(transformed_code, env, roots, error);
            }
            
            // else primitives
            sexpr_t* arguments = eval_list(CDR(sexpr), env, roots, error);
            if(*error != NULL) {
                return NULL;
            }
            sexpr_t* to_eval = mk_cons(fn, arguments);
            return eval(to_eval, env, roots, error);
        }
    } else if(CAR(CAR(sexpr)) == interp.fn_sym) {
        // executes an anonymous function

        sexpr_t* fn = CAR(sexpr);
        sexpr_t* fn_code = CAR(CDR(CDR(fn)));
        sexpr_t* arguments = eval_list(CDR(sexpr), env, roots, error);
        if(*error != NULL) {
            return NULL;
        }
        
        sexpr_t* l = pair(CAR(CDR(fn)), arguments);
        l = append(l, *env);

        roots = cons_to_roots_list(roots, l);
        return eval(fn_code, &l, roots, error);
    }

    print_sexpr(sexpr);
    printf("\n");
    *error = mk_error("Invalid expression", "");

    return NULL;
}
Exemple #9
0
static ERL_NIF_TERM do_job(ErlNifEnv* env, int argc,
			   const ERL_NIF_TERM argv[])
{
  state_t *state = NULL;
  ErlNifBinary input;
  size_t block_size;
  int is_eof;
  size_t input_size;
  char *input_data;
  rs_result res;
    
  if (!enif_get_resource(env, argv[0], state_r, (void *) &state))
    return enif_make_badarg(env);

  if (argc == 1) {
    is_eof = 1;
    input_size = 0;
    input_data = NULL;
  } else {
    if (!enif_inspect_iolist_as_binary(env, argv[1], &input))
      return enif_make_badarg(env);
    is_eof = 0;
    input_size = input.size;
    input_data = (char *) input.data;
  }

  block_size = MAX(state->in_size + input_size, RS_JOB_BLOCKSIZE);
  if (input_size) {
    state->in = realloc(state->in, state->in_size + input_size);
    memcpy(state->in + state->in_size, input_data, input_size);
  }
  state->in_size += input_size;
  state->out_size = 0;

  while (1) {
    state->out = realloc(state->out, state->out_size + block_size);
    rs_buffers_t buf = {.next_in = state->in,
			.avail_in = state->in_size,
			.eof_in = is_eof,
			.next_out = state->out + state->out_size,
			.avail_out = block_size};
    res = rs_job_iter(state->job, &buf);
    state->in_size = buf.avail_in;
    state->out_size += block_size - buf.avail_out;
    if (res == RS_BLOCKED) {
      if (buf.avail_in > 0) {
	state->in = realloc(state->in, buf.avail_in);
	memcpy(state->in, buf.next_in, buf.avail_in);
      }
      if (!is_eof)
	return mk_output(env, state);
    } else if (res == RS_DONE) {
      return mk_output(env, state);
    } else {
      return mk_error(env, res);
    }
  }
}

static ERL_NIF_TERM job_iter(ErlNifEnv* env, int argc,
			     const ERL_NIF_TERM argv[])
{
  return do_job(env, argc, argv);
}

static ERL_NIF_TERM job_done(ErlNifEnv* env, int argc,
			     const ERL_NIF_TERM argv[])
{
  return do_job(env, argc, argv);
}

static ErlNifFunc nif_funcs[] =
  {
    {"sig_init", 0, sig_init},
    {"loadsig_init", 0, loadsig_init},
    {"delta_init", 1, delta_init},
    {"patch_init", 1, patch_init},
    {"format_error_nif", 1, format_error},
    {"job_iter", 2, job_iter},
    {"job_done", 1, job_done}
  };

ERL_NIF_INIT(rsync, nif_funcs, load, NULL, NULL, NULL)