#include "libNPK_StdAfx.h" #include "libNPK_FileStream.h" #include "libNPK_Errors.h" #include "libEncrypt_CRC32.h" namespace NPK { CFileStream::CFileStream(CNPKFile* pNPKFile, HANDLE hFile, const FileItemBaseInfo& baseFileInfo) : m_pNPKFile(pNPKFile) , m_hFileandle(hFile) , m_fileName(baseFileInfo.keyName) , m_fileOffset(baseFileInfo.fileOffset) , m_fileSize(baseFileInfo.fileSize) , m_currentOffset(0) { } CFileStream::~CFileStream() { } uint32_t CFileStream::read(void* buffer, uint32_t size) { if(isEOF()) { return 0; // End of file } DWORD dwOffset = m_fileOffset + m_currentOffset; if (dwOffset != ::SetFilePointer(m_hFileandle, dwOffset, NULL, FILE_BEGIN)) { setLastError(NPK_ERR_FILE_READ, "WinErr=%d", ::GetLastError()); return 0; // Failed to set file pointer } DWORD dwRemainBytes = m_fileSize - m_currentOffset; DWORD dwToRead = (size < dwRemainBytes) ? size : dwRemainBytes; DWORD dwBytesRead = 0; if(!::ReadFile(m_hFileandle, buffer, dwToRead, &dwBytesRead, NULL)) { setLastError(NPK_ERR_FILE_READ, "WinErr=%d", ::GetLastError()); return 0; // Failed to read file } m_currentOffset += dwBytesRead; return dwBytesRead; } bool CFileStream::seek(uint32_t offset) { if(offset > m_fileSize) { setLastError(NPK_ERR_FILE_READ, "Seek offset %u exceeds file size %u", offset, m_fileSize); return false; // Seek offset exceeds file size } m_currentOffset = offset; return true; } uint32_t CFileStream::crc32(void) { if (m_crc32Calculated) return m_crc32; // CRC32 already calculated const size_t kBufferSize = 1024*4; uint8_t pTempBuffer[kBufferSize]; uint32_t currentOffset = m_currentOffset; m_currentOffset = 0; m_crc32 = 0; // Read the entire file to calculate CRC32 uint32_t bytesRead = 0; while ((bytesRead = read(pTempBuffer, kBufferSize)) > 0) { m_crc32 = crcMemory32(pTempBuffer, bytesRead, m_crc32); } m_currentOffset = currentOffset; m_crc32Calculated = true; return m_crc32; } }