File Coverage

blib/lib/IO/Callback.pm
Criterion Covered Total %
statement 221 221 100.0
branch 138 144 95.8
condition 48 51 94.1
subroutine 30 30 100.0
pod 1 20 5.0
total 438 466 93.9


line stmt bran cond sub pod time code
1             package IO::Callback;
2              
3 24     24   1888006 use warnings;
  24         225  
  24         857  
4 24     24   135 use strict;
  24         45  
  24         1717  
5              
6             =head1 NAME
7              
8             IO::Callback - Emulate file interface for a code reference
9              
10             =head1 VERSION
11              
12             Version 2.00
13              
14             =cut
15              
16             our $VERSION = '2.00';
17              
18             =head1 SYNOPSIS
19              
20             C provides an easy way to produce a phoney read-only filehandle that calls back to your own code when it needs data to satisfy a read. This is useful if you want to use a library module that expects to read data from a filehandle, but you want the data to come from some other source and you don't want to read it all into memory and use L.
21              
22             use IO::Callback;
23              
24             my $fh = IO::Callback->new('<', sub { ... ; return $data });
25             my $object = Some::Class->new_from_file($fh);
26              
27             Similarly, IO::Callback allows you to wrap up a coderef as a write-only filehandle, which you can pass to a library module that expects to write its output to a filehandle.
28              
29             my $fh = IO::Callback->new('>', sub { my $data = shift ; ... });
30             $object->dump_to_file($fh);
31              
32              
33             =head1 CONSTRUCTOR
34              
35             =head2 C
36              
37             Returns a filehandle object encapsulating the coderef.
38              
39             MODE must be either C> for a read-only filehandle or C> for a write-only filehandle.
40              
41             For a read-only filehandle, the callback coderef will be invoked in a scalar context each time more data is required to satisfy a read. It must return some more input data (at least one byte) as a string. If there is no more data to be read, then the callback should return either C or the empty string. If ARG values were supplied to the constructor, then they will be passed to the callback each time it is invoked.
42              
43             For a write-only filehandle, the callback will be invoked each time there is data to be written. The first argument will be the data as a string, which will always be at least one byte long. If ARG values were supplied to the constructor, then they will be passed as additional arguments to the callback. When the filehandle is closed, the callback will be invoked once with the empty string as its first argument.
44              
45             To simulate a non-fatal error on the file, the callback should set C<$!> and return the special value C. See examples 6 and 7 below.
46              
47             =head1 EXAMPLES
48              
49             =over 4
50              
51             =item Example 1
52              
53             To generate a filehandle from which an infinite number of C characters can be read:
54              
55             =for test "ex1" begin
56              
57             my $fh = IO::Callback->new('<', sub {"xxxxxxxxxxxxxxxxxxxxxxxxxxx"});
58              
59             my $x = $fh->getc; # $x now contains "x"
60             read $fh, $x, 5; # $x now contains "xxxxx"
61              
62             =for test "ex1" end
63              
64             =item Example 2
65              
66             A filehandle from which 1000 C lines can be read before EOF:
67              
68             =for test "ex2" begin
69              
70             my $count = 0;
71             my $fh = IO::Callback->new('<', sub {
72             return if ++$count > 1000; # EOF
73             return "foo\n";
74             });
75              
76             my $x = <$fh>; # $x now contains "foo\n"
77             read $fh, $x, 2; # $x now contains "fo"
78             read $fh, $x, 2; # $x now contains "o\n"
79             read $fh, $x, 20; # $x now contains "foo\nfoo\nfoo\nfoo\nfoo\n"
80             my @foos = <$fh>; # @foos now contains ("foo\n") x 993
81              
82             =for test "ex2" end
83              
84             The example above uses a C (a special kind of anonymous sub, see L) to allow the callback to keep track of how many lines it has returned. You don't have to use a closure if you don't want to, since C will forward extra constructor arguments to the callback. This example could be re-written as:
85              
86             =for test "ex2a" begin
87              
88             my $count = 0;
89             my $fh = IO::Callback->new('<', \&my_callback, \$count);
90              
91             my $x = <$fh>; # $x now contains "foo\n"
92             read $fh, $x, 2; # $x now contains "fo"
93             read $fh, $x, 2; # $x now contains "o\n"
94             read $fh, $x, 20; # $x now contains "foo\nfoo\nfoo\nfoo\nfoo\n"
95             my @foos = <$fh>; # @foos now contains ("foo\n") x 993
96              
97             sub my_callback {
98             my $count_ref = shift;
99              
100             return if ++$$count_ref > 1000; # EOF
101             return "foo\n";
102             };
103              
104             =for test "ex2a" end
105              
106             =item Example 3
107              
108             To generate a filehandle interface to data drawn from an SQL table:
109              
110             =for test "ex3" begin
111              
112             my $sth = $dbh->prepare("SELECT ...");
113             $sth->execute;
114             my $fh = IO::Callback->new('<', sub {
115             my @row = $sth->fetchrow_array;
116             return unless @row; # EOF
117             return join(',', @row) . "\n";
118             });
119              
120             # ...
121              
122             =for test "ex3" end
123              
124             =item Example 4
125              
126             You want a filehandle to which data can be written, where the data is discarded but an exception is raised if the data includes the string C.
127              
128             =for test "ex4" begin
129              
130             my $buf = '';
131             my $fh = IO::Callback->new('>', sub {
132             $buf .= shift;
133             die "foo written" if $buf =~ /foo/;
134              
135             if ($buf =~ /(fo?)\z/) {
136             # Part way through a "foo", carry over to the next block.
137             $buf = $1;
138             } else {
139             $buf = '';
140             }
141             });
142              
143             =for test "ex4" end
144              
145             =item Example 5
146              
147             You have been given an object with a copy_data_out() method that takes a destination filehandle as an argument. You don't want the data written to a file though, you want it split into 1024-byte blocks and inserted into an SQL database.
148              
149             =for test "ex5" begin
150              
151             my $blocksize = 1024;
152             my $sth = $dbh->prepare('INSERT ...');
153              
154             my $buf = '';
155             my $fh = IO::Callback->new('>', sub {
156             $buf .= shift;
157             while (length $buf >= $blocksize) {
158             $sth->execute(substr $buf, 0, $blocksize, '');
159             }
160             });
161              
162             $thing->copy_data_out($fh);
163              
164             if (length $buf) {
165             # There is a remainder of < $blocksize
166             $sth->execute($buf);
167             }
168              
169             =for test "ex5" end
170              
171             =item Example 6
172              
173             You're testing some code that reads data from a file, you want to check that it behaves as expected if it gets an IO error part way through the file.
174              
175             =for test "ex6" begin
176              
177             use IO::Callback;
178             use Errno qw/EIO/;
179              
180             my $block1 = "x" x 10240;
181             my $block2 = "y" x 10240;
182             my @blocks = ($block1, $block2);
183              
184             my $fh = IO::Callback->new('<', sub {
185             return shift @blocks if @blocks;
186             $! = EIO;
187             return IO::Callback::Error;
188             });
189              
190             # ...
191              
192             =for test "ex6" end
193              
194             =item Example 7
195              
196             You're testing some code that writes data to a file handle, you want to check that it behaves as expected if it gets a C error after it has written the first 100k of data.
197              
198             =for test "ex7" begin
199              
200             use IO::Callback;
201             use Errno qw/ENOSPC/;
202              
203             my $wrote = 0;
204             my $fh = IO::Callback->new('>', sub {
205             $wrote += length $_[0];
206             if ($wrote > 100_000) {
207             $! = ENOSPC;
208             return IO::Callback::Error;
209             }
210             });
211              
212             # ...
213              
214             =for test "ex7" end
215              
216             =back
217              
218             =cut
219              
220 24     24   153 use Carp;
  24         44  
  24         1479  
221 24     24   8445 use Errno qw/EBADF/;
  24         24159  
  24         2683  
222 24     24   12255 use IO::String;
  24         89232  
  24         835  
223 24     24   174 use base qw/IO::String/;
  24         47  
  24         63735  
224              
225             sub open
226             {
227 194001     194001 1 378879399 my $self = shift;
228 194001 50       550511 return $self->new(@_) unless ref($self);
229              
230 194001 100       440903 my $mode = shift or croak "mode missing in IO::Callback::new";
231 193995 100       462037 if ($mode eq '<') {
    100          
232 135324         322849 *$self->{r} = 1;
233             } elsif ($mode eq '>') {
234 58663         132051 *$self->{w} = 1;
235             } else {
236 8         71 croak qq{invalid mode "$mode" in IO::Callback::new};
237             }
238              
239 193987 100       427126 my $code = shift or croak "coderef missing in IO::Callback::new";
240 193983 100       401453 ref $code eq "CODE" or croak "non-coderef second argument in IO::Callback::new";
241              
242 193981         289490 my $buf = '';
243 193981         343653 *$self->{buf} = \$buf;
244 193981         334184 *$self->{pos} = 0;
245 193981         303896 *$self->{err} = 0;
246 193981         279108 *$self->{lno} = 0;
247              
248 193981 100       364350 if (@_) {
249 135260         269992 my @args = @_;
250 135260     1215935   694963 *$self->{code} = sub { $code->(@_, @args) };
  1215935         2093780  
251             } else {
252 58721         130974 *$self->{code} = $code;
253             }
254             }
255              
256             sub close
257             {
258 43     43 0 2128 my $self = shift;
259 43 100       154 return unless defined *$self->{code};
260 35 100       88 return if *$self->{err};
261 34 100       84 if (*$self->{w}) {
262 25         68 my $ret = *$self->{code}('');
263 25 100 100     177 if ($ret and ref $ret eq 'IO::Callback::ErrorMarker') {
264 1         3 *$self->{err} = 1;
265 1         12 return;
266             }
267             }
268 33         74 foreach my $key (qw/code buf eof r w pos lno/) {
269 231         434 delete *$self->{$key};
270             }
271 33         64 *$self->{err} = -1;
272 33 50       78 undef *$self if $] eq "5.008"; # cargo culted from IO::String
273 33         195 return 1;
274             }
275              
276             sub opened
277             {
278 38     38 0 329 my $self = shift;
279 38   100     213 return defined *$self->{r} || defined *$self->{w};
280             }
281              
282             sub getc
283             {
284 42689     42689 0 720638 my $self = shift;
285 42689 100       95381 *$self->{r} or return $self->_ebadf;
286 42685         53344 my $buf;
287 42685 100       73823 return $buf if $self->read($buf, 1);
288 3293         40136 return undef;
289             }
290              
291             sub ungetc
292             {
293 40232     40232 0 247376 my ($self, $char) = @_;
294 40232 100       93978 *$self->{r} or return $self->_ebadf;
295 40231         63699 my $buf = *$self->{buf};
296 40231         98159 $$buf = chr($char) . $$buf;
297 40231         60915 --*$self->{pos};
298 40231         61033 delete *$self->{eof};
299 40231         69226 return 1;
300             }
301              
302             sub eof
303             {
304 2     2 0 5 my $self = shift;
305 2         8 return *$self->{eof};
306             }
307              
308             # Use something very distinctive for the error return code, since write callbacks
309             # may pay no attention to what they are returning, and it would be bad to mistake
310             # returned noise for an error indication.
311             sub Error () {
312 21     21 0 3305 return bless {}, 'IO::Callback::ErrorMarker';
313             }
314              
315             sub _doread {
316 1224455     1224455   1520186 my $self = shift;
317              
318 1224455 100       2014899 return unless *$self->{code};
319 1217295         1702684 my $newbit = *$self->{code}();
320 1217295 100       5670378 if (defined $newbit) {
321 1084819 100       1675739 if (ref $newbit) {
322 9 100       26 if (ref $newbit eq 'IO::Callback::ErrorMarker') {
323 8         15 *$self->{err} = 1;
324 8         31 return;
325             } else {
326 1         27 confess "unexpected reference type ".ref($newbit)." returned by callback";
327             }
328             }
329 1084810 100       1601492 if (length $newbit) {
330 1083809         1153398 ${*$self->{buf}} .= $newbit;
  1083809         1763738  
331 1083809         2699472 return 1;
332             }
333             }
334              
335             # fall-through for both undef and ''
336 133477         520746 delete *$self->{code};
337 133477         290937 return;
338             }
339              
340             sub getline
341             {
342 201231     201231 0 1366618 my $self = shift;
343              
344 201231 100       407133 *$self->{r} or return $self->_ebadf;
345 201229 100 100     850794 return if *$self->{eof} || *$self->{err};
346 133457         187818 my $buf = *$self->{buf};
347 133457         228950 $. = *$self->{lno};
348              
349 133457 100       254058 unless (defined $/) { # slurp
350 26964         53813 1 while $self->_doread;
351 26964 100       57442 return if *$self->{err};
352 26962         45092 *$self->{pos} += length $$buf;
353 26962         44495 *$self->{eof} = 1;
354 26962         55276 *$self->{buf} = \(my $newbuf = '');
355 26962         49818 $. = ++ *$self->{lno};
356 26962         255709 return $$buf;
357             }
358              
359 106493 100       242392 my $rs = length $/ ? $/ : "\n\n";
360 106493         137818 for (;;) {
361             # In paragraph mode, discard extra newlines.
362 647014 100 100     1484430 if ($/ eq '' and $$buf =~ s/^(\n+)//) {
363 13312         32197 *$self->{pos} += length $1;
364             }
365 647014         939362 my $pos = index $$buf, $rs;
366 647014 100       990894 if ($pos >= 0) {
367 53539         87613 *$self->{pos} += $pos+length($rs);
368 53539         118240 my $ret = substr $$buf, 0, $pos+length($rs), '';
369 53539 100       104028 unless (length $/) {
370             # paragraph mode, discard extra trailing newlines
371 8226 100       24678 $$buf =~ s/^(\n+)// and *$self->{pos} += length $1;
372 8226   100     31146 while (*$self->{code} and length $$buf == 0) {
373 8698         19187 $self->_doread;
374 8698 50       16821 return if *$self->{err};
375 8698 100       32084 $$buf =~ s/^(\n+)// and *$self->{pos} += length $1;
376             }
377             }
378 53539   100     219673 $self->_doread while *$self->{code} and length $$buf == 0 and not *$self->{err};
      66        
379 53539 100 66     141279 if (length $$buf == 0 and not *$self->{code}) {
380 19845         34882 *$self->{eof} = 1;
381             }
382 53539         89302 $. = ++ *$self->{lno};
383 53539         429688 return $ret;
384             }
385 593475 100       930932 if (*$self->{code}) {
386 540525         966227 $self->_doread;
387 540525 100       904672 return if *$self->{err};
388             } else {
389             # EOL not in buffer and no more data to come - the last line is missing its EOL.
390 52950         89831 *$self->{eof} = 1;
391 52950         87170 *$self->{pos} += length $$buf;
392 52950         105614 *$self->{buf} = \(my $newbuf = '');
393 52950 100       130972 $. = ++ *$self->{lno} if length $$buf;
394 52950 100       441397 return $$buf if length $$buf;
395 10460         112794 return;
396             }
397             }
398             }
399              
400             sub getlines
401             {
402 60753 100   60753 0 1083289 croak "getlines() called in scalar context" unless wantarray;
403 60752         95396 my $self = shift;
404              
405 60752 100       141079 *$self->{r} or return $self->_ebadf;
406 60750 100 100     301745 return if *$self->{err} || *$self->{eof};
407              
408             # To exactly match Perl's behavior on real files, getlines() should not
409             # increment $. if there is no more input, but getline() should. I won't
410             # call getline() until I've established that there is more input.
411 56891         88521 my $buf = *$self->{buf};
412 56891 100       122196 unless (length $$buf) {
413 41563         101128 $self->_doread;
414 41563 100       160773 return unless length $$buf;
415             }
416              
417 50971         75079 my($line, @lines);
418 50971         104526 push(@lines, $line) while defined($line = $self->getline);
419 50971         827621 return @lines;
420             }
421              
422             sub READLINE
423             {
424 71105 100   71105   2266947 goto &getlines if wantarray;
425 40717         135343 goto &getline;
426             }
427              
428             sub read
429             {
430 332458     332458 0 5730778 my $self = shift;
431              
432 332458 100       712886 *$self->{r} or return $self->_ebadf;
433 332453   100     584162 my $len = $_[1]||0;
434              
435 332453 100       617116 croak "Negative length" if $len < 0;
436 332053 50       593562 return if *$self->{err};
437 332053 100       622074 return 0 if *$self->{eof};
438 326771         434465 my $buf = *$self->{buf};
439              
440 326771   100     1203534 1 while *$self->{code} and $len > length $$buf and $self->_doread;
      100        
441 326770 100       595259 return if *$self->{err};
442 326768 100       552650 if ($len > length $$buf) {
443 81295         105976 $len = length $$buf;
444 81295 100       173283 *$self->{eof} = 1 unless $len;
445             }
446              
447 326768 100       573643 if (@_ > 2) { # read offset
448 2281   100     4674 my $offset = $_[2]||0;
449 2281 100       4762 if ($offset < -1 * length $_[0]) {
450 480         50761 croak "Offset outside string";
451             }
452 1801 100       3457 if ($offset > length $_[0]) {
453 480         1277 $_[0] .= "\0" x ($offset - length $_[0]);
454             }
455 1801         4789 substr($_[0], $offset) = substr($$buf, 0, $len, '');
456             }
457             else {
458 324487         639641 $_[0] = substr($$buf, 0, $len, '');
459             }
460 326288         468662 *$self->{pos} += $len;
461 326288         3910138 return $len;
462             }
463              
464             *sysread = \&read;
465             *syswrite = \&write;
466              
467             sub stat {
468 1     1 0 7 my $self = shift;
469 1 50       3 return unless $self->opened;
470 1 50       5 return 1 unless wantarray;
471              
472 1         7 my @stat = $self->SUPER::stat();
473              
474             # size unknown, report 0
475 1         33 $stat[7] = 0;
476 1         2 $stat[12] = 1;
477              
478 1         4 return @stat;
479             }
480              
481             sub print
482             {
483 54454     54454 0 1482128 my $self = shift;
484              
485 54454         79368 my $result;
486 54454 100       121834 if (defined $\) {
487 40802 100       70402 if (defined $,) {
488 30601         110927 $result = $self->write(join($,, @_).$\);
489             }
490             else {
491 10201         36711 $result = $self->write(join("",@_).$\);
492             }
493             }
494             else {
495 13652 100       23153 if (defined $,) {
496 10200         32942 $result = $self->write(join($,, @_));
497             }
498             else {
499 3452         9878 $result = $self->write(join("",@_));
500             }
501             }
502              
503 54454 100       112300 return unless defined $result;
504 54424         144437 return 1;
505             }
506             *printflush = \*print;
507              
508             sub printf
509             {
510 3462     3462 0 93291 my $self = shift;
511 3462         5408 my $fmt = shift;
512 3462         12119 my $result = $self->write(sprintf($fmt, @_));
513 3462 100       7474 return unless defined $result;
514 3414         6882 return 1;
515             }
516              
517             sub getpos
518             {
519 773863     773863 0 13211433 my $self = shift;
520              
521 773863         1310487 $. = *$self->{lno};
522 773863         1636027 return *$self->{pos};
523             }
524             *tell = \&getpos;
525             *pos = \&getpos;
526              
527             sub setpos
528             {
529 1     1 0 745 croak "setpos not implemented for IO::Callback";
530             }
531              
532             sub truncate
533             {
534 1     1 0 698 croak "truncate not implemented for IO::Callback";
535             }
536              
537             sub seek
538             {
539 1     1 0 835 croak "Illegal seek";
540             }
541             *sysseek = \&seek;
542              
543             sub write
544             {
545 58771     58771 0 114478 my $self = shift;
546              
547 58771 100       129420 *$self->{w} or return $self->_ebadf;
548 58748 100       105829 return if *$self->{err};
549              
550 58667         87042 my $slen = length($_[0]);
551 58667         71900 my $len = $slen;
552 58667         82166 my $off = 0;
553 58667 100       105092 if (@_ > 1) {
554 815 100       1537 my $xlen = defined $_[1] ? $_[1] : 0;
555 815 100       1654 $len = $xlen if $xlen < $len;
556 815 100       8657 croak "Negative length" if $len < 0;
557 735 100       1364 if (@_ > 2) {
558 592   100     1296 $off = $_[2] || 0;
559 592 100 100     2104 if ( $off >= $slen and $off > 0 and ($] < 5.011 or $off > $slen) ) {
      66        
      100        
560 120         11279 croak "Offset outside string";
561             }
562 472 100       876 if ($off < 0) {
563 237         325 $off += $slen;
564 237 100       11347 croak "Offset outside string" if $off < 0;
565             }
566 352         589 my $rem = $slen - $off;
567 352 100       738 $len = $rem if $rem < $len;
568             }
569             }
570 58347 100       111451 return $len if $len == 0;
571 48578         132314 my $ret = *$self->{code}(substr $_[0], $off, $len);
572 48578 100 100     372326 if (defined $ret and ref $ret eq 'IO::Callback::ErrorMarker') {
573 12         28 *$self->{err} = 1;
574 12         80 return;
575             }
576 48566         82703 *$self->{pos} += $len;
577 48566         87483 return $len;
578             }
579              
580             sub error {
581 2885     2885 0 1690226 my $self = shift;
582              
583 2885         16545 return *$self->{err};
584             }
585              
586             sub clearerr {
587 33     33 0 16822 my $self = shift;
588              
589 33         121 *$self->{err} = 0;
590             }
591              
592             sub _ebadf {
593 37     37   54 my $self = shift;
594              
595 37         81 $! = EBADF;
596 37         62 *$self->{err} = -1;
597 37         218 return;
598             }
599              
600             *GETC = \&getc;
601             *PRINT = \&print;
602             *PRINTF = \&printf;
603             *READ = \&read;
604             *WRITE = \&write;
605             *SEEK = \&seek;
606             *TELL = \&getpos;
607             *EOF = \&eof;
608             *CLOSE = \&close;
609              
610             =head1 AUTHOR
611              
612             Dave Taylor, C<< >>
613              
614             =head1 BUGS AND LIMITATIONS
615              
616             Fails to inter-operate with some library modules that read or write filehandles from within XS code. I am aware of the following specific cases, please let me know if you run into any others:
617              
618             =over 4
619              
620             =item C
621              
622             =back
623              
624             Please report any other bugs or feature requests to C, or through
625             the web interface at L. I will be notified, and then you'll
626             automatically be notified of progress on your bug as I make changes.
627              
628             =head1 SUPPORT
629              
630             You can find documentation for this module with the perldoc command.
631              
632             perldoc IO::Callback
633              
634             You can also look for information at:
635              
636             =over 4
637              
638             =item * RT: CPAN's request tracker
639              
640             L
641              
642             =item * AnnoCPAN: Annotated CPAN documentation
643              
644             L
645              
646             =item * CPAN Ratings
647              
648             L
649              
650             =item * Search CPAN
651              
652             L
653              
654             =back
655              
656             =head1 SEE ALSO
657              
658             L, L, L
659              
660             =head1 ACKNOWLEDGEMENTS
661              
662             Adapted from code in L by Gisle Aas.
663              
664             =head1 MANITAINER
665              
666             This module is currently being maintained by Toby Inkster (TOBYINK)
667             for bug fixes. No substantial changes or new features are planned.
668              
669             =head1 COPYRIGHT & LICENSE
670              
671             Copyright 1998-2005 Gisle Aas.
672              
673             Copyright 2009-2010 Dave Taylor.
674              
675             This program is free software; you can redistribute it and/or modify it
676             under the same terms as Perl itself.
677              
678             =cut
679              
680             1; # End of IO::Callback