Commit | Line | Data |
---|---|---|
e7a1fdd7 NIS |
1 | #define PERL_NO_GET_CONTEXT |
2 | #include "EXTERN.h" | |
3 | #include "perl.h" | |
4 | #include "XSUB.h" | |
5 | #ifdef PERLIO_LAYERS | |
6 | ||
7 | #include "perliol.h" | |
8 | ||
9 | typedef struct | |
10 | { | |
11 | struct _PerlIO base; /* Base "class" info */ | |
12 | HV * stash; | |
13 | SV * obj; | |
14 | SV * var; | |
15 | SSize_t cnt; | |
e7a1fdd7 NIS |
16 | IO * io; |
17 | SV * fh; | |
18 | CV *PUSHED; | |
19 | CV *POPPED; | |
20 | CV *OPEN; | |
21 | CV *FDOPEN; | |
22 | CV *SYSOPEN; | |
23 | CV *GETARG; | |
24 | CV *FILENO; | |
25 | CV *READ; | |
26 | CV *WRITE; | |
27 | CV *FILL; | |
28 | CV *CLOSE; | |
29 | CV *SEEK; | |
30 | CV *TELL; | |
31 | CV *UNREAD; | |
32 | CV *FLUSH; | |
33 | CV *SETLINEBUF; | |
34 | CV *CLEARERR; | |
c7997937 | 35 | CV *mERROR; |
e7a1fdd7 | 36 | CV *mEOF; |
86e05cf2 | 37 | CV *BINMODE; |
802588c3 | 38 | CV *UTF8; |
e7a1fdd7 NIS |
39 | } PerlIOVia; |
40 | ||
41 | #define MYMethod(x) #x,&s->x | |
42 | ||
43 | CV * | |
d3f5e399 | 44 | PerlIOVia_fetchmethod(pTHX_ PerlIOVia * s, const char *method, CV ** save) |
e7a1fdd7 | 45 | { |
fc040538 | 46 | GV *gv = gv_fetchmeth(s->stash, method, strlen(method), 0); |
e7a1fdd7 | 47 | #if 0 |
bfcb3514 | 48 | Perl_warn(aTHX_ "Lookup %s::%s => %p", HvNAME_get(s->stash), method, gv); |
e7a1fdd7 | 49 | #endif |
fc040538 NIS |
50 | if (gv) { |
51 | return *save = GvCV(gv); | |
52 | } | |
53 | else { | |
54 | return *save = (CV *) - 1; | |
55 | } | |
e7a1fdd7 NIS |
56 | } |
57 | ||
d9dac8cd NIS |
58 | /* |
59 | * Try and call method, possibly via cached lookup. | |
60 | * If method does not exist return Nullsv (caller may fallback to another approach | |
61 | * If method does exist call it with flags passing variable number of args | |
62 | * Last arg is a "filehandle" to layer below (if present) | |
63 | * Returns scalar returned by method (if any) otherwise sv_undef | |
64 | */ | |
65 | ||
e7a1fdd7 | 66 | SV * |
d3f5e399 | 67 | PerlIOVia_method(pTHX_ PerlIO * f, const char *method, CV ** save, int flags, |
fc040538 | 68 | ...) |
e7a1fdd7 | 69 | { |
fc040538 | 70 | PerlIOVia *s = PerlIOSelf(f, PerlIOVia); |
3ed3a8af | 71 | SV *result = Nullsv; |
fc040538 NIS |
72 | CV *cv = |
73 | (*save) ? *save : PerlIOVia_fetchmethod(aTHX_ s, method, save); | |
fc040538 NIS |
74 | if (cv != (CV *) - 1) { |
75 | IV count; | |
76 | dSP; | |
77 | SV *arg; | |
3ed3a8af JH |
78 | va_list ap; |
79 | ||
80 | va_start(ap, flags); | |
fc040538 NIS |
81 | PUSHSTACKi(PERLSI_MAGIC); |
82 | ENTER; | |
fc040538 NIS |
83 | PUSHMARK(sp); |
84 | XPUSHs(s->obj); | |
85 | while ((arg = va_arg(ap, SV *))) { | |
86 | XPUSHs(arg); | |
87 | } | |
3ed3a8af | 88 | va_end(ap); |
fc040538 NIS |
89 | if (*PerlIONext(f)) { |
90 | if (!s->fh) { | |
63d83481 DM |
91 | GV *gv; |
92 | char *package = HvNAME_get(s->stash); | |
93 | ||
94 | if (!package) | |
95 | return Nullsv; /* can this ever happen? */ | |
96 | gv = newGVgen(package); | |
fc040538 | 97 | GvIOp(gv) = newIO(); |
5a33563f | 98 | s->fh = newRV((SV *) gv); |
fc040538 | 99 | s->io = GvIOp(gv); |
8d06e08c MHM |
100 | if (gv) { |
101 | /* shamelessly stolen from IO::File's new_tmpfile() */ | |
c33e8be1 | 102 | (void) hv_delete(GvSTASH(gv), GvNAME(gv), GvNAMELEN(gv), G_DISCARD); |
8d06e08c | 103 | } |
fc040538 NIS |
104 | } |
105 | IoIFP(s->io) = PerlIONext(f); | |
106 | IoOFP(s->io) = PerlIONext(f); | |
107 | XPUSHs(s->fh); | |
108 | } | |
109 | else { | |
110 | PerlIO_debug("No next\n"); | |
30ef3321 | 111 | /* FIXME: How should this work for OPEN etc? */ |
fc040538 NIS |
112 | } |
113 | PUTBACK; | |
114 | count = call_sv((SV *) cv, flags); | |
115 | if (count) { | |
116 | SPAGAIN; | |
117 | result = POPs; | |
118 | PUTBACK; | |
119 | } | |
120 | else { | |
121 | result = &PL_sv_undef; | |
122 | } | |
123 | LEAVE; | |
124 | POPSTACK; | |
e7a1fdd7 | 125 | } |
fc040538 | 126 | return result; |
e7a1fdd7 NIS |
127 | } |
128 | ||
129 | IV | |
fc040538 NIS |
130 | PerlIOVia_pushed(pTHX_ PerlIO * f, const char *mode, SV * arg, |
131 | PerlIO_funcs * tab) | |
e7a1fdd7 | 132 | { |
fc040538 NIS |
133 | IV code = PerlIOBase_pushed(aTHX_ f, mode, Nullsv, tab); |
134 | if (code == 0) { | |
135 | PerlIOVia *s = PerlIOSelf(f, PerlIOVia); | |
136 | if (!arg) { | |
137 | if (ckWARN(WARN_LAYER)) | |
138 | Perl_warner(aTHX_ packWARN(WARN_LAYER), | |
139 | "No package specified"); | |
140 | errno = EINVAL; | |
141 | code = -1; | |
142 | } | |
143 | else { | |
144 | STRLEN pkglen = 0; | |
7248df0a | 145 | const char *pkg = SvPV(arg, pkglen); |
a681c2f1 RGS |
146 | s->obj = |
147 | newSVpvn(Perl_form(aTHX_ "PerlIO::via::%s", pkg), | |
148 | pkglen + 13); | |
149 | s->stash = gv_stashpvn(SvPVX_const(s->obj), pkglen + 13, 0); | |
fc040538 | 150 | if (!s->stash) { |
3904eff9 | 151 | SvREFCNT_dec(s->obj); |
a681c2f1 RGS |
152 | s->obj = SvREFCNT_inc(arg); |
153 | s->stash = gv_stashpvn(pkg, pkglen, 0); | |
fc040538 NIS |
154 | } |
155 | if (s->stash) { | |
abc0a015 NIS |
156 | char lmode[8]; |
157 | SV *modesv; | |
158 | SV *result; | |
159 | if (!mode) { | |
160 | /* binmode() passes NULL - so find out what mode is */ | |
161 | mode = PerlIO_modestr(f,lmode); | |
162 | } | |
d3d34884 | 163 | modesv = newSVpvn_flags(mode, strlen(mode), SVs_TEMP); |
abc0a015 | 164 | result = PerlIOVia_method(aTHX_ f, MYMethod(PUSHED), G_SCALAR, |
fc040538 NIS |
165 | modesv, Nullsv); |
166 | if (result) { | |
167 | if (sv_isobject(result)) { | |
3904eff9 | 168 | SvREFCNT_dec(s->obj); |
fc040538 | 169 | s->obj = SvREFCNT_inc(result); |
fc040538 NIS |
170 | } |
171 | else if (SvIV(result) != 0) | |
172 | return SvIV(result); | |
173 | } | |
4f776d34 RC |
174 | else { |
175 | goto push_failed; | |
176 | } | |
802588c3 NIS |
177 | modesv = (*PerlIONext(f) && (PerlIOBase(PerlIONext(f))->flags & PERLIO_F_UTF8)) |
178 | ? &PL_sv_yes : &PL_sv_no; | |
179 | result = PerlIOVia_method(aTHX_ f, MYMethod(UTF8), G_SCALAR, modesv, Nullsv); | |
180 | if (result && SvTRUE(result)) { | |
7248df0a | 181 | PerlIOBase(f)->flags |= PERLIO_F_UTF8; |
802588c3 NIS |
182 | } |
183 | else { | |
184 | PerlIOBase(f)->flags &= ~PERLIO_F_UTF8; | |
185 | } | |
fc040538 NIS |
186 | if (PerlIOVia_fetchmethod(aTHX_ s, MYMethod(FILL)) == |
187 | (CV *) - 1) | |
188 | PerlIOBase(f)->flags &= ~PERLIO_F_FASTGETS; | |
189 | else | |
190 | PerlIOBase(f)->flags |= PERLIO_F_FASTGETS; | |
191 | } | |
192 | else { | |
193 | if (ckWARN(WARN_LAYER)) | |
194 | Perl_warner(aTHX_ packWARN(WARN_LAYER), | |
195 | "Cannot find package '%.*s'", (int) pkglen, | |
196 | pkg); | |
4f776d34 | 197 | push_failed: |
267cbce7 | 198 | #ifdef ENOSYS |
fc040538 | 199 | errno = ENOSYS; |
267cbce7 NIS |
200 | #else |
201 | #ifdef ENOENT | |
fc040538 | 202 | errno = ENOENT; |
267cbce7 NIS |
203 | #endif |
204 | #endif | |
fc040538 NIS |
205 | code = -1; |
206 | } | |
207 | } | |
e7a1fdd7 | 208 | } |
fc040538 | 209 | return code; |
e7a1fdd7 NIS |
210 | } |
211 | ||
212 | PerlIO * | |
fc040538 NIS |
213 | PerlIOVia_open(pTHX_ PerlIO_funcs * self, PerlIO_list_t * layers, |
214 | IV n, const char *mode, int fd, int imode, int perm, | |
215 | PerlIO * f, int narg, SV ** args) | |
e7a1fdd7 | 216 | { |
fc040538 NIS |
217 | if (!f) { |
218 | f = PerlIO_push(aTHX_ PerlIO_allocate(aTHX), self, mode, | |
219 | PerlIOArg); | |
e7a1fdd7 | 220 | } |
fc040538 NIS |
221 | else { |
222 | /* Reopen */ | |
223 | if (!PerlIO_push(aTHX_ f, self, mode, PerlIOArg)) | |
224 | return NULL; | |
e7a1fdd7 | 225 | } |
fc040538 NIS |
226 | if (f) { |
227 | PerlIOVia *s = PerlIOSelf(f, PerlIOVia); | |
228 | SV *result = Nullsv; | |
229 | if (fd >= 0) { | |
230 | SV *fdsv = sv_2mortal(newSViv(fd)); | |
231 | result = | |
232 | PerlIOVia_method(aTHX_ f, MYMethod(FDOPEN), G_SCALAR, fdsv, | |
233 | Nullsv); | |
234 | } | |
235 | else if (narg > 0) { | |
236 | if (*mode == '#') { | |
237 | SV *imodesv = sv_2mortal(newSViv(imode)); | |
238 | SV *permsv = sv_2mortal(newSViv(perm)); | |
239 | result = | |
240 | PerlIOVia_method(aTHX_ f, MYMethod(SYSOPEN), G_SCALAR, | |
241 | *args, imodesv, permsv, Nullsv); | |
242 | } | |
243 | else { | |
244 | result = | |
245 | PerlIOVia_method(aTHX_ f, MYMethod(OPEN), G_SCALAR, | |
246 | *args, Nullsv); | |
d9dac8cd | 247 | } |
d9dac8cd | 248 | } |
fc040538 NIS |
249 | if (result) { |
250 | if (sv_isobject(result)) | |
251 | s->obj = SvREFCNT_inc(result); | |
252 | else if (!SvTRUE(result)) { | |
253 | return NULL; | |
254 | } | |
255 | } | |
256 | else { | |
257 | /* Required open method not present */ | |
258 | PerlIO_funcs *tab = NULL; | |
d26d6e72 | 259 | IV m = n - 1; |
fc040538 NIS |
260 | while (m >= 0) { |
261 | PerlIO_funcs *t = | |
262 | PerlIO_layer_fetch(aTHX_ layers, m, NULL); | |
263 | if (t && t->Open) { | |
264 | tab = t; | |
265 | break; | |
266 | } | |
d26d6e72 | 267 | m--; |
fc040538 NIS |
268 | } |
269 | if (tab) { | |
270 | if ((*tab->Open) (aTHX_ tab, layers, m, mode, fd, imode, | |
271 | perm, PerlIONext(f), narg, args)) { | |
272 | PerlIO_debug("Opened with %s => %p->%p\n", tab->name, | |
273 | PerlIONext(f), *PerlIONext(f)); | |
274 | if (m + 1 < n) { | |
275 | /* | |
276 | * More layers above the one that we used to open - | |
277 | * apply them now | |
278 | */ | |
279 | if (PerlIO_apply_layera | |
280 | (aTHX_ PerlIONext(f), mode, layers, m + 1, | |
281 | n) != 0) { | |
282 | /* If pushing layers fails close the file */ | |
283 | PerlIO_close(f); | |
284 | f = NULL; | |
285 | } | |
d9dac8cd | 286 | } |
30ef3321 | 287 | /* FIXME - Call an OPENED method here ? */ |
fc040538 NIS |
288 | return f; |
289 | } | |
290 | else { | |
30ef3321 NIS |
291 | PerlIO_debug("Open fail %s => %p->%p\n", tab->name, |
292 | PerlIONext(f), *PerlIONext(f)); | |
fc040538 | 293 | /* Sub-layer open failed */ |
d9dac8cd | 294 | } |
d9dac8cd NIS |
295 | } |
296 | else { | |
30ef3321 | 297 | PerlIO_debug("Nothing to open with"); |
fc040538 | 298 | /* Nothing to do the open */ |
d9dac8cd | 299 | } |
30ef3321 | 300 | PerlIO_pop(aTHX_ f); |
fc040538 | 301 | return NULL; |
d9dac8cd | 302 | } |
d9dac8cd | 303 | } |
fc040538 | 304 | return f; |
e7a1fdd7 NIS |
305 | } |
306 | ||
307 | IV | |
fc040538 | 308 | PerlIOVia_popped(pTHX_ PerlIO * f) |
e7a1fdd7 | 309 | { |
fc040538 NIS |
310 | PerlIOVia *s = PerlIOSelf(f, PerlIOVia); |
311 | PerlIOVia_method(aTHX_ f, MYMethod(POPPED), G_VOID, Nullsv); | |
312 | if (s->var) { | |
313 | SvREFCNT_dec(s->var); | |
314 | s->var = Nullsv; | |
315 | } | |
316 | ||
317 | if (s->io) { | |
318 | IoIFP(s->io) = NULL; | |
319 | IoOFP(s->io) = NULL; | |
320 | } | |
321 | if (s->fh) { | |
322 | SvREFCNT_dec(s->fh); | |
323 | s->fh = Nullsv; | |
324 | s->io = NULL; | |
325 | } | |
326 | if (s->obj) { | |
327 | SvREFCNT_dec(s->obj); | |
328 | s->obj = Nullsv; | |
329 | } | |
330 | return 0; | |
e7a1fdd7 NIS |
331 | } |
332 | ||
333 | IV | |
fc040538 | 334 | PerlIOVia_close(pTHX_ PerlIO * f) |
e7a1fdd7 | 335 | { |
fc040538 NIS |
336 | PerlIOVia *s = PerlIOSelf(f, PerlIOVia); |
337 | IV code = PerlIOBase_close(aTHX_ f); | |
338 | SV *result = | |
339 | PerlIOVia_method(aTHX_ f, MYMethod(CLOSE), G_SCALAR, Nullsv); | |
340 | if (result && SvIV(result) != 0) | |
341 | code = SvIV(result); | |
342 | PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF | PERLIO_F_WRBUF); | |
343 | return code; | |
e7a1fdd7 NIS |
344 | } |
345 | ||
346 | IV | |
fc040538 | 347 | PerlIOVia_fileno(pTHX_ PerlIO * f) |
e7a1fdd7 | 348 | { |
fc040538 NIS |
349 | PerlIOVia *s = PerlIOSelf(f, PerlIOVia); |
350 | SV *result = | |
351 | PerlIOVia_method(aTHX_ f, MYMethod(FILENO), G_SCALAR, Nullsv); | |
352 | return (result) ? SvIV(result) : PerlIO_fileno(PerlIONext(f)); | |
e7a1fdd7 NIS |
353 | } |
354 | ||
355 | IV | |
fc040538 | 356 | PerlIOVia_binmode(pTHX_ PerlIO * f) |
86e05cf2 | 357 | { |
fc040538 NIS |
358 | PerlIOVia *s = PerlIOSelf(f, PerlIOVia); |
359 | SV *result = | |
360 | PerlIOVia_method(aTHX_ f, MYMethod(BINMODE), G_SCALAR, Nullsv); | |
361 | if (!result || !SvOK(result)) { | |
362 | PerlIO_pop(aTHX_ f); | |
363 | return 0; | |
364 | } | |
365 | return SvIV(result); | |
86e05cf2 NIS |
366 | } |
367 | ||
6efa4722 | 368 | IV |
fc040538 | 369 | PerlIOVia_seek(pTHX_ PerlIO * f, Off_t offset, int whence) |
e7a1fdd7 | 370 | { |
fc040538 | 371 | PerlIOVia *s = PerlIOSelf(f, PerlIOVia); |
4a9d6100 GS |
372 | SV *offsv = sv_2mortal(sizeof(Off_t) > sizeof(IV) |
373 | ? newSVnv((NV)offset) : newSViv((IV)offset)); | |
fc040538 NIS |
374 | SV *whsv = sv_2mortal(newSViv(whence)); |
375 | SV *result = | |
376 | PerlIOVia_method(aTHX_ f, MYMethod(SEEK), G_SCALAR, offsv, whsv, | |
377 | Nullsv); | |
b6290011 JH |
378 | #if Off_t_size == 8 && defined(CONDOP_SIZE) && CONDOP_SIZE < Off_t_size |
379 | if (result) | |
380 | return (Off_t) SvIV(result); | |
381 | else | |
382 | return (Off_t) -1; | |
383 | #else | |
fc040538 | 384 | return (result) ? SvIV(result) : -1; |
b6290011 | 385 | #endif |
e7a1fdd7 NIS |
386 | } |
387 | ||
388 | Off_t | |
fc040538 | 389 | PerlIOVia_tell(pTHX_ PerlIO * f) |
e7a1fdd7 | 390 | { |
fc040538 NIS |
391 | PerlIOVia *s = PerlIOSelf(f, PerlIOVia); |
392 | SV *result = | |
393 | PerlIOVia_method(aTHX_ f, MYMethod(TELL), G_SCALAR, Nullsv); | |
4a9d6100 GS |
394 | return (result) |
395 | ? (SvNOK(result) ? (Off_t)SvNV(result) : (Off_t)SvIV(result)) | |
396 | : (Off_t) - 1; | |
e7a1fdd7 NIS |
397 | } |
398 | ||
399 | SSize_t | |
fc040538 | 400 | PerlIOVia_unread(pTHX_ PerlIO * f, const void *vbuf, Size_t count) |
e7a1fdd7 | 401 | { |
fc040538 | 402 | PerlIOVia *s = PerlIOSelf(f, PerlIOVia); |
d3d34884 | 403 | SV *buf = newSVpvn_flags((char *) vbuf, count, SVs_TEMP); |
fc040538 NIS |
404 | SV *result = |
405 | PerlIOVia_method(aTHX_ f, MYMethod(UNREAD), G_SCALAR, buf, Nullsv); | |
406 | if (result) | |
407 | return (SSize_t) SvIV(result); | |
408 | else { | |
409 | return PerlIOBase_unread(aTHX_ f, vbuf, count); | |
410 | } | |
e7a1fdd7 NIS |
411 | } |
412 | ||
413 | SSize_t | |
fc040538 | 414 | PerlIOVia_read(pTHX_ PerlIO * f, void *vbuf, Size_t count) |
e7a1fdd7 | 415 | { |
fc040538 NIS |
416 | SSize_t rd = 0; |
417 | if (PerlIOBase(f)->flags & PERLIO_F_CANREAD) { | |
418 | if (PerlIOBase(f)->flags & PERLIO_F_FASTGETS) { | |
419 | rd = PerlIOBase_read(aTHX_ f, vbuf, count); | |
420 | } | |
421 | else { | |
422 | PerlIOVia *s = PerlIOSelf(f, PerlIOVia); | |
423 | SV *buf = sv_2mortal(newSV(count)); | |
424 | SV *n = sv_2mortal(newSViv(count)); | |
425 | SV *result = | |
426 | PerlIOVia_method(aTHX_ f, MYMethod(READ), G_SCALAR, buf, n, | |
427 | Nullsv); | |
428 | if (result) { | |
429 | rd = (SSize_t) SvIV(result); | |
430 | Move(SvPVX(buf), vbuf, rd, char); | |
431 | return rd; | |
432 | } | |
433 | } | |
e7a1fdd7 | 434 | } |
fc040538 | 435 | return rd; |
e7a1fdd7 NIS |
436 | } |
437 | ||
438 | SSize_t | |
fc040538 | 439 | PerlIOVia_write(pTHX_ PerlIO * f, const void *vbuf, Size_t count) |
e7a1fdd7 | 440 | { |
fc040538 NIS |
441 | if (PerlIOBase(f)->flags & PERLIO_F_CANWRITE) { |
442 | PerlIOVia *s = PerlIOSelf(f, PerlIOVia); | |
443 | SV *buf = newSVpvn((char *) vbuf, count); | |
444 | SV *result = | |
445 | PerlIOVia_method(aTHX_ f, MYMethod(WRITE), G_SCALAR, buf, | |
446 | Nullsv); | |
447 | SvREFCNT_dec(buf); | |
448 | if (result) | |
449 | return (SSize_t) SvIV(result); | |
450 | return -1; | |
451 | } | |
452 | return 0; | |
e7a1fdd7 NIS |
453 | } |
454 | ||
455 | IV | |
fc040538 | 456 | PerlIOVia_fill(pTHX_ PerlIO * f) |
e7a1fdd7 | 457 | { |
fc040538 NIS |
458 | if (PerlIOBase(f)->flags & PERLIO_F_CANREAD) { |
459 | PerlIOVia *s = PerlIOSelf(f, PerlIOVia); | |
460 | SV *result = | |
461 | PerlIOVia_method(aTHX_ f, MYMethod(FILL), G_SCALAR, Nullsv); | |
462 | if (s->var) { | |
463 | SvREFCNT_dec(s->var); | |
464 | s->var = Nullsv; | |
465 | } | |
466 | if (result && SvOK(result)) { | |
467 | STRLEN len = 0; | |
7248df0a | 468 | const char *p = SvPV(result, len); |
fc040538 NIS |
469 | s->var = newSVpvn(p, len); |
470 | s->cnt = SvCUR(s->var); | |
471 | return 0; | |
472 | } | |
473 | else | |
474 | PerlIOBase(f)->flags |= PERLIO_F_EOF; | |
e7a1fdd7 | 475 | } |
fc040538 | 476 | return -1; |
e7a1fdd7 NIS |
477 | } |
478 | ||
479 | IV | |
fc040538 | 480 | PerlIOVia_flush(pTHX_ PerlIO * f) |
e7a1fdd7 | 481 | { |
fc040538 NIS |
482 | PerlIOVia *s = PerlIOSelf(f, PerlIOVia); |
483 | SV *result = | |
484 | PerlIOVia_method(aTHX_ f, MYMethod(FLUSH), G_SCALAR, Nullsv); | |
485 | if (s->var && s->cnt > 0) { | |
486 | SvREFCNT_dec(s->var); | |
487 | s->var = Nullsv; | |
488 | } | |
489 | return (result) ? SvIV(result) : 0; | |
e7a1fdd7 NIS |
490 | } |
491 | ||
492 | STDCHAR * | |
fc040538 | 493 | PerlIOVia_get_base(pTHX_ PerlIO * f) |
e7a1fdd7 | 494 | { |
fc040538 NIS |
495 | if (PerlIOBase(f)->flags & PERLIO_F_CANREAD) { |
496 | PerlIOVia *s = PerlIOSelf(f, PerlIOVia); | |
497 | if (s->var) { | |
498 | return (STDCHAR *) SvPVX(s->var); | |
499 | } | |
e7a1fdd7 | 500 | } |
9849c14c | 501 | return (STDCHAR *) NULL; |
e7a1fdd7 NIS |
502 | } |
503 | ||
504 | STDCHAR * | |
fc040538 | 505 | PerlIOVia_get_ptr(pTHX_ PerlIO * f) |
e7a1fdd7 | 506 | { |
fc040538 NIS |
507 | if (PerlIOBase(f)->flags & PERLIO_F_CANREAD) { |
508 | PerlIOVia *s = PerlIOSelf(f, PerlIOVia); | |
509 | if (s->var) { | |
510 | STDCHAR *p = (STDCHAR *) (SvEND(s->var) - s->cnt); | |
511 | return p; | |
512 | } | |
e7a1fdd7 | 513 | } |
9849c14c | 514 | return (STDCHAR *) NULL; |
e7a1fdd7 NIS |
515 | } |
516 | ||
517 | SSize_t | |
fc040538 | 518 | PerlIOVia_get_cnt(pTHX_ PerlIO * f) |
e7a1fdd7 | 519 | { |
fc040538 NIS |
520 | if (PerlIOBase(f)->flags & PERLIO_F_CANREAD) { |
521 | PerlIOVia *s = PerlIOSelf(f, PerlIOVia); | |
522 | if (s->var) { | |
523 | return s->cnt; | |
524 | } | |
e7a1fdd7 | 525 | } |
fc040538 | 526 | return 0; |
e7a1fdd7 NIS |
527 | } |
528 | ||
529 | Size_t | |
fc040538 | 530 | PerlIOVia_bufsiz(pTHX_ PerlIO * f) |
e7a1fdd7 | 531 | { |
fc040538 NIS |
532 | if (PerlIOBase(f)->flags & PERLIO_F_CANREAD) { |
533 | PerlIOVia *s = PerlIOSelf(f, PerlIOVia); | |
534 | if (s->var) | |
535 | return SvCUR(s->var); | |
536 | } | |
537 | return 0; | |
e7a1fdd7 NIS |
538 | } |
539 | ||
540 | void | |
fc040538 | 541 | PerlIOVia_set_ptrcnt(pTHX_ PerlIO * f, STDCHAR * ptr, SSize_t cnt) |
e7a1fdd7 | 542 | { |
fc040538 | 543 | PerlIOVia *s = PerlIOSelf(f, PerlIOVia); |
c33e8be1 | 544 | PERL_UNUSED_ARG(ptr); |
fc040538 | 545 | s->cnt = cnt; |
e7a1fdd7 NIS |
546 | } |
547 | ||
548 | void | |
fc040538 | 549 | PerlIOVia_setlinebuf(pTHX_ PerlIO * f) |
e7a1fdd7 | 550 | { |
fc040538 NIS |
551 | PerlIOVia *s = PerlIOSelf(f, PerlIOVia); |
552 | PerlIOVia_method(aTHX_ f, MYMethod(SETLINEBUF), G_VOID, Nullsv); | |
553 | PerlIOBase_setlinebuf(aTHX_ f); | |
e7a1fdd7 NIS |
554 | } |
555 | ||
556 | void | |
fc040538 | 557 | PerlIOVia_clearerr(pTHX_ PerlIO * f) |
e7a1fdd7 | 558 | { |
fc040538 NIS |
559 | PerlIOVia *s = PerlIOSelf(f, PerlIOVia); |
560 | PerlIOVia_method(aTHX_ f, MYMethod(CLEARERR), G_VOID, Nullsv); | |
561 | PerlIOBase_clearerr(aTHX_ f); | |
e7a1fdd7 NIS |
562 | } |
563 | ||
c7997937 | 564 | IV |
fc040538 | 565 | PerlIOVia_error(pTHX_ PerlIO * f) |
e7a1fdd7 | 566 | { |
fc040538 NIS |
567 | PerlIOVia *s = PerlIOSelf(f, PerlIOVia); |
568 | SV *result = | |
569 | PerlIOVia_method(aTHX_ f, "ERROR", &s->mERROR, G_SCALAR, Nullsv); | |
570 | return (result) ? SvIV(result) : PerlIOBase_error(aTHX_ f); | |
e7a1fdd7 NIS |
571 | } |
572 | ||
573 | IV | |
fc040538 | 574 | PerlIOVia_eof(pTHX_ PerlIO * f) |
e7a1fdd7 | 575 | { |
fc040538 NIS |
576 | PerlIOVia *s = PerlIOSelf(f, PerlIOVia); |
577 | SV *result = | |
578 | PerlIOVia_method(aTHX_ f, "EOF", &s->mEOF, G_SCALAR, Nullsv); | |
579 | return (result) ? SvIV(result) : PerlIOBase_eof(aTHX_ f); | |
e7a1fdd7 NIS |
580 | } |
581 | ||
ecdeb87c | 582 | SV * |
fc040538 | 583 | PerlIOVia_getarg(pTHX_ PerlIO * f, CLONE_PARAMS * param, int flags) |
ecdeb87c | 584 | { |
fc040538 | 585 | PerlIOVia *s = PerlIOSelf(f, PerlIOVia); |
c33e8be1 Z |
586 | PERL_UNUSED_ARG(param); |
587 | PERL_UNUSED_ARG(flags); | |
fc040538 | 588 | return PerlIOVia_method(aTHX_ f, MYMethod(GETARG), G_SCALAR, Nullsv); |
ecdeb87c NIS |
589 | } |
590 | ||
8cf8f3d1 | 591 | PerlIO * |
fc040538 NIS |
592 | PerlIOVia_dup(pTHX_ PerlIO * f, PerlIO * o, CLONE_PARAMS * param, |
593 | int flags) | |
8cf8f3d1 | 594 | { |
fc040538 NIS |
595 | if ((f = PerlIOBase_dup(aTHX_ f, o, param, flags))) { |
596 | /* Most of the fields will lazily set themselves up as needed | |
597 | stash and obj have been set up by the implied push | |
598 | */ | |
599 | } | |
600 | return f; | |
8cf8f3d1 NIS |
601 | } |
602 | ||
fc040538 NIS |
603 | |
604 | ||
27da23d5 | 605 | PERLIO_FUNCS_DECL(PerlIO_object) = { |
2dc2558e | 606 | sizeof(PerlIO_funcs), |
e934609f | 607 | "via", |
e7a1fdd7 NIS |
608 | sizeof(PerlIOVia), |
609 | PERLIO_K_BUFFERED|PERLIO_K_DESTRUCT, | |
610 | PerlIOVia_pushed, | |
611 | PerlIOVia_popped, | |
d9dac8cd | 612 | PerlIOVia_open, /* NULL, */ |
86e05cf2 | 613 | PerlIOVia_binmode, /* NULL, */ |
e7a1fdd7 NIS |
614 | PerlIOVia_getarg, |
615 | PerlIOVia_fileno, | |
8cf8f3d1 | 616 | PerlIOVia_dup, |
e7a1fdd7 NIS |
617 | PerlIOVia_read, |
618 | PerlIOVia_unread, | |
619 | PerlIOVia_write, | |
620 | PerlIOVia_seek, | |
621 | PerlIOVia_tell, | |
622 | PerlIOVia_close, | |
623 | PerlIOVia_flush, | |
624 | PerlIOVia_fill, | |
625 | PerlIOVia_eof, | |
626 | PerlIOVia_error, | |
627 | PerlIOVia_clearerr, | |
628 | PerlIOVia_setlinebuf, | |
629 | PerlIOVia_get_base, | |
630 | PerlIOVia_bufsiz, | |
631 | PerlIOVia_get_ptr, | |
632 | PerlIOVia_get_cnt, | |
633 | PerlIOVia_set_ptrcnt, | |
634 | }; | |
635 | ||
636 | ||
637 | #endif /* Layers available */ | |
638 | ||
e934609f | 639 | MODULE = PerlIO::via PACKAGE = PerlIO::via |
e7a1fdd7 NIS |
640 | PROTOTYPES: ENABLE; |
641 | ||
642 | BOOT: | |
643 | { | |
644 | #ifdef PERLIO_LAYERS | |
27da23d5 | 645 | PerlIO_define_layer(aTHX_ PERLIO_FUNCS_CAST(&PerlIO_object)); |
e7a1fdd7 NIS |
646 | #endif |
647 | } | |
648 | ||
fc040538 | 649 | |
30ef3321 NIS |
650 | |
651 | ||
652 |