qminizip.cpp
Go to the documentation of this file.
00001 
00047 #include "re_object_recorder/qminizip.h"
00048 
00049 #include "minizip/zip.h"
00050 #include "minizip/unzip.h"
00051 #include <stdexcept>
00052 
00053 #include <QDateTime>
00054 #include <QDebug>
00055 #include <QDir>
00056 
00057 QMiniZip::QMiniZip(QString zipfile_, OpenMode mode_) : zipFileInfo(zipfile_), mode(mode_) {
00058     if (mode == ZIP_CREATE /*|| mode == ZIP_APPEND*/) {
00059 //        qDebug() << "creating zip file" << (int)(mode == ZIP_APPEND);
00060         zf = zipOpen64(qPrintable(zipfile_), mode == ZIP_APPEND);
00061         if (zf == NULL)
00062             throw std::runtime_error("could not open zip file");
00063     }
00064     else if (mode == UNZIP) {
00065         uf = unzOpen64(qPrintable(zipfile_));
00066     }
00067     else
00068         throw std::logic_error("not implemented yet");
00069 }
00070 
00071 QMiniZip::~QMiniZip() {
00072     if (mode == ZIP_APPEND || mode == ZIP_CREATE)
00073         zipClose(zf, NULL);
00074     else if (mode == UNZIP)
00075         unzClose(uf);
00076     else
00077         throw std::logic_error("unknown mode in destructor");
00078 }
00079 
00080 void QMiniZip::addFile(const QFileInfo& fileInfo, const QString& nameInZip) {
00081     if (mode != ZIP_CREATE && mode != ZIP_APPEND) {
00082         throw std::logic_error("cannot add to zip file that was opened in UNZIP mode");
00083     }
00084 
00085     zip_fileinfo zi;
00086     zi.dosDate = 0;
00087     zi.internal_fa = 0;
00088     zi.external_fa = 0;
00089 
00090     QDateTime lastModified = fileInfo.lastModified();
00091     zi.tmz_date.tm_hour = lastModified.time().hour();
00092     zi.tmz_date.tm_min = lastModified.time().minute();
00093     zi.tmz_date.tm_sec = lastModified.time().second();
00094     zi.tmz_date.tm_mday = lastModified.date().day();
00095     zi.tmz_date.tm_mon = lastModified.date().month() - 1;
00096     zi.tmz_date.tm_year = lastModified.date().year();
00097 
00098     QString niz = nameInZip.isEmpty() ? fileInfo.fileName() : nameInZip;
00099     int opt_compress_level = Z_DEFAULT_COMPRESSION;
00100     int err = zipOpenNewFileInZip3_64(zf, qPrintable(niz), &zi,
00101                                       NULL,0,NULL,0,NULL,
00102                                       (opt_compress_level != 0) ? Z_DEFLATED : 0,
00103                                       opt_compress_level,0,
00104                                       -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
00105                                       NULL, 0, 1);
00106     if (err != ZIP_OK)
00107     {
00108         throw std::runtime_error("could not create file in zip");
00109     }
00110 
00111     const size_t WRITE_BUFFER_SIZE = 16384;
00112     char *buf = new char[WRITE_BUFFER_SIZE];
00113     FILE *fin = fopen64(qPrintable(fileInfo.absoluteFilePath()), "rb");
00114     int size_read;
00115     do {
00116         size_read = fread(buf, 1, WRITE_BUFFER_SIZE, fin);
00117 
00118         if (size_read > 0)
00119             err = zipWriteInFileInZip(zf, buf, size_read);
00120     } while ((err == ZIP_OK) && (size_read > 0));
00121 
00122     if (err != ZIP_OK) {
00123         throw std::runtime_error("error reading input file");
00124     }
00125 
00126     fclose(fin);
00127     err = zipCloseFileInZip(zf);
00128     if (err != ZIP_OK) {
00129         throw std::runtime_error("error closing newly created file in zip");
00130     }
00131     delete [] buf;
00132 }
00133 
00134 QStringList QMiniZip::unzip(QDir target_path) {
00135     QStringList result;
00136     unz_global_info64 gi;
00137     int err;
00138 
00139     unzGoToFirstFile(uf);
00140 
00141     err = unzGetGlobalInfo64(uf, &gi);
00142     if (err!=UNZ_OK) {
00143         qDebug() << "error with zipfile in unzGetGlobalInfo";
00144     }
00145 
00146 //    qDebug() << "number of entries: " << gi.number_entry;
00147 
00148     for (size_t i=0; i<gi.number_entry; i++)
00149     {
00150         QString extracted_file = do_extract_currentfile(target_path);
00151         if (extracted_file.isEmpty())
00152             break;
00153         result.append(extracted_file);
00154 
00155         if ((i+1)<gi.number_entry)
00156         {
00157             err = unzGoToNextFile(uf);
00158             if (err!=UNZ_OK)
00159             {
00160                 printf("error %d with zipfile in unzGoToNextFile\n",err);
00161                 break;
00162             }
00163         }
00164     }
00165     return result;
00166 }
00167 
00168 QString QMiniZip::do_extract_currentfile(const QDir& target_dir) {
00169     char filename_inzip[256];
00170     unz_file_info64 file_info;
00171     int err;
00172     //        uLong ratio=0;
00173     err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
00174     if (err != UNZ_OK)
00175         throw std::runtime_error("error during unzGetCurrentFileInfo");
00176 
00177     const size_t WRITE_BUFFER_SIZE = 16384;
00178     char *buf = new char[WRITE_BUFFER_SIZE];
00179 
00180     QString filename_inzip_qstr(filename_inzip);
00181     QString path = filename_inzip_qstr.left(filename_inzip_qstr.lastIndexOf("/"));
00182     if (!path.isEmpty() && path != filename_inzip_qstr) {
00183         QFileInfo p(target_dir.filePath(path));
00184         if (!p.exists()) {
00185             //                qDebug() << "creating path " << path;
00186             target_dir.mkpath(path);
00187         }
00188     }
00189 
00190     err = unzOpenCurrentFilePassword(uf,NULL);
00191     if (err!=UNZ_OK)
00192     {
00193         printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err);
00194     }
00195 
00196     QString resulting_filename(target_dir.filePath(filename_inzip_qstr));
00197 
00198     FILE *fout;
00199     fout=fopen64(qPrintable(resulting_filename),"wb");
00200     do
00201     {
00202         err = unzReadCurrentFile(uf, buf, WRITE_BUFFER_SIZE);
00203         if (err<0)
00204         {
00205             printf("error %d with zipfile in unzReadCurrentFile\n",err);
00206             break;
00207         }
00208         if (err>0)
00209             if (fwrite(buf,err,1,fout)!=1)
00210             {
00211                 printf("error in writing extracted file\n");
00212                 err=UNZ_ERRNO;
00213                 break;
00214             }
00215     } while (err>0);
00216     if (fout)
00217         fclose(fout);
00218 
00219     if (err==UNZ_OK)
00220     {
00221         err = unzCloseCurrentFile (uf);
00222     }
00223 
00224 
00225     delete [] buf;
00226     return resulting_filename;
00227 }
00228 
00229 QByteArray QMiniZip::getFile(const QString& filename) {
00230     unz_file_info64 file_info;
00231     QByteArray result;
00232     char filename_inzip[256];
00233 
00234     unz_global_info64 gi;
00235     int err;
00236 
00237     unzGoToFirstFile(uf);
00238 
00239     err = unzGetGlobalInfo64(uf, &gi);
00240     if (err!=UNZ_OK) {
00241         qDebug() << "error with zipfile in unzGetGlobalInfo";
00242     }
00243 
00244     for (size_t i=0; i<gi.number_entry; i++)
00245     {
00246         err = unzGoToNextFile(uf);
00247         if (err != UNZ_OK) {
00248             return result;
00249         }
00250         err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
00251         err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
00252         if (err != UNZ_OK)
00253             return result;
00254         QString fn(filename_inzip);
00255         if (fn.endsWith(filename)) {
00256             break;
00257         }
00258     }
00259 
00260     const size_t WRITE_BUFFER_SIZE = 16384;
00261     static char buf[WRITE_BUFFER_SIZE];
00262 
00263     err = unzOpenCurrentFilePassword(uf, NULL);
00264     if (err!=UNZ_OK) {
00265         printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err);
00266     }
00267 
00268     do {
00269         err = unzReadCurrentFile(uf, buf, WRITE_BUFFER_SIZE);
00270         if (err<0) {
00271             printf("error %d with zipfile in unzReadCurrentFile\n",err);
00272             break;
00273         }
00274         if (err>0) {
00275             result.append(buf, err);
00276         }
00277     } while (err>0);
00278     if (err==UNZ_OK) {
00279         err = unzCloseCurrentFile (uf);
00280     }
00281 
00282     return result;
00283 }
00284 
00285 QStringList QMiniZip::getContents() {
00286     QStringList result;
00287     unz_global_info64 gi;
00288     int err;
00289 
00290     unzGoToFirstFile(uf);
00291 
00292     err = unzGetGlobalInfo64(uf, &gi);
00293 //    if (err!=UNZ_OK)
00294 //        printf("error %d with zipfile in unzGetGlobalInfo \n", err);
00295 
00296     for (uLong i=0;i<gi.number_entry;i++) {
00297         char filename_inzip[256];
00298         unz_file_info64 file_info;
00299         err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
00300         if (err!=UNZ_OK)
00301         {
00302 //            printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
00303             break;
00304         }
00305         result.append(QString::fromLocal8Bit(filename_inzip));
00306 
00307         if ((i+1)<gi.number_entry)
00308         {
00309             err = unzGoToNextFile(uf);
00310             if (err!=UNZ_OK)
00311             {
00312                 printf("error %d with zipfile in unzGoToNextFile\n",err);
00313                 break;
00314             }
00315         }
00316     }
00317 
00318     return result;
00319 }


re_object_recorder
Author(s): Andreas Koch
autogenerated on Sun Jan 5 2014 11:39:12