#include #include #include #include #include #if defined(_WIN32) # include # ifdef _MSC_VER # define setmode _setmode # endif # ifdef _XBOX # include # define INVALID_FILE_ATTRIBUTES -1 # else # include # include # include # include # endif #elif defined(VITA) # include # include #else # if defined(PSP) # include # endif # include # include # include # include #endif #ifdef __CELLOS_LV2__ #include #else #include #endif struct RFILE { int fd; }; RFILE *retro_fopen(const char *path, unsigned mode, ssize_t len) { RFILE *stream = (RFILE*)calloc(1, sizeof(*stream)); if (!stream) return NULL; switch (mode) { case RFILE_MODE_READ: stream->fd = open(path, O_RDONLY); break; case RFILE_MODE_WRITE: stream->fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); break; case RFILE_MODE_READ_WRITE: #ifdef _WIN32 stream->fd = open(path, O_RDWR | O_BINARY); #else stream->fd = open(path, O_RDWR); #endif break; } return stream; } ssize_t retro_fseek(RFILE *stream, ssize_t offset, int whence) { if (!stream) return -1; return lseek(stream->fd, offset, whence); } ssize_t retro_fread(RFILE *stream, void *s, size_t len) { if (!stream) return -1; return read(stream->fd, s, len); } ssize_t retro_fwrite(RFILE *stream, const void *s, size_t len) { if (!stream) return -1; return write(stream->fd, s, len); } void retro_fclose(RFILE *stream) { if (!stream) return; close(stream->fd); free(stream); } bool retro_fmemcpy(const char *path, char *s, size_t len, ssize_t *bytes_written) { RFILE *stream = retro_fopen(path, RFILE_MODE_READ, -1); if (!stream) return false; do { *bytes_written = retro_fread(stream, s, len); }while(*bytes_written < 0 && errno == EINTR); retro_fclose(stream); if (*bytes_written < 0) return false; /* NULL-terminate the string. */ s[*bytes_written] = '\0'; return true; }