Cassandra-Client

 view release on metacpan or  search on metacpan

Client.xs  view on Meta::CPAN

            } else {
                column->keyspace = unpack_string_sv(aTHX_ ptr, size, &pos);
                column->table = unpack_string_sv(aTHX_ ptr, size, &pos);
            }

            column->name = unpack_string_sv_hash(aTHX_ ptr, size, &pos, &column->name_hash);
            unpack_type(aTHX_ ptr, size, &pos, &column->type);
            if (!hv_exists_ent(name_hash, column->name, column->name_hash)) {
                uniq_column_count++;
                hv_store_ent(name_hash, column->name, &PL_sv_undef, column->name_hash);
            }
        }

        row_meta->uniq_column_count = uniq_column_count;
    }

    sv_chop(data, (char*)ptr+pos);

    XSRETURN(2);

MODULE = Cassandra::Client  PACKAGE = Cassandra::Client::RowMetaPtr

AV*
decode(self, data, use_hashes)
    Cassandra::Client::RowMeta *self
    SV *data
    int use_hashes
  CODE:
    STRLEN size, pos;
    unsigned char *ptr;
    int32_t row_count;
    int i, j, col_count;
    struct cc_column *columns;

    RETVAL = newAV();
    sv_2mortal((SV*)RETVAL); /* work around a bug in perl */

    ptr = (unsigned char*)SvPV(data, size);
    pos = 0;

    if (UNLIKELY(!ptr))
        croak("Invalid input to decode()");

    col_count = self->column_count;
    columns = self->columns;

    row_count = unpack_int(aTHX_ ptr, size, &pos);

    /* This came up while fuzzing: when we have 1000000 rows but no columns, we
     * just flood the memory with empty arrays/hashes. Let's just reject this
     * corner case. If you need this, please contact the author! */
    if (UNLIKELY(row_count > 1000 && !col_count))
        croak("Refusing to decode %d rows without known column information", row_count);

    for (i = 0; i < row_count; i++) {
        if (use_hashes) {
            HV *this_row = newHV();
            av_push(RETVAL, newRV_noinc((SV*)this_row));

            for (j = 0; j < col_count; j++) {
                SV *decoded = newSV(0);
                hv_store_ent(this_row, columns[j].name, decoded, columns[j].name_hash);

                decode_cell(aTHX_ ptr, size, &pos, &columns[j].type, decoded);
            }

        } else {
            AV *this_row = newAV();
            av_push(RETVAL, newRV_noinc((SV*)this_row));

            for (j = 0; j < col_count; j++) {
                SV *decoded = newSV(0);
                av_push(this_row, decoded);

                decode_cell(aTHX_ ptr, size, &pos, &columns[j].type, decoded);
            }
        }
    }

  OUTPUT:
    RETVAL

SV*
encode(self, row)
    Cassandra::Client::RowMeta *self
    SV* row
  CODE:
    int column_count, i, use_hash;
    STRLEN size_estimate;
    AV *row_a;
    HV *row_h;

    if (UNLIKELY(row == NULL))
        croak("row must be passed");
    if (UNLIKELY(!SvROK(row)))
        croak("encode: argument must be a reference");

    column_count = self->column_count;

    if (SvTYPE(SvRV(row)) == SVt_PVAV) {
        row_a = (AV*)SvRV(row);
        use_hash = 0;
        if (UNLIKELY((av_len(row_a)+1) != column_count))
            croak("row encoder expected %d column(s), but got %d", column_count, ((int)av_len(row_a))+1);

    } else if (SvTYPE(SvRV(row)) == SVt_PVHV) {
        row_h = (HV*)SvRV(row);
        use_hash = 1;
        if (UNLIKELY(HvUSEDKEYS(row_h) != self->uniq_column_count))
            croak("row encoder expected %d column(s), but got %d", self->uniq_column_count, (int)HvUSEDKEYS(row_h));

    } else {
        croak("encode: argument must be an ARRAY or HASH reference");
    }

    /* Rough estimate. We only use it to predict Sv size, we don't rely on it being accurate.
       If we overshoot, we waste some memory, and if we undershoot we copy a bit too often. */
    size_estimate = 2 + (column_count * 12);
    if (size_estimate <= 0) /* overflows aren't impossible, I guess */
        size_estimate = 0; /* wing it */

    RETVAL = newSV(size_estimate);
    sv_setpvn(RETVAL, "", 0);
    pack_short(aTHX_ RETVAL, column_count);

    if (!use_hash) {
        for (i = 0; i < column_count; i++) {
            SV **maybe_cell = av_fetch(row_a, i, 0);
            if (UNLIKELY(maybe_cell == NULL))
                croak("row encoder error. bailing out");
            encode_cell(aTHX_ RETVAL, *maybe_cell, &self->columns[i].type);
        }

    } else {
        for (i = 0; i < column_count; i++) {



( run in 1.139 second using v1.01-cache-2.11-cpan-2398b32b56e )