#include "StdAfx.h" #include #include #include #include "EterPackManager.h" #include "../eterBase/Debug.h" #include "../eterBase/CRC32.h" #include "Folder.h" #include "ZIP.h" #define PATH_ABSOLUTE_YMIRWORK1 "d:/ymir work/" #define PATH_ABSOLUTE_YMIRWORK2 "d:\\ymir work\\" // StringPath std::string ¹öÀü std::string CEterPackManager::ConvertFileName(std::string fileName) { std::string convertedFileName = fileName; stl_lowers(convertedFileName); for (DWORD i = 0; i < convertedFileName.length(); i++) { if (convertedFileName[i] == '\\') convertedFileName[i] = '/'; } return convertedFileName; } bool CEterPackManager::CompareName(const char * c_szDirectoryName, DWORD /*dwLength*/, const char * c_szFileName) { const char * c_pszSrc = c_szDirectoryName; const char * c_pszCmp = c_szFileName; while (*c_pszSrc) { if (*(c_pszSrc++) != *(c_pszCmp++)) return false; if (!*c_pszCmp) return false; } return true; } struct TimeChecker { TimeChecker(const char* name) : name(name) { baseTime = timeGetTime(); } ~TimeChecker() { printf("load %s (%d)\n", name, timeGetTime() - baseTime); } const char* name; DWORD baseTime; }; bool CEterPackManager::Get(const std::string& fileName, TPackDataPtr& dataPtr) { //TimeChecker timeChecker(c_szFileName); //Logf(1, "Load %s\n", c_szFileName); if (m_iSearchMode == SEARCH_FILE_FIRST) { if (GetFromFile(fileName, dataPtr)) return true; return GetFromPack(fileName, dataPtr); } if (GetFromPack(fileName, dataPtr)) return true; return GetFromFile(fileName, dataPtr); } bool CEterPackManager::Get(const std::string& fileName, std::stringstream& dataStream) { CEterPackManager::TPackDataPtr data; if (!Get(fileName, data)) return false; // Copy the data from the pack into the file sstream dataStream.str(""); std::copy(data->begin(), data->end(), std::ostream_iterator(dataStream)); return true; } struct FinderLock { FinderLock(CRITICAL_SECTION& cs) : p_cs(&cs) { EnterCriticalSection(p_cs); } ~FinderLock() { LeaveCriticalSection(p_cs); } CRITICAL_SECTION* p_cs; }; bool CEterPackManager::GetFromPack(const std::string& fileName, TPackDataPtr& dataPtr) { FinderLock lock(m_csFinder); std::string strFileName = ConvertFileName(fileName); auto pkFileItem = m_FileMap.find(strFileName); if (pkFileItem == m_FileMap.end()) { #ifdef _DEBUG TraceError("CANNOT_FIND_PACK_FILE [%s]", strFileName.c_str()); #endif return false; } auto data = std::make_shared>(); if (!pkFileItem->second->getFile(strFileName, data)) return false; // Set dataPtr to the retreived data pointer dataPtr = data; return true; } bool CEterPackManager::GetFromFile(const std::string& fileName, TPackDataPtr& dataPtr) { // Try to open the file std::ifstream file(fileName, std::ios::binary); if (!file.is_open()) return false; // Read the file's contents dataPtr = std::make_shared>( std::istreambuf_iterator(file), std::istreambuf_iterator() ); return true; } bool CEterPackManager::isExistInPack(const char * c_szFileName) { std::string strFileName = ConvertFileName(c_szFileName); auto pkFileItem = m_FileMap.find(strFileName); if (pkFileItem == m_FileMap.end()) return false; if (!pkFileItem->second) return false; return pkFileItem->second->fileExists(strFileName.c_str()); } bool CEterPackManager::isExist(const char * c_szFileName) { if (m_iSearchMode == SEARCH_PACK_FIRST) { if (isExistInPack(c_szFileName)) return true; return _access(c_szFileName, 0) == 0; } if (_access(c_szFileName, 0) == 0) return true; return isExistInPack(c_szFileName); } bool CEterPackManager::PackExists(const std::string& name, const std::string& container) { if (container == "FOLDER") { return _access(name.c_str(), 0) == 0; } else if (container == "ZIP") { std::string zipName = name + ".zip"; return _access(zipName.c_str(), 0) == 0; } throw std::runtime_error("Unexpected container type: " + container + "!"); } bool CEterPackManager::RegisterPack(const std::string& name, const std::string& container) { auto it = m_PackMap.find(name); if (it != m_PackMap.end()) return true; try { bool bReadOnly = true; std::shared_ptr pack; // Determine requested container type if (container == "FOLDER") pack = std::make_shared(name); else if (container == "ZIP") pack = std::make_shared(name + ".zip"); else throw std::runtime_error("Unexpected container type: " + container + "!"); // Load container data auto packFiles = pack->listFiles(); for (auto const& fileName : packFiles) m_FileMap.insert({ fileName, pack }); m_PackMap.insert({ name, pack }); return true; } catch (std::exception& e) { #ifdef _DEBUG Tracef("Unable to load file provider '%s': %s\n", name.c_str(), e.what()); #endif return false; } } void CEterPackManager::SetSearchMode(bool bPackFirst) { m_iSearchMode = bPackFirst ? SEARCH_PACK_FIRST : SEARCH_FILE_FIRST; } int CEterPackManager::GetSearchMode() { return m_iSearchMode; } CEterPackManager::CEterPackManager() : m_iSearchMode(SEARCH_FILE_FIRST) { InitializeCriticalSection(&m_csFinder); } CEterPackManager::~CEterPackManager() { DeleteCriticalSection(&m_csFinder); } const CEterPackManager::TFileMap& CEterPackManager::GetFileMap() { return this->m_FileMap; }