// TJP COPYRIGHT HEADER #include "Decompress.h" #include #include #include "../endian/Endian.h" #include "../file/File.h" #include #include #include "../file/Path.h" #include #include #include "minizip/ioapi.h" #ifdef WIN32 #include "minizip/iowin32.h" #endif using namespace tjp; using namespace core; using namespace core::zip; #include "minizip/unzip.h" void extractFile( unzFile uf, const char *password, const std::string &basedirectory, std::string &relativefilename ) { unz_file_info file_info; char filename_inzip[256]; int err; err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0); if (err!=UNZ_OK) { throw zip::Exception ("unzGetCurrentFileInfo"); } relativefilename = filename_inzip; std::string filename = basedirectory + file::convertDelimiter (relativefilename); file::ensurePath (filename); const int size_buf = 16384; char *buf = new char [size_buf]; try { std::ofstream outfile (filename.c_str(), std::ios::binary); if (unzOpenCurrentFilePassword(uf,password)!=UNZ_OK) { throw zip::Exception ("unzOpenCurrentFilePassword"); } int len; do { len = unzReadCurrentFile(uf,buf,size_buf); if (len<0) { throw zip::Exception("unzReadCurrentFile"); } else if (len>0) { if (!outfile.write (buf, len)) { throw zip::Exception("error in writing extracted file\n"); } } } while (len>0); } catch (zip::Exception &e) { file::deleteFile(filename); unzCloseCurrentFile (uf); delete[] buf; throw e; } delete[] buf; // change_file_date(filename,file_info.dosDate, // file_info.tmu_date); err = unzCloseCurrentFile (uf); if (err!=UNZ_OK) { throw zip::Exception("error %d with zipfile in unzCloseCurrentFile"); } } void extractZip( unzFile uf, const char* password, const std::string &basedirectory, std::list &list ) { uLong i; unz_global_info gi; int err; err = unzGetGlobalInfo (uf,&gi); if (err!=UNZ_OK) throw zip::Exception("unzGetGlobalInfo"); for (i=0;i &files) { #ifdef WIN32 zlib_filefunc_def ffunc; #endif char filename_try[256+1]; strncpy(filename_try, file.c_str(),256-1); /* strncpy doesnt append the trailing NULL, if the string is too long. */ filename_try[256] = '\0'; #ifdef WIN32 fill_win32_filefunc(&ffunc); unzFile uf = unzOpen2(filename_try,&ffunc); #else unzFile uf = unzOpen(filename_try); #endif if (uf==NULL) { throw zip::Exception ("unzOpen"); } try { extractZip (uf,NULL, path, files); } catch (zip::Exception &) { unzCloseCurrentFile(uf); throw; } unzCloseCurrentFile(uf); } void zip::decompress (const std::string &from, const std::string &to) { gzFile gz = gzopen (from.c_str(), "rb"); if (gz == NULL) throw zip::Exception ("gzopen"); int size_buf = 16384; char *buf = new char[16384]; try { file::ensurePath (to); std::ofstream outfile (to.c_str(), std::ios::binary); int read = 0; while ( (read = gzread (gz, buf, size_buf) > 0) && outfile) { outfile.write (buf, read); } if (read < 0 && !outfile) { throw zip::Exception ("gzread"); } } catch (zip::Exception &e) { delete[] buf; file::deleteFile (to); throw e; } } typedef unsigned int Header; bool zip::decompress (const char *in, int insize, char *&out, int &outsize) { const char *block = in; const Header *header = (const Header *)block; const char *data = block + sizeof (Header); endian::swap (*header); uLongf ulInSize = insize - sizeof (Header); uLongf ulOutSize = *header; char *uncompressed = new char[ulOutSize]; int error = ::uncompress((Bytef *)uncompressed, &ulOutSize, (const Bytef*)data, ulInSize); if (error!=Z_OK) { delete[] uncompressed; return false; } out = uncompressed; outsize = (int)ulOutSize; return true; } bool zip::decompress (const char *in, int insize, std::vector &out) { const char *block = in; const Header *header = (const Header *)block; const char *data = block + sizeof (Header); endian::swap (*header); uLongf ulInSize = insize - sizeof (Header); uLongf ulOutSize = *header; out.resize(ulOutSize); char *uncompressed = out.data(); int error = ::uncompress((Bytef *)uncompressed, &ulOutSize, (const Bytef*)data, ulInSize); if (error!=Z_OK) { delete[] uncompressed; return false; } return true; } std::vector zip::decompress (const char *in, int insize) { std::vector out; zip::decompress(in, insize, out); return out; }