1 /*
2 * compression/DecompressorGZIP.cpp
3 *
4 * Copyright 2009 Peter Barth
5 *
6 * This file is part of Milkytracker.
7 *
8 * Milkytracker is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * Milkytracker is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with Milkytracker. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23 /*
24 * DecompressorGZIP.cpp
25 * milkytracker_universal
26 *
27 * Created by Peter Barth on 22.06.08.
28 *
29 */
30
31 #include "DecompressorGZIP.h"
32 #include "XMFile.h"
33 #include "LittleEndian.h"
34 #include "zlib.h"
35
36 // -- GZIP --------------------------------------------------------------------
DecompressorGZIP(const PPSystemString & fileName)37 DecompressorGZIP::DecompressorGZIP(const PPSystemString& fileName) :
38 DecompressorBase(fileName)
39 {
40 }
41
identify(XMFile & f)42 bool DecompressorGZIP::identify(XMFile& f)
43 {
44 f.seek(0);
45 mp_dword id = f.readDword();
46
47 // GZIP ID
48 return (id == 0x08088B1F);
49 }
50
getDescriptors(Hints hint) const51 const PPSimpleVector<Descriptor>& DecompressorGZIP::getDescriptors(Hints hint) const
52 {
53 descriptors.clear();
54 descriptors.add(new Descriptor("gz", "GZIP Archive"));
55 return descriptors;
56 }
57
decompress(const PPSystemString & outFileName,Hints hint)58 bool DecompressorGZIP::decompress(const PPSystemString& outFileName, Hints hint)
59 {
60 gzFile gz_input_file = NULL;
61 int len = 0;
62 pp_uint8 *buf;
63
64 if ((gz_input_file = gzopen (fileName.getStrBuffer(), "r")) == NULL)
65 return false;
66
67 if ((buf = new pp_uint8[0x10000]) == NULL)
68 return false;
69
70 XMFile fOut(outFileName, true);
71
72 while (true)
73 {
74 len = gzread (gz_input_file, buf, 0x10000);
75
76 if (len < 0)
77 {
78 delete[] buf;
79 return false;
80 }
81
82 if (len == 0) break;
83
84 fOut.write(buf, 1, len);
85 }
86
87 if (gzclose (gz_input_file) != Z_OK)
88 {
89 delete[] buf;
90 return false;
91 }
92
93 delete[] buf;
94
95 return true;
96 }
97
clone()98 DecompressorBase* DecompressorGZIP::clone()
99 {
100 return new DecompressorGZIP(fileName);
101 }
102
103 static Decompressor::RegisterDecompressor<DecompressorGZIP> registerDecompressor;
104