diff options
Diffstat (limited to 'rbutil/rbutilqt/quazip/quazipfile.cpp')
-rw-r--r-- | rbutil/rbutilqt/quazip/quazipfile.cpp | 385 |
1 files changed, 255 insertions, 130 deletions
diff --git a/rbutil/rbutilqt/quazip/quazipfile.cpp b/rbutil/rbutilqt/quazip/quazipfile.cpp index 0399d1dbd0..8d56417698 100644 --- a/rbutil/rbutilqt/quazip/quazipfile.cpp +++ b/rbutil/rbutilqt/quazip/quazipfile.cpp | |||
@@ -1,91 +1,165 @@ | |||
1 | /* | 1 | /* |
2 | -- A kind of "standard" GPL license statement -- | 2 | Copyright (C) 2005-2014 Sergey A. Tachenov |
3 | QuaZIP - a Qt/C++ wrapper for the ZIP/UNZIP package | 3 | |
4 | Copyright (C) 2005-2007 Sergey A. Tachenov | 4 | This file is part of QuaZIP. |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | 6 | QuaZIP is free software: you can redistribute it and/or modify |
7 | under the terms of the GNU General Public License as published by the | 7 | it under the terms of the GNU Lesser General Public License as published by |
8 | Free Software Foundation; either version 2 of the License, or (at your | 8 | the Free Software Foundation, either version 2.1 of the License, or |
9 | option) any later version. | 9 | (at your option) any later version. |
10 | 10 | ||
11 | This program is distributed in the hope that it will be useful, but | 11 | QuaZIP is distributed in the hope that it will be useful, |
12 | WITHOUT ANY WARRANTY; without even the implied warranty of | 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General | 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | Public License for more details. | 14 | GNU Lesser General Public License for more details. |
15 | 15 | ||
16 | You should have received a copy of the GNU General Public License along | 16 | You should have received a copy of the GNU Lesser General Public License |
17 | with this program; if not, write to the Free Software Foundation, Inc., | 17 | along with QuaZIP. If not, see <http://www.gnu.org/licenses/>. |
18 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | |
19 | 19 | See COPYING file for the full LGPL text. | |
20 | -- A kind of "standard" GPL license statement ends here -- | 20 | |
21 | 21 | Original ZIP package is copyrighted by Gilles Vollant, see | |
22 | See COPYING file for GPL. | 22 | quazip/(un)zip.h files for details, basically it's zlib license. |
23 | |||
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 | **/ | 23 | **/ |
32 | 24 | ||
33 | #include "quazipfile.h" | 25 | #include "quazipfile.h" |
34 | 26 | ||
35 | using namespace std; | 27 | using namespace std; |
36 | 28 | ||
29 | /// The implementation class for QuaZip. | ||
30 | /** | ||
31 | \internal | ||
32 | |||
33 | This class contains all the private stuff for the QuaZipFile class, thus | ||
34 | allowing to preserve binary compatibility between releases, the | ||
35 | technique known as the Pimpl (private implementation) idiom. | ||
36 | */ | ||
37 | class QuaZipFilePrivate { | ||
38 | friend class QuaZipFile; | ||
39 | private: | ||
40 | /// The pointer to the associated QuaZipFile instance. | ||
41 | QuaZipFile *q; | ||
42 | /// The QuaZip object to work with. | ||
43 | QuaZip *zip; | ||
44 | /// The file name. | ||
45 | QString fileName; | ||
46 | /// Case sensitivity mode. | ||
47 | QuaZip::CaseSensitivity caseSensitivity; | ||
48 | /// Whether this file is opened in the raw mode. | ||
49 | bool raw; | ||
50 | /// Write position to keep track of. | ||
51 | /** | ||
52 | QIODevice::pos() is broken for non-seekable devices, so we need | ||
53 | our own position. | ||
54 | */ | ||
55 | qint64 writePos; | ||
56 | /// Uncompressed size to write along with a raw file. | ||
57 | quint64 uncompressedSize; | ||
58 | /// CRC to write along with a raw file. | ||
59 | quint32 crc; | ||
60 | /// Whether \ref zip points to an internal QuaZip instance. | ||
61 | /** | ||
62 | This is true if the archive was opened by name, rather than by | ||
63 | supplying an existing QuaZip instance. | ||
64 | */ | ||
65 | bool internal; | ||
66 | /// The last error. | ||
67 | int zipError; | ||
68 | /// Resets \ref zipError. | ||
69 | inline void resetZipError() const {setZipError(UNZ_OK);} | ||
70 | /// Sets the zip error. | ||
71 | /** | ||
72 | This function is marked as const although it changes one field. | ||
73 | This allows to call it from const functions that don't change | ||
74 | anything by themselves. | ||
75 | */ | ||
76 | void setZipError(int zipError) const; | ||
77 | /// The constructor for the corresponding QuaZipFile constructor. | ||
78 | inline QuaZipFilePrivate(QuaZipFile *q): | ||
79 | q(q), zip(NULL), internal(true), zipError(UNZ_OK) {} | ||
80 | /// The constructor for the corresponding QuaZipFile constructor. | ||
81 | inline QuaZipFilePrivate(QuaZipFile *q, const QString &zipName): | ||
82 | q(q), internal(true), zipError(UNZ_OK) | ||
83 | { | ||
84 | zip=new QuaZip(zipName); | ||
85 | } | ||
86 | /// The constructor for the corresponding QuaZipFile constructor. | ||
87 | inline QuaZipFilePrivate(QuaZipFile *q, const QString &zipName, const QString &fileName, | ||
88 | QuaZip::CaseSensitivity cs): | ||
89 | q(q), internal(true), zipError(UNZ_OK) | ||
90 | { | ||
91 | zip=new QuaZip(zipName); | ||
92 | this->fileName=fileName; | ||
93 | if (this->fileName.startsWith('/')) | ||
94 | this->fileName = this->fileName.mid(1); | ||
95 | this->caseSensitivity=cs; | ||
96 | } | ||
97 | /// The constructor for the QuaZipFile constructor accepting a file name. | ||
98 | inline QuaZipFilePrivate(QuaZipFile *q, QuaZip *zip): | ||
99 | q(q), zip(zip), internal(false), zipError(UNZ_OK) {} | ||
100 | /// The destructor. | ||
101 | inline ~QuaZipFilePrivate() | ||
102 | { | ||
103 | if (internal) | ||
104 | delete zip; | ||
105 | } | ||
106 | }; | ||
107 | |||
37 | QuaZipFile::QuaZipFile(): | 108 | QuaZipFile::QuaZipFile(): |
38 | zip(NULL), internal(true), zipError(UNZ_OK) | 109 | p(new QuaZipFilePrivate(this)) |
39 | { | 110 | { |
40 | } | 111 | } |
41 | 112 | ||
42 | QuaZipFile::QuaZipFile(QObject *parent): | 113 | QuaZipFile::QuaZipFile(QObject *parent): |
43 | QIODevice(parent), zip(NULL), internal(true), zipError(UNZ_OK) | 114 | QIODevice(parent), |
115 | p(new QuaZipFilePrivate(this)) | ||
44 | { | 116 | { |
45 | } | 117 | } |
46 | 118 | ||
47 | QuaZipFile::QuaZipFile(const QString& zipName, QObject *parent): | 119 | QuaZipFile::QuaZipFile(const QString& zipName, QObject *parent): |
48 | QIODevice(parent), internal(true), zipError(UNZ_OK) | 120 | QIODevice(parent), |
121 | p(new QuaZipFilePrivate(this, zipName)) | ||
49 | { | 122 | { |
50 | zip=new QuaZip(zipName); | ||
51 | Q_CHECK_PTR(zip); | ||
52 | } | 123 | } |
53 | 124 | ||
54 | QuaZipFile::QuaZipFile(const QString& zipName, const QString& fileName, | 125 | QuaZipFile::QuaZipFile(const QString& zipName, const QString& fileName, |
55 | QuaZip::CaseSensitivity cs, QObject *parent): | 126 | QuaZip::CaseSensitivity cs, QObject *parent): |
56 | QIODevice(parent), internal(true), zipError(UNZ_OK) | 127 | QIODevice(parent), |
128 | p(new QuaZipFilePrivate(this, zipName, fileName, cs)) | ||
57 | { | 129 | { |
58 | zip=new QuaZip(zipName); | ||
59 | Q_CHECK_PTR(zip); | ||
60 | this->fileName=fileName; | ||
61 | this->caseSensitivity=cs; | ||
62 | } | 130 | } |
63 | 131 | ||
64 | QuaZipFile::QuaZipFile(QuaZip *zip, QObject *parent): | 132 | QuaZipFile::QuaZipFile(QuaZip *zip, QObject *parent): |
65 | QIODevice(parent), | 133 | QIODevice(parent), |
66 | zip(zip), internal(false), | 134 | p(new QuaZipFilePrivate(this, zip)) |
67 | zipError(UNZ_OK) | ||
68 | { | 135 | { |
69 | } | 136 | } |
70 | 137 | ||
71 | QuaZipFile::~QuaZipFile() | 138 | QuaZipFile::~QuaZipFile() |
72 | { | 139 | { |
73 | if(isOpen()) close(); | 140 | if (isOpen()) |
74 | if(internal) delete zip; | 141 | close(); |
142 | delete p; | ||
143 | } | ||
144 | |||
145 | QString QuaZipFile::getZipName() const | ||
146 | { | ||
147 | return p->zip==NULL ? QString() : p->zip->getZipName(); | ||
75 | } | 148 | } |
76 | 149 | ||
77 | QString QuaZipFile::getZipName()const | 150 | QuaZip *QuaZipFile::getZip() const |
78 | { | 151 | { |
79 | return zip==NULL?QString():zip->getZipName(); | 152 | return p->internal ? NULL : p->zip; |
80 | } | 153 | } |
81 | 154 | ||
82 | QString QuaZipFile::getActualFileName()const | 155 | QString QuaZipFile::getActualFileName()const |
83 | { | 156 | { |
84 | setZipError(UNZ_OK); | 157 | p->setZipError(UNZ_OK); |
85 | if(zip==NULL||(openMode()&WriteOnly)) return QString(); | 158 | if (p->zip == NULL || (openMode() & WriteOnly)) |
86 | QString name=zip->getCurrentFileName(); | 159 | return QString(); |
160 | QString name=p->zip->getCurrentFileName(); | ||
87 | if(name.isNull()) | 161 | if(name.isNull()) |
88 | setZipError(zip->getZipError()); | 162 | p->setZipError(p->zip->getZipError()); |
89 | return name; | 163 | return name; |
90 | } | 164 | } |
91 | 165 | ||
@@ -95,10 +169,10 @@ void QuaZipFile::setZipName(const QString& zipName) | |||
95 | qWarning("QuaZipFile::setZipName(): file is already open - can not set ZIP name"); | 169 | qWarning("QuaZipFile::setZipName(): file is already open - can not set ZIP name"); |
96 | return; | 170 | return; |
97 | } | 171 | } |
98 | if(zip!=NULL&&internal) delete zip; | 172 | if(p->zip!=NULL && p->internal) |
99 | zip=new QuaZip(zipName); | 173 | delete p->zip; |
100 | Q_CHECK_PTR(zip); | 174 | p->zip=new QuaZip(zipName); |
101 | internal=true; | 175 | p->internal=true; |
102 | } | 176 | } |
103 | 177 | ||
104 | void QuaZipFile::setZip(QuaZip *zip) | 178 | void QuaZipFile::setZip(QuaZip *zip) |
@@ -107,19 +181,20 @@ void QuaZipFile::setZip(QuaZip *zip) | |||
107 | qWarning("QuaZipFile::setZip(): file is already open - can not set ZIP"); | 181 | qWarning("QuaZipFile::setZip(): file is already open - can not set ZIP"); |
108 | return; | 182 | return; |
109 | } | 183 | } |
110 | if(this->zip!=NULL&&internal) delete this->zip; | 184 | if(p->zip!=NULL && p->internal) |
111 | this->zip=zip; | 185 | delete p->zip; |
112 | this->fileName=QString(); | 186 | p->zip=zip; |
113 | internal=false; | 187 | p->fileName=QString(); |
188 | p->internal=false; | ||
114 | } | 189 | } |
115 | 190 | ||
116 | void QuaZipFile::setFileName(const QString& fileName, QuaZip::CaseSensitivity cs) | 191 | void QuaZipFile::setFileName(const QString& fileName, QuaZip::CaseSensitivity cs) |
117 | { | 192 | { |
118 | if(zip==NULL) { | 193 | if(p->zip==NULL) { |
119 | qWarning("QuaZipFile::setFileName(): call setZipName() first"); | 194 | qWarning("QuaZipFile::setFileName(): call setZipName() first"); |
120 | return; | 195 | return; |
121 | } | 196 | } |
122 | if(!internal) { | 197 | if(!p->internal) { |
123 | qWarning("QuaZipFile::setFileName(): should not be used when not using internal QuaZip"); | 198 | qWarning("QuaZipFile::setFileName(): should not be used when not using internal QuaZip"); |
124 | return; | 199 | return; |
125 | } | 200 | } |
@@ -127,18 +202,20 @@ void QuaZipFile::setFileName(const QString& fileName, QuaZip::CaseSensitivity cs | |||
127 | qWarning("QuaZipFile::setFileName(): can not set file name for already opened file"); | 202 | qWarning("QuaZipFile::setFileName(): can not set file name for already opened file"); |
128 | return; | 203 | return; |
129 | } | 204 | } |
130 | this->fileName=fileName; | 205 | p->fileName=fileName; |
131 | this->caseSensitivity=cs; | 206 | if (p->fileName.startsWith('/')) |
207 | p->fileName = p->fileName.mid(1); | ||
208 | p->caseSensitivity=cs; | ||
132 | } | 209 | } |
133 | 210 | ||
134 | void QuaZipFile::setZipError(int zipError)const | 211 | void QuaZipFilePrivate::setZipError(int zipError) const |
135 | { | 212 | { |
136 | QuaZipFile *fakeThis=(QuaZipFile*)this; // non-const | 213 | QuaZipFilePrivate *fakeThis = const_cast<QuaZipFilePrivate*>(this); // non-const |
137 | fakeThis->zipError=zipError; | 214 | fakeThis->zipError=zipError; |
138 | if(zipError==UNZ_OK) | 215 | if(zipError==UNZ_OK) |
139 | fakeThis->setErrorString(QString()); | 216 | q->setErrorString(QString()); |
140 | else | 217 | else |
141 | fakeThis->setErrorString(tr("ZIP/UNZIP API error %1").arg(zipError)); | 218 | q->setErrorString(QuaZipFile::tr("ZIP/UNZIP API error %1").arg(zipError)); |
142 | } | 219 | } |
143 | 220 | ||
144 | bool QuaZipFile::open(OpenMode mode) | 221 | bool QuaZipFile::open(OpenMode mode) |
@@ -148,7 +225,7 @@ bool QuaZipFile::open(OpenMode mode) | |||
148 | 225 | ||
149 | bool QuaZipFile::open(OpenMode mode, int *method, int *level, bool raw, const char *password) | 226 | bool QuaZipFile::open(OpenMode mode, int *method, int *level, bool raw, const char *password) |
150 | { | 227 | { |
151 | resetZipError(); | 228 | p->resetZipError(); |
152 | if(isOpen()) { | 229 | if(isOpen()) { |
153 | qWarning("QuaZipFile::open(): already opened"); | 230 | qWarning("QuaZipFile::open(): already opened"); |
154 | return false; | 231 | return false; |
@@ -158,35 +235,35 @@ bool QuaZipFile::open(OpenMode mode, int *method, int *level, bool raw, const ch | |||
158 | return false; | 235 | return false; |
159 | } | 236 | } |
160 | if((mode&ReadOnly)&&!(mode&WriteOnly)) { | 237 | if((mode&ReadOnly)&&!(mode&WriteOnly)) { |
161 | if(internal) { | 238 | if(p->internal) { |
162 | if(!zip->open(QuaZip::mdUnzip)) { | 239 | if(!p->zip->open(QuaZip::mdUnzip)) { |
163 | setZipError(zip->getZipError()); | 240 | p->setZipError(p->zip->getZipError()); |
164 | return false; | 241 | return false; |
165 | } | 242 | } |
166 | if(!zip->setCurrentFile(fileName, caseSensitivity)) { | 243 | if(!p->zip->setCurrentFile(p->fileName, p->caseSensitivity)) { |
167 | setZipError(zip->getZipError()); | 244 | p->setZipError(p->zip->getZipError()); |
168 | zip->close(); | 245 | p->zip->close(); |
169 | return false; | 246 | return false; |
170 | } | 247 | } |
171 | } else { | 248 | } else { |
172 | if(zip==NULL) { | 249 | if(p->zip==NULL) { |
173 | qWarning("QuaZipFile::open(): zip is NULL"); | 250 | qWarning("QuaZipFile::open(): zip is NULL"); |
174 | return false; | 251 | return false; |
175 | } | 252 | } |
176 | if(zip->getMode()!=QuaZip::mdUnzip) { | 253 | if(p->zip->getMode()!=QuaZip::mdUnzip) { |
177 | qWarning("QuaZipFile::open(): file open mode %d incompatible with ZIP open mode %d", | 254 | qWarning("QuaZipFile::open(): file open mode %d incompatible with ZIP open mode %d", |
178 | (int)mode, (int)zip->getMode()); | 255 | (int)mode, (int)p->zip->getMode()); |
179 | return false; | 256 | return false; |
180 | } | 257 | } |
181 | if(!zip->hasCurrentFile()) { | 258 | if(!p->zip->hasCurrentFile()) { |
182 | qWarning("QuaZipFile::open(): zip does not have current file"); | 259 | qWarning("QuaZipFile::open(): zip does not have current file"); |
183 | return false; | 260 | return false; |
184 | } | 261 | } |
185 | } | 262 | } |
186 | setZipError(unzOpenCurrentFile3(zip->getUnzFile(), method, level, (int)raw, password)); | 263 | p->setZipError(unzOpenCurrentFile3(p->zip->getUnzFile(), method, level, (int)raw, password)); |
187 | if(zipError==UNZ_OK) { | 264 | if(p->zipError==UNZ_OK) { |
188 | setOpenMode(mode); | 265 | setOpenMode(mode); |
189 | this->raw=raw; | 266 | p->raw=raw; |
190 | return true; | 267 | return true; |
191 | } else | 268 | } else |
192 | return false; | 269 | return false; |
@@ -201,23 +278,23 @@ bool QuaZipFile::open(OpenMode mode, const QuaZipNewInfo& info, | |||
201 | int windowBits, int memLevel, int strategy) | 278 | int windowBits, int memLevel, int strategy) |
202 | { | 279 | { |
203 | zip_fileinfo info_z; | 280 | zip_fileinfo info_z; |
204 | resetZipError(); | 281 | p->resetZipError(); |
205 | if(isOpen()) { | 282 | if(isOpen()) { |
206 | qWarning("QuaZipFile::open(): already opened"); | 283 | qWarning("QuaZipFile::open(): already opened"); |
207 | return false; | 284 | return false; |
208 | } | 285 | } |
209 | if((mode&WriteOnly)&&!(mode&ReadOnly)) { | 286 | if((mode&WriteOnly)&&!(mode&ReadOnly)) { |
210 | if(internal) { | 287 | if(p->internal) { |
211 | qWarning("QuaZipFile::open(): write mode is incompatible with internal QuaZip approach"); | 288 | qWarning("QuaZipFile::open(): write mode is incompatible with internal QuaZip approach"); |
212 | return false; | 289 | return false; |
213 | } | 290 | } |
214 | if(zip==NULL) { | 291 | if(p->zip==NULL) { |
215 | qWarning("QuaZipFile::open(): zip is NULL"); | 292 | qWarning("QuaZipFile::open(): zip is NULL"); |
216 | return false; | 293 | return false; |
217 | } | 294 | } |
218 | if(zip->getMode()!=QuaZip::mdCreate&&zip->getMode()!=QuaZip::mdAppend&&zip->getMode()!=QuaZip::mdAdd) { | 295 | if(p->zip->getMode()!=QuaZip::mdCreate&&p->zip->getMode()!=QuaZip::mdAppend&&p->zip->getMode()!=QuaZip::mdAdd) { |
219 | qWarning("QuaZipFile::open(): file open mode %d incompatible with ZIP open mode %d", | 296 | qWarning("QuaZipFile::open(): file open mode %d incompatible with ZIP open mode %d", |
220 | (int)mode, (int)zip->getMode()); | 297 | (int)mode, (int)p->zip->getMode()); |
221 | return false; | 298 | return false; |
222 | } | 299 | } |
223 | info_z.tmz_date.tm_year=info.dateTime.date().year(); | 300 | info_z.tmz_date.tm_year=info.dateTime.date().year(); |
@@ -229,21 +306,25 @@ bool QuaZipFile::open(OpenMode mode, const QuaZipNewInfo& info, | |||
229 | info_z.dosDate = 0; | 306 | info_z.dosDate = 0; |
230 | info_z.internal_fa=(uLong)info.internalAttr; | 307 | info_z.internal_fa=(uLong)info.internalAttr; |
231 | info_z.external_fa=(uLong)info.externalAttr; | 308 | info_z.external_fa=(uLong)info.externalAttr; |
232 | setZipError(zipOpenNewFileInZip3(zip->getZipFile(), | 309 | if (p->zip->isDataDescriptorWritingEnabled()) |
233 | zip->getFileNameCodec()->fromUnicode(info.name).constData(), &info_z, | 310 | zipSetFlags(p->zip->getZipFile(), ZIP_WRITE_DATA_DESCRIPTOR); |
311 | else | ||
312 | zipClearFlags(p->zip->getZipFile(), ZIP_WRITE_DATA_DESCRIPTOR); | ||
313 | p->setZipError(zipOpenNewFileInZip3_64(p->zip->getZipFile(), | ||
314 | p->zip->getFileNameCodec()->fromUnicode(info.name).constData(), &info_z, | ||
234 | info.extraLocal.constData(), info.extraLocal.length(), | 315 | info.extraLocal.constData(), info.extraLocal.length(), |
235 | info.extraGlobal.constData(), info.extraGlobal.length(), | 316 | info.extraGlobal.constData(), info.extraGlobal.length(), |
236 | zip->getCommentCodec()->fromUnicode(info.comment).constData(), | 317 | p->zip->getCommentCodec()->fromUnicode(info.comment).constData(), |
237 | method, level, (int)raw, | 318 | method, level, (int)raw, |
238 | windowBits, memLevel, strategy, | 319 | windowBits, memLevel, strategy, |
239 | password, (uLong)crc)); | 320 | password, (uLong)crc, p->zip->isZip64Enabled())); |
240 | if(zipError==UNZ_OK) { | 321 | if(p->zipError==UNZ_OK) { |
241 | writePos=0; | 322 | p->writePos=0; |
242 | setOpenMode(mode); | 323 | setOpenMode(mode); |
243 | this->raw=raw; | 324 | p->raw=raw; |
244 | if(raw) { | 325 | if(raw) { |
245 | this->crc=crc; | 326 | p->crc=crc; |
246 | this->uncompressedSize=info.uncompressedSize; | 327 | p->uncompressedSize=info.uncompressedSize; |
247 | } | 328 | } |
248 | return true; | 329 | return true; |
249 | } else | 330 | } else |
@@ -260,7 +341,7 @@ bool QuaZipFile::isSequential()const | |||
260 | 341 | ||
261 | qint64 QuaZipFile::pos()const | 342 | qint64 QuaZipFile::pos()const |
262 | { | 343 | { |
263 | if(zip==NULL) { | 344 | if(p->zip==NULL) { |
264 | qWarning("QuaZipFile::pos(): call setZipName() or setZip() first"); | 345 | qWarning("QuaZipFile::pos(): call setZipName() or setZip() first"); |
265 | return -1; | 346 | return -1; |
266 | } | 347 | } |
@@ -269,14 +350,17 @@ qint64 QuaZipFile::pos()const | |||
269 | return -1; | 350 | return -1; |
270 | } | 351 | } |
271 | if(openMode()&ReadOnly) | 352 | if(openMode()&ReadOnly) |
272 | return unztell(zip->getUnzFile()); | 353 | // QIODevice::pos() is broken for sequential devices, |
354 | // but thankfully bytesAvailable() returns the number of | ||
355 | // bytes buffered, so we know how far ahead we are. | ||
356 | return unztell(p->zip->getUnzFile()) - QIODevice::bytesAvailable(); | ||
273 | else | 357 | else |
274 | return writePos; | 358 | return p->writePos; |
275 | } | 359 | } |
276 | 360 | ||
277 | bool QuaZipFile::atEnd()const | 361 | bool QuaZipFile::atEnd()const |
278 | { | 362 | { |
279 | if(zip==NULL) { | 363 | if(p->zip==NULL) { |
280 | qWarning("QuaZipFile::atEnd(): call setZipName() or setZip() first"); | 364 | qWarning("QuaZipFile::atEnd(): call setZipName() or setZip() first"); |
281 | return false; | 365 | return false; |
282 | } | 366 | } |
@@ -285,7 +369,9 @@ bool QuaZipFile::atEnd()const | |||
285 | return false; | 369 | return false; |
286 | } | 370 | } |
287 | if(openMode()&ReadOnly) | 371 | if(openMode()&ReadOnly) |
288 | return unzeof(zip->getUnzFile())==1; | 372 | // the same problem as with pos() |
373 | return QIODevice::bytesAvailable() == 0 | ||
374 | && unzeof(p->zip->getUnzFile())==1; | ||
289 | else | 375 | else |
290 | return true; | 376 | return true; |
291 | } | 377 | } |
@@ -297,81 +383,120 @@ qint64 QuaZipFile::size()const | |||
297 | return -1; | 383 | return -1; |
298 | } | 384 | } |
299 | if(openMode()&ReadOnly) | 385 | if(openMode()&ReadOnly) |
300 | return raw?csize():usize(); | 386 | return p->raw?csize():usize(); |
301 | else | 387 | else |
302 | return writePos; | 388 | return p->writePos; |
303 | } | 389 | } |
304 | 390 | ||
305 | qint64 QuaZipFile::csize()const | 391 | qint64 QuaZipFile::csize()const |
306 | { | 392 | { |
307 | unz_file_info info_z; | 393 | unz_file_info64 info_z; |
308 | setZipError(UNZ_OK); | 394 | p->setZipError(UNZ_OK); |
309 | if(zip==NULL||zip->getMode()!=QuaZip::mdUnzip) return -1; | 395 | if(p->zip==NULL||p->zip->getMode()!=QuaZip::mdUnzip) return -1; |
310 | setZipError(unzGetCurrentFileInfo(zip->getUnzFile(), &info_z, NULL, 0, NULL, 0, NULL, 0)); | 396 | p->setZipError(unzGetCurrentFileInfo64(p->zip->getUnzFile(), &info_z, NULL, 0, NULL, 0, NULL, 0)); |
311 | if(zipError!=UNZ_OK) | 397 | if(p->zipError!=UNZ_OK) |
312 | return -1; | 398 | return -1; |
313 | return info_z.compressed_size; | 399 | return info_z.compressed_size; |
314 | } | 400 | } |
315 | 401 | ||
316 | qint64 QuaZipFile::usize()const | 402 | qint64 QuaZipFile::usize()const |
317 | { | 403 | { |
318 | unz_file_info info_z; | 404 | unz_file_info64 info_z; |
319 | setZipError(UNZ_OK); | 405 | p->setZipError(UNZ_OK); |
320 | if(zip==NULL||zip->getMode()!=QuaZip::mdUnzip) return -1; | 406 | if(p->zip==NULL||p->zip->getMode()!=QuaZip::mdUnzip) return -1; |
321 | setZipError(unzGetCurrentFileInfo(zip->getUnzFile(), &info_z, NULL, 0, NULL, 0, NULL, 0)); | 407 | p->setZipError(unzGetCurrentFileInfo64(p->zip->getUnzFile(), &info_z, NULL, 0, NULL, 0, NULL, 0)); |
322 | if(zipError!=UNZ_OK) | 408 | if(p->zipError!=UNZ_OK) |
323 | return -1; | 409 | return -1; |
324 | return info_z.uncompressed_size; | 410 | return info_z.uncompressed_size; |
325 | } | 411 | } |
326 | 412 | ||
327 | bool QuaZipFile::getFileInfo(QuaZipFileInfo *info) | 413 | bool QuaZipFile::getFileInfo(QuaZipFileInfo *info) |
328 | { | 414 | { |
329 | if(zip==NULL||zip->getMode()!=QuaZip::mdUnzip) return false; | 415 | QuaZipFileInfo64 info64; |
330 | zip->getCurrentFileInfo(info); | 416 | if (getFileInfo(&info64)) { |
331 | setZipError(zip->getZipError()); | 417 | info64.toQuaZipFileInfo(*info); |
332 | return zipError==UNZ_OK; | 418 | return true; |
419 | } else { | ||
420 | return false; | ||
421 | } | ||
422 | } | ||
423 | |||
424 | bool QuaZipFile::getFileInfo(QuaZipFileInfo64 *info) | ||
425 | { | ||
426 | if(p->zip==NULL||p->zip->getMode()!=QuaZip::mdUnzip) return false; | ||
427 | p->zip->getCurrentFileInfo(info); | ||
428 | p->setZipError(p->zip->getZipError()); | ||
429 | return p->zipError==UNZ_OK; | ||
333 | } | 430 | } |
334 | 431 | ||
335 | void QuaZipFile::close() | 432 | void QuaZipFile::close() |
336 | { | 433 | { |
337 | resetZipError(); | 434 | p->resetZipError(); |
338 | if(zip==NULL||!zip->isOpen()) return; | 435 | if(p->zip==NULL||!p->zip->isOpen()) return; |
339 | if(!isOpen()) { | 436 | if(!isOpen()) { |
340 | qWarning("QuaZipFile::close(): file isn't open"); | 437 | qWarning("QuaZipFile::close(): file isn't open"); |
341 | return; | 438 | return; |
342 | } | 439 | } |
343 | if(openMode()&ReadOnly) | 440 | if(openMode()&ReadOnly) |
344 | setZipError(unzCloseCurrentFile(zip->getUnzFile())); | 441 | p->setZipError(unzCloseCurrentFile(p->zip->getUnzFile())); |
345 | else if(openMode()&WriteOnly) | 442 | else if(openMode()&WriteOnly) |
346 | if(isRaw()) setZipError(zipCloseFileInZipRaw(zip->getZipFile(), uncompressedSize, crc)); | 443 | if(isRaw()) p->setZipError(zipCloseFileInZipRaw64(p->zip->getZipFile(), p->uncompressedSize, p->crc)); |
347 | else setZipError(zipCloseFileInZip(zip->getZipFile())); | 444 | else p->setZipError(zipCloseFileInZip(p->zip->getZipFile())); |
348 | else { | 445 | else { |
349 | qWarning("Wrong open mode: %d", (int)openMode()); | 446 | qWarning("Wrong open mode: %d", (int)openMode()); |
350 | return; | 447 | return; |
351 | } | 448 | } |
352 | if(zipError==UNZ_OK) setOpenMode(QIODevice::NotOpen); | 449 | if(p->zipError==UNZ_OK) setOpenMode(QIODevice::NotOpen); |
353 | else return; | 450 | else return; |
354 | if(internal) { | 451 | if(p->internal) { |
355 | zip->close(); | 452 | p->zip->close(); |
356 | setZipError(zip->getZipError()); | 453 | p->setZipError(p->zip->getZipError()); |
357 | } | 454 | } |
358 | } | 455 | } |
359 | 456 | ||
360 | qint64 QuaZipFile::readData(char *data, qint64 maxSize) | 457 | qint64 QuaZipFile::readData(char *data, qint64 maxSize) |
361 | { | 458 | { |
362 | setZipError(UNZ_OK); | 459 | p->setZipError(UNZ_OK); |
363 | qint64 bytesRead=unzReadCurrentFile(zip->getUnzFile(), data, (unsigned)maxSize); | 460 | qint64 bytesRead=unzReadCurrentFile(p->zip->getUnzFile(), data, (unsigned)maxSize); |
364 | if(bytesRead<0) setZipError((int)bytesRead); | 461 | if (bytesRead < 0) { |
462 | p->setZipError((int) bytesRead); | ||
463 | return -1; | ||
464 | } | ||
365 | return bytesRead; | 465 | return bytesRead; |
366 | } | 466 | } |
367 | 467 | ||
368 | qint64 QuaZipFile::writeData(const char* data, qint64 maxSize) | 468 | qint64 QuaZipFile::writeData(const char* data, qint64 maxSize) |
369 | { | 469 | { |
370 | setZipError(ZIP_OK); | 470 | p->setZipError(ZIP_OK); |
371 | setZipError(zipWriteInFileInZip(zip->getZipFile(), data, (uint)maxSize)); | 471 | p->setZipError(zipWriteInFileInZip(p->zip->getZipFile(), data, (uint)maxSize)); |
372 | if(zipError!=ZIP_OK) return -1; | 472 | if(p->zipError!=ZIP_OK) return -1; |
373 | else { | 473 | else { |
374 | writePos+=maxSize; | 474 | p->writePos+=maxSize; |
375 | return maxSize; | 475 | return maxSize; |
376 | } | 476 | } |
377 | } | 477 | } |
478 | |||
479 | QString QuaZipFile::getFileName() const | ||
480 | { | ||
481 | return p->fileName; | ||
482 | } | ||
483 | |||
484 | QuaZip::CaseSensitivity QuaZipFile::getCaseSensitivity() const | ||
485 | { | ||
486 | return p->caseSensitivity; | ||
487 | } | ||
488 | |||
489 | bool QuaZipFile::isRaw() const | ||
490 | { | ||
491 | return p->raw; | ||
492 | } | ||
493 | |||
494 | int QuaZipFile::getZipError() const | ||
495 | { | ||
496 | return p->zipError; | ||
497 | } | ||
498 | |||
499 | qint64 QuaZipFile::bytesAvailable() const | ||
500 | { | ||
501 | return size() - pos(); | ||
502 | } | ||