#include "StdAfx.h" #include "PackFile.h" #define PACK_IMPORT #include "..\\..\\PackTool\\PackLib\\PackInterface.h" #ifdef _DEBUG #pragma comment( lib, "..\\..\\PackTool\\PackLib\\Lib\\PackLibDllD.lib" ) #else #pragma comment( lib, "..\\..\\PackTool\\PackLib\\Lib\\PackLibDll.lib" ) #endif NiImplementDerivedBinaryStream(CPackFile, FileRead, FileWrite); CPackFile::CPackFile(const char* pcName, unsigned int uiBufferSize /* = 32768 */, bool bAudio /* = false */ ) :m_hFile(NULL) { SetEndianSwap(false); m_eMode = READ_ONLY; if ( bAudio ) { m_hFile = g_pPackAudioManager->OpenFile(pcName); } else m_hFile = g_pPackManager->OpenFile(pcName); m_bGood = (m_hFile != NULL); uiBufferSize = uiBufferSize > 256*1024 ? uiBufferSize : 256*1024; m_uiBufferAllocSize = uiBufferSize; m_uiPos = m_uiBufferReadSize = 0; if (m_bGood && uiBufferSize > 0) { m_pBuffer = NiAlloc(char, m_uiBufferAllocSize); NIASSERT(m_pBuffer != NULL); } else { m_pBuffer = NULL; } } CPackFile::~CPackFile(void) { if(m_hFile) { g_pPackInterface->CloseFile(m_hFile); m_hFile = NULL; } } void CPackFile::Seek(int iOffset, int iWhence) { NIASSERT(iWhence == ms_iSeekSet || iWhence == ms_iSeekCur || iWhence == ms_iSeekEnd); NIASSERT(m_eMode != APPEND_ONLY); if (m_bGood) { unsigned int uiNewPos = (int)m_uiAbsoluteCurrentPos + iOffset; if (iWhence == ms_iSeekCur) { // If we can accomplish the Seek by adjusting m_uiPos, do so. int iNewPos = (int) m_uiPos + iOffset; if (iNewPos >= 0 && iNewPos < (int) m_uiBufferReadSize) { m_uiPos = iNewPos; m_uiAbsoluteCurrentPos = (int)m_uiAbsoluteCurrentPos + iOffset; return; } // User's notion of current file position is different from // actual file position because of bufferring implemented by // this class. Make appropriate adjustment to offset. iOffset -= (m_uiBufferReadSize - m_uiPos); } Flush(); g_pPackInterface->SetFilePointer(m_hFile, iOffset, iWhence); m_uiAbsoluteCurrentPos = g_pPackInterface->GetFilePosition(m_hFile); #ifdef _DEBUG if (iWhence == ms_iSeekCur) { NIASSERT(uiNewPos == m_uiAbsoluteCurrentPos); } else if (iWhence == ms_iSeekSet) { NIASSERT(m_uiAbsoluteCurrentPos == iOffset); } #endif } } unsigned int CPackFile::GetFileSize() const { NIASSERT(m_bGood && m_hFile); return g_pPackInterface->GetFileSize(m_hFile); } NiFile* CPackFile::CreateFile(const char* pcName, NiFile::OpenMode eMode, unsigned int uiBufferSize) { if(eMode == READ_ONLY) return NiNew CPackFile(pcName, uiBufferSize); return NiNew NiFile(pcName, eMode, uiBufferSize); } bool CPackFile::AccessFile(const char* pcName, NiFile::OpenMode eMode) { return g_pPackManager->HasFile(pcName); } bool CPackFile::AccessAudioFile(const char* pcName, NiFile::OpenMode eMode) { return g_pPackAudioManager->HasFile(pcName); } void CPackFile::Init( bool bAudio ) { if( bAudio ) g_pPackAudioManager->Init(); else g_pPackManager->Init(); } void CPackFile::Shutdown( bool bAudio ) { if( bAudio ) g_pPackAudioManager->Shutdown(); else g_pPackManager->Shutdown(); } unsigned int CPackFile::FileRead(void* pBuffer, unsigned int uiBytes) { NIASSERT(m_eMode == READ_ONLY); if (m_bGood) { unsigned int uiAvailBufferBytes, uiRead; uiRead = 0; uiAvailBufferBytes = m_uiBufferReadSize - m_uiPos; if (uiBytes > uiAvailBufferBytes) { if (uiAvailBufferBytes > 0) { NiMemcpy(pBuffer, &m_pBuffer[m_uiPos], uiAvailBufferBytes); pBuffer = &(((char *) pBuffer)[uiAvailBufferBytes]); uiBytes -= uiAvailBufferBytes; uiRead = uiAvailBufferBytes; } Flush(); if (uiBytes > m_uiBufferAllocSize) { return uiRead + DiskRead(pBuffer, uiBytes); } else { m_uiBufferReadSize = DiskRead(m_pBuffer, m_uiBufferAllocSize); if (m_uiBufferReadSize < uiBytes) { uiBytes = m_uiBufferReadSize; } } } NiMemcpy(pBuffer, &m_pBuffer[m_uiPos], uiBytes); m_uiPos += uiBytes; return uiRead + uiBytes; } else { return 0; } } unsigned int CPackFile::FileWrite(const void *pBuffer, unsigned int uiBytes) { NIASSERT(false); return 0; } bool CPackFile::Flush() { NIASSERT(m_bGood); m_uiBufferReadSize = 0; m_uiPos = 0; return true; } unsigned int CPackFile::DiskRead(void* pvBuffer, unsigned int uiBytes) { NIASSERT(m_bGood && m_hFile); unsigned int ret = g_pPackInterface->ReadFile(m_hFile, pvBuffer, uiBytes); return ret; }