/* Must be defined before including Perl header files or we slow down by 2x! */
#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#define NEED_newSV_type
#include "ppport.h"
#include "srl_encoder.h"
#include "srl_buffer.h"
/* Generated code for exposing C constants to Perl */
#include "srl_protocol.h"
#include "const-c.inc"
#include "ptable.h"
MODULE = Sereal::Encoder PACKAGE = Sereal::Encoder
PROTOTYPES: DISABLE
srl_encoder_t *
new(CLASS, opt = NULL)
char *CLASS;
HV *opt;
CODE:
RETVAL = srl_build_encoder_struct(aTHX_ opt);
RETVAL->flags |= SRL_F_REUSE_ENCODER;
OUTPUT: RETVAL
void
DESTROY(enc)
srl_encoder_t *enc;
CODE:
srl_destroy_encoder(aTHX_ enc);
void
encode(enc, src)
srl_encoder_t *enc;
SV *src;
PPCODE:
assert(enc != NULL);
srl_dump_data_structure(aTHX_ enc, src);
assert(enc->pos > enc->buf_start);
/* We always copy the string since we might reuse the string buffer. That means
* we already have to do a malloc and we might as well use the opportunity to
* allocate only as much memory as we really need to hold the output. */
ST(0) = sv_2mortal(newSVpvn(enc->buf_start, (STRLEN)BUF_POS_OFS(enc)));
XSRETURN(1);
void
encode_sereal(src, opt = NULL)
SV *src;
HV *opt;
PREINIT:
srl_encoder_t *enc;
PPCODE:
enc = srl_build_encoder_struct(aTHX_ opt);
assert(enc != NULL);
srl_dump_data_structure(aTHX_ enc, src);
/* Avoid copy by stealing string buffer if it is not too large.
* This makes sense in the functional interface since the string
* buffer isn't ever going to be reused. */
assert(enc->buf_start < enc->pos);
if (BUF_POS_OFS(enc) > 20 && BUF_SPACE(enc) < BUF_POS_OFS(enc) ) {
/* If not wasting more than 2x memory - FIXME fungible */
SV *sv = sv_2mortal(newSV_type(SVt_PV));
ST(0) = sv;
SvPV_set(sv, enc->buf_start);
SvLEN_set(sv, BUF_SIZE(enc));
SvCUR_set(sv, BUF_POS_OFS(enc));
SvPOK_on(sv);
enc->buf_start = enc->pos = NULL; /* no need to free these guys now */
}
else {
ST(0) = sv_2mortal(newSVpvn(enc->buf_start, (STRLEN)BUF_POS_OFS(enc)));
}
XSRETURN(1);
MODULE = Sereal::Encoder PACKAGE = Sereal::Encoder::Constants
PROTOTYPES: DISABLE
INCLUDE: const-xs.inc
MODULE = Sereal::Encoder PACKAGE = Sereal::Encoder::_ptabletest
void
test()
PREINIT:
PTABLE_t *tbl;
PTABLE_ITER_t *iter;
PTABLE_ENTRY_t *ent;
UV i, n = 20;
char *check[20];
char fail[5] = "not ";
char noop[1] = "";
CODE:
tbl = PTABLE_new_size(10);
for (i = 0; i < (UV)n; ++i) {
PTABLE_store(tbl, (void *)(1000+i), (void *)(1000+i));
check[i] = fail;
}
for (i = 0; i < (UV)n; ++i) {
const UV res = (UV)PTABLE_fetch(tbl, (void *)(1000+i));
printf("%sok %u - fetch %u\n", (res == (UV)(1000+i)) ? noop : fail, (unsigned int)(1+i), (unsigned int)(i+1));
}
iter = PTABLE_iter_new(tbl);
while ( NULL != (ent = PTABLE_iter_next(iter)) ) {
const UV res = ((UV)ent->value) - 1000;
if (res < 20)
check[res] = noop;
else
abort();
}
for (i = 0; i < (UV)n; ++i) {
printf("%sok %u - iter %u\n", check[i], (unsigned int)(21+i), (unsigned int)(i+1));
}
PTABLE_iter_free(iter);
PTABLE_free(tbl);