- Timestamp:
- 2011-06-01T12:33:42+12:00 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
main/trunk/greenstone2/perllib/cpan/File/RandomAccess.pm
r16844 r24107 4 4 # Description: Buffer to support random access reading of sequential file 5 5 # 6 # Revisions: 02/11/04 - P. Harvey Created 7 # 02/20/04 - P. Harvey Added flag to disable SeekTest in new() 8 # 11/18/04 - P. Harvey Fixed bug with seek relative to end of file 9 # 01/02/05 - P. Harvey Added DEBUG code 10 # 01/09/06 - P. Harvey Fixed bug in ReadLine() when using 11 # multi-character EOL sequences 12 # 02/20/06 - P. Harvey Fixed bug where seek past end of file could 13 # generate "substr outside string" warning 14 # 06/10/06 - P. Harvey Decreased $CHUNK_SIZE from 64k to 8k 15 # 11/23/06 - P. Harvey Limit reads to < 0x80000000 bytes 6 # Revisions: 02/11/2004 - P. Harvey Created 7 # 02/20/2004 - P. Harvey Added flag to disable SeekTest in new() 8 # 11/18/2004 - P. Harvey Fixed bug with seek relative to end of file 9 # 01/02/2005 - P. Harvey Added DEBUG code 10 # 01/09/2006 - P. Harvey Fixed bug in ReadLine() when using 11 # multi-character EOL sequences 12 # 02/20/2006 - P. Harvey Fixed bug where seek past end of file could 13 # generate "substr outside string" warning 14 # 06/10/2006 - P. Harvey Decreased $CHUNK_SIZE from 64k to 8k 15 # 11/23/2006 - P. Harvey Limit reads to < 0x80000000 bytes 16 # 11/26/2008 - P. Harvey Fixed bug in ReadLine when reading from a 17 # scalar with a multi-character newline 18 # 01/24/2009 - PH Protect against reading too much at once 16 19 # 17 20 # Notes: Calls the normal file i/o routines unless SeekTest() fails, in … … 22 25 # May also be used for string i/o (just pass a scalar reference) 23 26 # 24 # Legal: Copyright (c) 200 4-2006Phil Harvey (phil at owl.phy.queensu.ca)27 # Legal: Copyright (c) 2003-2010 Phil Harvey (phil at owl.phy.queensu.ca) 25 28 # This library is free software; you can redistribute it and/or 26 29 # modify it under the same terms as Perl itself. … … 34 37 35 38 use vars qw($VERSION @ISA @EXPORT_OK); 36 $VERSION = '1. 07';39 $VERSION = '1.10'; 37 40 @ISA = qw(Exporter); 41 42 sub Read($$$); 38 43 39 44 # constants … … 64 69 # file i/o 65 70 my $buff = ''; 66 $self = { 71 $self = { 67 72 FILE_PT => $filePt, # file pointer 68 73 BUFF_PT => \$buff, # reference to file data … … 156 161 #------------------------------------------------------------------------------ 157 162 # Read from the file 158 # Inputs: 0) reference to RandomAccess object 159 # 1) buffer, 2) bytes to read 163 # Inputs: 0) reference to RandomAccess object, 1) buffer, 2) bytes to read 160 164 # Returns: Number of bytes read 161 165 sub Read($$$) … … 165 169 my $rtnVal; 166 170 167 # avoid dying with "Negative length" error 168 return 0 if $len & 0x80000000; 169 171 # protect against reading too much at once 172 # (also from dying with a "Negative length" error) 173 if ($len & 0xf8000000) { 174 return 0 if $len < 0; 175 # read in smaller blocks because Windows attempts to pre-allocate 176 # memory for the full size, which can lead to an out-of-memory error 177 my $maxLen = 0x4000000; # (MUST be less than bitmask in "if" above) 178 my $num = Read($self, $_[0], $maxLen); 179 return $num if $num < $maxLen; 180 for (;;) { 181 $len -= $maxLen; 182 last if $len <= 0; 183 my $l = $len < $maxLen ? $len : $maxLen; 184 my $buff; 185 my $n = Read($self, $buff, $l); 186 last unless $n; 187 $_[0] .= $buff; 188 $num += $n; 189 last if $n < $l; 190 } 191 return $num; 192 } 193 # read through our buffer if necessary 170 194 if ($self->{TESTED} < 0) { 171 195 my $buff; … … 196 220 $self->{POS} += $rtnVal; 197 221 } else { 222 # read directly from file 198 223 $_[0] = '' unless defined $_[0]; 199 224 $rtnVal = read($self->{FILE_PT}, $_[0], $len) || 0; … … 204 229 $self->{DEBUG}->{$pos} = $rtnVal; 205 230 } 206 } 231 } 207 232 return $rtnVal; 208 233 } … … 217 242 my $rtnVal; 218 243 my $fp = $self->{FILE_PT}; 219 244 220 245 if ($self->{TESTED} < 0) { 221 246 my ($num, $buff); … … 231 256 # scan and read until we find the EOL (or hit EOF) 232 257 for (;;) { 233 $pos = index(${$self->{BUFF_PT}}, $/, $pos) + length($/); 234 last if $pos > 0; 258 $pos = index(${$self->{BUFF_PT}}, $/, $pos); 259 if ($pos >= 0) { 260 $pos += length($/); 261 last; 262 } 235 263 $pos = $self->{LEN}; # have scanned to end of buffer 236 264 $num = read($fp, $buff, $CHUNK_SIZE) or last; … … 240 268 } else { 241 269 # string i/o 242 $pos = index(${$self->{BUFF_PT}}, $/, $pos) + length($/); 243 $pos <= 0 and $pos = $self->{LEN}; 270 $pos = index(${$self->{BUFF_PT}}, $/, $pos); 271 if ($pos < 0) { 272 $pos = $self->{LEN}; 273 $self->{POS} = $pos if $self->{POS} > $pos; 274 } else { 275 $pos += length($/); 276 } 244 277 } 245 278 # read the line from our buffer … … 260 293 $self->{DEBUG}->{$pos} = $rtnVal; 261 294 } 262 } 263 return $rtnVal; 295 } 296 return $rtnVal; 264 297 } 265 298 … … 295 328 { 296 329 my $self = shift; 297 330 298 331 if ($self->{DEBUG}) { 299 332 local $_;
Note:
See TracChangeset
for help on using the changeset viewer.