mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-13 09:35:23 -04:00
PSP: Use native PSP APIs for I/O rather than libc APIs
This commit is contained in:
parent
159f0d5f56
commit
a8a40c18e4
@ -11,12 +11,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <pspkernel.h>
|
#include <pspkernel.h>
|
||||||
#include <pspnet_inet.h>
|
#include <pspnet_inet.h>
|
||||||
#include <pspnet_resolver.h>
|
#include <pspnet_resolver.h>
|
||||||
@ -72,8 +67,11 @@ void Platform_Log(const char* msg, int len) {
|
|||||||
sceIoWrite(fd, msg, len);
|
sceIoWrite(fd, msg, len);
|
||||||
sceIoWrite(fd, "\n", 1);
|
sceIoWrite(fd, "\n", 1);
|
||||||
|
|
||||||
//pspDebugSioPutData(msg, len);
|
//sceIoDevctl("emulator:", 2, msg, len, NULL, 0);
|
||||||
//pspDebugSioPutData("\n", 1);
|
//cc_string str = String_Init(msg, len, len);
|
||||||
|
//cc_file file = 0;
|
||||||
|
//File_Open(&file, &str);
|
||||||
|
//File_Close(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define UnixTime_TotalMS(time) ((cc_uint64)time.tv_sec * 1000 + UNIX_EPOCH + (time.tv_usec / 1000))
|
#define UnixTime_TotalMS(time) ((cc_uint64)time.tv_sec * 1000 + UNIX_EPOCH + (time.tv_usec / 1000))
|
||||||
@ -109,112 +107,122 @@ cc_uint64 Stopwatch_Measure(void) {
|
|||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
void Directory_GetCachePath(cc_string* path) { }
|
void Directory_GetCachePath(cc_string* path) { }
|
||||||
|
|
||||||
|
extern int __path_absolute(const char *in, char *out, int len);
|
||||||
|
static void GetNativePath(char* str, const cc_string* path) {
|
||||||
|
char tmp[NATIVE_STR_LEN + 1];
|
||||||
|
String_EncodeUtf8(tmp, path);
|
||||||
|
__path_absolute(tmp, str, NATIVE_STR_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GetSCEResult(result) (result >= 0 ? 0 : result & 0xFFFF)
|
||||||
|
|
||||||
cc_result Directory_Create(const cc_string* path) {
|
cc_result Directory_Create(const cc_string* path) {
|
||||||
char str[NATIVE_STR_LEN];
|
char str[NATIVE_STR_LEN];
|
||||||
String_EncodeUtf8(str, path);
|
GetNativePath(str, path);
|
||||||
/* read/write/search permissions for owner and group, and with read/search permissions for others. */
|
|
||||||
/* TODO: Is the default mode in all cases */
|
int result = sceIoMkdir(str, 0777);
|
||||||
return mkdir(str, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1 ? errno : 0;
|
return GetSCEResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
int File_Exists(const cc_string* path) {
|
int File_Exists(const cc_string* path) {
|
||||||
char str[NATIVE_STR_LEN];
|
char str[NATIVE_STR_LEN];
|
||||||
struct stat sb;
|
SceIoStat sb;
|
||||||
String_EncodeUtf8(str, path);
|
GetNativePath(str, path);
|
||||||
return stat(str, &sb) == 0 && S_ISREG(sb.st_mode);
|
return sceIoGetstat(str, &sb) == 0 && (sb.st_attr & FIO_SO_IFREG) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCallback callback) {
|
cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCallback callback) {
|
||||||
cc_string path; char pathBuffer[FILENAME_SIZE];
|
cc_string path; char pathBuffer[FILENAME_SIZE];
|
||||||
char str[NATIVE_STR_LEN];
|
char str[NATIVE_STR_LEN];
|
||||||
DIR* dirPtr;
|
int res;
|
||||||
struct dirent* entry;
|
|
||||||
char* src;
|
|
||||||
int len, res, is_dir;
|
|
||||||
|
|
||||||
String_EncodeUtf8(str, dirPath);
|
GetNativePath(str, dirPath);
|
||||||
dirPtr = opendir(str);
|
SceUID uid = sceIoDopen(str);
|
||||||
if (!dirPtr) return errno;
|
if (uid < 0) return GetSCEResult(uid); // error
|
||||||
|
|
||||||
/* POSIX docs: "When the end of the directory is encountered, a null pointer is returned and errno is not changed." */
|
|
||||||
/* errno is sometimes leftover from previous calls, so always reset it before readdir gets called */
|
|
||||||
errno = 0;
|
|
||||||
String_InitArray(path, pathBuffer);
|
String_InitArray(path, pathBuffer);
|
||||||
|
SceIoDirent entry;
|
||||||
|
|
||||||
while ((entry = readdir(dirPtr))) {
|
while ((res = sceIoDread(uid, &entry)) > 0) {
|
||||||
path.length = 0;
|
path.length = 0;
|
||||||
String_Format1(&path, "%s/", dirPath);
|
String_Format1(&path, "%s/", dirPath);
|
||||||
|
|
||||||
/* ignore . and .. entry */
|
// ignore . and .. entry (PSP does return them)
|
||||||
src = entry->d_name;
|
char* src = entry.d_name;
|
||||||
if (src[0] == '.' && src[1] == '\0') continue;
|
if (src[0] == '.' && src[1] == '\0') continue;
|
||||||
if (src[0] == '.' && src[1] == '.' && src[2] == '\0') continue;
|
if (src[0] == '.' && src[1] == '.' && src[2] == '\0') continue;
|
||||||
|
|
||||||
len = String_Length(src);
|
int len = String_Length(src);
|
||||||
String_AppendUtf8(&path, src, len);
|
String_AppendUtf8(&path, src, len);
|
||||||
|
|
||||||
is_dir = entry->d_type == DT_DIR;
|
if (entry.d_stat.st_attr & FIO_SO_IFDIR) {
|
||||||
/* TODO: fallback to stat when this fails */
|
|
||||||
|
|
||||||
if (is_dir) {
|
|
||||||
res = Directory_Enum(&path, obj, callback);
|
res = Directory_Enum(&path, obj, callback);
|
||||||
if (res) { closedir(dirPtr); return res; }
|
if (res) break;
|
||||||
} else {
|
} else {
|
||||||
callback(&path, obj);
|
callback(&path, obj);
|
||||||
}
|
}
|
||||||
errno = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
res = errno; /* return code from readdir */
|
sceIoDclose(uid);
|
||||||
closedir(dirPtr);
|
return GetSCEResult(res);
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cc_result File_Do(cc_file* file, const cc_string* path, int mode) {
|
static cc_result File_Do(cc_file* file, const cc_string* path, int mode) {
|
||||||
char str[NATIVE_STR_LEN];
|
char str[NATIVE_STR_LEN];
|
||||||
String_EncodeUtf8(str, path);
|
GetNativePath(str, path);
|
||||||
*file = open(str, mode, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
|
||||||
return *file == -1 ? errno : 0;
|
int result = sceIoOpen(str, mode, 0777);
|
||||||
|
*file = result;
|
||||||
|
return GetSCEResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_result File_Open(cc_file* file, const cc_string* path) {
|
cc_result File_Open(cc_file* file, const cc_string* path) {
|
||||||
return File_Do(file, path, O_RDONLY);
|
return File_Do(file, path, PSP_O_RDONLY);
|
||||||
}
|
}
|
||||||
cc_result File_Create(cc_file* file, const cc_string* path) {
|
cc_result File_Create(cc_file* file, const cc_string* path) {
|
||||||
return File_Do(file, path, O_RDWR | O_CREAT | O_TRUNC);
|
return File_Do(file, path, PSP_O_RDWR | PSP_O_CREAT | PSP_O_TRUNC);
|
||||||
}
|
}
|
||||||
cc_result File_OpenOrCreate(cc_file* file, const cc_string* path) {
|
cc_result File_OpenOrCreate(cc_file* file, const cc_string* path) {
|
||||||
return File_Do(file, path, O_RDWR | O_CREAT);
|
return File_Do(file, path, PSP_O_RDWR | PSP_O_CREAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_result File_Read(cc_file file, void* data, cc_uint32 count, cc_uint32* bytesRead) {
|
cc_result File_Read(cc_file file, void* data, cc_uint32 count, cc_uint32* bytesRead) {
|
||||||
*bytesRead = read(file, data, count);
|
int result = sceIoRead(file, data, count);
|
||||||
return *bytesRead == -1 ? errno : 0;
|
*bytesRead = result;
|
||||||
|
return GetSCEResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_result File_Write(cc_file file, const void* data, cc_uint32 count, cc_uint32* bytesWrote) {
|
cc_result File_Write(cc_file file, const void* data, cc_uint32 count, cc_uint32* bytesWrote) {
|
||||||
*bytesWrote = write(file, data, count);
|
int result = sceIoWrite(file, data, count);
|
||||||
return *bytesWrote == -1 ? errno : 0;
|
*bytesWrote = result;
|
||||||
|
return GetSCEResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_result File_Close(cc_file file) {
|
cc_result File_Close(cc_file file) {
|
||||||
return close(file) == -1 ? errno : 0;
|
int result = sceIoDclose(file);
|
||||||
|
return GetSCEResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_result File_Seek(cc_file file, int offset, int seekType) {
|
cc_result File_Seek(cc_file file, int offset, int seekType) {
|
||||||
static cc_uint8 modes[3] = { SEEK_SET, SEEK_CUR, SEEK_END };
|
static cc_uint8 modes[3] = { PSP_SEEK_SET, PSP_SEEK_CUR, PSP_SEEK_END };
|
||||||
return lseek(file, offset, modes[seekType]) == -1 ? errno : 0;
|
|
||||||
|
int result = sceIoLseek32(file, offset, modes[seekType]);
|
||||||
|
return GetSCEResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_result File_Position(cc_file file, cc_uint32* pos) {
|
cc_result File_Position(cc_file file, cc_uint32* pos) {
|
||||||
*pos = lseek(file, 0, SEEK_CUR);
|
int result = sceIoLseek32(file, 0, PSP_SEEK_CUR);
|
||||||
return *pos == -1 ? errno : 0;
|
*pos = result;
|
||||||
|
return GetSCEResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_result File_Length(cc_file file, cc_uint32* len) {
|
cc_result File_Length(cc_file file, cc_uint32* len) {
|
||||||
struct stat st;
|
int curPos = sceIoLseek32(file, 0, PSP_SEEK_CUR);
|
||||||
if (fstat(file, &st) == -1) { *len = -1; return errno; }
|
if (curPos < 0) { *len = -1; return GetSCEResult(curPos); }
|
||||||
*len = st.st_size; return 0;
|
|
||||||
|
*len = sceIoLseek32(file, 0, PSP_SEEK_END);
|
||||||
|
sceIoLseek32(file, curPos, PSP_SEEK_SET); // restore position
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user