Cassandra-Client

 view release on metacpan or  search on metacpan

decode.c  view on Meta::CPAN

void decode_utf8(pTHX_ unsigned char *input, STRLEN len, struct cc_type *type, SV *output)
{
    sv_setpvn(output, (char*)input, len);
    SvUTF8_on(output);
}

void decode_boolean(pTHX_ unsigned char *input, STRLEN len, struct cc_type *type, SV *output)
{
    if (UNLIKELY(len != 1))
        croak("decode_boolean: len != 1");

    if (*input)
        sv_setsv(output, &PL_sv_yes);
    else
        sv_setsv(output, &PL_sv_no);
}

void decode_inet(pTHX_ unsigned char *input, STRLEN len, struct cc_type *type, SV *output)
{
    if (len == 4) {
        char str[INET_ADDRSTRLEN];
        inet_ntop(AF_INET, (char*)input, str, INET_ADDRSTRLEN);
        sv_setpv(output, str);

    } else if (len == 16) {
        char str[INET6_ADDRSTRLEN];
        inet_ntop(AF_INET6, (char*)input, str, INET6_ADDRSTRLEN);
        sv_setpv(output, str);

    } else {
        croak("decode_inet: len != (4|16)");
    }
}

void decode_list(pTHX_ unsigned char *input, STRLEN len, struct cc_type *type, SV *output)
{
    struct cc_type *inner_type;
    int i;
    AV *the_list;
    SV *the_rv;
    STRLEN pos;

    inner_type = type->inner_type;
    assert(inner_type);

    if (UNLIKELY(len < 4))
        croak("decode_list: len < 4");

    int32_t num_elements = (int32_t)ntohl(*(uint32_t*)(input));
    if (UNLIKELY(num_elements < 0))
        croak("decode_list: num_elements < 0");

    the_list = newAV();
    the_rv = newRV_noinc((SV*)the_list);
    sv_setsv(output, the_rv);
    SvREFCNT_dec(the_rv);

    pos = 4;

    for (i = 0; i < num_elements; i++) {
        SV *decoded = newSV(0);
        av_push(the_list, decoded);

        decode_cell(aTHX_ input, len, &pos, inner_type, decoded);
    }
}

void decode_uuid(pTHX_ unsigned char *input, STRLEN len, struct cc_type *type, SV *output)
{
    if (UNLIKELY(len != 16))
        croak("decode_uuid: len != 16");

    sv_setpvf(output, "%.2x%.2x%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x",
        input[0],  input[1],  input[2],  input[3],
        input[4],  input[5],  input[6],  input[7],
        input[8],  input[9],  input[10], input[11],
        input[12], input[13], input[14], input[15]);
}

void decode_decimal(pTHX_ unsigned char *input, STRLEN len, struct cc_type *type, SV *output)
{
    union {
        unsigned char bytes[4];
        int32_t scale;
    } bytes_or_scale;

    if (UNLIKELY(len < 5))
        croak("decode_decimal: len < 5");

    memcpy(bytes_or_scale.bytes, input, 4);
    bswap4(bytes_or_scale.bytes);
    bytes_or_scale.scale *= -1;

    decode_varint(aTHX_ input+4, len-4, type, output);
    if (bytes_or_scale.scale != 0) {
        char *sign;
        if (bytes_or_scale.scale > 0) {
            sign = "+";
        } else {
            sign = "";
        }
        sv_catpvf(output, "e%s%d", sign, bytes_or_scale.scale);
    }
}

void decode_varint(pTHX_ unsigned char *input, STRLEN len, struct cc_type *type, SV *output)
{
    if (UNLIKELY(len <= 0)) {
        croak("decode_varint: len <= 0");
    } else if (len == 1) {
        decode_tinyint(aTHX_ input, len, type, output);
    } else if (len == 2) {
        decode_smallint(aTHX_ input, len, type, output);
    } else if (len == 3) {
        unsigned char bytes[4];
        memcpy(bytes+1, input, 3);
        if (input[0] & 0x80) {
            bytes[0] = 0xff;
        } else {
            bytes[0] = 0;
        }
        decode_int(aTHX_ bytes, 4, type, output);
    } else if (len == 4) {
        decode_int(aTHX_ input, len, type, output);

decode.c  view on Meta::CPAN


        decode_cell(aTHX_ input, len, &pos, value_type, value);
    }
}

void decode_udt(pTHX_ unsigned char *input, STRLEN len, struct cc_type *type, SV *output)
{
    struct cc_udt *udt;
    int i;
    STRLEN pos;
    HV *the_obj;
    SV *the_rv;

    the_obj = newHV();
    the_rv = newRV_noinc((SV*)the_obj);
    sv_setsv(output, the_rv);
    SvREFCNT_dec(the_rv);

    udt = type->udt;
    assert(udt && udt->fields);

    pos = 0;

    for (i = 0; i < udt->field_count; i++) {
        if (len == pos) {
            break;
        }

        struct cc_udt_field *field;
        SV *value;

        field = &udt->fields[i];
        value = newSV(0);

        hv_store_ent(the_obj, field->name, value, field->name_hash);

        decode_cell(aTHX_ input, len, &pos, &field->type, value);
    }
}

void decode_tuple(pTHX_ unsigned char *input, STRLEN len, struct cc_type *type, SV *output)
{
    SV *the_rv;
    AV *the_tuple;
    struct cc_tuple *tuple;
    int i;
    STRLEN pos;

    the_tuple = newAV();
    the_rv = newRV_noinc((SV*)the_tuple);
    sv_setsv(output, the_rv);
    SvREFCNT_dec(the_rv);

    tuple = type->tuple;
    assert(tuple);

    pos = 0;

    for (i = 0; i < tuple->field_count; i++) {
        struct cc_type *type = &tuple->fields[i];
        SV *decoded = newSV(0);
        av_push(the_tuple, decoded);

        decode_cell(aTHX_ input, len, &pos, type, decoded);
    }
}



( run in 0.566 second using v1.01-cache-2.11-cpan-39bf76dae61 )