diff options
Diffstat (limited to 'ext/ByteLoader/ByteLoader.xs')
-rw-r--r-- | ext/ByteLoader/ByteLoader.xs | 103 |
1 files changed, 25 insertions, 78 deletions
diff --git a/ext/ByteLoader/ByteLoader.xs b/ext/ByteLoader/ByteLoader.xs index d3b435199e..7c3746bba7 100644 --- a/ext/ByteLoader/ByteLoader.xs +++ b/ext/ByteLoader/ByteLoader.xs @@ -4,74 +4,31 @@ #include "XSUB.h" #include "byterun.h" -/* Something arbitary for a buffer size */ -#define BYTELOADER_BUFFER 8096 - -int -bl_getc(struct byteloader_fdata *data) +static int +xgetc(PerlIO *io) { dTHX; - if (SvCUR(data->datasv) <= 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 */ - } - - return *((char *) SvPV_nolen (data->datasv) + data->next_out++); + return PerlIO_getc(io); } -int -bl_read(struct byteloader_fdata *data, char *buf, size_t size, size_t n) +static int +xfread(char *buf, size_t size, size_t n, PerlIO *io) { dTHX; - char *start; - STRLEN len; - size_t wanted = size * n; - - start = SvPV (data->datasv, len); - if (len < (data->next_out + wanted)) { - int result; - - /* Shuffle data to start of buffer */ - len -= data->next_out; - if (len) { - memmove (start, start + data->next_out, len + 1); - SvCUR_set (data->datasv, len); - } else { - *start = '\0'; /* Avoid call to memmove. */ - SvCUR_set (data->datasv, 0); - } - data->next_out = 0; - - /* Attempt to read more data. */ - do { - result = FILTER_READ (data->idx + 1, data->datasv, BYTELOADER_BUFFER); - - start = SvPV (data->datasv, len); - } while (result > 0 && len < wanted); - /* Loop while not (EOF || error) and short reads */ - - /* If not enough data read, truncate copy */ - if (wanted > len) - wanted = len; - } + int i = PerlIO_read(io, buf, n * size); + if (i > 0) + i /= size; + return i; +} - if (wanted > 0) { - memcpy (buf, start + data->next_out, wanted); - data->next_out += wanted; - wanted /= size; - } - return (int) wanted; +static void +freadpv(U32 len, void *data, XPV *pv) +{ + dTHX; + New(666, pv->xpv_pv, len, char); + PerlIO_read((PerlIO*)data, (void*)pv->xpv_pv, len); + pv->xpv_len = len; + pv->xpv_cur = len - 1; } static I32 @@ -80,20 +37,14 @@ byteloader_filter(pTHXo_ int idx, SV *buf_sv, int maxlen) dTHR; OP *saveroot = PL_main_root; OP *savestart = PL_main_start; - struct byteloader_state bstate; - struct byteloader_fdata data; - - data.next_out = 0; - data.datasv = FILTER_DATA(idx); - data.idx = idx; + struct bytestream bs; - bstate.bs_fdata = &data; - bstate.bs_obj_list = Null(void**); - bstate.bs_obj_list_fill = -1; - bstate.bs_sv = Nullsv; - bstate.bs_iv_overflows = 0; + bs.data = PL_rsfp; + bs.pfgetc = (int(*) (void*))xgetc; + bs.pfread = (int(*) (char*,size_t,size_t,void*))xfread; + bs.pfreadpv = freadpv; - byterun(aTHXo_ &bstate); + byterun(aTHXo_ bs); if (PL_in_eval) { OP *o; @@ -119,12 +70,8 @@ PROTOTYPES: ENABLE void import(...) - PREINIT: - SV *sv = newSVpvn ("", 0); PPCODE: - if (!sv) - croak ("Could not allocate ByteLoader buffers"); - filter_add(byteloader_filter, sv); + filter_add(byteloader_filter, NULL); void unimport(...) |