#include "PatchFile.h" #include "FileSource.h" #include "Util.h" bool operator <(const CPatchVersion& first, const CPatchVersion& second) { if (first.m_MajorVersion < second.m_MajorVersion) { return true; } else if (first.m_MajorVersion == second.m_MajorVersion) { if (first.m_MinorVersion < second.m_MinorVersion) { return true; } else if (first.m_MinorVersion == second.m_MinorVersion) { return first.m_AdditionVersion < second.m_AdditionVersion; } else { } } else { } return false; } bool operator ==(const CPatchVersion& first, const CPatchVersion& second) { return first.m_MajorVersion == second.m_MajorVersion && first.m_MinorVersion == second.m_MinorVersion && first.m_AdditionVersion == second.m_AdditionVersion; } bool operator !=(const CPatchVersion& first, const CPatchVersion& second) { return !(first == second); } CPatchVersion::CPatchVersion() { } CPatchVersion::CPatchVersion(uint8 nMajor, uint8 nMin, uint16 nAdd) : m_MajorVersion(nMajor), m_MinorVersion(nMin), m_AdditionVersion(nAdd) { } CPatchVersion::~CPatchVersion() { } int CPatchVersion::ParseVersion(const char *szVersionString) { string strVersion(szVersionString); string::size_type stPos = strVersion.find('.'); vector vectInt; while (stPos != string::npos) { string strTmp; strTmp = strVersion.substr(0, stPos); vectInt.push_back(atoi(strTmp.c_str())); strVersion = strVersion.substr(stPos + 1, strVersion.length()); stPos = strVersion.find('.'); } if (!strVersion.empty()) { vectInt.push_back(atoi(strVersion.c_str())); } if (vectInt.size() != 3) { //显示版本号错误 return -1; } m_MajorVersion = vectInt[0]; m_MinorVersion = vectInt[1]; m_AdditionVersion = vectInt[2]; return 0; } void CPatchVersion::GetVersionInfo(uint8& nMajor, uint8& nMin, uint16& nAdd) { nMajor = m_MajorVersion; nMin = m_MinorVersion; nAdd = m_AdditionVersion; } string CPatchVersion::VersionToFileName() { char szFileName[MAX_FILE_NAME]; sprintf(szFileName, "%s%d.%d.%d", PATCHFILE_PRE, m_MajorVersion, m_MinorVersion, m_AdditionVersion); return szFileName; } void CPatchVersion::SetVersion(uint8 nMajor, uint8 nMin, uint16 nAdd) { m_MajorVersion = nMajor; m_MinorVersion = nMin; m_AdditionVersion = nAdd; } CPatchVersion& CPatchVersion::operator=(const CPatchVersion& patchVersion) { m_MajorVersion = patchVersion.m_MajorVersion; m_MinorVersion = patchVersion.m_MinorVersion; m_AdditionVersion = patchVersion.m_AdditionVersion; return *this; } CPatchFile::CPatchFile(const char* PatchFileName) : m_FileName(PatchFileName) { const char* Pos = strrchr(PatchFileName, PATH_DELIMITER); if (Pos) { string strVersion(Pos + 1); int nPos = strVersion.rfind('.'); strVersion.erase(strVersion.begin() + nPos, strVersion.end()); if (CheckPatchFileName(strVersion.c_str()) == 0) { strVersion.erase(0, strlen("patch")); m_PatchVersion.ParseVersion(strVersion.c_str()); } else { //文件名格式不正确 } } } CPatchFile::~CPatchFile(void) { // } int CPatchFile::CheckPatchFileName(const char* szFileName) { return 0; } int CPatchFile::LoadPatchFile(const char *szFileName) { //获得文件大小 FILE* pFile = NULL; pFile = fopen(szFileName, "rb"); if (!pFile) { //报告错误 CUtil::Msg("%s %d.\n", "open file error", errno); return -1; } try { fseek(pFile, 0, SEEK_SET); uint32 nPos = ftell(pFile); fseek(pFile, 0, SEEK_END); m_FileSize = ftell(pFile) - nPos; CreatePartCount(); //移动到文件头 CUtil::Msg("hashing patch file %s\n", szFileName); fseek(pFile, 0, SEEK_SET); if (setvbuf(pFile, 0, _IOFBF, PARTSIZE) != 0) { CUtil::Msg("%s.%d\n", "set file buffer failed", errno); } uint8* pBuf = new uint8[PARTSIZE]; memset(pBuf, 0, PARTSIZE); while (!feof(pFile)) { nPos = fread(pBuf, sizeof(uint8), PARTSIZE, pFile); if (ferror(pFile)) { //报告错误 CUtil::Msg("read file %s failed,error code %d", szFileName, errno); return -1; } CPatchKey Key; Key.CreateKey(pBuf, nPos); m_FileKeys.AddKeys(Key); } delete [] pBuf; //生成整个文件的hash m_FileKeys.CreateFileKey(); CUtil::Msg("hashed file %s.\n", szFileName); } catch (...) { } fclose(pFile); return 0; } void CPatchFile::AddSource(CFileSource* pFileSource) { } void CPatchFile::DeleteSource(CFileSource *pFileSource) { } uint32 CPatchFile::ReadData(uint32 nPos, char* pData, uint32 nLen) { uint32 nRead = 0; FILE* pFile = fopen(m_FileName.c_str(), "rb"); if (pFile) { fseek(pFile, nPos, SEEK_SET); nRead = fread(pData, sizeof(char), nLen, pFile); //判断是否读取错误 if (nRead < nLen) { if (ferror(pFile)) { nRead = 0; //报告错误 } } fclose(pFile); } return nRead; } void CPatchFile::CreatePartCount() { //向上圆整 m_PartCount = (m_FileSize + PARTSIZE - 1) / PARTSIZE; }