File Coverage

lib/IO/Scalar.pm
Criterion Covered Total %
statement 112 165 67.8
branch 35 46 76.0
condition 6 13 46.1
subroutine 26 48 54.1
pod 23 24 95.8
total 202 296 68.2


line stmt bran cond sub pod time code
1             package IO::Scalar;
2              
3              
4             =head1 NAME
5              
6             IO::Scalar - IO:: interface for reading/writing a scalar
7              
8              
9             =head1 SYNOPSIS
10              
11             Perform I/O on strings, using the basic OO interface...
12              
13             use 5.005;
14             use IO::Scalar;
15             $data = "My message:\n";
16              
17             ### Open a handle on a string, and append to it:
18             $SH = new IO::Scalar \$data;
19             $SH->print("Hello");
20             $SH->print(", world!\nBye now!\n");
21             print "The string is now: ", $data, "\n";
22              
23             ### Open a handle on a string, read it line-by-line, then close it:
24             $SH = new IO::Scalar \$data;
25             while (defined($_ = $SH->getline)) {
26             print "Got line: $_";
27             }
28             $SH->close;
29              
30             ### Open a handle on a string, and slurp in all the lines:
31             $SH = new IO::Scalar \$data;
32             print "All lines:\n", $SH->getlines;
33              
34             ### Get the current position (either of two ways):
35             $pos = $SH->getpos;
36             $offset = $SH->tell;
37              
38             ### Set the current position (either of two ways):
39             $SH->setpos($pos);
40             $SH->seek($offset, 0);
41              
42             ### Open an anonymous temporary scalar:
43             $SH = new IO::Scalar;
44             $SH->print("Hi there!");
45             print "I printed: ", ${$SH->sref}, "\n"; ### get at value
46              
47              
48             Don't like OO for your I/O? No problem.
49             Thanks to the magic of an invisible tie(), the following now
50             works out of the box, just as it does with IO::Handle:
51              
52             use 5.005;
53             use IO::Scalar;
54             $data = "My message:\n";
55              
56             ### Open a handle on a string, and append to it:
57             $SH = new IO::Scalar \$data;
58             print $SH "Hello";
59             print $SH ", world!\nBye now!\n";
60             print "The string is now: ", $data, "\n";
61              
62             ### Open a handle on a string, read it line-by-line, then close it:
63             $SH = new IO::Scalar \$data;
64             while (<$SH>) {
65             print "Got line: $_";
66             }
67             close $SH;
68              
69             ### Open a handle on a string, and slurp in all the lines:
70             $SH = new IO::Scalar \$data;
71             print "All lines:\n", <$SH>;
72              
73             ### Get the current position (WARNING: requires 5.6):
74             $offset = tell $SH;
75              
76             ### Set the current position (WARNING: requires 5.6):
77             seek $SH, $offset, 0;
78              
79             ### Open an anonymous temporary scalar:
80             $SH = new IO::Scalar;
81             print $SH "Hi there!";
82             print "I printed: ", ${$SH->sref}, "\n"; ### get at value
83              
84              
85             And for you folks with 1.x code out there: the old tie() style still works,
86             though this is I:
87              
88             use IO::Scalar;
89              
90             ### Writing to a scalar...
91             my $s;
92             tie *OUT, 'IO::Scalar', \$s;
93             print OUT "line 1\nline 2\n", "line 3\n";
94             print "String is now: $s\n"
95              
96             ### Reading and writing an anonymous scalar...
97             tie *OUT, 'IO::Scalar';
98             print OUT "line 1\nline 2\n", "line 3\n";
99             tied(OUT)->seek(0,0);
100             while () {
101             print "Got line: ", $_;
102             }
103              
104              
105             Stringification works, too!
106              
107             my $SH = new IO::Scalar \$data;
108             print $SH "Hello, ";
109             print $SH "world!";
110             print "I printed: $SH\n";
111              
112              
113              
114             =head1 DESCRIPTION
115              
116             This class is part of the IO::Stringy distribution;
117             see L for change log and general information.
118              
119             The IO::Scalar class implements objects which behave just like
120             IO::Handle (or FileHandle) objects, except that you may use them
121             to write to (or read from) scalars. These handles are
122             automatically tiehandle'd (though please see L<"WARNINGS">
123             for information relevant to your Perl version).
124              
125              
126             Basically, this:
127              
128             my $s;
129             $SH = new IO::Scalar \$s;
130             $SH->print("Hel", "lo, "); ### OO style
131             $SH->print("world!\n"); ### ditto
132              
133             Or this:
134              
135             my $s;
136             $SH = tie *OUT, 'IO::Scalar', \$s;
137             print OUT "Hel", "lo, "; ### non-OO style
138             print OUT "world!\n"; ### ditto
139              
140             Causes $s to be set to:
141              
142             "Hello, world!\n"
143              
144              
145             =head1 PUBLIC INTERFACE
146              
147             =cut
148              
149 4     4   9780 use Carp;
  4         5  
  4         235  
150 4     4   16 use strict;
  4         4  
  4         98  
151 4     4   12 use vars qw($VERSION @ISA);
  4         4  
  4         224  
152 4     4   1364 use IO::Handle;
  4         12831  
  4         127  
153              
154 4     4   65 use 5.005;
  4         9  
  4         191  
155              
156             ### Stringification, courtesy of B. K. Oxley (binkley): :-)
157 4     4   3418 use overload '""' => sub { ${*{$_[0]}->{SR}} };
  4     3   2787  
  4         23  
  3         25  
  3         3  
  3         11  
158 4     4   196 use overload 'bool' => sub { 1 }; ### have to do this, so object is true!
  4     1   6  
  4         13  
  1         9  
159              
160             ### The package version, both in 1.23 style *and* usable by MakeMaker:
161             $VERSION = "2.111";
162              
163             ### Inheritance:
164             @ISA = qw(IO::Handle);
165              
166             ### This stuff should be got rid of ASAP.
167             require IO::WrapTie and push @ISA, 'IO::WrapTie::Slave' if ($] >= 5.004);
168              
169             #==============================
170              
171             =head2 Construction
172              
173             =over 4
174              
175             =cut
176              
177             #------------------------------
178              
179             =item new [ARGS...]
180              
181             I
182             Return a new, unattached scalar handle.
183             If any arguments are given, they're sent to open().
184              
185             =cut
186              
187             sub new {
188 12     12 1 923391 my $proto = shift;
189 12   33     51 my $class = ref($proto) || $proto;
190 12         12 my $self = bless \do { local *FH }, $class;
  12         38  
191 12         464 tie *$self, $class, $self;
192 12         30 $self->open(@_); ### open on anonymous by default
193 12         23 $self;
194             }
195             sub DESTROY {
196 11     11   319 shift->close;
197             }
198              
199             #------------------------------
200              
201             =item open [SCALARREF]
202              
203             I
204             Open the scalar handle on a new scalar, pointed to by SCALARREF.
205             If no SCALARREF is given, a "private" scalar is created to hold
206             the file data.
207              
208             Returns the self object on success, undefined on error.
209              
210             =cut
211              
212             sub open {
213 12     12 1 15 my ($self, $sref) = @_;
214              
215             ### Sanity:
216 12 100       31 defined($sref) or do {my $s = ''; $sref = \$s};
  2         4  
  2         6  
217 12 50       25 (ref($sref) eq "SCALAR") or croak "open() needs a ref to a scalar";
218              
219             ### Setup:
220 12         27 *$self->{Pos} = 0; ### seek position
221 12         23 *$self->{SR} = $sref; ### scalar reference
222 12         14 $self;
223             }
224              
225             #------------------------------
226              
227             =item opened
228              
229             I
230             Is the scalar handle opened on something?
231              
232             =cut
233              
234             sub opened {
235 0     0 1 0 *{shift()}->{SR};
  0         0  
236             }
237              
238             #------------------------------
239              
240             =item close
241              
242             I
243             Disassociate the scalar handle from its underlying scalar.
244             Done automatically on destroy.
245              
246             =cut
247              
248             sub close {
249 11     11 1 9 my $self = shift;
250 11         11 %{*$self} = ();
  11         21  
251 11         24 1;
252             }
253              
254             =back
255              
256             =cut
257              
258              
259              
260             #==============================
261              
262             =head2 Input and output
263              
264             =over 4
265              
266             =cut
267              
268              
269             #------------------------------
270              
271             =item flush
272              
273             I
274             No-op, provided for OO compatibility.
275              
276             =cut
277              
278 0     0 1 0 sub flush { "0 but true" }
279              
280             #------------------------------
281              
282             =item fileno
283              
284             I
285             No-op, returns undef
286              
287             =cut
288              
289 1     1 1 29 sub fileno { }
290              
291             #------------------------------
292              
293             =item getc
294              
295             I
296             Return the next character, or undef if none remain.
297              
298             =cut
299              
300             sub getc {
301 3     3 1 7 my $self = shift;
302              
303             ### Return undef right away if at EOF; else, move pos forward:
304 3 50       4 return undef if $self->eof;
305 3         2 substr(${*$self->{SR}}, *$self->{Pos}++, 1);
  3         10  
306             }
307              
308             #------------------------------
309              
310             =item getline
311              
312             I
313             Return the next line, or undef on end of string.
314             Can safely be called in an array context.
315             Currently, lines are delimited by "\n".
316              
317             =cut
318              
319             sub getline {
320 49     49 1 646 my $self = shift;
321              
322             ### Return undef right away if at EOF:
323 49 100       50 return undef if $self->eof;
324              
325             ### Get next line:
326 42         61 my $sr = *$self->{SR};
327 42         45 my $i = *$self->{Pos}; ### Start matching at this point.
328              
329             ### Minimal impact implementation!
330             ### We do the fast thing (no regexps) if using the
331             ### classic input record separator.
332              
333             ### Case 1: $/ is undef: slurp all...
334 42 100       90 if (!defined($/)) {
    100          
    50          
335 2         3 *$self->{Pos} = length $$sr;
336 2         10 return substr($$sr, $i);
337             }
338              
339             ### Case 2: $/ is "\n": zoom zoom zoom...
340             elsif ($/ eq "\012") {
341              
342             ### Seek ahead for "\n"... yes, this really is faster than regexps.
343 35         33 my $len = length($$sr);
344 35         49 for (; $i < $len; ++$i) {
345 797 100       1317 last if ord (substr ($$sr, $i, 1)) == 10;
346             }
347              
348             ### Extract the line:
349 35         31 my $line;
350 35 100       36 if ($i < $len) { ### We found a "\n":
351 34         74 $line = substr ($$sr, *$self->{Pos}, $i - *$self->{Pos} + 1);
352 34         44 *$self->{Pos} = $i+1; ### Remember where we finished up.
353             }
354             else { ### No "\n"; slurp the remainder:
355 1         3 $line = substr ($$sr, *$self->{Pos}, $i - *$self->{Pos});
356 1         7 *$self->{Pos} = $len;
357             }
358 35         91 return $line;
359             }
360              
361             ### Case 3: $/ is ref to int. Do fixed-size records.
362             ### (Thanks to Dominique Quatravaux.)
363             elsif (ref($/)) {
364 0         0 my $len = length($$sr);
365 0         0 my $i = ${$/} + 0;
  0         0  
366 0         0 my $line = substr ($$sr, *$self->{Pos}, $i);
367 0         0 *$self->{Pos} += $i;
368 0 0       0 *$self->{Pos} = $len if (*$self->{Pos} > $len);
369 0         0 return $line;
370             }
371              
372             ### Case 4: $/ is either "" (paragraphs) or something weird...
373             ### This is Graham's general-purpose stuff, which might be
374             ### a tad slower than Case 2 for typical data, because
375             ### of the regexps.
376             else {
377 5         7 pos($$sr) = $i;
378              
379             ### If in paragraph mode, skip leading lines (and update i!):
380 5 100 33     16 length($/) or
381             (($$sr =~ m/\G\n*/g) and ($i = pos($$sr)));
382              
383             ### If we see the separator in the buffer ahead...
384 5 100       26 if (length($/)
    100          
385             ? $$sr =~ m,\Q$/\E,g ### (ordinary sep) TBD: precomp!
386             : $$sr =~ m,\n\n,g ### (a paragraph)
387             ) {
388 4         6 *$self->{Pos} = pos $$sr;
389 4         18 return substr($$sr, $i, *$self->{Pos}-$i);
390             }
391             ### Else if no separator remains, just slurp the rest:
392             else {
393 1         2 *$self->{Pos} = length $$sr;
394 1         4 return substr($$sr, $i);
395             }
396             }
397             }
398              
399             #------------------------------
400              
401             =item getlines
402              
403             I
404             Get all remaining lines.
405             It will croak() if accidentally called in a scalar context.
406              
407             =cut
408              
409             sub getlines {
410 3     3 1 6 my $self = shift;
411 3 50       7 wantarray or croak("can't call getlines in scalar context!");
412 3         4 my ($line, @lines);
413 3         8 push @lines, $line while (defined($line = $self->getline));
414 3         13 @lines;
415             }
416              
417             #------------------------------
418              
419             =item print ARGS...
420              
421             I
422             Print ARGS to the underlying scalar.
423              
424             B this continues to always cause a seek to the end
425             of the string, but if you perform seek()s and tell()s, it is
426             still safer to explicitly seek-to-end before subsequent print()s.
427              
428             =cut
429              
430             sub print {
431 14     14 1 21 my $self = shift;
432 14 50       11 *$self->{Pos} = length(${*$self->{SR}} .= join('', @_) . (defined($\) ? $\ : ""));
  14         76  
433 14         24 1;
434             }
435             sub _unsafe_print {
436 0     0   0 my $self = shift;
437 0         0 my $append = join('', @_) . $\;
438 0         0 ${*$self->{SR}} .= $append;
  0         0  
439 0         0 *$self->{Pos} += length($append);
440 0         0 1;
441             }
442             sub _old_print {
443 0     0   0 my $self = shift;
444 0         0 ${*$self->{SR}} .= join('', @_) . $\;
  0         0  
445 0         0 *$self->{Pos} = length(${*$self->{SR}});
  0         0  
446 0         0 1;
447             }
448              
449              
450             #------------------------------
451              
452             =item read BUF, NBYTES, [OFFSET]
453              
454             I
455             Read some bytes from the scalar.
456             Returns the number of bytes actually read, 0 on end-of-file, undef on error.
457              
458             =cut
459              
460             sub read {
461 6     6 1 33 my $self = $_[0];
462 6         1 my $n = $_[2];
463 6   50     14 my $off = $_[3] || 0;
464              
465 6         6 my $read = substr(${*$self->{SR}}, *$self->{Pos}, $n);
  6         10  
466 6         6 $n = length($read);
467 6         5 *$self->{Pos} += $n;
468 6 50       10 ($off ? substr($_[1], $off) : $_[1]) = $read;
469 6         5 return $n;
470             }
471              
472             #------------------------------
473              
474             =item write BUF, NBYTES, [OFFSET]
475              
476             I
477             Write some bytes to the scalar.
478              
479             =cut
480              
481             sub write {
482 0     0 1 0 my $self = $_[0];
483 0         0 my $n = $_[2];
484 0   0     0 my $off = $_[3] || 0;
485              
486 0         0 my $data = substr($_[1], $off, $n);
487 0         0 $n = length($data);
488 0         0 $self->print($data);
489 0         0 return $n;
490             }
491              
492             #------------------------------
493              
494             =item sysread BUF, LEN, [OFFSET]
495              
496             I
497             Read some bytes from the scalar.
498             Returns the number of bytes actually read, 0 on end-of-file, undef on error.
499              
500             =cut
501              
502             sub sysread {
503 0     0 1 0 my $self = shift;
504 0         0 $self->read(@_);
505             }
506              
507             #------------------------------
508              
509             =item syswrite BUF, NBYTES, [OFFSET]
510              
511             I
512             Write some bytes to the scalar.
513              
514             =cut
515              
516             sub syswrite {
517 0     0 1 0 my $self = shift;
518 0         0 $self->write(@_);
519             }
520              
521             =back
522              
523             =cut
524              
525              
526             #==============================
527              
528             =head2 Seeking/telling and other attributes
529              
530             =over 4
531              
532             =cut
533              
534              
535             #------------------------------
536              
537             =item autoflush
538              
539             I
540             No-op, provided for OO compatibility.
541              
542             =cut
543              
544 0     0 1 0 sub autoflush {}
545              
546             #------------------------------
547              
548             =item binmode
549              
550             I
551             No-op, provided for OO compatibility.
552              
553             =cut
554              
555 0     0 1 0 sub binmode {}
556              
557             #------------------------------
558              
559             =item clearerr
560              
561             I Clear the error and EOF flags. A no-op.
562              
563             =cut
564              
565 0     0 1 0 sub clearerr { 1 }
566              
567             #------------------------------
568              
569             =item eof
570              
571             I Are we at end of file?
572              
573             =cut
574              
575             sub eof {
576 52     52 1 36 my $self = shift;
577 52         62 (*$self->{Pos} >= length(${*$self->{SR}}));
  52         116  
578             }
579              
580             #------------------------------
581              
582             =item seek OFFSET, WHENCE
583              
584             I Seek to a given position in the stream.
585              
586             =cut
587              
588             sub seek {
589 12     12 1 471 my ($self, $pos, $whence) = @_;
590 12         12 my $eofpos = length(${*$self->{SR}});
  12         23  
591              
592             ### Seek:
593 12 100       29 if ($whence == 0) { *$self->{Pos} = $pos } ### SEEK_SET
  10 100       14  
    50          
594 1         2 elsif ($whence == 1) { *$self->{Pos} += $pos } ### SEEK_CUR
595 1         2 elsif ($whence == 2) { *$self->{Pos} = $eofpos + $pos} ### SEEK_END
596 0         0 else { croak "bad seek whence ($whence)" }
597              
598             ### Fixup:
599 12 50       29 if (*$self->{Pos} < 0) { *$self->{Pos} = 0 }
  0         0  
600 12 50       30 if (*$self->{Pos} > $eofpos) { *$self->{Pos} = $eofpos }
  0         0  
601 12         20 return 1;
602             }
603              
604             #------------------------------
605              
606             =item sysseek OFFSET, WHENCE
607              
608             I Identical to C, I
609              
610             =cut
611              
612             sub sysseek {
613 0     0 1 0 my $self = shift;
614 0         0 $self->seek (@_);
615             }
616              
617             #------------------------------
618              
619             =item tell
620              
621             I
622             Return the current position in the stream, as a numeric offset.
623              
624             =cut
625              
626 1     1 1 22 sub tell { *{shift()}->{Pos} }
  1         6  
627              
628             #------------------------------
629             #
630             # use_RS [YESNO]
631             #
632             # I
633             # Obey the current setting of $/, like IO::Handle does?
634             # Default is false in 1.x, but cold-welded true in 2.x and later.
635             #
636             sub use_RS {
637 0     0 0 0 my ($self, $yesno) = @_;
638 0         0 carp "use_RS is deprecated and ignored; \$/ is always consulted\n";
639             }
640              
641             #------------------------------
642              
643             =item setpos POS
644              
645             I
646             Set the current position, using the opaque value returned by C.
647              
648             =cut
649              
650 0     0 1 0 sub setpos { shift->seek($_[0],0) }
651              
652             #------------------------------
653              
654             =item getpos
655              
656             I
657             Return the current position in the string, as an opaque object.
658              
659             =cut
660              
661             *getpos = \&tell;
662              
663              
664             #------------------------------
665              
666             =item sref
667              
668             I
669             Return a reference to the underlying scalar.
670              
671             =cut
672              
673 2     2 1 8 sub sref { *{shift()}->{SR} }
  2         11  
674              
675              
676             #------------------------------
677             # Tied handle methods...
678             #------------------------------
679              
680             # Conventional tiehandle interface:
681             sub TIEHANDLE {
682 14 100 100 14   122 ((defined($_[1]) && UNIVERSAL::isa($_[1], "IO::Scalar"))
683             ? $_[1]
684             : shift->new(@_));
685             }
686 0     0   0 sub GETC { shift->getc(@_) }
687 11     11   284 sub PRINT { shift->print(@_) }
688 0     0   0 sub PRINTF { shift->print(sprintf(shift, @_)) }
689 0     0   0 sub READ { shift->read(@_) }
690 9 100   9   76 sub READLINE { wantarray ? shift->getlines(@_) : shift->getline(@_) }
691 0     0     sub WRITE { shift->write(@_); }
692 0     0     sub CLOSE { shift->close(@_); }
693 0     0     sub SEEK { shift->seek(@_); }
694 0     0     sub TELL { shift->tell(@_); }
695 0     0     sub EOF { shift->eof(@_); }
696 0     0     sub BINMODE { 1; }
697              
698             #------------------------------------------------------------
699              
700             1;
701              
702             __END__