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
LoadFileFunc(const char * pFilename,char ** pData,size_t & size)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
ReleaseFileFunc(void * handle)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 *****************************************************************************/
SetReadPath(const char * const pszReadPath)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 *****************************************************************************/
GetReadPath()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 *****************************************************************************/
SetLoadReleaseFunctions(void * pLoadFileFunc,void * pReleaseFileFunc)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 *****************************************************************************/
CPVRTResourceFile(const char * const pszFilename)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 *****************************************************************************/
CPVRTResourceFile(const char * pData,size_t i32Size)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 *****************************************************************************/
~CPVRTResourceFile()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 *****************************************************************************/
IsOpen() const168 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 *****************************************************************************/
IsMemoryFile() const178 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 *****************************************************************************/
Size() const188 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 *****************************************************************************/
DataPtr() const198 const void* CPVRTResourceFile::DataPtr() const
199 {
200 return m_pData;
201 }
202
203 /*!***************************************************************************
204 @Function Close
205 @Description Closes the file
206 *****************************************************************************/
Close()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 *****************************************************************************/
~CAtExit()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
CPVRTMemoryFileSystem(const char * pszFilename,const void * pBuffer,size_t Size,bool bCopy)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 *****************************************************************************/
RegisterMemoryFile(const char * pszFilename,const void * pBuffer,size_t Size,bool bCopy)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 *****************************************************************************/
GetFile(const char * pszFilename,const void ** ppBuffer,size_t * pSize)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 *****************************************************************************/
GetNumFiles()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 *****************************************************************************/
GetFilename(int i32Index)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