1package Test::Builder::IO::Scalar; 2 3 4=head1 NAME 5 6Test::Builder::IO::Scalar - A copy of IO::Scalar for Test::Builder 7 8=head1 DESCRIPTION 9 10This is a copy of L<IO::Scalar> which ships with L<Test::Builder> to 11support scalar references as filehandles on Perl 5.6. Newer 12versions of Perl simply use C<open()>'s built in support. 13 14L<Test::Builder> can not have dependencies on other modules without 15careful consideration, so its simply been copied into the distribution. 16 17=head1 COPYRIGHT and LICENSE 18 19This file came from the "IO-stringy" Perl5 toolkit. 20 21Copyright (c) 1996 by Eryq. All rights reserved. 22Copyright (c) 1999,2001 by ZeeGee Software Inc. All rights reserved. 23 24This program is free software; you can redistribute it and/or 25modify it under the same terms as Perl itself. 26 27 28=cut 29 30# This is copied code, I don't care. 31##no critic 32 33use Carp; 34use strict; 35use vars qw($VERSION @ISA); 36use IO::Handle; 37 38use 5.005; 39 40### The package version, both in 1.23 style *and* usable by MakeMaker: 41$VERSION = "2.114"; 42 43### Inheritance: 44@ISA = qw(IO::Handle); 45 46#============================== 47 48=head2 Construction 49 50=over 4 51 52=cut 53 54#------------------------------ 55 56=item new [ARGS...] 57 58I<Class method.> 59Return a new, unattached scalar handle. 60If any arguments are given, they're sent to open(). 61 62=cut 63 64sub new { 65 my $proto = shift; 66 my $class = ref($proto) || $proto; 67 my $self = bless \do { local *FH }, $class; 68 tie *$self, $class, $self; 69 $self->open(@_); ### open on anonymous by default 70 $self; 71} 72sub DESTROY { 73 shift->close; 74} 75 76#------------------------------ 77 78=item open [SCALARREF] 79 80I<Instance method.> 81Open the scalar handle on a new scalar, pointed to by SCALARREF. 82If no SCALARREF is given, a "private" scalar is created to hold 83the file data. 84 85Returns the self object on success, undefined on error. 86 87=cut 88 89sub open { 90 my ($self, $sref) = @_; 91 92 ### Sanity: 93 defined($sref) or do {my $s = ''; $sref = \$s}; 94 (ref($sref) eq "SCALAR") or croak "open() needs a ref to a scalar"; 95 96 ### Setup: 97 *$self->{Pos} = 0; ### seek position 98 *$self->{SR} = $sref; ### scalar reference 99 $self; 100} 101 102#------------------------------ 103 104=item opened 105 106I<Instance method.> 107Is the scalar handle opened on something? 108 109=cut 110 111sub opened { 112 *{shift()}->{SR}; 113} 114 115#------------------------------ 116 117=item close 118 119I<Instance method.> 120Disassociate the scalar handle from its underlying scalar. 121Done automatically on destroy. 122 123=cut 124 125sub close { 126 my $self = shift; 127 %{*$self} = (); 128 1; 129} 130 131=back 132 133=cut 134 135 136 137#============================== 138 139=head2 Input and output 140 141=over 4 142 143=cut 144 145 146#------------------------------ 147 148=item flush 149 150I<Instance method.> 151No-op, provided for OO compatibility. 152 153=cut 154 155sub flush { "0 but true" } 156 157#------------------------------ 158 159=item getc 160 161I<Instance method.> 162Return the next character, or undef if none remain. 163 164=cut 165 166sub getc { 167 my $self = shift; 168 169 ### Return undef right away if at EOF; else, move pos forward: 170 return undef if $self->eof; 171 substr(${*$self->{SR}}, *$self->{Pos}++, 1); 172} 173 174#------------------------------ 175 176=item getline 177 178I<Instance method.> 179Return the next line, or undef on end of string. 180Can safely be called in an array context. 181Currently, lines are delimited by "\n". 182 183=cut 184 185sub getline { 186 my $self = shift; 187 188 ### Return undef right away if at EOF: 189 return undef if $self->eof; 190 191 ### Get next line: 192 my $sr = *$self->{SR}; 193 my $i = *$self->{Pos}; ### Start matching at this point. 194 195 ### Minimal impact implementation! 196 ### We do the fast fast thing (no regexps) if using the 197 ### classic input record separator. 198 199 ### Case 1: $/ is undef: slurp all... 200 if (!defined($/)) { 201 *$self->{Pos} = length $$sr; 202 return substr($$sr, $i); 203 } 204 205 ### Case 2: $/ is "\n": zoom zoom zoom... 206 elsif ($/ eq "\012") { 207 208 ### Seek ahead for "\n"... yes, this really is faster than regexps. 209 my $len = length($$sr); 210 for (; $i < $len; ++$i) { 211 last if ord (substr ($$sr, $i, 1)) == 10; 212 } 213 214 ### Extract the line: 215 my $line; 216 if ($i < $len) { ### We found a "\n": 217 $line = substr ($$sr, *$self->{Pos}, $i - *$self->{Pos} + 1); 218 *$self->{Pos} = $i+1; ### Remember where we finished up. 219 } 220 else { ### No "\n"; slurp the remainder: 221 $line = substr ($$sr, *$self->{Pos}, $i - *$self->{Pos}); 222 *$self->{Pos} = $len; 223 } 224 return $line; 225 } 226 227 ### Case 3: $/ is ref to int. Do fixed-size records. 228 ### (Thanks to Dominique Quatravaux.) 229 elsif (ref($/)) { 230 my $len = length($$sr); 231 my $i = ${$/} + 0; 232 my $line = substr ($$sr, *$self->{Pos}, $i); 233 *$self->{Pos} += $i; 234 *$self->{Pos} = $len if (*$self->{Pos} > $len); 235 return $line; 236 } 237 238 ### Case 4: $/ is either "" (paragraphs) or something weird... 239 ### This is Graham's general-purpose stuff, which might be 240 ### a tad slower than Case 2 for typical data, because 241 ### of the regexps. 242 else { 243 pos($$sr) = $i; 244 245 ### If in paragraph mode, skip leading lines (and update i!): 246 length($/) or 247 (($$sr =~ m/\G\n*/g) and ($i = pos($$sr))); 248 249 ### If we see the separator in the buffer ahead... 250 if (length($/) 251 ? $$sr =~ m,\Q$/\E,g ### (ordinary sep) TBD: precomp! 252 : $$sr =~ m,\n\n,g ### (a paragraph) 253 ) { 254 *$self->{Pos} = pos $$sr; 255 return substr($$sr, $i, *$self->{Pos}-$i); 256 } 257 ### Else if no separator remains, just slurp the rest: 258 else { 259 *$self->{Pos} = length $$sr; 260 return substr($$sr, $i); 261 } 262 } 263} 264 265#------------------------------ 266 267=item getlines 268 269I<Instance method.> 270Get all remaining lines. 271It will croak() if accidentally called in a scalar context. 272 273=cut 274 275sub getlines { 276 my $self = shift; 277 wantarray or croak("can't call getlines in scalar context!"); 278 my ($line, @lines); 279 push @lines, $line while (defined($line = $self->getline)); 280 @lines; 281} 282 283#------------------------------ 284 285=item print ARGS... 286 287I<Instance method.> 288Print ARGS to the underlying scalar. 289 290B<Warning:> this continues to always cause a seek to the end 291of the string, but if you perform seek()s and tell()s, it is 292still safer to explicitly seek-to-end before subsequent print()s. 293 294=cut 295 296sub print { 297 my $self = shift; 298 *$self->{Pos} = length(${*$self->{SR}} .= join('', @_) . (defined($\) ? $\ : "")); 299 1; 300} 301sub _unsafe_print { 302 my $self = shift; 303 my $append = join('', @_) . $\; 304 ${*$self->{SR}} .= $append; 305 *$self->{Pos} += length($append); 306 1; 307} 308sub _old_print { 309 my $self = shift; 310 ${*$self->{SR}} .= join('', @_) . $\; 311 *$self->{Pos} = length(${*$self->{SR}}); 312 1; 313} 314 315 316#------------------------------ 317 318=item read BUF, NBYTES, [OFFSET] 319 320I<Instance method.> 321Read some bytes from the scalar. 322Returns the number of bytes actually read, 0 on end-of-file, undef on error. 323 324=cut 325 326sub read { 327 my $self = $_[0]; 328 my $n = $_[2]; 329 my $off = $_[3] || 0; 330 331 my $read = substr(${*$self->{SR}}, *$self->{Pos}, $n); 332 $n = length($read); 333 *$self->{Pos} += $n; 334 ($off ? substr($_[1], $off) : $_[1]) = $read; 335 return $n; 336} 337 338#------------------------------ 339 340=item write BUF, NBYTES, [OFFSET] 341 342I<Instance method.> 343Write some bytes to the scalar. 344 345=cut 346 347sub write { 348 my $self = $_[0]; 349 my $n = $_[2]; 350 my $off = $_[3] || 0; 351 352 my $data = substr($_[1], $off, $n); 353 $n = length($data); 354 $self->print($data); 355 return $n; 356} 357 358#------------------------------ 359 360=item sysread BUF, LEN, [OFFSET] 361 362I<Instance method.> 363Read some bytes from the scalar. 364Returns the number of bytes actually read, 0 on end-of-file, undef on error. 365 366=cut 367 368sub sysread { 369 my $self = shift; 370 $self->read(@_); 371} 372 373#------------------------------ 374 375=item syswrite BUF, NBYTES, [OFFSET] 376 377I<Instance method.> 378Write some bytes to the scalar. 379 380=cut 381 382sub syswrite { 383 my $self = shift; 384 $self->write(@_); 385} 386 387=back 388 389=cut 390 391 392#============================== 393 394=head2 Seeking/telling and other attributes 395 396=over 4 397 398=cut 399 400 401#------------------------------ 402 403=item autoflush 404 405I<Instance method.> 406No-op, provided for OO compatibility. 407 408=cut 409 410sub autoflush {} 411 412#------------------------------ 413 414=item binmode 415 416I<Instance method.> 417No-op, provided for OO compatibility. 418 419=cut 420 421sub binmode {} 422 423#------------------------------ 424 425=item clearerr 426 427I<Instance method.> Clear the error and EOF flags. A no-op. 428 429=cut 430 431sub clearerr { 1 } 432 433#------------------------------ 434 435=item eof 436 437I<Instance method.> Are we at end of file? 438 439=cut 440 441sub eof { 442 my $self = shift; 443 (*$self->{Pos} >= length(${*$self->{SR}})); 444} 445 446#------------------------------ 447 448=item seek OFFSET, WHENCE 449 450I<Instance method.> Seek to a given position in the stream. 451 452=cut 453 454sub seek { 455 my ($self, $pos, $whence) = @_; 456 my $eofpos = length(${*$self->{SR}}); 457 458 ### Seek: 459 if ($whence == 0) { *$self->{Pos} = $pos } ### SEEK_SET 460 elsif ($whence == 1) { *$self->{Pos} += $pos } ### SEEK_CUR 461 elsif ($whence == 2) { *$self->{Pos} = $eofpos + $pos} ### SEEK_END 462 else { croak "bad seek whence ($whence)" } 463 464 ### Fixup: 465 if (*$self->{Pos} < 0) { *$self->{Pos} = 0 } 466 if (*$self->{Pos} > $eofpos) { *$self->{Pos} = $eofpos } 467 return 1; 468} 469 470#------------------------------ 471 472=item sysseek OFFSET, WHENCE 473 474I<Instance method.> Identical to C<seek OFFSET, WHENCE>, I<q.v.> 475 476=cut 477 478sub sysseek { 479 my $self = shift; 480 $self->seek (@_); 481} 482 483#------------------------------ 484 485=item tell 486 487I<Instance method.> 488Return the current position in the stream, as a numeric offset. 489 490=cut 491 492sub tell { *{shift()}->{Pos} } 493 494#------------------------------ 495 496=item use_RS [YESNO] 497 498I<Instance method.> 499B<Deprecated and ignored.> 500Obey the current setting of $/, like IO::Handle does? 501Default is false in 1.x, but cold-welded true in 2.x and later. 502 503=cut 504 505sub use_RS { 506 my ($self, $yesno) = @_; 507 carp "use_RS is deprecated and ignored; \$/ is always consulted\n"; 508 } 509 510#------------------------------ 511 512=item setpos POS 513 514I<Instance method.> 515Set the current position, using the opaque value returned by C<getpos()>. 516 517=cut 518 519sub setpos { shift->seek($_[0],0) } 520 521#------------------------------ 522 523=item getpos 524 525I<Instance method.> 526Return the current position in the string, as an opaque object. 527 528=cut 529 530*getpos = \&tell; 531 532 533#------------------------------ 534 535=item sref 536 537I<Instance method.> 538Return a reference to the underlying scalar. 539 540=cut 541 542sub sref { *{shift()}->{SR} } 543 544 545#------------------------------ 546# Tied handle methods... 547#------------------------------ 548 549# Conventional tiehandle interface: 550sub TIEHANDLE { 551 ((defined($_[1]) && UNIVERSAL::isa($_[1], __PACKAGE__)) 552 ? $_[1] 553 : shift->new(@_)); 554} 555sub GETC { shift->getc(@_) } 556sub PRINT { shift->print(@_) } 557sub PRINTF { shift->print(sprintf(shift, @_)) } 558sub READ { shift->read(@_) } 559sub READLINE { wantarray ? shift->getlines(@_) : shift->getline(@_) } 560sub WRITE { shift->write(@_); } 561sub CLOSE { shift->close(@_); } 562sub SEEK { shift->seek(@_); } 563sub TELL { shift->tell(@_); } 564sub EOF { shift->eof(@_); } 565sub FILENO { -1 } 566 567#------------------------------------------------------------ 568 5691; 570 571__END__ 572 573 574 575=back 576 577=cut 578 579 580=head1 WARNINGS 581 582Perl's TIEHANDLE spec was incomplete prior to 5.005_57; 583it was missing support for C<seek()>, C<tell()>, and C<eof()>. 584Attempting to use these functions with an IO::Scalar will not work 585prior to 5.005_57. IO::Scalar will not have the relevant methods 586invoked; and even worse, this kind of bug can lie dormant for a while. 587If you turn warnings on (via C<$^W> or C<perl -w>), 588and you see something like this... 589 590 attempt to seek on unopened filehandle 591 592...then you are probably trying to use one of these functions 593on an IO::Scalar with an old Perl. The remedy is to simply 594use the OO version; e.g.: 595 596 $SH->seek(0,0); ### GOOD: will work on any 5.005 597 seek($SH,0,0); ### WARNING: will only work on 5.005_57 and beyond 598 599 600=head1 VERSION 601 602$Id: Scalar.pm,v 1.6 2005/02/10 21:21:53 dfs Exp $ 603 604 605=head1 AUTHORS 606 607=head2 Primary Maintainer 608 609David F. Skoll (F<dfs@roaringpenguin.com>). 610 611=head2 Principal author 612 613Eryq (F<eryq@zeegee.com>). 614President, ZeeGee Software Inc (F<http://www.zeegee.com>). 615 616 617=head2 Other contributors 618 619The full set of contributors always includes the folks mentioned 620in L<IO::Stringy/"CHANGE LOG">. But just the same, special 621thanks to the following individuals for their invaluable contributions 622(if I've forgotten or misspelled your name, please email me!): 623 624I<Andy Glew,> 625for contributing C<getc()>. 626 627I<Brandon Browning,> 628for suggesting C<opened()>. 629 630I<David Richter,> 631for finding and fixing the bug in C<PRINTF()>. 632 633I<Eric L. Brine,> 634for his offset-using read() and write() implementations. 635 636I<Richard Jones,> 637for his patches to massively improve the performance of C<getline()> 638and add C<sysread> and C<syswrite>. 639 640I<B. K. Oxley (binkley),> 641for stringification and inheritance improvements, 642and sundry good ideas. 643 644I<Doug Wilson,> 645for the IO::Handle inheritance and automatic tie-ing. 646 647 648=head1 SEE ALSO 649 650L<IO::String>, which is quite similar but which was designed 651more-recently and with an IO::Handle-like interface in mind, 652so you could mix OO- and native-filehandle usage without using tied(). 653 654I<Note:> as of version 2.x, these classes all work like 655their IO::Handle counterparts, so we have comparable 656functionality to IO::String. 657 658=cut 659 660