|  | /****************************************************************************** | 
|  |  | 
|  | @File         PVRTResourceFile.cpp | 
|  |  | 
|  | @Title        PVRTResourceFile.cpp | 
|  |  | 
|  | @Version | 
|  |  | 
|  | @Copyright    Copyright (c) Imagination Technologies Limited. | 
|  |  | 
|  | @Platform     ANSI compatible | 
|  |  | 
|  | @Description  Simple resource file wrapper | 
|  |  | 
|  | ******************************************************************************/ | 
|  |  | 
|  | #include "PVRTResourceFile.h" | 
|  | #include <stdio.h> | 
|  | #include <string.h> | 
|  |  | 
|  | #include "PVRTResourceFile.h" | 
|  | #include "PVRTString.h" | 
|  | #include "PVRTMemoryFileSystem.h" | 
|  |  | 
|  | CPVRTString CPVRTResourceFile::s_ReadPath; | 
|  |  | 
|  | static void* LoadFileFunc(const char* pFilename, char** pData, size_t &size) | 
|  | { | 
|  | size = 0; | 
|  |  | 
|  | FILE* pFile = fopen(pFilename, "rb"); | 
|  |  | 
|  | if (pFile) | 
|  | { | 
|  | // Get the file size | 
|  | fseek(pFile, 0, SEEK_END); | 
|  | size = ftell(pFile); | 
|  | fseek(pFile, 0, SEEK_SET); | 
|  |  | 
|  | // read the data | 
|  | char* pTmp = new char[size]; | 
|  | size_t BytesRead = fread(pTmp, 1, size, pFile); | 
|  |  | 
|  | if (BytesRead != size) | 
|  | { | 
|  | delete [] pTmp; | 
|  | pTmp = NULL; | 
|  | size = 0; | 
|  | } | 
|  | else | 
|  | *pData = pTmp; | 
|  |  | 
|  | fclose(pFile); | 
|  | return pTmp; | 
|  | } | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static bool ReleaseFileFunc(void* handle) | 
|  | { | 
|  | if(handle) | 
|  | { | 
|  | delete[] (char*) handle; | 
|  | return true; | 
|  | } | 
|  |  | 
|  | return false; | 
|  | } | 
|  |  | 
|  | PFNLoadFileFunc CPVRTResourceFile::s_pLoadFileFunc = &LoadFileFunc; | 
|  | PFNReleaseFileFunc CPVRTResourceFile::s_pReleaseFileFunc = &ReleaseFileFunc; | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @Function			SetReadPath | 
|  | @Input				pszReadPath The path where you would like to read from | 
|  | @Description		Sets the read path | 
|  | *****************************************************************************/ | 
|  | void CPVRTResourceFile::SetReadPath(const char* const pszReadPath) | 
|  | { | 
|  | s_ReadPath = (pszReadPath) ? pszReadPath : ""; | 
|  | } | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @Function			GetReadPath | 
|  | @Returns			The currently set read path | 
|  | @Description		Returns the currently set read path | 
|  | *****************************************************************************/ | 
|  | CPVRTString CPVRTResourceFile::GetReadPath() | 
|  | { | 
|  | return CPVRTString(s_ReadPath); | 
|  | } | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @Function			SetLoadReleaseFunctions | 
|  | @Input				pLoadFileFunc Function to use for opening a file | 
|  | @Input				pReleaseFileFunc Function to release any data allocated by the load function | 
|  | @Description		This function is used to override the CPVRTResource file loading functions. If | 
|  | you pass NULL in as the load function CPVRTResource will use the default functions. | 
|  | *****************************************************************************/ | 
|  | void CPVRTResourceFile::SetLoadReleaseFunctions(void* pLoadFileFunc, void* pReleaseFileFunc) | 
|  | { | 
|  | if(pLoadFileFunc) | 
|  | { | 
|  | s_pLoadFileFunc = (PFNLoadFileFunc) pLoadFileFunc; | 
|  | s_pReleaseFileFunc = (PFNReleaseFileFunc) pReleaseFileFunc; | 
|  | } | 
|  | else | 
|  | { | 
|  | s_pLoadFileFunc = &LoadFileFunc; | 
|  | s_pReleaseFileFunc = &ReleaseFileFunc; | 
|  | } | 
|  | } | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @Function			CPVRTResourceFile | 
|  | @Input				pszFilename Name of the file you would like to open | 
|  | @Description		Constructor | 
|  | *****************************************************************************/ | 
|  | CPVRTResourceFile::CPVRTResourceFile(const char* const pszFilename) : | 
|  | m_bOpen(false), | 
|  | m_bMemoryFile(false), | 
|  | m_Size(0), | 
|  | m_pData(0), | 
|  | m_Handle(0) | 
|  | { | 
|  | CPVRTString Path(s_ReadPath); | 
|  | Path += pszFilename; | 
|  |  | 
|  | m_Handle = s_pLoadFileFunc(Path.c_str(), (char**) &m_pData, m_Size); | 
|  | m_bOpen = (m_pData && m_Size) != 0; | 
|  |  | 
|  | if (!m_bOpen) | 
|  | { | 
|  | m_bOpen = m_bMemoryFile = CPVRTMemoryFileSystem::GetFile(pszFilename, (const void**)(&m_pData), &m_Size); | 
|  | } | 
|  | } | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @Function			CPVRTResourceFile | 
|  | @Input				pData A pointer to the data you would like to use | 
|  | @Input				i32Size The size of the data | 
|  | @Description		Constructor | 
|  | *****************************************************************************/ | 
|  | CPVRTResourceFile::CPVRTResourceFile(const char* pData, size_t i32Size) : | 
|  | m_bOpen(true), | 
|  | m_bMemoryFile(true), | 
|  | m_Size(i32Size), | 
|  | m_pData(pData), | 
|  | m_Handle(0) | 
|  | { | 
|  | } | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @Function			~CPVRTResourceFile | 
|  | @Description		Destructor | 
|  | *****************************************************************************/ | 
|  | CPVRTResourceFile::~CPVRTResourceFile() | 
|  | { | 
|  | Close(); | 
|  | } | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @Function			IsOpen | 
|  | @Returns			true if the file is open | 
|  | @Description		Is the file open | 
|  | *****************************************************************************/ | 
|  | bool CPVRTResourceFile::IsOpen() const | 
|  | { | 
|  | return m_bOpen; | 
|  | } | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @Function			IsMemoryFile | 
|  | @Returns			true if the file was opened from memory | 
|  | @Description		Was the file opened from memory | 
|  | *****************************************************************************/ | 
|  | bool CPVRTResourceFile::IsMemoryFile() const | 
|  | { | 
|  | return m_bMemoryFile; | 
|  | } | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @Function			Size | 
|  | @Returns			The size of the opened file | 
|  | @Description		Returns the size of the opened file | 
|  | *****************************************************************************/ | 
|  | size_t CPVRTResourceFile::Size() const | 
|  | { | 
|  | return m_Size; | 
|  | } | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @Function			DataPtr | 
|  | @Returns			A pointer to the file data | 
|  | @Description		Returns a pointer to the file data | 
|  | *****************************************************************************/ | 
|  | const void* CPVRTResourceFile::DataPtr() const | 
|  | { | 
|  | return m_pData; | 
|  | } | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @Function			Close | 
|  | @Description		Closes the file | 
|  | *****************************************************************************/ | 
|  | void CPVRTResourceFile::Close() | 
|  | { | 
|  | if (m_bOpen) | 
|  | { | 
|  | if (!m_bMemoryFile && s_pReleaseFileFunc) | 
|  | { | 
|  | s_pReleaseFileFunc(m_Handle); | 
|  | } | 
|  |  | 
|  | m_bMemoryFile = false; | 
|  | m_bOpen = false; | 
|  | m_pData = 0; | 
|  | m_Size = 0; | 
|  | } | 
|  | } | 
|  |  | 
|  | /**************************************************************************** | 
|  | ** class CPVRTMemoryFileSystem | 
|  | ****************************************************************************/ | 
|  | CPVRTMemoryFileSystem::CAtExit CPVRTMemoryFileSystem::s_AtExit; | 
|  | CPVRTMemoryFileSystem::SFileInfo* CPVRTMemoryFileSystem::s_pFileInfo = 0; | 
|  | int CPVRTMemoryFileSystem::s_i32Capacity = 0; | 
|  | int CPVRTMemoryFileSystem::s_i32NumFiles = 0; | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @Function		Destructor | 
|  | @Description	Destructor of CAtExit class. Workaround for platforms that | 
|  | don't support the atexit() function. This deletes any memory | 
|  | file system data. | 
|  | *****************************************************************************/ | 
|  | CPVRTMemoryFileSystem::CAtExit::~CAtExit() | 
|  | { | 
|  | for (int i = 0; i < CPVRTMemoryFileSystem::s_i32NumFiles; ++i) | 
|  | { | 
|  | if (CPVRTMemoryFileSystem::s_pFileInfo[i].bAllocated) | 
|  | { | 
|  | delete [] (char*)CPVRTMemoryFileSystem::s_pFileInfo[i].pszFilename; | 
|  | delete [] (char*)CPVRTMemoryFileSystem::s_pFileInfo[i].pBuffer; | 
|  | } | 
|  | } | 
|  | delete [] CPVRTMemoryFileSystem::s_pFileInfo; | 
|  | } | 
|  |  | 
|  | CPVRTMemoryFileSystem::CPVRTMemoryFileSystem(const char* pszFilename, const void* pBuffer, size_t Size, bool bCopy) | 
|  | { | 
|  | RegisterMemoryFile(pszFilename, pBuffer, Size, bCopy); | 
|  | } | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @Function		RegisterMemoryFile | 
|  | @Input			pszFilename		Name of file to register | 
|  | @Input			pBuffer			Pointer to file data | 
|  | @Input			Size			File size | 
|  | @Input			bCopy			Name and data should be copied? | 
|  | @Description	Registers a block of memory as a file that can be looked up | 
|  | by name. | 
|  | *****************************************************************************/ | 
|  | void CPVRTMemoryFileSystem::RegisterMemoryFile(const char* pszFilename, const void* pBuffer, size_t Size, bool bCopy) | 
|  | { | 
|  | if (s_i32NumFiles == s_i32Capacity) | 
|  | { | 
|  | SFileInfo* pFileInfo = new SFileInfo[s_i32Capacity + 10]; | 
|  | memcpy(pFileInfo, s_pFileInfo, sizeof(SFileInfo) * s_i32Capacity); | 
|  | delete [] s_pFileInfo; | 
|  | s_pFileInfo = pFileInfo; | 
|  | s_i32Capacity += 10; | 
|  | } | 
|  |  | 
|  | s_pFileInfo[s_i32NumFiles].pszFilename = pszFilename; | 
|  | s_pFileInfo[s_i32NumFiles].pBuffer = pBuffer; | 
|  | if (bCopy) | 
|  | { | 
|  | char* pszNewFilename = new char[strlen(pszFilename) + 1]; | 
|  | strcpy(pszNewFilename, pszFilename); | 
|  | s_pFileInfo[s_i32NumFiles].pszFilename = pszNewFilename; | 
|  |  | 
|  | void* pszNewBuffer = new char[Size]; | 
|  | memcpy(pszNewBuffer, pBuffer, Size); | 
|  | s_pFileInfo[s_i32NumFiles].pBuffer = pszNewBuffer; | 
|  | } | 
|  | s_pFileInfo[s_i32NumFiles].Size = Size; | 
|  | s_pFileInfo[s_i32NumFiles].bAllocated = bCopy; | 
|  | ++s_i32NumFiles; | 
|  | } | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @Function		GetFile | 
|  | @Input			pszFilename		Name of file to open | 
|  | @Output			ppBuffer		Pointer to file data | 
|  | @Output			pSize			File size | 
|  | @Return			true if the file was found in memory, false otherwise | 
|  | @Description	Looks up a file in the memory file system by name. Returns a | 
|  | pointer to the file data as well as its size on success. | 
|  | *****************************************************************************/ | 
|  | bool CPVRTMemoryFileSystem::GetFile(const char* pszFilename, const void** ppBuffer, size_t* pSize) | 
|  | { | 
|  | for (int i = 0; i < s_i32NumFiles; ++i) | 
|  | { | 
|  | if (strcmp(s_pFileInfo[i].pszFilename, pszFilename) == 0) | 
|  | { | 
|  | if (ppBuffer) *ppBuffer = s_pFileInfo[i].pBuffer; | 
|  | if (pSize) *pSize = s_pFileInfo[i].Size; | 
|  | return true; | 
|  | } | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @Function		GetNumFiles | 
|  | @Return			The number of registered files | 
|  | @Description	Getter for the number of registered files | 
|  | *****************************************************************************/ | 
|  | int CPVRTMemoryFileSystem::GetNumFiles() | 
|  | { | 
|  | return s_i32NumFiles; | 
|  | } | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @Function		GetFilename | 
|  | @Input			i32Index		Index of file | 
|  | @Return			A pointer to the filename of the requested file | 
|  | @Description	Looks up a file in the memory file system by name. Returns a | 
|  | pointer to the file data as well as its size on success. | 
|  | *****************************************************************************/ | 
|  | const char* CPVRTMemoryFileSystem::GetFilename(int i32Index) | 
|  | { | 
|  | if (i32Index < 0 || i32Index > s_i32NumFiles) return 0; | 
|  |  | 
|  | return s_pFileInfo[i32Index].pszFilename; | 
|  | } | 
|  |  | 
|  |  | 
|  | /***************************************************************************** | 
|  | End of file (PVRTResourceFile.cpp) | 
|  | *****************************************************************************/ |