📄 archive.cpp
字号:
{ case(STATE_ARCH_HEADER): { res = ReadTarHeader(pArchData + ulRead, ulSize - ulRead, ulLocalRead); } break; case(STATE_FILE_HEADER): { res = ReadFileHeader(pArchData + ulRead, ulSize - ulRead, ulLocalRead); } break; case(STATE_FILE_NAME): { res = ReadFileName(pArchData + ulRead, ulSize - ulRead, ulLocalRead); } break; case(STATE_FILE_DATA): { res = ReadFileData(pArchData + ulRead, ulSize - ulRead, ulLocalRead); } } if(FAILED(res)) { break; } ulRead += ulLocalRead; } return res;}HX_RESULTDearchiver::ReadTarHeader(BYTE* pArchData, const UINT32 ulSize, UINT32& ulRead){ HX_RESULT res = HXR_OK; BOOL bNeedMoreData = FALSE; UINT32 ulPos = 0; BYTE* pBuf = pArchData; UINT32 ulCopySize = 0; // We have a partial header, save what we've got if(ulSize + m_ulSaved < HXAR_ARCH_DESC_SIZE) { bNeedMoreData = TRUE; ulCopySize = ulSize; } // We have a partial header stored, copy the rest of it else if (m_ulSaved) { ulCopySize = HXAR_ARCH_DESC_SIZE - m_ulSaved; } // copy if(ulCopySize) { // Should never happen! if(m_ulSaved + ulCopySize > DESC_BUF_SIZE) { return HXR_FAIL; } pBuf = m_pSaveBuf; memcpy((void*)(m_pSaveBuf + m_ulSaved), pArchData, ulCopySize); m_ulSaved += ulCopySize; } // Read the tar descriptor if(!bNeedMoreData) { if(strncmp((const char*)pBuf, HXAR_ID, HXAR_ID_SIZE) == 0) { ulPos = HXAR_ID_SIZE; if(pBuf[ulPos] > HXAR_VER_MAJOR || (pBuf[ulPos] == HXAR_VER_MAJOR && pBuf[ulPos + 1] > HXAR_VER_MINOR)) { res = HXR_INVALID_VERSION; } ulPos += 2; m_State = STATE_FILE_HEADER; } else { res = HXR_INVALID_FILE; } // Clear the save buffer m_ulSaved = 0; } if(SUCCEEDED(res)) { ulRead = ulCopySize ? ulCopySize : ulPos; } return res;}HX_RESULTDearchiver::ReadFileHeader(BYTE* pArchData, const UINT32 ulSize, UINT32& ulRead){ HX_RESULT res = HXR_OK; BOOL bNeedMoreData = FALSE; UINT32 ulPos = 0; BYTE* pBuf = pArchData; UINT32 ulCopySize = 0; // We have a partial header, save what we've got if(ulSize + m_ulSaved < HXAR_FILE_DESC_SIZE) { bNeedMoreData = TRUE; ulCopySize = ulSize; } // We have a partial header stored, copy the rest of it else if (m_ulSaved) { ulCopySize = HXAR_FILE_DESC_SIZE - m_ulSaved; } // copy if(ulCopySize) { // Should never happen! if(m_ulSaved + ulCopySize > DESC_BUF_SIZE) { return HXR_FAIL; } pBuf = m_pSaveBuf; memcpy((void*)(m_pSaveBuf + m_ulSaved), pArchData, ulCopySize); m_ulSaved += ulCopySize; } // Read the file descriptor if(!bNeedMoreData) { if(strncmp((const char*)pBuf, HXAR_FILE_ID, HXAR_FILE_ID_SIZE) == 0) { ulPos = HXAR_FILE_ID_SIZE; m_ulMode = (pBuf[ulPos] << 8) + pBuf[ulPos+1]; ulPos += 6; m_ulFileSize = (pBuf[ulPos] << 24) + (pBuf[ulPos+1] << 16) + (pBuf[ulPos+2] << 8) + pBuf[ulPos+3]; ulPos += 4; m_State = STATE_FILE_NAME; } else { res = HXR_INVALID_FILE; } // Clear the save buffer m_ulSaved = 0; } if(SUCCEEDED(res)) { ulRead = ulCopySize ? ulCopySize : ulPos; } return res;}HX_RESULTDearchiver::ReadFileName(BYTE* pArchData, const UINT32 ulSize, UINT32& ulRead){ HX_RESULT res = HXR_OK; BOOL bNeedMoreData = FALSE; //UINT32 ulPos = 0; BYTE* pBuf = pArchData; UINT32 ulCopySize = 0; // Find the null terminator signaling end of file name BYTE* pEnd = (BYTE*)memchr((void*)pArchData, '\0', ulSize); // We have a partial header, save what we've got if(!pEnd) { bNeedMoreData = TRUE; ulCopySize = ulSize; } // We have a partial header stored, copy the rest of it else if(m_ulSaved) { ulCopySize = pEnd - pArchData + 1; } // copy if(ulCopySize) { // File name is too long if(m_ulSaved + ulCopySize > DESC_BUF_SIZE) { return HXR_INVALID_FILE; } pBuf = m_pSaveBuf; memcpy((void*)(m_pSaveBuf + m_ulSaved), pArchData, ulCopySize); m_ulSaved += ulCopySize; } if(!bNeedMoreData) { res = OpenOutFile((const char*)pBuf); // Clear the save buffer m_ulSaved = 0; } if(SUCCEEDED(res)) { ulRead = ulCopySize ? ulCopySize : pEnd - pArchData + 1; } return res;}HX_RESULTDearchiver::ReadFileData(BYTE* pArchData, const UINT32 ulSize, UINT32& ulRead){ if(!m_fFile) { return HXR_FAIL; } HX_RESULT res = HXR_OK; UINT32 ulWriteSize = ulSize; ulRead = 0; if(m_ulWritten + ulSize > m_ulFileSize) { ulWriteSize = m_ulFileSize - m_ulWritten; } // Write the block if(fwrite((void*)pArchData, 1, ulWriteSize, m_fFile) != ulWriteSize) { res = HXR_WRITE_ERROR; } if(SUCCEEDED(res)) { ulRead = ulWriteSize; m_ulWritten += ulWriteSize; if(m_ulWritten >= m_ulFileSize) { m_State = STATE_FILE_HEADER; CloseOutFile(); } } return res;}HX_RESULTDearchiver::OpenOutFile(const char* szFileName){ const char* pPath; char szFullPath[MAX_PATH + 1]; struct stat fileInfo; // Add the output directory for the full file name if(m_szOutDir) { snprintf(szFullPath, MAX_PATH, "%s%c%s", m_szOutDir, OS_SEPARATOR_CHAR, szFileName); pPath = szFullPath; } else { pPath = szFileName; } // Create the directory if(m_ulMode & _S_IFDIR) { if(stat(pPath, &fileInfo) == 0) { if(!(fileInfo.st_mode & _S_IFDIR)) { return HXR_WRITE_ERROR; } } else if(mkdir(pPath) != 0) { return HXR_WRITE_ERROR; } m_State = STATE_FILE_HEADER; m_fFile = NULL; } // Open the file else { m_fFile = fopen(pPath, "wb"); if(!m_fFile) { return HXR_WRITE_ERROR; } else { m_State = STATE_FILE_DATA; } } return HXR_OK;}voidDearchiver::CloseOutFile(){ m_ulFileSize = 0; m_ulWritten = 0; m_ulSaved = 0; m_State = STATE_FILE_HEADER; if(m_fFile) { fclose(m_fFile); }}voidDearchiver::Close(){ CloseOutFile(); m_State = STATE_CLOSED; m_szOutDir = NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -