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 25 CPVRTString CPVRTResourceFile::s_ReadPath; 26 27 static 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 60 static bool ReleaseFileFunc(void* handle) 61 { 62 if(handle) 63 { 64 delete[] (char*) handle; 65 return true; 66 } 67 68 return false; 69 } 70 71 PFNLoadFileFunc CPVRTResourceFile::s_pLoadFileFunc = &LoadFileFunc; 72 PFNReleaseFileFunc 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 *****************************************************************************/ 79 void 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 *****************************************************************************/ 89 CPVRTString 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 *****************************************************************************/ 101 void 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 *****************************************************************************/ 120 CPVRTResourceFile::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 *****************************************************************************/ 145 CPVRTResourceFile::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 *****************************************************************************/ 158 CPVRTResourceFile::~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 *****************************************************************************/ 168 bool 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 *****************************************************************************/ 178 bool 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 *****************************************************************************/ 188 size_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 *****************************************************************************/ 198 const void* CPVRTResourceFile::DataPtr() const 199 { 200 return m_pData; 201 } 202 203 /*!*************************************************************************** 204 @Function Close 205 @Description Closes the file 206 *****************************************************************************/ 207 void 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 ****************************************************************************/ 226 CPVRTMemoryFileSystem::CAtExit CPVRTMemoryFileSystem::s_AtExit; 227 CPVRTMemoryFileSystem::SFileInfo* CPVRTMemoryFileSystem::s_pFileInfo = 0; 228 int CPVRTMemoryFileSystem::s_i32Capacity = 0; 229 int 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 *****************************************************************************/ 237 CPVRTMemoryFileSystem::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 250 CPVRTMemoryFileSystem::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 *****************************************************************************/ 264 void 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 *****************************************************************************/ 301 bool 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 *****************************************************************************/ 320 int 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 *****************************************************************************/ 332 const 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