Esempio n. 1
0
static inline int
enc_double(Encoder* e, double val)
{
    char* start;
    size_t len;
    size_t i;

    if(!enc_ensure(e, 32)) {
        return 0;
    }

    start = &(e->p[e->i]);

    sprintf(start, "%0.20g", val);
    len = strlen(start);

    // Check if we have a decimal point
    for(i = 0; i < len; i++) {
        if(start[i] == '.' || start[i] == 'e' || start[i] == 'E')
            goto done;
    }

    if(len > 29) return 0;

    // Force a decimal point
    start[len++] = '.';
    start[len++] = '0';

done:
    e->i += len;
    e->count++;
    return 1;
}
Esempio n. 2
0
static inline int
enc_char(Encoder* e, char c)
{
    if(!enc_ensure(e, 1)) {
        return 0;
    }

    e->p[e->i++] = c;
    return 1;
}
Esempio n. 3
0
static inline int
enc_literal(Encoder* e, const char* literal, size_t len)
{
    if(!enc_ensure(e, len)) {
        return 0;
    }

    memcpy(&(e->p[e->i]), literal, len);
    e->i += len;
    e->count++;
    return 1;
}
Esempio n. 4
0
static inline int
enc_long(Encoder* e, long val)
{
    if(!enc_ensure(e, 32)) {
        return 0;
    }

    snprintf(&(e->p[e->i]), 32, "%ld", val);
    e->i += strlen(&(e->p[e->i]));
    e->count++;

    return 1;
}
Esempio n. 5
0
static inline int
enc_double(Encoder* e, double val)
{
    if(!enc_ensure(e, 32)) {
        return 0;
    }

    //snprintf(&(e->p[e->i]), 31, "%0.20g", val);
    sprintf(&(e->p[e->i]), "%.20g", val);
    e->i += strlen(&(e->p[e->i]));
    e->count++;

    return 1;
}
Esempio n. 6
0
static inline int
enc_long(Encoder* e, ErlNifSInt64 val)
{
    if(!enc_ensure(e, 32)) {
        return 0;
    }

#if (defined(__WIN32__) || defined(_WIN32) || defined(_WIN32_))
    snprintf(&(e->p[e->i]), 32, "%ld", val);
#elif SIZEOF_LONG == 8
    snprintf(&(e->p[e->i]), 32, "%ld", val);
#else
    snprintf(&(e->p[e->i]), 32, "%lld", val);
#endif

    e->i += strlen(&(e->p[e->i]));
    e->count++;

    return 1;
}
Esempio n. 7
0
static inline int
enc_double(Encoder* e, double val)
{
    char* start;
    size_t len;

    if(!enc_ensure(e, 32)) {
        return 0;
    }

    start = &(e->p[e->i]);

    if(!double_to_shortest(start, e->curr->size, &len, val)) {
        return 0;
    }

    e->i += len;
    e->count++;
    return 1;
}
Esempio n. 8
0
static inline int
enc_string(Encoder* e, ERL_NIF_TERM val)
{
    ErlNifBinary bin;
    char atom[512];

    unsigned char* data;
    size_t size;

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

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

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

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

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

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

                    ulen = unicode_uescape(uval, &(e->p[e->i]));
                    if(ulen < 0) {
                        return 0;
                    }
                    e->i += ulen;

                    ulen = utf8_len(uval);
                    if(ulen < 0) {
                        return 0;
                    }
                    i += ulen;
                } else {
                    e->u[e->i++] = data[i++];
                }
        }
    }

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

    return 1;
}