Esempio n. 1
0
static ERL_NIF_TERM parse(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
    XML_Parser **parser;
    int is_final, res, errcode;
    ErlNifBinary stream;
    char *errstring;

    assert(argc == 3);

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

    if (!enif_is_binary(env, argv[1]))
        return enif_make_badarg(env);

    enif_get_int(env, argv[2], &is_final);
    enif_inspect_binary(env, argv[1], &stream);

    expat_parser *parser_data = XML_GetUserData((XML_Parser)(*parser));
    parser_data->result = enif_make_list(env, 0);
    parser_data->env = env;
    XML_SetUserData((XML_Parser)(*parser), parser_data);

    res = XML_Parse((XML_Parser)(*parser), (const char *)stream.data, stream.size, is_final);
    if(!res)
        {
            errcode = XML_GetErrorCode((XML_Parser)(*parser));
            errstring = (char *)XML_ErrorString(errcode);

            return enif_make_tuple(env, 2, ERROR,
                                   enif_make_string(env, errstring, ERL_NIF_LATIN1));
        }

    return enif_make_tuple(env, 2, OK, parser_data->result);
};
Esempio n. 2
0
static void *start_element_handler(expat_parser *parser_data, const XML_Char *name, const XML_Char **atts)
{
    ErlNifBinary element_name;
    ERL_NIF_TERM attrs_list = enif_make_list(parser_data->env, 0);
    int i;

    element_name = encode_name(parser_data, name);
    for(i = 0; atts[i]; i += 2);
    while(i)
        {
            ErlNifBinary attr_name, attr_value;

            enif_alloc_binary(strlen(atts[i-1]), &attr_value);
            strcpy((char *) attr_value.data, (const char *)atts[i-1]);
            attr_name = encode_name(parser_data, atts[i-2]);

            ERL_NIF_TERM attr = enif_make_tuple(parser_data->env, 2,
                                                enif_make_binary(parser_data->env, &attr_name),
                                                enif_make_binary(parser_data->env, &attr_value));
            attrs_list = enif_make_list_cell(parser_data->env, attr, attrs_list);

            i -= 2;
        };

    if(parser_data->xmlns)
        attrs_list = enif_make_list_cell(parser_data->env, parser_data->xmlns, attrs_list);
    parser_data->xmlns = (ERL_NIF_TERM)NULL;

    ERL_NIF_TERM event = enif_make_tuple(parser_data->env, 3, XML_ELEMENT_START,
                                         enif_make_binary(parser_data->env, &element_name),
                                         attrs_list);
    parser_data->result = enif_make_list_cell(parser_data->env, event, parser_data->result);

    return NULL;
};
Esempio n. 3
0
static void *start_element_handler(expat_parser *parser_data, const XML_Char *name, const XML_Char **atts)
{
    ERL_NIF_TERM element_name;
    ERL_NIF_TERM attrs_list = enif_make_list(parser_data->env, 0);
    int i;

    element_name = encode_name(parser_data, name);
    for(i = 0; atts[i]; i += 2);
    while(i)
    {
        ERL_NIF_TERM attr_name, attr_value;

        size_t atts_len = strlen(atts[i-1]);
        unsigned char *attr_data = enif_make_new_binary(parser_data->env, atts_len, &attr_value);
        strncpy((char*)attr_data, (const char *)atts[i-1], atts_len);
        attr_name = encode_name(parser_data, atts[i-2]);

        ERL_NIF_TERM attr = enif_make_tuple(parser_data->env, 2, attr_name, attr_value);
        attrs_list = enif_make_list_cell(parser_data->env, attr, attrs_list);

        i -= 2;
    };


    ERL_NIF_TERM event = enif_make_tuple(parser_data->env, 4, XML_ELEMENT_START,
                                         element_name,
                                         parser_data->xmlns,
                                         attrs_list);
    parser_data->result = enif_make_list_cell(parser_data->env, event, parser_data->result);
    parser_data->xmlns = enif_make_list(parser_data->env, 0);

    return NULL;
};
Esempio n. 4
0
ERL_NIF_TERM entry_to_term(ErlNifEnv *env, const git_index_entry *entry)
{
	ErlNifBinary id, path;
	size_t len;

	if (geef_oid_bin(&id, &entry->id) < 0)
		return geef_oom(env);

	len = strlen(entry->path);
	if (!enif_alloc_binary(len, &path)) {
		enif_release_binary(&id);
		return geef_oom(env);
	}
	memcpy(path.data, entry->path, len);

	return enif_make_tuple(env, 13, atoms.ok,
			       enif_make_int64(env, entry->ctime.seconds),
			       enif_make_int64(env, entry->mtime.seconds),
			       enif_make_uint(env, entry->dev),
			       enif_make_uint(env, entry->ino),
			       enif_make_uint(env, entry->mode),
			       enif_make_uint(env, entry->uid),
			       enif_make_uint(env, entry->gid),
			       enif_make_int64(env, entry->file_size),
			       enif_make_binary(env, &id),
			       enif_make_uint(env, entry->flags),
			       enif_make_uint(env, entry->flags_extended),
			       enif_make_binary(env, &path));
}
Esempio n. 5
0
static void *namespace_decl_handler(expat_parser *parser_data, const XML_Char *prefix, const XML_Char *uri)
{
    ERL_NIF_TERM ns_prefix_bin, ns_uri_bin, ns_pair;

    if(uri == NULL)
    {
        /* parser_data->xmlns = (ERL_NIF_TERM)NULL; */
        fprintf(stderr, "URI IS NULL?\n");
        return NULL;
    }

    if(prefix)
    {
        size_t prefix_len = strlen(prefix);
        unsigned char *ns_prefix_data = enif_make_new_binary(parser_data->env, prefix_len, &ns_prefix_bin);
        strncpy((char*)ns_prefix_data, (const char *)prefix, prefix_len);
    } else
    {
        ns_prefix_bin = NONE;
    }

    size_t uri_len = strlen(uri);
    unsigned char *ns_uri_data = enif_make_new_binary(parser_data->env, uri_len, &ns_uri_bin);
    strncpy((char*)ns_uri_data, uri, uri_len);

    ns_pair = enif_make_tuple(parser_data->env, 2, ns_uri_bin, ns_prefix_bin);
    parser_data->xmlns = enif_make_list_cell(parser_data->env, ns_pair, parser_data->xmlns);

    return NULL;
};
Esempio n. 6
0
    static ERL_NIF_TERM
error_tuple(ErlNifEnv *env, char *err)
{
    return enif_make_tuple(env, 2,
            enif_make_atom(env, "error"),
            enif_make_atom(env, err));
}
Esempio n. 7
0
static ERL_NIF_TERM read_info_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
    posix_errno_t posix_errno;

    efile_fileinfo_t info = {0};
    efile_path_t path;
    int follow_links;

    if(argc != 2 || !enif_get_int(env, argv[1], &follow_links)) {
        return enif_make_badarg(env);
    }

    if((posix_errno = efile_marshal_path(env, argv[0], &path))) {
        return posix_error_to_tuple(env, posix_errno);
    } else if((posix_errno = efile_read_info(&path, follow_links, &info))) {
        return posix_error_to_tuple(env, posix_errno);
    }

    /* #file_info as declared in file.hrl */
    return enif_make_tuple(env, 14,
        am_file_info,
        enif_make_uint64(env, info.size),
        efile_filetype_to_atom(info.type),
        efile_access_to_atom(info.access),
        enif_make_int64(env, MAX(EFILE_MIN_FILETIME, info.a_time)),
        enif_make_int64(env, MAX(EFILE_MIN_FILETIME, info.m_time)),
        enif_make_int64(env, MAX(EFILE_MIN_FILETIME, info.c_time)),
        enif_make_uint(env, info.mode),
        enif_make_uint(env, info.links),
        enif_make_uint(env, info.major_device),
        enif_make_uint(env, info.minor_device),
        enif_make_uint(env, info.inode),
        enif_make_uint(env, info.uid),
        enif_make_uint(env, info.gid)
    );
}
Esempio n. 8
0
static void *namespace_decl_handler(expat_parser *parser_data, const XML_Char *prefix, const XML_Char *uri)
{
    ErlNifBinary ns_prefix_bin, ns_uri_bin;
    ERL_NIF_TERM ns_prefix, ns_uri, ns_pair;

    if(uri == NULL)
        {
            /* parser_data->xmlns = (ERL_NIF_TERM)NULL; */
            fprintf(stderr, "URI IS NULL?\n");
            return NULL;
        }

    if(prefix)
        {
            enif_alloc_binary(strlen(prefix), &ns_prefix_bin);
            strcpy((char *)ns_prefix_bin.data, (const char *)prefix);
            ns_prefix = enif_make_binary(parser_data->env, &ns_prefix_bin);
        } else
        {
            ns_prefix = NONE;
        }

    enif_alloc_binary(strlen(uri), &ns_uri_bin);
    strcpy((char *)ns_uri_bin.data, uri);
    ns_uri = enif_make_binary(parser_data->env, &ns_uri_bin);

    ns_pair = enif_make_tuple(parser_data->env, 2, ns_uri, ns_prefix);
    parser_data->xmlns = enif_make_list_cell(parser_data->env, ns_pair, parser_data->xmlns);

    return NULL;
};
Esempio n. 9
0
static ERL_NIF_TERM
do_column_types(ErlNifEnv *env, sqlite3_stmt *stmt)
{
    int i, size;
    const char *type;
    ERL_NIF_TERM *array;
    ERL_NIF_TERM column_types;

    size = sqlite3_column_count(stmt);
    if(size == 0)
        return enif_make_tuple(env, 0);
    else if(size < 0)
        return make_error_tuple(env, "invalid_column_count");

    array = (ERL_NIF_TERM *) enif_alloc(sizeof(ERL_NIF_TERM) * size);
    if(!array)
        return make_error_tuple(env, "no_memory");

    for(i = 0; i < size; i++) {
        type = sqlite3_column_decltype(stmt, i);
        if(type == NULL) {
	    type = "nil";
        }

        array[i] = make_atom(env, type);
    }

    column_types = enif_make_tuple_from_array(env, array, size);
    enif_free(array);
    return column_types;
}
Esempio n. 10
0
static ERL_NIF_TERM
no_mem_error(ErlNifEnv* env)
{
    return enif_make_tuple(env, 2,
            enif_make_atom(env, "error"),
            enif_make_atom(env, "insufficient_memory"));
}
Esempio n. 11
0
static ERL_NIF_TERM
error_tuple(ErlNifEnv *env, char *err)
{
    return enif_make_tuple(env, 2,
                           atom_error,
                           enif_make_string(env, err, ERL_NIF_LATIN1));
}
Esempio n. 12
0
static void *namespace_decl_handler(expat_parser *parser_data, const XML_Char *prefix, const XML_Char *uri)
{
    ErlNifBinary ns_name, ns_value;

    if(uri == NULL)
        {
            parser_data->xmlns = (ERL_NIF_TERM)NULL;
            return NULL;
        }

    if(prefix)
        {
            enif_alloc_binary(strlen(prefix)+6, &ns_name);
            strcpy((char *)ns_name.data, "xmlns:");
            strcpy((char *)ns_name.data+6, (const char *)prefix);
        } else
        {
            enif_alloc_binary(5, &ns_name);
            strcpy((char *)ns_name.data, "xmlns");
        }

    enif_alloc_binary(strlen(uri), &ns_value);
    strcpy((char *)ns_value.data, uri);

    parser_data->xmlns = enif_make_tuple(parser_data->env, 2,
                                         enif_make_binary(parser_data->env, &ns_name),
                                         enif_make_binary(parser_data->env, &ns_value));

    return NULL;
};
Esempio n. 13
0
static ERL_NIF_TERM new_parser(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
    XML_Parser parser;
    expat_parser *parser_data = (expat_parser *)enif_alloc(sizeof(expat_parser));
    ERL_NIF_TERM parser_resource;

    // this is the variant from esl/exml:208d5e17e547b303b310627e3e525b57b2843e83
    /*parser = XML_ParserCreate_MM("UTF-8", &ms, "\n");*/

    // this makes the tests pass, but according to expat documentation it turns namespace support off
    /*parser = XML_ParserCreate_MM("UTF-8", &ms, NULL);*/

    // this is a try to preserve namespace support but make the tests pass;
    // this is the character defined as a macro in xmlwf sources for namespace-enabled parser
    /*XML_Char namespaceSeparator = '\001';*/
    /*parser = XML_ParserCreate_MM("UTF-8", &ms, &namespaceSeparator);*/
    parser = XML_ParserCreate_MM("UTF-8", &ms, ":");

    parser_data->env = env;
    parser_data->xmlns = (ERL_NIF_TERM)NULL;

    init_parser(parser, parser_data);

    XML_Parser *xml_parser = (XML_Parser *)enif_alloc_resource(PARSER_POINTER, sizeof(XML_Parser));
    *xml_parser = parser;
    parser_resource = enif_make_resource(env, (void *)xml_parser);
    enif_release_resource(xml_parser);

    return enif_make_tuple(env, 2, OK, parser_resource);
};
Esempio n. 14
0
ERL_NIF_TERM
make_empty_document(ErlNifEnv *env, int return_maps) 
{
    if(return_maps) {
        return enif_make_new_map(env);
    }
    return enif_make_tuple(env, 0);
}
Esempio n. 15
0
static void *end_element_handler(expat_parser *parser_data, const XML_Char *name)
{
    ERL_NIF_TERM element_name = encode_name(parser_data, name);

    ERL_NIF_TERM event = enif_make_tuple(parser_data->env, 2, XML_ELEMENT_END, element_name);
    parser_data->result = enif_make_list_cell(parser_data->env, event, parser_data->result);

    return NULL;
};
Esempio n. 16
0
int
enc_map(Encoder* enc, ERL_NIF_TERM head, ERL_NIF_TERM tail)
{
    int arity;
    const ERL_NIF_TERM* tuple;

    if(yajl_gen_map_open(enc->handle) != yajl_gen_status_ok)
    {
        enc->error = enif_make_atom(enc->env, "failed_to_open_map");
        return ERROR;
    }

    do {
        if(!enif_get_tuple(enc->env, head, &arity, &tuple))
        {
            enc->error = enif_make_tuple(enc->env, 2,
                enif_make_atom(enc->env, "badarg"),
                head
            );
            return ERROR;
        }
        if(arity != 2)
        {
            enc->error = enif_make_tuple(enc->env, 2,
                enif_make_atom(enc->env, "badarity"),
                head
            );
            return ERROR;
        }
        if(enc_key(enc, tuple[0]) != OK) return ERROR;
        if(enc_json(enc, tuple[1]) != OK) return ERROR;
    } while(enif_get_list_cell(enc->env, tail, &head, &tail));
    
    if(yajl_gen_map_close(enc->handle) != yajl_gen_status_ok)
    {
        enc->error = enif_make_atom(enc->env, "failed_to_close_map");
        return ERROR;
    }
    
    return OK;
}
Esempio n. 17
0
static void *character_data_handler(expat_parser *parser_data, const XML_Char *s, int len)
{
    ERL_NIF_TERM cdata;

    unsigned char *cdata_data = enif_make_new_binary(parser_data->env, len, &cdata);
    strncpy((char*)cdata_data, (const char *)s, len);

    ERL_NIF_TERM event = enif_make_tuple(parser_data->env, 2, XML_CDATA, cdata);
    parser_data->result = enif_make_list_cell(parser_data->env, event, parser_data->result);

    return NULL;
};
Esempio n. 18
0
static ERL_NIF_TERM atom_to_bin(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    ErlNifBinary obin;
    unsigned size;
    int n;
    if (!enif_get_int(env,argv[1],(int*)&size) 
	|| !enif_alloc_binary(size,&obin)) {
	return enif_make_badarg(env);
    }
    n = enif_get_atom(env, argv[0], (char*)obin.data, size, ERL_NIF_LATIN1);
    return enif_make_tuple(env, 2, enif_make_int(env,n),
			   enif_make_binary(env,&obin));
}
Esempio n. 19
0
static void *character_data_handler(expat_parser *parser_data, const XML_Char *s, int len)
{
    ErlNifBinary cdata;

    enif_alloc_binary(len, &cdata);
    strncpy((char *)cdata.data, (const char *)s, len);

    ERL_NIF_TERM event = enif_make_tuple(parser_data->env, 2, XML_CDATA,
                                         enif_make_binary(parser_data->env, &cdata));
    parser_data->result = enif_make_list_cell(parser_data->env, event, parser_data->result);

    return NULL;
};
Esempio n. 20
0
static int
decode_map_key(void* ctx, const unsigned char* data, unsigned int size)
{
    ErlNifBinary bin;
    if(!enif_alloc_binary_compat(ENV(ctx), size, &bin))
    {
       return CANCEL;
    }
    memcpy(bin.data, data, size);
    add_to_head(ctx, enif_make_tuple(ENV(ctx), 2,
                        enif_make_int(ENV(ctx), 3),
                        enif_make_binary(ENV(ctx), &bin)));
    return CONTINUE;
}
Esempio n. 21
0
static int
decode_number(void * ctx, const char * numberVal, unsigned int numberLen)
{
    // scan in the input to see if it's a float or int

    int numberType = 0; // 0 means integer, 1 means float
    unsigned int i;
    ErlNifBinary bin;
    int missingDot = 1;
    unsigned int expPos;

    for(i=0; i<numberLen; i++) {
        switch (numberVal[i]) {
        case '.':
            missingDot = 0;
            numberType = 1; // it's  a float
            goto loopend;
        case 'E':
        case 'e':
            expPos = i;
            numberType = 1; // it's  a float
            goto loopend;
        }
    }
loopend:
    if ((numberType == 1) && missingDot)
    {
        if(!enif_alloc_binary_compat(ENV(ctx), numberLen + 2, &bin))
        {
            return CANCEL;
        }
        memcpy(bin.data, numberVal, expPos);
        bin.data[expPos] = '.';
        bin.data[expPos + 1] = '0';
        memcpy(bin.data + expPos + 2, numberVal + expPos, numberLen - expPos);
    }
    else
    {
        if(!enif_alloc_binary_compat(ENV(ctx), numberLen, &bin))
        {
            return CANCEL;
        }
        memcpy(bin.data, numberVal, numberLen);
    }
    add_to_head(ctx, enif_make_tuple(ENV(ctx), 2,
                        enif_make_int(ENV(ctx), numberType),
                        enif_make_binary(ENV(ctx), &bin)));
    return CONTINUE;
}
Esempio n. 22
0
static ERL_NIF_TERM
make_error(yajl_handle handle, ErlNifEnv* env)
{
    char* yajlError = (char*) yajl_get_error(handle, 0, NULL, 0);
    ERL_NIF_TERM errMsg;

    if(yajlError != NULL)
    {
        errMsg = enif_make_string(env, yajlError, ERL_NIF_LATIN1);
        yajl_free_error(handle, (unsigned char*) yajlError);
    }
    else
    {
        errMsg = enif_make_string(env, "unknown parse error", ERL_NIF_LATIN1);
    }

    return enif_make_tuple(env, 2,
        enif_make_atom(env, "error"),
        enif_make_tuple(env, 2,
            enif_make_uint(env, handle->bytesConsumed),
            errMsg
        )
    );
}
Esempio n. 23
0
static ERL_NIF_TERM new_parser(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
    XML_Parser parser;
    expat_parser *parser_data = (expat_parser *)enif_alloc(sizeof(expat_parser));
    ERL_NIF_TERM parser_resource;

    parser = XML_ParserCreate_MM("UTF-8", &ms, "\n");
    parser_data->env = env;
    parser_data->xmlns = enif_make_list(env, 0);

    init_parser(parser, parser_data);

    XML_Parser *xml_parser = (XML_Parser *)enif_alloc_resource(PARSER_POINTER, sizeof(XML_Parser));
    *xml_parser = parser;
    parser_resource = enif_make_resource(env, (void *)xml_parser);
    enif_release_resource(xml_parser);
    return enif_make_tuple(env, 2, OK, parser_resource);
};
Esempio n. 24
0
static int
enc_map_to_ejson(ErlNifEnv* env, ERL_NIF_TERM map, ERL_NIF_TERM* out)
{
    ErlNifMapIterator iter;
    size_t size;

    ERL_NIF_TERM list;
    ERL_NIF_TERM tuple;
    ERL_NIF_TERM key;
    ERL_NIF_TERM val;

    if(!enif_get_map_size(env, map, &size)) {
        fprintf(stderr, "bad map size\r\n");
        return 0;
    }

    list = enif_make_list(env, 0);

    if(size == 0) {
        *out = enif_make_list_cell(env, enif_make_tuple(env, 0), list);
        return 1;
    }

    if(!enif_map_iterator_create(env, map, &iter, ERL_NIF_MAP_ITERATOR_HEAD)) {
        fprintf(stderr, "bad iterator create\r\n");
        return 0;
    }

    do {
        if(!enif_map_iterator_get_pair(env, &iter, &key, &val)) {
            fprintf(stderr, "bad get pair\r\n");
            return 0;
        }
        tuple = enif_make_tuple2(env, key, val);
        list = enif_make_list_cell(env, tuple, list);
    } while(enif_map_iterator_next(env, &iter));

    *out = list;
    return 1;
}
Esempio n. 25
0
int
enc_key(Encoder* enc, ERL_NIF_TERM key)
{
    char buf[512];
    ErlNifBinary bin;
    
    if(enif_is_atom(enc->env, key))
    {
        if(!enif_get_atom_compat(enc->env, key, buf, 512))
        {
            enc->error = enif_make_atom(enc->env, "failed_getting_atom_key");
            return ERROR;
        }
        if(yajl_gen_string(enc->handle, (unsigned char*) buf, strlen(buf))
                != yajl_gen_status_ok)
        {
            enc->error = enif_make_atom(enc->env, "failed_writing_atom_key");
            return ERROR;
        }
        return OK;
    }
    else if(enif_inspect_iolist_as_binary(enc->env, key, &bin))
    {
        if(yajl_gen_string(enc->handle, bin.data, bin.size) != yajl_gen_status_ok)
        {
            enc->error = enif_make_atom(enc->env, "failed_writing_binary_key");
            return ERROR;
        }
        return OK;
    }
    
    enc->error = enif_make_tuple(enc->env, 2,
        enif_make_atom(enc->env, "badkey"),
        key
    );
    return ERROR;
}
Esempio n. 26
0
ERL_NIF_TERM
mk_error(ErlNifEnv* env, const char* mesg)
{
    return enif_make_tuple(env, mk_atom(env, "error"), mk_atom(env, mesg));
}
Esempio n. 27
0
ERL_NIF_TERM
reverse_tokens(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    decode_ctx ctx;
    yajl_parser_config conf = {0, 1}; // No comments, check utf8
    yajl_handle handle = yajl_alloc(&decoder_callbacks, &conf, NULL, &ctx);
    yajl_status status;
    unsigned int used;
    ErlNifBinary bin;
    ERL_NIF_TERM ret;

    ctx.env = env;
    ctx.head = enif_make_list_from_array(env, NULL, 0);

    if(!enif_inspect_iolist_as_binary(env, argv[0], &bin))
    {
        ret = enif_make_badarg(env);
        goto done;
    }

    status = yajl_parse(handle, bin.data, bin.size);
    used = handle->bytesConsumed;

    // Parsing something like "2.0" (without quotes) will
    // cause a spurious semi-error. We add the extra size
    // check so that "2008-20-10" doesn't pass.
    if(status == yajl_status_insufficient_data && used == bin.size)
    {
        status = yajl_parse_complete(handle);
    }

    if(status == yajl_status_ok && used != bin.size)
    {
        if(check_rest(bin.data, bin.size, used) == CANCEL)
        {
            ret = enif_make_tuple(env, 2,
                enif_make_atom(env, "error"),
                enif_make_atom(env, "garbage_after_value")
            );
            goto done;
        }
    }

    switch(status)
    {
        case yajl_status_ok:
            ret = enif_make_tuple(env, 2, enif_make_atom(env, "ok"), ctx.head);
            goto done;

        case yajl_status_error:
            ret = make_error(handle, env);
            goto done;

        case yajl_status_insufficient_data:
            ret = enif_make_tuple(env, 2,
                enif_make_atom(env, "error"),
                enif_make_atom(env, "insufficient_data")
            );
            goto done;

        case yajl_status_client_canceled:
        /* the only time we do this is when we can't allocate a binary. */
            ret = enif_make_tuple(env, 2,
                enif_make_atom(env, "error"),
                enif_make_atom(env, "insufficient_memory")
            );
            goto done;

        default:
            ret = enif_make_tuple(env, 2,
                enif_make_atom(env, "error"),
                enif_make_atom(env, "unknown")
            );
            goto done;
    }

done:
    if(handle != NULL) yajl_free(handle);
    return ret;
}
Esempio n. 28
0
ERL_NIF_TERM _hi_next(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    hi_ctx_t* ctx = NULL;

    ErlNifResourceType* ctx_type = get_hi_ctx_type(env);
    if (argc != 1 ||
        ctx_type == NULL ||
        !enif_get_resource(env, argv[0], ctx_type, (void **)&ctx))
    {
        return enif_make_badarg(env);
    }

    if (ctx != NULL && ctx->type == HDR_ITER_REC)
    {
        // skip until first non-zero index
        bool has_next = false;
        while (ctx->iter != NULL && (has_next = hdr_recorded_iter_next(ctx->iter)))
        {
            struct hdr_recorded_iter* x = ((struct hdr_recorded_iter*)ctx->iter);
            struct hdr_iter iter = x->iter;
            if (0 != iter.count_at_index)
            {
                int64_t stp = x->count_added_in_this_iteration_step;
                int32_t bdx = iter.bucket_index;
                int64_t sdx = iter.sub_bucket_index;
                int64_t val = iter.value_from_index;
                int64_t cat = iter.count_at_index;
                int64_t cto = iter.count_to_index;
                int64_t heq = iter.highest_equivalent_value;
                return enif_make_tuple2(env,
                  ATOM_RECORD,
                  enif_make_list(env, 7,
                      enif_make_tuple2(env,
                          ATOM_BUCKET_IDX,
                          enif_make_int(env,bdx)),
                      enif_make_tuple2(env,
                          ATOM_SUB_BUCKET_IDX,
                          enif_make_long(env,sdx)),
                      enif_make_tuple2(env,
                          ATOM_VAL_FROM_IDX,
                          enif_make_long(env,val)),
                      enif_make_tuple2(env,
                          ATOM_VAL_AT_IDX,
                          enif_make_long(env,cat)),
                      enif_make_tuple2(env,
                          ATOM_COUNT_AT_IDX,
                          enif_make_long(env,cto)),
                      enif_make_tuple2(env,
                          ATOM_HIGHEST_EQUIV_VAL,
                          enif_make_long(env,heq)),
                      enif_make_tuple2(env,
                          ATOM_STEP_COUNT,
                          enif_make_long(env,stp))));
            }
        }
    }

    if (ctx != NULL && ctx->type == HDR_ITER_LIN)
    {
        // skip until first non-zero index
        bool has_next = false;
        while (ctx->iter != NULL && (has_next = hdr_linear_iter_next(ctx->iter)))
        {
            struct hdr_linear_iter* x = ((struct hdr_linear_iter*)ctx->iter);
            struct hdr_iter iter = x->iter;
            if (0 != iter.count_at_index)
            {
                int64_t stp = x->count_added_in_this_iteration_step;
                int32_t vub = x->value_units_per_bucket;
                int64_t nvl = x->next_value_reporting_level;
                int64_t nve = x->next_value_reporting_level_lowest_equivalent;
                int32_t bdx = iter.bucket_index;
                int64_t sdx = iter.sub_bucket_index;
                int64_t val = iter.value_from_index;
                int64_t cat = iter.count_at_index;
                int64_t cto = iter.count_to_index;
                int64_t heq = iter.highest_equivalent_value;
                return enif_make_tuple2(env,
                  ATOM_LINEAR,
                  enif_make_list(env, 10,
                      enif_make_tuple2(env,
                          ATOM_BUCKET_IDX,
                          enif_make_int(env,bdx)),
                      enif_make_tuple2(env,
                          ATOM_SUB_BUCKET_IDX,
                          enif_make_long(env,sdx)),
                      enif_make_tuple2(env,
                          ATOM_VAL_FROM_IDX,
                          enif_make_long(env,val)),
                      enif_make_tuple2(env,
                          ATOM_VAL_AT_IDX,
                          enif_make_long(env,cat)),
                      enif_make_tuple2(env,
                          ATOM_COUNT_AT_IDX,
                          enif_make_long(env,cto)),
                      enif_make_tuple2(env,
                          ATOM_HIGHEST_EQUIV_VAL,
                          enif_make_long(env,heq)),
                      enif_make_tuple2(env,
                          ATOM_VAL_UNITS_PER_BUCKET,
                          enif_make_int(env,vub)),
                      enif_make_tuple2(env,
                          ATOM_STEP_COUNT,
                          enif_make_long(env,stp)),
                      enif_make_tuple2(env,
                          ATOM_NEXT_VAL_REP_LVL,
                          enif_make_long(env,nvl)),
                      enif_make_tuple2(env,
                          ATOM_NEXT_VAL_REP_LVL_LOW_EQUIV,
                          enif_make_long(env,nve))));
            }
        }
    }

    if (ctx != NULL && ctx->type == HDR_ITER_LOG)
    {
        // skip until first non-zero index
        bool has_next = false;
        while (ctx->iter != NULL && (has_next = hdr_log_iter_next(ctx->iter)))
        {
            struct hdr_log_iter* x = (struct hdr_log_iter*)ctx->iter;
            struct hdr_iter iter = x->iter;
            if (0 != iter.count_at_index)
            {
                int64_t stp = x->count_added_in_this_iteration_step;
                int32_t vfb = x->value_units_first_bucket;
                double lgb = x->log_base;
                int64_t nvl = x->next_value_reporting_level;
                int64_t nve = x->next_value_reporting_level_lowest_equivalent;
                int32_t bdx = iter.bucket_index;
                int64_t sdx = iter.sub_bucket_index;
                int64_t val = iter.value_from_index;
                int64_t cat = iter.count_at_index;
                int64_t cto = iter.count_to_index;
                int64_t heq = iter.highest_equivalent_value;
                return enif_make_tuple2(env,
                  ATOM_LOGARITHMIC,
                  enif_make_list(env, 11,
                      enif_make_tuple2(env,
                          ATOM_BUCKET_IDX,
                          enif_make_int(env,bdx)),
                      enif_make_tuple2(env,
                          ATOM_SUB_BUCKET_IDX,
                          enif_make_long(env,sdx)),
                      enif_make_tuple2(env,
                          ATOM_VAL_FROM_IDX,
                          enif_make_long(env,val)),
                      enif_make_tuple2(env,
                          ATOM_VAL_AT_IDX,
                          enif_make_long(env,cat)),
                      enif_make_tuple2(env,
                          ATOM_COUNT_AT_IDX,
                          enif_make_long(env,cto)),
                      enif_make_tuple2(env,
                          ATOM_HIGHEST_EQUIV_VAL,
                          enif_make_long(env,heq)),
                      enif_make_tuple2(env,
                          ATOM_VAL_UNITS_FIRST_BUCKET,
                          enif_make_int(env,vfb)),
                      enif_make_tuple2(env,
                          ATOM_STEP_COUNT,
                          enif_make_long(env,stp)),
                      enif_make_tuple2(env,
                          ATOM_LOG_BASE,
                          enif_make_double(env,lgb)),
                      enif_make_tuple2(env,
                          ATOM_NEXT_VAL_REP_LVL,
                          enif_make_long(env,nvl)),
                      enif_make_tuple2(env,
                          ATOM_NEXT_VAL_REP_LVL_LOW_EQUIV,
                          enif_make_long(env,nve))));
            }
        }
    }

    if (ctx != NULL && ctx->type == HDR_ITER_PCT)
    {
        // skip until first non-zero index
        bool has_next = false;
        while (ctx->iter != NULL && (has_next = hdr_percentile_iter_next(ctx->iter)))
        {
            struct hdr_percentile_iter* x = (struct hdr_percentile_iter*)ctx->iter;
            struct hdr_iter iter = x->iter;
            if (0 != iter.count_at_index)
            {
                bool slv = x->seen_last_value;
                int32_t tph = x->ticks_per_half_distance;
                double pti = x->percentile_to_iterate_to;
                double pct = x->percentile;
                int32_t bdx = iter.bucket_index;
                int64_t sdx = iter.sub_bucket_index;
                int64_t val = iter.value_from_index;
                int64_t cat = iter.count_at_index;
                int64_t cto = iter.count_to_index;
                int64_t heq = iter.highest_equivalent_value;
                return enif_make_tuple2(env,
                  ATOM_PERCENTILE,
                  enif_make_list(env, 10,
                      enif_make_tuple2(env,
                          ATOM_BUCKET_IDX,
                          enif_make_int(env,bdx)),
                      enif_make_tuple2(env,
                          ATOM_SUB_BUCKET_IDX,
                          enif_make_long(env,sdx)),
                      enif_make_tuple2(env,
                          ATOM_VAL_FROM_IDX,
                          enif_make_long(env,val)),
                      enif_make_tuple2(env,
                          ATOM_VAL_AT_IDX,
                          enif_make_long(env,cat)),
                      enif_make_tuple2(env,
                          ATOM_COUNT_AT_IDX,
                          enif_make_long(env,cto)),
                      enif_make_tuple2(env,
                          ATOM_HIGHEST_EQUIV_VAL,
                          enif_make_long(env,heq)),
                      enif_make_tuple2(env,
                          ATOM_SEEN_LAST_VAL,
                          enif_make_atom(env,slv ? "true" : "false")),
                      enif_make_tuple2(env,
                          ATOM_PERCENTILE_TO_ITERATE_TO,
                          enif_make_double(env,pti)),
                      enif_make_tuple2(env,
                          ATOM_PERCENTILE,
                          enif_make_double(env,pct)),
                      enif_make_tuple2(env,
                          ATOM_TICKS_PER_HALF_DISTANCE,
                          enif_make_int(env,tph))));
            }
        }
    }

    return enif_make_tuple2(
        env,
        ATOM_FALSE,
        enif_make_tuple(env,0)
    );
}
Esempio n. 29
0
ERL_NIF_TERM
json_encode(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    Encoder enc;
    yajl_gen_config config = {0, NULL};
    yajl_gen handle = yajl_gen_alloc(&config, NULL);
    yajl_gen_status status;
    ERL_NIF_TERM ret = enif_make_badarg(env);
    ErlNifBinary bin;
    const unsigned char* json;
    unsigned int jsonlen;
    
    if(argc != 1) goto done;

    if(handle == NULL)
    {
        ret = enif_make_tuple(env, 2,
            enif_make_atom(env, "error"),
            enif_make_atom(env, "memory_error")
        );
        goto done;
    }

    enc.env = env;
    enc.handle = handle;
    enc.error = 0;
    if(enc_json(&enc, argv[0]) == ERROR)
    {
        if(enc.error == 0)
        {
            ret = enif_make_atom(env, "unknown");
        }
        else
        {
            ret = enc.error;
        }
        ret = enif_make_tuple(env, 2,
            enif_make_atom(env, "error"),
            ret
        );
        goto done;
    }

    status = yajl_gen_get_buf(handle, &json, &jsonlen);
    if(status != yajl_gen_status_ok)
    {
        ret = enif_make_tuple(env, 2,
            enif_make_atom(env, "error"),
            enif_make_atom(env, "unknown")
        );
        goto done;
    }
    
    if(!enif_alloc_binary_compat(env, jsonlen, &bin))
    {
        ret = enif_make_atom(env, "memory_error");
        goto done;
    }
    
    memcpy(bin.data, json, jsonlen);
    
    ret = enif_make_tuple(env, 2,
        enif_make_atom(env, "ok"),
        enif_make_binary(env, &bin)
    );

done:
    if(handle != NULL) yajl_gen_free(handle);
    return ret;
}
Esempio n. 30
0
int
enc_json(Encoder* enc, ERL_NIF_TERM term)
{
    int ival;
    unsigned int uival;
    long lval;
    unsigned long ulval;
    double dval;
    ERL_NIF_TERM head;
    ERL_NIF_TERM tail;
    int arity;
    const ERL_NIF_TERM* tuple;
    
    if(enif_is_atom(enc->env, term))
    {
        return enc_atom(enc, term);
    }
    
    if(enif_is_binary(enc->env, term))
    {
        return enc_binary(enc, term);
    }
    
    if(enif_get_int(enc->env, term, &ival))
    {
        if(yajl_gen_integer(enc->handle, ival) != yajl_gen_status_ok)
        {
            enc->error = enif_make_atom(enc->env, "bad_integer");
            return ERROR;
        }
        return OK;
    }
    
    if(enif_get_uint(enc->env, term, &uival))
    {
        if(yajl_gen_integer(enc->handle, uival) != yajl_gen_status_ok)
        {
            enc->error = enif_make_atom(enc->env, "bad_unsigned_integer");
            return ERROR;
        }
        return OK;
    }
    
    if(enif_get_long(enc->env, term, &lval))
    {
        if(yajl_gen_integer(enc->handle, lval) != yajl_gen_status_ok)
        {
            enc->error = enif_make_atom(enc->env, "bad_long");
            return ERROR;
        }
        return OK;
    }
    
    if(enif_get_ulong(enc->env, term, &ulval))
    {
        if(yajl_gen_integer(enc->handle, ulval) != yajl_gen_status_ok)
        {
            enc->error = enif_make_atom(enc->env, "bad_unsigned_long");
            return ERROR;
        }
        return OK;
    }

    if(enif_get_double(enc->env, term, &dval))
    {
        if(yajl_gen_double(enc->handle, dval) != yajl_gen_status_ok)
        {
            enc->error = enif_make_atom(enc->env, "bad_double");
            return ERROR;
        }
        return OK;
    }

    if(enif_is_empty_list(enc->env, term))
    {
        if(yajl_gen_array_open(enc->handle) != yajl_gen_status_ok)
        {
            enc->error = enif_make_atom(enc->env, "failed_to_open_empty_list");
            return ERROR;
        }
        if(yajl_gen_array_close(enc->handle) != yajl_gen_status_ok)
        {
            enc->error = enif_make_atom(enc->env, "failed_to_close_empty_list");
            return ERROR;
        }
        return OK;
    }

    if(enif_get_list_cell(enc->env, term, &head, &tail))
    {
        return enc_array(enc, head, tail);
    }
    
    if(enif_get_tuple(enc->env, term, &arity, &tuple))
    {
        if(arity == 1)
        {
            if(enif_is_empty_list(enc->env, tuple[0]))
            {
                if(yajl_gen_map_open(enc->handle) != yajl_gen_status_ok)
                {
                    enc->error = enif_make_atom(enc->env,
                                                "failed_to_open_empty_map");
                    return ERROR;
                }
                if(yajl_gen_map_close(enc->handle) != yajl_gen_status_ok)
                {
                    enc->error = enif_make_atom(enc->env,
                                                "failed_to_close_empty_map");
                    return ERROR;
                }
                return OK;
            }
            else if(enif_get_list_cell(enc->env, tuple[0], &head, &tail))
            {
                return enc_map(enc, head, tail);
            }
        }
    }

    enc->error = enif_make_tuple(enc->env, 2,
        enif_make_atom(enc->env, "badarg"),
        term
    );
    return ERROR;
}