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

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