blob: d92abe3ad27cd8133e6b59812511e51813c59fc0 [file] [log] [blame]
Nicolas Capens7b21f272014-06-04 22:51:10 -04001/******************************************************************************
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*****************************************************************************/