File Coverage

inc/IO/Compress/Gzip.pm
Criterion Covered Total %
statement 75 105 71.4
branch 21 62 33.8
condition 2 27 7.4
subroutine 16 18 88.8
pod 2 9 22.2
total 116 221 52.4


line stmt bran cond sub pod time code
1             #line 1
2             package IO::Compress::Gzip ;
3              
4             require 5.006 ;
5 1     1   3231  
  1         3  
  1         40  
6 1     1   5 use strict ;
  1         10  
  1         32  
7 1     1   1178 use warnings;
  1         13  
  1         5  
8             use bytes;
9              
10             require Exporter ;
11 1     1   766416  
  1         49896  
  1         28  
12 1     1   9 use IO::Compress::RawDeflate 2.058 () ;
  1         22  
  1         176  
13             use IO::Compress::Adapter::Deflate 2.058 ;
14 1     1   4  
  1         12  
  1         99  
15 1     1   1330 use IO::Compress::Base::Common 2.058 qw(:Status );
  1         1877  
  1         280  
16 1     1   1323 use IO::Compress::Gzip::Constants 2.058 ;
  1         1957  
  1         71  
17             use IO::Compress::Zlib::Extra 2.058 ;
18              
19             BEGIN
20 1 50   1   7 {
21 1         1602 if (defined &utf8::downgrade )
22             { *noUTF8 = \&utf8::downgrade }
23 0         0 else
  0         0  
24             { *noUTF8 = sub {} }
25             }
26              
27             our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, %DEFLATE_CONSTANTS, $GzipError);
28              
29             $VERSION = '2.058';
30             $GzipError = '' ;
31              
32             @ISA = qw(Exporter IO::Compress::RawDeflate);
33             @EXPORT_OK = qw( $GzipError gzip ) ;
34             %EXPORT_TAGS = %IO::Compress::RawDeflate::DEFLATE_CONSTANTS ;
35              
36             push @{ $EXPORT_TAGS{all} }, @EXPORT_OK ;
37             Exporter::export_ok_tags('all');
38              
39             sub new
40 0     0 1 0 {
41             my $class = shift ;
42 0         0  
43             my $obj = IO::Compress::Base::Common::createSelfTiedObject($class, \$GzipError);
44 0         0  
45             $obj->_create(undef, @_);
46             }
47              
48              
49             sub gzip
50 2     2 1 1860 {
51 2         247 my $obj = IO::Compress::Base::Common::createSelfTiedObject(undef, \$GzipError);
52             return $obj->_def(@_);
53             }
54              
55             #sub newHeader
56             #{
57             # my $self = shift ;
58             # #return GZIP_MINIMUM_HEADER ;
59             # return $self->mkHeader(*$self->{Got});
60             #}
61              
62             sub getExtraParams
63 2     2 0 494 {
64             my $self = shift ;
65              
66             return (
67 2         38 # zlib behaviour
68             $self->getZlibParams(),
69            
70             # Gzip header fields
71             'minimal' => [IO::Compress::Base::Common::Parse_boolean, 0],
72             'comment' => [IO::Compress::Base::Common::Parse_any, undef],
73             'name' => [IO::Compress::Base::Common::Parse_any, undef],
74             'time' => [IO::Compress::Base::Common::Parse_any, undef],
75             'textflag' => [IO::Compress::Base::Common::Parse_boolean, 0],
76             'headercrc' => [IO::Compress::Base::Common::Parse_boolean, 0],
77             'os_code' => [IO::Compress::Base::Common::Parse_unsigned, $Compress::Raw::Zlib::gzip_os_code],
78             'extrafield'=> [IO::Compress::Base::Common::Parse_any, undef],
79             'extraflags'=> [IO::Compress::Base::Common::Parse_any, undef],
80              
81             );
82             }
83              
84              
85             sub ckParams
86 2     2 0 259 {
87 2         5 my $self = shift ;
88             my $got = shift ;
89              
90 2         14 # gzip always needs crc32
91             $got->setValue('crc32' => 1);
92 2 50       20  
93             return 1
94             if $got->getValue('merge') ;
95 2         15  
96             my $strict = $got->getValue('strict') ;
97              
98              
99 2 50       14 {
  2         8  
100             if (! $got->parsed('time') ) {
101 2         16 # Modification time defaults to now.
102             $got->setValue(time => time) ;
103             }
104              
105             # Check that the Name & Comment don't have embedded NULLs
106 2 50 33     16 # Also check that they only contain ISO 8859-1 chars.
107 0         0 if ($got->parsed('name') && defined $got->getValue('name')) {
108             my $name = $got->getValue('name');
109 0 0 0     0
110             return $self->saveErrorString(undef, "Null Character found in Name",
111             Z_DATA_ERROR)
112             if $strict && $name =~ /\x00/ ;
113 0 0 0     0  
114             return $self->saveErrorString(undef, "Non ISO 8859-1 Character found in Name",
115             Z_DATA_ERROR)
116             if $strict && $name =~ /$GZIP_FNAME_INVALID_CHAR_RE/o ;
117             }
118 2 50 33     16  
119 0         0 if ($got->parsed('comment') && defined $got->getValue('comment')) {
120             my $comment = $got->getValue('comment');
121 0 0 0     0  
122             return $self->saveErrorString(undef, "Null Character found in Comment",
123             Z_DATA_ERROR)
124             if $strict && $comment =~ /\x00/ ;
125 0 0 0     0  
126             return $self->saveErrorString(undef, "Non ISO 8859-1 Character found in Comment",
127             Z_DATA_ERROR)
128             if $strict && $comment =~ /$GZIP_FCOMMENT_INVALID_CHAR_RE/o;
129             }
130 2 50       17  
131 0         0 if ($got->parsed('os_code') ) {
132             my $value = $got->getValue('os_code');
133 0 0 0     0  
134             return $self->saveErrorString(undef, "OS_Code must be between 0 and 255, got '$value'")
135             if $value < 0 || $value > 255 ;
136            
137             }
138              
139 2         38 # gzip only supports Deflate at present
140             $got->setValue('method' => Z_DEFLATED) ;
141 2 50       29  
142 2 50       14 if ( ! $got->parsed('extraflags')) {
143             $got->setValue('extraflags' => 2)
144 2 50       106 if $got->getValue('level') == Z_BEST_COMPRESSION ;
145             $got->setValue('extraflags' => 4)
146             if $got->getValue('level') == Z_BEST_SPEED ;
147             }
148 2         41  
149 2 50       13 my $data = $got->getValue('extrafield') ;
150 0         0 if (defined $data) {
151 0 0       0 my $bad = IO::Compress::Zlib::Extra::parseExtraField($data, $strict, 1) ;
152             return $self->saveErrorString(undef, "Error with ExtraField Parameter: $bad", Z_DATA_ERROR)
153             if $bad ;
154 0         0  
155             $got->setValue('extrafield' => $data) ;
156             }
157             }
158 2         6  
159             return 1;
160             }
161              
162             sub mkTrailer
163 2     2 0 585 {
164 2         18 my $self = shift ;
165             return pack("V V", *$self->{Compress}->crc32(),
166             *$self->{UnCompSize}->get32bit());
167             }
168              
169             sub getInverseClass
170 0     0 0 0 {
171             return ('IO::Uncompress::Gunzip',
172             \$IO::Uncompress::Gunzip::GunzipError);
173             }
174              
175             sub getFileInfo
176 2     2 0 491 {
177 2         4 my $self = shift ;
178 2         4 my $params = shift;
179             my $filename = shift ;
180 2 50       7  
181             return if IO::Compress::Base::Common::isaScalar($filename);
182 0         0  
183             my $defaultTime = (stat($filename))[9] ;
184 0 0       0  
185             $params->setValue('name' => $filename)
186             if ! $params->parsed('name') ;
187 0 0       0  
188             $params->setValue('time' => $defaultTime)
189             if ! $params->parsed('time') ;
190             }
191              
192              
193             sub mkHeader
194 2     2 0 2077 {
195 2         4 my $self = shift ;
196             my $param = shift ;
197              
198 2 50       8 # stort-circuit if a minimal header is requested.
199             return GZIP_MINIMUM_HEADER if $param->getValue('minimal') ;
200              
201 2         18 # METHOD
202             my $method = $param->valueOrDefault('method', GZIP_CM_DEFLATED) ;
203              
204 2         24 # FLAGS
205 2 50       9 my $flags = GZIP_FLG_DEFAULT ;
206 2 50       13 $flags |= GZIP_FLG_FTEXT if $param->getValue('textflag') ;
207 2 50       16 $flags |= GZIP_FLG_FHCRC if $param->getValue('headercrc') ;
208 2 50       13 $flags |= GZIP_FLG_FEXTRA if $param->wantValue('extrafield') ;
209 2 50       14 $flags |= GZIP_FLG_FNAME if $param->wantValue('name') ;
210             $flags |= GZIP_FLG_FCOMMENT if $param->wantValue('comment') ;
211            
212 2         26 # MTIME
213             my $time = $param->valueOrDefault('time', GZIP_MTIME_DEFAULT) ;
214              
215 2         27 # EXTRA FLAGS
216             my $extra_flags = $param->valueOrDefault('extraflags', GZIP_XFL_DEFAULT);
217              
218 2         23 # OS CODE
219             my $os_code = $param->valueOrDefault('os_code', GZIP_OS_DEFAULT) ;
220              
221 2         33  
222             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 2 50       7 # EXTRA
233 0         0 if ($flags & GZIP_FLG_FEXTRA) {
234 0         0 my $extra = $param->getValue('extrafield') ;
235             $out .= pack("v", length $extra) . $extra ;
236             }
237              
238 2 50       7 # NAME
239 0         0 if ($flags & GZIP_FLG_FNAME) {
240 0         0 my $name .= $param->getValue('name') ;
241 0         0 $name =~ s/\x00.*$//;
242             $out .= $name ;
243 0 0 0     0 # Terminate the filename with NULL unless it already is
244             $out .= GZIP_NULL_BYTE
245             if !length $name or
246             substr($name, 1, -1) ne GZIP_NULL_BYTE ;
247             }
248              
249 2 50       8 # COMMENT
250 0         0 if ($flags & GZIP_FLG_FCOMMENT) {
251 0         0 my $comment .= $param->getValue('comment') ;
252 0         0 $comment =~ s/\x00.*$//;
253             $out .= $comment ;
254 0 0 0     0 # Terminate the comment with NULL unless it already is
255             $out .= GZIP_NULL_BYTE
256             if ! length $comment or
257             substr($comment, 1, -1) ne GZIP_NULL_BYTE;
258             }
259              
260 2 50       7 # HEADER CRC
261             $out .= pack("v", Compress::Raw::Zlib::crc32($out) & 0x00FF ) if $param->getValue('headercrc') ;
262 2         14  
263             noUTF8($out);
264 2         9  
265             return $out ;
266             }
267              
268             sub mkFinalTrailer
269 2     2 0 81 {
270             return '';
271             }
272              
273             1;
274              
275             __END__