1/****************************************************************************** 2 3 @File PVRTResourceFile.cpp 4 5 @Title PVRTResourceFile.cpp 6 7 @Version 8 9 @Copyright Copyright (c) Imagination Technologies Limited. 10 11 @Platform ANSI compatible 12 13 @Description Simple resource file wrapper 14 15******************************************************************************/ 16 17#include "PVRTResourceFile.h" 18#include <stdio.h> 19#include <string.h> 20 21#include "PVRTResourceFile.h" 22#include "PVRTString.h" 23#include "PVRTMemoryFileSystem.h" 24 25CPVRTString CPVRTResourceFile::s_ReadPath; 26 27static void* LoadFileFunc(const char* pFilename, char** pData, size_t &size) 28{ 29 size = 0; 30 31 FILE* pFile = fopen(pFilename, "rb"); 32 33 if (pFile) 34 { 35 // Get the file size 36 fseek(pFile, 0, SEEK_END); 37 size = ftell(pFile); 38 fseek(pFile, 0, SEEK_SET); 39 40 // read the data 41 char* pTmp = new char[size]; 42 size_t BytesRead = fread(pTmp, 1, size, pFile); 43 44 if (BytesRead != size) 45 { 46 delete [] pTmp; 47 pTmp = NULL; 48 size = 0; 49 } 50 else 51 *pData = pTmp; 52 53 fclose(pFile); 54 return pTmp; 55 } 56 57 return 0; 58} 59 60static bool ReleaseFileFunc(void* handle) 61{ 62 if(handle) 63 { 64 delete[] (char*) handle; 65 return true; 66 } 67 68 return false; 69} 70 71PFNLoadFileFunc CPVRTResourceFile::s_pLoadFileFunc = &LoadFileFunc; 72PFNReleaseFileFunc CPVRTResourceFile::s_pReleaseFileFunc = &ReleaseFileFunc; 73 74/*!*************************************************************************** 75@Function SetReadPath 76@Input pszReadPath The path where you would like to read from 77@Description Sets the read path 78*****************************************************************************/ 79void CPVRTResourceFile::SetReadPath(const char* const pszReadPath) 80{ 81 s_ReadPath = (pszReadPath) ? pszReadPath : ""; 82} 83 84/*!*************************************************************************** 85@Function GetReadPath 86@Returns The currently set read path 87@Description Returns the currently set read path 88*****************************************************************************/ 89CPVRTString CPVRTResourceFile::GetReadPath() 90{ 91 return CPVRTString(s_ReadPath); 92} 93 94/*!*************************************************************************** 95@Function SetLoadReleaseFunctions 96@Input pLoadFileFunc Function to use for opening a file 97@Input pReleaseFileFunc Function to release any data allocated by the load function 98@Description This function is used to override the CPVRTResource file loading functions. If 99 you pass NULL in as the load function CPVRTResource will use the default functions. 100*****************************************************************************/ 101void CPVRTResourceFile::SetLoadReleaseFunctions(void* pLoadFileFunc, void* pReleaseFileFunc) 102{ 103 if(pLoadFileFunc) 104 { 105 s_pLoadFileFunc = (PFNLoadFileFunc) pLoadFileFunc; 106 s_pReleaseFileFunc = (PFNReleaseFileFunc) pReleaseFileFunc; 107 } 108 else 109 { 110 s_pLoadFileFunc = &LoadFileFunc; 111 s_pReleaseFileFunc = &ReleaseFileFunc; 112 } 113} 114 115/*!*************************************************************************** 116@Function CPVRTResourceFile 117@Input pszFilename Name of the file you would like to open 118@Description Constructor 119*****************************************************************************/ 120CPVRTResourceFile::CPVRTResourceFile(const char* const pszFilename) : 121 m_bOpen(false), 122 m_bMemoryFile(false), 123 m_Size(0), 124 m_pData(0), 125 m_Handle(0) 126{ 127 CPVRTString Path(s_ReadPath); 128 Path += pszFilename; 129 130 m_Handle = s_pLoadFileFunc(Path.c_str(), (char**) &m_pData, m_Size); 131 m_bOpen = (m_pData && m_Size) != 0; 132 133 if (!m_bOpen) 134 { 135 m_bOpen = m_bMemoryFile = CPVRTMemoryFileSystem::GetFile(pszFilename, (const void**)(&m_pData), &m_Size); 136 } 137} 138 139/*!*************************************************************************** 140@Function CPVRTResourceFile 141@Input pData A pointer to the data you would like to use 142@Input i32Size The size of the data 143@Description Constructor 144*****************************************************************************/ 145CPVRTResourceFile::CPVRTResourceFile(const char* pData, size_t i32Size) : 146 m_bOpen(true), 147 m_bMemoryFile(true), 148 m_Size(i32Size), 149 m_pData(pData), 150 m_Handle(0) 151{ 152} 153 154/*!*************************************************************************** 155@Function ~CPVRTResourceFile 156@Description Destructor 157*****************************************************************************/ 158CPVRTResourceFile::~CPVRTResourceFile() 159{ 160 Close(); 161} 162 163/*!*************************************************************************** 164@Function IsOpen 165@Returns true if the file is open 166@Description Is the file open 167*****************************************************************************/ 168bool CPVRTResourceFile::IsOpen() const 169{ 170 return m_bOpen; 171} 172 173/*!*************************************************************************** 174@Function IsMemoryFile 175@Returns true if the file was opened from memory 176@Description Was the file opened from memory 177*****************************************************************************/ 178bool CPVRTResourceFile::IsMemoryFile() const 179{ 180 return m_bMemoryFile; 181} 182 183/*!*************************************************************************** 184@Function Size 185@Returns The size of the opened file 186@Description Returns the size of the opened file 187*****************************************************************************/ 188size_t CPVRTResourceFile::Size() const 189{ 190 return m_Size; 191} 192 193/*!*************************************************************************** 194@Function DataPtr 195@Returns A pointer to the file data 196@Description Returns a pointer to the file data 197*****************************************************************************/ 198const void* CPVRTResourceFile::DataPtr() const 199{ 200 return m_pData; 201} 202 203/*!*************************************************************************** 204@Function Close 205@Description Closes the file 206*****************************************************************************/ 207void CPVRTResourceFile::Close() 208{ 209 if (m_bOpen) 210 { 211 if (!m_bMemoryFile && s_pReleaseFileFunc) 212 { 213 s_pReleaseFileFunc(m_Handle); 214 } 215 216 m_bMemoryFile = false; 217 m_bOpen = false; 218 m_pData = 0; 219 m_Size = 0; 220 } 221} 222 223/**************************************************************************** 224** class CPVRTMemoryFileSystem 225****************************************************************************/ 226CPVRTMemoryFileSystem::CAtExit CPVRTMemoryFileSystem::s_AtExit; 227CPVRTMemoryFileSystem::SFileInfo* CPVRTMemoryFileSystem::s_pFileInfo = 0; 228int CPVRTMemoryFileSystem::s_i32Capacity = 0; 229int CPVRTMemoryFileSystem::s_i32NumFiles = 0; 230 231/*!*************************************************************************** 232@Function Destructor 233@Description Destructor of CAtExit class. Workaround for platforms that 234 don't support the atexit() function. This deletes any memory 235 file system data. 236*****************************************************************************/ 237CPVRTMemoryFileSystem::CAtExit::~CAtExit() 238{ 239 for (int i = 0; i < CPVRTMemoryFileSystem::s_i32NumFiles; ++i) 240 { 241 if (CPVRTMemoryFileSystem::s_pFileInfo[i].bAllocated) 242 { 243 delete [] (char*)CPVRTMemoryFileSystem::s_pFileInfo[i].pszFilename; 244 delete [] (char*)CPVRTMemoryFileSystem::s_pFileInfo[i].pBuffer; 245 } 246 } 247 delete [] CPVRTMemoryFileSystem::s_pFileInfo; 248} 249 250CPVRTMemoryFileSystem::CPVRTMemoryFileSystem(const char* pszFilename, const void* pBuffer, size_t Size, bool bCopy) 251{ 252 RegisterMemoryFile(pszFilename, pBuffer, Size, bCopy); 253} 254 255/*!*************************************************************************** 256@Function RegisterMemoryFile 257@Input pszFilename Name of file to register 258@Input pBuffer Pointer to file data 259@Input Size File size 260@Input bCopy Name and data should be copied? 261@Description Registers a block of memory as a file that can be looked up 262 by name. 263*****************************************************************************/ 264void CPVRTMemoryFileSystem::RegisterMemoryFile(const char* pszFilename, const void* pBuffer, size_t Size, bool bCopy) 265{ 266 if (s_i32NumFiles == s_i32Capacity) 267 { 268 SFileInfo* pFileInfo = new SFileInfo[s_i32Capacity + 10]; 269 memcpy(pFileInfo, s_pFileInfo, sizeof(SFileInfo) * s_i32Capacity); 270 delete [] s_pFileInfo; 271 s_pFileInfo = pFileInfo; 272 s_i32Capacity += 10; 273 } 274 275 s_pFileInfo[s_i32NumFiles].pszFilename = pszFilename; 276 s_pFileInfo[s_i32NumFiles].pBuffer = pBuffer; 277 if (bCopy) 278 { 279 char* pszNewFilename = new char[strlen(pszFilename) + 1]; 280 strcpy(pszNewFilename, pszFilename); 281 s_pFileInfo[s_i32NumFiles].pszFilename = pszNewFilename; 282 283 void* pszNewBuffer = new char[Size]; 284 memcpy(pszNewBuffer, pBuffer, Size); 285 s_pFileInfo[s_i32NumFiles].pBuffer = pszNewBuffer; 286 } 287 s_pFileInfo[s_i32NumFiles].Size = Size; 288 s_pFileInfo[s_i32NumFiles].bAllocated = bCopy; 289 ++s_i32NumFiles; 290} 291 292/*!*************************************************************************** 293@Function GetFile 294@Input pszFilename Name of file to open 295@Output ppBuffer Pointer to file data 296@Output pSize File size 297@Return true if the file was found in memory, false otherwise 298@Description Looks up a file in the memory file system by name. Returns a 299 pointer to the file data as well as its size on success. 300*****************************************************************************/ 301bool CPVRTMemoryFileSystem::GetFile(const char* pszFilename, const void** ppBuffer, size_t* pSize) 302{ 303 for (int i = 0; i < s_i32NumFiles; ++i) 304 { 305 if (strcmp(s_pFileInfo[i].pszFilename, pszFilename) == 0) 306 { 307 if (ppBuffer) *ppBuffer = s_pFileInfo[i].pBuffer; 308 if (pSize) *pSize = s_pFileInfo[i].Size; 309 return true; 310 } 311 } 312 return false; 313} 314 315/*!*************************************************************************** 316@Function GetNumFiles 317@Return The number of registered files 318@Description Getter for the number of registered files 319*****************************************************************************/ 320int CPVRTMemoryFileSystem::GetNumFiles() 321{ 322 return s_i32NumFiles; 323} 324 325/*!*************************************************************************** 326@Function GetFilename 327@Input i32Index Index of file 328@Return A pointer to the filename of the requested file 329@Description Looks up a file in the memory file system by name. Returns a 330 pointer to the file data as well as its size on success. 331*****************************************************************************/ 332const char* CPVRTMemoryFileSystem::GetFilename(int i32Index) 333{ 334 if (i32Index < 0 || i32Index > s_i32NumFiles) return 0; 335 336 return s_pFileInfo[i32Index].pszFilename; 337} 338 339 340/***************************************************************************** 341 End of file (PVRTResourceFile.cpp) 342*****************************************************************************/ 343