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