4 * Author : Paul Marquess
5 * Date : 25th February 2009
8 * Copyright (c) 1995-2009 Paul Marquess. All rights reserved.
9 * This program is free software; you can redistribute it and/or
10 * modify it under the same terms as Perl itself.
14 #define PERL_NO_GET_CONTEXT
22 /* Internal defines */
23 #define PERL_MODULE(s) IoBOTTOM_NAME(s)
24 #define PERL_OBJECT(s) IoTOP_GV(s)
25 #define FILTER_ACTIVE(s) IoLINES(s)
26 #define BUF_OFFSET(sv) IoPAGE_LEN(sv)
27 #define CODE_REF(sv) IoPAGE(sv)
28 #ifndef PERL_FILTER_EXISTS
29 # define PERL_FILTER_EXISTS(i) (PL_rsfp_filters && (i) <= av_len(PL_rsfp_filters))
32 #define SET_LEN(sv,len) \
33 do { SvPVX(sv)[len] = '\0'; SvCUR_set(sv, len); } while (0)
38 #define MY_CXT_KEY "Filter::Util::Call::_guts" XS_VERSION
47 #define fdebug (MY_CXT.x_fdebug)
48 #define current_idx (MY_CXT.x_current_idx)
52 filter_call(pTHX_ int idx, SV *buf_sv, int maxlen)
55 SV *my_sv = FILTER_DATA(idx);
56 const char *nl = "\n";
62 warn("**** In filter_call - maxlen = %d, out len buf = %d idx = %d my_sv = %d [%s]\n",
63 maxlen, SvCUR(buf_sv), idx, SvCUR(my_sv), SvPVX(my_sv) ) ;
67 /* anything left from last time */
68 if ((n = SvCUR(my_sv))) {
70 out_ptr = SvPVX(my_sv) + BUF_OFFSET(my_sv) ;
75 warn("BLOCK(%d): size = %d, maxlen = %d\n",
78 sv_catpvn(buf_sv, out_ptr, maxlen > n ? n : maxlen );
80 BUF_OFFSET(my_sv) = 0 ;
84 BUF_OFFSET(my_sv) += maxlen ;
85 SvCUR_set(my_sv, n - maxlen) ;
91 if ((p = ninstr(out_ptr, out_ptr + n, nl, nl + 1))) {
93 sv_catpvn(buf_sv, out_ptr, p - out_ptr + 1);
95 n = n - (p - out_ptr + 1);
96 BUF_OFFSET(my_sv) += (p - out_ptr + 1);
99 warn("recycle %d - leaving %d, returning %d [%s]",
100 idx, n, SvCUR(buf_sv), SvPVX(buf_sv)) ;
102 return SvCUR(buf_sv);
104 else /* no EOL, so append the complete buffer */
105 sv_catpvn(buf_sv, out_ptr, n) ;
112 BUF_OFFSET(my_sv) = 0 ;
114 if (FILTER_ACTIVE(my_sv))
120 warn("gonna call %s::filter\n", PERL_MODULE(my_sv)) ;
125 SAVEINT(current_idx) ; /* save current idx */
128 SAVE_DEFSV ; /* save $_ */
129 /* make $_ use our buffer */
130 DEFSV_set(newSVpv("", 0)) ;
134 if (CODE_REF(my_sv)) {
135 /* if (SvROK(PERL_OBJECT(my_sv)) && SvTYPE(SvRV(PERL_OBJECT(my_sv))) == SVt_PVCV) { */
136 count = perl_call_sv((SV*)PERL_OBJECT(my_sv), G_SCALAR);
139 XPUSHs((SV*)PERL_OBJECT(my_sv)) ;
143 count = perl_call_method("filter", G_SCALAR);
149 croak("Filter::Util::Call - %s::filter returned %d values, 1 was expected \n",
150 PERL_MODULE(my_sv), count ) ;
155 warn("status = %d, length op buf = %d [%s]\n",
156 n, SvCUR(DEFSV), SvPVX(DEFSV) ) ;
158 sv_setpvn(my_sv, SvPVX(DEFSV), SvCUR(DEFSV)) ;
167 n = FILTER_READ(idx + 1, my_sv, maxlen) ;
171 /* Either EOF or an error */
174 warn ("filter_read %d returned %d , returning %d\n", idx, n,
175 (SvCUR(buf_sv)>0) ? SvCUR(buf_sv) : n);
177 /* PERL_MODULE(my_sv) ; */
178 /* PERL_OBJECT(my_sv) ; */
179 filter_del(filter_call);
181 /* If error, return the code */
185 /* return what we have so far else signal eof */
186 return (SvCUR(buf_sv)>0) ? SvCUR(buf_sv) : n;
194 MODULE = Filter::Util::Call PACKAGE = Filter::Util::Call
199 #define IDX current_idx
207 SV * buffer = DEFSV ;
209 RETVAL = FILTER_READ(IDX + 1, buffer, size) ;
218 real_import(object, perlmodule, coderef)
226 (void)SvPOK_only(sv) ;
227 filter_add(filter_call, sv) ;
229 PERL_MODULE(sv) = savepv(perlmodule) ;
230 PERL_OBJECT(sv) = (GV*) newSVsv(object) ;
231 FILTER_ACTIVE(sv) = TRUE ;
233 CODE_REF(sv) = coderef ;
243 if (PERL_FILTER_EXISTS(IDX) && FILTER_DATA(IDX) && FILTER_ACTIVE(FILTER_DATA(IDX)))
244 FILTER_ACTIVE(FILTER_DATA(IDX)) = FALSE ;
249 unimport(package="$Package", ...)
252 filter_del(filter_call);
259 /* temporary hack to control debugging in toke.c */
261 filter_add(NULL, (fdebug) ? (SV*)"1" : (SV*)"0");