ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/staticperl/perl/ext/ByteLoader/ByteLoader.xs
Revision: 1.1
Committed: Thu Jun 30 14:26:44 2005 UTC (21 years, 3 months ago) by root
Branch: MAIN
CVS Tags: PERL-5-8-7, HEAD
Branch point for: PERL
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 #include "EXTERN.h"
2     #include "perl.h"
3     #include "XSUB.h"
4     #include "byterun.h"
5    
6     /* Something arbitary for a buffer size */
7     #define BYTELOADER_BUFFER 8096
8    
9     int
10     bl_getc(struct byteloader_fdata *data)
11     {
12     dTHX;
13     if (SvCUR(data->datasv) <= (STRLEN)data->next_out) {
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    
29     return *((U8 *) SvPV_nolen (data->datasv) + data->next_out++);
30     }
31    
32     int
33     bl_read(struct byteloader_fdata *data, char *buf, size_t size, size_t n)
34     {
35     dTHX;
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);
48     SvCUR_set (data->datasv, len);
49     } else {
50     *start = '\0'; /* Avoid call to memmove. */
51     SvCUR_set (data->datasv, 0);
52     }
53     data->next_out = 0;
54    
55     /* Attempt to read more data. */
56     do {
57     result = FILTER_READ (data->idx + 1, data->datasv, BYTELOADER_BUFFER);
58    
59     start = SvPV (data->datasv, len);
60     } while (result > 0 && len < wanted);
61     /* Loop while not (EOF || error) and short reads */
62    
63     /* If not enough data read, truncate copy */
64     if (wanted > len)
65     wanted = len;
66     }
67    
68     if (wanted > 0) {
69     memcpy (buf, start + data->next_out, wanted);
70     data->next_out += wanted;
71     wanted /= size;
72     }
73     return (int) wanted;
74     }
75    
76     static I32
77     byteloader_filter(pTHX_ int idx, SV *buf_sv, int maxlen)
78     {
79     OP *saveroot = PL_main_root;
80     OP *savestart = PL_main_start;
81     struct byteloader_state bstate;
82     struct byteloader_fdata data;
83     int len;
84    
85     data.next_out = 0;
86     data.datasv = FILTER_DATA(idx);
87     data.idx = idx;
88    
89     bstate.bs_fdata = &data;
90     bstate.bs_obj_list = Null(void**);
91     bstate.bs_obj_list_fill = -1;
92     bstate.bs_sv = Nullsv;
93     bstate.bs_iv_overflows = 0;
94    
95     /* KLUDGE */
96     if (byterun(aTHX_ &bstate)
97     && (len = SvCUR(data.datasv) - (STRLEN)data.next_out))
98     {
99     PerlIO_seek(PL_rsfp, -len, SEEK_CUR);
100     PL_rsfp = NULL;
101     }
102     filter_del(byteloader_filter);
103    
104     if (PL_in_eval) {
105     OP *o;
106    
107     PL_eval_start = PL_main_start;
108    
109     o = newSVOP(OP_CONST, 0, newSViv(1));
110     PL_eval_root = newLISTOP(OP_LINESEQ, 0, PL_main_root, o);
111     PL_main_root->op_next = o;
112     PL_eval_root = newUNOP(OP_LEAVEEVAL, 0, PL_eval_root);
113     o->op_next = PL_eval_root;
114    
115     PL_main_root = saveroot;
116     PL_main_start = savestart;
117     }
118    
119     return 0;
120     }
121    
122     MODULE = ByteLoader PACKAGE = ByteLoader
123    
124     PROTOTYPES: ENABLE
125    
126     void
127     import(package="ByteLoader", ...)
128     char *package
129     PREINIT:
130     SV *sv = newSVpvn ("", 0);
131     PPCODE:
132     if (!sv)
133     croak ("Could not allocate ByteLoader buffers");
134     filter_add(byteloader_filter, sv);