- Timestamp:
- 2021-02-26T19:39:51+13:00 (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
main/trunk/greenstone2/perllib/cpan/File/RandomAccess.pm
r24107 r34921 17 17 # scalar with a multi-character newline 18 18 # 01/24/2009 - PH Protect against reading too much at once 19 # 10/04/2018 - PH Added NoBuffer option 19 20 # 20 21 # Notes: Calls the normal file i/o routines unless SeekTest() fails, in … … 25 26 # May also be used for string i/o (just pass a scalar reference) 26 27 # 27 # Legal: Copyright (c) 2003-20 10 Phil Harvey (phil at owl.phy.queensu.ca)28 # Legal: Copyright (c) 2003-2021 Phil Harvey (philharvey66 at gmail.com) 28 29 # This library is free software; you can redistribute it and/or 29 30 # modify it under the same terms as Perl itself. … … 37 38 38 39 use vars qw($VERSION @ISA @EXPORT_OK); 39 $VERSION = '1.1 0';40 $VERSION = '1.11'; 40 41 @ISA = qw(Exporter); 41 42 … … 44 45 # constants 45 46 my $CHUNK_SIZE = 8192; # size of chunks to read from file (must be power of 2) 47 my $SKIP_SIZE = 65536; # size to skip when fast-forwarding over sequential data 46 48 my $SLURP_CHUNKS = 16; # read this many chunks at a time when slurping 47 49 … … 61 63 $self = { 62 64 BUFF_PT => $filePt, 65 BASE => 0, 63 66 POS => 0, 64 67 LEN => length($$filePt), … … 72 75 FILE_PT => $filePt, # file pointer 73 76 BUFF_PT => \$buff, # reference to file data 74 POS => 0, # current position in file 75 LEN => 0, # data length 77 BASE => 0, # location of start of buffer in file 78 POS => 0, # current position in buffer 79 LEN => 0, # length of data in buffer 76 80 TESTED => 0, # 0=untested, 1=passed, -1=failed (requires buffering) 77 81 }; … … 119 123 my $rtnVal; 120 124 if ($self->{TESTED} < 0) { 121 $rtnVal = $self->{POS} ;125 $rtnVal = $self->{POS} + $self->{BASE}; 122 126 } else { 123 127 $rtnVal = tell($self->{FILE_PT}); … … 142 146 my $newPos; 143 147 if ($whence == 0) { 144 $newPos = $num ;# from start of file148 $newPos = $num - $self->{BASE}; # from start of file 145 149 } elsif ($whence == 1) { 146 150 $newPos = $num + $self->{POS}; # relative to current position 151 } elsif ($self->{NoBuffer} and $self->{FILE_PT}) { 152 $newPos = -1; # (can't seek relative to end if no buffering) 147 153 } else { 148 154 $self->Slurp(); # read whole file into buffer … … 193 199 # read through our buffer if necessary 194 200 if ($self->{TESTED} < 0) { 201 # purge old data before reading in NoBuffer mode 202 $self->Purge() or return 0 if $self->{NoBuffer}; 195 203 my $buff; 196 204 my $newPos = $self->{POS} + $len; … … 245 253 if ($self->{TESTED} < 0) { 246 254 my ($num, $buff); 255 $self->Purge() or return 0 if $self->{NoBuffer}; 247 256 my $pos = $self->{POS}; 248 257 if ($fp) { … … 312 321 } 313 322 314 315 #------------------------------------------------------------------------------ 316 # set binary mode 323 #------------------------------------------------------------------------------ 324 # Purge internal buffer [internal use only] 325 # Inputs: 0) reference to RandomAccess object 326 # Returns: 1 on success, or 0 if current buffer position is negative 327 # Notes: This is called only in NoBuffer mode 328 sub Purge($) 329 { 330 my $self = shift; 331 return 1 unless $self->{FILE_PT}; 332 return 0 if $self->{POS} < 0; # error if we can't read from here 333 if ($self->{POS} > $CHUNK_SIZE) { 334 my $purge = $self->{POS} - ($self->{POS} % $CHUNK_SIZE); 335 if ($purge >= $self->{LEN}) { 336 # read up to current position in 64k chunks, discarding as we go 337 while ($self->{POS} > $self->{LEN}) { 338 $self->{BASE} += $self->{LEN}; 339 $self->{POS} -= $self->{LEN}; 340 ${$self->{BUFF_PT}} = ''; 341 $self->{LEN} = read($self->{FILE_PT}, ${$self->{BUFF_PT}}, $SKIP_SIZE); 342 last if $self->{LEN} < $SKIP_SIZE; 343 } 344 } elsif ($purge > 0) { 345 ${$self->{BUFF_PT}} = substr ${$self->{BUFF_PT}}, $purge; 346 $self->{BASE} += $purge; 347 $self->{POS} -= $purge; 348 $self->{LEN} -= $purge; 349 } 350 } 351 return 1; 352 } 353 354 #------------------------------------------------------------------------------ 355 # Set binary mode 317 356 # Inputs: 0) reference to RandomAccess object 318 357 sub BinMode($) … … 323 362 324 363 #------------------------------------------------------------------------------ 325 # close the file and free the buffer364 # Close the file and free the buffer 326 365 # Inputs: 0) reference to RandomAccess object 327 366 sub Close($) … … 371 410 my $emptyBuff = ''; 372 411 $self->{BUFF_PT} = \$emptyBuff; 412 $self->{BASE} = 0; 373 413 $self->{LEN} = 0; 374 414 $self->{POS} = 0;
Note:
See TracChangeset
for help on using the changeset viewer.