Exemple #1
0
ERL_NIF_TERM
decode_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    Decoder* d;
    jiffy_st* st = (jiffy_st*) enif_priv_data(env);
    ERL_NIF_TERM tmp_argv[5];
    ERL_NIF_TERM opts;
    ERL_NIF_TERM val;

    if(argc != 2) {
        return enif_make_badarg(env);
    }

    d = dec_new(env);
    if(d == NULL) {
        return make_error(st, env, "internal_error");
    }

    tmp_argv[0] = argv[0];
    tmp_argv[1] = enif_make_resource(env, d);
    tmp_argv[2] = st->atom_error;
    tmp_argv[3] = enif_make_list(env, 0);
    tmp_argv[4] = enif_make_list(env, 0);

    enif_release_resource(d);

    opts = argv[1];
    if(!enif_is_list(env, opts)) {
        return enif_make_badarg(env);
    }

    while(enif_get_list_cell(env, opts, &val, &opts)) {
        if(get_bytes_per_iter(env, val, &(d->bytes_per_red))) {
            continue;
        } else if(get_bytes_per_red(env, val, &(d->bytes_per_red))) {
            continue;
        } else if(enif_compare(val, d->atoms->atom_return_maps) == 0) {
#if MAP_TYPE_PRESENT
            d->return_maps = 1;
#else
            return enif_make_badarg(env);
#endif
        } else if(enif_compare(val, d->atoms->atom_return_trailer) == 0) {
            d->return_trailer = 1;
        } else if(enif_compare(val, d->atoms->atom_dedupe_keys) == 0) {
            d->dedupe_keys = 1;
        } else if(enif_compare(val, d->atoms->atom_use_nil) == 0) {
            d->null_term = d->atoms->atom_nil;
        } else if(get_null_term(env, val, &(d->null_term))) {
            continue;
        } else {
            return enif_make_badarg(env);
        }
    }

    return decode_iter(env, 5, tmp_argv);
}
Exemple #2
0
ERL_NIF_TERM
encode_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    jiffy_st* st = (jiffy_st*) enif_priv_data(env);
    Encoder* e;

    ERL_NIF_TERM opts;
    ERL_NIF_TERM val;
    ERL_NIF_TERM tmp_argv[3];

    if(argc != 2) {
        return enif_make_badarg(env);
    }

    e = enc_new(env);
    if(e == NULL) {
        return make_error(st, env, "internal_error");
    }

    tmp_argv[0] = enif_make_resource(env, e);
    tmp_argv[1] = enif_make_list(env, 1, argv[0]);
    tmp_argv[2] = enif_make_list(env, 0);

    enif_release_resource(e);

    opts = argv[1];
    if(!enif_is_list(env, opts)) {
        return enif_make_badarg(env);
    }

    while(enif_get_list_cell(env, opts, &val, &opts)) {
        if(enif_compare(val, e->atoms->atom_uescape) == 0) {
            e->uescape = 1;
        } else if(enif_compare(val, e->atoms->atom_pretty) == 0) {
            e->pretty = 1;
        } else if(enif_compare(val, e->atoms->atom_escape_forward_slashes) == 0) {
            e->escape_forward_slashes = 1;
        } else if(enif_compare(val, e->atoms->atom_use_nil) == 0) {
            e->use_nil = 1;
        } else if(enif_compare(val, e->atoms->atom_force_utf8) == 0) {
            // Ignore, handled in Erlang
        } else if(get_bytes_per_iter(env, val, &(e->bytes_per_red))) {
            continue;
        } else if(get_bytes_per_red(env, val, &(e->bytes_per_red))) {
            continue;
        } else {
            return enif_make_badarg(env);
        }
    }

    return encode_iter(env, 3, tmp_argv);
}
Exemple #3
0
static ERL_NIF_TERM compare(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{    
    if (argc != 2) {
	return enif_make_badarg(env);
    }
    return enif_make_int(env, enif_compare(argv[0],argv[1]));
}
Exemple #4
0
int
enc_init(Encoder* e, ErlNifEnv* env, ERL_NIF_TERM opts, ErlNifBinary* bin)
{
    ERL_NIF_TERM val;

    e->env = env;
    e->atoms = enif_priv_data(env);
    e->uescape = 0;
    e->pretty = 0;
    e->shiftcnt = 0;
    e->count = 0;

    if(!enif_is_list(env, opts)) {
        return 0;
    }

    while(enif_get_list_cell(env, opts, &val, &opts)) {
        if(enif_compare(val, e->atoms->atom_uescape) == 0) {
            e->uescape = 1;
        } else if(enif_compare(val, e->atoms->atom_pretty) == 0) {
            e->pretty = 1;
        } else if(enif_compare(val, e->atoms->atom_force_utf8) == 0) {
            // Ignore, handled in Erlang
        } else {
            return 0;
        }
    }

    e->iolen = 0;
    e->iolist = enif_make_list(env, 0);
    e->curr = bin;
    if(!enif_alloc_binary(BIN_INC_SIZE, e->curr)) {
        return 0;
    }

    memset(e->curr->data, 0, e->curr->size);

    e->p = (char*) e->curr->data;
    e->u = (unsigned char*) e->curr->data;
    e->i = 0;

    return 1;
}
Exemple #5
0
ERL_NIF_TERM 
decode(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
    cabala_st *st = (cabala_st*)enif_priv_data(env);
    ERL_NIF_TERM data, opts, out;
    decode_state ds;

    ErlNifBinary bin;
    bson_t *bson;

    /* init params */
    if(argc != 2) {
        return enif_make_badarg(env);
    }
    init_state(&ds, env, st);
    data = argv[0];
    opts = argv[1];

    /* parse decode options */
    while(enif_get_list_cell(env, opts, &out, &opts)) {
        if(enif_compare(out, st->atom_return_maps) == 0) {
            ds.return_maps = 1;
        } else {
            return enif_make_badarg(env);
        }
    }

    /* check data is bson */
    if(!enif_inspect_binary(env, data, &bin)) {
        return enif_make_badarg(env);
    }
    bson = bson_new_from_data(bin.data, bin.size);
    if(!bson) {
        return make_error(st, env, "badbson");
    }
    if(bson_empty(bson)) {
        bson_destroy(bson);
        return make_empty_document(env, ds.return_maps);
    }

    LOG("decode begin, return_maps: %d\r\n", ds.return_maps);

    if(!iter_bson(bson, &out, &ds)) {
        out = make_error(st, env, "internal_error");
    }
    bson_destroy(bson);
    return out;
}
static ERL_NIF_TERM
cmp(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    assert(argc == 2 && "cmp is a 2-arity function.");
    int c = enif_compare(argv[0], argv[1]);
    if(c < 0)
    {
        return mk_atom(env, "lesser");
    }
    else if(c == 0)
    {
        return mk_atom(env, "equal");
    }
    else
    {
        return mk_atom(env, "greater");
    }
}
/*-----------------------------------------------------------------------------------------------------------------------*/
static ERL_NIF_TERM get_parser(ErlNifEnv* env, ERL_NIF_TERM ref, ERL_NIF_TERM* pres, ParserRes** parser)
{
   ERL_NIF_TERM const* tuple = NULL;
   int32_t arity;
   if (!enif_get_tuple(env, ref, &arity, &tuple) || arity != 2)
   {
      return make_error(env, FIX_FAILED, "Wrong parser reference.");
   }
   if (enif_compare(tuple[0], parser_atom))
   {
      return make_error(env, FIX_FAILED, "Wrong parser reference.");
   }
   *pres = tuple[1];
   void* res = NULL;
   if (!enif_get_resource(env, *pres, parser_res, &res))
   {
      return make_error(env, FIX_FAILED, "Wrong parser resource.");
   }
   *parser = (ParserRes*)res;
   return ok_atom;
}
/*-----------------------------------------------------------------------------------------------------------------------*/
static ERL_NIF_TERM get_parser_msg(
      ErlNifEnv* env, ERL_NIF_TERM ref,
      ERL_NIF_TERM* pres, ERL_NIF_TERM* mres,
      ParserRes** parser, FIXMsg** msg)
{
   int32_t arity;
   ERL_NIF_TERM const* tuple = NULL;
   if (!enif_get_tuple(env, ref, &arity, &tuple) || arity != 3)
   {
      return make_error(env, FIX_FAILED, "Wrong msg reference.");
   }
   if (enif_compare(tuple[0], msg_atom))
   {
      return make_error(env, FIX_FAILED, "Wrong msg reference.");
   }
   ERL_NIF_TERM const* data = NULL;
   if (!enif_get_tuple(env, tuple[2], &arity, &data) || arity != 2)
   {
      return make_error(env, FIX_FAILED, "Wrong msg reference.");
   }
   *pres = data[0];
   *mres = data[1];
   void* res = NULL;
   if (!enif_get_resource(env, *pres, parser_res, &res))
   {
      return make_error(env, FIX_FAILED, "Wrong parser resource.");
   }
   *parser = (ParserRes*)res;

   if (!enif_get_resource(env, *mres, message_res, &res))
   {
      return make_error(env, FIX_FAILED, "Wrong message resource.");
   }
   *msg = ((MsgRes*)res)->msg;
   return ok_atom;
}
Exemple #9
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) {
    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);
}
Exemple #10
0
ERL_NIF_TERM
encode(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    Encoder enc;
    Encoder* e = &enc;

    ErlNifBinary bin;
    ERL_NIF_TERM ret;

    ERL_NIF_TERM stack;
    ERL_NIF_TERM curr;
    ERL_NIF_TERM item;
    const ERL_NIF_TERM* tuple;
    int arity;
    ErlNifSInt64 lval;
    double dval;

    if(argc != 2) {
        return enif_make_badarg(env);
    }

    if(!enc_init(e, env, argv[1], &bin)) {
        return enif_make_badarg(env);
    }

    stack = enif_make_list(env, 1, argv[0]);

    while(!enif_is_empty_list(env, stack)) {
        if(!enif_get_list_cell(env, stack, &curr, &stack)) {
            ret = enc_error(e, "internal_error");
            goto done;
        }
        if(enif_is_identical(curr, e->atoms->ref_object)) {
            if(!enif_get_list_cell(env, stack, &curr, &stack)) {
                ret = enc_error(e, "internal_error");
                goto done;
            }
            if(enif_is_empty_list(env, curr)) {
                if(!enc_end_object(e)) {
                    ret = enc_error(e, "internal_error");
                    goto done;
                }
                continue;
            }
            if(!enif_get_list_cell(env, curr, &item, &curr)) {
                ret = enc_error(e, "internal_error");
                goto done;
            }
            if(!enif_get_tuple(env, item, &arity, &tuple)) {
                ret = enc_error(e, "invalid_object_pair");
                goto done;
            }
            if(arity != 2) {
                ret = enc_error(e, "invalid_object_pair");
                goto done;
            }
            if(!enc_comma(e)) {
                ret = enc_error(e, "internal_error");
                goto done;
            }
            if(!enc_string(e, tuple[0])) {
                ret = enc_error(e, "invalid_object_key");
                goto done;
            }
            if(!enc_colon(e)) {
                ret = enc_error(e, "internal_error");
                goto done;
            }
            stack = enif_make_list_cell(env, curr, stack);
            stack = enif_make_list_cell(env, e->atoms->ref_object, stack);
            stack = enif_make_list_cell(env, tuple[1], stack);
        } else if(enif_is_identical(curr, e->atoms->ref_array)) {
            if(!enif_get_list_cell(env, stack, &curr, &stack)) {
                ret = enc_error(e, "internal_error");
                goto done;
            }
            if(enif_is_empty_list(env, curr)) {
                if(!enc_end_array(e)) {
                    ret = enc_error(e, "internal_error");
                    goto done;
                }
                continue;
            }
            if(!enc_comma(e)) {
                ret = enc_error(e, "internal_error");
                goto done;
            }
            if(!enif_get_list_cell(env, curr, &item, &curr)) {
                ret = enc_error(e, "internal_error");
                goto done;
            }
            stack = enif_make_list_cell(env, curr, stack);
            stack = enif_make_list_cell(env, e->atoms->ref_array, stack);
            stack = enif_make_list_cell(env, item, stack);
        } else if(enif_compare(curr, e->atoms->atom_null) == 0) {
            if(!enc_literal(e, "null", 4)) {
                ret = enc_error(e, "null");
                goto done;
            }
        } else if(enif_compare(curr, e->atoms->atom_true) == 0) {
            if(!enc_literal(e, "true", 4)) {
                ret = enc_error(e, "true");
                goto done;
            }
        } else if(enif_compare(curr, e->atoms->atom_false) == 0) {
            if(!enc_literal(e, "false", 5)) {
                ret = enc_error(e, "false");
                goto done;
            }
        } else if(enif_is_binary(env, curr)) {
            if(!enc_string(e, curr)) {
                ret = enc_error(e, "invalid_string");
                goto done;
            }
        } else if(enif_is_atom(env, curr)) {
            if(!enc_string(e, curr)) {
                ret = enc_error(e, "invalid_string");
                goto done;
            }
        } else if(enif_get_int64(env, curr, &lval)) {
            if(!enc_long(e, lval)) {
                ret = enc_error(e, "internal_error");
                goto done;
            }
        } else if(enif_get_double(env, curr, &dval)) {
            if(!enc_double(e, dval)) {
                ret = enc_error(e, "internal_error");
                goto done;
            }
        } else if(enif_get_tuple(env, curr, &arity, &tuple)) {
            if(arity != 1) {
                ret = enc_error(e, "invalid_ejson");
                goto done;
            }
            if(!enif_is_list(env, tuple[0])) {
                ret = enc_error(e, "invalid_object");
                goto done;
            }
            if(!enc_start_object(e)) {
                ret = enc_error(e, "internal_error");
                goto done;
            }
            if(enif_is_empty_list(env, tuple[0])) {
                if(!enc_end_object(e)) {
                    ret = enc_error(e, "internal_error");
                    goto done;
                }
                continue;
            }
            if(!enif_get_list_cell(env, tuple[0], &item, &curr)) {
                ret = enc_error(e, "internal_error");
                goto done;
            }
            if(!enif_get_tuple(env, item, &arity, &tuple)) {
                ret = enc_error(e, "invalid_object_member");
                goto done;
            }
            if(arity != 2) {
                ret = enc_error(e, "invalid_object_member_arity");
                goto done;
            }
            if(!enc_string(e, tuple[0])) {
                ret = enc_error(e, "invalid_object_member_key");
                goto done;
            }
            if(!enc_colon(e)) {
                ret = enc_error(e, "internal_error");
                goto done;
            }
            stack = enif_make_list_cell(env, curr, stack);
            stack = enif_make_list_cell(env, e->atoms->ref_object, stack);
            stack = enif_make_list_cell(env, tuple[1], stack);
        } else if(enif_is_list(env, curr)) {
            if(!enc_start_array(e)) {
                ret = enc_error(e, "internal_error");
                goto done;
            }
            if(enif_is_empty_list(env, curr)) {
                if(!enc_end_array(e)) {
                    ret = enc_error(e, "internal_error");
                    goto done;
                }
                continue;
            }
            if(!enif_get_list_cell(env, curr, &item, &curr)) {
                ret = enc_error(e, "internal_error");
                goto done;
            }
            stack = enif_make_list_cell(env, curr, stack);
            stack = enif_make_list_cell(env, e->atoms->ref_array, stack);
            stack = enif_make_list_cell(env, item, stack);
        } else {
            if(!enc_unknown(e, curr)) {
                ret = enc_error(e, "internal_error");
                goto done;
            }
        }
    }

    if(!enc_done(e, &item)) {
        ret = enc_error(e, "internal_error");
        goto done;
    }

    if(e->iolen == 0) {
        ret = item;
    } else {
        ret = enif_make_tuple2(env, e->atoms->atom_partial, item);
    }

done:
    enc_destroy(e);
    return ret;
}
Exemple #11
0
/* comparison operator for the atom -> cache RB tree */
static int
atom_tree_cmp(struct atom_node *a1, struct atom_node *a2)
{
	return enif_compare(a1->atom, a2->atom);
}
Exemple #12
0
// build out_ds
static ERL_NIF_TERM gdal_nif_create_warped_vrtimg(ErlNifEnv* env, int argc,
                                          const ERL_NIF_TERM argv[])
{
    ErlNifBinary filenameBin;
    if (!enif_inspect_iolist_as_binary(env, argv[0], &filenameBin) || 
        (filenameBin.size >= FILENAME_LEN)) {
        return make_error_msg(env, "filename error, maybe too long");
    }

    char imgfilename[FILENAME_LEN] = "";
    size_t name_sz = filenameBin.size;
    memcpy(imgfilename, filenameBin.data, filenameBin.size);
    DEBUG("img filename: %s\r\n", imgfilename);

    int epsg_code;
    if (!enif_get_int(env, argv[1], &epsg_code)) {
        return enif_make_badarg(env);
    }

    GDALDatasetH in_ds = GDALOpenShared(imgfilename, GA_ReadOnly);
    if (in_ds == NULL) {
        const char* msg = "It is not possible to open the input file '%s'.";
        char errstr[name_sz + strlen(msg) + 1];
        sprintf(errstr, msg, imgfilename);
        return make_error_msg(env, errstr);
    }

    gdal_img_handle* handle = enif_alloc_resource(
                                            gdal_img_RESOURCE, 
                                            sizeof(gdal_img_handle));
    memset(handle, '\0', sizeof(*handle));
    handle->in_ds = in_ds;
    handle->options_resampling = "average";
    handle->querysize = 256 * 4;
    handle->tilesize = 256;

    int rasterCount = GDALGetRasterCount(in_ds);
    if (rasterCount == 0) {
        const char* msg = "Input file '%s' has no raster band";
        char errstr[name_sz + strlen(msg) + 1];
        sprintf(errstr, msg, imgfilename);

        destroy_img_handle(handle);
        return make_error_msg(env, errstr);
    }

    GDALRasterBandH hBand = GDALGetRasterBand(in_ds, 1);
    if (GDALGetRasterColorTable(hBand) != NULL) {
        const char* msg = 
            "Please convert this file to RGB/RGBA and run gdal2tiles on the result.\n" 
            "From paletted file you can create RGBA file (temp.vrt) by:\n"
            "gdal_translate -of vrt -expand rgba %s temp.vrt\n"
            "then run this program: gdal2tiles temp.vrt";
        char errstr[name_sz + strlen(msg) + 1];
        sprintf(errstr, msg, imgfilename);

        destroy_img_handle(handle);
        return make_error_msg(env, errstr);
    }

    double padfTransform[6];
    double errTransform[6] = {0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
    GDALGetGeoTransform(in_ds, padfTransform);
    if (0 == memcmp(padfTransform, errTransform, sizeof(errTransform))
             && GDALGetGCPCount(in_ds) == 0) {
        destroy_img_handle(handle);
        return make_error_msg(env, 
                              "There is no georeference - "
                              "neither affine transformation (worldfile) nor GCPs");
    }

    const char* in_srs_wkt = GDALGetProjectionRef(in_ds);
    if (in_srs_wkt == NULL && GDALGetGCPCount(in_ds) != 0) {
        in_srs_wkt = GDALGetGCPProjection(in_ds);
    }
    char* out_srs_wkt = get_wkt_of(epsg_code);
    GDALDatasetH out_ds = GDALAutoCreateWarpedVRT(in_ds, 
                                                  in_srs_wkt, 
                                                  out_srs_wkt, 
                                                  GRA_NearestNeighbour, 
                                                  0.0, 
                                                  NULL);
    handle->out_ds = out_ds;
    OGRFree(out_srs_wkt);


    handle->alphaBand = GDALGetMaskBand(GDALGetRasterBand(handle->out_ds, 1));
    rasterCount = GDALGetRasterCount(handle->out_ds);
    unsigned int dataBandsCount;
    if (GDALGetMaskFlags(handle->alphaBand) & GMF_ALPHA || 
            rasterCount == 4 || rasterCount == 2) {
        dataBandsCount = rasterCount - 1;
    }
    else {
        dataBandsCount = rasterCount;
    }
    handle->dataBandsCount = dataBandsCount;
    handle->tilebands = dataBandsCount + 1;


    ERL_NIF_TERM imginfo = get_imginfo(env, out_ds);
    if (enif_compare(ATOM_ERROR, imginfo) == 0) {
        destroy_img_handle(handle);
        return make_error_msg(env,
                              "Georeference of the raster contains rotation or skew. "
                              "Such raster is not supported. "
                              "Please use gdalwarp first");
    }

    ERL_NIF_TERM imgref = enif_make_resource(env, handle);
    enif_release_resource(handle);

    return enif_make_tuple3(env, ATOM_OK, imgref, imginfo);
}
Exemple #13
0
/*-----------------------------------------------------------------------------------------------------------------------*/
static ERL_NIF_TERM get_parser_msg_group(
      ErlNifEnv* env, ERL_NIF_TERM ref,
      ERL_NIF_TERM* pres, ERL_NIF_TERM* mres, ERL_NIF_TERM* gres,
      ParserRes** parser, FIXMsg** msg, FIXGroup** group)
{
   int32_t arity;
   ERL_NIF_TERM const* tuple = NULL;
   if (!enif_get_tuple(env, ref, &arity, &tuple) || (arity != 2 && arity != 3))
   {
      return make_error(env, FIX_FAILED, "Wrong msg reference1.");
   }
   if (enif_compare(tuple[0], msg_atom) && enif_compare(tuple[0], group_atom))
   {
      return make_error(env, FIX_FAILED, "Wrong msg reference2.");
   }
   ERL_NIF_TERM const* data = NULL;
   if (arity == 3) // this is a message
   {
      if (!enif_get_tuple(env, tuple[2], &arity, &data) || arity != 2)
      {
         return make_error(env, FIX_FAILED, "Wrong msg reference3.");
      }
   }
   else // this is a group
   {
      if (!enif_get_tuple(env, tuple[1], &arity, &data) || arity != 3)
      {
         return make_error(env, FIX_FAILED, "Wrong msg reference4.");
      }
   }
   *pres = data[0];
   *mres = data[1];
   if (arity == 3) // group exists
   {
      *gres = data[2];
   }
   void* res = NULL;
   if (!enif_get_resource(env, *pres, parser_res, &res))
   {
      return make_error(env, FIX_FAILED, "Wrong parser resource.");
   }
   *parser = (ParserRes*)res;

   if (!enif_get_resource(env, *mres, message_res, &res))
   {
      return make_error(env, FIX_FAILED, "Wrong message resource.");
   }
   *msg = ((MsgRes*)res)->msg;
   if (arity == 3) // group exists
   {
      if (!enif_get_resource(env, *gres, group_res, &res))
      {
         return make_error(env, FIX_FAILED, "Wrong group resource.");
      }
      *group = *(FIXGroup**)res;
   }
   else
   {
      *group = NULL;
   }
   return ok_atom;
}
Exemple #14
0
static ERL_NIF_TERM type_test(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    int i;
    int sint;
    unsigned uint;
    long slong;
    unsigned long ulong;
    ErlNifSInt64 sint64;
    ErlNifUInt64 uint64;
    double d;
    ERL_NIF_TERM atom, ref1, ref2;

    sint = INT_MIN;
    do {
	if (!test_int(env,sint)) {
	    goto error;
	}
	sint += ~sint / 3 + 1;
    } while (sint < 0);
    sint = INT_MAX;
    do {
	if (!test_int(env,sint)) {
	    goto error;
	}
	sint -= sint / 3 + 1;
    } while (sint >= 0);

    slong = LONG_MIN;
    do {
	if (!test_long(env,slong)) {
	    goto error;
	}
	slong += ~slong / 3 + 1;
    } while (slong < 0);
    slong = LONG_MAX;
    do {
	if (!test_long(env,slong)) {
	    goto error;
	}
	slong -= slong / 3 + 1;
    } while (slong >= 0);

    sint64 = ((ErlNifSInt64)1 << 63); /* INT64_MIN */
    do {
	if (!test_int64(env,sint64)) {
	    goto error;
	}
	sint64 += ~sint64 / 3 + 1;
    } while (sint64 < 0);
    sint64 = ((ErlNifUInt64)1 << 63) - 1; /* INT64_MAX */
    do {
	if (!test_int64(env,sint64)) {
	    goto error;
	}
	sint64 -= sint64 / 3 + 1;
    } while (sint64 >= 0);

    uint = UINT_MAX;
    for (;;) {
	if (!test_uint(env,uint)) {
	    goto error;
	}
	if (uint == 0) break;
	uint -= uint / 3 + 1;
    }
    ulong = ULONG_MAX;
    for (;;) {
	if (!test_ulong(env,ulong)) {
	    goto error;
	}
	if (ulong == 0) break;
	ulong -= ulong / 3 + 1;
    }    
    uint64 = (ErlNifUInt64)-1; /* UINT64_MAX */
    for (;;) {
	if (!test_uint64(env,uint64)) {
	    goto error;
	}
	if (uint64 == 0) break;
	uint64 -= uint64 / 3 + 1;
    }    

    if (MAX_SMALL < INT_MAX) { /* 32-bit */
	for (i=-10 ; i <= 10; i++) {
	    if (!test_int(env,MAX_SMALL+i)) {
		goto error;
	    }
	}
	for (i=-10 ; i <= 10; i++) {
	    if (!test_int(env,MIN_SMALL+i)) {
		goto error;
	    }
	}
	for (i=-10 ; i <= 10; i++) {
	    if (!test_uint(env,MAX_SMALL+i)) {
		goto error;
	    }
	}
    }
    assert((MAX_SMALL < INT_MAX) == (MIN_SMALL > INT_MIN));

    for (i=-10 ; i < 10; i++) {
	if (!test_long(env,MAX_SMALL+i) || !test_ulong(env,MAX_SMALL+i) ||
	    !test_long(env,MIN_SMALL+i) ||
	    !test_int64(env,MAX_SMALL+i) || !test_uint64(env,MAX_SMALL+i) ||
	    !test_int64(env,MIN_SMALL+i)) {
	    goto error;
	}
	if (MAX_SMALL < INT_MAX) {
	    if (!test_int(env,MAX_SMALL+i) || !test_uint(env,MAX_SMALL+i) ||
		!test_int(env,MIN_SMALL+i)) {
		goto error;
	    }
	}
    }
    for (d=3.141592e-100 ; d < 1e100 ; d *= 9.97) {
	if (!test_double(env,d) || !test_double(env,-d)) {
	    goto error;
	}	
    }

    if (!enif_make_existing_atom(env,"nif_SUITE", &atom, ERL_NIF_LATIN1)
	|| !enif_is_identical(atom,enif_make_atom(env,"nif_SUITE"))) {
	fprintf(stderr, "nif_SUITE not an atom?\r\n");
	goto error;
    }
    for (i=2; i; i--) {
	if (enif_make_existing_atom(env,"nif_SUITE_pink_unicorn", &atom, ERL_NIF_LATIN1)) {
	    fprintf(stderr, "pink unicorn exist?\r\n");
	    goto error;
	}
    }
    ref1 = enif_make_ref(env);
    ref2 = enif_make_ref(env);
    if (!enif_is_ref(env,ref1) || !enif_is_ref(env,ref2) 
	|| enif_is_identical(ref1,ref2) || enif_compare(ref1,ref2)==0) {
	fprintf(stderr, "strange refs?\r\n");
	goto error;
    }
    return enif_make_atom(env,"ok");

error:
    return enif_make_atom(env,"error");
}
Exemple #15
0
ERL_NIF_TERM
encode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    Encoder* e;
    jiffy_st* st = (jiffy_st*) enif_priv_data(env);

    ERL_NIF_TERM ret = 0;

    ERL_NIF_TERM stack;
    ERL_NIF_TERM curr;
    ERL_NIF_TERM item;
    const ERL_NIF_TERM* tuple;
    int arity;
    ErlNifSInt64 lval;
    double dval;

    size_t start;
    size_t processed;

    if(argc != 3) {
        return enif_make_badarg(env);
    } else if(!enif_get_resource(env, argv[0], st->res_enc, (void**) &e)) {
        return enif_make_badarg(env);
    } else if(!enif_is_list(env, argv[1])) {
        return enif_make_badarg(env);
    } else if(!enif_is_list(env, argv[2])) {
        return enif_make_badarg(env);
    }

    if(!enc_init(e, env)) {
        return enif_make_badarg(env);
    }

    stack = argv[1];
    e->iolist = argv[2];

    start = e->iosize + e->i;

    while(!enif_is_empty_list(env, stack)) {

        processed = (e->iosize + e->i) - start;
        if(should_yield(processed, e->bytes_per_iter)) {
            consume_timeslice(env, processed, e->bytes_per_iter);
            return enif_make_tuple4(
                    env,
                    st->atom_iter,
                    argv[0],
                    stack,
                    e->iolist
                );
        }

        if(!enif_get_list_cell(env, stack, &curr, &stack)) {
            ret = enc_error(e, "internal_error");
            goto done;
        }
        if(enif_is_identical(curr, e->atoms->ref_object)) {
            if(!enif_get_list_cell(env, stack, &curr, &stack)) {
                ret = enc_error(e, "internal_error");
                goto done;
            }
            if(enif_is_empty_list(env, curr)) {
                if(!enc_end_object(e)) {
                    ret = enc_error(e, "internal_error");
                    goto done;
                }
                continue;
            }
            if(!enif_get_list_cell(env, curr, &item, &curr)) {
                ret = enc_error(e, "internal_error");
                goto done;
            }
            if(!enif_get_tuple(env, item, &arity, &tuple)) {
                ret = enc_obj_error(e, "invalid_object_member", item);
                goto done;
            }
            if(arity != 2) {
                ret = enc_obj_error(e, "invalid_object_member_arity", item);
                goto done;
            }
            if(!enc_comma(e)) {
                ret = enc_error(e, "internal_error");
                goto done;
            }
            if(!enc_string(e, tuple[0])) {
                ret = enc_obj_error(e, "invalid_object_member_key", tuple[0]);
                goto done;
            }
            if(!enc_colon(e)) {
                ret = enc_error(e, "internal_error");
                goto done;
            }
            stack = enif_make_list_cell(env, curr, stack);
            stack = enif_make_list_cell(env, e->atoms->ref_object, stack);
            stack = enif_make_list_cell(env, tuple[1], stack);
        } else if(enif_is_identical(curr, e->atoms->ref_array)) {
            if(!enif_get_list_cell(env, stack, &curr, &stack)) {
                ret = enc_error(e, "internal_error");
                goto done;
            }
            if(enif_is_empty_list(env, curr)) {
                if(!enc_end_array(e)) {
                    ret = enc_error(e, "internal_error");
                    goto done;
                }
                continue;
            }
            if(!enc_comma(e)) {
                ret = enc_error(e, "internal_error");
                goto done;
            }
            if(!enif_get_list_cell(env, curr, &item, &curr)) {
                ret = enc_error(e, "internal_error");
                goto done;
            }
            stack = enif_make_list_cell(env, curr, stack);
            stack = enif_make_list_cell(env, e->atoms->ref_array, stack);
            stack = enif_make_list_cell(env, item, stack);
        } else if(enif_compare(curr, e->atoms->atom_null) == 0) {
            if(!enc_literal(e, "null", 4)) {
                ret = enc_error(e, "null");
                goto done;
            }
        } else if(e->use_nil && enif_compare(curr, e->atoms->atom_nil) == 0) {
            if(!enc_literal(e, "null", 4)) {
                ret = enc_error(e, "null");
                goto done;
            }
        } else if(enif_compare(curr, e->atoms->atom_true) == 0) {
            if(!enc_literal(e, "true", 4)) {
                ret = enc_error(e, "true");
                goto done;
            }
        } else if(enif_compare(curr, e->atoms->atom_false) == 0) {
            if(!enc_literal(e, "false", 5)) {
                ret = enc_error(e, "false");
                goto done;
            }
        } else if(enif_is_binary(env, curr)) {
            if(!enc_string(e, curr)) {
                ret = enc_obj_error(e, "invalid_string", curr);
                goto done;
            }
        } else if(enif_is_atom(env, curr)) {
            if(!enc_string(e, curr)) {
                ret = enc_obj_error(e, "invalid_string", curr);
                goto done;
            }
        } else if(enif_get_int64(env, curr, &lval)) {
            if(!enc_long(e, lval)) {
                ret = enc_error(e, "internal_error");
                goto done;
            }
        } else if(enif_get_double(env, curr, &dval)) {
            if(!enc_double(e, dval)) {
                ret = enc_error(e, "internal_error");
                goto done;
            }
        } else if(enif_get_tuple(env, curr, &arity, &tuple)) {
			ret = enc_obj_error(e, "invalid_ejson", curr);
			goto done;
#if MAP_TYPE_PRESENT
        } else if(enif_is_map(env, curr)) {
            if(!enc_map_to_ejson(env, curr, &curr)) {
                ret = enc_error(e, "internal_error");
                goto done;
            }
            stack = enif_make_list_cell(env, curr, stack);
#endif
        } else if(enif_is_list(env, curr)) {
            if(enif_is_empty_list(env, curr)) {
                if(!enc_start_array(e) || !enc_end_array(e)) {
                    ret = enc_error(e, "internal_error");
                    goto done;
                }
                continue;
            }
            if(!enif_get_list_cell(env, curr, &item, &curr)) {
                ret = enc_error(e, "internal_error");
                goto done;
            }
            if(!enif_get_tuple(env, item, &arity, &tuple)) {
				if(!enc_start_array(e)) {
					ret = enc_error(e, "internal_error");
					goto done;
				}
				stack = enif_make_list_cell(env, curr, stack);
				stack = enif_make_list_cell(env, e->atoms->ref_array, stack);
				stack = enif_make_list_cell(env, item, stack);
            } else {
				if(!enc_start_object(e)) {
					ret = enc_error(e, "internal_error");
					goto done;
				}
				if(arity == 0) {
					if(!enc_end_object(e)) {
						ret = enc_error(e, "internal_error");
						goto done;
					}
					continue;
				} else if(arity != 2) {
					ret = enc_obj_error(e, "invalid_object_member_arity", item);
					goto done;
				}
				if(!enc_string(e, tuple[0])) {
					ret = enc_obj_error(e, "invalid_object_member_key", tuple[0]);
					goto done;
				}
				if(!enc_colon(e)) {
					ret = enc_error(e, "internal_error");
					goto done;
				}
				stack = enif_make_list_cell(env, curr, stack);
				stack = enif_make_list_cell(env, e->atoms->ref_object, stack);
				stack = enif_make_list_cell(env, tuple[1], stack);
			}
        } else {
            if(!enc_unknown(e, curr)) {
                ret = enc_error(e, "internal_error");
                goto done;
            }
        }
    }

    if(!enc_done(e, &item)) {
        ret = enc_error(e, "internal_error");
        goto done;
    }

    if(e->iolen == 0) {
        ret = item;
    } else {
        ret = enif_make_tuple2(env, e->atoms->atom_partial, item);
    }

done:
    processed = (e->iosize + e->i) - start;
    consume_timeslice(env, processed, e->bytes_per_iter);

    return ret;
}
Exemple #16
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;
}