File Coverage

blib/lib/IO/Uncompress/UnLzop.pm
Criterion Covered Total %
statement 16 18 88.8
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 22 24 91.6


line stmt bran cond sub pod time code
1             package IO::Uncompress::UnLzop ;
2              
3 1     1   2392 use strict ;
  1         1  
  1         21  
4 1     1   3 use warnings;
  1         2  
  1         16  
5 1     1   2 use bytes;
  1         1  
  1         8  
6              
7 1     1   26 use IO::Compress::Base::Common 2.073 qw(:Status createSelfTiedObject);
  1         12  
  1         96  
8              
9 1     1   4 use IO::Uncompress::Base 2.073 ;
  1         11  
  1         60  
10 1     1   31 use IO::Uncompress::Adapter::LZO 2.073 ;
  0            
  0            
11             use Compress::LZO qw(crc32 adler32);
12             use IO::Compress::Lzop::Constants 2.073 ;
13              
14              
15             require Exporter ;
16             our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $UnLzopError);
17              
18             $VERSION = '2.073';
19             $UnLzopError = '';
20              
21             @ISA = qw( IO::Uncompress::Base Exporter );
22             @EXPORT_OK = qw( $UnLzopError unlzop ) ;
23             #%EXPORT_TAGS = %IO::Uncompress::Base::EXPORT_TAGS ;
24             push @{ $EXPORT_TAGS{all} }, @EXPORT_OK ;
25             #Exporter::export_ok_tags('all');
26              
27              
28             sub new
29             {
30             my $class = shift ;
31             my $obj = createSelfTiedObject($class, \$UnLzopError);
32              
33             $obj->_create(undef, 0, @_);
34             }
35              
36             sub unlzop
37             {
38             my $obj = createSelfTiedObject(undef, \$UnLzopError);
39             return $obj->_inf(@_);
40             }
41              
42             sub getExtraParams
43             {
44             return ();
45             }
46              
47             sub ckParams
48             {
49             my $self = shift ;
50             my $got = shift ;
51              
52             return 1;
53             }
54              
55             sub mkUncomp
56             {
57             my $self = shift ;
58             my $got = shift ;
59              
60             my $magic = $self->ckMagic()
61             or return 0;
62              
63             *$self->{Info} = $self->readHeader($magic)
64             or return undef ;
65              
66             my ($obj, $errstr, $errno) = IO::Uncompress::Adapter::LZO::mkUncompObject();
67              
68             return $self->saveErrorString(undef, $errstr, $errno)
69             if ! defined $obj;
70              
71             *$self->{Uncomp} = $obj;
72            
73             return 1;
74             }
75              
76              
77             sub ckMagic
78             {
79             my $self = shift;
80              
81             my $magic ;
82             $self->smartReadExact(\$magic, 9);
83              
84             *$self->{HeaderPending} = $magic ;
85            
86             return $self->HeaderError("Header size is " .
87             9 . " bytes")
88             if length $magic != 9;
89              
90             return $self->HeaderError("Bad Magic.")
91             if ! isLzopMagic($magic) ;
92            
93            
94             *$self->{Type} = 'lzop';
95             return $magic;
96             }
97              
98             sub readHeader
99             {
100             my $self = shift;
101             my $magic = shift ;
102              
103             my $keep ;
104             my $buffer;
105              
106             $self->smartReadExact(\$buffer, 25 )
107             or return $self->HeaderError("Minimum header size is " .
108             38 . " bytes") ;
109             $keep .= $buffer;
110             my $version = unpack 'n', substr($buffer, 0, 2);
111             my $lib_ver = unpack 'n', substr($buffer, 2, 2);
112             my $xtr_ver = unpack 'n', substr($buffer, 4, 2);
113             my $method = unpack 'C', substr($buffer, 6, 1);
114              
115             my $level = unpack 'C', substr($buffer, 7, 1);
116             my $flags = unpack 'N', substr($buffer, 8, 4);
117              
118             #my $filter = unpack 'N', substr($buffer, 8, 1);
119             my $mode = unpack 'N', substr($buffer, 12, 4);
120             my $time = unpack 'N', substr($buffer, 16, 4);
121             my $gmoff = unpack 'N', substr($buffer, 20, 4);
122             my $flen = unpack 'C', substr($buffer, 24, 1);
123              
124             my $filename ;
125             if ($flen) {
126             $self->smartReadExact(\$filename, $flen)
127             or return $self->HeaderError("xxx");
128             $keep .= $filename ;
129             }
130              
131              
132             $self->smartReadExact(\$buffer, 4)
133             or return $self->HeaderError("xxx");
134             my $crcGot = unpack 'N', $buffer;
135              
136             if (*$self->{Strict} ) {
137             my $crc ;
138             if ($flags & F_H_CRC32)
139             { $crc = crc32($keep) }
140             else
141             { $crc = adler32($keep) }
142              
143             return $self->HeaderError("CRC Error")
144             if $crcGot != $crc;
145             }
146              
147             $keep .= $buffer ;
148              
149             if ($flags & F_H_EXTRA_FIELD) {
150             $self->smartReadExact(\$buffer, 4)
151             or return $self->HeaderError("xxx");
152             my $len = unpack 'N', $buffer ; # Extra Length
153             my $extra = '';
154             $self->smartReadExact(\$extra, $len)
155             or return $self->HeaderError("xxx");
156             $self->smartReadExact(\$buffer, 4)
157             or return $self->HeaderError("xxx");
158             }
159              
160             *$self->{LzopData}{Flags} = $flags;
161              
162             $keep = $magic . $keep ;
163              
164             return {
165             'Type' => 'lzop',
166             'FingerprintLength' => 9,
167             'HeaderLength' => length $keep,
168             'TrailerLength' => 0,
169             'Header' => $keep,
170             };
171            
172             }
173              
174             sub chkTrailer
175             {
176             return STATUS_OK;
177             }
178              
179             sub readBlock
180             {
181             my $self = shift ;
182             my $buff = shift ;
183             my $size = shift ;
184              
185             my $tmp;
186              
187             # uncompressed size
188             $self->smartReadExact(\$tmp, 4)
189             or return $self->saveErrorString(STATUS_ERROR, "Error Reading Data");
190            
191             my $uncSize = unpack("N", $tmp);
192             $_[0] = $uncSize;
193              
194             if ($uncSize == 0) {
195             return STATUS_ENDSTREAM;
196             }
197              
198             return $self->saveErrorString(STATUS_ERROR, "Split file not supported")
199             if $uncSize == 0xFFFFFFFF ;
200              
201             return $self->saveErrorString(STATUS_ERROR, "Corrupt - $uncSize >" . MAX_BLOCK_SIZE )
202             if $uncSize > MAX_BLOCK_SIZE ;
203              
204             # compressed size
205             $self->smartReadExact(\$tmp, 4)
206             or return $self->saveErrorString(STATUS_ERROR, "Error Reading Data");
207            
208             my $compSize = unpack("N", $tmp);
209              
210             return $self->saveErrorString(STATUS_ERROR, "File corrupt compressed size > uncompressed size")
211             if $compSize > $uncSize ;
212              
213             return $self->saveErrorString(STATUS_ERROR, "File corrupt uncompressed size > " . BLOCK_SIZE)
214             if $uncSize > BLOCK_SIZE ;
215              
216             my $uncCRC ;
217             my $compCRC ;
218             if (*$self->{LzopData}{Flags} & FLAG_CRC_UNCOMP) {
219             # CRC
220             $self->smartReadExact(\$tmp, 4)
221             or return $self->saveErrorString(STATUS_ERROR, "Error Reading Data");
222            
223             $uncCRC = unpack("N", $tmp);
224             }
225              
226             if (*$self->{LzopData}{Flags} & FLAG_CRC_COMP) {
227             # CRC
228             if ($compSize != $uncSize) {
229             $self->smartReadExact(\$tmp, 4)
230             or return $self->saveErrorString(STATUS_ERROR, "Error Reading Data");
231            
232             $compCRC = unpack("N", $tmp);
233             }
234             else {
235             $compCRC = $uncCRC ;
236             }
237             }
238              
239             *$self->{LzopData}{compSize} = $compSize;
240             *$self->{LzopData}{uncSize} = $uncSize;
241             *$self->{LzopData}{compCRC} = $compCRC;
242             *$self->{LzopData}{uncCRC} = $uncCRC;
243              
244              
245             # data
246             $self->smartReadExact($buff, $compSize)
247             or return $self->saveErrorString(STATUS_ERROR, "Error Reading Data");
248              
249             if (*$self->{Strict} && *$self->{LzopData}{Flags} & FLAG_CRC_COMP) {
250             my $crc ;
251             $crc = crc32($$buff) if *$self->{LzopData}{Flags} & F_CRC32_C ;
252             $crc = adler32($$buff) if *$self->{LzopData}{Flags} & F_ADLER32_C ;
253             return $self->saveErrorString(STATUS_ERROR, "CRC error")
254             if $compCRC != $crc;
255             }
256              
257             return STATUS_OK;
258             }
259              
260              
261             sub postBlockChk
262             {
263             my $self = shift ;
264             my $buffer = shift ;
265             my $offset = shift ;
266              
267             if (*$self->{Strict} && *$self->{LzopData}{Flags} & FLAG_CRC_UNCOMP
268             && *$self->{LzopData}{compSize} != *$self->{LzopData}{uncSize} ) {
269              
270             my $crc ;
271              
272             my $buf = $buffer;
273              
274             if ($offset) {
275             my $x = substr($$buffer, $offset);
276             $buf = \$x;
277             }
278              
279             $crc = crc32($$buffer)
280             if *$self->{LzopData}{Flags} & F_CRC32_D ;
281              
282             $crc = adler32($$buffer)
283             if *$self->{LzopData}{Flags} & F_ADLER32_D ;
284            
285             return $self->saveErrorString(STATUS_ERROR, "CRC error")
286             if *$self->{LzopData}{uncCRC} != $crc;
287             }
288              
289             return STATUS_OK;
290             }
291              
292              
293              
294              
295             sub isLzopMagic
296             {
297             my $buffer = shift ;
298             return $buffer eq SIGNATURE ;
299             }
300              
301             1 ;
302              
303             __END__