Пример #1
0
SLVAL
sl_string_eq(sl_vm_t* vm, SLVAL self, SLVAL other)
{
    if(!sl_is_a(vm, other, vm->lib.String)) {
        return vm->lib._false;
    }
    sl_string_t* a = sl_get_string(vm, self);
    sl_string_t* b = sl_get_string(vm, other);
    return sl_make_bool(vm, str_cmp(vm, a, b) == 0);
}
Пример #2
0
SLVAL
sl_string_concat(sl_vm_t* vm, SLVAL self, SLVAL other)
{
    sl_string_t* a = sl_get_string(vm, self);
    sl_string_t* b = sl_get_string(vm, other);
    uint8_t* buff = (uint8_t*)sl_alloc_buffer(vm->arena, a->buff_len + b->buff_len);
    memcpy(buff, a->buff, a->buff_len);
    memcpy(buff + a->buff_len, b->buff, b->buff_len);
    return sl_make_string(vm, buff, a->buff_len + b->buff_len);
}
Пример #3
0
SLVAL
sl_string_concat(sl_vm_t* vm, SLVAL self, SLVAL other)
{
    sl_string_t* a = sl_get_string(vm, self);
    sl_string_t* b = sl_get_string(vm, other);
    if(strcmp(a->encoding, b->encoding) != 0) {
        return sl_string_concat(vm, self, sl_string_encode(vm, other, a->encoding));
    }
    uint8_t* buff = (uint8_t*)sl_alloc_buffer(vm->arena, a->buff_len + b->buff_len);
    memcpy(buff, a->buff, a->buff_len);
    memcpy(buff + a->buff_len, b->buff, b->buff_len);
    return sl_make_string(vm, buff, a->buff_len + b->buff_len);
}
Пример #4
0
SLVAL
sl_string_html_escape(sl_vm_t* vm, SLVAL self)
{
    sl_string_t* str = sl_get_string(vm, self);
    size_t out_cap = 32;
    size_t out_len = 0;
    size_t str_i;
    uint8_t* out = sl_alloc_buffer(vm->arena, out_cap);
    for(str_i = 0; str_i < str->buff_len; str_i++) {
        if(out_len + 8 >= out_cap) {
            out_cap *= 2;
            out = sl_realloc(vm->arena, out, out_cap);
        }
        if(str->buff[str_i] == '<') {
            memcpy(out + out_len, "&lt;", 4);
            out_len += 4;
        } else if(str->buff[str_i] == '>') {
            memcpy(out + out_len, "&gt;", 4);
            out_len += 4;
        } else if(str->buff[str_i] == '"') {
            memcpy(out + out_len, "&quot;", 6);
            out_len += 6;
        } else if(str->buff[str_i] == '\'') {
            memcpy(out + out_len, "&#039;", 6);
            out_len += 6;
        } else if(str->buff[str_i] == '&') {
            memcpy(out + out_len, "&amp;", 5);
            out_len += 5;
        } else {
            out[out_len++] = str->buff[str_i];
        }
    }
    return sl_make_string(vm, out, out_len);
}
Пример #5
0
SLVAL
sl_string_char_at_index(sl_vm_t* vm, SLVAL self, SLVAL index)
{
    sl_string_t* str = sl_get_string(vm, self);
    if(sl_is_a(vm, index, vm->lib.Range_Inclusive) || sl_is_a(vm, index, vm->lib.Range_Exclusive)) {
        return string_range_index(vm, self, index);
    }
    long idx = sl_get_int(sl_expect(vm, index, vm->lib.Int));
    if(idx < 0) {
        idx += str->char_len;
    }
    if(idx < 0 || idx >= (long)str->char_len) {
        return vm->lib.nil;
    }
    uint8_t* buff_ptr = str->buff;
    size_t len = str->buff_len;
    while(idx) {
        sl_utf8_each_char(vm, &buff_ptr, &len);
        idx--;
    }
    size_t slice_len = 1;
    while(slice_len < len && (buff_ptr[slice_len] & 0xc0) == 0x80) {
        slice_len++;
    }
    return sl_make_string(vm, buff_ptr, slice_len);
}
Пример #6
0
SLVAL
sl_string_url_decode(sl_vm_t* vm, SLVAL self)
{
    sl_string_t* str = sl_get_string(vm, self);
    size_t out_cap = 32;
    size_t out_len = 0;
    uint8_t* out = sl_alloc_buffer(vm->arena, out_cap);
    size_t str_i;
    char tmp[3];
    for(str_i = 0; str_i < str->buff_len; str_i++) {
        if(out_len + 8 >= out_cap) {
            out_cap *= 2;
            out = sl_realloc(vm->arena, out, out_cap);
        }
        if(str->buff[str_i] == '%') {
            if(str_i + 2 < str->buff_len) {
                if(is_hex_char(str->buff[str_i + 1]) && is_hex_char(str->buff[str_i + 2])) {
                    tmp[0] = str->buff[str_i + 1];
                    tmp[1] = str->buff[str_i + 2];
                    tmp[2] = 0;
                    out[out_len++] = strtol(tmp, NULL, 16);
                    str_i += 2;
                    continue;
                }
            }
        }
        if(str->buff[str_i] == '+') {
            out[out_len++] = ' ';
            continue;
        }
        out[out_len++] = str->buff[str_i];
    }
    return sl_make_string(vm, out, out_len);
}
Пример #7
0
SLVAL
sl_regexp_match(sl_vm_t* vm, SLVAL self, size_t argc, SLVAL* argv)
{
    sl_regexp_t* re = get_regexp_check(vm, self);
    sl_string_t* str = sl_get_string(vm, argv[0]);
    int offset = 0, rc, ncaps;
    int* caps;
    sl_regexp_match_t* match;
    if(argc > 1) {
        offset = sl_get_int(sl_expect(vm, argv[1], vm->lib.Int));
    }
    offset = sl_string_byte_offset_for_index(vm, argv[0], offset);
    if(offset < 0) {
        return vm->lib.nil;
    }
    pcre_fullinfo(re->re, re->study, PCRE_INFO_CAPTURECOUNT, &ncaps);
    ncaps += 1;
    ncaps *= 3;
    caps = sl_alloc(vm->arena, sizeof(int) * ncaps);
    rc = pcre_exec(re->re, re->study, (char*)str->buff, str->buff_len, offset, PCRE_NEWLINE_LF, caps, ncaps);
    if(rc == PCRE_ERROR_NOMATCH) {
        return vm->lib.nil;
    }
    check_pcre_error(vm, rc);
    match = (sl_regexp_match_t*)sl_get_ptr(sl_allocate(vm, vm->lib.Regexp_Match));
    match->re = re;
    match->match_string = argv[0];
    match->capture_count = ncaps / 3;
    match->captures = caps;
    return sl_make_ptr((sl_object_t*)match);
}
Пример #8
0
static SLVAL
sl_regexp_init(sl_vm_t* vm, SLVAL self, size_t argc, SLVAL* argv)
{
    sl_regexp_t* re_ptr = get_regexp(vm, self);
    sl_string_t* re = sl_get_string(vm, argv[0]);
    sl_string_t* opts;
    if(argc > 1) {
        opts = sl_get_string(vm, argv[1]);
    } else {
        opts = sl_cstring(vm, "");
    }
    if(re_ptr->re) {
        sl_throw_message2(vm, vm->lib.TypeError, "Cannot reinitialize already initialized Regexp");
    }
    sl_setup_regexp(vm, re_ptr, re->buff, re->buff_len, opts->buff, opts->buff_len);
    return self;
}
Пример #9
0
SLVAL
sl_string_encode(sl_vm_t* vm, SLVAL self, char* encoding)
{
    sl_string_t* str = sl_get_string(vm, self);
    size_t out_len;
    char* out_buff = sl_iconv(vm, (char*)str->buff, str->buff_len, "UTF-8", encoding, &out_len);
    return sl_make_buffer(vm, out_buff, out_len);
}
Пример #10
0
SLVAL
sl_string_times(sl_vm_t* vm, SLVAL self, SLVAL other)
{
    sl_string_t* str = sl_get_string(vm, self);
    long mul = sl_get_int(sl_expect(vm, other, vm->lib.Int));
    if(mul && (size_t)LONG_MAX / mul < str->buff_len) {
        sl_throw_message2(vm, vm->lib.ArgumentError, "String multiplier is too big");
    }
    sl_string_t* new_str = sl_get_string(vm, sl_make_string(vm, NULL, 0));
    new_str->buff_len = str->buff_len * mul;
    new_str->buff = sl_alloc(vm->arena, new_str->buff_len);
    for(size_t i = 0; i < new_str->buff_len; i += str->buff_len) {
        memcpy(new_str->buff + i, str->buff, str->buff_len);
    }
    new_str->char_len = str->char_len * mul;
    return sl_make_ptr((sl_object_t*)new_str);
}
Пример #11
0
static SLVAL
sl_mysql_escape(sl_vm_t* vm, SLVAL self, SLVAL str)
{
    mysql_t* mysql = get_mysql(vm, self);
    sl_string_t* s = sl_get_string(vm, str);
    char* esc = sl_alloc(vm->arena, s->buff_len * 2 + 1);
    size_t esc_len = mysql_real_escape_string(&mysql->mysql, esc, (char*)s->buff, s->buff_len);
    return sl_make_string(vm, (uint8_t*)esc, esc_len);
}
Пример #12
0
SLVAL
sl_string_index(sl_vm_t* vm, SLVAL self, SLVAL substr)
{
    sl_string_t* haystack = sl_get_string(vm, self);
    sl_string_t* needle = sl_get_string(vm, substr);

    /* @TODO use a more efficient algorithm */
    uint8_t* haystack_buff = haystack->buff;
    size_t haystack_len = haystack->buff_len;
    size_t i = 0;
    while(haystack_len >= needle->buff_len) {
        if(memcmp(haystack_buff, needle->buff, needle->buff_len) == 0) {
            return sl_make_int(vm, i);
        }
        sl_utf8_each_char(vm, &haystack_buff, &haystack_len);
        i++;
    }

    return vm->lib.nil;
}
Пример #13
0
SLVAL
sl_string_lower(sl_vm_t* vm, SLVAL selfv)
{
    sl_string_t* self = sl_get_string(vm, selfv);
    sl_string_t* retn = sl_get_string(vm, sl_allocate(vm, vm->lib.String));
    memcpy(retn, self, sizeof(sl_string_t));
    retn->buff = sl_alloc_buffer(vm->arena, retn->buff_len);

    size_t len = self->buff_len;
    uint8_t* buff = self->buff;
    size_t out_offset = 0;
    uint32_t lower_c;

    while(len) {
        uint32_t c = sl_utf8_each_char(vm, &buff, &len);
        lower_c = sl_unicode_tolower(c);
        out_offset += sl_utf32_char_to_utf8(vm, lower_c, retn->buff + out_offset);
    }

    return sl_make_ptr((sl_object_t*)retn);
}
Пример #14
0
SLVAL
sl_string_eq(sl_vm_t* vm, SLVAL self, SLVAL other)
{
    if(!sl_is_a(vm, other, vm->lib.String)) {
        return vm->lib._false;
    }
    sl_string_t* a = sl_get_string(vm, self);
    sl_string_t* b = sl_get_string(vm, other);
    if(a->encoding == b->encoding) {
        if(str_cmp((sl_string_t*)sl_get_ptr(self), (sl_string_t*)sl_get_ptr(other)) == 0) {
            return vm->lib._true;
        } else {
            return vm->lib._false;
        }
    }
    sl_vm_frame_t frame;
    SLVAL err;
    volatile SLVAL retn;
    SL_TRY(frame, SL_UNWIND_EXCEPTION, {
        retn = sl_string_eq(vm, self, sl_string_encode(vm, other, a->encoding));
    }, err, {
Пример #15
0
SLVAL
sl_regexp_is_match(sl_vm_t* vm, SLVAL self, SLVAL other)
{
    sl_regexp_t* re = get_regexp_check(vm, self);
    sl_string_t* str = sl_get_string(vm, other);
    int rc = pcre_exec(re->re, re->study, (char*)str->buff, str->buff_len, 0, PCRE_NEWLINE_LF, NULL, 0);
    if(rc == PCRE_ERROR_NOMATCH) {
        return vm->lib._false;
    }
    check_pcre_error(vm, rc);
    return vm->lib._true;
}
Пример #16
0
static SLVAL
sl_gcrypt_algorithm_hex_digest(sl_vm_t* vm, SLVAL self, SLVAL strv)
{
    size_t i;
    sl_string_t* str = sl_get_string(vm, strv);
    gcrypt_algorithm_t* algo = get_algo_check(vm, self);
    size_t digest_len = gcry_md_get_algo_dlen(algo->algo);
    char* digest = alloca(digest_len);
    char* hex_digest = alloca(digest_len * 2);
    gcry_md_hash_buffer(algo->algo, digest, str->buff, str->buff_len);
    for(i = 0; i < digest_len; i++) {
        sprintf(hex_digest + 2 * i, "%02x", (uint8_t)digest[i]);
    }
    return sl_make_string(vm, (uint8_t*)hex_digest, digest_len * 2);
}
Пример #17
0
int
sl_string_byte_offset_for_index(sl_vm_t* vm, SLVAL strv, int index)
{
    sl_string_t* str = sl_get_string(vm, strv);
    uint8_t* buff = str->buff;
    size_t len = str->buff_len;
    while(len) {
        if(index == 0) {
            return buff - str->buff;
        }
        sl_utf8_each_char(vm, &buff, &len);
        index--;
    }
    return -1;
}
Пример #18
0
SLVAL
sl_string_url_encode(sl_vm_t* vm, SLVAL self)
{
    sl_string_t* str = sl_get_string(vm, self);
    size_t out_cap = 32;
    size_t out_len = 0;
    uint8_t* out = sl_alloc_buffer(vm->arena, out_cap);
    size_t clen = str->buff_len;
    uint8_t* cbuff = str->buff;
    uint32_t c;
    uint8_t utf8buff[8];
    uint32_t utf8len;
    while(clen) {
        if(out_len + 16 >= out_cap) {
            out_cap *= 2;
            out = sl_realloc(vm->arena, out, out_cap);
        }
        c = sl_utf8_each_char(vm, &cbuff, &clen);
        if(c >= 'A' && c <= 'Z') {
            out[out_len++] = c;
            continue;
        }
        if(c >= 'a' && c <= 'z') {
            out[out_len++] = c;
            continue;
        }
        if(c >= '0' && c <= '9') {
            out[out_len++] = c;
            continue;
        }
        if(c == '-' || c == '_' || c == '.' || c == '~') {
            out[out_len++] = c;
            continue;
        }
        if(c == ' ') {
            out[out_len++] = '+';
            continue;
        }
        utf8len = sl_utf32_char_to_utf8(vm, c, utf8buff);
        for(unsigned int i = 0; i < utf8len; i++) {
            sprintf((char*)out + out_len, "%%%2X", utf8buff[i]);
            out_len += 3;
        }
    }
    return sl_make_string(vm, out, out_len);
}
Пример #19
0
SLVAL
sl_string_inspect(sl_vm_t* vm, SLVAL self)
{
    sl_string_t* str = sl_get_string(vm, self);
    size_t out_cap = 32;
    size_t out_len = 0;
    size_t str_i;
    uint8_t* out = sl_alloc_buffer(vm->arena, out_cap);
    out[out_len++] = '"';
    for(str_i = 0; str_i < str->buff_len; str_i++) {
        if(out_len + 8 >= out_cap) {
            out_cap *= 2;
            out = sl_realloc(vm->arena, out, out_cap);
        }
        if(str->buff[str_i] == '"') {
            memcpy(out + out_len, "\\\"", 2);
            out_len += 2;
        } else if(str->buff[str_i] == '\\') {
            memcpy(out + out_len, "\\\\", 2);
            out_len += 2;
        } else if(str->buff[str_i] == '\n') {
            memcpy(out + out_len, "\\n", 2);
            out_len += 2;
        } else if(str->buff[str_i] == '\r') {
            memcpy(out + out_len, "\\r", 2);
            out_len += 2;
        } else if(str->buff[str_i] == '\t') {
            memcpy(out + out_len, "\\t", 2);
            out_len += 2;
        } else if(str->buff[str_i] < 0x20) {
            out[out_len++] = '\\';
            out[out_len++] = 'x';
            out[out_len++] = '0' + str->buff[str_i] / 0x10;
            if(str->buff[str_i] % 0x10 < 10) {
                out[out_len++] = '0' + str->buff[str_i] % 0x10;
            } else {
                out[out_len++] = 'A' + (str->buff[str_i] % 0x10) - 10;
            }
        } else {
            out[out_len++] = str->buff[str_i];
        }
    }
    out[out_len++] = '"';
    return sl_make_string(vm, out, out_len);
}
Пример #20
0
int
sl_string_index_for_byte_offset(sl_vm_t* vm, SLVAL strv, int byte_offset)
{
    sl_string_t* str = sl_get_string(vm, strv);
    uint8_t* buff = str->buff;
    size_t len = str->buff_len;
    int index = 0;
    while(len && byte_offset > 0) {
        size_t old_len = len;
        sl_utf8_each_char(vm, &buff, &len);
        index++;
        byte_offset -= old_len - len;
    }
    if(byte_offset > 0) {
        return -1;
    }
    return index;
}
Пример #21
0
static SLVAL
sl_mysql_prepare(sl_vm_t* vm, SLVAL self, SLVAL query)
{
    mysql_t* mysql = get_mysql(vm, self);
    SLVAL stmtv = sl_allocate(vm, vm->store[cMySQL_Statement]);
    mysql_stmt_t* stmt = sl_data_get_ptr(vm, &mysql_stmt_data_type, stmtv);
    stmt->mysql = mysql;
    if(!(stmt->stmt = mysql_stmt_init(&mysql->mysql))) {
        sl_mysql_check_error(vm, &mysql->mysql);
    }

    sl_string_t* str = sl_get_string(vm, query);
    if(mysql_stmt_prepare(stmt->stmt, (char*)str->buff, str->buff_len)) {
        sl_mysql_stmt_check_error(vm, stmt->stmt);
    }

    return stmtv;
}
Пример #22
0
static SLVAL
string_range_index(sl_vm_t* vm, SLVAL self, SLVAL range)
{
    sl_string_t* str = sl_get_string(vm, self);
    SLVAL lowerv = sl_range_lower(vm, range);
    SLVAL upperv = sl_range_upper(vm, range);
    if(!sl_is_a(vm, lowerv, vm->lib.Int) || !sl_is_a(vm, upperv, vm->lib.Int)) {
        sl_throw_message2(vm, vm->lib.TypeError, "Expected range of integers");
    }
    long lower = sl_get_int(lowerv), upper = sl_get_int(upperv);
    if(lower < 0) {
        lower += str->char_len;
    }
    if(lower < 0 || (size_t)lower >= str->char_len) {
        return sl_make_cstring(vm, "");
    }
    if(upper < 0) {
        upper += str->char_len;
    }
    if(upper < 0) {
        return sl_make_cstring(vm, "");
    }
    if(sl_range_is_exclusive(vm, range)) {
        upper--;
    }
    if(upper < lower) {
        return sl_make_cstring(vm, "");
    }
    uint8_t* begin_ptr = str->buff;
    uint8_t* end_ptr;
    size_t len = str->buff_len;
    long idx = 0;
    while(idx < lower && len) {
        idx++;
        sl_utf8_each_char(vm, &begin_ptr, &len);
    }
    end_ptr = begin_ptr;
    while(lower <= upper) {
        lower++;
        sl_utf8_each_char(vm, &end_ptr, &len);
    }
    return sl_make_string(vm, begin_ptr, (size_t)end_ptr - (size_t)begin_ptr);
}
Пример #23
0
static SLVAL
sl_mysql_raw_query(sl_vm_t* vm, SLVAL self, SLVAL query)
{
    mysql_t* mysql = get_mysql(vm, self);
    sl_string_t* str = sl_get_string(vm, query);

    if(mysql_real_query(&mysql->mysql, (char*)str->buff, str->buff_len)) {
        sl_mysql_check_error(vm, &mysql->mysql);
    }

    MYSQL_RES* result;
    if((result = mysql_store_result(&mysql->mysql))) {
        /* do shit */
        int ncolumns = mysql_num_fields(result);
        int nrows = mysql_num_rows(result);
        SLVAL* rows = sl_alloc(vm->arena, sizeof(SLVAL) * nrows);
        MYSQL_FIELD* fields = mysql_fetch_fields(result);
        for(int i = 0; i < nrows; i++) {
            SLVAL* cells = sl_alloc(vm->arena, sizeof(SLVAL) * ncolumns * 2);
            MYSQL_ROW row = mysql_fetch_row(result);
            size_t* lengths = mysql_fetch_lengths(result);
            for(int j = 0; j < ncolumns; j++) {
                cells[j * 2] = sl_make_cstring(vm, fields[j].name);
                if(row[j]) {
                    cells[j * 2 + 1] = sl_make_string(vm, (uint8_t*)row[j], lengths[j]);
                } else {
                    cells[j * 2 + 1] = vm->lib.nil;
                }
            }
            rows[i] = sl_make_dict(vm, ncolumns, cells);
        }
        mysql_free_result(result);
        return sl_make_array(vm, nrows, rows);
    } else {
        if(mysql_field_count(&mysql->mysql) != 0) {
            sl_mysql_check_error(vm, &mysql->mysql);
        }
        return sl_make_int(vm, mysql_affected_rows(&mysql->mysql));
    }
}
Пример #24
0
SLVAL
sl_regexp_match(sl_vm_t* vm, SLVAL self, size_t argc, SLVAL* argv)
{
    sl_regexp_t* re = get_regexp_check(vm, self);
    sl_string_t* str = sl_get_string(vm, argv[0]);
    int offset = 0, rc, ncaps;
    int* caps;
    char err_buff[256];
    sl_regexp_match_t* match;
    if(argc > 1) {
        offset = sl_get_int(sl_expect(vm, argv[1], vm->lib.Int));
    }
    offset = sl_string_byte_offset_for_index(vm, argv[0], offset);
    if(offset < 0) {
        return vm->lib.nil;
    }
    pcre_fullinfo(re->re, re->study, PCRE_INFO_CAPTURECOUNT, &ncaps);
    ncaps += 1;
    ncaps *= 3;
    caps = sl_alloc(vm->arena, sizeof(int) * ncaps);
    rc = pcre_exec(re->re, re->study, (char*)str->buff, str->buff_len, offset, PCRE_NEWLINE_LF, caps, ncaps);
    if(rc < 0) {
        if(rc == PCRE_ERROR_NOMATCH) {
            return vm->lib.nil;
        }
        if(rc == PCRE_ERROR_BADUTF8) {
            sl_throw_message2(vm, vm->lib.EncodingError, "Invalid UTF-8 in regular expression or match text");
        }
        sprintf(err_buff, "PCRE error (%d)", rc);
        sl_throw_message2(vm, vm->lib.Error, err_buff);
    }
    match = (sl_regexp_match_t*)sl_get_ptr(sl_allocate(vm, vm->lib.Regexp_Match));
    match->re = re;
    match->match_string = argv[0];
    match->capture_count = ncaps / 3;
    match->captures = caps;
    return sl_make_ptr((sl_object_t*)match);
}
Пример #25
0
static SLVAL
sl_mysql_stmt_execute(sl_vm_t* vm, SLVAL self, size_t argc, SLVAL* argv)
{
    mysql_stmt_t* stmt = get_mysql_stmt(vm, self);
    size_t req = mysql_stmt_param_count(stmt->stmt);
    if(argc < req) {
        char buff[100];
        sprintf(buff, "Prepared statement has %lu parameter markers, but only %lu parameters were given", req, argc);
        sl_throw_message2(vm, vm->lib.ArgumentError, buff);
    }

    if(!stmt->bind) {
        stmt->bind = sl_alloc(vm->arena, sizeof(MYSQL_BIND) * req);
    }

    for(size_t i = 0; i < req; i++) {
        stmt->bind[i].buffer_type = MYSQL_TYPE_STRING;
        sl_string_t* str = sl_get_string(vm, sl_to_s(vm, argv[i]));
        stmt->bind[i].buffer = str->buff;
        stmt->bind[i].buffer_length = str->buff_len;
        stmt->bind[i].length = NULL;
        stmt->bind[i].is_null = NULL;
        stmt->bind[i].is_unsigned = 1;
        stmt->bind[i].error = NULL;
    }

    if(mysql_stmt_bind_param(stmt->stmt, stmt->bind)) {
        sl_mysql_stmt_check_error(vm, stmt->stmt);
    }

    if(mysql_stmt_execute(stmt->stmt)) {
        sl_mysql_stmt_check_error(vm, stmt->stmt);
    }

    MYSQL_RES* res = mysql_stmt_result_metadata(stmt->stmt);
    if(!res) {
        /* query did not produce a result set */
        return sl_make_int(vm, mysql_stmt_affected_rows(stmt->stmt));
    }

    int field_count = mysql_stmt_field_count(stmt->stmt);
    MYSQL_FIELD* field;
    SLVAL field_names[field_count];
    enum enum_field_types field_types[field_count];
    size_t field_i = 0;
    while((field = mysql_fetch_field(res))) {
        field_names[field_i] = sl_make_cstring(vm, field->name);
        if(field->type == MYSQL_TYPE_LONG || field->type == MYSQL_TYPE_SHORT || field->type == MYSQL_TYPE_TINY) {
            field_types[field_i] = MYSQL_TYPE_LONG;
        } else {
            field_types[field_i] = MYSQL_TYPE_STRING;
        }
        field_i++;
    }

    MYSQL_BIND output_binds[field_count];
    my_bool output_errors[field_count];
    my_bool output_is_nulls[field_count];
    unsigned long output_lengths[field_count];
    for(int i = 0; i < field_count; i++) {
        output_binds[i].buffer_type = MYSQL_TYPE_STRING;
        output_binds[i].buffer = NULL;
        output_binds[i].buffer_length = 0;
        output_binds[i].length = &output_lengths[i];
        output_binds[i].is_null = &output_is_nulls[i];
        output_binds[i].error = &output_errors[i];
    }
    if(mysql_stmt_bind_result(stmt->stmt, output_binds)) {
        sl_mysql_stmt_check_error(vm, stmt->stmt);
    }

    SLVAL result_rows = sl_make_array(vm, 0, NULL);
    while(1) {
        int code = mysql_stmt_fetch(stmt->stmt);
        if(code == MYSQL_NO_DATA) {
            break;
        }
        if(code == 1) {
            sl_mysql_stmt_check_error(vm, stmt->stmt);
        }
        SLVAL row = sl_make_dict(vm, 0, NULL);
        for(int i = 0; i < field_count; i++) {
            MYSQL_BIND cell;
            cell.length = &output_lengths[i];
            cell.is_null = &output_is_nulls[i];
            cell.error = &output_errors[i];
            cell.buffer_type = field_types[i];
            int buffer_long;
            switch(field_types[i]) {
                case MYSQL_TYPE_LONG:
                    cell.buffer = &buffer_long;
                    cell.buffer_length = sizeof(buffer_long);
                    break;
                default: /* MYSQL_TYPE_STRING */
                    cell.buffer = sl_alloc_buffer(vm->arena, output_lengths[i] + 1);
                    cell.buffer_length = output_lengths[i];
                    break;
            }
            if(mysql_stmt_fetch_column(stmt->stmt, &cell, i, 0)) {
                sl_mysql_stmt_check_error(vm, stmt->stmt);
            }
            switch(field_types[i]) {
                case MYSQL_TYPE_LONG:
                    sl_dict_set(vm, row, field_names[i], sl_make_int(vm, buffer_long));
                    break;
                default: /* MYSQL_TYPE_STRING */
                    sl_dict_set(vm, row, field_names[i], sl_make_string(vm, cell.buffer, output_lengths[i]));
                    break;
            }
        }
        sl_array_push(vm, result_rows, 1, &row);
    }

    return result_rows;
}
Пример #26
0
SLVAL
sl_string_length(sl_vm_t* vm, SLVAL self)
{
    return sl_make_int(vm, sl_get_string(vm, self)->char_len);
}
Пример #27
0
static SLVAL
sl_string_hash(sl_vm_t* vm, SLVAL self)
{
    return sl_make_int(vm, str_hash(vm, sl_get_string(vm, self)));
}
Пример #28
0
static SLVAL
sl_string_spaceship(sl_vm_t* vm, SLVAL self, SLVAL other)
{
    return sl_make_int(vm, str_cmp(vm, sl_get_string(vm, self), sl_get_string(vm, other)));
}
Пример #29
0
static SLVAL
sl_string_to_i(sl_vm_t* vm, SLVAL self)
{
    sl_string_t* str = sl_get_string(vm, self);
    return sl_integer_parse(vm, str->buff, str->buff_len);
}
Пример #30
-6
Файл: json.c Проект: Hmaal/slash
static SLVAL
sl_json_parse(sl_vm_t* vm, SLVAL self, size_t argc, SLVAL* argv)
{
    sl_string_t* str = sl_get_string(vm, argv[0]);
    json_parse_t json;
    yajl_alloc_funcs alloc_funcs = {
        sl_yajl_alloc,
        sl_yajl_realloc,
        sl_yajl_free,
        NULL
    };
    alloc_funcs.ctx = vm->arena;
    json.vm = vm;
    json.max_depth = 32;
    json.stack_len = 0;
    json.stack_cap = 32;
    json.stack = sl_alloc(vm->arena, sizeof(SLVAL) * json.stack_cap);
    json.type_stack = sl_alloc(vm->arena, json.stack_cap);
    if(argc > 1) {
        json.max_depth = sl_get_int(sl_expect(vm, argv[1], vm->lib.Int));
    }
    
    json.yajl = yajl_alloc(&callbacks, &alloc_funcs, &json);
    sl_json_parse_check_error(vm, str, &json, yajl_parse(json.yajl, str->buff, str->buff_len));
    sl_json_parse_check_error(vm, str, &json, yajl_complete_parse(json.yajl));
    yajl_free(json.yajl);

    /* must've been OK! */
    return json.stack[0];
        
    (void)self;
}