#define PERL_CODE /*
# To test this run
# cc -o test.o test.c `perl -MExtUtils::Embed -e ccopts -e ldopts` && ./test.o | perl test.c
use Storable qw(thaw);
use Data::Dumper;
local $/ = undef;
my $b = <STDIN>;
print Dumper(thaw($b))."\n";
__END__
                  */
#include <EXTERN.h>
#include <perl.h>
#include <string.h>
/***    The Perl interpreter    ***/
static PerlInterpreter *my_perl;

int storable_freeze(char** output, SV* data) {
        dSP;
        ENTER;
        SAVETMPS;
        STRLEN len;
        PUSHMARK(SP);
        XPUSHs(newRV_inc((SV*)data));
        PUTBACK;
        call_pv("Storable::freeze",G_SCALAR);
        SPAGAIN;
        SV* serialized = POPs;
        PUTBACK;
        char *ret = SvPV(serialized,len);
        *output = malloc(len);
        memcpy(*output,ret,len);
        FREETMPS;
        LEAVE;
        return len;
}

void test_storable() {
        dSP;
        ENTER;
        SAVETMPS;
        AV* data = (AV*)sv_2mortal((SV*)newAV());
        int i;
        for (i = 0; i < 3; i++) {
                HV* hash = (HV*)newHV();
                U32 ret = 0;
                hv_store(hash,"ASDFGH",6,newSViv(i),ret);
                hv_store(hash,"ASDFGHIJ",8,newSViv(i),ret);
                av_push(data,newRV_noinc((SV*)hash));
        }
        char* serialized;
        int len = storable_freeze(&serialized,(SV*)data);
        write(1,serialized,len);
        free(serialized);
        FREETMPS;
        LEAVE;
}


EXTERN_C void xs_init (pTHX);
EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);
EXTERN_C void xs_init(pTHX) {
	char *file = __FILE__;
	dXSUB_SYS;
	newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
}
int main(int argc, char** argv, char** env) {
        PERL_SYS_INIT3(&argc,&argv,&env);
        my_perl = perl_alloc();
        perl_construct(my_perl);
        PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
        char *embedding[] = { "", "-e", "0" };
        perl_parse(my_perl, xs_init, 3, embedding, (char **)NULL);

        SV* module = newSVpv("Storable",8);
        load_module(PERL_LOADMOD_NOIMPORT,module,NULL);
        
        test_storable();

        perl_destruct(my_perl);
        perl_free(my_perl);
        PERL_SYS_TERM();
        return 0;
}
