Files
dnf-utils/libnpk/source/libNPK_FileStream.cpp
T
2025-09-02 20:39:30 +08:00

88 lines
1.9 KiB
C++

#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;
}
}