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