| /****************************************************************************** | |
| @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) | |
| *****************************************************************************/ |