• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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