1 #define PERL_NO_GET_CONTEXT
9 static const char code_point_warning[] =
10 "Strings with code points over 0xFF may not be mapped into in-memory file handles\n";
13 struct _PerlIO base; /* Base "class" info */
19 PerlIOScalar_pushed(pTHX_ PerlIO * f, const char *mode, SV * arg,
23 PerlIOScalar *s = PerlIOSelf(f, PerlIOScalar);
24 /* If called (normally) via open() then arg is ref to scalar we are
25 * using, otherwise arg (from binmode presumably) is either NULL
26 * or the _name_ of the scalar
28 if (arg && SvOK(arg)) {
30 if (SvREADONLY(SvRV(arg)) && !SvIsCOW(SvRV(arg))
31 && mode && *mode != 'r') {
32 if (ckWARN(WARN_LAYER))
33 Perl_warner(aTHX_ packWARN(WARN_LAYER), "%s", PL_no_modify);
34 SETERRNO(EINVAL, SS_IVCHAN);
37 s->var = SvREFCNT_inc(SvRV(arg));
39 if (!SvPOK(s->var) && SvOK(s->var))
40 (void)SvPV_nomg_const_nolen(s->var);
44 SvREFCNT_inc(perl_get_sv
45 (SvPV_nolen(arg), GV_ADD | GV_ADDMULTI));
49 s->var = newSVpvn("", 0);
52 /* force refs, overload etc to be plain strings */
53 (void)SvPV_force_nomg_nolen(s->var);
55 SvUPGRADE(s->var, SVt_PV);
57 code = PerlIOBase_pushed(aTHX_ f, mode, Nullsv, tab);
58 if (!SvOK(s->var) || (PerlIOBase(f)->flags) & PERLIO_F_TRUNCATE)
60 sv_force_normal(s->var);
63 if (SvUTF8(s->var) && !sv_utf8_downgrade(s->var, TRUE)) {
64 if (ckWARN(WARN_UTF8))
65 Perl_warner(aTHX_ packWARN(WARN_UTF8), code_point_warning);
66 SETERRNO(EINVAL, SS_IVCHAN);
71 if ((PerlIOBase(f)->flags) & PERLIO_F_APPEND)
73 sv_force_normal(s->var);
74 s->posn = SvCUR(s->var);
83 PerlIOScalar_popped(pTHX_ PerlIO * f)
85 PerlIOScalar *s = PerlIOSelf(f, PerlIOScalar);
94 PerlIOScalar_close(pTHX_ PerlIO * f)
96 IV code = PerlIOBase_close(aTHX_ f);
97 PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF | PERLIO_F_WRBUF);
102 PerlIOScalar_fileno(pTHX_ PerlIO * f)
109 PerlIOScalar_seek(pTHX_ PerlIO * f, Off_t offset, int whence)
111 PerlIOScalar *s = PerlIOSelf(f, PerlIOScalar);
118 s->posn = offset + s->posn;
123 (void)SvPV(s->var, oldcur);
124 s->posn = offset + oldcur;
129 if (ckWARN(WARN_LAYER))
130 Perl_warner(aTHX_ packWARN(WARN_LAYER), "Offset outside string");
131 SETERRNO(EINVAL, SS_IVCHAN);
138 PerlIOScalar_tell(pTHX_ PerlIO * f)
140 PerlIOScalar *s = PerlIOSelf(f, PerlIOScalar);
146 PerlIOScalar_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
150 if (!(PerlIOBase(f)->flags & PERLIO_F_CANREAD)) {
151 PerlIOBase(f)->flags |= PERLIO_F_ERROR;
152 SETERRNO(EBADF, SS_IVCHAN);
156 PerlIOScalar *s = PerlIOSelf(f, PerlIOScalar);
163 if (sv_utf8_downgrade(sv, TRUE)) {
164 p = SvPV_nomg(sv, len);
167 if (ckWARN(WARN_UTF8))
168 Perl_warner(aTHX_ packWARN(WARN_UTF8), code_point_warning);
169 SETERRNO(EINVAL, SS_IVCHAN);
173 got = len - (STRLEN)(s->posn);
176 if ((STRLEN)got > (STRLEN)count)
178 Copy(p + (STRLEN)(s->posn), vbuf, got, STDCHAR);
179 s->posn += (Off_t)got;
185 PerlIOScalar_write(pTHX_ PerlIO * f, const void *vbuf, Size_t count)
187 if (PerlIOBase(f)->flags & PERLIO_F_CANWRITE) {
189 PerlIOScalar *s = PerlIOSelf(f, PerlIOScalar);
193 if (!SvROK(sv)) sv_force_normal(sv);
194 if (SvOK(sv)) SvPV_force_nomg_nolen(sv);
195 if (SvUTF8(sv) && !sv_utf8_downgrade(sv, TRUE)) {
196 if (ckWARN(WARN_UTF8))
197 Perl_warner(aTHX_ packWARN(WARN_UTF8), code_point_warning);
198 SETERRNO(EINVAL, SS_IVCHAN);
201 if ((PerlIOBase(f)->flags) & PERLIO_F_APPEND) {
202 dst = SvGROW(sv, SvCUR(sv) + count + 1);
204 s->posn = offset + count;
207 STRLEN const cur = SvCUR(sv);
209 dst = SvGROW(sv, (STRLEN)s->posn + count + 1);
210 Zero(SvPVX(sv) + cur, (STRLEN)s->posn - cur, char);
212 else if ((s->posn + count) >= cur)
213 dst = SvGROW(sv, (STRLEN)s->posn + count + 1);
219 Move(vbuf, dst + offset, count, char);
220 if ((STRLEN) s->posn > SvCUR(sv)) {
221 SvCUR_set(sv, (STRLEN)s->posn);
222 dst[(STRLEN) s->posn] = 0;
233 PerlIOScalar_fill(pTHX_ PerlIO * f)
240 PerlIOScalar_flush(pTHX_ PerlIO * f)
247 PerlIOScalar_get_base(pTHX_ PerlIO * f)
249 PerlIOScalar *s = PerlIOSelf(f, PerlIOScalar);
250 if (PerlIOBase(f)->flags & PERLIO_F_CANREAD) {
252 return (STDCHAR *) SvPV_nolen(s->var);
254 return (STDCHAR *) NULL;
258 PerlIOScalar_get_ptr(pTHX_ PerlIO * f)
260 if (PerlIOBase(f)->flags & PERLIO_F_CANREAD) {
261 PerlIOScalar *s = PerlIOSelf(f, PerlIOScalar);
262 return PerlIOScalar_get_base(aTHX_ f) + s->posn;
264 return (STDCHAR *) NULL;
268 PerlIOScalar_get_cnt(pTHX_ PerlIO * f)
270 if (PerlIOBase(f)->flags & PERLIO_F_CANREAD) {
271 PerlIOScalar *s = PerlIOSelf(f, PerlIOScalar);
274 if (isGV_with_GP(s->var))
275 (void)SvPV(s->var,len);
276 else len = SvCUR(s->var);
277 if (len > (STRLEN) s->posn)
278 return len - (STRLEN)s->posn;
286 PerlIOScalar_bufsiz(pTHX_ PerlIO * f)
288 if (PerlIOBase(f)->flags & PERLIO_F_CANREAD) {
289 PerlIOScalar *s = PerlIOSelf(f, PerlIOScalar);
291 return SvCUR(s->var);
297 PerlIOScalar_set_ptrcnt(pTHX_ PerlIO * f, STDCHAR * ptr, SSize_t cnt)
299 PerlIOScalar *s = PerlIOSelf(f, PerlIOScalar);
301 PERL_UNUSED_ARG(ptr);
303 if (isGV_with_GP(s->var)) (void)SvPV(s->var,len);
304 else len = SvCUR(s->var);
309 PerlIOScalar_open(pTHX_ PerlIO_funcs * self, PerlIO_list_t * layers, IV n,
310 const char *mode, int fd, int imode, int perm,
311 PerlIO * f, int narg, SV ** args)
313 SV *arg = (narg > 0) ? *args : PerlIOArg;
315 PERL_UNUSED_ARG(imode);
316 PERL_UNUSED_ARG(perm);
317 if (SvROK(arg) || SvPOK(arg)) {
319 f = PerlIO_allocate(aTHX);
321 if ( (f = PerlIO_push(aTHX_ f, self, mode, arg)) ) {
322 PerlIOBase(f)->flags |= PERLIO_F_OPEN;
330 PerlIOScalar_arg(pTHX_ PerlIO * f, CLONE_PARAMS * param, int flags)
332 PerlIOScalar *s = PerlIOSelf(f, PerlIOScalar);
334 if (flags & PERLIO_DUP_CLONE)
335 var = PerlIO_sv_dup(aTHX_ var, param);
336 else if (flags & PERLIO_DUP_FD) {
337 /* Equivalent (guesses NI-S) of dup() is to create a new scalar */
341 var = SvREFCNT_inc(var);
343 return newRV_noinc(var);
347 PerlIOScalar_dup(pTHX_ PerlIO * f, PerlIO * o, CLONE_PARAMS * param,
350 /* Duplication causes the scalar layer to be pushed on to clone, caus-
351 ing the cloned scalar to be set to the empty string by
352 PerlIOScalar_pushed. So set aside our scalar temporarily. */
353 PerlIOScalar * const os = PerlIOSelf(o, PerlIOScalar);
355 SV * const var = os->var;
356 os->var = newSVpvs("");
357 if ((f = PerlIOBase_dup(aTHX_ f, o, param, flags))) {
358 fs = PerlIOSelf(f, PerlIOScalar);
359 /* var has been set by implicit push, so replace it */
360 SvREFCNT_dec(fs->var);
362 SvREFCNT_dec(os->var);
365 SV * const rv = PerlIOScalar_arg(aTHX_ o, param, flags);
366 fs->var = SvREFCNT_inc(SvRV(rv));
373 PERLIO_FUNCS_DECL(PerlIO_scalar) = {
374 sizeof(PerlIO_funcs),
376 sizeof(PerlIOScalar),
377 PERLIO_K_BUFFERED | PERLIO_K_RAW,
396 PerlIOBase_setlinebuf,
397 PerlIOScalar_get_base,
399 PerlIOScalar_get_ptr,
400 PerlIOScalar_get_cnt,
401 PerlIOScalar_set_ptrcnt,
405 #endif /* Layers available */
407 MODULE = PerlIO::scalar PACKAGE = PerlIO::scalar
414 PerlIO_define_layer(aTHX_ PERLIO_FUNCS_CAST(&PerlIO_scalar));