#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "byterun.h" /* Something arbitary for a buffer size */ #define BYTELOADER_BUFFER 8096 int bl_getc(struct byteloader_fdata *data) 4482 { dTHX; 4482 if (SvCUR(data->datasv) <= (STRLEN)data->next_out) { ###### int result; /* Run out of buffered data, so attempt to read some more */ ###### *(SvPV_nolen (data->datasv)) = '\0'; ###### SvCUR_set (data->datasv, 0); ###### data->next_out = 0; ###### result = FILTER_READ (data->idx + 1, data->datasv, BYTELOADER_BUFFER); /* Filter returned error, or we got EOF and no data, then return EOF. Not sure if filter is allowed to return EOF and add data simultaneously Think not, but will bullet proof against it. */ ###### if (result < 0 || SvCUR(data->datasv) == 0) ###### return EOF; /* Else there must be at least one byte present, which is good enough */ } 4482 return *((U8 *) SvPV_nolen (data->datasv) + data->next_out++); } int bl_read(struct byteloader_fdata *data, char *buf, size_t size, size_t n) 2463 { dTHX; 2463 char *start; 2463 STRLEN len; 2463 size_t wanted = size * n; 2463 start = SvPV (data->datasv, len); 2463 if (len < (data->next_out + wanted)) { 19 int result; /* Shuffle data to start of buffer */ 19 len -= data->next_out; 19 if (len) { ###### memmove (start, start + data->next_out, len + 1); } else { 19 *start = '\0'; /* Avoid call to memmove. */ } 19 SvCUR_set(data->datasv, len); 19 data->next_out = 0; /* Attempt to read more data. */ 19 do { 19 result = FILTER_READ (data->idx + 1, data->datasv, BYTELOADER_BUFFER); 19 start = SvPV (data->datasv, len); 19 } while (result > 0 && len < wanted); /* Loop while not (EOF || error) and short reads */ /* If not enough data read, truncate copy */ 19 if (wanted > len) ###### wanted = len; } 2463 if (wanted > 0) { 2463 memcpy (buf, start + data->next_out, wanted); 2463 data->next_out += wanted; 2463 wanted /= size; } 2463 return (int) wanted; } static I32 byteloader_filter(pTHX_ int idx, SV *buf_sv, int maxlen) 19 { 19 OP *saveroot = PL_main_root; 19 OP *savestart = PL_main_start; 19 struct byteloader_state bstate; 19 struct byteloader_fdata data; 19 int len; 19 (void)buf_sv; 19 (void)maxlen; 19 data.next_out = 0; 19 data.datasv = FILTER_DATA(idx); 19 data.idx = idx; 19 bstate.bs_fdata = &data; 19 bstate.bs_obj_list = Null(void**); 19 bstate.bs_obj_list_fill = -1; 19 bstate.bs_sv = Nullsv; 19 bstate.bs_iv_overflows = 0; /* KLUDGE */ 19 if (byterun(aTHX_ &bstate) && (len = SvCUR(data.datasv) - (STRLEN)data.next_out)) { 1 PerlIO_seek(PL_rsfp, -len, SEEK_CUR); 1 PL_rsfp = NULL; } 19 filter_del(byteloader_filter); 19 if (PL_in_eval) { ###### OP *o; ###### PL_eval_start = PL_main_start; ###### o = newSVOP(OP_CONST, 0, newSViv(1)); ###### PL_eval_root = newLISTOP(OP_LINESEQ, 0, PL_main_root, o); ###### PL_main_root->op_next = o; ###### PL_eval_root = newUNOP(OP_LEAVEEVAL, 0, PL_eval_root); ###### o->op_next = PL_eval_root; ###### PL_main_root = saveroot; ###### PL_main_start = savestart; } 19 return 0; } MODULE = ByteLoader PACKAGE = ByteLoader PROTOTYPES: ENABLE void import(package="ByteLoader", ...) char *package PREINIT: 19 SV *sv = newSVpvn ("", 0); PPCODE: 19 if (!sv) ###### croak ("Could not allocate ByteLoader buffers"); 19 filter_add(byteloader_filter, sv);