26#include "physfsrwops.h"
29#if defined(SDL_VERSION_ATLEAST)
30#if SDL_VERSION_ATLEAST(2, 0, 0)
37#define RW_SEEK_SET SEEK_SET
40#define RW_SEEK_CUR SEEK_CUR
43#define RW_SEEK_END SEEK_END
48static Sint64 SDLCALL physfsrwops_size(
struct SDL_RWops *rw)
50 PHYSFS_File *handle = (PHYSFS_File *) rw->hidden.unknown.data1;
51 return (Sint64) PHYSFS_fileLength(handle);
57static Sint64 SDLCALL physfsrwops_seek(
struct SDL_RWops *rw, Sint64 offset,
int whence)
59static int physfsrwops_seek(SDL_RWops *rw,
int offset,
int whence)
62 PHYSFS_File *handle = (PHYSFS_File *) rw->hidden.unknown.data1;
63 PHYSFS_sint64 pos = 0;
65 if (whence == RW_SEEK_SET)
66 pos = (PHYSFS_sint64) offset;
68 else if (whence == RW_SEEK_CUR)
70 const PHYSFS_sint64 current = PHYSFS_tell(handle);
73 SDL_SetError(
"Can't find position in file: %s",
74 PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
81 return (Sint64) current;
87 pos = current + ((PHYSFS_sint64) offset);
90 else if (whence == RW_SEEK_END)
92 const PHYSFS_sint64 len = PHYSFS_fileLength(handle);
95 SDL_SetError(
"Can't find end of file: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
99 pos = len + ((PHYSFS_sint64) offset);
104 SDL_SetError(
"Invalid 'whence' parameter.");
110 SDL_SetError(
"Attempt to seek past start of file.");
114 if (!PHYSFS_seek(handle, (PHYSFS_uint64) pos))
116 SDL_SetError(
"PhysicsFS error: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
129static size_t SDLCALL physfsrwops_read(
struct SDL_RWops *rw,
void *ptr,
130 size_t size,
size_t maxnum)
132static int physfsrwops_read(SDL_RWops *rw,
void *ptr,
int size,
int maxnum)
135 PHYSFS_File *handle = (PHYSFS_File *) rw->hidden.unknown.data1;
136 const PHYSFS_uint64 readlen = (PHYSFS_uint64) (maxnum * size);
137 const PHYSFS_sint64 rc = PHYSFS_readBytes(handle, ptr, readlen);
138 if (rc != ((PHYSFS_sint64) readlen))
140 if (!PHYSFS_eof(handle))
142 SDL_SetError(
"PhysicsFS error: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
153 return (
size_t) rc / size;
155 return (
int) rc / size;
161static size_t SDLCALL physfsrwops_write(
struct SDL_RWops *rw,
const void *ptr,
162 size_t size,
size_t num)
164static int physfsrwops_write(SDL_RWops *rw,
const void *ptr,
int size,
int num)
167 PHYSFS_File *handle = (PHYSFS_File *) rw->hidden.unknown.data1;
168 const PHYSFS_uint64 writelen = (PHYSFS_uint64) (num * size);
169 const PHYSFS_sint64 rc = PHYSFS_writeBytes(handle, ptr, writelen);
170 if (rc != ((PHYSFS_sint64) writelen))
171 SDL_SetError(
"PhysicsFS error: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
181static int physfsrwops_close(SDL_RWops *rw)
183 PHYSFS_File *handle = (PHYSFS_File *) rw->hidden.unknown.data1;
184 if (!PHYSFS_close(handle))
186 SDL_SetError(
"PhysicsFS error: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
195static SDL_RWops *create_rwops(PHYSFS_File *handle)
197 SDL_RWops *retval = NULL;
200 SDL_SetError(
"PhysicsFS error: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
203 retval = SDL_AllocRW();
207 retval->size = physfsrwops_size;
209 retval->seek = physfsrwops_seek;
210 retval->read = physfsrwops_read;
211 retval->write = physfsrwops_write;
212 retval->close = physfsrwops_close;
213 retval->hidden.unknown.data1 = handle;
221SDL_RWops *PHYSFSRWOPS_makeRWops(PHYSFS_File *handle)
223 SDL_RWops *retval = NULL;
225 SDL_SetError(
"NULL pointer passed to PHYSFSRWOPS_makeRWops().");
227 retval = create_rwops(handle);
233SDL_RWops *PHYSFSRWOPS_openRead(
const char *fname)
235 return create_rwops(PHYSFS_openRead(fname));
239SDL_RWops *PHYSFSRWOPS_openWrite(
const char *fname)
241 return create_rwops(PHYSFS_openWrite(fname));
245SDL_RWops *PHYSFSRWOPS_openAppend(
const char *fname)
247 return create_rwops(PHYSFS_openAppend(fname));