int
compare_props(int depth, couch_ejson_ctx_t* ctx, ERL_NIF_TERM a, ERL_NIF_TERM b)
{
    ERL_NIF_TERM headA, tailA;
    ERL_NIF_TERM headB, tailB;
    int aArity, bArity;
    const ERL_NIF_TERM *aKV, *bKV;
    ErlNifBinary keyA, keyB;
    int aIsEmpty, bIsEmpty;
    int keyCompResult, valueCompResult;

    while (1) {
        aIsEmpty = !enif_get_list_cell(ctx->env, a, &headA, &tailA);
        bIsEmpty = !enif_get_list_cell(ctx->env, b, &headB, &tailB);

        if (aIsEmpty) {
            if (bIsEmpty) {
                return 0;
            }
            return -1;
        }

        if (bIsEmpty) {
            return 1;
        }

        if (!enif_get_tuple(ctx->env, headA, &aArity, &aKV)) {
            ctx->error = 1;
            return 0;
        }
        if ((aArity != 2) || !enif_inspect_binary(ctx->env, aKV[0], &keyA)) {
            ctx->error = 1;
            return 0;
        }

        if (!enif_get_tuple(ctx->env, headB, &bArity, &bKV)) {
            ctx->error = 1;
            return 0;
        }
        if ((bArity != 2) || !enif_inspect_binary(ctx->env, bKV[0], &keyB)) {
            ctx->error = 1;
            return 0;
        }

        keyCompResult = compare_strings(ctx, keyA, keyB);

        if (ctx->error || keyCompResult != 0) {
            return keyCompResult;
        }

        valueCompResult = less_ejson(depth + 1, ctx, aKV[1], bKV[1]);

        if (ctx->error || valueCompResult != 0) {
            return valueCompResult;
        }

        a = tailA;
        b = tailB;
    }

    return 0;
}
Exemple #2
0
static ERL_NIF_TERM
nif_scheduler_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    ErlNifBinary frameworkInfo_binary;
    ErlNifBinary credentials_binary;
    char masterUrl[MAXBUFLEN];

    state_ptr state = (state_ptr) enif_priv_data(env);
    
    if(state->initilised == 1) 
    {
        return enif_make_tuple2(env, 
            enif_make_atom(env, "state_error"), 
            enif_make_atom(env, "scheduler_already_inited"));
    }

    ErlNifPid* pid = (ErlNifPid*) enif_alloc(sizeof(ErlNifPid));

    if(!enif_get_local_pid(env, argv[0], pid))
    {
        return enif_make_tuple3(env, 
                                enif_make_atom(env, "argument_error"), 
                                enif_make_atom(env, "invalid_or_corrupted_parameter"),
                                enif_make_atom(env, "pid"));
    }

    if (!enif_inspect_binary(env, argv[1], &frameworkInfo_binary)) 
    {
        return enif_make_tuple3(env, 
                    enif_make_atom(env, "argument_error"), 
                    enif_make_atom(env, "invalid_or_corrupted_parameter"),
                    enif_make_atom(env, "framework_info"));
    }

    if(!enif_get_string(env, argv[2], masterUrl , MAXBUFLEN, ERL_NIF_LATIN1 ))
    {
        return enif_make_tuple3(env, 
                    enif_make_atom(env, "argument_error"), 
                    enif_make_atom(env, "invalid_or_corrupted_parameter"),
                    enif_make_atom(env, "master_info"));
    }

    if(argc == 4 )
    {
        if(!enif_inspect_binary(env,argv[3], &credentials_binary))
        {           
            return enif_make_tuple3(env, 
                        enif_make_atom(env, "argument_error"), 
                        enif_make_atom(env, "invalid_or_corrupted_parameter"),
                        enif_make_atom(env, "credential"));
            
        }
        state->scheduler_state = scheduler_init(pid, &frameworkInfo_binary, masterUrl, 1, &credentials_binary);
    }
    else
    {
        state->scheduler_state = scheduler_init(pid, &frameworkInfo_binary, masterUrl, 0, &credentials_binary);
    }
    state->initilised = 1;
    return enif_make_atom(env, "ok");
}
ERL_NIF_TERM nif_process_trends(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {

  ErlNifBinary trends_bin;
  unsigned char trends_buffer[MAX_LIST_BUFFER_LEN];
  unsigned int trends_len = 0;

  if (enif_inspect_binary(env, argv[0], &trends_bin)) {
    memcpy((char *)trends_buffer, trends_bin.data, trends_bin.size);
    trends_buffer[trends_bin.size] = '\0';
    trends_len = trends_bin.size;
#ifdef ERLANG_R14B02 
    enif_release_binary(&trends_bin);
#else
    enif_release_binary(env, &trends_bin);
#endif
  } else {
#ifndef TRENDS_DEBUG
    return enif_make_atom(env, "error");
#else
    return enif_make_atom(env, "error_invalid_trends_bin");
#endif
  }

  unsigned int trends_count = 0;
  if (ProcessTrends(trends_buffer, &trends_len, &trends_count) < 0) {
#ifndef TRENDS_DEBUG
    return enif_make_atom(env, "error");
#else
    return enif_make_atom(env, "error_GetTrends");
#endif
  }

  ERL_NIF_TERM processed_trends_list = enif_make_list(env, 0);

  if (strlen(trends_buffer) > 0) {
    char* start = (char*) trends_buffer;
    char* end = strstr(start, "|");
    unsigned int len = 0;
    ErlNifBinary processed_trends_bin;
    int ret_val = 0;
    unsigned int i=0;

    while (start && end && *end != '\0') {
      end = strstr(start, "|");
      if (!end)
        break;
      *end = '\0';
      len = end - start;
#ifdef ERLANG_R14B02
      ret_val = enif_alloc_binary(len, &processed_trends_bin);
#else
      ret_val = enif_alloc_binary(env, len, &processed_trends_bin);
#endif
      if (ret_val < 0) {
#ifndef TRENDS_DEBUG
        return enif_make_atom(env, "error");
#else
        return enif_make_atom(env, "error_processed_trends_bin_alloc");
#endif
      }
      for (i=0; i<len; i++) {
        processed_trends_bin.data[i] = *(start + i);
      }
      processed_trends_list = enif_make_list_cell(env,
                                                  enif_make_binary(env, &processed_trends_bin),
                                                  processed_trends_list);

      *end = '|';
      start = end + 1;
    }
  }

  return processed_trends_list;
}
Exemple #4
0
/* For OpenSSL >= 1.1.1 the hmac_nif and cmac_nif could be integrated into poly1305 (with 'type' as parameter) */
ERL_NIF_TERM poly1305_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Key, Text) */
#ifdef HAVE_POLY1305
    ErlNifBinary key_bin, text, ret_bin;
    ERL_NIF_TERM ret;
    EVP_PKEY *key = NULL;
    EVP_MD_CTX *mctx = NULL;
    EVP_PKEY_CTX *pctx = NULL;
    const EVP_MD *md = NULL;
    size_t size;
    int ret_bin_alloc = 0;

    ASSERT(argc == 2);

    if (!enif_inspect_binary(env, argv[0], &key_bin))
        goto bad_arg;
    if (key_bin.size != 32)
        goto bad_arg;
    if (!enif_inspect_binary(env, argv[1], &text))
        goto bad_arg;

    if ((key = EVP_PKEY_new_raw_private_key(EVP_PKEY_POLY1305, /*engine*/ NULL, key_bin.data,  key_bin.size)) == NULL)
        goto err;

    if ((mctx = EVP_MD_CTX_new()) == NULL)
        goto err;
    if (EVP_DigestSignInit(mctx, &pctx, md, /*engine*/ NULL, key) != 1)
        goto err;
    if (EVP_DigestSignUpdate(mctx, text.data, text.size) != 1)
        goto err;

    if (EVP_DigestSignFinal(mctx, NULL, &size) != 1)
        goto err;
    if (!enif_alloc_binary(size, &ret_bin))
        goto err;
    ret_bin_alloc = 1;
    if (EVP_DigestSignFinal(mctx, ret_bin.data, &size) != 1)
        goto err;

    if (size != ret_bin.size) {
        if (!enif_realloc_binary(&ret_bin, size))
            goto err;
    }

    ret = enif_make_binary(env, &ret_bin);
    ret_bin_alloc = 0;
    goto done;

 bad_arg:
    return enif_make_badarg(env);

 err:
    if (ret_bin_alloc)
        enif_release_binary(&ret_bin);
    ret = atom_error;

 done:
    if (mctx)
        EVP_MD_CTX_free(mctx);
    if (key)
        EVP_PKEY_free(key);
    return ret;

#else
    return enif_raise_exception(env, atom_notsup);
#endif
}
Exemple #5
0
static ERL_NIF_TERM
mmap_open(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
  Mmap *desc;
  ERL_NIF_TERM f;
  ErlNifBinary bin_path;
  char path[PATH_SIZE];
  int fd;
  struct stat st;
  int debug = 0;
  ERL_NIF_TERM opt, opts;
  
  
  if (!enif_inspect_binary(env, argv[0], &bin_path)) {
    return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_string(env, "Should pass binary filename", ERL_NIF_LATIN1));
  }
  if (!enif_is_list(env, argv[1])) {
    return enif_make_badarg(env);
  }
  
  bzero(path, PATH_SIZE);
  strncpy(path, (const char *)bin_path.data, bin_path.size >= PATH_SIZE ? PATH_SIZE - 1 : bin_path.size);
  
  opts = argv[1];
  while(enif_get_list_cell(env, opts, &opt, &opts)) {
    if(!enif_compare(opt, enif_make_atom(env, "debug"))) {
      debug = 1;
    }
  }
  
  
  fd = open(path, O_RDONLY);
  if(fd == -1) {
    if(errno == ENOENT) return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_atom(env, "enoent"));
    return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_string(env, strerror(errno), ERL_NIF_LATIN1));
  }
  if(fstat(fd, &st)) {
    close(fd);
    return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_string(env, strerror(errno), ERL_NIF_LATIN1));
  }
  
  if (debug) fprintf(stderr, "Opened file %s %ld\r\n", path, (ssize_t)st.st_size);
  
  desc = (Mmap *)enif_alloc_resource(MmapResource, sizeof(Mmap));
  if(!desc) {
    close(fd);
    return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_string(env, "Couldn't allocate mmap resource", ERL_NIF_LATIN1));
  }
  desc->fd = fd;
  desc->size = st.st_size;
  if (debug) fprintf(stderr, "Mmaping file: %p\r\n", desc);
  desc->ptr = mmap(NULL, desc->size, PROT_READ, MAP_FILE | MAP_PRIVATE, desc->fd, 0);
  close(fd);
  if(desc->ptr == MAP_FAILED) {
    enif_release_resource(desc);
    return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_string(env, "Couldn't mmap", ERL_NIF_LATIN1));
  }
  if (debug) fprintf(stderr, "Mmaped file to %p\r\n", desc->ptr);
  f = enif_make_resource_binary(env, (void *)desc, desc->ptr, desc->size);
  enif_release_resource(desc);
  desc->debug = debug;
  
  return enif_make_tuple2(env, enif_make_atom(env, "ok"), f);
}
ERL_NIF_TERM nif_test_twitter_timeline(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {

  char tweets_buffer[MAX_LIST_BUFFER_LEN];
  memset(tweets_buffer, 0, MAX_LIST_BUFFER_LEN);

  int out_length = 0;
  if (argc == 1) {
    char user_name_str[MAX_NAME_LEN];
    memset(user_name_str, 0, MAX_NAME_LEN);
    ErlNifBinary user_name;

    if (enif_inspect_binary(env, argv[0], &user_name)) {
      memcpy(user_name_str, user_name.data, user_name.size);
      user_name_str[user_name.size] = '\0';
#ifdef ERLANG_R14B02 
      enif_release_binary(&user_name);
#else
      enif_release_binary(env, &user_name);
#endif
    }   else {
#ifdef ERLANG_R14B02 
      enif_release_binary(&user_name);
#else
      enif_release_binary(env, &user_name);
#endif
#ifndef TRENDS_DEBUG
      return enif_make_atom(env, "error");
#else
      return enif_make_atom(env, "error_user_name");
#endif
    }

    if (GetTestTweets(user_name_str, MAX_LIST_BUFFER_LEN, tweets_buffer, &out_length) < 0) {
#ifndef TRENDS_DEBUG
      return enif_make_atom(env, "error");
#else
      return enif_make_atom(env, "error_get_test_tweets_for_user");
#endif
    }
  } else {
    if (GetTestTweets(NULL, MAX_LIST_BUFFER_LEN, tweets_buffer, &out_length) < 0) {
#ifndef TRENDS_DEBUG
      return enif_make_atom(env, "error");
#else
      return enif_make_atom(env, "error_get_test_tweets_for_null_user");
#endif
    }
  }

  if (0 == out_length || out_length > MAX_LIST_BUFFER_LEN) {
#ifndef TRENDS_DEBUG
    return enif_make_atom(env, "error");
#else
    return enif_make_atom(env, "error_out_length");
#endif
  }

  ErlNifBinary tweets_bin;
  unsigned int tweets_len = out_length;
  int ret_val = 0;
  unsigned int i = 0;
  ERL_NIF_TERM arg_array[1]; 
  ERL_NIF_TERM trends_list = enif_make_list(env, 0);

#ifdef ERLANG_R14B02
  ret_val = enif_alloc_binary(tweets_len, &tweets_bin);
#else
  ret_val = enif_alloc_binary(env, tweets_len, &tweets_bin);
#endif

  if (ret_val < 0) {
#ifndef TRENDS_DEBUG
    return enif_make_atom(env, "error");
#else
    return enif_make_atom(env, "error_tweet_len");
#endif
  }
  for (i=0; i<tweets_len; i++) {
    tweets_bin.data[i] = *(tweets_buffer + i);
  }

  arg_array[0] = enif_make_binary(env, &tweets_bin);
  trends_list = nif_get_trends(env, 1, arg_array);
  if (enif_is_atom(env, trends_list)) {
    return enif_make_atom(env, "error_nif_get_trends");
  }

  return trends_list;
}
Exemple #7
0
static ERL_NIF_TERM
_send  (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
  CAN_handle* handle;
  unsigned int i = 0, length, total_size = 0;
  ERL_NIF_TERM result;
  if (!enif_get_resource(env, argv[0], CAN_handle_type, (void**) &handle))
    return enif_make_int(env, -2000);
  if (!enif_get_list_length(env, argv[1], &length))
    return enif_make_int(env, -2001);
  canmsg_t* buffer = enif_alloc(length * sizeof(canmsg_t));
  memset(buffer, 0, length * sizeof(canmsg_t));
  ERL_NIF_TERM list = argv[1];
  ERL_NIF_TERM head, tail;
  while (enif_get_list_cell(env, list, &head, &tail))
    {
      canmsg_t* can_msg = &buffer[i++];
      int arity;
      canmsg_id_t target;
      ErlNifBinary msg;
      const ERL_NIF_TERM* items;
      list = tail;
      if (!enif_get_tuple(env, head, &arity, &items))
        {
          result = enif_make_int(env, -1000);
          goto end;
        }
      if (arity != 2)
        {
          result = enif_make_int(env, -1001);
          goto end;
        }
      if (!enif_get_ulong(env, items[0], &target))
        {
          result = enif_make_int(env, -1002);
          goto end;
        }
      if (!enif_inspect_binary(env, items[1], &msg))
        {
          result = enif_make_int(env, -1003);
          goto end;
        }
      if (msg.size > CAN_MSG_LENGTH)
        {
          result = enif_make_int(env, -1005);
          goto end;
        }
      can_msg->id = target;
      memcpy(&can_msg->data[0], msg.data, msg.size);
      can_msg->length = msg.size;
      total_size += msg.size;
    }
  {
    int status = write(handle->device, buffer, length * sizeof(canmsg_t));
    if (status != length * sizeof(canmsg_t)) status = errno;
    result = enif_make_tuple2(env,
                              enif_make_int(env, status),
                              enif_make_int(env, total_size));
  }
end:
  enif_free(buffer);
  return result;
}
Exemple #8
0
/* 0: list */
    static ERL_NIF_TERM
nif_alloc(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
    ERL_NIF_TERM head = {0};
    ERL_NIF_TERM tail = {0};

    int arity = 0;
    char key[MAXATOMLEN+1];  /* Includes terminating NULL */
    const ERL_NIF_TERM *array = NULL;

    ERL_NIF_TERM resources = {0};
    ErlNifBinary req = {0};


    if (!enif_is_list(env, argv[0]) || enif_is_empty_list(env, argv[0]))
        return enif_make_badarg(env);

    resources = enif_make_list(env, 0);
    if (!enif_alloc_binary(0, &req))
        return error_tuple(env, ENOMEM);

    tail = argv[0];

    /* [binary(), {ptr, integer()}, {ptr, binary()}, ...] */
    while (enif_get_list_cell(env, tail, &head, &tail)) {
        int index = req.size;
        ErlNifBinary bin = {0};

        if (enif_inspect_binary(env, head, &bin)) {
            enif_realloc_binary(&req, req.size+bin.size);
            (void)memcpy(req.data+index, bin.data, bin.size);
        }
        else if (enif_get_tuple(env, head, &arity, &array)) {
            ALLOC_STATE *p = NULL;
            ERL_NIF_TERM res = {0};
            size_t val = 0;
            ErlNifBinary initial = {0};

            if ( (arity != 2) ||
                !enif_get_atom(env, array[0], key, sizeof(key), ERL_NIF_LATIN1) ||
                (strcmp(key, "ptr") != 0))
                return enif_make_badarg(env);

            if ( !(enif_get_ulong(env, array[1], (unsigned long *)&val) && val > 0) &&
                !(enif_inspect_binary(env, array[1], &initial) && initial.size > 0))
                return enif_make_badarg(env);

            val = (initial.size > 0) ? initial.size : val;

            p = enif_alloc_resource(PROCKET_ALLOC_RESOURCE, sizeof(ALLOC_STATE));

            if (p == NULL)
                return error_tuple(env, ENOMEM);

            p->size = val;
            p->buf = calloc(val, 1);

            if (p->buf == NULL) {
                enif_release_resource(p);
                return error_tuple(env, ENOMEM);
            }

            if (initial.size > 0)
                (void)memcpy(p->buf, initial.data, p->size);

            if (!enif_realloc_binary(&req, req.size+sizeof(void *)))
                return error_tuple(env, ENOMEM);

            (void)memcpy(req.data+index, &p->buf, sizeof(void *));

            res = enif_make_resource(env, p);
            enif_release_resource(p);

            resources = enif_make_list_cell(env, res, resources);
        }
        else
            return enif_make_badarg(env);
    }

    return enif_make_tuple3(env, atom_ok,
            enif_make_binary(env, &req),
            resources);
}
ERL_NIF_TERM nif_detect_lang(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {

  if (argc != 1) {
#ifndef LD_DEBUG
    return enif_make_atom(env, "error");
#else
    return enif_make_atom(env, "error_invalid_argc");
#endif
  }

  ErlNifBinary tweet_bin;
  char tweet_str[MAX_BUFFER_LEN];
  ERL_NIF_TERM tweet_term;
 
  bool success = enif_inspect_binary(env, argv[0], &tweet_bin);
  int tweet_len = tweet_bin.size;
  if (success && tweet_len > 1 && tweet_len < MAX_BUFFER_LEN) {
    memcpy(tweet_str, tweet_bin.data, tweet_len);
    tweet_str[tweet_len] = '\0';
    tweet_term = enif_make_binary(env, &tweet_bin);
    //enif_release_binary(env, &tweet_bin);
  } else {
#ifdef ERLANG_R14B02
    enif_release_binary(&tweet_bin);
#else
    enif_release_binary(env, &tweet_bin);
#endif
#ifndef LD_DEBUG
    return enif_make_atom(env, "error");
#else
    return enif_make_atom(env, "error_invalid_input_binary");
#endif
  }

  char lang_buffer[MAX_BUFFER_LEN];
  lang_buffer[0] = '\0';
  if (CallClassify(tweet_str, tweet_len, lang_buffer, MAX_BUFFER_LEN) < 0) { 
#ifndef LD_DEBUG
    return enif_make_atom(env, "error");
#else
    return enif_make_atom(env, "error_call_classify_failed");
#endif
  }

  unsigned int len = 0;
  unsigned int i = 0;
  int ret_val = 0;
  ErlNifBinary lang_bin;
  ERL_NIF_TERM lang_term;

  len = strlen(lang_buffer);
  if (len < 2) {
    strcpy(lang_buffer, "00");
    len = 2;
    lang_buffer[2] = '\0';
  }

#ifdef ERLANG_R14B02
  ret_val = enif_alloc_binary(len, &lang_bin);
#else
  ret_val = enif_alloc_binary(env, len, &lang_bin);
#endif
  if (ret_val < 0) {
#ifndef LD_DEBUG
    return enif_make_atom(env, "error");
#else
    return enif_make_atom(env, "error_lang_bin_alloc");
#endif
  }

  for (i=0; i<len; i++) {
    lang_bin.data[i] = *(lang_buffer + i);
  }
  lang_term = enif_make_binary(env, &lang_bin);

  return enif_make_tuple2(env, tweet_term, lang_term);
}
Exemple #10
0
ERL_NIF_TERM
decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    Decoder* d;
    jiffy_st* st = (jiffy_st*) enif_priv_data(env);

    ErlNifBinary bin;

    ERL_NIF_TERM objs;
    ERL_NIF_TERM curr;
    ERL_NIF_TERM val = argv[2];
    ERL_NIF_TERM trailer;
    ERL_NIF_TERM ret;
    size_t bytes_read = 0;

    if(argc != 5) {
        return enif_make_badarg(env);
    } else if(!enif_inspect_binary(env, argv[0], &bin)) {
        return enif_make_badarg(env);
    } else if(!enif_get_resource(env, argv[1], st->res_dec, (void**) &d)) {
        return enif_make_badarg(env);
    } else if(!enif_is_list(env, argv[3])) {
        return enif_make_badarg(env);
    } else if(!enif_is_list(env, argv[4])) {
        return enif_make_badarg(env);
    }

    dec_init(d, env, argv[0], &bin);
    objs = argv[3];
    curr = argv[4];

    while(d->i < bin.size) {
        if(should_yield(env, &bytes_read, d->bytes_per_red)) {
            return enif_make_tuple5(
                    env,
                    st->atom_iter,
                    argv[1],
                    val,
                    objs,
                    curr
                );
        }

        bytes_read += 1;

        switch(dec_curr(d)) {
            case st_value:
                switch(d->p[d->i]) {
                    case ' ':
                    case '\n':
                    case '\r':
                    case '\t':
                        d->i++;
                        break;
                    case 'n':
                        if(d->i + 3 >= d->len) {
                            ret = dec_error(d, "invalid_literal");
                            goto done;
                        }
                        if(memcmp(&(d->p[d->i]), "null", 4) != 0) {
                            ret = dec_error(d, "invalid_literal");
                            goto done;
                        }
                        val = d->null_term;
                        dec_pop(d, st_value);
                        d->i += 4;
                        break;
                    case 't':
                        if(d->i + 3 >= d->len) {
                            ret = dec_error(d, "invalid_literal");
                            goto done;
                        }
                        if(memcmp(&(d->p[d->i]), "true", 4) != 0) {
                            ret = dec_error(d, "invalid_literal");
                            goto done;
                        }
                        val = d->atoms->atom_true;
                        dec_pop(d, st_value);
                        d->i += 4;
                        break;
                    case 'f':
                        if(d->i + 4 >= bin.size) {
                            ret = dec_error(d, "invalid_literal");
                            goto done;
                        }
                        if(memcmp(&(d->p[d->i]), "false", 5) != 0) {
                            ret = dec_error(d, "invalid_literal");
                            goto done;
                        }
                        val = d->atoms->atom_false;
                        dec_pop(d, st_value);
                        d->i += 5;
                        break;
                    case '\"':
                        if(!dec_string(d, &val)) {
                            ret = dec_error(d, "invalid_string");
                            goto done;
                        }
                        dec_pop(d, st_value);
                        break;
                    case '-':
                    case '0':
                    case '1':
                    case '2':
                    case '3':
                    case '4':
                    case '5':
                    case '6':
                    case '7':
                    case '8':
                    case '9':
                        if(!dec_number(d, &val)) {
                            ret = dec_error(d, "invalid_number");
                            goto done;
                        }
                        dec_pop(d, st_value);
                        break;
                    case '{':
                        dec_push(d, st_object);
                        dec_push(d, st_key);
                        objs = enif_make_list_cell(env, curr, objs);
                        curr = enif_make_list(env, 0);
                        d->i++;
                        break;
                    case '[':
                        dec_push(d, st_array);
                        dec_push(d, st_value);
                        objs = enif_make_list_cell(env, curr, objs);
                        curr = enif_make_list(env, 0);
                        d->i++;
                        break;
                    case ']':
                        if(!enif_is_empty_list(env, curr)) {
                            ret = dec_error(d, "invalid_json");
                            goto done;
                        }
                        dec_pop(d, st_value);
                        if(dec_curr(d) != st_array) {
                            ret = dec_error(d, "invalid_json");
                            goto done;
                        }
                        dec_pop(d, st_array);
                        dec_pop(d, st_value);
                        val = curr; // curr is []
                        if(!enif_get_list_cell(env, objs, &curr, &objs)) {
                            ret = dec_error(d, "internal_error");
                            goto done;
                        }
                        d->i++;
                        break;
                    default:
                        ret = dec_error(d, "invalid_json");
                        goto done;
                }
                if(dec_top(d) == 0) {
                    dec_push(d, st_done);
                } else if(dec_curr(d) != st_value && dec_curr(d) != st_key) {
                    dec_push(d, st_comma);
                    curr = enif_make_list_cell(env, val, curr);
                }
                break;

            case st_key:
                switch(d->p[d->i]) {
                    case ' ':
                    case '\n':
                    case '\r':
                    case '\t':
                        d->i++;
                        break;
                    case '\"':
                        if(!dec_string(d, &val)) {
                            ret = dec_error(d, "invalid_string");
                            goto done;
                        }
                        dec_pop(d, st_key);
                        dec_push(d, st_colon);
                        curr = enif_make_list_cell(env, val, curr);
                        break;
                    case '}':
                        if(!enif_is_empty_list(env, curr)) {
                            ret = dec_error(d, "invalid_json");
                            goto done;
                        }
                        dec_pop(d, st_key);
                        dec_pop(d, st_object);
                        dec_pop(d, st_value);
                        val = make_empty_object(env, d->return_maps);
                        if(!enif_get_list_cell(env, objs, &curr, &objs)) {
                            ret = dec_error(d, "internal_error");
                            goto done;
                        }
                        if(dec_top(d) == 0) {
                            dec_push(d, st_done);
                        } else {
                            dec_push(d, st_comma);
                            curr = enif_make_list_cell(env, val, curr);
                        }
                        d->i++;
                        break;
                    default:
                        ret = dec_error(d, "invalid_json");
                        goto done;
                }
                break;

            case st_colon:
                switch(d->p[d->i]) {
                    case ' ':
                    case '\n':
                    case '\r':
                    case '\t':
                        d->i++;
                        break;
                    case ':':
                        dec_pop(d, st_colon);
                        dec_push(d, st_value);
                        d->i++;
                        break;
                    default:
                        ret = dec_error(d, "invalid_json");
                        goto done;
                }
                break;

            case st_comma:
                switch(d->p[d->i]) {
                    case ' ':
                    case '\n':
                    case '\r':
                    case '\t':
                        d->i++;
                        break;
                    case ',':
                        dec_pop(d, st_comma);
                        switch(dec_curr(d)) {
                            case st_object:
                                dec_push(d, st_key);
                                break;
                            case st_array:
                                dec_push(d, st_value);
                                break;
                            default:
                                ret = dec_error(d, "internal_error");
                                goto done;
                        }
                        d->i++;
                        break;
                    case '}':
                        dec_pop(d, st_comma);
                        if(dec_curr(d) != st_object) {
                            ret = dec_error(d, "invalid_json");
                            goto done;
                        }
                        dec_pop(d, st_object);
                        dec_pop(d, st_value);
                        if(!make_object(env, curr, &val,
                                d->return_maps, d->dedupe_keys)) {
                            ret = dec_error(d, "internal_object_error");
                            goto done;
                        }
                        if(!enif_get_list_cell(env, objs, &curr, &objs)) {
                            ret = dec_error(d, "internal_error");
                            goto done;
                        }
                        if(dec_top(d) > 0) {
                            dec_push(d, st_comma);
                            curr = enif_make_list_cell(env, val, curr);
                        } else {
                            dec_push(d, st_done);
                        }
                        d->i++;
                        break;
                    case ']':
                        dec_pop(d, st_comma);
                        if(dec_curr(d) != st_array) {
                            ret = dec_error(d, "invalid_json");
                            goto done;
                        }
                        dec_pop(d, st_array);
                        dec_pop(d, st_value);
                        val = make_array(env, curr);
                        if(!enif_get_list_cell(env, objs, &curr, &objs)) {
                            ret = dec_error(d, "internal_error");
                            goto done;
                        }
                        if(dec_top(d) > 0) {
                            dec_push(d, st_comma);
                            curr = enif_make_list_cell(env, val, curr);
                        } else {
                            dec_push(d, st_done);
                        }
                        d->i++;
                        break;
                    default:
                        ret = dec_error(d, "invalid_json");
                        goto done;
                }
                break;

            case st_done:
                switch(d->p[d->i]) {
                    case ' ':
                    case '\n':
                    case '\r':
                    case '\t':
                        d->i++;
                        break;
                    default:
                        goto decode_done;
                }
                break;

            default:
                ret = dec_error(d, "invalid_internal_state");
                goto done;
        }
    }

decode_done:

    if(d->i < bin.size && d->return_trailer) {
        trailer = enif_make_sub_binary(env, argv[0], d->i, bin.size - d->i);
        val = enif_make_tuple3(env, d->atoms->atom_has_trailer, val, trailer);
    } else if(d->i < bin.size) {
        ret = dec_error(d, "invalid_trailing_data");
        goto done;
    }

    if(dec_curr(d) != st_done) {
        ret = dec_error(d, "truncated_json");
    } else if(d->is_partial) {
        ret = enif_make_tuple2(env, d->atoms->atom_partial, val);
    } else {
        ret = val;
    }

done:
    return ret;
}
ERL_NIF_TERM nif_test_twitter_timeline(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {

  char tweets_buffer[MAX_LIST_BUFFER_LEN];
  memset(tweets_buffer, 0, MAX_LIST_BUFFER_LEN);

  int out_length = 0;
  if (argc == 1) {
    char user_name_str[MAX_NAME_LEN];
    memset(user_name_str, 0, MAX_NAME_LEN);
    ErlNifBinary user_name;

    if (enif_inspect_binary(env, argv[0], &user_name)) {
      memcpy(user_name_str, user_name.data, user_name.size);
      user_name_str[user_name.size] = '\0';
#ifdef ERLANG_R14B02
      enif_release_binary(&user_name);
#else
      enif_release_binary(env, &user_name);
#endif
    } else {
#ifdef ERLANG_R14B02
      enif_release_binary(&user_name);
#else
      enif_release_binary(env, &user_name);
#endif
#ifndef LD_DEBUG
      return enif_make_atom(env, "error");
#else
      return enif_make_atom(env, "error_user_name");
#endif
    }

    if (GetTestTweets(user_name_str, MAX_LIST_BUFFER_LEN, tweets_buffer, &out_length) < 0) {
#ifndef LD_DEBUG
      return enif_make_atom(env, "error");
#else
      return enif_make_atom(env, "error_get_test_tweets_for_user");
#endif
    }
  } else {
    if (GetTestTweets(NULL, MAX_LIST_BUFFER_LEN, tweets_buffer, &out_length) < 0) {
#ifndef LD_DEBUG
      return enif_make_atom(env, "error");
#else
      return enif_make_atom(env, "error_get_test_tweets_for_null_user");
#endif
    }
  }

  if (0 == out_length || out_length > MAX_LIST_BUFFER_LEN) {
#ifndef LD_DEBUG
    return enif_make_atom(env, "error");
#else
    return enif_make_atom(env, "error_out_length");
#endif
  }

  ErlNifBinary tweet;
  char *tweet_start = tweets_buffer;
  char *tweet_end = strstr(tweet_start, "|");
  int ret_val = 0;
  unsigned int i = 0;
  unsigned int tweet_len = 0;
  ERL_NIF_TERM arg_array[1]; 
  ERL_NIF_TERM tuple2_list = enif_make_list(env, 0);

  while (tweet_start && tweet_end && *tweet_end != '\0') {
    tweet_end = strstr(tweet_start, "|");
    if (!tweet_end)
      break;
    *tweet_end = '\0';
    tweet_len = tweet_end - tweet_start;

    if (tweet_len <= 0 || tweet_len >= MAX_BUFFER_LEN) {
#ifndef LD_DEBUG
      return enif_make_atom(env, "error");
#else
      return enif_make_atom(env, "error_tweet_length");
#endif
    }

#ifdef ERLANG_R14B02
    ret_val = enif_alloc_binary(tweet_len, &tweet);
#else
    ret_val = enif_alloc_binary(env, tweet_len, &tweet);
#endif
    if (ret_val < 0) {
#ifndef LD_DEBUG
      return enif_make_atom(env, "error");
#else
      return enif_make_atom(env, "error_alloc_bin_failed_for_tweet");
#endif
    }

    for (i=0; i<tweet_len; i++) {
      tweet.data[i] = *(tweet_start + i);
    }

    arg_array[0] = enif_make_binary(env, &tweet);
    ERL_NIF_TERM tuple2 = nif_detect_lang(env, 1, arg_array);
    if (enif_is_atom(env, tuple2)) {
#ifndef LD_DEBUG
      return enif_make_atom(env, "error");
#else
      return enif_make_atom(env, "error_not_a_tuple2");
#endif
    //} else if (enif_is_tuple(env, tuple2)) {
    } else {
      tuple2_list = enif_make_list_cell(env, tuple2, tuple2_list);
/*
#ifndef LD_DEBUG
      return enif_make_atom(env, "error");
#else
      return enif_make_atom(env, "error_undefined_detect_lang_output");
#endif
*/
    }

    *tweet_end = '|';
    tweet_start = tweet_end + 1;
  }
  tweet_start = NULL;
  tweet_end = NULL;

  return tuple2_list;
}
Exemple #12
0
static int initialize(ErlNifEnv* env, ERL_NIF_TERM load_info)
{
#ifdef OPENSSL_THREADS
    ErlNifSysInfo sys_info;
#endif
    get_crypto_callbacks_t* funcp;
    struct crypto_callbacks* ccb;
    int nlocks = 0;
    int tpl_arity;
    const ERL_NIF_TERM* tpl_array;
    int vernum;
    ErlNifBinary lib_bin;
    char lib_buf[1000];
#ifdef HAVE_DYNAMIC_CRYPTO_LIB
    void *handle;
#endif

    if (!verify_lib_version())
	return __LINE__;

    /* load_info: {302, <<"/full/path/of/this/library">>,true|false} */
    if (!enif_get_tuple(env, load_info, &tpl_arity, &tpl_array))
        return __LINE__;
    if (tpl_arity != 3)
        return __LINE__;
    if (!enif_get_int(env, tpl_array[0], &vernum))
        return __LINE__;
    if (vernum != 302)
        return __LINE__;
    if (!enif_inspect_binary(env, tpl_array[1], &lib_bin))
        return __LINE__;

    if (!init_hmac_ctx(env)) {
	return __LINE__;
    }
    if (!init_hash_ctx(env)) {
        return __LINE__;
    }
    if (!init_cipher_ctx(env)) {
        return __LINE__;
    }
    if (!init_engine_ctx(env)) {
        return __LINE__;
    }

    if (library_initialized) {
	/* Repeated loading of this library (module upgrade).
	 * Atoms and callbacks are already set, we are done.
	 */
	return 0;
    }

    if (!init_atoms(env, tpl_array[2], load_info)) {
        return __LINE__;
    }

#ifdef HAVE_DYNAMIC_CRYPTO_LIB
    if (!change_basename(&lib_bin, lib_buf, sizeof(lib_buf), crypto_callback_name))
        return __LINE__;
    if ((handle = enif_dlopen(lib_buf, &error_handler, NULL)) == NULL)
        return __LINE__;
    if ((funcp = (get_crypto_callbacks_t*) enif_dlsym(handle, "get_crypto_callbacks",
                                                       &error_handler, NULL)) == NULL)
        return __LINE__;
#else /* !HAVE_DYNAMIC_CRYPTO_LIB */
    funcp = &get_crypto_callbacks;
#endif

#ifdef OPENSSL_THREADS
    enif_system_info(&sys_info, sizeof(sys_info));
    if (sys_info.scheduler_threads > 1) {
	nlocks = CRYPTO_num_locks();
    }
    /* else no need for locks */
#endif

    ccb = (*funcp)(nlocks);

    if (!ccb || ccb->sizeof_me != sizeof(*ccb)) {
	PRINTF_ERR0("Invalid 'crypto_callbacks'");
	return __LINE__;
    }

#ifdef HAS_CRYPTO_MEM_FUNCTIONS
    if (!CRYPTO_set_mem_functions(ccb->crypto_alloc, ccb->crypto_realloc, ccb->crypto_free))
        return __LINE__;
#endif

#ifdef OPENSSL_THREADS
    if (nlocks > 0) {
	CRYPTO_set_locking_callback(ccb->locking_function);
	CRYPTO_set_id_callback(ccb->id_function);
	CRYPTO_set_dynlock_create_callback(ccb->dyn_create_function);
	CRYPTO_set_dynlock_lock_callback(ccb->dyn_lock_function);
	CRYPTO_set_dynlock_destroy_callback(ccb->dyn_destroy_function);
    }
#endif /* OPENSSL_THREADS */

    init_digest_types(env);
    init_cipher_types(env);
    init_algorithms_types(env);

    library_initialized = 1;
    return 0;
}
Exemple #13
0
ERL_NIF_TERM
geef_index_add(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
	geef_index *index;
	const ERL_NIF_TERM *eentry;
	int arity;
	unsigned int tmp;
	ErlNifBinary path, id;
	git_index_entry entry;

	if (!enif_get_resource(env, argv[0], geef_index_type, (void **) &index))
		return enif_make_badarg(env);

	if (!enif_get_tuple(env, argv[1], &arity, &eentry))
		return enif_make_badarg(env);

	memset(&entry, 0, sizeof(entry));

	if (enif_compare(eentry[1], atoms.undefined) &&
	    !enif_get_int64(env, eentry[1], &entry.ctime.seconds))
		return enif_make_badarg(env);

	if (enif_compare(eentry[2], atoms.undefined) &&
	    !enif_get_int64(env, eentry[2], &entry.mtime.seconds))
		return enif_make_badarg(env);

	if (enif_compare(eentry[3], atoms.undefined) &&
	    !enif_get_uint(env, eentry[3], &entry.dev))
		return enif_make_badarg(env);

	if (enif_compare(eentry[4], atoms.undefined) &&
	    !enif_get_uint(env, eentry[4], &entry.ino))
		return enif_make_badarg(env);

	if (!enif_get_uint(env, eentry[5], &entry.mode))
		return enif_make_badarg(env);

	if (enif_compare(eentry[6], atoms.undefined) &&
	    !enif_get_uint(env, eentry[6], &entry.uid))
		return enif_make_badarg(env);

	if (enif_compare(eentry[7], atoms.undefined) &&
	    !enif_get_uint(env, eentry[7], &entry.gid))
		return enif_make_badarg(env);

	if (!enif_get_int64(env, eentry[8], &entry.file_size))
		return enif_make_badarg(env);

	/* [9] comes later */

	tmp = 0;
	if (enif_compare(eentry[10], atoms.undefined) &&
	    !enif_get_uint(env, eentry[10], &tmp))
		return enif_make_badarg(env);
	entry.flags = tmp;

	tmp = 0;
	if (enif_compare(eentry[11], atoms.undefined) &&
	    !enif_get_uint(env, eentry[11], &tmp))
		return enif_make_badarg(env);
	entry.flags_extended = tmp;

	if (!enif_inspect_iolist_as_binary(env, eentry[12], &path))
		return enif_make_badarg(env);

	if (!geef_terminate_binary(&path))
		return geef_oom(env);

	entry.path = (char *) path.data;

	if (!enif_inspect_binary(env, eentry[9], &id))
		return enif_make_badarg(env);

	git_oid_fromraw(&entry.id, id.data);

	if (git_index_add(index->index, &entry) < 0)
		return geef_error(env);

	return atoms.ok;
}
Exemple #14
0
// Feed scanner a binary data block
ERL_NIF_TERM yang_scan_next_token(ErlNifEnv* env, int argc,
				  const ERL_NIF_TERM argv[])
{
    yang_scanner_t* obj;
    token_t* t;
    uint8_t* ptr;
    uint8_t* ptr_end;
    ErlNifBinary bin;
    state_t state;

#define STATE(st) state_##st: case STATE_##st
#define GOTO(st)  state = STATE_##st; goto state_##st
#define SET_STATE(st) state = STATE_##st

    if (!enif_get_resource(env, argv[0], yang_scan_resource, (void**) &obj)) {
	DBG("argv[0] not a resource\r\n");
	return enif_make_badarg(env);
    }

    state = obj->state;

    if (argc == 2) {
	if (!enif_inspect_binary(env, argv[1], &bin)) {
	    DBG("argv[1] not a binary\r\n");
	    return enif_make_badarg(env);
	}
	ptr = bin.data;
	ptr_end = ptr + bin.size;
	// now scan the data and push tokens

	switch (state) {
	STATE(WSP_SLASH):
	    DBG("WSP_SLASH remain=%ld\r\n", ptr_end - ptr);
	    if (ptr >= ptr_end)
		goto out;
	    else {
		if (*ptr == '/')      { ptr++; GOTO(LINE_COMMENT); }
		else if (*ptr == '*') { ptr++; GOTO(BLOCK_COMMENT); }
		else {
		    obj->t_line = obj->line;
		    add_char('/', obj);
		    GOTO(WORD);
		}
	    }
	    SET_STATE(WSP);
	    // FALL THROUGH
	STATE(WSP):
	    DBG("WSP remain=%ld\r\n", ptr_end - ptr);
	    while(ptr < ptr_end) {
		int c = *ptr++;
		switch(c) {
		case '/': GOTO(WSP_SLASH); break;
		case ' ':  obj->column += 1; break;
		case '\t': obj->column += 8; break;
		case '\r': break;
		case '\n': obj->line += 1; obj->column = 1; break;
		case '\"':
		    obj->t_column = obj->column; // save column
		    obj->t_line   = obj->line;   // save start line
		    obj->t_skip   = false;
		    obj->column++;
		    GOTO(DQUOTE_STRING);
		case '\'':
		    obj->t_column = obj->column; // save column
		    obj->t_line   = obj->line;   // save start line
		    obj->column++;
		    GOTO(SQUOTE_STRING);
		case '{':
		case '}':
		case ';':
		    enq_char(obj, c);
		    break;
		default:
		    obj->t_line = obj->line;
		    add_char(c, obj);
		    GOTO(WORD);
		}
	    }
	    break;

	STATE(LINE_COMMENT):
	    DBG("LINE_COMMENT remain=%ld\r\n", ptr_end - ptr);
	    while(ptr < ptr_end) {
		int c = *ptr++;
		if (c == '\n') {
		    obj->line++;
		    obj->column = 1;
		    GOTO(WSP);
		}
	    }
	    break;

	STATE(BLOCK_COMMENT_STAR):
	    DBG("BLOCK_COMMENT_STAR remain=%ld\r\n", ptr_end - ptr);
	    if (ptr >= ptr_end)
		goto out;
	    else if (*ptr == '/') {
		ptr++; obj->column += 2; GOTO(WSP);
	    }
	    SET_STATE(BLOCK_COMMENT);
	    // FALL TROUGH
	STATE(BLOCK_COMMENT):
	    DBG("BLOCK_COMMENT remain=%ld\r\n", ptr_end - ptr);
	    while(ptr < ptr_end) {
		int c = *ptr++;
		if (c == '\n') {
		    obj->line++;
		    obj->column = 1;
		}
		else if (c == '*') {
		    GOTO(BLOCK_COMMENT_STAR);
		}
		else {
		    obj->column++;
		}
	    }
	    break;

	STATE(WORD_SLASH):
	    DBG("WORD_SLASH remain=%ld\r\n", ptr_end - ptr);
	    if (ptr >=  ptr_end)
		goto out;
	    else {
		if (*ptr == '/') {
		    enq_word(obj); ptr++; GOTO(LINE_COMMENT);
		}
		else if (*ptr == '*') {
		    enq_word(obj); ptr++; GOTO(BLOCK_COMMENT);
		}
		else {
		    add_char('/', obj);
		}
	    }
	    SET_STATE(WORD);
	    // FALL THROUGH
	STATE(WORD):
	    DBG("WORD remain=%ld\r\n", ptr_end - ptr);
	    while(ptr < ptr_end) {
		int c = *ptr++;
		switch(c) {
		case '/':  GOTO(WORD_SLASH);
		case ' ':  enq_word(obj); obj->column += 1; GOTO(WSP);
		case '\t': enq_word(obj); obj->column += 8; GOTO(WSP);
		case '\r': enq_word(obj); GOTO(WSP);
		case '\n': case ';': case '{': case '}':
		    enq_word(obj); ptr--; GOTO(WSP);
		default:
		    obj->column++;
		    add_char(c, obj);
		}
	    }
	    break;

	STATE(DQUOTE_STRING_BSLASH):
	    DBG("DQUOTE_STRING_BSLASH remain=%ld\r\n", ptr_end - ptr);
	    if (ptr >= ptr_end)
		goto out;
	    else {
		int c = *ptr++;
		switch(c) {
		case 'n':  add_char('\n', obj); break;
		case 't':  add_char('\t', obj); break;
		case '"':  add_char(c, obj); break;
		case '\\': add_char(c, obj); break;
		default:
		    add_char('\\', obj);
		    add_char(c, obj);
		    break;
		}
		obj->t_skip = false;
	    }
	    SET_STATE(DQUOTE_STRING);
	    // FALL THROUGH
	STATE(DQUOTE_STRING):
	    DBG("DQUOTE_STRING remain=%ld\r\n", ptr_end - ptr);
	    while(ptr < ptr_end) {
		int c = *ptr++;
		switch(c) {
		case '\\':
		    GOTO(DQUOTE_STRING_BSLASH);
		case '\"':
		    enq_string(obj);
		    obj->column++;
		    GOTO(WSP);
		case '\n':
		    trim_wsp(obj); // remove trailing wsp
		    obj->line++;
		    obj->column = 1;
		    obj->t_skip = true;
		    add_char(c, obj);
		    break;
		case ' ':
		    if (obj->t_skip && (obj->column <= obj->t_column))
			obj->column += 1;
		    else {
			add_char(' ', obj);
			obj->t_skip = false;
			obj->column += 1;
		    }
		    break;
		case '\t':
		    if (obj->t_skip && (obj->column <= obj->t_column))
			obj->column += 8;
		    else {
			add_char('\t', obj);
			obj->t_skip = false;
			obj->column += 8;
		    }
		    break;
		default:
		    add_char(c, obj);
		    obj->column += 1;
		    obj->t_skip = false;
		    break;
		}
	    }
	    break;

	STATE(SQUOTE_STRING):
	    DBG("SQUOTE_STRING remain=%ld\r\n", ptr_end - ptr);
	    while(ptr < ptr_end) {
		int c = *ptr++;
		switch(c) {
		case '\'':
		    enq_string(obj);
		    obj->column++;
		    GOTO(WSP);
		case '\n':
		    obj->line++;
		    obj->column = 1;
		    // FALL TROUGH
		default:
		    add_char(c, obj);
		    break;
		}
	    }
	    break;

	default:
	    DBG("STATE = %d,  remain=%ld\r\n", state, ptr_end - ptr);
	    return enif_make_badarg(env);
	}
    }

out:
    obj->state = state;

    t = deq_token(obj);
    if (t == NULL) {
	DBG("deq_token return NULL\r\n");
	return atm_more;
    }
    else {
	ERL_NIF_TERM r;
	r = make_token(env, t);
	release_token(env, t);
	return r;
    }
}
Exemple #15
0
static ERL_NIF_TERM binary_to_libyaml_event_stream_rev(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    ErlNifBinary bin;
    ERL_NIF_TERM tail;
    yaml_parser_t parser;
    yaml_event_t event;
    yaml_error_type_t error;
    int done = 0;
    char msg[200];

    if (!enif_inspect_binary(env, argv[0], &bin))
    {
        return enif_make_badarg(env);
    }

    tail = enif_make_list(env,0);

    /* Create the Parser object. */
    yaml_parser_initialize(&parser);

    yaml_parser_set_input_string(&parser, bin.data, bin.size);

    /* Read the event sequence. */
    while (!done) {

        /* Get the next event. */
        if (!yaml_parser_parse(&parser, &event))
            goto parser_error;

        // convert and add to list
        tail = enif_make_list_cell(env, event_to_term(env,&event), tail);

        /* Are we finished? */
        done = (event.type == YAML_STREAM_END_EVENT);

        /* The application is responsible for destroying the event object. */
        yaml_event_delete(&event);

    }

    /* Destroy the Parser object. */
    yaml_parser_delete(&parser);

    return enif_make_tuple2(env,
                            enif_make_atom(env, "ok"),
                            tail);

    /* On error. */
parser_error:
    memset(msg,0, sizeof(msg));

    error = parser.error;
    switch (error)
    {
    case YAML_MEMORY_ERROR:
        snprintf(msg, sizeof(msg), "Memory error: Not enough memory for parsing\n");
        break;

    case YAML_READER_ERROR:
        if (parser.problem_value != -1) {
            snprintf(msg, sizeof(msg), "Reader error: %s: #%X at %zu\n", parser.problem,
                     parser.problem_value, parser.problem_offset);
        }
        else {
            fprintf(stderr, "Reader error: %s at %zu\n", parser.problem,
                    parser.problem_offset);
        }
        break;

    case YAML_SCANNER_ERROR:
        if (parser.context) {
            snprintf(msg, sizeof(msg), "Scanner error: %s at line %zu, column %zu\n"
                     "%s at line %zu, column %zu\n", parser.context,
                     parser.context_mark.line+1, parser.context_mark.column+1,
                     parser.problem, parser.problem_mark.line+1,
                     parser.problem_mark.column+1);
        }
        else {
            snprintf(msg, sizeof(msg), "Scanner error: %s at line %zu, column %zu\n",
                     parser.problem, parser.problem_mark.line+1,
                     parser.problem_mark.column+1);
        }
        break;

    case YAML_PARSER_ERROR:
        if (parser.context) {
            snprintf(msg, sizeof(msg), "Parser error: %s at line %zu, column %zu\n"
                     "%s at line %zu, column %zu\n", parser.context,
                     parser.context_mark.line+1, parser.context_mark.column+1,
                     parser.problem, parser.problem_mark.line+1,
                     parser.problem_mark.column+1);
        }
        else {
            snprintf(msg, sizeof(msg), "Parser error: %s at line %zu, column %zu\n",
                     parser.problem, parser.problem_mark.line+1,
                     parser.problem_mark.column+1);
        }
        break;
    default:
    	break;
    }



    /* Destroy the Parser object. */
    yaml_parser_delete(&parser);

    return enif_make_tuple2(env,
                            enif_make_atom(env, "error"),
                            enif_make_tuple2(env,
                                             enum_to_atom(env, error, error_type_atoms),
                                             cstr_to_binary(env,msg)));

}
Exemple #16
0
    static ERL_NIF_TERM
nif_sendmsg(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
    int sockfd = -1;
    int flags = 0;

    ssize_t n = 0;

    ErlNifBinary buf = {0};
    ErlNifBinary sa = {0};

    ERL_NIF_TERM cdata_list, head, tail;

    char *cdata = NULL;
    struct iovec iov[1];
    struct msghdr message;
    struct cmsghdr *cmsg;
    size_t cdata_size = 0;

    if (!enif_get_int(env, argv[0], &sockfd))
        return enif_make_badarg(env);

    if (!enif_inspect_binary(env, argv[1], &buf))
        return enif_make_badarg(env);

    if (!enif_get_int(env, argv[2], &flags))
        return enif_make_badarg(env);

    if (!enif_is_list(env, argv[3]))
        return enif_make_badarg(env);

    if (!enif_inspect_binary(env, argv[4], &sa))
        return enif_make_badarg(env);

    cdata_list = argv[3];

    // figure out how much control data we'll need to send
    while(enif_get_list_cell(env, cdata_list, &head, &tail)) {
        const ERL_NIF_TERM* fields;
        int arity;
        int level, type;
        ErlNifBinary cdata_field = {0};
        if (!enif_get_tuple(env, head, &arity, &fields) || arity != 3) {
            return enif_make_badarg(env);
        }

        if (!enif_get_int(env, fields[0], &level)) {
            return enif_make_badarg(env);
        }

        if (!enif_get_int(env, fields[1], &type)) {
            return enif_make_badarg(env);
        }

        if (!enif_inspect_binary(env, fields[2], &cdata_field)) {
            return enif_make_badarg(env);
        }

        cdata_size += CMSG_SPACE(cdata_field.size);

        cdata_list = tail;
    }

    if (cdata_size > 0) {
        // allocate enough control data space, if any
        // freebsd throws einval if the cdata length is 0
        // but the pointer isn't NULL
        if (!(cdata = malloc(cdata_size))) {
            return error_tuple(env, ENOMEM);
        }
    }

    // set up the iov and msghdr stuff
    iov[0].iov_base=(buf.size == 0 ? NULL : buf.data);
    iov[0].iov_len=buf.size;

    message.msg_name=(sa.size == 0 ? NULL : sa.data);
    message.msg_namelen=sa.size;
    message.msg_iov=iov;
    message.msg_iovlen=1;
    message.msg_control=cdata;
    message.msg_controllen=cdata_size;


    // loop over the control data again, this time filling in the data in the
    // msghdr
    cdata_list = argv[3];

    cmsg = CMSG_FIRSTHDR(&message);

    while(cmsg && enif_get_list_cell(env, cdata_list, &head, &tail)) {
        const ERL_NIF_TERM* fields;
        int arity;
        unsigned char *cmsg_data;
        ErlNifBinary cdata_field = {0};
        // don't need to check here, we'd have crashed in the last loop if
        // things were wrong
        enif_get_tuple(env, head, &arity, &fields);
        enif_get_int(env, fields[0], &cmsg->cmsg_level);
        enif_get_int(env, fields[1], &cmsg->cmsg_type);
        enif_inspect_binary(env, fields[2], &cdata_field);
        cmsg_data = CMSG_DATA(cmsg);
        // copy the control data into the cdata struct
        memcpy(cmsg_data, cdata_field.data, cdata_field.size);

        // set the length
        cmsg->cmsg_len=CMSG_LEN(cdata_field.size);

        cdata_list = tail;
        cmsg = CMSG_NXTHDR(&message,cmsg);
    }

    n = sendmsg(sockfd, &message, flags);

    if (n < 0)
        return error_tuple(env, errno);

    return enif_make_tuple2(env, atom_ok, enif_make_int64(env, n));
}
static ERL_NIF_TERM
mpegts_decode(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
  ErlNifBinary bin;
  Mpegts *ts;
  int eof = 0;
  if(argc != 2) return enif_make_badarg(env);

  char eof_str[10];


  if(!enif_inspect_binary(env, argv[0], &bin)) {
    if(!enif_get_atom(env, argv[0], eof_str, sizeof(eof_str), ERL_NIF_LATIN1)) return enif_make_badarg(env);
    if(!strcmp(eof_str, "eof")) eof = 1;
  }

  if(eof) return enif_make_tuple3(env, enif_make_atom(env, "ok"), argv[1], enif_make_list(env, 0));


  if(!enif_get_resource(env, argv[1], MpegtsResource, (void **)&ts)) {
    return enif_make_badarg(env); 
  }


  // fprintf(stderr, "Decode %d bytes, %d in buffer, %d going to leave \r\n", (int)bin.size, ts->last_ts_size, (bin.size - ts->last_ts_size) % 188);

  uint8_t *pkt = bin.data;
  uint32_t size = bin.size;
  if(ts->last_ts_size > 0) {
    if(ts->last_ts_size + size < TS_BUFFERED) {
      memcpy(ts->last_ts + ts->last_ts_size, pkt, size);
      ts->last_ts_size += bin.size;
      size = 0;
    } else {
      uint32_t size1 = TS_BUFFERED - ts->last_ts_size;
      memcpy(ts->last_ts + ts->last_ts_size, pkt, size1);
      pkt += size1;
      size -= size1;
      ts->last_ts_size += size1;
      size1 = 0;
      while(size1 <= ts->last_ts_size - 188) {
        handle_ts(ts, ts->last_ts+size1);
        size1 += 188;
      }
      ts->last_ts_size = 0;
    }
  }


  while(size >= TS_BUFFERED) {
    while(size >= TS_BUFFERED && (pkt[0] != 0x47 || pkt[188] != 0x47 || pkt[2*188] != 0x47)) {
      pkt++;
      size--;
    }
    if(size >= TS_BUFFERED) {
      handle_ts(ts, pkt);
      pkt+=188;
      size-=188;
    }
  }

  if(size > 0) {
    assert(size <= TS_BUFFERED);
    ts->last_ts_size = size;
    memcpy(ts->last_ts, pkt, ts->last_ts_size);
  }
  return enif_make_tuple3(env, enif_make_atom(env, "ok"), argv[1], enif_make_list(env, 0));
}
Exemple #18
0
static inline int
enc_string(Encoder* e, ERL_NIF_TERM val)
{
    ErlNifBinary bin;
    char atom[512];

    unsigned char* data;
    size_t size;

    int esc_extra = 0;
    int ulen;
    int uval;
    int i;

    if(enif_is_binary(e->env, val)) {
        if(!enif_inspect_binary(e->env, val, &bin)) {
            return 0;
        }
        data = bin.data;
        size = bin.size;
    } else if(enif_is_atom(e->env, val)) {
        if(!enif_get_atom(e->env, val, atom, 512, ERL_NIF_LATIN1)) {
            return 0;
        }
        data = (unsigned char*) atom;
        size = strlen(atom);
    } else {
        return 0;
    }

    i = 0;
    while(i < size) {
        switch((char) data[i]) {
            case '\"':
            case '\\':
            case '/':
            case '\b':
            case '\f':
            case '\n':
            case '\r':
            case '\t':
                esc_extra += 1;
                i++;
                continue;
            default:
                if(data[i] < 0x20) {
                    esc_extra += 5;
                    i++;
                    continue;
                } else if(data[i] < 0x80) {
                    i++;
                    continue;
                }
                ulen = utf8_validate(&(data[i]), size - i);
                if(ulen < 0) {
                    return 0;
                }
                if(e->uescape) {
                    uval = utf8_to_unicode(&(data[i]), ulen);
                    if(uval < 0) {
                        return 0;
                    }
                    ulen = utf8_esc_len(uval);
                    if(ulen < 0) {
                        return 0;
                    }
                }
                i += ulen;
        }
    }

    if(!enc_ensure(e, size + esc_extra + 2)) {
        return 0;
    }

    e->p[e->i++] = '\"';

    i = 0;
    while(i < size) {
        switch((char) data[i]) {
            case '\"':
            case '\\':
            case '/':
                e->p[e->i++] = '\\';
                e->u[e->i++] = data[i];
                i++;
                continue;
            case '\b':
                e->p[e->i++] = '\\';
                e->p[e->i++] = 'b';
                i++;
                continue;
            case '\f':
                e->p[e->i++] = '\\';
                e->p[e->i++] = 'f';
                i++;
                continue;
            case '\n':
                e->p[e->i++] = '\\';
                e->p[e->i++] = 'n';
                i++;
                continue;
            case '\r':
                e->p[e->i++] = '\\';
                e->p[e->i++] = 'r';
                i++;
                continue;
            case '\t':
                e->p[e->i++] = '\\';
                e->p[e->i++] = 't';
                i++;
                continue;
            default:
                if(data[i] < 0x20) {
                    ulen = unicode_uescape(data[i], &(e->p[e->i]));
                    if(ulen < 0) {
                        return 0;
                    }
                    e->i += ulen;
                    i++;
                } else if((data[i] & 0x80) && e->uescape) {
                    uval = utf8_to_unicode(&(data[i]), size-i);
                    if(uval < 0) {
                        return 0;
                    }
                    
                    ulen = unicode_uescape(uval, &(e->p[e->i]));
                    if(ulen < 0) {
                        return 0;
                    }
                    e->i += ulen;
                    
                    ulen = utf8_len(uval);
                    if(ulen < 0) {
                        return 0;
                    }
                    i += ulen;
                } else {
                    e->u[e->i++] = data[i++];
                }
        }
    }

    e->p[e->i++] = '\"';
    e->count++;

    return 1;
}
ERL_NIF_TERM nif_test_from_file(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {

  char tweets_buffer[MAX_LIST_BUFFER_LEN];
  memset(tweets_buffer, 0, MAX_LIST_BUFFER_LEN);

  int out_length = 0;
  if (argc != 1) {
#ifndef SENTIMENT_DEBUG
     return enif_make_atom(env, "error"); 
#else
     return enif_make_atom(env, "error_invalid_argc"); 
#endif
  } else {
    char file_name_str[MAX_NAME_LEN];
    memset(file_name_str, 0, MAX_NAME_LEN);
    ErlNifBinary file_name;

    if (enif_inspect_binary(env, argv[0], &file_name)) {
      memcpy(file_name_str, file_name.data, file_name.size);
      file_name_str[file_name.size] = '\0';
#ifdef ERLANG_R14B02 
      enif_release_binary(&file_name);
#else
      enif_release_binary(env, &file_name);
#endif
    }   else {
#ifdef ERLANG_R14B02 
      enif_release_binary(&file_name);
#else
      enif_release_binary(env, &file_name);
#endif
#ifndef SENTIMENT_DEBUG
      return enif_make_atom(env, "error");
#else
      return enif_make_atom(env, "error_file_name");
#endif
    }

    if (GetTestTweetsFromFile(file_name_str, MAX_LIST_BUFFER_LEN, tweets_buffer, &out_length) < 0) {
#ifndef SENTIMENT_DEBUG
      return enif_make_atom(env, "error");
#else
      return enif_make_atom(env, "error_get_test_tweets_for_user");
#endif
    }
  }

  if (0 == out_length || out_length > MAX_LIST_BUFFER_LEN) {
#ifndef SENTIMENT_DEBUG
    return enif_make_atom(env, "error");
#else
    return enif_make_atom(env, "error_out_length");
#endif
  }

  ErlNifBinary tweet;
  char *tweet_start = tweets_buffer;
  char *tweet_end = strstr(tweet_start, "|");
  int ret_val = 0;
  unsigned int i = 0;
  unsigned int tweet_len = 0;
  ERL_NIF_TERM arg_array[1]; 
  ERL_NIF_TERM tuple6;
  ERL_NIF_TERM tuple6_list = enif_make_list(env, 0);
  unsigned int error_count = 0;

  while (tweet_start && tweet_end && *tweet_end != '\0') {

    tweet_end = strstr(tweet_start, "|");
    if (!tweet_end)
      break;
    *tweet_end = '\0';
    tweet_len = tweet_end - tweet_start;

    if (tweet_len <= 0 || tweet_len >= MAX_BUFFER_LEN) {
#ifndef SENTIMENT_DEBUG
      return enif_make_atom(env, "error");
#else
      return enif_make_atom(env, "error_out_length");
#endif
    }

#ifdef ERLANG_R14B02
    ret_val = enif_alloc_binary(tweet_len, &tweet);
#else
    ret_val = enif_alloc_binary(env, tweet_len, &tweet);
#endif

    if (ret_val < 0) {
#ifndef SENTIMENT_DEBUG
      return enif_make_atom(env, "error");
#else
      return enif_make_atom(env, "error_tweet_len");
#endif
    }
    for (i=0; i<tweet_len; i++) {
      tweet.data[i] = *(tweet_start + i);
    }

    arg_array[0] = enif_make_binary(env, &tweet);
    tuple6 = nif_get_sentiment(env, 1, arg_array);
    if (enif_is_atom(env, tuple6)) {
      error_count++;
    } else {
      tuple6_list = enif_make_list_cell(env, tuple6, tuple6_list);
    }
    *tweet_end = '|';
    tweet_start = tweet_end + 1;
  }
  tweet_start = NULL;
  tweet_end = NULL;

  return tuple6_list;
}
Exemple #20
0
ERL_NIF_TERM blake2sp_hash(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
	uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];
	blake2s_state S[PARALLELISM_DEGREE][1];
	blake2s_state FS[1];
	ErlNifBinary input, key, salt, personal;
	uint8_t out[BLAKE2S_OUTBYTES] = {0};
	unsigned int outlen;
	int i;
	ERL_NIF_TERM tmphash[BLAKE2S_OUTBYTES];

	if (argc != 5 || !enif_inspect_binary(env, argv[0], &input) ||
			!enif_inspect_binary(env, argv[1], &key) ||
			!enif_get_uint(env, argv[2], &outlen) ||
			!enif_inspect_binary(env, argv[3], &salt) ||
			!enif_inspect_binary(env, argv[4], &personal))
		return enif_make_badarg(env);

	if (!outlen || outlen > BLAKE2S_OUTBYTES) return -1;
	if( key.size > BLAKE2S_KEYBYTES ) return -1;

	for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
		if( blake2sp_init_leaf( S[i], outlen, key.size, i, salt.data,
					personal.data, salt.size, personal.size) < 0 )
			return -1;

	S[PARALLELISM_DEGREE - 1]->last_node = 1; // mark last node

	if( key.size > 0 )
	{
		uint8_t block[BLAKE2S_BLOCKBYTES];
		memset( block, 0, BLAKE2S_BLOCKBYTES );
		memcpy( block, key.data, key.size );

		for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
			blake2s_update( S[i], block, BLAKE2S_BLOCKBYTES );

		secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
	}

#if defined(_OPENMP)
#pragma omp parallel shared(S,hash), num_threads(PARALLELISM_DEGREE)
#else

	for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )
#endif
	{
#if defined(_OPENMP)
		size_t      id__ = omp_get_thread_num();
#endif
		uint64_t inlen__ = input.size;
		const uint8_t *in__ = ( const uint8_t * )input.data;
		in__ += id__ * BLAKE2S_BLOCKBYTES;

		while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES )
		{
			blake2s_update( S[id__], in__, BLAKE2S_BLOCKBYTES );
			in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
			inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
		}

		if( inlen__ > id__ * BLAKE2S_BLOCKBYTES )
		{
			const size_t left = inlen__ - id__ * BLAKE2S_BLOCKBYTES;
			const size_t len = left <= BLAKE2S_BLOCKBYTES ? left : BLAKE2S_BLOCKBYTES;
			blake2s_update( S[id__], in__, len );
		}

		blake2s_final( S[id__], hash[id__], BLAKE2S_OUTBYTES );
	}

	if( blake2sp_init_root( FS, outlen, key.size, salt.data, personal.data, salt.size, personal.size) < 0 )
		return -1;

	FS->last_node = 1; // Mark as last node

	for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
		blake2s_update( FS, hash[i], BLAKE2S_OUTBYTES );

	blake2s_final( FS, out, outlen );;

	for (i = 0; i < outlen; i++) {
		tmphash[i] = enif_make_uint(env, out[i]);
	}

	return enif_make_list_from_array(env, tmphash, outlen);
}
ERL_NIF_TERM nif_get_sentiment(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {

  if (argc != 1) {
#ifndef SENTIMENT_DEBUG
    return enif_make_atom(env, "error");
#else
    return enif_make_atom(env, "error_invalid_argc");
#endif
  }

  ErlNifBinary text;
  unsigned char text_str[MAX_BUFFER_LEN];
  unsigned int text_buffer_len = MAX_BUFFER_LEN;
  memset(text_str, 0, MAX_BUFFER_LEN);

  bool success = enif_inspect_binary(env, argv[0], &text);
  int text_len = text.size;
  if (success && text_len > 1 && text_len < MAX_BUFFER_LEN) {
    memcpy(text_str, text.data, text_len);
    text_str[text_len] = '\0';
#ifdef ERLANG_R14B02 
    enif_release_binary(&text);
#else
    enif_release_binary(env, &text);
#endif
  } else {
#ifdef ERLANG_R14B02 
    enif_release_binary(&text);
#else
    enif_release_binary(env, &text);
#endif
#ifndef SENTIMENT_DEBUG
    return enif_make_atom(env, "error");
#else
    return enif_make_atom(env, "error_invalid_tweet_len");
#endif
  }

  char safe_status[10];
  memset(safe_status, 0, 10);
  char script[4];
  memset(script, 0, 4);
  int sentiment_valence = 0;

  int ret_value = 0;
  if ((ret_value = GetSentiment((unsigned char *) text_str, text_buffer_len, text_len,
                                (char *) safe_status, 10,
                                (char *) script, 4,
                                &sentiment_valence)) < 0) {
#ifndef SENTIMENT_DEBUG
    return enif_make_atom(env, "error");
#else
    return enif_make_atom(env, "error_GetSentiment");
#endif
  }

  unsigned int len = 0;
  unsigned int i = 0;
  int ret_val = 0;
  ErlNifBinary safe_status_bin;
  ErlNifBinary script_bin;
  ERL_NIF_TERM safe_status_term; 
  ERL_NIF_TERM script_term; 

  len = strlen(safe_status);
  if (len < 4 || len > 6) {
    strcpy(safe_status, "ERROR");
    len = 5;
  }
#ifdef ERLANG_R14B02 
  ret_val = enif_alloc_binary(len, &safe_status_bin);
#else
  ret_val = enif_alloc_binary(env, len, &safe_status_bin);
#endif
  if (ret_val < 0) {
#ifndef SENTIMENT_DEBUG
    return enif_make_atom(env, "error");
#else
    return enif_make_atom(env, "error_safe_status_bin_alloc");
#endif
  }
  for (i=0; i<len; i++) {
    safe_status_bin.data[i] = *(safe_status + i);
  }
  safe_status_term = enif_make_binary(env, &safe_status_bin);

  len = strlen(script);
  if (len != 2 && len != 3) {
    strcpy(script, "00");
    len = 2;
  }
#ifdef ERLANG_R14B02 
  ret_val = enif_alloc_binary(len, &script_bin);
#else
  ret_val = enif_alloc_binary(env, len, &script_bin);
#endif
  if (ret_val < 0) {
#ifndef SENTIMENT_DEBUG
    return enif_make_atom(env, "error");
#else
    return enif_make_atom(env, "error_script_bin_alloc");
#endif
  }
  for (i=0; i<len; i++) {
    script_bin.data[i] = *(script + i);
  }
  script_term = enif_make_binary(env, &script_bin);

  ERL_NIF_TERM sentiment_term;
  sentiment_term = enif_make_int(env, sentiment_valence);

  return enif_make_tuple3(env, safe_status_term, script_term, sentiment_term);

}
ERL_NIF_TERM nif_test_from_file(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {

  if (argc != 1) {
#ifndef TRENDS_DEBUG
    return enif_make_atom(env, "error");
#else
    return enif_make_atom(env, "error_invalid_argc");
#endif
  }

  ErlNifBinary file_path;

  char trends_file_path[MAX_NAME_LEN];
  bool success = enif_inspect_binary(env, argv[0], &file_path);
  if (success && (file_path.size < MAX_NAME_LEN)) {
    memcpy(trends_file_path, file_path.data, file_path.size);
    trends_file_path[file_path.size] = '\0';
#ifdef ERLANG_R14B02 
    enif_release_binary(&file_path);
#else
    enif_release_binary(env, &file_path);
#endif
  } else {
#ifdef ERLANG_R14B02 
    enif_release_binary(&file_path);
#else
    enif_release_binary(env, &file_path);
#endif
#ifndef TRENDS_DEBUG
    return enif_make_atom(env, "error");
#else
    return enif_make_atom(env, "error_trends_file_path_inspect_bin");
#endif
  }

  unsigned char trends_buffer[MAX_LIST_BUFFER_LEN];
  unsigned int trends_len = 0;
  unsigned int trends_count = 0;
  if (GetTestTrendsFromFile(trends_file_path,
                    trends_buffer, MAX_LIST_BUFFER_LEN,
                    &trends_len, &trends_count) < 0) {
#ifndef TRENDS_DEBUG
    return enif_make_atom(env, "error");
#else
    return enif_make_atom(env, "error_get_test_trends_failed");
#endif
  }

  if (trends_len <= 0 || trends_len >= MAX_LIST_BUFFER_LEN) {
#ifndef TRENDS_DEBUG
    return enif_make_atom(env, "error");
#else
    return enif_make_atom(env, "error_invalid_trends_len");
#endif
  }

  ErlNifBinary trends_bin;
  int ret_val = 0;
#ifdef ERLANG_R14B02
  ret_val = enif_alloc_binary(trends_len, &trends_bin);
#else
  ret_val = enif_alloc_binary(env, trends_len, &trends_bin);
#endif

  if (ret_val < 0) {
#ifndef TRENDS_DEBUG
    return enif_make_atom(env, "error");
#else
    return enif_make_atom(env, "error_tweet_len");
#endif
  }
  unsigned int i=0;
  for (i=0; i<trends_len; i++) {
    trends_bin.data[i] = *(trends_buffer + i);
  }

  ERL_NIF_TERM arg_array[1];
  arg_array[0] = enif_make_binary(env, &trends_bin);
  ERL_NIF_TERM trends_list = nif_get_trends(env, 1, arg_array);
  if (enif_is_atom(env, trends_list)) {
#ifndef TRENDS_DEBUG
    return enif_make_atom(env, "error");
#else
    return enif_make_atom(env, "error_get_trends_failed");
#endif
  }

  return trends_list; 
}
Exemple #23
0
static
int exmagick_get_utf8str (ErlNifEnv *env, const ERL_NIF_TERM arg, ErlNifBinary *utf8)
{ return(enif_inspect_binary(env, arg, utf8)); }
Exemple #24
0
ERL_NIF_TERM
final_encode(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    ERL_NIF_TERM head = argv[0];
    ERL_NIF_TERM term;
    double number;
    encode_ctx ctx;

    ctx.env = env;
    ctx.fill_offset = 0;
    ctx.error = 0;

    if (!enif_alloc_binary_compat(env, 100, &ctx.bin)) {
            return no_mem_error(env);
    }

    while(enif_get_list_cell(env, head, &term, &head)) {
        ErlNifBinary termbin;
        const ERL_NIF_TERM* array;
        int arity;
        int code;

        // We scan the list, looking for things to write into the binary, or
        // encode and then write into the binary. We encode values that are
        // tuples tagged with a type and a value: {Type, Value} where Type
        // is a an Integer and Value is what is to be encoded

        if (enif_get_tuple(env, term, &arity, &array)) {
            // It's a tuple to encode and copy
            if (arity != 2 || !enif_get_int(env, array[0], &code)) {
                // not arity 2 or the first element isn't an int
                ctx.error = BADARG;
                goto done;
            }
            if (code == 0) {
                // {0, String}
                if (encode_string(&ctx, array[1]) != SUCCESS) {
                    goto done;
                }
            }
            else {
                // {1, Double}
                if(!enif_get_double(env, array[1], &number)) {
                    ctx.error = BADARG;
                    goto done;
                }
                // We can't encode these.
                if (isnan(number) || isinf(number)) {
                    ctx.error = BADARG;
                    goto done;
                }
                if ((ctx.error = ensure_buffer(&ctx, 32)) != SUCCESS) {
                    goto done;
                }
                // write the string into the buffer
                snprintf((char*)ctx.bin.data+ctx.fill_offset, 32,
                        "%.16g", number);
                // increment the length
                ctx.fill_offset += strlen((char*)ctx.bin.data+ctx.fill_offset);
            }
        } else if (enif_inspect_binary(env, term, &termbin)) {
            // this is a regular binary, copy the contents into the buffer
            fill_buffer(&ctx, (char*)termbin.data, termbin.size);
            if (ctx.error) {
                goto done;
            }
        }
        else {
            //not a binary, not a tuple, wtf!
            ctx.error = BADARG;
            goto done;
        }
    }
done:
    if (ctx.error == NOMEM) {
        enif_release_binary_compat(env, &ctx.bin);
        return no_mem_error(env);
    } else if (ctx.error == BADARG) {
        enif_release_binary_compat(env, &ctx.bin);
        return enif_make_badarg(env);
    }

    // Resize the binary to our exact final size
    if(!enif_realloc_binary_compat(env, &(ctx.bin), ctx.fill_offset)) {
        enif_release_binary_compat(env, &ctx.bin);
        return no_mem_error(env);
    }
    // make the binary term which transfers ownership
    return enif_make_binary(env, &ctx.bin);
}
Exemple #25
0
static ERL_NIF_TERM
nif_scheduler_launchTasks(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    unsigned int length ;
    ErlNifBinary offerId_binary;
    ErlNifBinary filters_binary;

    state_ptr state = (state_ptr) enif_priv_data(env);
    
    if(state->initilised == 0 ) 
    {
        return enif_make_tuple2(env, 
            enif_make_atom(env, "state_error"), 
            enif_make_atom(env, "scheduler_not_inited"));
    }

    if (!enif_inspect_binary(env, argv[0], &offerId_binary)) 
    {
        return enif_make_tuple3(env, 
                    enif_make_atom(env, "argument_error"), 
                    enif_make_atom(env, "invalid_or_corrupted_parameter"),
                    enif_make_atom(env, "offer_id"));
    }
    
    if(!enif_is_list(env, argv[1])) 
    {
        return enif_make_tuple3(env, 
                    enif_make_atom(env, "argument_error"), 
                    enif_make_atom(env, "invalid_or_corrupted_parameter"),
                    enif_make_atom(env, "task_info_array"));
    };

    if(!enif_get_list_length(env, argv[1], &length))
    {
        return enif_make_tuple3(env, 
                    enif_make_atom(env, "argument_error"), 
                    enif_make_atom(env, "invalid_or_corrupted_parameter"),
                    enif_make_atom(env, "task_info_array"));

    }
    
    ErlNifBinary task_info_binary_arr[length];

    if(!inspect_array_of_binary_objects(env, argv[1], &task_info_binary_arr ))
    {
        return enif_make_tuple3(env, 
                    enif_make_atom(env, "argument_error"), 
                    enif_make_atom(env, "invalid_or_corrupted_parameter"),
                    enif_make_atom(env, "task_info_array"));
    }   

    if (!enif_inspect_binary(env, argv[2], &filters_binary)) 
    {
        return enif_make_tuple3(env, 
                    enif_make_atom(env, "argument_error"), 
                    enif_make_atom(env, "invalid_or_corrupted_parameter"),
                    enif_make_atom(env, "filters"));
    }

    BinaryNifArray binaryNifArrayHolder ;
    binaryNifArrayHolder.length = length;
    binaryNifArrayHolder.obj = &task_info_binary_arr[0];

    SchedulerDriverStatus status = scheduler_launchTasks(state->scheduler_state, &offerId_binary, &binaryNifArrayHolder, &filters_binary);
    return get_return_value_from_status(env, status);
}
Exemple #26
0
ERL_NIF_TERM
make_encoder_resource_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]){
  unsigned rs_len, fs_len, bin_sz;
  enif_get_uint(env, argv[0], &rs_len);
  enif_get_uint(env, argv[1], &fs_len);
  enif_get_uint(env, argv[4], &bin_sz);
  PrivData* priv = (PrivData*)enif_priv_data(env);
  unsigned resource_sz = enc_resource_size(rs_len, fs_len);
  EncEntry *enc_entry = (EncEntry*)enif_alloc_resource(priv->encoder_RSTYPE, resource_sz);
  //memset(enc_entry, 0, resource_sz);
  enc_entry->records_cnt = rs_len;
  enc_entry->fields_cnt = fs_len;
  if(!enif_alloc_binary(bin_sz + 1, &enc_entry->bin))
    goto error;
  //memset(enc_entry->bin.data, 0, bin_sz + 1);
  ErlNifBinary ebin;
  enif_inspect_binary(env, argv[5], &ebin);
  memcpy(enc_entry->bin.data, ebin.data , ebin.size);

  ERL_NIF_TERM list, head, tail;
  list = argv[2];
  int i = 0;
  while(enif_get_list_cell(env, list, &head, &tail)){
    const ERL_NIF_TERM *tuple;
    int arity;
    unsigned ip;
    enif_get_tuple(env, head, &arity, &tuple);
    EncRecord *records = enc_records_base(enc_entry);
    records[i].tag = tuple[0];
    enif_get_uint(env, tuple[1], &ip);
    records[i].fds_offset = ip;
    enif_get_uint(env, tuple[2], &ip);
    records[i].arity = ip;
    i++;
    list = tail;
  }

  list = argv[3];
  i = 0;
  while(enif_get_list_cell(env, list, &head, &tail)){
    const ERL_NIF_TERM *tuple;
    int arity;
    unsigned ip;
    enif_get_tuple(env, head, &arity, &tuple);
    EncField *fields = enc_fields_base(enc_entry);
    enif_get_uint(env, tuple[0], &ip);
    fields[i].offset = ip;
    enif_get_uint(env, tuple[1], &ip);
    fields[i].size = ip;
    i++;
    list = tail;
  }

  list = argv[6];
  if(!enif_get_list_length(env, list, &(enc_entry->ignored_len)))
    goto error;
  enc_entry->ignored = (ERL_NIF_TERM*)enif_alloc(enc_entry->ignored_len*sizeof(ERL_NIF_TERM));
  i = 0;
  while(enif_get_list_cell(env, list, &head, &tail)){
    // ignored term should be atoms
    if(enif_is_atom(env, head)){
      enc_entry->ignored[i] = head;
    }else{
      enif_free(enc_entry->ignored);
      goto error;
    }
    i++;
    list = tail;
  }
  ERL_NIF_TERM ret = enif_make_resource(env, (void *)enc_entry);
  enif_release_resource(enc_entry);
  return ret;
 error:
  enif_release_resource(enc_entry);
  return enif_make_badarg(env);
}
Exemple #27
0
int
less_ejson(int depth, couch_ejson_ctx_t* ctx, ERL_NIF_TERM a, ERL_NIF_TERM b)
{
    int aIsAtom, bIsAtom;
    int aIsBin, bIsBin;
    int aIsNumber, bIsNumber;
    int aIsList, bIsList;
    int aArity, bArity;
    const ERL_NIF_TERM *aProps, *bProps;

    /*
     * Avoid too much recursion. Normally there isn't more than a few levels
     * of recursion, as in practice view keys do not go beyond 1 to 3 levels
     * of nesting. In case of too much recursion, signal it to the Erlang land
     * via an exception and do the EJSON comparison in Erlang land.
     */
    if (depth > MAX_DEPTH) {
        ctx->error = 1;
        return 0;
    }

    aIsAtom = enif_is_atom(ctx->env, a);
    bIsAtom = enif_is_atom(ctx->env, b);

    if (aIsAtom) {
        if (bIsAtom) {
            int aSortOrd, bSortOrd;

            if ((aSortOrd = atom_sort_order(ctx->env, a)) == -1) {
                ctx->error = 1;
                return 0;
            }

            if ((bSortOrd = atom_sort_order(ctx->env, b)) == -1) {
                ctx->error = 1;
                return 0;
            }

            return aSortOrd - bSortOrd;
        }

        return -1;
    }

    if (bIsAtom) {
        return 1;
    }

    aIsNumber = term_is_number(ctx->env, a);
    bIsNumber = term_is_number(ctx->env, b);

    if (aIsNumber) {
        if (bIsNumber) {
            return enif_compare_compat(ctx->env, a, b);
        }

        return -1;
    }

    if (bIsNumber) {
        return 1;
    }

    aIsBin = enif_is_binary(ctx->env, a);
    bIsBin = enif_is_binary(ctx->env, b);

    if (aIsBin) {
        if (bIsBin) {
            ErlNifBinary binA, binB;

            enif_inspect_binary(ctx->env, a, &binA);
            enif_inspect_binary(ctx->env, b, &binB);

            return compare_strings(ctx, binA, binB);
        }

        return -1;
    }

    if (bIsBin) {
        return 1;
    }

    aIsList = enif_is_list(ctx->env, a);
    bIsList = enif_is_list(ctx->env, b);

    if (aIsList) {
        if (bIsList) {
            return compare_lists(depth, ctx, a, b);
        }

        return -1;
    }

    if (bIsList) {
        return 1;
    }

    if (!enif_get_tuple(ctx->env, a, &aArity, &aProps)) {
        ctx->error = 1;
        return 0;
    }
    if ((aArity != 1) || !enif_is_list(ctx->env, aProps[0])) {
        ctx->error = 1;
        return 0;
    }

    if (!enif_get_tuple(ctx->env, b, &bArity, &bProps)) {
        ctx->error = 1;
        return 0;
    }
    if ((bArity != 1) || !enif_is_list(ctx->env, bProps[0])) {
        ctx->error = 1;
        return 0;
    }

    return compare_props(depth, ctx, aProps[0], bProps[0]);
}