Convert ByteLoader to use CopARYBASE_set().
[p5sagit/p5-mst-13.2.git] / ext / ByteLoader / ByteLoader.xs
CommitLineData
b295d113 1#include "EXTERN.h"
2#include "perl.h"
3#include "XSUB.h"
e8edd1e6 4#include "byterun.h"
b295d113 5
059a8bb7 6/* Something arbitary for a buffer size */
7#define BYTELOADER_BUFFER 8096
33c2a728 8
059a8bb7 9int
10bl_getc(struct byteloader_fdata *data)
33c2a728 11{
12 dTHX;
7c436af3 13 if (SvCUR(data->datasv) <= (STRLEN)data->next_out) {
059a8bb7 14 int result;
15 /* Run out of buffered data, so attempt to read some more */
16 *(SvPV_nolen (data->datasv)) = '\0';
17 SvCUR_set (data->datasv, 0);
18 data->next_out = 0;
19 result = FILTER_READ (data->idx + 1, data->datasv, BYTELOADER_BUFFER);
20
21 /* Filter returned error, or we got EOF and no data, then return EOF.
22 Not sure if filter is allowed to return EOF and add data simultaneously
23 Think not, but will bullet proof against it. */
24 if (result < 0 || SvCUR(data->datasv) == 0)
25 return EOF;
26 /* Else there must be at least one byte present, which is good enough */
27 }
28
1df34986 29 return *((U8 *) SvPV_nolen (data->datasv) + data->next_out++);
33c2a728 30}
d8ab9aa2 31
059a8bb7 32int
33bl_read(struct byteloader_fdata *data, char *buf, size_t size, size_t n)
e8edd1e6 34{
c5be433b 35 dTHX;
059a8bb7 36 char *start;
37 STRLEN len;
38 size_t wanted = size * n;
39
40 start = SvPV (data->datasv, len);
41 if (len < (data->next_out + wanted)) {
42 int result;
43
44 /* Shuffle data to start of buffer */
45 len -= data->next_out;
46 if (len) {
47 memmove (start, start + data->next_out, len + 1);
059a8bb7 48 } else {
49 *start = '\0'; /* Avoid call to memmove. */
059a8bb7 50 }
4b31f138 51 SvCUR_set(data->datasv, len);
059a8bb7 52 data->next_out = 0;
53
54 /* Attempt to read more data. */
55 do {
56 result = FILTER_READ (data->idx + 1, data->datasv, BYTELOADER_BUFFER);
57
58 start = SvPV (data->datasv, len);
59 } while (result > 0 && len < wanted);
60 /* Loop while not (EOF || error) and short reads */
61
62 /* If not enough data read, truncate copy */
63 if (wanted > len)
64 wanted = len;
65 }
66
67 if (wanted > 0) {
68 memcpy (buf, start + data->next_out, wanted);
69 data->next_out += wanted;
70 wanted /= size;
71 }
72 return (int) wanted;
e8edd1e6 73}
b295d113 74
75static I32
acfe0abc 76byteloader_filter(pTHX_ int idx, SV *buf_sv, int maxlen)
b295d113 77{
78 OP *saveroot = PL_main_root;
79 OP *savestart = PL_main_start;
059a8bb7 80 struct byteloader_state bstate;
81 struct byteloader_fdata data;
1df34986 82 int len;
4b31f138 83 (void)buf_sv;
84 (void)maxlen;
059a8bb7 85
86 data.next_out = 0;
87 data.datasv = FILTER_DATA(idx);
88 data.idx = idx;
b295d113 89
059a8bb7 90 bstate.bs_fdata = &data;
91 bstate.bs_obj_list = Null(void**);
92 bstate.bs_obj_list_fill = -1;
93 bstate.bs_sv = Nullsv;
94 bstate.bs_iv_overflows = 0;
e8edd1e6 95
1df34986 96/* KLUDGE */
97 if (byterun(aTHX_ &bstate)
98 && (len = SvCUR(data.datasv) - (STRLEN)data.next_out))
99 {
100 PerlIO_seek(PL_rsfp, -len, SEEK_CUR);
101 PL_rsfp = NULL;
102 }
103 filter_del(byteloader_filter);
b295d113 104
105 if (PL_in_eval) {
106 OP *o;
107
108 PL_eval_start = PL_main_start;
109
110 o = newSVOP(OP_CONST, 0, newSViv(1));
111 PL_eval_root = newLISTOP(OP_LINESEQ, 0, PL_main_root, o);
112 PL_main_root->op_next = o;
113 PL_eval_root = newUNOP(OP_LEAVEEVAL, 0, PL_eval_root);
114 o->op_next = PL_eval_root;
115
116 PL_main_root = saveroot;
117 PL_main_start = savestart;
118 }
119
120 return 0;
121}
122
123MODULE = ByteLoader PACKAGE = ByteLoader
124
125PROTOTYPES: ENABLE
126
127void
c6c619a9 128import(package="ByteLoader", ...)
129 char *package
059a8bb7 130 PREINIT:
131 SV *sv = newSVpvn ("", 0);
b295d113 132 PPCODE:
059a8bb7 133 if (!sv)
134 croak ("Could not allocate ByteLoader buffers");
135 filter_add(byteloader_filter, sv);