Files
2026-06-01 12:46:52 +02:00

158 lines
4.2 KiB
C++

#include "../../include/kfile/KPackingFileMaker.h"
#include "../../include/kfile/KFileNameCipher.h"
#include "../../include/toolkit/XFileUtil.h"
#include "../../include/compress/XZip.h"
KPackingFileMaker::KPackingFileMaker( KPackingFileSystem* pPackingFS )
: m_pPackingFS( pPackingFS )
, m_destDataFileInfo( NULL )
, m_nDataFileCount( 0 )
{
m_destDataFileInfo = new sDataFileInfo[pPackingFS->GetDataFileCount()];
m_nDataFileCount = pPackingFS->GetDataFileCount();
}
KPackingFileMaker::~KPackingFileMaker()
{
close();
}
void KPackingFileMaker::close()
{
if( m_destDataFileInfo != NULL )
{
for( int i = 0; i < m_nDataFileCount; ++i )
{
m_destDataFileInfo[i].close();
}
delete [] m_destDataFileInfo;
m_destDataFileInfo = NULL;
m_nDataFileCount = 0;
}
m_destIndexFileList.clear();
}
KPackingFileMaker::sDataFileInfo* KPackingFileMaker::getDataFileInfo( size_t hash_key )
{
if( static_cast< int >( hash_key ) < m_nDataFileCount )
{
return &m_destDataFileInfo[hash_key];
}
return NULL;
}
bool KPackingFileMaker::packingFile( const char *szFileName, const char* pBuffer, size_t size, bool bCompress )
{
std::string strEncodedFileName = szFileName;
std::string strFileName = strEncodedFileName;
std::string strExtension;
if( KFileNameCipher::IsEncodedName( strEncodedFileName ) ) //<= "Win98sUpdateUtil.exe" 제대로 체크 안된다.
KFileNameCipher::DecodeFileName( strFileName );
else
KFileNameCipher::EncodeFileName( strEncodedFileName );
XFileUtil::GetFileName( strFileName.c_str(), strFileName );
XFileUtil::GetFileExtension( strFileName.c_str(), strExtension );
//
size_t hash_key = KPackingFileSystem::getFileHashKey( strEncodedFileName.c_str(), m_nDataFileCount );
sDataFileInfo* d_info = getDataFileInfo( hash_key );
if( d_info->m_file == NULL )
{
std::string dataFileName = KPackingFileSystem::getDataFileName( m_pPackingFS->GetDataFileName().c_str(), hash_key ) + ".new";
if( !d_info->create( dataFileName.c_str() ) )
{
return false;
}
}
size_t oldOffset = 0;
if( (size >= KFileSystem::MIN_COMPRESS_FILE_SIZE) && (bCompress == true) )
{
size_t xzipBufferSize = XZip::GetBufferSize( size );
char* xzipBuffer = new char[xzipBufferSize];
size_t compressSize = XZip::Compress( pBuffer, size, xzipBuffer, xzipBufferSize );
// 압축되지 않고 팩킹된 파일을 여러번 repacking할 때 compressSize < size를 하면 bIsNeedXOR 때문에 문제가 될수 있다
if( compressSize < size )
{
if( d_info->write( xzipBuffer, compressSize, &oldOffset ) == false )
{
delete [] xzipBuffer;
return false;
}
KPackingFileSystem::KFileInfo kFileInfo( strEncodedFileName.c_str(), compressSize, oldOffset, hash_key );
m_destIndexFileList.push_back( kFileInfo );
}
else
{
if( d_info->write( pBuffer, size, &oldOffset ) == false )
{
delete [] xzipBuffer;
return false;
}
KPackingFileSystem::KFileInfo kFileInfo( strEncodedFileName.c_str(), size, oldOffset, hash_key );
m_destIndexFileList.push_back( kFileInfo );
}
delete [] xzipBuffer;
}
else
{
if( d_info->write( pBuffer, size, &oldOffset ) == false )
{
return false;
}
KPackingFileSystem::KFileInfo kFileInfo( strEncodedFileName.c_str(), size, oldOffset, hash_key );
m_destIndexFileList.push_back( kFileInfo );
}
return true;
}
bool KPackingFileMaker::saveIndexFile()
{
std::string strNewIndexFile = std::string( m_pPackingFS->GetIndexFileName() ) + ".new";
SetFileAttributes( strNewIndexFile.c_str(), FILE_ATTRIBUTE_NORMAL );
DeleteFile( strNewIndexFile.c_str() );
KHFILE pFile;
pFile = ::CreateFile( strNewIndexFile.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 );
if ( !IsValidKHFile( pFile) )
{
assert( 0 );
return false;
}
int seed = 0;
std::vector< KPackingFileSystem::KFileInfo >::const_iterator pos = m_destIndexFileList.begin();
std::vector< KPackingFileSystem::KFileInfo >::const_iterator end = m_destIndexFileList.end();
for( ; pos != end; ++pos )
{
const KPackingFileSystem::KFileInfo& info = (*pos);
if( info.saveFileInfo( pFile, &seed ) == false )
{
CloseHandle( pFile );
DeleteFile( strNewIndexFile.c_str() );
return false;
}
}
FlushFileBuffers( pFile );
CloseHandle( pFile );
return true;
}