flatten 20260225
This commit is contained in:
276
tjp/core/zip/Decompress.cpp
Executable file
276
tjp/core/zip/Decompress.cpp
Executable file
@@ -0,0 +1,276 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
|
||||
#include "Decompress.h"
|
||||
#include <assert.h>
|
||||
#include <list>
|
||||
#include "../endian/Endian.h"
|
||||
#include "../file/File.h"
|
||||
#include <fstream>
|
||||
|
||||
#include <tjp/core/log/Log.h>
|
||||
#include "../file/Path.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <zlib/zlib.h>
|
||||
|
||||
#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<std::string> &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<gi.number_entry;i++)
|
||||
{
|
||||
std::string filename;
|
||||
extractFile(uf, password, basedirectory, filename);
|
||||
list.push_back(filename);
|
||||
|
||||
if ((i+1)<gi.number_entry)
|
||||
{
|
||||
err = unzGoToNextFile(uf);
|
||||
|
||||
if (err!=UNZ_OK)
|
||||
throw zip::Exception ("unzGoToNextFile");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void extractOneFile(
|
||||
unzFile uf,
|
||||
const std::string &filename,
|
||||
const char* password,
|
||||
const std::string &basedirectory
|
||||
)
|
||||
{
|
||||
if (unzLocateFile(uf,filename.c_str(),false)!=UNZ_OK)
|
||||
throw zip::Exception ("unzLocateFile");
|
||||
|
||||
std::string dummyfilename;
|
||||
extractFile(uf,password,basedirectory,dummyfilename);
|
||||
}
|
||||
|
||||
void zip::decompress (const std::string &file, const std::string &path, std::list<std::string> &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<char> &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<char> zip::decompress (const char *in, int insize)
|
||||
{
|
||||
std::vector<char> out;
|
||||
zip::decompress(in, insize, out);
|
||||
|
||||
return out;
|
||||
}
|
||||
Reference in New Issue
Block a user