Rockbox Utility: Replace OSDaB Zip with QuaZip.
[kugel-rb.git] / rbutil / rbutilqt / quazip / quazip.cpp
blob3f7314a43389f45b5221aedab7cd4351c694d262
1 /*
2 -- A kind of "standard" GPL license statement --
3 QuaZIP - a Qt/C++ wrapper for the ZIP/UNZIP package
4 Copyright (C) 2005-2007 Sergey A. Tachenov
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2 of the License, or (at your
9 option) any later version.
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
14 Public License for more details.
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 -- A kind of "standard" GPL license statement ends here --
22 See COPYING file for GPL.
24 You are also permitted to use QuaZIP under the terms of LGPL (see
25 COPYING.LGPL). You are free to choose either license, but please note
26 that QuaZIP makes use of Qt, which is not licensed under LGPL. So if
27 you are using Open Source edition of Qt, you therefore MUST use GPL for
28 your code based on QuaZIP, since it would be also based on Qt in this
29 case. If you are Qt commercial license owner, then you are free to use
30 QuaZIP as long as you respect either GPL or LGPL for QuaZIP code.
31 **/
33 #include <QFile>
35 #include "quazip.h"
37 QuaZip::QuaZip():
38 fileNameCodec(QTextCodec::codecForLocale()),
39 commentCodec(QTextCodec::codecForLocale()),
40 mode(mdNotOpen), hasCurrentFile_f(false), zipError(UNZ_OK)
44 QuaZip::QuaZip(const QString& zipName):
45 fileNameCodec(QTextCodec::codecForLocale()),
46 commentCodec(QTextCodec::codecForLocale()),
47 zipName(zipName),
48 mode(mdNotOpen), hasCurrentFile_f(false), zipError(UNZ_OK)
52 QuaZip::~QuaZip()
54 if(isOpen()) close();
57 bool QuaZip::open(Mode mode, zlib_filefunc_def* ioApi)
59 zipError=UNZ_OK;
60 if(isOpen()) {
61 qWarning("QuaZip::open(): ZIP already opened");
62 return false;
64 switch(mode) {
65 case mdUnzip:
66 unzFile_f=unzOpen2(QFile::encodeName(zipName).constData(), ioApi);
67 if(unzFile_f!=NULL) {
68 this->mode=mode;
69 return true;
70 } else {
71 zipError=UNZ_OPENERROR;
72 return false;
74 case mdCreate:
75 case mdAppend:
76 case mdAdd:
77 zipFile_f=zipOpen2(QFile::encodeName(zipName).constData(),
78 mode==mdCreate?APPEND_STATUS_CREATE:
79 mode==mdAppend?APPEND_STATUS_CREATEAFTER:
80 APPEND_STATUS_ADDINZIP,
81 NULL,
82 ioApi);
83 if(zipFile_f!=NULL) {
84 this->mode=mode;
85 return true;
86 } else {
87 zipError=UNZ_OPENERROR;
88 return false;
90 default:
91 qWarning("QuaZip::open(): unknown mode: %d", (int)mode);
92 return false;
93 break;
97 void QuaZip::close()
99 zipError=UNZ_OK;
100 switch(mode) {
101 case mdNotOpen:
102 qWarning("QuaZip::close(): ZIP is not open");
103 return;
104 case mdUnzip:
105 zipError=unzClose(unzFile_f);
106 break;
107 case mdCreate:
108 case mdAppend:
109 case mdAdd:
110 zipError=zipClose(zipFile_f, commentCodec->fromUnicode(comment).constData());
111 break;
112 default:
113 qWarning("QuaZip::close(): unknown mode: %d", (int)mode);
114 return;
116 if(zipError==UNZ_OK) mode=mdNotOpen;
119 void QuaZip::setZipName(const QString& zipName)
121 if(isOpen()) {
122 qWarning("QuaZip::setZipName(): ZIP is already open!");
123 return;
125 this->zipName=zipName;
128 int QuaZip::getEntriesCount()const
130 QuaZip *fakeThis=(QuaZip*)this; // non-const
131 fakeThis->zipError=UNZ_OK;
132 if(mode!=mdUnzip) {
133 qWarning("QuaZip::getEntriesCount(): ZIP is not open in mdUnzip mode");
134 return -1;
136 unz_global_info globalInfo;
137 if((fakeThis->zipError=unzGetGlobalInfo(unzFile_f, &globalInfo))!=UNZ_OK)
138 return zipError;
139 return (int)globalInfo.number_entry;
142 QString QuaZip::getComment()const
144 QuaZip *fakeThis=(QuaZip*)this; // non-const
145 fakeThis->zipError=UNZ_OK;
146 if(mode!=mdUnzip) {
147 qWarning("QuaZip::getComment(): ZIP is not open in mdUnzip mode");
148 return QString();
150 unz_global_info globalInfo;
151 QByteArray comment;
152 if((fakeThis->zipError=unzGetGlobalInfo(unzFile_f, &globalInfo))!=UNZ_OK)
153 return QString();
154 comment.resize(globalInfo.size_comment);
155 if((fakeThis->zipError=unzGetGlobalComment(unzFile_f, comment.data(), comment.size()))!=UNZ_OK)
156 return QString();
157 return commentCodec->toUnicode(comment);
160 bool QuaZip::setCurrentFile(const QString& fileName, CaseSensitivity cs)
162 zipError=UNZ_OK;
163 if(mode!=mdUnzip) {
164 qWarning("QuaZip::setCurrentFile(): ZIP is not open in mdUnzip mode");
165 return false;
167 if(fileName.isNull()) {
168 hasCurrentFile_f=false;
169 return true;
171 // Unicode-aware reimplementation of the unzLocateFile function
172 if(unzFile_f==NULL) {
173 zipError=UNZ_PARAMERROR;
174 return false;
176 if(fileName.length()>MAX_FILE_NAME_LENGTH) {
177 zipError=UNZ_PARAMERROR;
178 return false;
180 bool sens;
181 if(cs==csDefault) {
182 #ifdef Q_WS_WIN
183 sens=false;
184 #else
185 sens=true;
186 #endif
187 } else sens=cs==csSensitive;
188 QString lower, current;
189 if(!sens) lower=fileName.toLower();
190 hasCurrentFile_f=false;
191 for(bool more=goToFirstFile(); more; more=goToNextFile()) {
192 current=getCurrentFileName();
193 if(current.isNull()) return false;
194 if(sens) {
195 if(current==fileName) break;
196 } else {
197 if(current.toLower()==lower) break;
200 return hasCurrentFile_f;
203 bool QuaZip::goToFirstFile()
205 zipError=UNZ_OK;
206 if(mode!=mdUnzip) {
207 qWarning("QuaZip::goToFirstFile(): ZIP is not open in mdUnzip mode");
208 return false;
210 zipError=unzGoToFirstFile(unzFile_f);
211 hasCurrentFile_f=zipError==UNZ_OK;
212 return hasCurrentFile_f;
215 bool QuaZip::goToNextFile()
217 zipError=UNZ_OK;
218 if(mode!=mdUnzip) {
219 qWarning("QuaZip::goToFirstFile(): ZIP is not open in mdUnzip mode");
220 return false;
222 zipError=unzGoToNextFile(unzFile_f);
223 hasCurrentFile_f=zipError==UNZ_OK;
224 if(zipError==UNZ_END_OF_LIST_OF_FILE) zipError=UNZ_OK;
225 return hasCurrentFile_f;
228 bool QuaZip::getCurrentFileInfo(QuaZipFileInfo *info)const
230 QuaZip *fakeThis=(QuaZip*)this; // non-const
231 fakeThis->zipError=UNZ_OK;
232 if(mode!=mdUnzip) {
233 qWarning("QuaZip::getCurrentFileInfo(): ZIP is not open in mdUnzip mode");
234 return false;
236 unz_file_info info_z;
237 QByteArray fileName;
238 QByteArray extra;
239 QByteArray comment;
240 if(info==NULL) return false;
241 if(!isOpen()||!hasCurrentFile()) return false;
242 if((fakeThis->zipError=unzGetCurrentFileInfo(unzFile_f, &info_z, NULL, 0, NULL, 0, NULL, 0))!=UNZ_OK)
243 return false;
244 fileName.resize(info_z.size_filename);
245 extra.resize(info_z.size_file_extra);
246 comment.resize(info_z.size_file_comment);
247 if((fakeThis->zipError=unzGetCurrentFileInfo(unzFile_f, NULL,
248 fileName.data(), fileName.size(),
249 extra.data(), extra.size(),
250 comment.data(), comment.size()))!=UNZ_OK)
251 return false;
252 info->versionCreated=info_z.version;
253 info->versionNeeded=info_z.version_needed;
254 info->flags=info_z.flag;
255 info->method=info_z.compression_method;
256 info->crc=info_z.crc;
257 info->compressedSize=info_z.compressed_size;
258 info->uncompressedSize=info_z.uncompressed_size;
259 info->diskNumberStart=info_z.disk_num_start;
260 info->internalAttr=info_z.internal_fa;
261 info->externalAttr=info_z.external_fa;
262 info->name=fileNameCodec->toUnicode(fileName);
263 info->comment=commentCodec->toUnicode(comment);
264 info->extra=extra;
265 info->dateTime=QDateTime(
266 QDate(info_z.tmu_date.tm_year, info_z.tmu_date.tm_mon+1, info_z.tmu_date.tm_mday),
267 QTime(info_z.tmu_date.tm_hour, info_z.tmu_date.tm_min, info_z.tmu_date.tm_sec));
268 return true;
271 QString QuaZip::getCurrentFileName()const
273 QuaZip *fakeThis=(QuaZip*)this; // non-const
274 fakeThis->zipError=UNZ_OK;
275 if(mode!=mdUnzip) {
276 qWarning("QuaZip::getCurrentFileName(): ZIP is not open in mdUnzip mode");
277 return QString();
279 if(!isOpen()||!hasCurrentFile()) return QString();
280 QByteArray fileName(MAX_FILE_NAME_LENGTH, 0);
281 if((fakeThis->zipError=unzGetCurrentFileInfo(unzFile_f, NULL, fileName.data(), fileName.size(),
282 NULL, 0, NULL, 0))!=UNZ_OK)
283 return QString();
284 return fileNameCodec->toUnicode(fileName.constData());