From 72c1f73bc5227bf9e9c213dc1f1a4f6f826d0107 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Wed, 14 Dec 2022 15:42:54 -0500
Subject: [PATCH] rwops: Make read and write work like POSIX, not stdio.
This simplifies some things, clarifies some things, and also allows
for the possibility of RWops that offer non-blocking i/o (although
none of the current built-in ones do, intentionally, we could add this
later if we choose, or people could provide things like network socket
RWops implementations now, etc.
Fixes #6729.
---
include/SDL3/SDL_rwops.h | 86 ++++++++++------
src/audio/SDL_wave.c | 12 +--
src/audio/disk/SDL_diskaudio.c | 10 +-
src/core/android/SDL_android.c | 20 +---
src/core/android/SDL_android.h | 4 +-
src/dynapi/SDL_dynapi_procs.h | 4 +-
src/file/SDL_rwops.c | 162 +++++++++++++-----------------
src/joystick/SDL_gamecontroller.c | 2 +-
src/video/SDL_bmp.c | 61 ++++++-----
test/testautomation_rwops.c | 18 ++--
test/testime.c | 6 +-
test/testoverlay2.c | 2 +-
test/testresample.c | 2 +-
test/teststreaming.c | 2 +-
14 files changed, 195 insertions(+), 196 deletions(-)
diff --git a/include/SDL3/SDL_rwops.h b/include/SDL3/SDL_rwops.h
index d8fb1dd3a3c9..5ff826cf5590 100644
--- a/include/SDL3/SDL_rwops.h
+++ b/include/SDL3/SDL_rwops.h
@@ -66,22 +66,32 @@ typedef struct SDL_RWops
int whence);
/**
- * Read up to \c maxnum objects each of size \c size from the data
- * stream to the area pointed at by \c ptr.
+ * Read up to \c size bytes from the data stream to the area pointed
+ * at by \c ptr.
*
- * \return the number of objects read, or 0 at error or end of file.
+ * It is an error to use a negative \c size, but this parameter is
+ * signed so you definitely cannot overflow the return value on a
+ * successful run with enormous amounts of data.
+ *
+ * \return the number of objects read, or 0 on end of file, or -1 on error.
*/
- size_t (SDLCALL * read) (struct SDL_RWops * context, void *ptr,
- size_t size, size_t maxnum);
+ Sint64 (SDLCALL * read) (struct SDL_RWops * context, void *ptr,
+ Sint64 size);
/**
- * Write exactly \c num objects each of size \c size from the area
- * pointed at by \c ptr to data stream.
+ * Write exactly \c size bytes from the area pointed at by \c ptr
+ * to data stream. May write less than requested (error, non-blocking i/o,
+ * etc). Returns -1 on error when nothing was written.
+ *
+ * It is an error to use a negative \c size, but this parameter is
+ * signed so you definitely cannot overflow the return value on a
+ * successful run with enormous amounts of data.
*
- * \return the number of objects written, or 0 at error or end of file.
+ * \return the number of bytes written, which might be less than \c size,
+ * and -1 on error.
*/
- size_t (SDLCALL * write) (struct SDL_RWops * context, const void *ptr,
- size_t size, size_t num);
+ Sint64 (SDLCALL * write) (struct SDL_RWops * context, const void *ptr,
+ Sint64 size);
/**
* Close and free an allocated SDL_RWops structure.
@@ -406,22 +416,25 @@ extern DECLSPEC Sint64 SDLCALL SDL_RWtell(SDL_RWops *context);
/**
* Read from a data source.
*
- * This function reads up to `maxnum` objects each of size `size` from the
- * data source to the area pointed at by `ptr`. This function may read less
- * objects than requested. It will return zero when there has been an error or
- * the data stream is completely read.
+ * This function reads up `size` bytes from the data source to the area
+ * pointed at by `ptr`. This function may read less bytes than requested.
+ * It will return zero when the data stream is completely read, or
+ * -1 on error. For streams that support non-blocking
+ * operation, if nothing was read because it would require blocking,
+ * this function returns -2 to distinguish that this is not an error or
+ * end-of-file, and the caller can try again later.
*
* SDL_RWread() is actually a function wrapper that calls the SDL_RWops's
* `read` method appropriately, to simplify application development.
*
- * Prior to SDL 2.0.10, this function was a macro.
+ * It is an error to specify a negative `size`, but this parameter is
+ * signed so you definitely cannot overflow the return value on a
+ * successful run with enormous amounts of data.
*
* \param context a pointer to an SDL_RWops structure
* \param ptr a pointer to a buffer to read data into
- * \param size the size of each object to read, in bytes
- * \param maxnum the maximum number of objects to be read
- * \returns the number of objects read, or 0 at error or end of file; call
- * SDL_GetError() for more information.
+ * \param size the number of bytes to read from the data source.
+ * \returns the number of bytes read, or 0 at end of file, or -1 on error.
*
* \since This function is available since SDL 3.0.0.
*
@@ -432,28 +445,36 @@ extern DECLSPEC Sint64 SDLCALL SDL_RWtell(SDL_RWops *context);
* \sa SDL_RWseek
* \sa SDL_RWwrite
*/
-extern DECLSPEC size_t SDLCALL SDL_RWread(SDL_RWops *context,
- void *ptr, size_t size,
- size_t maxnum);
+extern DECLSPEC Sint64 SDLCALL SDL_RWread(SDL_RWops *context,
+ void *ptr, Sint64 size);
/**
* Write to an SDL_RWops data stream.
*
- * This function writes exactly `num` objects each of size `size` from the
- * area pointed at by `ptr` to the stream. If this fails for any reason, it'll
- * return less than `num` to demonstrate how far the write progressed. On
- * success, it returns `num`.
+ * This function writes exactly `size` bytes from the area pointed at by
+ * `ptr` to the stream. If this fails for any reason, it'll return less
+ * than `size` to demonstrate how far the write progressed. On success,
+ * it returns `num`.
+ *
+ * On error, this function still attempts to write as much as possible,
+ * so it might return a positive value less than the requested write
+ * size. If the function failed to write anything and there was an
+ * actual error, it will return -1. For streams that support non-blocking
+ * operation, if nothing was written because it would require blocking,
+ * this function returns -2 to distinguish that this is not an error and
+ * the caller can try again later.
*
* SDL_RWwrite is actually a function wrapper that calls the SDL_RWops's
* `write` method appropriately, to simplify application development.
*
- * Prior to SDL 2.0.10, this function was a macro.
+ * It is an error to specify a negative `size`, but this parameter is
+ * signed so you definitely cannot overflow the return value on a
+ * successful run with enormous amounts of data.
*
* \param context a pointer to an SDL_RWops structure
* \param ptr a pointer to a buffer containing data to write
- * \param size the size of an object to write, in bytes
- * \param num the number of objects to write
- * \returns the number of objects written, which will be less than **num** on
+ * \param size the number of bytes to write
+ * \returns the number of bytes written, which will be less than `num` on
* error; call SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
@@ -465,9 +486,8 @@ extern DECLSPEC size_t SDLCALL SDL_RWread(SDL_RWops *context,
* \sa SDL_RWread
* \sa SDL_RWseek
*/
-extern DECLSPEC size_t SDLCALL SDL_RWwrite(SDL_RWops *context,
- const void *ptr, size_t size,
- size_t num);
+extern DECLSPEC Sint64 SDLCALL SDL_RWwrite(SDL_RWops *context,
+ const void *ptr, Sint64 size);
/**
* Close and free an allocated SDL_RWops structure.
diff --git a/src/audio/SDL_wave.c b/src/audio/SDL_wave.c
index 654397ca1ec0..37b13b5d37ef 100644
--- a/src/audio/SDL_wave.c
+++ b/src/audio/SDL_wave.c
@@ -1523,7 +1523,7 @@ static int WaveNextChunk(SDL_RWops *src, WaveChunk *chunk)
if (SDL_RWseek(src, nextposition, RW_SEEK_SET) != nextposition) {
/* Not sure how we ended up here. Just abort. */
return -2;
- } else if (SDL_RWread(src, chunkheader, 4, 2) != 2) {
+ } else if (SDL_RWread(src, chunkheader, sizeof(Uint32) * 2) != (sizeof(Uint32) * 2)) {
return -1;
}
@@ -1553,7 +1553,7 @@ static int WaveReadPartialChunkData(SDL_RWops *src, WaveChunk *chunk, size_t len
return -2;
}
- chunk->size = SDL_RWread(src, chunk->data, 1, length);
+ chunk->size = SDL_RWread(src, chunk->data, length);
if (chunk->size != length) {
/* Expected to be handled by the caller. */
}
@@ -1650,7 +1650,7 @@ static int WaveReadFormat(WaveFile *file)
format->validsamplebits = SDL_ReadLE16(fmtsrc);
format->samplesperblock = format->validsamplebits;
format->channelmask = SDL_ReadLE32(fmtsrc);
- SDL_RWread(fmtsrc, format->subformat, 1, 16);
+ SDL_RWread(fmtsrc, format->subformat, 16);
format->encoding = WaveGetFormatGUIDEncoding(format);
}
@@ -1806,7 +1806,7 @@ static int WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 *
if (RIFFchunk.fourcc == RIFF) {
Uint32 formtype;
/* Read the form type. "WAVE" expected. */
- if (SDL_RWread(src, &formtype, sizeof(Uint32), 1) != 1) {
+ if (SDL_RWread(src, &formtype, sizeof(Uint32)) != sizeof (Uint32)) {
return SDL_SetError("Could not read RIFF form type");
} else if (SDL_SwapLE32(formtype) != WAVE) {
return SDL_SetError("RIFF form type is not WAVE (not a Waveform file)");
@@ -1896,7 +1896,7 @@ static int WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 *
/* Let's use src directly, it's just too convenient. */
Sint64 position = SDL_RWseek(src, chunk->position, RW_SEEK_SET);
Uint32 samplelength;
- if (position == chunk->position && SDL_RWread(src, &samplelength, sizeof(Uint32), 1) == 1) {
+ if (position == chunk->position && SDL_RWread(src, &samplelength, sizeof(Uint32)) == sizeof(Uint32)) {
file->fact.status = 1;
file->fact.samplelength = SDL_SwapLE32(samplelength);
} else {
@@ -1941,7 +1941,7 @@ static int WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 *
Uint64 position = (Uint64)chunk->position + chunk->length - 1;
if (position > SDL_MAX_SINT64 || SDL_RWseek(src, (Sint64)position, RW_SEEK_SET) != (Sint64)position) {
return SDL_SetError("Could not seek to WAVE chunk data");
- } else if (SDL_RWread(src, &tmp, 1, 1) != 1) {
+ } else if (SDL_RWread(src, &tmp, 1) != 1) {
return SDL_SetError("RIFF size truncates chunk");
}
}
diff --git a/src/audio/disk/SDL_diskaudio.c b/src/audio/disk/SDL_diskaudio.c
index b458f3e98443..84b096ecaafd 100644
--- a/src/audio/disk/SDL_diskaudio.c
+++ b/src/audio/disk/SDL_diskaudio.c
@@ -47,16 +47,16 @@ static void DISKAUDIO_WaitDevice(_THIS)
static void DISKAUDIO_PlayDevice(_THIS)
{
- const size_t written = SDL_RWwrite(_this->hidden->io,
+ const Sint64 written = SDL_RWwrite(_this->hidden->io,
_this->hidden->mixbuf,
- 1, _this->spec.size);
+ _this->spec.size);
/* If we couldn't write, assume fatal error for now */
if (written != _this->spec.size) {
SDL_OpenedAudioDeviceDisconnected(_this);
}
#ifdef DEBUG_AUDIO
- fprintf(stderr, "Wrote %d bytes of audio data\n", written);
+ fprintf(stderr, "Wrote %d bytes of audio data\n", (int) written);
#endif
}
@@ -73,8 +73,8 @@ static int DISKAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
SDL_Delay(h->io_delay);
if (h->io) {
- const size_t br = SDL_RWread(h->io, buffer, 1, buflen);
- buflen -= (int)br;
+ const int br = (int) SDL_RWread(h->io, buffer, (Sint64) buflen);
+ buflen -= br;
buffer = ((Uint8 *)buffer) + br;
if (buflen > 0) { /* EOF (or error, but whatever). */
SDL_RWclose(h->io);
diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c
index fbec5a8971e5..f91e8010cf73 100644
--- a/src/core/android/SDL_android.c
+++ b/src/core/android/SDL_android.c
@@ -1846,27 +1846,15 @@ int Android_JNI_FileOpen(SDL_RWops *ctx,
return 0;
}
-size_t Android_JNI_FileRead(SDL_RWops *ctx, void *buffer,
- size_t size, size_t maxnum)
+Sint64 Android_JNI_FileRead(SDL_RWops *ctx, void *buffer, Sint64 size)
{
- size_t result;
AAsset *asset = (AAsset *)ctx->hidden.androidio.asset;
- result = AAsset_read(asset, buffer, size * maxnum);
-
- if (result > 0) {
- /* Number of chuncks */
- return result / size;
- } else {
- /* Error or EOF */
- return result;
- }
+ return (Sint64) AAsset_read(asset, buffer, (size_t) size);
}
-size_t Android_JNI_FileWrite(SDL_RWops *ctx, const void *buffer,
- size_t size, size_t num)
+Sint64 Android_JNI_FileWrite(SDL_RWops *ctx, const void *buffer, Sint64 size)
{
- SDL_SetError("Cannot write to Android package filesystem");
- return 0;
+ return SDL_SetError("Cannot write to Android package filesystem");
}
Sint64 Android_JNI_FileSize(SDL_RWops *ctx)
diff --git a/src/core/android/SDL_android.h b/src/core/android/SDL_android.h
index fc7225e5b258..ceb1cbffda16 100644
--- a/src/core/android/SDL_android.h
+++ b/src/core/android/SDL_android.h
@@ -62,8 +62,8 @@ extern SDL_bool Android_IsChromebook(void);
int Android_JNI_FileOpen(SDL_RWops *ctx, const char *fileName, const char *mode);
Sint64 Android_JNI_FileSize(SDL_RWops *ctx);
Sint64 Android_JNI_FileSeek(SDL_RWops *ctx, Sint64 offset, int whence);
-size_t Android_JNI_FileRead(SDL_RWops *ctx, void *buffer, size_t size, size_t maxnum);
-size_t Android_JNI_FileWrite(SDL_RWops *ctx, const void *buffer, size_t size, size_t num);
+Sint64 Android_JNI_FileRead(SDL_RWops *ctx, void *buffer, Sint64 size);
+Sint64 Android_JNI_FileWrite(SDL_RWops *ctx, const void *buffer, Sint64 size);
int Android_JNI_FileClose(SDL_RWops *ctx);
/* Environment support */
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index 9f79080fbbe5..7915e6c9e024 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -753,8 +753,8 @@ SDL_DYNAPI_PROC(void,SDL_SIMDFree,(void *a),(a),)
SDL_DYNAPI_PROC(Sint64,SDL_RWsize,(SDL_RWops *a),(a),return)
SDL_DYNAPI_PROC(Sint64,SDL_RWseek,(SDL_RWops *a, Sint64 b, int c),(a,b,c),return)
SDL_DYNAPI_PROC(Sint64,SDL_RWtell,(SDL_RWops *a),(a),return)
-SDL_DYNAPI_PROC(size_t,SDL_RWread,(SDL_RWops *a, void *b, size_t c, size_t d),(a,b,c,d),return)
-SDL_DYNAPI_PROC(size_t,SDL_RWwrite,(SDL_RWops *a, const void *b, size_t c, size_t d),(a,b,c,d),return)
+SDL_DYNAPI_PROC(Sint64,SDL_RWread,(SDL_RWops *a, void *b, Sint64 c),(a,b,c),return)
+SDL_DYNAPI_PROC(Sint64,SDL_RWwrite,(SDL_RWops *a, const void *b, Sint64 c),(a,b,c),return)
SDL_DYNAPI_PROC(int,SDL_RWclose,(SDL_RWops *a),(a),return)
SDL_DYNAPI_PROC(void*,SDL_LoadFile,(const char *a, size_t *b),(a,b),return)
SDL_DYNAPI_PROC(SDL_MetalView,SDL_Metal_CreateView,(SDL_Window *a),(a),return)
diff --git a/src/file/SDL_rwops.c b/src/file/SDL_rwops.c
index 51600cf9d6ce..4d72c31314a5 100644
--- a/src/file/SDL_rwops.c
+++ b/src/file/SDL_rwops.c
@@ -182,20 +182,21 @@ static Sint64 SDLCALL windows_file_seek(SDL_RWops *context, Sint64 offset, int w
return windowsoffset.QuadPart;
}
-static size_t SDLCALL
-windows_file_read(SDL_RWops *context, void *ptr, size_t size, size_t maxnum)
+static Sint64 SDLCALL
+windows_file_read(SDL_RWops *context, void *ptr, Sint64 size)
{
- size_t total_need;
+ const size_t total_need = (size_t) size;
size_t total_read = 0;
size_t read_ahead;
DWORD byte_read;
- total_need = size * maxnum;
-
- if (context == NULL || context->hidden.windowsio.h == INVALID_HANDLE_VALUE || !total_need) {
+ if (context == NULL || context->hidden.windowsio.h == INVALID_HANDLE_VALUE) {
+ return SDL_SetError("Invalid file handle");
+ } else if (!total_need) {
return 0;
}
+
if (context->hidden.windowsio.buffer.left > 0) {
void *data = (char *)context->hidden.windowsio.buffer.data +
context->hidden.windowsio.buffer.size -
@@ -206,7 +207,7 @@ windows_file_read(SDL_RWops *context, void *ptr, size_t size, size_t maxnum)
context->hidden.windowsio.buffer.left -= read_ahead;
if (read_ahead == total_need) {
- return maxnum;
+ return size;
}
ptr = (char *)ptr + read_ahead;
total_need -= read_ahead;
@@ -216,8 +217,7 @@ windows_file_read(SDL_RWops *context, void *ptr, size_t size, size_t maxnum)
if (total_need < READAHEAD_BUFFER_SIZE) {
if (!ReadFile(context->hidden.windowsio.h, context->hidden.windowsio.buffer.data,
READAHEAD_BUFFER_SIZE, &byte_read, NULL)) {
- SDL_Error(SDL_EFREAD);
- return 0;
+ return SDL_Error(SDL_EFREAD);
}
read_ahead = SDL_min(total_need, (int)byte_read);
SDL_memcpy(ptr, context->hidden.windowsio.buffer.data, read_ahead);
@@ -226,26 +226,23 @@ windows_file_read(SDL_RWops *context, void *ptr, size_t size, size_t maxnum)
total_read += read_ahead;
} else {
if (!ReadFile(context->hidden.windowsio.h, ptr, (DWORD)total_need, &byte_read, NULL)) {
- SDL_Error(SDL_EFREAD);
- return 0;
+ return SDL_Error(SDL_EFREAD);
}
total_read += byte_read;
}
- return total_read / size;
+ return total_read;
}
-static size_t SDLCALL
-windows_file_write(SDL_RWops *context, const void *ptr, size_t size,
- size_t num)
+static Sint64 SDLCALL
+windows_file_write(SDL_RWops *context, const void *ptr, Sint64 size)
{
-
- size_t total_bytes;
+ const size_t total_bytes = (size_t) size;
DWORD byte_written;
size_t nwritten;
- total_bytes = size * num;
-
- if (context == NULL || context->hidden.windowsio.h == INVALID_HANDLE_VALUE || !size || !total_bytes) {
+ if (context == NULL || context->hidden.windowsio.h == INVALID_HANDLE_VALUE) {
+ return SDL_SetError("Invalid file handle");
+ } else if (!total_bytes) {
return 0;
}
@@ -260,23 +257,19 @@ windows_file_write(SDL_RWops *context, const void *ptr, size_t size,
if (context->hidden.windowsio.append) {
if (SetFilePointer(context->hidden.windowsio.h, 0L, NULL, FILE_END) ==
INVALID_SET_FILE_POINTER) {
- SDL_Error(SDL_EFWRITE);
- return 0;
+ return SDL_Error(SDL_EFWRITE);
}
}
if (!WriteFile(context->hidden.windowsio.h, ptr, (DWORD)total_bytes, &byte_written, NULL)) {
- SDL_Error(SDL_EFWRITE);
- return 0;
+ return SDL_Error(SDL_EFWRITE);
}
- nwritten = byte_written / size;
- return nwritten;
+ return (Sint64) byte_written;
}
static int SDLCALL windows_file_close(SDL_RWops *context)
{
-
if (context) {
if (context->hidden.windowsio.h != INVALID_HANDLE_VALUE) {
CloseHandle(context->hidden.windowsio.h);
@@ -378,28 +371,28 @@ static Sint64 SDLCALL stdio_seek(SDL_RWops *context, Sint64 offset, int whence)
return SDL_Error(SDL_EFSEEK);
}
-static size_t SDLCALL
-stdio_read(SDL_RWops *context, void *ptr, size_t size, size_t maxnum)
+static Sint64 SDLCALL
+stdio_read(SDL_RWops *context, void *ptr, Sint64 size)
{
size_t nread;
- nread = fread(ptr, size, maxnum, (FILE *)context->hidden.stdio.fp);
+ nread = fread(ptr, 1, size, (FILE *)context->hidden.stdio.fp);
if (nread == 0 && ferror((FILE *)context->hidden.stdio.fp)) {
- SDL_Error(SDL_EFREAD);
+ return SDL_Error(SDL_EFREAD);
}
- return nread;
+ return (Sint64) nread;
}
-static size_t SDLCALL
-stdio_write(SDL_RWops *context, const void *ptr, size_t size, size_t num)
+static Sint64 SDLCALL
+stdio_write(SDL_RWops *context, const void *ptr, Sint64 size)
{
size_t nwrote;
- nwrote = fwrite(ptr, size, num, (FILE *)context->hidden.stdio.fp);
+ nwrote = fwrite(ptr, 1, size, (FILE *)context->hidden.stdio.fp);
if (nwrote == 0 && ferror((FILE *)context->hidden.stdio.fp)) {
- SDL_Error(SDL_EFWRITE);
+ return SDL_Error(SDL_EFWRITE);
}
- return nwrote;
+ return (Sint64) nwrote;
}
static int SDLCALL stdio_close(SDL_RWops *context)
@@ -469,44 +462,33 @@ static Sint64 SDLCALL mem_seek(SDL_RWops *context, Sint64 offset, int whence)
return (Sint64)(context->hidden.mem.here - context->hidden.mem.base);
}
-static size_t SDLCALL
-mem_read(SDL_RWops *context, void *ptr, size_t size, size_t maxnum)
+static Sint64 mem_io(SDL_RWops *context, void *dst, const void *src, Sint64 size)
{
- size_t total_bytes;
- size_t mem_available;
-
- total_bytes = (maxnum * size);
- if (!maxnum || !size || ((total_bytes / maxnum) != size)) {
- return 0;
- }
-
- mem_available = (context->hidden.mem.stop - context->hidden.mem.here);
- if (total_bytes > mem_available) {
- total_bytes = mem_available;
+ const Sint64 mem_available = (Sint64) (context->hidden.mem.stop - context->hidden.mem.here);
+ if (size > mem_available) {
+ size = mem_available;
}
+ SDL_memcpy(dst, src, (size_t) size);
+ context->hidden.mem.here += size;
+ return size;
+}
- SDL_memcpy(ptr, context->hidden.mem.here, total_bytes);
- context->hidden.mem.here += total_bytes;
-
- return total_bytes / size;
+static Sint64 SDLCALL
+mem_read(SDL_RWops *context, void *ptr, Sint64 size)
+{
+ return mem_io(context, ptr, context->hidden.mem.here, size);
}
-static size_t SDLCALL
-mem_write(SDL_RWops *context, const void *ptr, size_t size, size_t num)
+static Sint64 SDLCALL
+mem_write(SDL_RWops *context, const void *ptr, Sint64 size)
{
- if ((context->hidden.mem.here + (num * size)) > context->hidden.mem.stop) {
- num = (context->hidden.mem.stop - context->hidden.mem.here) / size;
- }
- SDL_memcpy(context->hidden.mem.here, ptr, num * size);
- context->hidden.mem.here += num * size;
- return num;
+ return mem_io(context, context->hidden.mem.here, ptr, size);
}
-static size_t SDLCALL
-mem_writeconst(SDL_RWops *context, const void *ptr, size_t size, size_t num)
+static Sint64 SDLCALL
+mem_writeconst(SDL_RWops *context, const void *ptr, Sint64 size)
{
- SDL_SetError("Can't write to read-only memory");
- return 0;
+ return SDL_SetError("Can't write to read-only memory");
}
static int SDLCALL mem_close(SDL_RWops *context)
@@ -693,7 +675,7 @@ SDL_LoadFile_RW(SDL_RWops *src, size_t *datasize, int freesrc)
{
static const Sint64 FILE_CHUNK_SIZE = 1024;
Sint64 size;
- size_t size_read, size_total;
+ Sint64 size_read, size_total;
void *data = NULL, *newdata;
if (src == NULL) {
@@ -709,7 +691,7 @@ SDL_LoadFile_RW(SDL_RWops *src, size_t *datasize, int freesrc)
size_total = 0;
for (;;) {
- if ((((Sint64)size_total) + FILE_CHUNK_SIZE) > size) {
+ if ((size_total + FILE_CHUNK_SIZE) > size) {
size = (size_total + FILE_CHUNK_SIZE);
newdata = SDL_realloc(data, (size_t)(size + 1));
if (newdata == NULL) {
@@ -721,7 +703,7 @@ SDL_LoadFile_RW(SDL_RWops *src, size_t *datasize, int freesrc)
data = newdata;
}
- size_read = SDL_RWread(src, (char *)data + size_total, 1, (size_t)(size - size_total));
+ size_read = SDL_RWread(src, (char *)data + size_total, size - size_total);
if (size_read == 0) {
break;
}
@@ -729,7 +711,7 @@ SDL_LoadFile_RW(SDL_RWops *src, size_t *datasize, int freesrc)
}
if (datasize) {
- *datasize = size_total;
+ *datasize = (size_t) size_total;
}
((char *)data)[size_total] = '\0';
@@ -764,16 +746,16 @@ SDL_RWtell(SDL_RWops *context)
return context->seek(context, 0, RW_SEEK_CUR);
}
-size_t
-SDL_RWread(SDL_RWops *context, void *ptr, size_t size, size_t maxnum)
+Sint64
+SDL_RWread(SDL_RWops *context, void *ptr, Sint64 size)
{
- return context->read(context, ptr, size, maxnum);
+ return context->read(context, ptr, size);
}
-size_t
-SDL_RWwrite(SDL_RWops *context, const void *ptr, size_t size, size_t num)
+Sint64
+SDL_RWwrite(SDL_RWops *context, const void *ptr, Sint64 size)
{
- return context->write(context, ptr, size, num);
+ return context->write(context, ptr, size);
}
int SDL_RWclose(SDL_RWops *context)
@@ -787,7 +769,7 @@ Uint8 SDL_ReadU8(SDL_RWops *src)
{
Uint8 value = 0;
- SDL_RWread(src, &value, sizeof(value), 1);
+ SDL_RWread(src, &value, sizeof(value));
return value;
}
@@ -796,7 +778,7 @@ SDL_ReadLE16(SDL_RWops *src)
{
Uint16 value = 0;
- SDL_RWread(src, &value, sizeof(value), 1);
+ SDL_RWread(src, &value, sizeof(value));
return SDL_SwapLE16(value);
}
@@ -805,7 +787,7 @@ SDL_ReadBE16(SDL_RWops *src)
{
Uint16 value = 0;
- SDL_RWread(src, &value, sizeof(value), 1);
+ SDL_RWread(src, &value, sizeof(value));
return SDL_SwapBE16(value);
}
@@ -814,7 +796,7 @@ SDL_ReadLE32(SDL_RWops *src)
{
Uint32 value = 0;
- SDL_RWread(src, &value, sizeof(value), 1);
+ SDL_RWread(src, &value, sizeof(value));
return SDL_SwapLE32(value);
}
@@ -823,7 +805,7 @@ SDL_ReadBE32(SDL_RWops *src)
{
Uint32 value = 0;
- SDL_RWread(src, &value, sizeof(value), 1);
+ SDL_RWread(src, &value, sizeof(value));
return SDL_SwapBE32(value);
}
@@ -832,7 +814,7 @@ SDL_ReadLE64(SDL_RWops *src)
{
Uint64 value = 0;
- SDL_RWread(src, &value, sizeof(value), 1);
+ SDL_RWread(src, &value, sizeof(value));
return SDL_SwapLE64(value);
}
@@ -841,56 +823,56 @@ SDL_ReadBE64(SDL_RWops *src)
{
Uint64 value = 0;
- SDL_RWread(src, &value, sizeof(value), 1);
+ SDL_RWread(src, &value, sizeof(value));
return SDL_SwapBE64(value);
}
size_t
SDL_WriteU8(SDL_RWops *dst, Uint8 value)
{
- return SDL_RWwrite(dst, &value, sizeof(value), 1);
+ return (SDL_RWwrite(dst, &value, sizeof(value)) == sizeof(value)) ? 1 : 0;
}
size_t
SDL_WriteLE16(SDL_RWops *dst, Uint16 value)
{
const Uint16 swapped = SDL_SwapLE16(value);
- return SDL_RWwrite(dst, &swapped, sizeof(swapped), 1);
+ return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? 1 : 0;
}
size_t
SDL_WriteBE16(SDL_RWops *dst, Uint16 value)
{
const Uint16 swapped = SDL_SwapBE16(value);
- return SDL_RWwrite(dst, &swapped, sizeof(swapped), 1);
+ return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? 1 : 0;
}
size_t
SDL_WriteLE32(SDL_RWops *dst, Uint32 value)
{
const Uint32 swapped = SDL_SwapLE32(value);
- return SDL_RWwrite(dst, &swapped, sizeof(swapped), 1);
+ return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? 1 : 0;
}
size_t
SDL_WriteBE32(SDL_RWops *dst, Uint32 value)
{
const Uint32 swapped = SDL_SwapBE32(value);
- return SDL_RWwrite(dst, &swapped, sizeof(swapped), 1);
+ return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? 1 : 0;
}
size_t
SDL_WriteLE64(SDL_RWops *dst, Uint64 value)
{
const Uint64 swapped = SDL_SwapLE64(value);
- return SDL_RWwrite(dst, &swapped, sizeof(swapped), 1);
+ return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? 1 : 0;
}
size_t
SDL_WriteBE64(SDL_RWops *dst, Uint64 value)
{
const Uint64 swapped = SDL_SwapBE64(value);
- return SDL_RWwrite(dst, &swapped, sizeof(swapped), 1);
+ return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? 1 : 0;
}
/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c
index fa9c600f00cd..f1d01d29abdb 100644
--- a/src/joystick/SDL_gamecontroller.c
+++ b/src/joystick/SDL_gamecontroller.c
@@ -1488,7 +1488,7 @@ int SDL_GameControllerAddMappingsFromRW(SDL_RWops *rw, int freerw)
return SDL_SetError("Could not allocate space to read DB into memory");
}
- if (SDL_RWread(rw, buf, db_size, 1) != 1) {
+ if (SDL_RWread(rw, buf, db_size) != db_size) {
if (freerw) {
SDL_RWclose(rw);
}
diff --git a/src/video/SDL_bmp.c b/src/video/SDL_bmp.c
index fca67eab83ef..0a4551f7e2fb 100644
--- a/src/video/SDL_bmp.c
+++ b/src/video/SDL_bmp.c
@@ -69,8 +69,9 @@ static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8)
if (spot >= start && spot < end) \
*spot = (x)
+ /* !!! FIXME: for all these reads, handle error vs eof? handle -2 if non-blocking? */
for (;;) {
- if (!SDL_RWread(src, &ch, 1, 1)) {
+ if (SDL_RWread(src, &ch, 1) <= 0) {
return SDL_TRUE;
}
/*
@@ -79,7 +80,7 @@ static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8)
*/
if (ch) {
Uint8 pixel;
- if (!SDL_RWread(src, &pixel, 1, 1)) {
+ if (SDL_RWread(src, &pixel, 1) <= 0) {
return SDL_TRUE;
}
if (isRle8) { /* 256-color bitmap, compressed */
@@ -106,7 +107,7 @@ static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8)
| a cursor move, or some absolute data.
| zero tag may be absolute mode or an escape
*/
- if (!SDL_RWread(src, &ch, 1, 1)) {
+ if (SDL_RWread(src, &ch, 1) <= 0) {
return SDL_TRUE;
}
switch (ch) {
@@ -117,11 +118,11 @@ static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8)
case 1: /* end of bitmap */
return SDL_FALSE; /* success! */
case 2: /* delta */
- if (!SDL_RWread(src, &ch, 1, 1)) {
+ if (SDL_RWread(src, &ch, 1) <= 0) {
return SDL_TRUE;
}
ofs += ch;
- if (!SDL_RWread(src, &ch, 1, 1)) {
+ if (SDL_RWread(src, &ch, 1) <= 0) {
return SDL_TRUE;
}
bits -= (ch * pitch);
@@ -131,7 +132,7 @@ static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8)
needsPad = (ch & 1);
do {
Uint8 pixel;
- if (!SDL_RWread(src, &pixel, 1, 1)) {
+ if (SDL_RWread(src, &pixel, 1) <= 0) {
return SDL_TRUE;
}
COPY_PIXEL(pixel);
@@ -140,7 +141,7 @@ static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8)
(Patch may be truncated, please check the link at the top of this post.)