~ubuntu-branches/ubuntu/trusty/tomahawk/trusty-proposed

« back to all changes in this revision

Viewing changes to src/libtomahawk/thirdparty/quazip/quazip/quazipfile.cpp

  • Committer: Package Import Robot
  • Author(s): Harald Sitter
  • Date: 2013-03-07 21:50:13 UTC
  • Revision ID: package-import@ubuntu.com-20130307215013-6gdjkdds7i9uenvs
Tags: upstream-0.6.0+dfsg
ImportĀ upstreamĀ versionĀ 0.6.0+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (C) 2005-2011 Sergey A. Tachenov
 
3
 
 
4
This program is free software; you can redistribute it and/or modify it
 
5
under the terms of the GNU Lesser General Public License as published by
 
6
the Free Software Foundation; either version 2 of the License, or (at
 
7
your option) any later version.
 
8
 
 
9
This program is distributed in the hope that it will be useful, but
 
10
WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
 
12
General Public License for more details.
 
13
 
 
14
You should have received a copy of the GNU Lesser General Public License
 
15
along with this program; if not, write to the Free Software Foundation,
 
16
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
17
 
 
18
See COPYING file for the full LGPL text.
 
19
 
 
20
Original ZIP package is copyrighted by Gilles Vollant, see
 
21
quazip/(un)zip.h files for details, basically it's zlib license.
 
22
 **/
 
23
 
 
24
#include "quazipfile.h"
 
25
 
 
26
using namespace std;
 
27
 
 
28
class QuaZipFilePrivate {
 
29
  friend class QuaZipFile;
 
30
  private:
 
31
    QuaZipFile *q;
 
32
    QuaZip *zip;
 
33
    QString fileName;
 
34
    QuaZip::CaseSensitivity caseSensitivity;
 
35
    bool raw;
 
36
    qint64 writePos;
 
37
    // these two are for writing raw files
 
38
    ulong uncompressedSize;
 
39
    quint32 crc;
 
40
    bool internal;
 
41
    int zipError;
 
42
    inline void resetZipError() const {setZipError(UNZ_OK);}
 
43
    // const, but sets zipError!
 
44
    void setZipError(int zipError) const;
 
45
    inline QuaZipFilePrivate(QuaZipFile *q):
 
46
      q(q), zip(NULL), internal(true), zipError(UNZ_OK) {}
 
47
    inline QuaZipFilePrivate(QuaZipFile *q, const QString &zipName):
 
48
      q(q), internal(true), zipError(UNZ_OK)
 
49
      {
 
50
        zip=new QuaZip(zipName);
 
51
      }
 
52
    inline QuaZipFilePrivate(QuaZipFile *q, const QString &zipName, const QString &fileName,
 
53
        QuaZip::CaseSensitivity cs):
 
54
      q(q), internal(true), zipError(UNZ_OK)
 
55
      {
 
56
        zip=new QuaZip(zipName);
 
57
        this->fileName=fileName;
 
58
        this->caseSensitivity=cs;
 
59
      }
 
60
    inline QuaZipFilePrivate(QuaZipFile *q, QuaZip *zip):
 
61
      q(q), zip(zip), internal(false), zipError(UNZ_OK) {}
 
62
    inline ~QuaZipFilePrivate()
 
63
    {
 
64
      if (internal)
 
65
        delete zip;
 
66
    }
 
67
};
 
68
 
 
69
QuaZipFile::QuaZipFile():
 
70
  p(new QuaZipFilePrivate(this))
 
71
{
 
72
}
 
73
 
 
74
QuaZipFile::QuaZipFile(QObject *parent):
 
75
  QIODevice(parent),
 
76
  p(new QuaZipFilePrivate(this))
 
77
{
 
78
}
 
79
 
 
80
QuaZipFile::QuaZipFile(const QString& zipName, QObject *parent):
 
81
  QIODevice(parent),
 
82
  p(new QuaZipFilePrivate(this, zipName))
 
83
{
 
84
}
 
85
 
 
86
QuaZipFile::QuaZipFile(const QString& zipName, const QString& fileName,
 
87
    QuaZip::CaseSensitivity cs, QObject *parent):
 
88
  QIODevice(parent),
 
89
  p(new QuaZipFilePrivate(this, zipName, fileName, cs))
 
90
{
 
91
}
 
92
 
 
93
QuaZipFile::QuaZipFile(QuaZip *zip, QObject *parent):
 
94
  QIODevice(parent),
 
95
  p(new QuaZipFilePrivate(this, zip))
 
96
{
 
97
}
 
98
 
 
99
QuaZipFile::~QuaZipFile()
 
100
{
 
101
  if (isOpen())
 
102
    close();
 
103
  delete p;
 
104
}
 
105
 
 
106
QString QuaZipFile::getZipName() const
 
107
{
 
108
  return p->zip==NULL ? QString() : p->zip->getZipName();
 
109
}
 
110
 
 
111
QString QuaZipFile::getActualFileName()const
 
112
{
 
113
  p->setZipError(UNZ_OK);
 
114
  if (p->zip == NULL || (openMode() & WriteOnly))
 
115
    return QString();
 
116
  QString name=p->zip->getCurrentFileName();
 
117
  if(name.isNull())
 
118
    p->setZipError(p->zip->getZipError());
 
119
  return name;
 
120
}
 
121
 
 
122
void QuaZipFile::setZipName(const QString& zipName)
 
123
{
 
124
  if(isOpen()) {
 
125
    qWarning("QuaZipFile::setZipName(): file is already open - can not set ZIP name");
 
126
    return;
 
127
  }
 
128
  if(p->zip!=NULL && p->internal)
 
129
    delete p->zip;
 
130
  p->zip=new QuaZip(zipName);
 
131
  p->internal=true;
 
132
}
 
133
 
 
134
void QuaZipFile::setZip(QuaZip *zip)
 
135
{
 
136
  if(isOpen()) {
 
137
    qWarning("QuaZipFile::setZip(): file is already open - can not set ZIP");
 
138
    return;
 
139
  }
 
140
  if(p->zip!=NULL && p->internal)
 
141
    delete p->zip;
 
142
  p->zip=zip;
 
143
  p->fileName=QString();
 
144
  p->internal=false;
 
145
}
 
146
 
 
147
void QuaZipFile::setFileName(const QString& fileName, QuaZip::CaseSensitivity cs)
 
148
{
 
149
  if(p->zip==NULL) {
 
150
    qWarning("QuaZipFile::setFileName(): call setZipName() first");
 
151
    return;
 
152
  }
 
153
  if(!p->internal) {
 
154
    qWarning("QuaZipFile::setFileName(): should not be used when not using internal QuaZip");
 
155
    return;
 
156
  }
 
157
  if(isOpen()) {
 
158
    qWarning("QuaZipFile::setFileName(): can not set file name for already opened file");
 
159
    return;
 
160
  }
 
161
  p->fileName=fileName;
 
162
  p->caseSensitivity=cs;
 
163
}
 
164
 
 
165
void QuaZipFilePrivate::setZipError(int zipError) const
 
166
{
 
167
  QuaZipFilePrivate *fakeThis = const_cast<QuaZipFilePrivate*>(this); // non-const
 
168
  fakeThis->zipError=zipError;
 
169
  if(zipError==UNZ_OK)
 
170
    q->setErrorString(QString());
 
171
  else
 
172
    q->setErrorString(q->tr("ZIP/UNZIP API error %1").arg(zipError));
 
173
}
 
174
 
 
175
bool QuaZipFile::open(OpenMode mode)
 
176
{
 
177
  return open(mode, NULL);
 
178
}
 
179
 
 
180
bool QuaZipFile::open(OpenMode mode, int *method, int *level, bool raw, const char *password)
 
181
{
 
182
  p->resetZipError();
 
183
  if(isOpen()) {
 
184
    qWarning("QuaZipFile::open(): already opened");
 
185
    return false;
 
186
  }
 
187
  if(mode&Unbuffered) {
 
188
    qWarning("QuaZipFile::open(): Unbuffered mode is not supported");
 
189
    return false;
 
190
  }
 
191
  if((mode&ReadOnly)&&!(mode&WriteOnly)) {
 
192
    if(p->internal) {
 
193
      if(!p->zip->open(QuaZip::mdUnzip)) {
 
194
        p->setZipError(p->zip->getZipError());
 
195
        return false;
 
196
      }
 
197
      if(!p->zip->setCurrentFile(p->fileName, p->caseSensitivity)) {
 
198
        p->setZipError(p->zip->getZipError());
 
199
        p->zip->close();
 
200
        return false;
 
201
      }
 
202
    } else {
 
203
      if(p->zip==NULL) {
 
204
        qWarning("QuaZipFile::open(): zip is NULL");
 
205
        return false;
 
206
      }
 
207
      if(p->zip->getMode()!=QuaZip::mdUnzip) {
 
208
        qWarning("QuaZipFile::open(): file open mode %d incompatible with ZIP open mode %d",
 
209
            (int)mode, (int)p->zip->getMode());
 
210
        return false;
 
211
      }
 
212
      if(!p->zip->hasCurrentFile()) {
 
213
        qWarning("QuaZipFile::open(): zip does not have current file");
 
214
        return false;
 
215
      }
 
216
    }
 
217
    p->setZipError(unzOpenCurrentFile3(p->zip->getUnzFile(), method, level, (int)raw, password));
 
218
    if(p->zipError==UNZ_OK) {
 
219
      setOpenMode(mode);
 
220
      p->raw=raw;
 
221
      return true;
 
222
    } else
 
223
      return false;
 
224
  }
 
225
  qWarning("QuaZipFile::open(): open mode %d not supported by this function", (int)mode);
 
226
  return false;
 
227
}
 
228
 
 
229
bool QuaZipFile::open(OpenMode mode, const QuaZipNewInfo& info,
 
230
    const char *password, quint32 crc,
 
231
    int method, int level, bool raw,
 
232
    int windowBits, int memLevel, int strategy)
 
233
{
 
234
  zip_fileinfo info_z;
 
235
  p->resetZipError();
 
236
  if(isOpen()) {
 
237
    qWarning("QuaZipFile::open(): already opened");
 
238
    return false;
 
239
  }
 
240
  if((mode&WriteOnly)&&!(mode&ReadOnly)) {
 
241
    if(p->internal) {
 
242
      qWarning("QuaZipFile::open(): write mode is incompatible with internal QuaZip approach");
 
243
      return false;
 
244
    }
 
245
    if(p->zip==NULL) {
 
246
      qWarning("QuaZipFile::open(): zip is NULL");
 
247
      return false;
 
248
    }
 
249
    if(p->zip->getMode()!=QuaZip::mdCreate&&p->zip->getMode()!=QuaZip::mdAppend&&p->zip->getMode()!=QuaZip::mdAdd) {
 
250
      qWarning("QuaZipFile::open(): file open mode %d incompatible with ZIP open mode %d",
 
251
          (int)mode, (int)p->zip->getMode());
 
252
      return false;
 
253
    }
 
254
    info_z.tmz_date.tm_year=info.dateTime.date().year();
 
255
    info_z.tmz_date.tm_mon=info.dateTime.date().month() - 1;
 
256
    info_z.tmz_date.tm_mday=info.dateTime.date().day();
 
257
    info_z.tmz_date.tm_hour=info.dateTime.time().hour();
 
258
    info_z.tmz_date.tm_min=info.dateTime.time().minute();
 
259
    info_z.tmz_date.tm_sec=info.dateTime.time().second();
 
260
    info_z.dosDate = 0;
 
261
    info_z.internal_fa=(uLong)info.internalAttr;
 
262
    info_z.external_fa=(uLong)info.externalAttr;
 
263
    p->setZipError(zipOpenNewFileInZip3(p->zip->getZipFile(),
 
264
          p->zip->getFileNameCodec()->fromUnicode(info.name).constData(), &info_z,
 
265
          info.extraLocal.constData(), info.extraLocal.length(),
 
266
          info.extraGlobal.constData(), info.extraGlobal.length(),
 
267
          p->zip->getCommentCodec()->fromUnicode(info.comment).constData(),
 
268
          method, level, (int)raw,
 
269
          windowBits, memLevel, strategy,
 
270
          password, (uLong)crc));
 
271
    if(p->zipError==UNZ_OK) {
 
272
      p->writePos=0;
 
273
      setOpenMode(mode);
 
274
      p->raw=raw;
 
275
      if(raw) {
 
276
        p->crc=crc;
 
277
        p->uncompressedSize=info.uncompressedSize;
 
278
      }
 
279
      return true;
 
280
    } else
 
281
      return false;
 
282
  }
 
283
  qWarning("QuaZipFile::open(): open mode %d not supported by this function", (int)mode);
 
284
  return false;
 
285
}
 
286
 
 
287
bool QuaZipFile::isSequential()const
 
288
{
 
289
  return true;
 
290
}
 
291
 
 
292
qint64 QuaZipFile::pos()const
 
293
{
 
294
  if(p->zip==NULL) {
 
295
    qWarning("QuaZipFile::pos(): call setZipName() or setZip() first");
 
296
    return -1;
 
297
  }
 
298
  if(!isOpen()) {
 
299
    qWarning("QuaZipFile::pos(): file is not open");
 
300
    return -1;
 
301
  }
 
302
  if(openMode()&ReadOnly)
 
303
    return unztell(p->zip->getUnzFile());
 
304
  else
 
305
    return p->writePos;
 
306
}
 
307
 
 
308
bool QuaZipFile::atEnd()const
 
309
{
 
310
  if(p->zip==NULL) {
 
311
    qWarning("QuaZipFile::atEnd(): call setZipName() or setZip() first");
 
312
    return false;
 
313
  }
 
314
  if(!isOpen()) {
 
315
    qWarning("QuaZipFile::atEnd(): file is not open");
 
316
    return false;
 
317
  }
 
318
  if(openMode()&ReadOnly)
 
319
    return unzeof(p->zip->getUnzFile())==1;
 
320
  else
 
321
    return true;
 
322
}
 
323
 
 
324
qint64 QuaZipFile::size()const
 
325
{
 
326
  if(!isOpen()) {
 
327
    qWarning("QuaZipFile::atEnd(): file is not open");
 
328
    return -1;
 
329
  }
 
330
  if(openMode()&ReadOnly)
 
331
    return p->raw?csize():usize();
 
332
  else
 
333
    return p->writePos;
 
334
}
 
335
 
 
336
qint64 QuaZipFile::csize()const
 
337
{
 
338
  unz_file_info info_z;
 
339
  p->setZipError(UNZ_OK);
 
340
  if(p->zip==NULL||p->zip->getMode()!=QuaZip::mdUnzip) return -1;
 
341
  p->setZipError(unzGetCurrentFileInfo(p->zip->getUnzFile(), &info_z, NULL, 0, NULL, 0, NULL, 0));
 
342
  if(p->zipError!=UNZ_OK)
 
343
    return -1;
 
344
  return info_z.compressed_size;
 
345
}
 
346
 
 
347
qint64 QuaZipFile::usize()const
 
348
{
 
349
  unz_file_info info_z;
 
350
  p->setZipError(UNZ_OK);
 
351
  if(p->zip==NULL||p->zip->getMode()!=QuaZip::mdUnzip) return -1;
 
352
  p->setZipError(unzGetCurrentFileInfo(p->zip->getUnzFile(), &info_z, NULL, 0, NULL, 0, NULL, 0));
 
353
  if(p->zipError!=UNZ_OK)
 
354
    return -1;
 
355
  return info_z.uncompressed_size;
 
356
}
 
357
 
 
358
bool QuaZipFile::getFileInfo(QuaZipFileInfo *info)
 
359
{
 
360
  if(p->zip==NULL||p->zip->getMode()!=QuaZip::mdUnzip) return false;
 
361
  p->zip->getCurrentFileInfo(info);
 
362
  p->setZipError(p->zip->getZipError());
 
363
  return p->zipError==UNZ_OK;
 
364
}
 
365
 
 
366
void QuaZipFile::close()
 
367
{
 
368
  p->resetZipError();
 
369
  if(p->zip==NULL||!p->zip->isOpen()) return;
 
370
  if(!isOpen()) {
 
371
    qWarning("QuaZipFile::close(): file isn't open");
 
372
    return;
 
373
  }
 
374
  if(openMode()&ReadOnly)
 
375
    p->setZipError(unzCloseCurrentFile(p->zip->getUnzFile()));
 
376
  else if(openMode()&WriteOnly)
 
377
    if(isRaw()) p->setZipError(zipCloseFileInZipRaw(p->zip->getZipFile(), p->uncompressedSize, p->crc));
 
378
    else p->setZipError(zipCloseFileInZip(p->zip->getZipFile()));
 
379
  else {
 
380
    qWarning("Wrong open mode: %d", (int)openMode());
 
381
    return;
 
382
  }
 
383
  if(p->zipError==UNZ_OK) setOpenMode(QIODevice::NotOpen);
 
384
  else return;
 
385
  if(p->internal) {
 
386
    p->zip->close();
 
387
    p->setZipError(p->zip->getZipError());
 
388
  }
 
389
}
 
390
 
 
391
qint64 QuaZipFile::readData(char *data, qint64 maxSize)
 
392
{
 
393
  p->setZipError(UNZ_OK);
 
394
  qint64 bytesRead=unzReadCurrentFile(p->zip->getUnzFile(), data, (unsigned)maxSize);
 
395
  if(bytesRead<0) p->setZipError((int)bytesRead);
 
396
  return bytesRead;
 
397
}
 
398
 
 
399
qint64 QuaZipFile::writeData(const char* data, qint64 maxSize)
 
400
{
 
401
  p->setZipError(ZIP_OK);
 
402
  p->setZipError(zipWriteInFileInZip(p->zip->getZipFile(), data, (uint)maxSize));
 
403
  if(p->zipError!=ZIP_OK) return -1;
 
404
  else {
 
405
    p->writePos+=maxSize;
 
406
    return maxSize;
 
407
  }
 
408
}
 
409
 
 
410
QString QuaZipFile::getFileName() const
 
411
{
 
412
  return p->fileName;
 
413
}
 
414
 
 
415
QuaZip::CaseSensitivity QuaZipFile::getCaseSensitivity() const
 
416
{
 
417
  return p->caseSensitivity;
 
418
}
 
419
 
 
420
bool QuaZipFile::isRaw() const
 
421
{
 
422
  return p->raw;
 
423
}
 
424
 
 
425
int QuaZipFile::getZipError() const
 
426
{
 
427
  return p->zipError;
 
428
}