| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | # IO::Zlib.pm | 
| 2 |  |  |  |  |  |  | # | 
| 3 |  |  |  |  |  |  | # Copyright (c) 1998-2004 Tom Hughes . | 
| 4 |  |  |  |  |  |  | # All rights reserved. This program is free software; you can redistribute | 
| 5 |  |  |  |  |  |  | # it and/or modify it under the same terms as Perl itself. | 
| 6 |  |  |  |  |  |  |  | 
| 7 |  |  |  |  |  |  | package IO::Zlib; | 
| 8 |  |  |  |  |  |  |  | 
| 9 |  |  |  |  |  |  | =head1 NAME | 
| 10 |  |  |  |  |  |  |  | 
| 11 |  |  |  |  |  |  | IO::Zlib - IO:: style interface to L | 
| 12 |  |  |  |  |  |  |  | 
| 13 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 14 |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  | With any version of Perl 5 you can use the basic OO interface: | 
| 16 |  |  |  |  |  |  |  | 
| 17 |  |  |  |  |  |  | use IO::Zlib; | 
| 18 |  |  |  |  |  |  |  | 
| 19 |  |  |  |  |  |  | $fh = new IO::Zlib; | 
| 20 |  |  |  |  |  |  | if ($fh->open("file.gz", "rb")) { | 
| 21 |  |  |  |  |  |  | print <$fh>; | 
| 22 |  |  |  |  |  |  | $fh->close; | 
| 23 |  |  |  |  |  |  | } | 
| 24 |  |  |  |  |  |  |  | 
| 25 |  |  |  |  |  |  | $fh = IO::Zlib->new("file.gz", "wb9"); | 
| 26 |  |  |  |  |  |  | if (defined $fh) { | 
| 27 |  |  |  |  |  |  | print $fh "bar\n"; | 
| 28 |  |  |  |  |  |  | $fh->close; | 
| 29 |  |  |  |  |  |  | } | 
| 30 |  |  |  |  |  |  |  | 
| 31 |  |  |  |  |  |  | $fh = IO::Zlib->new("file.gz", "rb"); | 
| 32 |  |  |  |  |  |  | if (defined $fh) { | 
| 33 |  |  |  |  |  |  | print <$fh>; | 
| 34 |  |  |  |  |  |  | undef $fh;       # automatically closes the file | 
| 35 |  |  |  |  |  |  | } | 
| 36 |  |  |  |  |  |  |  | 
| 37 |  |  |  |  |  |  | With Perl 5.004 you can also use the TIEHANDLE interface to access | 
| 38 |  |  |  |  |  |  | compressed files just like ordinary files: | 
| 39 |  |  |  |  |  |  |  | 
| 40 |  |  |  |  |  |  | use IO::Zlib; | 
| 41 |  |  |  |  |  |  |  | 
| 42 |  |  |  |  |  |  | tie *FILE, 'IO::Zlib', "file.gz", "wb"; | 
| 43 |  |  |  |  |  |  | print FILE "line 1\nline2\n"; | 
| 44 |  |  |  |  |  |  |  | 
| 45 |  |  |  |  |  |  | tie *FILE, 'IO::Zlib', "file.gz", "rb"; | 
| 46 |  |  |  |  |  |  | while () { print "LINE: ", $_ }; | 
| 47 |  |  |  |  |  |  |  | 
| 48 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 49 |  |  |  |  |  |  |  | 
| 50 |  |  |  |  |  |  | C provides an IO:: style interface to L and | 
| 51 |  |  |  |  |  |  | hence to gzip/zlib compressed files. It provides many of the same methods | 
| 52 |  |  |  |  |  |  | as the L interface. | 
| 53 |  |  |  |  |  |  |  | 
| 54 |  |  |  |  |  |  | Starting from IO::Zlib version 1.02, IO::Zlib can also use an | 
| 55 |  |  |  |  |  |  | external F command.  The default behaviour is to try to use | 
| 56 |  |  |  |  |  |  | an external F if no C can be loaded, unless | 
| 57 |  |  |  |  |  |  | explicitly disabled by | 
| 58 |  |  |  |  |  |  |  | 
| 59 |  |  |  |  |  |  | use IO::Zlib qw(:gzip_external 0); | 
| 60 |  |  |  |  |  |  |  | 
| 61 |  |  |  |  |  |  | If explicitly enabled by | 
| 62 |  |  |  |  |  |  |  | 
| 63 |  |  |  |  |  |  | use IO::Zlib qw(:gzip_external 1); | 
| 64 |  |  |  |  |  |  |  | 
| 65 |  |  |  |  |  |  | then the external F is used B of C. | 
| 66 |  |  |  |  |  |  |  | 
| 67 |  |  |  |  |  |  | =head1 CONSTRUCTOR | 
| 68 |  |  |  |  |  |  |  | 
| 69 |  |  |  |  |  |  | =over 4 | 
| 70 |  |  |  |  |  |  |  | 
| 71 |  |  |  |  |  |  | =item new ( [ARGS] ) | 
| 72 |  |  |  |  |  |  |  | 
| 73 |  |  |  |  |  |  | Creates an C object. If it receives any parameters, they are | 
| 74 |  |  |  |  |  |  | passed to the method C; if the open fails, the object is destroyed. | 
| 75 |  |  |  |  |  |  | Otherwise, it is returned to the caller. | 
| 76 |  |  |  |  |  |  |  | 
| 77 |  |  |  |  |  |  | =back | 
| 78 |  |  |  |  |  |  |  | 
| 79 |  |  |  |  |  |  | =head1 OBJECT METHODS | 
| 80 |  |  |  |  |  |  |  | 
| 81 |  |  |  |  |  |  | =over 4 | 
| 82 |  |  |  |  |  |  |  | 
| 83 |  |  |  |  |  |  | =item open ( FILENAME, MODE ) | 
| 84 |  |  |  |  |  |  |  | 
| 85 |  |  |  |  |  |  | C takes two arguments. The first is the name of the file to open | 
| 86 |  |  |  |  |  |  | and the second is the open mode. The mode can be anything acceptable to | 
| 87 |  |  |  |  |  |  | L and by extension anything acceptable to I (that | 
| 88 |  |  |  |  |  |  | basically means POSIX fopen() style mode strings plus an optional number | 
| 89 |  |  |  |  |  |  | to indicate the compression level). | 
| 90 |  |  |  |  |  |  |  | 
| 91 |  |  |  |  |  |  | =item opened | 
| 92 |  |  |  |  |  |  |  | 
| 93 |  |  |  |  |  |  | Returns true if the object currently refers to a opened file. | 
| 94 |  |  |  |  |  |  |  | 
| 95 |  |  |  |  |  |  | =item close | 
| 96 |  |  |  |  |  |  |  | 
| 97 |  |  |  |  |  |  | Close the file associated with the object and disassociate | 
| 98 |  |  |  |  |  |  | the file from the handle. | 
| 99 |  |  |  |  |  |  | Done automatically on destroy. | 
| 100 |  |  |  |  |  |  |  | 
| 101 |  |  |  |  |  |  | =item getc | 
| 102 |  |  |  |  |  |  |  | 
| 103 |  |  |  |  |  |  | Return the next character from the file, or undef if none remain. | 
| 104 |  |  |  |  |  |  |  | 
| 105 |  |  |  |  |  |  | =item getline | 
| 106 |  |  |  |  |  |  |  | 
| 107 |  |  |  |  |  |  | Return the next line from the file, or undef on end of string. | 
| 108 |  |  |  |  |  |  | Can safely be called in an array context. | 
| 109 |  |  |  |  |  |  | Currently ignores $/ ($INPUT_RECORD_SEPARATOR or $RS when L | 
| 110 |  |  |  |  |  |  | is in use) and treats lines as delimited by "\n". | 
| 111 |  |  |  |  |  |  |  | 
| 112 |  |  |  |  |  |  | =item getlines | 
| 113 |  |  |  |  |  |  |  | 
| 114 |  |  |  |  |  |  | Get all remaining lines from the file. | 
| 115 |  |  |  |  |  |  | It will croak() if accidentally called in a scalar context. | 
| 116 |  |  |  |  |  |  |  | 
| 117 |  |  |  |  |  |  | =item print ( ARGS... ) | 
| 118 |  |  |  |  |  |  |  | 
| 119 |  |  |  |  |  |  | Print ARGS to the  file. | 
| 120 |  |  |  |  |  |  |  | 
| 121 |  |  |  |  |  |  | =item read ( BUF, NBYTES, [OFFSET] ) | 
| 122 |  |  |  |  |  |  |  | 
| 123 |  |  |  |  |  |  | Read some bytes from the file. | 
| 124 |  |  |  |  |  |  | Returns the number of bytes actually read, 0 on end-of-file, undef on error. | 
| 125 |  |  |  |  |  |  |  | 
| 126 |  |  |  |  |  |  | =item eof | 
| 127 |  |  |  |  |  |  |  | 
| 128 |  |  |  |  |  |  | Returns true if the handle is currently positioned at end of file? | 
| 129 |  |  |  |  |  |  |  | 
| 130 |  |  |  |  |  |  | =item seek ( OFFSET, WHENCE ) | 
| 131 |  |  |  |  |  |  |  | 
| 132 |  |  |  |  |  |  | Seek to a given position in the stream. | 
| 133 |  |  |  |  |  |  | Not yet supported. | 
| 134 |  |  |  |  |  |  |  | 
| 135 |  |  |  |  |  |  | =item tell | 
| 136 |  |  |  |  |  |  |  | 
| 137 |  |  |  |  |  |  | Return the current position in the stream, as a numeric offset. | 
| 138 |  |  |  |  |  |  | Not yet supported. | 
| 139 |  |  |  |  |  |  |  | 
| 140 |  |  |  |  |  |  | =item setpos ( POS ) | 
| 141 |  |  |  |  |  |  |  | 
| 142 |  |  |  |  |  |  | Set the current position, using the opaque value returned by C. | 
| 143 |  |  |  |  |  |  | Not yet supported. | 
| 144 |  |  |  |  |  |  |  | 
| 145 |  |  |  |  |  |  | =item getpos ( POS ) | 
| 146 |  |  |  |  |  |  |  | 
| 147 |  |  |  |  |  |  | Return the current position in the string, as an opaque object. | 
| 148 |  |  |  |  |  |  | Not yet supported. | 
| 149 |  |  |  |  |  |  |  | 
| 150 |  |  |  |  |  |  | =back | 
| 151 |  |  |  |  |  |  |  | 
| 152 |  |  |  |  |  |  | =head1 USING THE EXTERNAL GZIP | 
| 153 |  |  |  |  |  |  |  | 
| 154 |  |  |  |  |  |  | If the external F is used, the following Cs are used: | 
| 155 |  |  |  |  |  |  |  | 
| 156 |  |  |  |  |  |  | open(FH, "gzip -dc $filename |")  # for read opens | 
| 157 |  |  |  |  |  |  | open(FH, " | gzip > $filename")   # for write opens | 
| 158 |  |  |  |  |  |  |  | 
| 159 |  |  |  |  |  |  | You can modify the 'commands' for example to hardwire | 
| 160 |  |  |  |  |  |  | an absolute path by e.g. | 
| 161 |  |  |  |  |  |  |  | 
| 162 |  |  |  |  |  |  | use IO::Zlib ':gzip_read_open'  => '/some/where/gunzip -c %s |'; | 
| 163 |  |  |  |  |  |  | use IO::Zlib ':gzip_write_open' => '| /some/where/gzip.exe > %s'; | 
| 164 |  |  |  |  |  |  |  | 
| 165 |  |  |  |  |  |  | The C<%s> is expanded to be the filename (C is used, so be | 
| 166 |  |  |  |  |  |  | careful to escape any other C<%> signs).  The 'commands' are checked | 
| 167 |  |  |  |  |  |  | for sanity - they must contain the C<%s>, and the read open must end | 
| 168 |  |  |  |  |  |  | with the pipe sign, and the write open must begin with the pipe sign. | 
| 169 |  |  |  |  |  |  |  | 
| 170 |  |  |  |  |  |  | =head1 CLASS METHODS | 
| 171 |  |  |  |  |  |  |  | 
| 172 |  |  |  |  |  |  | =over 4 | 
| 173 |  |  |  |  |  |  |  | 
| 174 |  |  |  |  |  |  | =item has_Compress_Zlib | 
| 175 |  |  |  |  |  |  |  | 
| 176 |  |  |  |  |  |  | Returns true if C is available.  Note that this does | 
| 177 |  |  |  |  |  |  | not mean that C is being used: see L | 
| 178 |  |  |  |  |  |  | and L. | 
| 179 |  |  |  |  |  |  |  | 
| 180 |  |  |  |  |  |  | =item gzip_external | 
| 181 |  |  |  |  |  |  |  | 
| 182 |  |  |  |  |  |  | Undef if an external F B be used if C is | 
| 183 |  |  |  |  |  |  | not available (see L), true if an external F | 
| 184 |  |  |  |  |  |  | is explicitly used, false if an external F must not be used. | 
| 185 |  |  |  |  |  |  | See L. | 
| 186 |  |  |  |  |  |  |  | 
| 187 |  |  |  |  |  |  | =item gzip_used | 
| 188 |  |  |  |  |  |  |  | 
| 189 |  |  |  |  |  |  | True if an external F is being used, false if not. | 
| 190 |  |  |  |  |  |  |  | 
| 191 |  |  |  |  |  |  | =item gzip_read_open | 
| 192 |  |  |  |  |  |  |  | 
| 193 |  |  |  |  |  |  | Return the 'command' being used for opening a file for reading using an | 
| 194 |  |  |  |  |  |  | external F. | 
| 195 |  |  |  |  |  |  |  | 
| 196 |  |  |  |  |  |  | =item gzip_write_open | 
| 197 |  |  |  |  |  |  |  | 
| 198 |  |  |  |  |  |  | Return the 'command' being used for opening a file for writing using an | 
| 199 |  |  |  |  |  |  | external F. | 
| 200 |  |  |  |  |  |  |  | 
| 201 |  |  |  |  |  |  | =back | 
| 202 |  |  |  |  |  |  |  | 
| 203 |  |  |  |  |  |  | =head1 DIAGNOSTICS | 
| 204 |  |  |  |  |  |  |  | 
| 205 |  |  |  |  |  |  | =over 4 | 
| 206 |  |  |  |  |  |  |  | 
| 207 |  |  |  |  |  |  | =item IO::Zlib::getlines: must be called in list context | 
| 208 |  |  |  |  |  |  |  | 
| 209 |  |  |  |  |  |  | If you want read lines, you must read in list context. | 
| 210 |  |  |  |  |  |  |  | 
| 211 |  |  |  |  |  |  | =item IO::Zlib::gzopen_external: mode '...' is illegal | 
| 212 |  |  |  |  |  |  |  | 
| 213 |  |  |  |  |  |  | Use only modes 'rb' or 'wb' or /wb[1-9]/. | 
| 214 |  |  |  |  |  |  |  | 
| 215 |  |  |  |  |  |  | =item IO::Zlib::import: '...' is illegal | 
| 216 |  |  |  |  |  |  |  | 
| 217 |  |  |  |  |  |  | The known import symbols are the C<:gzip_external>, C<:gzip_read_open>, | 
| 218 |  |  |  |  |  |  | and C<:gzip_write_open>.  Anything else is not recognized. | 
| 219 |  |  |  |  |  |  |  | 
| 220 |  |  |  |  |  |  | =item IO::Zlib::import: ':gzip_external' requires an argument | 
| 221 |  |  |  |  |  |  |  | 
| 222 |  |  |  |  |  |  | The C<:gzip_external> requires one boolean argument. | 
| 223 |  |  |  |  |  |  |  | 
| 224 |  |  |  |  |  |  | =item IO::Zlib::import: 'gzip_read_open' requires an argument | 
| 225 |  |  |  |  |  |  |  | 
| 226 |  |  |  |  |  |  | The C<:gzip_external> requires one string argument. | 
| 227 |  |  |  |  |  |  |  | 
| 228 |  |  |  |  |  |  | =item IO::Zlib::import: 'gzip_read' '...' is illegal | 
| 229 |  |  |  |  |  |  |  | 
| 230 |  |  |  |  |  |  | The C<:gzip_read_open> argument must end with the pipe sign (|) | 
| 231 |  |  |  |  |  |  | and have the C<%s> for the filename.  See L"USING THE EXTERNAL GZIP">. | 
| 232 |  |  |  |  |  |  |  | 
| 233 |  |  |  |  |  |  | =item IO::Zlib::import: 'gzip_write_open' requires an argument | 
| 234 |  |  |  |  |  |  |  | 
| 235 |  |  |  |  |  |  | The C<:gzip_external> requires one string argument. | 
| 236 |  |  |  |  |  |  |  | 
| 237 |  |  |  |  |  |  | =item IO::Zlib::import: 'gzip_write_open' '...' is illegal | 
| 238 |  |  |  |  |  |  |  | 
| 239 |  |  |  |  |  |  | The C<:gzip_write_open> argument must begin with the pipe sign (|) | 
| 240 |  |  |  |  |  |  | and have the C<%s> for the filename.  An output redirect (>) is also | 
| 241 |  |  |  |  |  |  | often a good idea, depending on your operating system shell syntax. | 
| 242 |  |  |  |  |  |  | See L"USING THE EXTERNAL GZIP">. | 
| 243 |  |  |  |  |  |  |  | 
| 244 |  |  |  |  |  |  | =item IO::Zlib::import: no Compress::Zlib and no external gzip | 
| 245 |  |  |  |  |  |  |  | 
| 246 |  |  |  |  |  |  | Given that we failed to load C and that the use of | 
| 247 |  |  |  |  |  |  | an external F was disabled, IO::Zlib has not much chance of working. | 
| 248 |  |  |  |  |  |  |  | 
| 249 |  |  |  |  |  |  | =item IO::Zlib::open: needs a filename | 
| 250 |  |  |  |  |  |  |  | 
| 251 |  |  |  |  |  |  | No filename, no open. | 
| 252 |  |  |  |  |  |  |  | 
| 253 |  |  |  |  |  |  | =item IO::Zlib::READ: NBYTES must be specified | 
| 254 |  |  |  |  |  |  |  | 
| 255 |  |  |  |  |  |  | We must know how much to read. | 
| 256 |  |  |  |  |  |  |  | 
| 257 |  |  |  |  |  |  | =item IO::Zlib::WRITE: too long LENGTH | 
| 258 |  |  |  |  |  |  |  | 
| 259 |  |  |  |  |  |  | The LENGTH must be less than or equal to the buffer size. | 
| 260 |  |  |  |  |  |  |  | 
| 261 |  |  |  |  |  |  | =back | 
| 262 |  |  |  |  |  |  |  | 
| 263 |  |  |  |  |  |  | =head1 SEE ALSO | 
| 264 |  |  |  |  |  |  |  | 
| 265 |  |  |  |  |  |  | L, | 
| 266 |  |  |  |  |  |  | L, | 
| 267 |  |  |  |  |  |  | L, | 
| 268 |  |  |  |  |  |  | L | 
| 269 |  |  |  |  |  |  |  | 
| 270 |  |  |  |  |  |  | =head1 HISTORY | 
| 271 |  |  |  |  |  |  |  | 
| 272 |  |  |  |  |  |  | Created by Tom Hughes EFE. | 
| 273 |  |  |  |  |  |  |  | 
| 274 |  |  |  |  |  |  | Support for external gzip added by Jarkko Hietaniemi EFE. | 
| 275 |  |  |  |  |  |  |  | 
| 276 |  |  |  |  |  |  | =head1 COPYRIGHT | 
| 277 |  |  |  |  |  |  |  | 
| 278 |  |  |  |  |  |  | Copyright (c) 1998-2004 Tom Hughes EFE. | 
| 279 |  |  |  |  |  |  | All rights reserved. This program is free software; you can redistribute | 
| 280 |  |  |  |  |  |  | it and/or modify it under the same terms as Perl itself. | 
| 281 |  |  |  |  |  |  |  | 
| 282 |  |  |  |  |  |  | =cut | 
| 283 |  |  |  |  |  |  |  | 
| 284 |  |  |  |  |  |  | require 5.006; | 
| 285 |  |  |  |  |  |  |  | 
| 286 | 9 |  |  | 9 |  | 4762 | use strict; | 
|  | 9 |  |  |  |  | 54 |  | 
|  | 9 |  |  |  |  | 253 |  | 
| 287 | 9 |  |  | 9 |  | 42 | use warnings; | 
|  | 9 |  |  |  |  | 17 |  | 
|  | 9 |  |  |  |  | 211 |  | 
| 288 |  |  |  |  |  |  |  | 
| 289 | 9 |  |  | 9 |  | 44 | use Carp; | 
|  | 9 |  |  |  |  | 15 |  | 
|  | 9 |  |  |  |  | 775 |  | 
| 290 | 9 |  |  | 9 |  | 54 | use Fcntl qw(SEEK_SET); | 
|  | 9 |  |  |  |  | 18 |  | 
|  | 9 |  |  |  |  | 363 |  | 
| 291 | 9 |  |  | 9 |  | 4234 | use Symbol; | 
|  | 9 |  |  |  |  | 7524 |  | 
|  | 9 |  |  |  |  | 558 |  | 
| 292 | 9 |  |  | 9 |  | 4023 | use Tie::Handle; | 
|  | 9 |  |  |  |  | 16968 |  | 
|  | 9 |  |  |  |  | 842 |  | 
| 293 |  |  |  |  |  |  |  | 
| 294 |  |  |  |  |  |  | our $VERSION = "1.12"; | 
| 295 |  |  |  |  |  |  | our $AUTOLOAD; | 
| 296 |  |  |  |  |  |  | our @ISA = qw(Tie::Handle); | 
| 297 |  |  |  |  |  |  |  | 
| 298 |  |  |  |  |  |  | my $has_Compress_Zlib; | 
| 299 |  |  |  |  |  |  | my $gzip_external; | 
| 300 |  |  |  |  |  |  | my $gzip_used; | 
| 301 |  |  |  |  |  |  | my $gzip_read_open = "gzip -dc %s |"; | 
| 302 |  |  |  |  |  |  | my $gzip_write_open = "| gzip > %s"; | 
| 303 |  |  |  |  |  |  | my $aliased; | 
| 304 |  |  |  |  |  |  |  | 
| 305 |  |  |  |  |  |  | BEGIN { | 
| 306 | 9 |  |  | 9 |  | 27 | eval { require Compress::Zlib }; | 
|  | 9 |  |  |  |  | 5358 |  | 
| 307 | 9 | 50 | 33 |  |  | 603949 | $has_Compress_Zlib = $@ || $Compress::Zlib::VERSION < 2.000 ? 0 : 1; | 
| 308 |  |  |  |  |  |  | } | 
| 309 |  |  |  |  |  |  |  | 
| 310 |  |  |  |  |  |  | sub has_Compress_Zlib | 
| 311 |  |  |  |  |  |  | { | 
| 312 | 0 |  |  | 0 | 1 | 0 | $has_Compress_Zlib; | 
| 313 |  |  |  |  |  |  | } | 
| 314 |  |  |  |  |  |  |  | 
| 315 |  |  |  |  |  |  | sub gzip_external | 
| 316 |  |  |  |  |  |  | { | 
| 317 | 0 |  |  | 0 | 1 | 0 | $gzip_external; | 
| 318 |  |  |  |  |  |  | } | 
| 319 |  |  |  |  |  |  |  | 
| 320 |  |  |  |  |  |  | sub gzip_used | 
| 321 |  |  |  |  |  |  | { | 
| 322 | 0 |  |  | 0 | 1 | 0 | $gzip_used; | 
| 323 |  |  |  |  |  |  | } | 
| 324 |  |  |  |  |  |  |  | 
| 325 |  |  |  |  |  |  | sub gzip_read_open | 
| 326 |  |  |  |  |  |  | { | 
| 327 | 0 |  |  | 0 | 1 | 0 | $gzip_read_open; | 
| 328 |  |  |  |  |  |  | } | 
| 329 |  |  |  |  |  |  |  | 
| 330 |  |  |  |  |  |  | sub gzip_write_open | 
| 331 |  |  |  |  |  |  | { | 
| 332 | 0 |  |  | 0 | 1 | 0 | $gzip_write_open; | 
| 333 |  |  |  |  |  |  | } | 
| 334 |  |  |  |  |  |  |  | 
| 335 |  |  |  |  |  |  | sub can_gunzip | 
| 336 |  |  |  |  |  |  | { | 
| 337 | 0 | 0 |  | 0 | 0 | 0 | $has_Compress_Zlib || $gzip_external; | 
| 338 |  |  |  |  |  |  | } | 
| 339 |  |  |  |  |  |  |  | 
| 340 |  |  |  |  |  |  | sub _import | 
| 341 |  |  |  |  |  |  | { | 
| 342 | 1 |  |  | 1 |  | 2 | my $import = shift; | 
| 343 |  |  |  |  |  |  |  | 
| 344 | 1 |  |  |  |  | 3 | while (@_) | 
| 345 |  |  |  |  |  |  | { | 
| 346 | 1 | 50 |  |  |  | 24 | if ($_[0] eq ':gzip_external') | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
| 347 |  |  |  |  |  |  | { | 
| 348 | 0 |  |  |  |  | 0 | shift; | 
| 349 |  |  |  |  |  |  |  | 
| 350 | 0 | 0 |  |  |  | 0 | if (@_) | 
| 351 |  |  |  |  |  |  | { | 
| 352 | 0 |  |  |  |  | 0 | $gzip_external = shift; | 
| 353 |  |  |  |  |  |  | } | 
| 354 |  |  |  |  |  |  | else | 
| 355 |  |  |  |  |  |  | { | 
| 356 | 0 |  |  |  |  | 0 | croak "$import: ':gzip_external' requires an argument"; | 
| 357 |  |  |  |  |  |  | } | 
| 358 |  |  |  |  |  |  | } | 
| 359 |  |  |  |  |  |  | elsif ($_[0] eq ':gzip_read_open') | 
| 360 |  |  |  |  |  |  | { | 
| 361 | 0 |  |  |  |  | 0 | shift; | 
| 362 |  |  |  |  |  |  |  | 
| 363 | 0 | 0 |  |  |  | 0 | if (@_) | 
| 364 |  |  |  |  |  |  | { | 
| 365 | 0 |  |  |  |  | 0 | $gzip_read_open = shift; | 
| 366 |  |  |  |  |  |  |  | 
| 367 | 0 | 0 |  |  |  | 0 | croak "$import: ':gzip_read_open' '$gzip_read_open' is illegal" | 
| 368 |  |  |  |  |  |  | unless $gzip_read_open =~ /^.+%s.+\|\s*$/; | 
| 369 |  |  |  |  |  |  | } | 
| 370 |  |  |  |  |  |  | else | 
| 371 |  |  |  |  |  |  | { | 
| 372 | 0 |  |  |  |  | 0 | croak "$import: ':gzip_read_open' requires an argument"; | 
| 373 |  |  |  |  |  |  | } | 
| 374 |  |  |  |  |  |  | } | 
| 375 |  |  |  |  |  |  | elsif ($_[0] eq ':gzip_write_open') | 
| 376 |  |  |  |  |  |  | { | 
| 377 | 0 |  |  |  |  | 0 | shift; | 
| 378 |  |  |  |  |  |  |  | 
| 379 | 0 | 0 |  |  |  | 0 | if (@_) | 
| 380 |  |  |  |  |  |  | { | 
| 381 | 0 |  |  |  |  | 0 | $gzip_write_open = shift; | 
| 382 |  |  |  |  |  |  |  | 
| 383 | 0 | 0 |  |  |  | 0 | croak "$import: ':gzip_write_open' '$gzip_read_open' is illegal" | 
| 384 |  |  |  |  |  |  | unless $gzip_write_open =~ /^\s*\|.+%s.*$/; | 
| 385 |  |  |  |  |  |  | } | 
| 386 |  |  |  |  |  |  | else | 
| 387 |  |  |  |  |  |  | { | 
| 388 | 0 |  |  |  |  | 0 | croak "$import: ':gzip_write_open' requires an argument"; | 
| 389 |  |  |  |  |  |  | } | 
| 390 |  |  |  |  |  |  | } | 
| 391 |  |  |  |  |  |  | else | 
| 392 |  |  |  |  |  |  | { | 
| 393 | 1 |  |  |  |  | 9 | last; | 
| 394 |  |  |  |  |  |  | } | 
| 395 |  |  |  |  |  |  | } | 
| 396 |  |  |  |  |  |  |  | 
| 397 | 1 |  |  |  |  | 3 | return @_; | 
| 398 |  |  |  |  |  |  | } | 
| 399 |  |  |  |  |  |  |  | 
| 400 |  |  |  |  |  |  | sub _alias | 
| 401 |  |  |  |  |  |  | { | 
| 402 | 8 |  |  | 8 |  | 17 | my $import = shift; | 
| 403 |  |  |  |  |  |  |  | 
| 404 | 8 | 50 | 33 |  |  | 81 | if ($gzip_external || (!$has_Compress_Zlib && !defined($gzip_external))) | 
|  |  | 50 | 33 |  |  |  |  | 
| 405 |  |  |  |  |  |  | { | 
| 406 | 0 |  |  |  |  | 0 | require IO::Handle; | 
| 407 |  |  |  |  |  |  |  | 
| 408 | 0 |  |  |  |  | 0 | undef *gzopen; | 
| 409 | 0 |  |  |  |  | 0 | *gzopen = \&gzopen_external; | 
| 410 |  |  |  |  |  |  |  | 
| 411 | 0 |  |  |  |  | 0 | *IO::Handle::gzread = \&gzread_external; | 
| 412 | 0 |  |  |  |  | 0 | *IO::Handle::gzwrite = \&gzwrite_external; | 
| 413 | 0 |  |  |  |  | 0 | *IO::Handle::gzreadline = \&gzreadline_external; | 
| 414 | 0 |  |  |  |  | 0 | *IO::Handle::gzeof = \&gzeof_external; | 
| 415 | 0 |  |  |  |  | 0 | *IO::Handle::gzclose = \&gzclose_external; | 
| 416 |  |  |  |  |  |  |  | 
| 417 | 0 |  |  |  |  | 0 | $gzip_used = 1; | 
| 418 |  |  |  |  |  |  | } | 
| 419 |  |  |  |  |  |  | elsif ($has_Compress_Zlib) | 
| 420 |  |  |  |  |  |  | { | 
| 421 | 8 |  |  |  |  | 27 | *gzopen = \&Compress::Zlib::gzopen; | 
| 422 | 8 |  |  |  |  | 76 | *gzread = \&Compress::Zlib::gzread; | 
| 423 | 8 |  |  |  |  | 31 | *gzwrite = \&Compress::Zlib::gzwrite; | 
| 424 | 8 |  |  |  |  | 19 | *gzreadline = \&Compress::Zlib::gzreadline; | 
| 425 | 8 |  |  |  |  | 23 | *gzeof = \&Compress::Zlib::gzeof; | 
| 426 |  |  |  |  |  |  | } | 
| 427 |  |  |  |  |  |  | else | 
| 428 |  |  |  |  |  |  | { | 
| 429 | 0 |  |  |  |  | 0 | croak "$import: no Compress::Zlib and no external gzip"; | 
| 430 |  |  |  |  |  |  | } | 
| 431 |  |  |  |  |  |  |  | 
| 432 | 8 |  |  |  |  | 10034 | $aliased = 1; | 
| 433 |  |  |  |  |  |  | } | 
| 434 |  |  |  |  |  |  |  | 
| 435 |  |  |  |  |  |  | sub import | 
| 436 |  |  |  |  |  |  | { | 
| 437 | 8 |  |  | 8 |  | 85 | my $class = shift; | 
| 438 | 8 |  |  |  |  | 14 | my $import = "IO::Zlib::import"; | 
| 439 |  |  |  |  |  |  |  | 
| 440 | 8 | 100 |  |  |  | 38 | if (@_) | 
| 441 |  |  |  |  |  |  | { | 
| 442 | 1 | 50 |  |  |  | 4 | if (_import($import, @_)) | 
| 443 |  |  |  |  |  |  | { | 
| 444 | 1 |  |  |  |  | 251 | croak "$import: '@_' is illegal"; | 
| 445 |  |  |  |  |  |  | } | 
| 446 |  |  |  |  |  |  | } | 
| 447 |  |  |  |  |  |  |  | 
| 448 | 7 |  |  |  |  | 21 | _alias($import); | 
| 449 |  |  |  |  |  |  | } | 
| 450 |  |  |  |  |  |  |  | 
| 451 |  |  |  |  |  |  | sub TIEHANDLE | 
| 452 |  |  |  |  |  |  | { | 
| 453 | 17 |  |  | 17 |  | 567 | my $class = shift; | 
| 454 | 17 |  |  |  |  | 41 | my @args = @_; | 
| 455 |  |  |  |  |  |  |  | 
| 456 | 17 |  |  |  |  | 40 | my $self = bless {}, $class; | 
| 457 |  |  |  |  |  |  |  | 
| 458 | 17 | 100 |  |  |  | 73 | return @args ? $self->OPEN(@args) : $self; | 
| 459 |  |  |  |  |  |  | } | 
| 460 |  |  |  |  |  |  |  | 
| 461 |  |  |  |  |  |  | sub DESTROY | 
| 462 |  |  |  | 0 |  |  | { | 
| 463 |  |  |  |  |  |  | } | 
| 464 |  |  |  |  |  |  |  | 
| 465 |  |  |  |  |  |  | sub OPEN | 
| 466 |  |  |  |  |  |  | { | 
| 467 | 17 |  |  | 17 |  | 28 | my $self = shift; | 
| 468 | 17 |  |  |  |  | 28 | my $filename = shift; | 
| 469 | 17 |  |  |  |  | 27 | my $mode = shift; | 
| 470 |  |  |  |  |  |  |  | 
| 471 | 17 | 50 |  |  |  | 48 | croak "IO::Zlib::open: needs a filename" unless defined($filename); | 
| 472 |  |  |  |  |  |  |  | 
| 473 | 17 |  |  |  |  | 57 | $self->{'file'} = gzopen($filename,$mode); | 
| 474 |  |  |  |  |  |  |  | 
| 475 | 17 | 100 |  |  |  | 31452 | return defined($self->{'file'}) ? $self : undef; | 
| 476 |  |  |  |  |  |  | } | 
| 477 |  |  |  |  |  |  |  | 
| 478 |  |  |  |  |  |  | sub CLOSE | 
| 479 |  |  |  |  |  |  | { | 
| 480 | 12 |  |  | 12 |  | 20 | my $self = shift; | 
| 481 |  |  |  |  |  |  |  | 
| 482 | 12 | 50 |  |  |  | 39 | return undef unless defined($self->{'file'}); | 
| 483 |  |  |  |  |  |  |  | 
| 484 | 12 |  |  |  |  | 42 | my $status = $self->{'file'}->gzclose(); | 
| 485 |  |  |  |  |  |  |  | 
| 486 | 12 |  |  |  |  | 2352 | delete $self->{'file'}; | 
| 487 |  |  |  |  |  |  |  | 
| 488 | 12 | 50 |  |  |  | 682 | return ($status == 0) ? 1 : undef; | 
| 489 |  |  |  |  |  |  | } | 
| 490 |  |  |  |  |  |  |  | 
| 491 |  |  |  |  |  |  | sub READ | 
| 492 |  |  |  |  |  |  | { | 
| 493 | 11 |  |  | 11 |  | 51 | my $self = shift; | 
| 494 | 11 |  |  |  |  | 35 | my $bufref = \$_[0]; | 
| 495 | 11 |  |  |  |  | 23 | my $nbytes = $_[1]; | 
| 496 | 11 |  | 100 |  |  | 80 | my $offset = $_[2] || 0; | 
| 497 |  |  |  |  |  |  |  | 
| 498 | 11 | 50 |  |  |  | 45 | croak "IO::Zlib::READ: NBYTES must be specified" unless defined($nbytes); | 
| 499 |  |  |  |  |  |  |  | 
| 500 | 11 | 100 |  |  |  | 46 | $$bufref = "" unless defined($$bufref); | 
| 501 |  |  |  |  |  |  |  | 
| 502 | 11 |  |  |  |  | 49 | my $bytesread = $self->{'file'}->gzread(substr($$bufref,$offset),$nbytes); | 
| 503 |  |  |  |  |  |  |  | 
| 504 | 11 | 50 |  |  |  | 3305 | return undef if $bytesread < 0; | 
| 505 |  |  |  |  |  |  |  | 
| 506 | 11 |  |  |  |  | 42 | return $bytesread; | 
| 507 |  |  |  |  |  |  | } | 
| 508 |  |  |  |  |  |  |  | 
| 509 |  |  |  |  |  |  | sub READLINE | 
| 510 |  |  |  |  |  |  | { | 
| 511 | 7 |  |  | 7 |  | 63 | my $self = shift; | 
| 512 |  |  |  |  |  |  |  | 
| 513 | 7 |  |  |  |  | 9 | my $line; | 
| 514 |  |  |  |  |  |  |  | 
| 515 | 7 | 100 |  |  |  | 22 | return () if $self->{'file'}->gzreadline($line) <= 0; | 
| 516 |  |  |  |  |  |  |  | 
| 517 | 6 | 100 |  |  |  | 909 | return $line unless wantarray; | 
| 518 |  |  |  |  |  |  |  | 
| 519 | 1 |  |  |  |  | 7 | my @lines = $line; | 
| 520 |  |  |  |  |  |  |  | 
| 521 | 1 |  |  |  |  | 3 | while ($self->{'file'}->gzreadline($line) > 0) | 
| 522 |  |  |  |  |  |  | { | 
| 523 | 3 |  |  |  |  | 395 | push @lines, $line; | 
| 524 |  |  |  |  |  |  | } | 
| 525 |  |  |  |  |  |  |  | 
| 526 | 1 |  |  |  |  | 177 | return @lines; | 
| 527 |  |  |  |  |  |  | } | 
| 528 |  |  |  |  |  |  |  | 
| 529 |  |  |  |  |  |  | sub WRITE | 
| 530 |  |  |  |  |  |  | { | 
| 531 | 6 |  |  | 6 |  | 354 | my $self = shift; | 
| 532 | 6 |  |  |  |  | 12 | my $buf = shift; | 
| 533 | 6 |  |  |  |  | 9 | my $length = shift; | 
| 534 | 6 |  |  |  |  | 12 | my $offset = shift; | 
| 535 |  |  |  |  |  |  |  | 
| 536 | 6 | 50 |  |  |  | 28 | croak "IO::Zlib::WRITE: too long LENGTH" unless $offset + $length <= length($buf); | 
| 537 |  |  |  |  |  |  |  | 
| 538 | 6 |  |  |  |  | 45 | return $self->{'file'}->gzwrite(substr($buf,$offset,$length)); | 
| 539 |  |  |  |  |  |  | } | 
| 540 |  |  |  |  |  |  |  | 
| 541 |  |  |  |  |  |  | sub EOF | 
| 542 |  |  |  |  |  |  | { | 
| 543 | 12 |  |  | 12 |  | 24 | my $self = shift; | 
| 544 |  |  |  |  |  |  |  | 
| 545 | 12 |  |  |  |  | 44 | return $self->{'file'}->gzeof(); | 
| 546 |  |  |  |  |  |  | } | 
| 547 |  |  |  |  |  |  |  | 
| 548 |  |  |  |  |  |  | sub FILENO | 
| 549 |  |  |  |  |  |  | { | 
| 550 | 0 |  |  | 0 |  | 0 | return undef; | 
| 551 |  |  |  |  |  |  | } | 
| 552 |  |  |  |  |  |  |  | 
| 553 |  |  |  |  |  |  | sub new | 
| 554 |  |  |  |  |  |  | { | 
| 555 | 15 |  |  | 15 | 1 | 5235 | my $class = shift; | 
| 556 | 15 |  |  |  |  | 41 | my @args = @_; | 
| 557 |  |  |  |  |  |  |  | 
| 558 | 15 | 100 |  |  |  | 45 | _alias("new", @_) unless $aliased; # Some call new IO::Zlib directly... | 
| 559 |  |  |  |  |  |  |  | 
| 560 | 15 |  |  |  |  | 84 | my $self = gensym(); | 
| 561 |  |  |  |  |  |  |  | 
| 562 | 15 |  |  |  |  | 228 | tie *{$self}, $class, @args; | 
|  | 15 |  |  |  |  | 94 |  | 
| 563 |  |  |  |  |  |  |  | 
| 564 | 15 | 100 |  |  |  | 27 | return tied(${$self}) ? bless $self, $class : undef; | 
|  | 15 |  |  |  |  | 127 |  | 
| 565 |  |  |  |  |  |  | } | 
| 566 |  |  |  |  |  |  |  | 
| 567 |  |  |  |  |  |  | sub getline | 
| 568 |  |  |  |  |  |  | { | 
| 569 | 5 |  |  | 5 | 1 | 78 | my $self = shift; | 
| 570 |  |  |  |  |  |  |  | 
| 571 | 5 |  |  |  |  | 10 | return scalar tied(*{$self})->READLINE(); | 
|  | 5 |  |  |  |  | 17 |  | 
| 572 |  |  |  |  |  |  | } | 
| 573 |  |  |  |  |  |  |  | 
| 574 |  |  |  |  |  |  | sub getlines | 
| 575 |  |  |  |  |  |  | { | 
| 576 | 2 |  |  | 2 | 1 | 232 | my $self = shift; | 
| 577 |  |  |  |  |  |  |  | 
| 578 | 2 | 100 |  |  |  | 210 | croak "IO::Zlib::getlines: must be called in list context" | 
| 579 |  |  |  |  |  |  | unless wantarray; | 
| 580 |  |  |  |  |  |  |  | 
| 581 | 1 |  |  |  |  | 6 | return tied(*{$self})->READLINE(); | 
|  | 1 |  |  |  |  | 5 |  | 
| 582 |  |  |  |  |  |  | } | 
| 583 |  |  |  |  |  |  |  | 
| 584 |  |  |  |  |  |  | sub opened | 
| 585 |  |  |  |  |  |  | { | 
| 586 | 8 |  |  | 8 | 1 | 633 | my $self = shift; | 
| 587 |  |  |  |  |  |  |  | 
| 588 | 8 |  |  |  |  | 12 | return defined tied(*{$self})->{'file'}; | 
|  | 8 |  |  |  |  | 43 |  | 
| 589 |  |  |  |  |  |  | } | 
| 590 |  |  |  |  |  |  |  | 
| 591 |  |  |  |  |  |  | sub AUTOLOAD | 
| 592 |  |  |  |  |  |  | { | 
| 593 | 39 |  |  | 39 |  | 1464 | my $self = shift; | 
| 594 |  |  |  |  |  |  |  | 
| 595 | 39 |  |  |  |  | 218 | $AUTOLOAD =~ s/.*:://; | 
| 596 | 39 |  |  |  |  | 102 | $AUTOLOAD =~ tr/a-z/A-Z/; | 
| 597 |  |  |  |  |  |  |  | 
| 598 | 39 |  |  |  |  | 57 | return tied(*{$self})->$AUTOLOAD(@_); | 
|  | 39 |  |  |  |  | 155 |  | 
| 599 |  |  |  |  |  |  | } | 
| 600 |  |  |  |  |  |  |  | 
| 601 |  |  |  |  |  |  | sub gzopen_external | 
| 602 |  |  |  |  |  |  | { | 
| 603 | 0 |  |  | 0 | 1 |  | my $filename = shift; | 
| 604 | 0 |  |  |  |  |  | my $mode = shift; | 
| 605 | 0 |  |  |  |  |  | my $fh = IO::Handle->new(); | 
| 606 |  |  |  |  |  |  |  | 
| 607 | 0 | 0 |  |  |  |  | if ($mode =~ /r/) | 
|  |  | 0 |  |  |  |  |  | 
| 608 |  |  |  |  |  |  | { | 
| 609 |  |  |  |  |  |  | # Because someone will try to read ungzipped files | 
| 610 |  |  |  |  |  |  | # with this we peek and verify the signature.  Yes, | 
| 611 |  |  |  |  |  |  | # this means that we open the file twice (if it is | 
| 612 |  |  |  |  |  |  | # gzipped). | 
| 613 |  |  |  |  |  |  | # Plenty of race conditions exist in this code, but | 
| 614 |  |  |  |  |  |  | # the alternative would be to capture the stderr of | 
| 615 |  |  |  |  |  |  | # gzip and parse it, which would be a portability nightmare. | 
| 616 | 0 | 0 | 0 |  |  |  | if (-e $filename && open($fh, $filename)) | 
| 617 |  |  |  |  |  |  | { | 
| 618 | 0 |  |  |  |  |  | binmode $fh; | 
| 619 |  |  |  |  |  |  |  | 
| 620 | 0 |  |  |  |  |  | my $sig; | 
| 621 | 0 |  |  |  |  |  | my $rdb = read($fh, $sig, 2); | 
| 622 |  |  |  |  |  |  |  | 
| 623 | 0 | 0 | 0 |  |  |  | if ($rdb == 2 && $sig eq "\x1F\x8B") | 
| 624 |  |  |  |  |  |  | { | 
| 625 | 0 |  |  |  |  |  | my $ropen = sprintf($gzip_read_open, $filename); | 
| 626 |  |  |  |  |  |  |  | 
| 627 | 0 | 0 |  |  |  |  | if (open($fh, $ropen)) | 
| 628 |  |  |  |  |  |  | { | 
| 629 | 0 |  |  |  |  |  | binmode $fh; | 
| 630 |  |  |  |  |  |  |  | 
| 631 | 0 |  |  |  |  |  | return $fh; | 
| 632 |  |  |  |  |  |  | } | 
| 633 |  |  |  |  |  |  | else | 
| 634 |  |  |  |  |  |  | { | 
| 635 | 0 |  |  |  |  |  | return undef; | 
| 636 |  |  |  |  |  |  | } | 
| 637 |  |  |  |  |  |  | } | 
| 638 |  |  |  |  |  |  |  | 
| 639 | 0 | 0 |  |  |  |  | seek($fh, 0, SEEK_SET) or | 
| 640 |  |  |  |  |  |  | die "IO::Zlib: open('$filename', 'r'): seek: $!"; | 
| 641 |  |  |  |  |  |  |  | 
| 642 | 0 |  |  |  |  |  | return $fh; | 
| 643 |  |  |  |  |  |  | } | 
| 644 |  |  |  |  |  |  | else | 
| 645 |  |  |  |  |  |  | { | 
| 646 | 0 |  |  |  |  |  | return undef; | 
| 647 |  |  |  |  |  |  | } | 
| 648 |  |  |  |  |  |  | } | 
| 649 |  |  |  |  |  |  | elsif ($mode =~ /w/) | 
| 650 |  |  |  |  |  |  | { | 
| 651 | 0 | 0 |  |  |  |  | my $level = $mode =~ /([1-9])/ ? "-$1" : ""; | 
| 652 |  |  |  |  |  |  |  | 
| 653 |  |  |  |  |  |  | # To maximize portability we would need to open | 
| 654 |  |  |  |  |  |  | # two filehandles here, one for "| gzip $level" | 
| 655 |  |  |  |  |  |  | # and another for "> $filename", and then when | 
| 656 |  |  |  |  |  |  | # writing copy bytes from the first to the second. | 
| 657 |  |  |  |  |  |  | # We are using IO::Handle objects for now, however, | 
| 658 |  |  |  |  |  |  | # and they can only contain one stream at a time. | 
| 659 | 0 |  |  |  |  |  | my $wopen = sprintf($gzip_write_open, $filename); | 
| 660 |  |  |  |  |  |  |  | 
| 661 | 0 | 0 |  |  |  |  | if (open($fh, $wopen)) | 
| 662 |  |  |  |  |  |  | { | 
| 663 | 0 |  |  |  |  |  | $fh->autoflush(1); | 
| 664 | 0 |  |  |  |  |  | binmode $fh; | 
| 665 |  |  |  |  |  |  |  | 
| 666 | 0 |  |  |  |  |  | return $fh; | 
| 667 |  |  |  |  |  |  | } | 
| 668 |  |  |  |  |  |  | else | 
| 669 |  |  |  |  |  |  | { | 
| 670 | 0 |  |  |  |  |  | return undef; | 
| 671 |  |  |  |  |  |  | } | 
| 672 |  |  |  |  |  |  | } | 
| 673 |  |  |  |  |  |  | else | 
| 674 |  |  |  |  |  |  | { | 
| 675 | 0 |  |  |  |  |  | croak "IO::Zlib::gzopen_external: mode '$mode' is illegal"; | 
| 676 |  |  |  |  |  |  | } | 
| 677 |  |  |  |  |  |  |  | 
| 678 | 0 |  |  |  |  |  | return undef; | 
| 679 |  |  |  |  |  |  | } | 
| 680 |  |  |  |  |  |  |  | 
| 681 |  |  |  |  |  |  | sub gzread_external | 
| 682 |  |  |  |  |  |  | { | 
| 683 | 0 |  |  | 0 | 0 |  | my $file = shift; | 
| 684 | 0 |  |  |  |  |  | my $bufref = \$_[0]; | 
| 685 | 0 |  | 0 |  |  |  | my $nbytes = $_[1] || 4096; | 
| 686 |  |  |  |  |  |  |  | 
| 687 |  |  |  |  |  |  | # Use read() instead of sysread() because people may | 
| 688 |  |  |  |  |  |  | # mix reads and readlines, and we don't want to mess | 
| 689 |  |  |  |  |  |  | # the stdio buffering.  See also gzreadline_external() | 
| 690 |  |  |  |  |  |  | # and gzwrite_external(). | 
| 691 | 0 |  |  |  |  |  | my $nread = read($file, $$bufref, $nbytes); | 
| 692 |  |  |  |  |  |  |  | 
| 693 | 0 | 0 |  |  |  |  | return defined $nread ? $nread : -1; | 
| 694 |  |  |  |  |  |  | } | 
| 695 |  |  |  |  |  |  |  | 
| 696 |  |  |  |  |  |  | sub gzwrite_external | 
| 697 |  |  |  |  |  |  | { | 
| 698 | 0 |  |  | 0 | 0 |  | my $file = shift; | 
| 699 | 0 |  |  |  |  |  | my $buf = shift; | 
| 700 |  |  |  |  |  |  |  | 
| 701 |  |  |  |  |  |  | # Using syswrite() is okay (cf. gzread_external()) | 
| 702 |  |  |  |  |  |  | # since the bytes leave this process and buffering | 
| 703 |  |  |  |  |  |  | # is therefore not an issue. | 
| 704 | 0 |  |  |  |  |  | my $nwrote = syswrite($file, $buf); | 
| 705 |  |  |  |  |  |  |  | 
| 706 | 0 | 0 |  |  |  |  | return defined $nwrote ? $nwrote : -1; | 
| 707 |  |  |  |  |  |  | } | 
| 708 |  |  |  |  |  |  |  | 
| 709 |  |  |  |  |  |  | sub gzreadline_external | 
| 710 |  |  |  |  |  |  | { | 
| 711 | 0 |  |  | 0 | 0 |  | my $file = shift; | 
| 712 | 0 |  |  |  |  |  | my $bufref = \$_[0]; | 
| 713 |  |  |  |  |  |  |  | 
| 714 |  |  |  |  |  |  | # See the comment in gzread_external(). | 
| 715 | 0 |  |  |  |  |  | $$bufref = readline($file); | 
| 716 |  |  |  |  |  |  |  | 
| 717 | 0 | 0 |  |  |  |  | return defined $$bufref ? length($$bufref) : -1; | 
| 718 |  |  |  |  |  |  | } | 
| 719 |  |  |  |  |  |  |  | 
| 720 |  |  |  |  |  |  | sub gzeof_external | 
| 721 |  |  |  |  |  |  | { | 
| 722 | 0 |  |  | 0 | 0 |  | my $file = shift; | 
| 723 |  |  |  |  |  |  |  | 
| 724 | 0 |  |  |  |  |  | return eof($file); | 
| 725 |  |  |  |  |  |  | } | 
| 726 |  |  |  |  |  |  |  | 
| 727 |  |  |  |  |  |  | sub gzclose_external | 
| 728 |  |  |  |  |  |  | { | 
| 729 | 0 |  |  | 0 | 0 |  | my $file = shift; | 
| 730 |  |  |  |  |  |  |  | 
| 731 | 0 |  |  |  |  |  | close($file); | 
| 732 |  |  |  |  |  |  |  | 
| 733 |  |  |  |  |  |  | # I am not entirely certain why this is needed but it seems | 
| 734 |  |  |  |  |  |  | # the above close() always fails (as if the stream would have | 
| 735 |  |  |  |  |  |  | # been already closed - something to do with using external | 
| 736 |  |  |  |  |  |  | # processes via pipes?) | 
| 737 | 0 |  |  |  |  |  | return 0; | 
| 738 |  |  |  |  |  |  | } | 
| 739 |  |  |  |  |  |  |  | 
| 740 |  |  |  |  |  |  | 1; |