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); }
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); }
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])); }
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; }
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; }
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); }
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; }
/* 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); }
// 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); }
/*-----------------------------------------------------------------------------------------------------------------------*/ 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; }
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"); }
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; }
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; }