Refactoring + tests

Add new class CunzFileWrapped,
Add tests for:
- IsArchive
- IsFileExistInArchive
- LoadFileFromArchive
This commit is contained in:
Alexey
2023-07-21 22:20:31 +03:00
parent 739a1d2a35
commit 1db7a6ae2a
5 changed files with 220 additions and 67 deletions

View File

@ -64,7 +64,6 @@ HRESULT COfficeUtils::ExtractToDirectory(BYTE* data, size_t len, const std::wstr
#if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64)
std::wstring unzipDir = CorrectPathW(_unzipDir);
#else
std::wstring zipFile = _zipFile;
std::wstring unzipDir = _unzipDir;
#endif
@ -157,6 +156,18 @@ HRESULT COfficeUtils::IsArchive(const std::wstring& _filename)
}
}
HRESULT COfficeUtils::IsArchive(BYTE* data, size_t len)
{
if( ZLibZipUtils::IsArchive(data, len) )
{
return S_OK;
}
else
{
return S_FALSE;
}
}
HRESULT COfficeUtils::IsFileExistInArchive(const std::wstring& _zipFile, const std::wstring& filePath)
{
#if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64)
@ -175,6 +186,18 @@ HRESULT COfficeUtils::IsFileExistInArchive(const std::wstring& _zipFile, const s
}
}
HRESULT COfficeUtils::IsFileExistInArchive(BYTE* data, size_t len, const std::wstring& filePath)
{
if( ZLibZipUtils::IsFileExistInArchive( data, len, filePath.c_str()) )
{
return S_OK;
}
else
{
return S_FALSE;
}
}
HRESULT COfficeUtils::LoadFileFromArchive(const std::wstring& _zipFile, const std::wstring& filePath, BYTE** fileInBytes, ULONG& nFileSize)
{
#if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64)
@ -193,6 +216,18 @@ HRESULT COfficeUtils::LoadFileFromArchive(const std::wstring& _zipFile, const st
}
}
HRESULT COfficeUtils::LoadFileFromArchive(BYTE* data, size_t len, const std::wstring& filePath, BYTE** fileInBytes, ULONG& nFileSize)
{
if( ZLibZipUtils::LoadFileFromArchive( data, len, filePath.c_str(), fileInBytes, nFileSize))
{
return S_OK;
}
else
{
return S_FALSE;
}
}
HRESULT COfficeUtils::ExtractFilesToMemory(const std::wstring& _zipFile, const ExtractedFileCallback& data_receiver, void* pParam, bool* result)
{
#if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64)

View File

@ -52,14 +52,21 @@ public:
HRESULT ExtractToDirectory (const std::wstring& zipFile, const std::wstring& unzipDir, wchar_t* password, short extract_without_path);
HRESULT ExtractToDirectory (BYTE* data, size_t len, const std::wstring& unzipDir, wchar_t* password, short extract_without_path);
HRESULT CompressFileOrDirectory (const std::wstring& name, const std::wstring& outputFile, bool bSorted = false, int method = Z_DEFLATED, short level = -1, bool bDateTime = false);
HRESULT Uncompress (BYTE* destBuf, ULONG* destSize, BYTE* sourceBuf, ULONG sourceSize);
HRESULT Compress (BYTE* destBuf, ULONG* destSize, BYTE* sourceBuf, ULONG sourceSize, short level = -1);
HRESULT IsArchive (const std::wstring& filename);
HRESULT IsArchive (BYTE* data, size_t len);
HRESULT IsFileExistInArchive (const std::wstring& zipFile, const std::wstring& filePath);
HRESULT IsFileExistInArchive (BYTE* data, size_t len, const std::wstring& filePath);
HRESULT LoadFileFromArchive (const std::wstring& zipFile, const std::wstring& filePath, BYTE** fileInBytes, ULONG& nFileSize);
HRESULT LoadFileFromArchive (BYTE* data, size_t len, const std::wstring& filePath, BYTE** fileInBytes, ULONG& nFileSize);
HRESULT ExtractFilesToMemory (const std::wstring& zipFile, const ExtractedFileCallback& data_receiver, void* pParam, bool* result);
HRESULT CompressFilesFromMemory (const std::wstring& zipFile, const RequestFileCallback& data_source, void* pParam, short compression_level, bool* result);
HRESULT GetFilesSize (const std::wstring& zipFile, const std::wstring& searchPattern, ULONG64& nCommpressed, ULONG64& nUncommpressed);

View File

@ -43,8 +43,86 @@
#define WRITEBUFFERSIZE 8192
#define READBUFFERSIZE 8192
unzFile unzOpenHelp(const wchar_t* filename);
namespace ZLibZipUtils
{
// internal class for C unzFile struct
class CunzFileWrapped
{
public:
CunzFileWrapped() = default;
~CunzFileWrapped();
// NOTE: calls Close() first
void Open(const wchar_t* filename);
// NOTE: calls Close() first
void Open(BYTE* data, size_t len);
int Close();
// NOTE: unzfile will be released after Close() or ~CunzFileWrapped()!
// return value will be NULL, if Open(...) fails
unzFile Get();
private:
unzFile m_unzFile {NULL};
BUFFER_IO* m_buffer {NULL};
};
CunzFileWrapped::~CunzFileWrapped()
{
Close();
}
void CunzFileWrapped::Open(const wchar_t* filename)
{
Close();
if(filename != NULL)
{
int old = zlip_get_addition_flag();
zlip_set_addition_flag(old | ZLIB_ADDON_FLAG_READ_ONLY);
m_unzFile = unzOpenHelp(filename);
zlip_set_addition_flag(old);
}
}
void CunzFileWrapped::Open(BYTE* data, size_t len)
{
Close();
m_buffer = new BUFFER_IO;
if ((data != NULL) && (len != 0))
{
int old = zlip_get_addition_flag();
zlip_set_addition_flag(old | ZLIB_ADDON_FLAG_READ_ONLY);
m_buffer->buffer = data;
m_buffer->nSize = len;
zlib_filefunc_def ffunc;
fill_buffer_filefunc(&ffunc, m_buffer);
m_unzFile = unzOpen2(NULL, &ffunc);
zlip_set_addition_flag(old);
}
}
int CunzFileWrapped::Close()
{
int err = 0;
if(m_unzFile)
err = unzClose(m_unzFile);
m_unzFile = NULL;
RELEASEOBJECT(m_buffer)
return err;
}
unzFile CunzFileWrapped::Get()
{
return m_unzFile;
}
#ifndef _IOS
zipFile zipOpenHelp(const wchar_t* filename)
{
@ -722,15 +800,13 @@ namespace ZLibZipUtils
int UnzipToDir( const WCHAR* zipFile, const WCHAR* unzipDir, const OnProgressCallback* progress, const WCHAR* password, bool opt_extract_without_path, bool clearOutputDirectory )
{
unzFile uf = NULL;
if ( ( zipFile != NULL ) )
{
int old = zlip_get_addition_flag();
zlip_set_addition_flag(old | ZLIB_ADDON_FLAG_READ_ONLY);
uf = unzOpenHelp (zipFile);
zlip_set_addition_flag(old);
}
int err = UnzipToDir(uf, unzipDir, progress, password, opt_extract_without_path, clearOutputDirectory);
CunzFileWrapped ufw;
ufw.Open(zipFile);
int err = UnzipToDir(ufw.Get(), unzipDir, progress, password, opt_extract_without_path, clearOutputDirectory);
// call Close() instead ~...() because of error code
if(err == UNZ_OK)
err = ufw.Close();
return err;
}
@ -738,27 +814,18 @@ namespace ZLibZipUtils
int UnzipToDir(BYTE* data, size_t len, const WCHAR* unzipDir, const OnProgressCallback* progress, const WCHAR* password, bool opt_extract_without_path, bool clearOutputDirectory )
{
unzFile uf = NULL;
BUFFER_IO* buf = new BUFFER_IO;
if ( ( data != NULL ) && ( len != 0 ) )
{
int old = zlip_get_addition_flag();
zlip_set_addition_flag(old | ZLIB_ADDON_FLAG_READ_ONLY);
CunzFileWrapped ufw;
ufw.Open(data, len);
int err = UnzipToDir(ufw.Get(), unzipDir, progress, password, opt_extract_without_path, clearOutputDirectory);
buf->buffer = data;
buf->nSize = len;
zlib_filefunc_def ffunc;
fill_buffer_filefunc(&ffunc, buf);
uf = unzOpen2(NULL, &ffunc);
zlip_set_addition_flag(old);
}
int err = UnzipToDir(uf, unzipDir, progress, password, opt_extract_without_path, clearOutputDirectory);
RELEASEOBJECT(buf);
// call Close() instead ~...() because of error code
if(err == UNZ_OK)
err = ufw.Close();
return err;
}
/*========================================================================================================*/
int UnzipToDir(unzFile uf, const WCHAR* unzipDir, const OnProgressCallback* progress, const WCHAR* password, bool opt_extract_without_path, bool clearOutputDirectory )
{
int err = -1;
@ -782,11 +849,6 @@ namespace ZLibZipUtils
else
err = do_extract( uf, unzipDir, opt_extract_without_path, 1, NULL, progress );
}
if ( err == UNZ_OK )
{
err = unzClose( uf );
}
}
return err;
}
@ -817,56 +879,62 @@ namespace ZLibZipUtils
bool IsArchive(const WCHAR* filename)
{
unzFile uf = NULL;
bool isZIP = false;
CunzFileWrapped ufw;
ufw.Open(filename);
return ufw.Get() != NULL;
}
if (( filename != NULL ))
uf = unzOpenHelp( filename );
/*========================================================================================================*/
if ( uf != NULL )
{
isZIP = true;
unzClose( uf );
}
return isZIP;
bool IsArchive(BYTE* data, size_t len)
{
CunzFileWrapped ufw;
ufw.Open(data, len);
return ufw.Get() != NULL;
}
/*========================================================================================================*/
bool IsFileExistInArchive(const WCHAR* zipFile, const WCHAR* filePathInZip)
{
unzFile uf = NULL;
bool isIn = false;
CunzFileWrapped ufw;
ufw.Open(zipFile);
unzFile uf = ufw.Get();
if ( ( zipFile != NULL ) && ( filePathInZip != NULL ) )
uf = unzOpenHelp( zipFile );
if ( uf != NULL )
{
isIn = is_file_in_archive( uf, filePathInZip );
unzClose( uf );
}
return filePathInZip != NULL && uf != NULL && is_file_in_archive(uf, filePathInZip);
}
return isIn;
/*========================================================================================================*/
bool IsFileExistInArchive(BYTE* data, size_t len, const WCHAR* filePathInZip)
{
CunzFileWrapped ufw;
ufw.Open(data, len);
unzFile uf = ufw.Get();
return filePathInZip != NULL && uf != NULL && is_file_in_archive(uf, filePathInZip);
}
/*========================================================================================================*/
bool LoadFileFromArchive(const WCHAR* zipFile, const WCHAR* filePathInZip, BYTE** fileInBytes, ULONG& nFileSize)
{
unzFile uf = NULL;
bool isIn = false;
CunzFileWrapped ufw;
ufw.Open(zipFile);
unzFile uf = ufw.Get();
if ( ( zipFile != NULL ) && ( filePathInZip != NULL ) )
uf = unzOpenHelp( zipFile );
return filePathInZip != NULL && uf != NULL && get_file_in_archive( uf, filePathInZip, fileInBytes, nFileSize);
}
if ( uf != NULL )
{
isIn = get_file_in_archive( uf, filePathInZip, fileInBytes, nFileSize);
unzClose( uf );
}
/*========================================================================================================*/
return isIn;
bool LoadFileFromArchive(BYTE* data, size_t len, const WCHAR* filePathInZip, BYTE** fileInBytes, ULONG& nFileSize)
{
CunzFileWrapped ufw;
ufw.Open(data, len);
unzFile uf = ufw.Get();
return filePathInZip != NULL && uf != NULL && get_file_in_archive( uf, filePathInZip, fileInBytes, nFileSize);
}
/*========================================================================================================*/

View File

@ -57,21 +57,30 @@ using namespace std;
namespace ZLibZipUtils
{
zipFile zipOpenHelp(const wchar_t* filename);
unzFile unzOpenHelp(const wchar_t* filename);
int ZipDir( const WCHAR* dir, const WCHAR* outputFile, const OnProgressCallback* progress, bool sorted = false, int method = Z_DEFLATED, int compressionLevel = -1, bool bDateTime = false);
int ZipFile( const WCHAR* inputFile, const WCHAR* outputFile, int method = Z_DEFLATED, int compressionLevel = -1, bool bDateTime = false );
bool ClearDirectory( const WCHAR* dir, bool delDir = false );
int UnzipToDir( unzFile uf, const WCHAR* unzipDir, const OnProgressCallback* progress, const WCHAR* password, bool opt_extract_without_path, bool clearOutputDirectory );
int UnzipToDir( const WCHAR* zipFile, const WCHAR* unzipDir, const OnProgressCallback* progress, const WCHAR* password = NULL, bool opt_extract_without_path = false, bool clearOutputDirectory = false );
int UnzipToDir( BYTE* data, size_t len, const WCHAR* unzipDir, const OnProgressCallback* progress, const WCHAR* password = NULL, bool opt_extract_without_path = false, bool clearOutputDirectory = false );
int UncompressBytes( BYTE* destBuf, ULONG* destSize, const BYTE* sourceBuf, ULONG sourceSize );
int CompressBytes( BYTE* destBuf, ULONG* destSize, const BYTE* sourceBuf, ULONG sourceSize, SHORT level );
bool IsArchive(const WCHAR* filename);
bool IsArchive(BYTE* data, size_t len);
bool IsFileExistInArchive(const WCHAR* zipFile, const WCHAR* filePathInZip);
bool IsFileExistInArchive(BYTE* data, size_t len, const WCHAR* filePathInZip);
bool LoadFileFromArchive(const WCHAR* zipFile, const WCHAR* filePathInZip, BYTE** fileInBytes, ULONG& nFileSize);
bool LoadFileFromArchive(BYTE* data, size_t len, const WCHAR* filePathInZip, BYTE** fileInBytes, ULONG& nFileSize);
bool ExtractFiles(const WCHAR* zip_file_path, const ExtractedFileCallback& callback, void* pParam);
bool CompressFiles(const WCHAR* zip_file_path, const RequestFileCallback& callback, void* pParam, int compression_level);
bool GetFilesSize(const WCHAR* zip_file_path, const std::wstring& searchPattern, ULONG64& nCommpressed, ULONG64& nUncommpressed);

View File

@ -181,9 +181,8 @@ TEST_F(COfficeUtilsTest, general_win_mem)
NSFile::CFileBinary::ReadAllBytes(zip_path, &bytes, len);
HRESULT error_code = utils.ExtractToDirectory(bytes, len, unzip_folder, NULL, false);
ASSERT_EQ(error_code, S_OK);
delete[] bytes;
ASSERT_EQ(error_code, S_OK);
std::vector<std::wstring> unzip_files = NSDirectory::GetFiles(unzip_folder, true);
std::vector<std::wstring> actual;
@ -277,9 +276,8 @@ TEST_F(COfficeUtilsTest, general_linux_mem)
NSFile::CFileBinary::ReadAllBytes(zip_path, &bytes, len);
HRESULT error_code = utils.ExtractToDirectory(bytes, len, unzip_folder, NULL, false);
ASSERT_EQ(error_code, S_OK);
delete[] bytes;
ASSERT_EQ(error_code, S_OK);
std::vector<std::wstring> unzip_files = NSDirectory::GetFiles(unzip_folder, true);
std::vector<std::wstring> actual;
@ -429,6 +427,42 @@ TEST_F(COfficeUtilsTest, docx_like_linux)
EXPECT_TRUE(IsFilesPathsEqual(actual, expected_docx_like));
}
TEST_F(COfficeUtilsTest, other_win)
{
std::wstring zip_filename = L"general_win";
std::wstring zip_path = zipDirectory + wsep + zip_filename;
// IsArchive(...)
HRESULT error_code = utils.IsArchive(zip_path);
EXPECT_EQ(error_code, S_OK);
size_t len = 100;
BYTE* data = new BYTE[len];
error_code = utils.IsArchive(data, len);
delete [] data;
EXPECT_EQ(error_code, S_FALSE);
// IsFileExistInArchive(...)
error_code = utils.IsFileExistInArchive(zip_path, L"2.txt");
EXPECT_EQ(error_code, S_OK);
error_code = utils.IsFileExistInArchive(zip_path, L"4.txt");
EXPECT_EQ(error_code, S_FALSE);
// LoadFileFromArchive(...)
data = new BYTE[100];
ULONG nFileSize;
error_code = utils.LoadFileFromArchive(zip_path, L"MF/file.txt", &data, nFileSize);
std::wstring wstr = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(data, nFileSize);
delete[] data;
ASSERT_EQ(error_code, S_OK);
EXPECT_EQ(wstr, L"123 321");
}