#include "StdAfx.h" #include "EtResourceMng.h" #include "Stream.h" #include "EtPackingStream.h" #include "PerfCheck.h" #include "StringUtil.h" #include "EtFileSystem.h" #include #ifdef _DEBUG #define new new(_NORMAL_BLOCK,__FILE__,__LINE__) #endif CEtResourceMng::CEtResourceMng( bool bUsePackingFile, bool bUseDynamic ) { ScopeLock Lock(m_SyncLock, bUseDynamic); m_pFileSystem = NULL; m_bUsePackingFile = bUsePackingFile; m_bUseDynamic = bUseDynamic; if( bUsePackingFile ) { m_pFileSystem = new CEtFileSystem( bUseDynamic ); } WCHAR wszTemp[_MAX_PATH] = { 0, }; ::GetCurrentDirectoryW( _MAX_PATH, wszTemp ); m_wszRootDirectory = wszTemp; char szTemp[_MAX_PATH] = { 0, }; WideCharToMultiByte( CP_ACP, 0, wszTemp, -1, szTemp, _MAX_PATH, NULL, NULL ); AddResourcePath( szTemp ); m_nCodePage = 949; m_bUseMapAccessSuccessFileName = true; } CEtResourceMng::~CEtResourceMng() { ClearCacheMemoryStream(); SAFE_DELETE( m_pFileSystem ); } bool CEtResourceMng::AddResourcePath( const char *szPath, bool bIncludeSubDir ) { bool bResult = _AddResourcePath( szPath, bIncludeSubDir ); if( m_bUsePackingFile ) CEtFileSystem::GetInstance().AddResourcePath( szPath, bIncludeSubDir ); return bResult; } void CEtResourceMng::RemoveResourcePath( const char *szPath, bool bIncludeSubDir ) { _RemoveResourcePath( szPath, bIncludeSubDir ); if( m_bUsePackingFile ) CEtFileSystem::GetInstance().RemoveResourcePath( szPath, bIncludeSubDir ); } void CEtResourceMng::ReserchAddResourcePath( const char* szPath ) { if( szPath == NULL ) return; CFileNameString szPathString = szPath; ToLowerA( szPathString ); std::map::iterator it = m_szMapCacheFolderList.find( szPathString ); if( it == m_szMapCacheFolderList.end() ) return; int nCashFilePos = it->second; CacheFileList( nCashFilePos, true ); } bool CEtResourceMng::_AddResourcePath( const char *szPath, bool bIncludeSubDir ) { ScopeLock Lock(m_SyncLock, m_bUseDynamic ); CFileNameString szTemp = szPath; ToLowerA( szTemp ); if( szTemp[0] == '.' && szTemp[1] == '\\' ) { char szTempPath[_MAX_PATH] = { 0, }; sprintf_s( szTempPath, "%s\\%s", m_szVecResourcePath[0].c_str(), szTemp.c_str() + 2 ); /* for( DWORD i=1; i szVecList; char szTempPath[_MAX_PATH]; _FindFolder( szTemp.c_str(), szVecList ); for( DWORD i=0; i Lock(m_SyncLock, m_bUseDynamic); CFileNameString szTemp = szPath; ToLowerA( szTemp ); std::map::iterator it = m_szMapCacheFolderList.find( szTemp ); if( it == m_szMapCacheFolderList.end() ) return; int nOffset = it->second; for( int i=nOffset; i<(int)m_szVecResourcePath.size(); i++ ) { if( _stricmp( m_szVecResourcePath[i].c_str(), szTemp.c_str() ) == NULL ) { CacheFileList( i, false ); m_szMapCacheFolderList.erase( m_szVecResourcePath[i] ); m_szVecResourcePath.erase( m_szVecResourcePath.begin() + i ); if( !bIncludeSubDir ) break; i--; if( szTemp[(int)strlen(szPath)-1] != '\\' ) szTemp += "\\"; continue; } if( bIncludeSubDir ) { if( szPath[1] == ':' && strlen(szPath) < 3 ) return; CacheFileList( i, false ); m_szMapCacheFolderList.erase( m_szVecResourcePath[i] ); m_szVecResourcePath.erase( m_szVecResourcePath.begin() + i ); i--; } } /* for( DWORD i=1; i szVecList; char szTempPath[_MAX_PATH]; _FindFolder( szTemp.c_str(), szVecList ); for( DWORD i=0; i Lock(m_SyncLock, m_bUseDynamic); char szTemp[256] = { 0, }; const char *szCodePageString = FindCodePageString( ( nCodePage == -1 ) ? m_nCodePage : nCodePage ); if( szCodePageString != NULL ) { sprintf_s( szTemp, "%s\\%s", szPath, szCodePageString ); AddResourcePath( szTemp, bIncludeSubDir ); } return AddResourcePath( szPath, bIncludeSubDir ); } bool CEtResourceMng::AddResourcePath( CFileNameString &szPath, bool bIncludeSubDir ) { return AddResourcePath( szPath.c_str(), bIncludeSubDir ); } void CEtResourceMng::RemoveResourcePath( CFileNameString &szPath, bool bIncludeSubDir ) { RemoveResourcePath( szPath.c_str(), bIncludeSubDir ); } bool CEtResourceMng::AddResourcePathByCodePage( CFileNameString &szPath, int nCodePage, bool bIncludeSubDir ) { return AddResourcePathByCodePage( szPath.c_str(), nCodePage, bIncludeSubDir ); } CFileNameString CEtResourceMng::GetFullName( CFileNameString &szFileName, bool *bFind ) { return GetFullName( szFileName.c_str(), bFind ); } CFileNameString CEtResourceMng::GetFullPath( CFileNameString &szPath, bool bSearchSubDir ) { return GetFullPath( szPath.c_str(), bSearchSubDir ); } CFileNameString CEtResourceMng::GetFullNameRandom( CFileNameString &szFileName, int nIndex, bool *bFind ) { ScopeLock Lock(m_SyncLock, m_bUseDynamic); char szTempName[_MAX_PATH]; char szTempFileName[_MAX_PATH]; char szExt[32]; _GetFileName( szTempFileName, _countof(szTempFileName), szFileName.c_str() ); _GetExt( szExt, _countof(szExt), szFileName.c_str() ); sprintf_s( szTempName, "%s_%c.%s", szTempFileName, 'a' + nIndex, szExt ); return GetFullName( szTempName, bFind ); } CStream *CEtResourceMng::GetStreamRandom( CFileNameString &szFileName, int nIndex, bool *bFind ) { ScopeLock Lock(m_SyncLock, m_bUseDynamic); char szTempName[_MAX_PATH]; char szTempFileName[_MAX_PATH]; char szExt[32]; _GetFileName( szTempFileName, _countof(szTempFileName), szFileName.c_str() ); _GetExt( szExt, _countof(szExt), szFileName.c_str() ); sprintf_s( szTempName, "%s_%c.%s", szTempFileName, 'a' + nIndex, szExt ); return GetStream( szTempName, bFind ); } CFileNameString CEtResourceMng::GetFullName( const char *szFileName, bool *bFind ) { CFileNameString strFullName; ScopeLock Lock(m_SyncLock, m_bUseDynamic); if( szFileName == NULL || strlen(szFileName) == 0 ) { if( bFind ) *bFind = false; return strFullName; } if( m_bUsePackingFile && szFileName[0] != '.' ) { strFullName = CEtFileSystem::GetInstance().GetFullName( szFileName, bFind ); } else { char szTemp[4096]; if( szFileName && strlen(szFileName) > 2 && ( ( szFileName[1] == ':' ) || ( szFileName[0] == '\\' && szFileName[1] == '\\' ) ) ) { if( bFind ) *bFind = IsExistFile( szFileName ); strFullName = szFileName; } else { char szName[_MAX_PATH] = { 0, }; _GetFullFileName( szName, _countof(szName), szFileName ); _strlwr_s( szName, _MAX_PATH ); std::map::iterator it = m_szMapAccessSuccessFileName.find( szName ); if( it != m_szMapAccessSuccessFileName.end() ) { if( bFind ) *bFind = true; strFullName = it->second; } if( strFullName.empty() ) { it = m_szMapAccessFailedFileName.find( szName ); if( it != m_szMapAccessFailedFileName.end() ) { if( bFind ) *bFind = false; strFullName = szFileName; } } if( strFullName.empty() ) { it = m_szMapCacheFileList.find( szName ); if( it != m_szMapCacheFileList.end() ) { if( bFind ) *bFind = true; strFullName = it->second; } } // ¾î´À¼ø°£ º¸´Ï, ¾Æ·¡ IsExistFile ÇÔ¼ö°¡ ·£´ýÇÏ°Ô ´À·ÁÁö´Â Çö»óÀÌ ¹ß»ýÇß´Ù. // ÆÄÀÏ ÀÖ´ÂÁö °Ë»çÇÏ´Â ´Ü¼øÇÑ ÇÔ¼öÀε¥, GetFileAttribute·Î ¹Ù²Ù°í ¾²·¹µå¸¦ ¾È¾²°í ÇØºÁµµ, // Á¤¸» ·£´ýÇÏ°Ô ´À·ÁÁú¶§°¡ ÀÖ´Ù. // (¾Æ·¡ m_szVecResourcePath ¸®½ºÆ® °³¼ö°¡ 760°³À϶§ Å×½ºÆ®ÇѰǵ¥, ºü¸£°Ô µ¹¶© 0-16ms³ª¿ÀÁö¸¸ ´À¸®°Ô µ¹¸é 140-250ms³ª¿Â´Ù.) // ¿ì¼±Àº ÇØ¿Üºôµåµµ ´ë±âÁßÀÌ°í º»¼· Ŭ¶óÀÌ¾ðÆ®µµ ·Îµù¶§¹®¿¡ ¹®Á¦°¡ ¹ß»ýÇѰа°¾Æ¼­, ÅøÀ̳ª ±âŸ »óȲ¿¡¼± ¾²°í, Ŭ¶ó¿¡¼± ¾È¾²´Â°Å·Î ¸·¾ÆµÐ´Ù. if( strFullName.empty() ) { if( m_bUseMapAccessSuccessFileName ) { for( DWORD i=1; i::iterator it = m_szMapCacheFileList.find( szChangeFileName ); if( it != m_szMapCacheFileList.end() ) { bFind = true; strFullName = it->second; } } return strFullName; } CFileNameString CEtResourceMng::GetFullName( std::string &szFileName, bool *bFind ) { return GetFullName( szFileName.c_str(), bFind ); } CFileNameString CEtResourceMng::GetFullNameInCacheList( const char *szFileName ) { char szName[_MAX_PATH] = { 0, }; _GetFullFileName( szName, _countof(szName), szFileName ); _strlwr_s( szName, _MAX_PATH ); std::map::iterator it = m_szMapCacheFileList.find( szName ); if( it != m_szMapCacheFileList.end() ) { return it->second; } return ""; } CFileNameString CEtResourceMng::GetFullNameRandom( std::string &szFileName, int nIndex, bool *bFind ) { ScopeLock Lock(m_SyncLock, m_bUseDynamic); char szTempName[_MAX_PATH]; char szTempFileName[_MAX_PATH]; char szExt[32]; _GetFileName( szTempFileName, _countof(szTempFileName), szFileName.c_str() ); _GetExt( szExt, _countof(szExt), szFileName.c_str() ); sprintf_s( szTempName, "%s_%c.%s", szTempFileName, 'a' + nIndex, szExt ); return GetFullName( szTempName, bFind ); } CFileNameString CEtResourceMng::GetFullPath( const char *szPath, bool bSearchSubDir ) { ScopeLock Lock(m_SyncLock, m_bUseDynamic); if( m_bUsePackingFile ) { return CEtFileSystem::GetInstance().GetFullPath( szPath ); } else { char szTemp[_MAX_PATH]; std::vector< CFileNameString > szVecList; int nLength = (int)strlen(szPath); for( DWORD i=0; i &szVecResult ) { ScopeLock Lock(m_SyncLock, m_bUseDynamic); if( m_bUsePackingFile ) { return CEtFileSystem::GetInstance().FindFullPathList( szPath, szVecResult ); } else { //char szTemp[_MAX_PATH]; std::vector< CFileNameString > szVecList; int nLength = (int)strlen(szPath); for( DWORD i=0; i Lock(m_SyncLock, m_bUseDynamic ); bool bExist = (_access(szFileName, 0)==0); // ¿©±ä Lock ¾ø¾îµµ µÉ°Í °°½À´Ï´Ù. return bExist; } void CEtResourceMng::Initialize() { ScopeLock Lock(m_SyncLock, m_bUseDynamic); // ÇöÁ¦ ±¹°¡ÄÚµå ¾ò¾î³õ´Â´Ù. WCHAR wszCodePage[ 8 ]; if( GetLocaleInfoW( MAKELCID( GetKeyboardLayout( 0 ), SORT_DEFAULT ), LOCALE_IDEFAULTANSICODEPAGE, wszCodePage, sizeof( wszCodePage ) / sizeof( wszCodePage[ 0 ] ) ) ) { m_nCodePage = wcstoul( wszCodePage, NULL, 0 ); // LOCALE_SABBREVLANGNAME // ¸¸¾à ÇöÁ¦ ±¹°¡Äڵ尡 ¾øÀ»°æ¿ì¿£ µî·ÏÇÑ´Ù. if( FindCodePageString( m_nCodePage ) == NULL ) { if( GetLocaleInfoW( MAKELCID( GetKeyboardLayout( 0 ), SORT_DEFAULT ), LOCALE_SABBREVLANGNAME, wszCodePage, sizeof( wszCodePage ) / sizeof( wszCodePage[ 0 ] ) ) ) { char szTemp[8]; WideCharToMultiByte( CP_ACP, 0, wszCodePage, -1, szTemp, 8, NULL, NULL ); _strlwr_s( szTemp, 8 ); m_mapCodePageString.insert( make_pair( m_nCodePage, szTemp ) ); } } } } void CEtResourceMng::AddCodePage( int nCodePage, const char *szCodePageStr ) { ScopeLock Lock(m_SyncLock, m_bUseDynamic); if( FindCodePageString( nCodePage ) != NULL ) return; m_mapCodePageString.insert( make_pair( nCodePage, szCodePageStr ) ); } const char *CEtResourceMng::FindCodePageString( int nCodePage ) { ScopeLock Lock(m_SyncLock, m_bUseDynamic); std::map::iterator it = m_mapCodePageString.find( nCodePage ); if( it == m_mapCodePageString.end() ) return NULL; return it->second.c_str(); } bool CEtResourceMng::IsCodePageFolder( const char *szCodePageStr ) { ScopeLock Lock(m_SyncLock, m_bUseDynamic); for( DWORD i=0; i &szVecResult) { if ( m_bUsePackingFile ) { CEtFileSystem::GetInstance().FindFileListInFolder( szFolderName, szExt, szVecResult); } else { FindFileListInDirectory(szFolderName, szExt, szVecResult); } } void CEtResourceMng::FindFileListAll_IgnoreExistFile( const char *szFolderName, const char *szExt, std::vector &szVecResult ) { std::vector szVecFolderList; FindFullPathList( szFolderName, szVecFolderList ); char szTemp[256]; std::vector szVecFileNameList; for( DWORD i=0; i szVecTemp; FindFileListInFolder( szVecFolderList[i].c_str(), szExt, szVecTemp ); for( DWORD j=0; j Lock(m_SyncLock, m_bUseDynamic); bool bExistFile = false; if( bFind ) *bFind = false; CFileNameString szResultName = szFileName; if( m_bUsePackingFile && szFileName[0] != '.' ) { CFileNameString szFullName = GetFullName( szFileName, &bExistFile ); CStream *pCacheStream = GetCacheMemoryStream( szFullName.c_str() ); if( pCacheStream ) return pCacheStream; CPackingStream *pStream = new CPackingStream( szResultName.c_str() ); if( !pStream->IsValid() ) { SAFE_DELETE( pStream ); return NULL; } if( bFind ) *bFind = true; return pStream; } else { CFileNameString szFullName = GetFullName( szFileName, &bExistFile ); if( bExistFile ) { CStream *pCacheStream = GetCacheMemoryStream( szFullName.c_str() ); if( pCacheStream ) return pCacheStream; CFileStream *pStream = new CFileStream( szFullName.c_str(), CFileStream::OPEN_READ ); if( !pStream->IsValid() ) { SAFE_DELETE( pStream ); return NULL; } if( bFind ) *bFind = true; return pStream; } } return NULL; } CStream *CEtResourceMng::GetStream( CFileNameString &szFileName, bool *bFind ) { return GetStream( szFileName.c_str(), bFind ); } void CEtResourceMng::CacheFileList( int nIndex, bool bAdd ) { ScopeLock Lock(m_SyncLock, m_bUseDynamic); char szTemp[4096]; std::vector szVecFileList; CFileNameString szFullName; if( m_szVecResourcePath[nIndex][0] == '.' && m_szVecResourcePath[nIndex][1] == '\\' ) { sprintf_s( szTemp, "%s\\%s\\", m_szVecResourcePath[0].c_str(), m_szVecResourcePath[nIndex].c_str() + 2 ); } else sprintf_s( szTemp, "%s\\", m_szVecResourcePath[nIndex].c_str() ); if( bAdd ) { OffsetStruct Struct; szVecFileList.clear(); FindFileListInDirectory( szTemp, "*.*", szVecFileList ); for( DWORD j=0; j= (int)m_VecPathCacheFileOffset.size() ) return; for( DWORD j=0; j::iterator it = m_szMapCacheMemoryBufferList.find( szFullName ); if( it != m_szMapCacheMemoryBufferList.end() ) return false; CResMngStream Stream( szFullName.c_str() ); if( !Stream.IsValid() ) return false; CacheMemoryBuffer *pBuffer = new CacheMemoryBuffer; pBuffer->pPtr = new char[Stream.Size()]; pBuffer->nSize = Stream.Size(); Stream.Read( pBuffer->pPtr, Stream.Size() ); m_szMapCacheMemoryBufferList.insert( make_pair( szFullName, pBuffer ) ); return true; } bool CEtResourceMng::RemoveCacheMemoryStream( const char *szFileName ) { bool bValid; CFileNameString szFullName = GetFullName( szFileName, &bValid ); if( !bValid ) return false; ToLowerA( szFullName ); std::map::iterator iter = m_szMapCacheMemoryBufferList.find( szFullName ); if( iter != m_szMapCacheMemoryBufferList.end() ) { SAFE_DELETEA( iter->second->pPtr ); SAFE_DELETE( iter->second ); m_szMapCacheMemoryBufferList.erase( iter ); } return true; } CStream *CEtResourceMng::GetCacheMemoryStream( const char *szFileName ) { CFileNameString szTemp = szFileName; ToLowerA( szTemp ); std::map::iterator it = m_szMapCacheMemoryBufferList.find( szTemp ); if( it == m_szMapCacheMemoryBufferList.end() ) return NULL; CMemoryStream *pStream = new CMemoryStream( it->second->pPtr, it->second->nSize ); pStream->SetName( szTemp.c_str() ); return pStream; } void CEtResourceMng::ClearCacheMemoryStream() { for( std::map::iterator it = m_szMapCacheMemoryBufferList.begin(); it != m_szMapCacheMemoryBufferList.end(); it++ ) { SAFE_DELETEA( it->second->pPtr ); SAFE_DELETE( it->second ); } SAFE_DELETE_VEC( m_szMapCacheMemoryBufferList ); } CEtResourceAccess::CEtResourceAccess() { m_pStream = NULL; m_bSelfDelete = true; m_bAddPath = false; m_bValid = false; m_bIncludeSubPath = false; m_szAddPath[0] = 0; } CEtResourceAccess::CEtResourceAccess( const char *pFileName, bool bSelfDelete, bool bIncludeSubPath ) { Initialize( pFileName, bSelfDelete, bIncludeSubPath ); } CEtResourceAccess::~CEtResourceAccess() { Finalize(); } void CEtResourceAccess::Initialize( const char *pFileName, bool bSelfDelete, bool bIncludeSubPath ) { m_pStream = NULL; m_bSelfDelete = bSelfDelete; m_bIncludeSubPath = bIncludeSubPath; if( IsFullName( pFileName ) ) { memset( m_szAddPath, 0, sizeof(m_szAddPath) ); _GetPath( m_szAddPath, _countof(m_szAddPath), pFileName ); if( m_szAddPath[strlen(m_szAddPath)-1] == '\\' ) m_szAddPath[strlen(m_szAddPath)-1] = 0; if( CEtResourceMng::GetInstance().IsUseDynamic() ) m_bAddPath = CEtResourceMng::GetInstance().AddResourcePath( m_szAddPath, m_bIncludeSubPath ); } else m_bAddPath = false; m_szFullName = CEtResourceMng::GetInstance().GetFullName( pFileName, &m_bValid ); if( !m_bValid ) m_szFullName = pFileName; } void CEtResourceAccess::Finalize() { if( m_bAddPath && CEtResourceMng::GetInstance().IsUseDynamic() ) CEtResourceMng::GetInstance().RemoveResourcePath( m_szAddPath, m_bIncludeSubPath ); if( m_bSelfDelete ) SAFE_DELETE( m_pStream ); m_pStream = NULL; m_bSelfDelete = true; m_bAddPath = false; m_bValid = false; } CStream *CEtResourceAccess::GetStream() { if( !m_bValid ) return NULL; m_pStream = CEtResourceMng::GetInstance().GetStream( m_szFullName ); return m_pStream; } CResMngStream::CResMngStream() { } CResMngStream::CResMngStream( const char *pFileName, bool bSelfDelete, bool bIncludeSubPath ) { Open( pFileName, bSelfDelete, bIncludeSubPath ); } CResMngStream::~CResMngStream() { } bool CResMngStream::Open( const char *pFileName, bool bSelfDelete, bool bIncludeSubPath ) { Initialize( pFileName, bSelfDelete, bIncludeSubPath ); GetStream(); return ( m_pStream ) ? true : false; } bool CResMngStream::IsEnd() const { if( !m_pStream ) return true; return m_pStream->IsEnd(); } long CResMngStream::Tell() { if( !m_pStream ) return 0; return m_pStream->Tell(); } int CResMngStream::Size() const { if( !m_pStream ) return 0; return m_pStream->Size(); } bool CResMngStream::IsValid() const { if( !m_pStream ) return false; return m_pStream->IsValid(); } void CResMngStream::Close() { Finalize(); } void CResMngStream::Activate() { // if( !m_pStream ) return; // m_pStream->Activate(); } int CResMngStream::Seek( long lOffset, int nOrigin ) { if( !m_pStream ) return 0; return m_pStream->Seek( lOffset, nOrigin ); } int CResMngStream::Read( void *pBuffer, int nSize ) { if( !m_pStream ) return 0; return m_pStream->Read( pBuffer, nSize ); } int CResMngStream::Write( const void *pBuffer, int nSize ) { return 0; } const char *CResMngStream::GetName() { if( !m_pStream ) return NULL; return m_pStream->GetName(); }