PageRenderTime 295ms CodeModel.GetById 150ms app.highlight 89ms RepoModel.GetById 51ms app.codeStats 1ms

/src/libtomahawk/thirdparty/quazip/quazip/JlCompress.cpp

http://github.com/tomahawk-player/tomahawk
C++ | 468 lines | 234 code | 53 blank | 181 comment | 48 complexity | ef929d406c6607efef387f821c5fea4d MD5 | raw file
  1#include "JlCompress.h"
  2#include <QDebug>
  3/**OK
  4 * Comprime il file fileName, nell'oggetto zip, con il nome fileDest.
  5 *
  6 * La funzione fallisce se:
  7 * * zip==NULL;
  8 * * l'oggetto zip č stato aperto in una modalitŕ non compatibile con l'aggiunta di file;
  9 * * non č possibile aprire il file d'origine;
 10 * * non č possibile creare il file all'interno dell'oggetto zip;
 11 * * si č rilevato un errore nella copia dei dati;
 12 * * non č stato possibile chiudere il file all'interno dell'oggetto zip;
 13 */
 14bool JlCompress::compressFile(QuaZip* zip, QString fileName, QString fileDest) {
 15    // zip: oggetto dove aggiungere il file
 16    // fileName: nome del file reale
 17    // fileDest: nome del file all'interno del file compresso
 18
 19    // Controllo l'apertura dello zip
 20    if (!zip) return false;
 21    if (zip->getMode()!=QuaZip::mdCreate &&
 22        zip->getMode()!=QuaZip::mdAppend &&
 23        zip->getMode()!=QuaZip::mdAdd) return false;
 24
 25    // Apro il file originale
 26    QFile inFile;
 27    inFile.setFileName(fileName);
 28    if(!inFile.open(QIODevice::ReadOnly)) return false;
 29
 30    // Apro il file risulato
 31    QuaZipFile outFile(zip);
 32    if(!outFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileDest, inFile.fileName()))) return false;
 33
 34    // Copio i dati
 35    char c;
 36    while(inFile.getChar(&c)&&outFile.putChar(c));
 37    if(outFile.getZipError()!=UNZ_OK) return false;
 38
 39    // Chiudo i file
 40    outFile.close();
 41    if (outFile.getZipError()!=UNZ_OK) return false;
 42    inFile.close();
 43
 44    return true;
 45}
 46
 47/**OK
 48 * Comprime la cartella dir nel file fileCompressed, se recursive č true allora
 49 * comprime anche le sotto cartelle. I nomi dei file preceduti dal path creato
 50 * togliendo il pat della cartella origDir al path della cartella dir.
 51 * Se la funzione fallisce restituisce false e cancella il file che si č tentato
 52 * di creare.
 53 *
 54 * La funzione fallisce se:
 55 * * zip==NULL;
 56 * * l'oggetto zip č stato aperto in una modalitŕ non compatibile con l'aggiunta di file;
 57 * * la cartella dir non esiste;
 58 * * la compressione di una sotto cartella fallisce (1);
 59 * * la compressione di un file fallisce;
 60 * (1) La funzione si richiama in maniera ricorsiva per comprimere le sotto cartelle
 61 * dunque gli errori di compressione di una sotto cartella sono gli stessi di questa
 62 * funzione.
 63 */
 64bool JlCompress::compressSubDir(QuaZip* zip, QString dir, QString origDir, bool recursive) {
 65    // zip: oggetto dove aggiungere il file
 66    // dir: cartella reale corrente
 67    // origDir: cartella reale originale
 68    // (path(dir)-path(origDir)) = path interno all'oggetto zip
 69
 70    // Controllo l'apertura dello zip
 71    if (!zip) return false;
 72    if (zip->getMode()!=QuaZip::mdCreate &&
 73        zip->getMode()!=QuaZip::mdAppend &&
 74        zip->getMode()!=QuaZip::mdAdd) return false;
 75
 76    // Controllo la cartella
 77    QDir directory(dir);
 78    if (!directory.exists()) return false;
 79
 80    // Se comprimo anche le sotto cartelle
 81    if (recursive) {
 82        // Per ogni sotto cartella
 83        QFileInfoList files = directory.entryInfoList(QDir::AllDirs|QDir::NoDotAndDotDot);
 84        foreach (QFileInfo file, files) {
 85            // Comprimo la sotto cartella
 86            if(!compressSubDir(zip,file.absoluteFilePath(),origDir,recursive)) return false;
 87        }
 88    }
 89
 90    // Per ogni file nella cartella
 91    QFileInfoList files = directory.entryInfoList(QDir::Files);
 92    QDir origDirectory(origDir);
 93    foreach (QFileInfo file, files) {
 94        // Se non č un file o č il file compresso che sto creando
 95        if(!file.isFile()||file.absoluteFilePath()==zip->getZipName()) continue;
 96
 97        // Creo il nome relativo da usare all'interno del file compresso
 98        QString filename = origDirectory.relativeFilePath(file.absoluteFilePath());
 99
100        // Comprimo il file
101        if (!compressFile(zip,file.absoluteFilePath(),filename)) return false;
102    }
103
104    return true;
105}
106
107/**OK
108 * Estrae il file fileName, contenuto nell'oggetto zip, con il nome fileDest.
109 * Se la funzione fallisce restituisce false e cancella il file che si č tentato di estrarre.
110 *
111 * La funzione fallisce se:
112 * * zip==NULL;
113 * * l'oggetto zip č stato aperto in una modalitŕ non compatibile con l'estrazione di file;
114 * * non č possibile aprire il file all'interno dell'oggetto zip;
115 * * non č possibile creare il file estratto;
116 * * si č rilevato un errore nella copia dei dati (1);
117 * * non č stato possibile chiudere il file all'interno dell'oggetto zip (1);
118 *
119 * (1): prima di uscire dalla funzione cancella il file estratto.
120 */
121bool JlCompress::extractFile(QuaZip* zip, QString fileName, QString fileDest) {
122    // zip: oggetto dove aggiungere il file
123    // filename: nome del file reale
124    // fileincompress: nome del file all'interno del file compresso
125
126    // Controllo l'apertura dello zip
127    if (!zip) return false;
128    if (zip->getMode()!=QuaZip::mdUnzip) return false;
129
130    // Apro il file compresso
131    zip->setCurrentFile(fileName);
132    QuaZipFile inFile(zip);
133    if(!inFile.open(QIODevice::ReadOnly) || inFile.getZipError()!=UNZ_OK) return false;
134
135    // Controllo esistenza cartella file risultato
136    QDir().mkpath(QFileInfo(fileDest).absolutePath());
137
138    // Apro il file risultato
139    QFile outFile;
140    outFile.setFileName(fileDest);
141    if(!outFile.open(QIODevice::WriteOnly)) return false;
142
143    // Copio i dati
144    char c;
145    while(inFile.getChar(&c)) outFile.putChar(c);
146    if (inFile.getZipError()!=UNZ_OK) {
147        removeFile(QStringList(fileDest));
148        return false;
149    }
150
151    // Chiudo i file
152    inFile.close();
153    if (inFile.getZipError()!=UNZ_OK) {
154        removeFile(QStringList(fileDest));
155        return false;
156    }
157    outFile.close();
158
159    return true;
160}
161
162/**
163 * Rimuove i file il cui nome č specificato all'interno di listFile.
164 * Restituisce true se tutti i file sono stati cancellati correttamente, attenzione
165 * perchč puň restituire false anche se alcuni file non esistevano e si č tentato
166 * di cancellarli.
167 */
168bool JlCompress::removeFile(QStringList listFile) {
169    bool ret = true;
170    // Per ogni file
171    for (int i=0; i<listFile.count(); i++) {
172        // Lo elimino
173        ret = ret && QFile::remove(listFile.at(i));
174    }
175    return ret;
176}
177
178////////////////////////////////////////////////////////////////////////////////
179////////////////////////////////////////////////////////////////////////////////
180/**OK
181 * Comprime il file fileName nel file fileCompressed.
182 * Se la funzione fallisce restituisce false e cancella il file che si č tentato
183 * di creare.
184 *
185 * La funzione fallisce se:
186 * * non si riesce ad aprire l'oggetto zip;
187 * * la compressione del file fallisce;
188 * * non si riesce a chiudere l'oggetto zip;
189 */
190bool JlCompress::compressFile(QString fileCompressed, QString file) {
191    // Creo lo zip
192    QuaZip* zip  = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath());
193    QDir().mkpath(QFileInfo(fileCompressed).absolutePath());
194    if(!zip->open(QuaZip::mdCreate)) {
195        delete zip;
196        QFile::remove(fileCompressed);
197        return false;
198    }
199
200    // Aggiungo il file
201    if (!compressFile(zip,file,QFileInfo(file).fileName())) {
202        delete zip;
203        QFile::remove(fileCompressed);
204        return false;
205    }
206
207    // Chiudo il file zip
208    zip->close();
209    if(zip->getZipError()!=0) {
210        delete zip;
211        QFile::remove(fileCompressed);
212        return false;
213    }
214    delete zip;
215
216    return true;
217}
218
219/**OK
220 * Comprime i file specificati in files nel file fileCompressed.
221 * Se la funzione fallisce restituisce false e cancella il file che si č tentato
222 * di creare.
223 *
224 * La funzione fallisce se:
225 * * non si riesce ad aprire l'oggetto zip;
226 * * la compressione di un file fallisce;
227 * * non si riesce a chiudere l'oggetto zip;
228 */
229bool JlCompress::compressFiles(QString fileCompressed, QStringList files) {
230    // Creo lo zip
231    QuaZip* zip  = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath());
232    QDir().mkpath(QFileInfo(fileCompressed).absolutePath());
233    if(!zip->open(QuaZip::mdCreate)) {
234        delete zip;
235        QFile::remove(fileCompressed);
236        return false;
237    }
238
239    // Comprimo i file
240    QFileInfo info;
241    foreach (QString file, files) {
242        info.setFile(file);
243        if (!info.exists() || !compressFile(zip,file,info.fileName())) {
244            delete zip;
245            QFile::remove(fileCompressed);
246            return false;
247        }
248    }
249
250    // Chiudo il file zip
251    zip->close();
252    if(zip->getZipError()!=0) {
253        delete zip;
254        QFile::remove(fileCompressed);
255        return false;
256    }
257    delete zip;
258
259    return true;
260}
261
262/**OK
263 * Comprime la cartella dir nel file fileCompressed, se recursive č true allora
264 * comprime anche le sotto cartelle.
265 * Se la funzione fallisce restituisce false e cancella il file che si č tentato
266 * di creare.
267 *
268 * La funzione fallisce se:
269 * * non si riesce ad aprire l'oggetto zip;
270 * * la compressione di un file fallisce;
271 * * non si riesce a chiudere l'oggetto zip;
272 */
273bool JlCompress::compressDir(QString fileCompressed, QString dir, bool recursive) {
274    // Creo lo zip
275    QuaZip* zip  = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath());
276    QDir().mkpath(QFileInfo(fileCompressed).absolutePath());
277    if(!zip->open(QuaZip::mdCreate)) {
278        delete zip;
279        QFile::remove(fileCompressed);
280        return false;
281    }
282
283    // Aggiungo i file e le sotto cartelle
284    if (!compressSubDir(zip,dir,dir,recursive)<0) {
285        delete zip;
286        QFile::remove(fileCompressed);
287        return false;
288    }
289
290    // Chiudo il file zip
291    zip->close();
292    if(zip->getZipError()!=0) {
293        delete zip;
294        QFile::remove(fileCompressed);
295        return false;
296    }
297    delete zip;
298
299    return true;
300}
301
302////////////////////////////////////////////////////////////////////////////////
303////////////////////////////////////////////////////////////////////////////////
304/**OK
305 * Estrae il file fileName, contenuto nel file fileCompressed, con il nome fileDest.
306 * Se fileDest = "" allora il file viene estratto con lo stesso nome con cui č
307 * stato compresso.
308 * Se la funzione fallisce cancella il file che si č tentato di estrarre.
309 * Restituisce il nome assoluto del file estratto.
310 *
311 * La funzione fallisce se:
312 * * non si riesce ad aprire l'oggetto zip;
313 * * l'estrazione del file fallisce;
314 * * non si riesce a chiudere l'oggetto zip;
315 */
316QString JlCompress::extractFile(QString fileCompressed, QString fileName, QString fileDest) {
317    // Apro lo zip
318    QuaZip* zip  = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath());
319    if(!zip->open(QuaZip::mdUnzip)) {
320        delete zip;
321        return QString();
322    }
323
324    // Estraggo il file
325    if (fileDest.isEmpty()) fileDest = fileName;
326    if (!extractFile(zip,fileName,fileDest)) {
327        delete zip;
328        return QString();
329    }
330
331    // Chiudo il file zip
332    zip->close();
333    if(zip->getZipError()!=0) {
334        removeFile(QStringList(fileDest));
335        return QString();
336    }
337    delete zip;
338
339    return QFileInfo(fileDest).absoluteFilePath();
340}
341
342/**OK
343 * Estrae i file specificati in files, contenuti nel file fileCompressed, nella
344 * cartella dir. La struttura a cartelle del file compresso viene rispettata.
345 * Se dir = "" allora il file viene estratto nella cartella corrente.
346 * Se la funzione fallisce cancella i file che si č tentato di estrarre.
347 * Restituisce i nomi assoluti dei file estratti.
348 *
349 * La funzione fallisce se:
350 * * non si riesce ad aprire l'oggetto zip;
351 * * l'estrazione di un file fallisce;
352 * * non si riesce a chiudere l'oggetto zip;
353 */
354QStringList JlCompress::extractFiles(QString fileCompressed, QStringList files, QString dir) {
355    // Creo lo zip
356    QuaZip* zip  = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath());
357    if(!zip->open(QuaZip::mdUnzip)) {
358        delete zip;
359        return QStringList();
360    }
361
362    // Estraggo i file
363    for (int i=0; i<files.count(); i++) {
364        if (!extractFile(zip, files.at(i), QDir(dir).absoluteFilePath(files.at(i)))) {
365            delete zip;
366            removeFile(files);
367            return QStringList();
368        }
369        files[i] = QDir(dir).absoluteFilePath(files.at(i));
370    }
371
372    // Chiudo il file zip
373    zip->close();
374    if(zip->getZipError()!=0) {
375        delete zip;
376        removeFile(files);
377        return QStringList();
378    }
379    delete zip;
380
381    return files;
382}
383
384/**OK
385 * Estrae il file fileCompressed nella cartella dir.
386 * Se dir = "" allora il file viene estratto nella cartella corrente.
387 * Se la funzione fallisce cancella i file che si č tentato di estrarre.
388 * Restituisce i nomi assoluti dei file estratti.
389 *
390 * La funzione fallisce se:
391 * * non si riesce ad aprire l'oggetto zip;
392 * * la compressione di un file fallisce;
393 * * non si riesce a chiudere l'oggetto zip;
394 */
395QStringList JlCompress::extractDir(QString fileCompressed, QString dir) {
396    // Apro lo zip
397    QuaZip* zip = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath());
398    if(!zip->open(QuaZip::mdUnzip)) {
399        delete zip;
400        return QStringList();
401    }
402
403    // Estraggo i file
404    QStringList lst = getFileList(fileCompressed);
405
406    QDir directory(dir);
407    for (int i=0; i<lst.count(); i++) {
408        QString absFilePath = directory.absoluteFilePath(lst.at(i));
409        if (!extractFile(zip, lst.at(i), absFilePath)) {
410            delete zip;
411            removeFile(lst);
412            return QStringList();
413        }
414        lst[i] = absFilePath;
415    }
416
417    // Chiudo il file zip
418    zip->close();
419    if(zip->getZipError()!=0) {
420        delete zip;
421        removeFile(lst);
422        return QStringList();
423    }
424    delete zip;
425
426    return lst;
427}
428
429/**OK
430 * Restituisce la lista dei file resenti nel file compresso fileCompressed.
431 * Se la funzione fallisce, restituisce un elenco vuoto.
432 *
433 * La funzione fallisce se:
434 * * non si riesce ad aprire l'oggetto zip;
435 * * la richiesta di informazioni di un file fallisce;
436 * * non si riesce a chiudere l'oggetto zip;
437 */
438QStringList JlCompress::getFileList(QString fileCompressed) {
439    // Apro lo zip
440    QuaZip* zip = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath());
441    if(!zip->open(QuaZip::mdUnzip)) {
442        delete zip;
443        return QStringList();
444    }
445
446    // Estraggo i nomi dei file
447    QStringList lst;
448    QuaZipFileInfo info;
449    for(bool more=zip->goToFirstFile(); more; more=zip->goToNextFile()) {
450      if(!zip->getCurrentFileInfo(&info)) {
451          delete zip;
452          return QStringList();
453      }
454      lst << info.name;
455      //info.name.toLocal8Bit().constData()
456    }
457
458    // Chiudo il file zip
459    zip->close();
460    if(zip->getZipError()!=0) {
461        delete zip;
462        return QStringList();
463    }
464    delete zip;
465
466    return lst;
467}
468