Cassandra-Client

 view release on metacpan or  search on metacpan

Client.xs  view on Meta::CPAN

#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"

#include <stdint.h>
#include "define.h"
#include "type.h"
#include "proto.h"
#include "decode.h"
#include "encode.h"

typedef struct {
    int column_count;
    int uniq_column_count;
    struct cc_column *columns;
} Cassandra__Client__RowMeta;

MODULE = Cassandra::Client  PACKAGE = Cassandra::Client::Protocol
PROTOTYPES: DISABLE

void
unpack_metadata(protocol_version, is_result, data)
    int protocol_version
    int is_result
    SV *data
  PPCODE:
    STRLEN pos, size;
    unsigned char *ptr;
    int32_t flags, column_count, uniq_column_count;
    Cassandra__Client__RowMeta *row_meta;

    ST(0) = &PL_sv_undef; /* Will have our RowMeta instance */
    ST(1) = &PL_sv_undef; /* Will have our paging state */

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

    if (UNLIKELY(!ptr))
        croak("Missing data argument to unpack_metadata");
    if (UNLIKELY(protocol_version != 3 && protocol_version != 4))
        croak("Invalid protocol version");

    flags = unpack_int(aTHX_ ptr, size, &pos);
    column_count = unpack_int(aTHX_ ptr, size, &pos);

    if (protocol_version >= 4 && !is_result) {
        int i, pk_count;

        pk_count = unpack_int(aTHX_ ptr, size, &pos);
        if (UNLIKELY(pk_count < 0))
            croak("Protocol error: pk_count<0");

        for (i = 0; i < pk_count; i++) {
            // Read the short, but throw it away for now.
            unpack_short(aTHX_ ptr, size, &pos);
        }
    }

    if (UNLIKELY(flags < 0 || flags > 7))
        croak("Invalid protocol data passed to unpack_metadata (reason: invalid flags)");
    if (UNLIKELY(column_count < 0))
        croak("Invalid protocol data passed to unpack_metadata (reason: invalid column count)");

    if (flags & CC_METADATA_FLAG_HAS_MORE_PAGES) {
        ST(1) = unpack_bytes_sv(aTHX_ ptr, size, &pos);
        sv_2mortal(ST(1));
    }

    if (!(flags & CC_METADATA_FLAG_NO_METADATA)) {
        int i, have_global_spec;
        SV *global_keyspace, *global_table;
        HV *name_hash;

        have_global_spec = flags & CC_METADATA_FLAG_GLOBAL_TABLES_SPEC;

        if (have_global_spec) {
            global_keyspace = unpack_string_sv(aTHX_ ptr, size, &pos);
            sv_2mortal(global_keyspace);
            global_table = unpack_string_sv(aTHX_ ptr, size, &pos);
            sv_2mortal(global_table);
        }

        Newxz(row_meta, 1, Cassandra__Client__RowMeta);
        ST(0) = sv_newmortal();
        sv_setref_pv(ST(0), "Cassandra::Client::RowMetaPtr", (void*)row_meta);



( run in 0.405 second using v1.01-cache-2.11-cpan-71847e10f99 )