Mercurial > projects > hoofbaby
comparison deps/Platinum/ThirdParty/Neptune/Source/System/PSP/NptPSPFile.cpp @ 0:3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
author | fraserofthenight |
---|---|
date | Mon, 06 Jul 2009 08:06:28 -0700 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:3425707ddbf6 |
---|---|
1 /***************************************************************** | |
2 | | |
3 | Neptune - File Byte Stream :: Standard C Implementation | |
4 | | |
5 | (c) 2001-2003 Gilles Boccon-Gibod | |
6 | Author: Gilles Boccon-Gibod (bok@bok.net) | |
7 | | |
8 ****************************************************************/ | |
9 | |
10 /*---------------------------------------------------------------------- | |
11 | includes | |
12 +---------------------------------------------------------------------*/ | |
13 #include <stdio.h> | |
14 #include <string.h> | |
15 #include <malloc.h> | |
16 | |
17 #include <kernel.h> | |
18 #include <psptypes.h> | |
19 #include <psperror.h> | |
20 #include <mediaman.h> | |
21 #include <umderror.h> | |
22 #include <fatms.h> | |
23 | |
24 #include "NptFile.h" | |
25 | |
26 /*---------------------------------------------------------------------- | |
27 | NPT_PSPFileWrapper | |
28 +---------------------------------------------------------------------*/ | |
29 class NPT_PSPFileWrapper | |
30 { | |
31 public: | |
32 // constructors and destructor | |
33 NPT_PSPFileWrapper(SceUID file) : m_File(file) {} | |
34 ~NPT_PSPFileWrapper() { | |
35 if (m_File >= 0) { | |
36 sceIoClose(m_File); | |
37 } | |
38 } | |
39 | |
40 // methods | |
41 SceUID GetFile() { return m_File; } | |
42 | |
43 private: | |
44 // members | |
45 SceUID m_File; | |
46 }; | |
47 | |
48 typedef NPT_Reference<NPT_PSPFileWrapper> NPT_PSPFileReference; | |
49 | |
50 /*---------------------------------------------------------------------- | |
51 | NPT_PSPFileStream | |
52 +---------------------------------------------------------------------*/ | |
53 class NPT_PSPFileStream | |
54 { | |
55 public: | |
56 // constructors and destructor | |
57 NPT_PSPFileStream(NPT_PSPFileReference file) : | |
58 m_FileReference(file), m_Position(0) {} | |
59 | |
60 // NPT_FileInterface methods | |
61 NPT_Result Seek(NPT_Offset offset); | |
62 NPT_Result Tell(NPT_Offset& offset); | |
63 | |
64 protected: | |
65 // constructors and destructors | |
66 virtual ~NPT_PSPFileStream() {} | |
67 | |
68 // members | |
69 NPT_PSPFileReference m_FileReference; | |
70 SceOff m_Position; | |
71 }; | |
72 | |
73 /*---------------------------------------------------------------------- | |
74 | NPT_PSPFileStream::Seek | |
75 +---------------------------------------------------------------------*/ | |
76 NPT_Result | |
77 NPT_PSPFileStream::Seek(NPT_Offset offset) | |
78 { | |
79 SceOff result; | |
80 | |
81 result = sceIoLseek(m_FileReference->GetFile(), offset, SEEK_SET); | |
82 if (result >= 0) { | |
83 m_Position = offset; | |
84 return NPT_SUCCESS; | |
85 } else { | |
86 return NPT_FAILURE; | |
87 } | |
88 } | |
89 | |
90 /*---------------------------------------------------------------------- | |
91 | NPT_PSPFileStream::Tell | |
92 +---------------------------------------------------------------------*/ | |
93 NPT_Result | |
94 NPT_PSPFileStream::Tell(NPT_Offset& offset) | |
95 { | |
96 offset = m_Position; | |
97 return NPT_SUCCESS; | |
98 } | |
99 | |
100 /*---------------------------------------------------------------------- | |
101 | NPT_PSPFileInputStream | |
102 +---------------------------------------------------------------------*/ | |
103 class NPT_PSPFileInputStream : public NPT_InputStream, | |
104 private NPT_PSPFileStream | |
105 | |
106 { | |
107 public: | |
108 // constructors and destructor | |
109 NPT_PSPFileInputStream(NPT_PSPFileReference& file, NPT_Size size) : | |
110 NPT_PSPFileStream(file), m_Size(size) {} | |
111 | |
112 // NPT_InputStream methods | |
113 NPT_Result Read(void* buffer, | |
114 NPT_Size bytes_to_read, | |
115 NPT_Size* bytes_read); | |
116 NPT_Result Seek(NPT_Offset offset) { | |
117 return NPT_PSPFileStream::Seek(offset); | |
118 } | |
119 NPT_Result Tell(NPT_Offset& offset) { | |
120 return NPT_PSPFileStream::Tell(offset); | |
121 } | |
122 NPT_Result GetSize(NPT_Size& size); | |
123 NPT_Result GetAvailable(NPT_Size& available); | |
124 | |
125 private: | |
126 // members | |
127 NPT_Size m_Size; | |
128 }; | |
129 | |
130 /*---------------------------------------------------------------------- | |
131 | NPT_PSPFileInputStream::Read | |
132 +---------------------------------------------------------------------*/ | |
133 NPT_Result | |
134 NPT_PSPFileInputStream::Read(void* buffer, | |
135 NPT_Size bytes_to_read, | |
136 NPT_Size* bytes_read) | |
137 { | |
138 size_t nb_read; | |
139 | |
140 if (buffer == NULL) { | |
141 return NPT_ERROR_INVALID_PARAMETERS; | |
142 } | |
143 | |
144 nb_read = sceIoRead(m_FileReference->GetFile(), (SceChar8*)buffer, bytes_to_read); | |
145 | |
146 if (nb_read > 0) { | |
147 if (bytes_read) *bytes_read = (NPT_Size)nb_read; | |
148 m_Position += nb_read; | |
149 return NPT_SUCCESS; | |
150 } else { | |
151 if (bytes_read) *bytes_read = 0; | |
152 return NPT_ERROR_EOS; | |
153 } | |
154 } | |
155 | |
156 /*---------------------------------------------------------------------- | |
157 | NPT_PSPFileInputStream::GetSize | |
158 +---------------------------------------------------------------------*/ | |
159 NPT_Result | |
160 NPT_PSPFileInputStream::GetSize(NPT_Size& size) | |
161 { | |
162 size = m_Size; | |
163 return NPT_SUCCESS; | |
164 } | |
165 | |
166 /*---------------------------------------------------------------------- | |
167 | NPT_PSPFileInputStream::GetAvailable | |
168 +---------------------------------------------------------------------*/ | |
169 NPT_Result | |
170 NPT_PSPFileInputStream::GetAvailable(NPT_Size& available) | |
171 { | |
172 long offset = m_Position; | |
173 if (offset >= 0 && (NPT_Size)offset <= m_Size) { | |
174 available = m_Size = offset; | |
175 return NPT_SUCCESS; | |
176 } else { | |
177 available = 0; | |
178 return NPT_FAILURE; | |
179 } | |
180 } | |
181 | |
182 /*---------------------------------------------------------------------- | |
183 | NPT_PSPFileOutputStream | |
184 +---------------------------------------------------------------------*/ | |
185 class NPT_PSPFileOutputStream : public NPT_OutputStream, | |
186 private NPT_PSPFileStream | |
187 { | |
188 public: | |
189 // constructors and destructor | |
190 NPT_PSPFileOutputStream(NPT_PSPFileReference& file) : | |
191 NPT_PSPFileStream(file) {} | |
192 | |
193 // NPT_InputStream methods | |
194 NPT_Result Write(const void* buffer, | |
195 NPT_Size bytes_to_write, | |
196 NPT_Size* bytes_written); | |
197 NPT_Result Seek(NPT_Offset offset) { | |
198 return NPT_PSPFileStream::Seek(offset); | |
199 } | |
200 NPT_Result Tell(NPT_Offset& offset) { | |
201 return NPT_PSPFileStream::Tell(offset); | |
202 } | |
203 }; | |
204 | |
205 /*---------------------------------------------------------------------- | |
206 | NPT_PSPFileOutputStream::Write | |
207 +---------------------------------------------------------------------*/ | |
208 NPT_Result | |
209 NPT_PSPFileOutputStream::Write(const void* buffer, | |
210 NPT_Size bytes_to_write, | |
211 NPT_Size* bytes_written) | |
212 { | |
213 size_t nb_written; | |
214 | |
215 nb_written = sceIoWrite(m_FileReference->GetFile(), (SceChar8*)buffer, bytes_to_write); | |
216 | |
217 if (nb_written > 0) { | |
218 if (bytes_written) *bytes_written = (NPT_Size)nb_written; | |
219 m_Position += nb_written; | |
220 return NPT_SUCCESS; | |
221 } else { | |
222 if (bytes_written) *bytes_written = 0; | |
223 return NPT_ERROR_WRITE_FAILED; | |
224 } | |
225 } | |
226 | |
227 /*---------------------------------------------------------------------- | |
228 | NPT_PSPFile | |
229 +---------------------------------------------------------------------*/ | |
230 class NPT_PSPFile: public NPT_FileInterface | |
231 { | |
232 public: | |
233 // constructors and destructor | |
234 NPT_PSPFile(const char* name); | |
235 ~NPT_PSPFile(); | |
236 | |
237 // NPT_FileInterface methods | |
238 NPT_Result Open(OpenMode mode); | |
239 NPT_Result Close(); | |
240 NPT_Result GetSize(NPT_Size& size); | |
241 NPT_Result GetInputStream(NPT_InputStreamReference& stream); | |
242 NPT_Result GetOutputStream(NPT_OutputStreamReference& stream); | |
243 | |
244 private: | |
245 // members | |
246 NPT_String m_Name; | |
247 OpenMode m_Mode; | |
248 NPT_PSPFileReference m_FileReference; | |
249 NPT_Size m_Size; | |
250 }; | |
251 | |
252 /*---------------------------------------------------------------------- | |
253 | NPT_PSPFile::NPT_PSPFile | |
254 +---------------------------------------------------------------------*/ | |
255 NPT_PSPFile::NPT_PSPFile(const char* name) : | |
256 m_Name(name), | |
257 m_Mode(0), | |
258 m_Size(0) | |
259 { | |
260 } | |
261 | |
262 /*---------------------------------------------------------------------- | |
263 | NPT_PSPFile::~NPT_PSPFile | |
264 +---------------------------------------------------------------------*/ | |
265 NPT_PSPFile::~NPT_PSPFile() | |
266 { | |
267 Close(); | |
268 } | |
269 | |
270 /*---------------------------------------------------------------------- | |
271 | NPT_PSPFile::Open | |
272 +---------------------------------------------------------------------*/ | |
273 NPT_Result | |
274 NPT_PSPFile::Open(NPT_File::OpenMode mode) | |
275 { | |
276 SceUID file = -1; | |
277 | |
278 // check if we're already open | |
279 if (!m_FileReference.IsNull()) { | |
280 return NPT_ERROR_FILE_ALREADY_OPEN; | |
281 } | |
282 | |
283 // store the mode | |
284 m_Mode = mode; | |
285 | |
286 // check for special names | |
287 const char* name = (const char*)m_Name; | |
288 int flags = 0; | |
289 SceMode perms = 0; // files opened/created on the PSP require certain permissions | |
290 | |
291 /* compute mode */ | |
292 if (mode & NPT_FILE_BYTE_STREAM_MODE_WRITE) { | |
293 perms = 0777; // since we're possibly creating a file, give it full permissions | |
294 if (mode & NPT_FILE_BYTE_STREAM_MODE_CREATE) { | |
295 if (mode & NPT_FILE_BYTE_STREAM_MODE_TRUNCATE) { | |
296 /* write, read, create, truncate */ | |
297 flags = SCE_O_RDWR | SCE_O_CREAT | SCE_O_TRUNC; | |
298 } else { | |
299 /* write, read, create */ | |
300 flags = SCE_O_RDWR | SCE_O_CREAT | SCE_O_APPEND; | |
301 } | |
302 } else { | |
303 if (mode & NPT_FILE_BYTE_STREAM_MODE_TRUNCATE) { | |
304 /* write, read, truncate */ | |
305 flags = SCE_O_RDWR | SCE_O_CREAT | SCE_O_TRUNC; | |
306 } else { | |
307 /* write, read */ | |
308 flags = SCE_O_RDWR; | |
309 } | |
310 } | |
311 } else { | |
312 /* read only */ | |
313 flags = SCE_O_RDONLY; | |
314 } | |
315 | |
316 // open the file | |
317 file = sceIoOpen(name, flags, perms); | |
318 | |
319 // test the result of the open | |
320 if (file < 0) { | |
321 if (file == (SceUID)SCE_ERROR_ERRNO_ENOENT ) { | |
322 return NPT_ERROR_NO_SUCH_FILE; | |
323 } else if (file == (SceUID)SCE_ERROR_ERRNO_EACCESS ) { | |
324 return NPT_ERROR_PERMISSION_DENIED; | |
325 } else { | |
326 return NPT_FAILURE; | |
327 } | |
328 } else { | |
329 // get the size | |
330 SceOff off; | |
331 off = sceIoLseek(file, 0, SCE_SEEK_END); | |
332 if (off >= 0) { | |
333 m_Size = off; | |
334 sceIoLseek(file, 0, SCE_SEEK_SET); | |
335 } | |
336 } | |
337 | |
338 // create a reference to the FILE object | |
339 m_FileReference = new NPT_PSPileWrapper(file); | |
340 | |
341 return NPT_SUCCESS; | |
342 } | |
343 | |
344 /*---------------------------------------------------------------------- | |
345 | NPT_PSPile::Close | |
346 +---------------------------------------------------------------------*/ | |
347 NPT_Result | |
348 NPT_PSPile::Close() | |
349 { | |
350 // release the file reference | |
351 m_FileReference = NULL; | |
352 | |
353 // reset the mode | |
354 m_Mode = 0; | |
355 | |
356 return NPT_SUCCESS; | |
357 } | |
358 | |
359 /*---------------------------------------------------------------------- | |
360 | NPT_PSPile::GetSize | |
361 +---------------------------------------------------------------------*/ | |
362 NPT_Result | |
363 NPT_PSPile::GetSize(NPT_Size& size) | |
364 { | |
365 // default value | |
366 size = 0; | |
367 | |
368 // check that the file is open | |
369 if (m_FileReference.IsNull()) return NPT_ERROR_FILE_NOT_OPEN; | |
370 | |
371 // return the size | |
372 size = m_Size; | |
373 | |
374 return NPT_SUCCESS; | |
375 } | |
376 | |
377 /*---------------------------------------------------------------------- | |
378 | NPT_PSPile::GetInputStream | |
379 +---------------------------------------------------------------------*/ | |
380 NPT_Result | |
381 NPT_PSPile::GetInputStream(NPT_InputStreamReference& stream) | |
382 { | |
383 // default value | |
384 stream = NULL; | |
385 | |
386 // check that the file is open | |
387 if (m_FileReference.IsNull()) return NPT_ERROR_FILE_NOT_OPEN; | |
388 | |
389 // check that the mode is compatible | |
390 if (!(m_Mode & NPT_FILE_OPEN_MODE_READ)) { | |
391 return NPT_ERROR_FILE_NOT_READABLE; | |
392 } | |
393 | |
394 // create a stream | |
395 stream = new NPT_PSPileInputStream(m_FileReference, m_Size); | |
396 | |
397 return NPT_SUCCESS; | |
398 } | |
399 | |
400 /*---------------------------------------------------------------------- | |
401 | NPT_PSPile::GetOutputStream | |
402 +---------------------------------------------------------------------*/ | |
403 NPT_Result | |
404 NPT_PSPile::GetOutputStream(NPT_OutputStreamReference& stream) | |
405 { | |
406 // default value | |
407 stream = NULL; | |
408 | |
409 // check that the file is open | |
410 if (m_FileReference.IsNull()) return NPT_ERROR_FILE_NOT_OPEN; | |
411 | |
412 // check that the mode is compatible | |
413 if (!(m_Mode & NPT_FILE_OPEN_MODE_WRITE)) { | |
414 return NPT_ERROR_FILE_NOT_WRITABLE; | |
415 } | |
416 | |
417 // create a stream | |
418 stream = new NPT_PSPileOutputStream(m_FileReference); | |
419 | |
420 return NPT_SUCCESS; | |
421 } | |
422 | |
423 /*---------------------------------------------------------------------- | |
424 | NPT_File::NPT_File | |
425 +---------------------------------------------------------------------*/ | |
426 NPT_File::NPT_File(const char* name) | |
427 { | |
428 m_Delegate = new NPT_PSPile(name); | |
429 } | |
430 | |
431 | |
432 | |
433 | |
434 | |
435 | |
436 | |
437 | |
438 | |
439 | |
440 | |
441 |