| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package IO::Compress::Gzip ; | 
| 2 |  |  |  |  |  |  |  | 
| 3 |  |  |  |  |  |  | require 5.006 ; | 
| 4 |  |  |  |  |  |  |  | 
| 5 | 24 |  |  | 24 |  | 56713 | use strict ; | 
|  | 24 |  |  |  |  | 130 |  | 
|  | 24 |  |  |  |  | 743 |  | 
| 6 | 24 |  |  | 24 |  | 139 | use warnings; | 
|  | 24 |  |  |  |  | 45 |  | 
|  | 24 |  |  |  |  | 661 |  | 
| 7 | 24 |  |  | 24 |  | 6418 | use bytes; | 
|  | 24 |  |  |  |  | 176 |  | 
|  | 24 |  |  |  |  | 149 |  | 
| 8 |  |  |  |  |  |  |  | 
| 9 |  |  |  |  |  |  | require Exporter ; | 
| 10 |  |  |  |  |  |  |  | 
| 11 | 24 |  |  | 24 |  | 12990 | use IO::Compress::RawDeflate 2.205 () ; | 
|  | 24 |  |  |  |  | 530 |  | 
|  | 24 |  |  |  |  | 915 |  | 
| 12 | 24 |  |  | 24 |  | 151 | use IO::Compress::Adapter::Deflate 2.205 ; | 
|  | 24 |  |  |  |  | 312 |  | 
|  | 24 |  |  |  |  | 4579 |  | 
| 13 |  |  |  |  |  |  |  | 
| 14 | 24 |  |  | 24 |  | 171 | use IO::Compress::Base::Common  2.205 qw(:Status ); | 
|  | 24 |  |  |  |  | 321 |  | 
|  | 24 |  |  |  |  | 2583 |  | 
| 15 | 24 |  |  | 24 |  | 5830 | use IO::Compress::Gzip::Constants 2.205 ; | 
|  | 24 |  |  |  |  | 450 |  | 
|  | 24 |  |  |  |  | 4854 |  | 
| 16 | 24 |  |  | 24 |  | 6069 | use IO::Compress::Zlib::Extra 2.205 ; | 
|  | 24 |  |  |  |  | 484 |  | 
|  | 24 |  |  |  |  | 1708 |  | 
| 17 |  |  |  |  |  |  |  | 
| 18 |  |  |  |  |  |  | BEGIN | 
| 19 |  |  |  |  |  |  | { | 
| 20 | 24 | 50 |  | 24 |  | 151 | if (defined &utf8::downgrade ) | 
| 21 | 24 |  |  |  |  | 19521 | { *noUTF8 = \&utf8::downgrade } | 
| 22 |  |  |  |  |  |  | else | 
| 23 | 0 |  |  |  |  | 0 | { *noUTF8 = sub {} } | 
| 24 |  |  |  |  |  |  | } | 
| 25 |  |  |  |  |  |  |  | 
| 26 |  |  |  |  |  |  | our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, %DEFLATE_CONSTANTS, $GzipError); | 
| 27 |  |  |  |  |  |  |  | 
| 28 |  |  |  |  |  |  | $VERSION = '2.205'; | 
| 29 |  |  |  |  |  |  | $GzipError = '' ; | 
| 30 |  |  |  |  |  |  |  | 
| 31 |  |  |  |  |  |  | @ISA    = qw(IO::Compress::RawDeflate Exporter); | 
| 32 |  |  |  |  |  |  | @EXPORT_OK = qw( $GzipError gzip ) ; | 
| 33 |  |  |  |  |  |  | %EXPORT_TAGS = %IO::Compress::RawDeflate::DEFLATE_CONSTANTS ; | 
| 34 |  |  |  |  |  |  |  | 
| 35 |  |  |  |  |  |  | push @{ $EXPORT_TAGS{all} }, @EXPORT_OK ; | 
| 36 |  |  |  |  |  |  | Exporter::export_ok_tags('all'); | 
| 37 |  |  |  |  |  |  |  | 
| 38 |  |  |  |  |  |  | sub new | 
| 39 |  |  |  |  |  |  | { | 
| 40 | 314 |  |  | 314 | 1 | 257899 | my $class = shift ; | 
| 41 |  |  |  |  |  |  |  | 
| 42 | 314 |  |  |  |  | 1126 | my $obj = IO::Compress::Base::Common::createSelfTiedObject($class, \$GzipError); | 
| 43 |  |  |  |  |  |  |  | 
| 44 | 314 |  |  |  |  | 1255 | $obj->_create(undef, @_); | 
| 45 |  |  |  |  |  |  | } | 
| 46 |  |  |  |  |  |  |  | 
| 47 |  |  |  |  |  |  |  | 
| 48 |  |  |  |  |  |  | sub gzip | 
| 49 |  |  |  |  |  |  | { | 
| 50 | 161 |  |  | 161 | 1 | 9147543 | my $obj = IO::Compress::Base::Common::createSelfTiedObject(undef, \$GzipError); | 
| 51 | 161 |  |  |  |  | 646 | return $obj->_def(@_); | 
| 52 |  |  |  |  |  |  | } | 
| 53 |  |  |  |  |  |  |  | 
| 54 |  |  |  |  |  |  | #sub newHeader | 
| 55 |  |  |  |  |  |  | #{ | 
| 56 |  |  |  |  |  |  | #    my $self = shift ; | 
| 57 |  |  |  |  |  |  | #    #return GZIP_MINIMUM_HEADER ; | 
| 58 |  |  |  |  |  |  | #    return $self->mkHeader(*$self->{Got}); | 
| 59 |  |  |  |  |  |  | #} | 
| 60 |  |  |  |  |  |  |  | 
| 61 |  |  |  |  |  |  | sub getExtraParams | 
| 62 |  |  |  |  |  |  | { | 
| 63 | 474 |  |  | 474 | 0 | 811 | my $self = shift ; | 
| 64 |  |  |  |  |  |  |  | 
| 65 |  |  |  |  |  |  | return ( | 
| 66 |  |  |  |  |  |  | # zlib behaviour | 
| 67 | 474 |  |  |  |  | 1486 | $self->getZlibParams(), | 
| 68 |  |  |  |  |  |  |  | 
| 69 |  |  |  |  |  |  | # Gzip header fields | 
| 70 |  |  |  |  |  |  | 'minimal'   => [IO::Compress::Base::Common::Parse_boolean,   0], | 
| 71 |  |  |  |  |  |  | 'comment'   => [IO::Compress::Base::Common::Parse_any,       undef], | 
| 72 |  |  |  |  |  |  | 'name'      => [IO::Compress::Base::Common::Parse_any,       undef], | 
| 73 |  |  |  |  |  |  | 'time'      => [IO::Compress::Base::Common::Parse_any,       undef], | 
| 74 |  |  |  |  |  |  | 'textflag'  => [IO::Compress::Base::Common::Parse_boolean,   0], | 
| 75 |  |  |  |  |  |  | 'headercrc' => [IO::Compress::Base::Common::Parse_boolean,   0], | 
| 76 |  |  |  |  |  |  | 'os_code'   => [IO::Compress::Base::Common::Parse_unsigned,  $Compress::Raw::Zlib::gzip_os_code], | 
| 77 |  |  |  |  |  |  | 'extrafield'=> [IO::Compress::Base::Common::Parse_any,       undef], | 
| 78 |  |  |  |  |  |  | 'extraflags'=> [IO::Compress::Base::Common::Parse_any,       undef], | 
| 79 |  |  |  |  |  |  |  | 
| 80 |  |  |  |  |  |  | ); | 
| 81 |  |  |  |  |  |  | } | 
| 82 |  |  |  |  |  |  |  | 
| 83 |  |  |  |  |  |  |  | 
| 84 |  |  |  |  |  |  | sub ckParams | 
| 85 |  |  |  |  |  |  | { | 
| 86 | 470 |  |  | 470 | 0 | 799 | my $self = shift ; | 
| 87 | 470 |  |  |  |  | 685 | my $got = shift ; | 
| 88 |  |  |  |  |  |  |  | 
| 89 |  |  |  |  |  |  | # gzip always needs crc32 | 
| 90 | 470 |  |  |  |  | 1266 | $got->setValue('crc32' => 1); | 
| 91 |  |  |  |  |  |  |  | 
| 92 | 470 | 100 |  |  |  | 955 | return 1 | 
| 93 |  |  |  |  |  |  | if $got->getValue('merge') ; | 
| 94 |  |  |  |  |  |  |  | 
| 95 | 443 |  |  |  |  | 983 | my $strict = $got->getValue('strict') ; | 
| 96 |  |  |  |  |  |  |  | 
| 97 |  |  |  |  |  |  |  | 
| 98 |  |  |  |  |  |  | { | 
| 99 | 443 | 100 |  |  |  | 719 | if (! $got->parsed('time') ) { | 
|  | 443 |  |  |  |  | 968 |  | 
| 100 |  |  |  |  |  |  | # Modification time defaults to now. | 
| 101 | 377 |  |  |  |  | 1012 | $got->setValue(time => time) ; | 
| 102 |  |  |  |  |  |  | } | 
| 103 |  |  |  |  |  |  |  | 
| 104 |  |  |  |  |  |  | # Check that the Name & Comment don't have embedded NULLs | 
| 105 |  |  |  |  |  |  | # Also check that they only contain ISO 8859-1 chars. | 
| 106 | 443 | 100 | 100 |  |  | 1057 | if ($got->parsed('name') && defined $got->getValue('name')) { | 
| 107 | 80 |  |  |  |  | 185 | my $name = $got->getValue('name'); | 
| 108 |  |  |  |  |  |  |  | 
| 109 | 80 | 100 | 100 |  |  | 385 | return $self->saveErrorString(undef, "Null Character found in Name", | 
| 110 |  |  |  |  |  |  | Z_DATA_ERROR) | 
| 111 |  |  |  |  |  |  | if $strict && $name =~ /\x00/ ; | 
| 112 |  |  |  |  |  |  |  | 
| 113 | 78 | 100 | 100 |  |  | 520 | return $self->saveErrorString(undef, "Non ISO 8859-1 Character found in Name", | 
| 114 |  |  |  |  |  |  | Z_DATA_ERROR) | 
| 115 |  |  |  |  |  |  | if $strict && $name =~ /$GZIP_FNAME_INVALID_CHAR_RE/o ; | 
| 116 |  |  |  |  |  |  | } | 
| 117 |  |  |  |  |  |  |  | 
| 118 | 440 | 100 | 100 |  |  | 1073 | if ($got->parsed('comment') && defined $got->getValue('comment')) { | 
| 119 | 38 |  |  |  |  | 84 | my $comment = $got->getValue('comment'); | 
| 120 |  |  |  |  |  |  |  | 
| 121 | 38 | 100 | 100 |  |  | 199 | return $self->saveErrorString(undef, "Null Character found in Comment", | 
| 122 |  |  |  |  |  |  | Z_DATA_ERROR) | 
| 123 |  |  |  |  |  |  | if $strict && $comment =~ /\x00/ ; | 
| 124 |  |  |  |  |  |  |  | 
| 125 | 36 | 100 | 100 |  |  | 260 | return $self->saveErrorString(undef, "Non ISO 8859-1 Character found in Comment", | 
| 126 |  |  |  |  |  |  | Z_DATA_ERROR) | 
| 127 |  |  |  |  |  |  | if $strict && $comment =~ /$GZIP_FCOMMENT_INVALID_CHAR_RE/o; | 
| 128 |  |  |  |  |  |  | } | 
| 129 |  |  |  |  |  |  |  | 
| 130 | 437 | 100 |  |  |  | 1001 | if ($got->parsed('os_code') ) { | 
| 131 | 6 |  |  |  |  | 16 | my $value = $got->getValue('os_code'); | 
| 132 |  |  |  |  |  |  |  | 
| 133 | 6 | 100 | 66 |  |  | 37 | return $self->saveErrorString(undef, "OS_Code must be between 0 and 255, got '$value'") | 
| 134 |  |  |  |  |  |  | if $value < 0 || $value > 255 ; | 
| 135 |  |  |  |  |  |  |  | 
| 136 |  |  |  |  |  |  | } | 
| 137 |  |  |  |  |  |  |  | 
| 138 |  |  |  |  |  |  | # gzip only supports Deflate at present | 
| 139 | 436 |  |  |  |  | 1343 | $got->setValue('method' => Z_DEFLATED) ; | 
| 140 |  |  |  |  |  |  |  | 
| 141 | 436 | 100 |  |  |  | 1040 | if ( ! $got->parsed('extraflags')) { | 
| 142 | 435 | 100 |  |  |  | 932 | $got->setValue('extraflags' => 2) | 
| 143 |  |  |  |  |  |  | if $got->getValue('level') == Z_BEST_COMPRESSION ; | 
| 144 | 435 | 100 |  |  |  | 2623 | $got->setValue('extraflags' => 4) | 
| 145 |  |  |  |  |  |  | if $got->getValue('level') == Z_BEST_SPEED ; | 
| 146 |  |  |  |  |  |  | } | 
| 147 |  |  |  |  |  |  |  | 
| 148 | 436 |  |  |  |  | 2222 | my $data = $got->getValue('extrafield') ; | 
| 149 | 436 | 100 |  |  |  | 1009 | if (defined $data) { | 
| 150 | 82 |  |  |  |  | 269 | my $bad = IO::Compress::Zlib::Extra::parseExtraField($data, $strict, 1) ; | 
| 151 | 82 | 100 |  |  |  | 216 | return $self->saveErrorString(undef, "Error with ExtraField Parameter: $bad", Z_DATA_ERROR) | 
| 152 |  |  |  |  |  |  | if $bad ; | 
| 153 |  |  |  |  |  |  |  | 
| 154 | 62 |  |  |  |  | 163 | $got->setValue('extrafield' => $data) ; | 
| 155 |  |  |  |  |  |  | } | 
| 156 |  |  |  |  |  |  | } | 
| 157 |  |  |  |  |  |  |  | 
| 158 | 416 |  |  |  |  | 1209 | return 1; | 
| 159 |  |  |  |  |  |  | } | 
| 160 |  |  |  |  |  |  |  | 
| 161 |  |  |  |  |  |  | sub mkTrailer | 
| 162 |  |  |  |  |  |  | { | 
| 163 | 438 |  |  | 438 | 0 | 770 | my $self = shift ; | 
| 164 |  |  |  |  |  |  | return pack("V V", *$self->{Compress}->crc32(), | 
| 165 | 438 |  |  |  |  | 1704 | *$self->{UnCompSize}->get32bit()); | 
| 166 |  |  |  |  |  |  | } | 
| 167 |  |  |  |  |  |  |  | 
| 168 |  |  |  |  |  |  | sub getInverseClass | 
| 169 |  |  |  |  |  |  | { | 
| 170 | 24 |  |  | 24 |  | 217 | no warnings 'once'; | 
|  | 24 |  |  |  |  | 144 |  | 
|  | 24 |  |  |  |  | 14173 |  | 
| 171 | 23 |  |  | 23 | 0 | 64 | return ('IO::Uncompress::Gunzip', | 
| 172 |  |  |  |  |  |  | \$IO::Uncompress::Gunzip::GunzipError); | 
| 173 |  |  |  |  |  |  | } | 
| 174 |  |  |  |  |  |  |  | 
| 175 |  |  |  |  |  |  | sub getFileInfo | 
| 176 |  |  |  |  |  |  | { | 
| 177 | 110 |  |  | 110 | 0 | 195 | my $self = shift ; | 
| 178 | 110 |  |  |  |  | 152 | my $params = shift; | 
| 179 | 110 |  |  |  |  | 178 | my $filename = shift ; | 
| 180 |  |  |  |  |  |  |  | 
| 181 | 110 | 100 |  |  |  | 265 | return if IO::Compress::Base::Common::isaScalar($filename); | 
| 182 |  |  |  |  |  |  |  | 
| 183 | 66 |  |  |  |  | 1029 | my $defaultTime = (stat($filename))[9] ; | 
| 184 |  |  |  |  |  |  |  | 
| 185 | 66 | 100 |  |  |  | 373 | $params->setValue('name' => $filename) | 
| 186 |  |  |  |  |  |  | if ! $params->parsed('name') ; | 
| 187 |  |  |  |  |  |  |  | 
| 188 | 66 | 100 |  |  |  | 182 | $params->setValue('time' => $defaultTime) | 
| 189 |  |  |  |  |  |  | if ! $params->parsed('time') ; | 
| 190 |  |  |  |  |  |  | } | 
| 191 |  |  |  |  |  |  |  | 
| 192 |  |  |  |  |  |  |  | 
| 193 |  |  |  |  |  |  | sub mkHeader | 
| 194 |  |  |  |  |  |  | { | 
| 195 | 418 |  |  | 418 | 0 | 685 | my $self = shift ; | 
| 196 | 418 |  |  |  |  | 635 | my $param = shift ; | 
| 197 |  |  |  |  |  |  |  | 
| 198 |  |  |  |  |  |  | # short-circuit if a minimal header is requested. | 
| 199 | 418 | 100 |  |  |  | 1085 | return GZIP_MINIMUM_HEADER if $param->getValue('minimal') ; | 
| 200 |  |  |  |  |  |  |  | 
| 201 |  |  |  |  |  |  | # METHOD | 
| 202 | 383 |  |  |  |  | 1110 | my $method = $param->valueOrDefault('method', GZIP_CM_DEFLATED) ; | 
| 203 |  |  |  |  |  |  |  | 
| 204 |  |  |  |  |  |  | # FLAGS | 
| 205 | 383 |  |  |  |  | 661 | my $flags       = GZIP_FLG_DEFAULT ; | 
| 206 | 383 | 100 |  |  |  | 794 | $flags |= GZIP_FLG_FTEXT    if $param->getValue('textflag') ; | 
| 207 | 383 | 100 |  |  |  | 877 | $flags |= GZIP_FLG_FHCRC    if $param->getValue('headercrc') ; | 
| 208 | 383 | 100 |  |  |  | 932 | $flags |= GZIP_FLG_FEXTRA   if $param->wantValue('extrafield') ; | 
| 209 | 383 | 100 |  |  |  | 952 | $flags |= GZIP_FLG_FNAME    if $param->wantValue('name') ; | 
| 210 | 383 | 100 |  |  |  | 932 | $flags |= GZIP_FLG_FCOMMENT if $param->wantValue('comment') ; | 
| 211 |  |  |  |  |  |  |  | 
| 212 |  |  |  |  |  |  | # MTIME | 
| 213 | 383 |  |  |  |  | 887 | my $time = $param->valueOrDefault('time', GZIP_MTIME_DEFAULT) ; | 
| 214 |  |  |  |  |  |  |  | 
| 215 |  |  |  |  |  |  | # EXTRA FLAGS | 
| 216 | 383 |  |  |  |  | 908 | my $extra_flags = $param->valueOrDefault('extraflags', GZIP_XFL_DEFAULT); | 
| 217 |  |  |  |  |  |  |  | 
| 218 |  |  |  |  |  |  | # OS CODE | 
| 219 | 383 |  |  |  |  | 884 | my $os_code = $param->valueOrDefault('os_code', GZIP_OS_DEFAULT) ; | 
| 220 |  |  |  |  |  |  |  | 
| 221 |  |  |  |  |  |  |  | 
| 222 | 383 |  |  |  |  | 1872 | my $out = pack("C4 V C C", | 
| 223 |  |  |  |  |  |  | GZIP_ID1,   # ID1 | 
| 224 |  |  |  |  |  |  | GZIP_ID2,   # ID2 | 
| 225 |  |  |  |  |  |  | $method,    # Compression Method | 
| 226 |  |  |  |  |  |  | $flags,     # Flags | 
| 227 |  |  |  |  |  |  | $time,      # Modification Time | 
| 228 |  |  |  |  |  |  | $extra_flags, # Extra Flags | 
| 229 |  |  |  |  |  |  | $os_code,   # Operating System Code | 
| 230 |  |  |  |  |  |  | ) ; | 
| 231 |  |  |  |  |  |  |  | 
| 232 |  |  |  |  |  |  | # EXTRA | 
| 233 | 383 | 100 |  |  |  | 1034 | if ($flags & GZIP_FLG_FEXTRA) { | 
| 234 | 62 |  |  |  |  | 160 | my $extra = $param->getValue('extrafield') ; | 
| 235 | 62 |  |  |  |  | 561 | $out .= pack("v", length $extra) . $extra ; | 
| 236 |  |  |  |  |  |  | } | 
| 237 |  |  |  |  |  |  |  | 
| 238 |  |  |  |  |  |  | # NAME | 
| 239 | 383 | 100 |  |  |  | 845 | if ($flags & GZIP_FLG_FNAME) { | 
| 240 | 86 |  |  |  |  | 199 | my $name .= $param->getValue('name') ; | 
| 241 | 86 |  |  |  |  | 260 | $name =~ s/\x00.*$//; | 
| 242 | 86 |  |  |  |  | 171 | $out .= $name ; | 
| 243 |  |  |  |  |  |  | # Terminate the filename with NULL unless it already is | 
| 244 | 86 | 50 | 66 |  |  | 470 | $out .= GZIP_NULL_BYTE | 
| 245 |  |  |  |  |  |  | if !length $name or | 
| 246 |  |  |  |  |  |  | substr($name, 1, -1) ne GZIP_NULL_BYTE ; | 
| 247 |  |  |  |  |  |  | } | 
| 248 |  |  |  |  |  |  |  | 
| 249 |  |  |  |  |  |  | # COMMENT | 
| 250 | 383 | 100 |  |  |  | 855 | if ($flags & GZIP_FLG_FCOMMENT) { | 
| 251 | 53 |  |  |  |  | 137 | my $comment .= $param->getValue('comment') ; | 
| 252 | 53 |  |  |  |  | 154 | $comment =~ s/\x00.*$//; | 
| 253 | 53 |  |  |  |  | 92 | $out .= $comment ; | 
| 254 |  |  |  |  |  |  | # Terminate the comment with NULL unless it already is | 
| 255 | 53 | 50 | 66 |  |  | 304 | $out .= GZIP_NULL_BYTE | 
| 256 |  |  |  |  |  |  | if ! length $comment or | 
| 257 |  |  |  |  |  |  | substr($comment, 1, -1) ne GZIP_NULL_BYTE; | 
| 258 |  |  |  |  |  |  | } | 
| 259 |  |  |  |  |  |  |  | 
| 260 |  |  |  |  |  |  | # HEADER CRC | 
| 261 | 383 | 100 |  |  |  | 961 | $out .= pack("v", Compress::Raw::Zlib::crc32($out) & 0x00FF ) | 
| 262 |  |  |  |  |  |  | if $param->getValue('headercrc') ; | 
| 263 |  |  |  |  |  |  |  | 
| 264 | 383 |  |  |  |  | 1220 | noUTF8($out); | 
| 265 |  |  |  |  |  |  |  | 
| 266 | 383 |  |  |  |  | 1244 | return $out ; | 
| 267 |  |  |  |  |  |  | } | 
| 268 |  |  |  |  |  |  |  | 
| 269 |  |  |  |  |  |  | sub mkFinalTrailer | 
| 270 |  |  |  |  |  |  | { | 
| 271 | 411 |  |  | 411 | 0 | 957 | return ''; | 
| 272 |  |  |  |  |  |  | } | 
| 273 |  |  |  |  |  |  |  | 
| 274 |  |  |  |  |  |  | 1; | 
| 275 |  |  |  |  |  |  |  | 
| 276 |  |  |  |  |  |  | __END__ |