linuxport: Merging in the fruits of my labors (Python VFS)
[xbmc:xbmc-antiquated.git] / xbmc / cores / DllLoader / exports / util / EmuFileWrapper.cpp
1 /*
2  *      Copyright (C) 2005-2008 Team XBMC
3  *      http://www.xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, write to
17  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18  *  http://www.gnu.org/copyleft/gpl.html
19  *
20  */
21  
22 #include "stdafx.h"
23 #include "EmuFileWrapper.h"
24 #include "FileSystem/File.h"
25 #include "utils/Mutex.h"
26
27 CEmuFileWrapper g_emuFileWrapper;
28
29 CEmuFileWrapper::CEmuFileWrapper()
30 {
31   InitializeCriticalSection(&m_criticalSection);
32
33   // since we always use dlls we might just initialize it directly
34   for (int i = 0; i < MAX_EMULATED_FILES; i++)
35   {
36     memset(&m_files[i], 0, sizeof(EmuFileObject));
37     m_files[i].used = false;
38     m_files[i].file_emu._file = -1;
39   }
40 }
41
42 CEmuFileWrapper::~CEmuFileWrapper()
43 {
44   DeleteCriticalSection(&m_criticalSection);
45 }
46
47 void CEmuFileWrapper::CleanUp()
48 {
49   EnterCriticalSection(&m_criticalSection);
50   for (int i = 0; i < MAX_EMULATED_FILES; i++)
51   {
52     if (m_files[i].used)
53     {
54       m_files[i].file_xbmc->Close();
55       delete m_files[i].file_xbmc;
56
57       if (m_files[i].file_lock)
58       {
59         delete m_files[i].file_lock;
60         m_files[i].file_lock = NULL;
61       }
62       memset(&m_files[i], 0, sizeof(EmuFileObject));
63       m_files[i].used = false;
64       m_files[i].file_emu._file = -1;
65     }
66   }
67   LeaveCriticalSection(&m_criticalSection);
68 }
69
70 EmuFileObject* CEmuFileWrapper::RegisterFileObject(XFILE::CFile* pFile)
71 {
72   EmuFileObject* object = NULL;
73
74   EnterCriticalSection(&m_criticalSection);
75
76   for (int i = 0; i < MAX_EMULATED_FILES; i++)
77   {
78     if (!m_files[i].used)
79     {
80       // found a free location
81       object = &m_files[i];
82       object->used = true;
83       object->file_xbmc = pFile;
84       object->file_emu._file = (i + FILE_WRAPPER_OFFSET);
85       object->file_lock = new CMutex();
86       break;
87     }
88   }
89
90   LeaveCriticalSection(&m_criticalSection);
91
92   return object;
93 }
94
95 void CEmuFileWrapper::UnRegisterFileObjectByDescriptor(int fd)
96 {
97   int i = fd - FILE_WRAPPER_OFFSET;
98   if (i >= 0 && i < MAX_EMULATED_FILES)
99   {
100     if (m_files[i].used)
101     {
102       EnterCriticalSection(&m_criticalSection);
103
104       // we assume the emulated function alreay deleted the CFile object
105       if (m_files[i].used)
106       {
107         if (m_files[i].file_lock)
108         {
109           delete m_files[i].file_lock;
110           m_files[i].file_lock = NULL;
111         }
112         memset(&m_files[i], 0, sizeof(EmuFileObject));
113         m_files[i].used = false;
114         m_files[i].file_emu._file = -1;
115       }
116
117       LeaveCriticalSection(&m_criticalSection);
118     }
119   }
120 }
121
122 void CEmuFileWrapper::UnRegisterFileObjectByStream(FILE* stream)
123 {
124   if (stream != NULL)
125   {
126     return UnRegisterFileObjectByDescriptor(stream->_file);
127   }
128 }
129
130 void CEmuFileWrapper::LockFileObjectByDescriptor(int fd)
131 {
132   int i = fd - FILE_WRAPPER_OFFSET;
133   if (i >= 0 && i < MAX_EMULATED_FILES)
134   {
135     if (m_files[i].used)
136     {
137       m_files[i].file_lock->Wait();
138     }
139   }
140 }
141
142 bool CEmuFileWrapper::TryLockFileObjectByDescriptor(int fd)
143
144   int i = fd - FILE_WRAPPER_OFFSET;  
145   if (i >= 0 && i < MAX_EMULATED_FILES)
146   { 
147     if (m_files[i].used)
148     {   
149       return m_files[i].file_lock->WaitMSec(0);
150     }
151   }
152   return false;
153 }
154
155 void CEmuFileWrapper::UnlockFileObjectByDescriptor(int fd)
156
157   int i = fd - FILE_WRAPPER_OFFSET;  
158   if (i >= 0 && i < MAX_EMULATED_FILES)
159   { 
160     if (m_files[i].used)
161     {   
162       m_files[i].file_lock->Release();
163     }
164   }
165 }
166
167 EmuFileObject* CEmuFileWrapper::GetFileObjectByDescriptor(int fd)
168 {
169   int i = fd - FILE_WRAPPER_OFFSET;
170   if (i >= 0 && i < MAX_EMULATED_FILES)
171   {
172     if (m_files[i].used)
173     {
174       return &m_files[i];
175     }
176   }
177   return NULL;
178 }
179
180 EmuFileObject* CEmuFileWrapper::GetFileObjectByStream(FILE* stream)
181 {
182   if (stream != NULL)
183   {
184     return GetFileObjectByDescriptor(stream->_file);
185   }
186
187   return NULL;
188 }
189
190 XFILE::CFile* CEmuFileWrapper::GetFileXbmcByDescriptor(int fd)
191 {
192   EmuFileObject* object = GetFileObjectByDescriptor(fd);
193   if (object != NULL && object->used)
194   {
195     return object->file_xbmc;
196   }
197   return NULL;
198 }
199
200 XFILE::CFile* CEmuFileWrapper::GetFileXbmcByStream(FILE* stream)
201 {
202   if (stream != NULL)
203   {
204     EmuFileObject* object = GetFileObjectByDescriptor(stream->_file);
205     if (object != NULL && object->used)
206     {
207       return object->file_xbmc;
208     }
209   }
210   return NULL;
211 }
212
213 int CEmuFileWrapper::GetDescriptorByStream(FILE* stream)
214 {
215   if (stream != NULL)
216   {
217     int i = stream->_file - FILE_WRAPPER_OFFSET;
218     if (i >= 0 && i < MAX_EMULATED_FILES)
219     {
220       return stream->_file;
221     }
222   }
223   return -1;
224 }
225
226 FILE* CEmuFileWrapper::GetStreamByDescriptor(int fd)
227 {
228   EmuFileObject* object = GetFileObjectByDescriptor(fd);
229   if (object != NULL && object->used)
230   {
231     return &object->file_emu;
232   }
233   return NULL;
234 }
235
236 bool CEmuFileWrapper::DescriptorIsEmulatedFile(int fd)
237 {
238   int i = fd - FILE_WRAPPER_OFFSET;
239   if (i >= 0 && i < MAX_EMULATED_FILES)
240   {
241     return true;
242   }
243   return false;
244 }
245
246 bool CEmuFileWrapper::StreamIsEmulatedFile(FILE* stream)
247 {
248   if (stream != NULL)
249   {
250     return DescriptorIsEmulatedFile(stream->_file);
251   }
252   return false;
253 }