Browse Source

SDL_rwops read/write functions return size_t again

The current status is stored in the SDL_rwops 'status' field to be able to determine whether a 0 return value is caused by end of file, an error, or a non-blocking source not being ready.

The functions to read sized datatypes now return SDL_bool so you can detect read errors.

Fixes https://github.com/libsdl-org/SDL/issues/6729
Sam Lantinga 2 years ago
parent
commit
b903ccf945

+ 60 - 0
build-scripts/SDL_migration.cocci

@@ -2690,3 +2690,63 @@ typedef SDL_cond, SDL_Condition;
 - SDL_strtokr
 + SDL_strtok_r
   (...)
+@@
+@@
+- SDL_ReadLE16
++ SDL_ReadU16LE
+  (...)
+@@
+@@
+- SDL_ReadLE32
++ SDL_ReadU32LE
+  (...)
+@@
+@@
+- SDL_ReadBE32
++ SDL_ReadU32BE
+  (...)
+@@
+@@
+- SDL_ReadBE16
++ SDL_ReadU16BE
+  (...)
+@@
+@@
+- SDL_ReadLE64
++ SDL_ReadU64LE
+  (...)
+@@
+@@
+- SDL_ReadBE64
++ SDL_ReadU64BE
+  (...)
+@@
+@@
+- SDL_WriteLE16
++ SDL_WriteU16LE
+  (...)
+@@
+@@
+- SDL_WriteBE16
++ SDL_WriteU16BE
+  (...)
+@@
+@@
+- SDL_WriteLE32
++ SDL_WriteU32LE
+  (...)
+@@
+@@
+- SDL_WriteBE32
++ SDL_WriteU32BE
+  (...)
+@@
+@@
+- SDL_WriteLE64
++ SDL_WriteU64LE
+  (...)
+@@
+@@
+- SDL_WriteBE64
++ SDL_WriteU64BE
+  (...)

+ 37 - 55
docs/README-migration.md

@@ -910,33 +910,26 @@ size_t SDL_RWwrite(SDL_RWops *context, const void *ptr, size_t size, size_t maxn
 But now they look more like POSIX:
 
 ```c
-Sint64 SDL_RWread(SDL_RWops *context, void *ptr, Sint64 size);
-Sint64 SDL_RWwrite(SDL_RWops *context, const void *ptr, Sint64 size);
+size_t SDL_RWread(SDL_RWops *context, void *ptr, size_t size);
+size_t SDL_RWwrite(SDL_RWops *context, const void *ptr, size_t size);
 ```
 
-SDL_RWread() previously returned 0 at end of file or other error. Now it returns the number of bytes read, 0 for end of file, -1 for another error, or -2 for data not ready (in the case of a non-blocking context).
-
 Code that used to look like this:
 ```
 size_t custom_read(void *ptr, size_t size, size_t nitems, SDL_RWops *stream)
 {
-    return (size_t)SDL_RWread(stream, ptr, size, nitems);
+    return SDL_RWread(stream, ptr, size, nitems);
 }
 ```
 should be changed to:
 ```
 size_t custom_read(void *ptr, size_t size, size_t nitems, SDL_RWops *stream)
 {
-    Sint64 amount = SDL_RWread(stream, ptr, size * nitems);
-    if (amount <= 0) {
-        return 0;
-    }
-    return (size_t)(amount / size);
+    size_t bytes = SDL_RWread(stream, ptr, size * nitems);
+    return (bytes / size);
 }
 ```
 
-Similarly, SDL_RWwrite() can return -2 for data not ready in the case of a non-blocking context. There is currently no way to create a non-blocking context, we have simply defined the semantic for your own custom SDL_RWops object.
-
 SDL_RWFromFP has been removed from the API, due to issues when the SDL library uses a different C runtime from the application.
 
 You can implement this in your own code easily:
@@ -944,23 +937,7 @@ You can implement this in your own code easily:
 #include <stdio.h>
 
 
-static Sint64 SDLCALL
-stdio_size(SDL_RWops * context)
-{
-    Sint64 pos, size;
-
-    pos = SDL_RWseek(context, 0, SDL_RW_SEEK_CUR);
-    if (pos < 0) {
-        return -1;
-    }
-    size = SDL_RWseek(context, 0, SDL_RW_SEEK_END);
-
-    SDL_RWseek(context, pos, SDL_RW_SEEK_SET);
-    return size;
-}
-
-static Sint64 SDLCALL
-stdio_seek(SDL_RWops * context, Sint64 offset, int whence)
+static Sint64 SDLCALL stdio_seek(SDL_RWops *context, Sint64 offset, int whence)
 {
     int stdiowhence;
 
@@ -988,54 +965,46 @@ stdio_seek(SDL_RWops * context, Sint64 offset, int whence)
     return SDL_Error(SDL_EFSEEK);
 }
 
-static Sint64 SDLCALL
-stdio_read(SDL_RWops * context, void *ptr, Sint64 size)
+static size_t SDLCALL stdio_read(SDL_RWops *context, void *ptr, size_t size)
 {
-    size_t nread;
+    size_t bytes;
 
-    nread = fread(ptr, 1, (size_t) size, (FILE *)context->hidden.stdio.fp);
-    if (nread == 0 && ferror((FILE *)context->hidden.stdio.fp)) {
-        return SDL_Error(SDL_EFREAD);
+    bytes = fread(ptr, 1, size, (FILE *)context->hidden.stdio.fp);
+    if (bytes == 0 && ferror((FILE *)context->hidden.stdio.fp)) {
+        SDL_Error(SDL_EFREAD);
     }
-    return (Sint64) nread;
+    return bytes;
 }
 
-static Sint64 SDLCALL
-stdio_write(SDL_RWops * context, const void *ptr, Sint64 size)
+static size_t SDLCALL stdio_write(SDL_RWops *context, const void *ptr, size_t size)
 {
-    size_t nwrote;
+    size_t bytes;
 
-    nwrote = fwrite(ptr, 1, (size_t) size, (FILE *)context->hidden.stdio.fp);
-    if (nwrote == 0 && ferror((FILE *)context->hidden.stdio.fp)) {
-        return SDL_Error(SDL_EFWRITE);
+    bytes = fwrite(ptr, 1, size, (FILE *)context->hidden.stdio.fp);
+    if (bytes == 0 && ferror((FILE *)context->hidden.stdio.fp)) {
+        SDL_Error(SDL_EFWRITE);
     }
-    return (Sint64) nwrote;
+    return bytes;
 }
 
-static int SDLCALL
-stdio_close(SDL_RWops * context)
+static int SDLCALL stdio_close(SDL_RWops *context)
 {
     int status = 0;
-    if (context) {
-        if (context->hidden.stdio.autoclose) {
-            /* WARNING:  Check the return value here! */
-            if (fclose((FILE *)context->hidden.stdio.fp) != 0) {
-                status = SDL_Error(SDL_EFWRITE);
-            }
+    if (context->hidden.stdio.autoclose) {
+        if (fclose((FILE *)context->hidden.stdio.fp) != 0) {
+            status = SDL_Error(SDL_EFWRITE);
         }
-        SDL_DestroyRW(context);
     }
+    SDL_DestroyRW(context);
     return status;
 }
 
-SDL_RWops *
-SDL_RWFromFP(void *fp, SDL_bool autoclose)
+SDL_RWops *SDL_RWFromFP(void *fp, SDL_bool autoclose)
 {
     SDL_RWops *rwops = NULL;
 
     rwops = SDL_CreateRW();
     if (rwops != NULL) {
-        rwops->size = stdio_size;
         rwops->seek = stdio_seek;
         rwops->read = stdio_read;
         rwops->write = stdio_write;
@@ -1048,10 +1017,23 @@ SDL_RWFromFP(void *fp, SDL_bool autoclose)
 }
 ```
 
+The functions SDL_ReadU8(), SDL_ReadU16LE(), SDL_ReadU16BE(), SDL_ReadU32LE(), SDL_ReadU32BE(), SDL_ReadU64LE(), and SDL_ReadU64BE() now return SDL_TRUE if the read succeeded and SDL_FALSE if it didn't, and store the data in a pointer passed in as a parameter.
 
 The following functions have been renamed:
 * SDL_AllocRW() => SDL_CreateRW()
 * SDL_FreeRW() => SDL_DestroyRW()
+* SDL_ReadBE16() => SDL_ReadU16BE()
+* SDL_ReadBE32() => SDL_ReadU32BE()
+* SDL_ReadBE64() => SDL_ReadU64BE()
+* SDL_ReadLE16() => SDL_ReadU16LE()
+* SDL_ReadLE32() => SDL_ReadU32LE()
+* SDL_ReadLE64() => SDL_ReadU64LE()
+* SDL_WriteBE16() => SDL_WriteU16BE()
+* SDL_WriteBE32() => SDL_WriteU32BE()
+* SDL_WriteBE64() => SDL_WriteU64BE()
+* SDL_WriteLE16() => SDL_WriteU16LE()
+* SDL_WriteLE32() => SDL_WriteU32LE()
+* SDL_WriteLE64() => SDL_WriteU64LE()
 
 ## SDL_sensor.h
 

+ 3 - 2
include/SDL3/SDL_gamepad.h

@@ -176,7 +176,8 @@ extern DECLSPEC int SDLCALL SDL_AddGamepadMapping(const char *mapping);
  * constrained environment.
  *
  * \param src the data stream for the mappings to be added
- * \param freesrc non-zero to close the stream after being read
+ * \param freesrc if SDL_TRUE, calls SDL_RWclose() on `src` before returning,
+ *                even in the case of an error
  * \returns the number of mappings added or -1 on error; call SDL_GetError()
  *          for more information.
  *
@@ -186,7 +187,7 @@ extern DECLSPEC int SDLCALL SDL_AddGamepadMapping(const char *mapping);
  * \sa SDL_AddGamepadMappingsFromFile
  * \sa SDL_GetGamepadMappingForGUID
  */
-extern DECLSPEC int SDLCALL SDL_AddGamepadMappingsFromRW(SDL_RWops *src, int freesrc);
+extern DECLSPEC int SDLCALL SDL_AddGamepadMappingsFromRW(SDL_RWops *src, SDL_bool freesrc);
 
 /**
  * Load a set of gamepad mappings from a file.

+ 24 - 0
include/SDL3/SDL_oldnames.h

@@ -423,6 +423,18 @@
 #define RW_SEEK_SET SDL_RW_SEEK_SET
 #define SDL_AllocRW SDL_CreateRW
 #define SDL_FreeRW SDL_DestroyRW
+#define SDL_ReadBE16 SDL_ReadU16BE
+#define SDL_ReadBE32 SDL_ReadU32BE
+#define SDL_ReadBE64 SDL_ReadU64BE
+#define SDL_ReadLE16 SDL_ReadU16LE
+#define SDL_ReadLE32 SDL_ReadU32LE
+#define SDL_ReadLE64 SDL_ReadU64LE
+#define SDL_WriteBE16 SDL_WriteU16BE
+#define SDL_WriteBE32 SDL_WriteU32BE
+#define SDL_WriteBE64 SDL_WriteU64BE
+#define SDL_WriteLE16 SDL_WriteU16LE
+#define SDL_WriteLE32 SDL_WriteU32LE
+#define SDL_WriteLE64 SDL_WriteU64LE
 
 /* ##SDL_sensor.h */
 #define SDL_SensorClose SDL_CloseSensor
@@ -863,6 +875,18 @@
 #define RW_SEEK_SET RW_SEEK_SET_renamed_SDL_RW_SEEK_SET
 #define SDL_AllocRW SDL_AllocRW_renamed_SDL_CreateRW
 #define SDL_FreeRW SDL_FreeRW_renamed_SDL_DestroyRW
+#define SDL_ReadBE16 SDL_ReadBE16_renamed_SDL_ReadU16BE
+#define SDL_ReadBE32 SDL_ReadBE32_renamed_SDL_ReadU32BE
+#define SDL_ReadBE64 SDL_ReadBE64_renamed_SDL_ReadU64BE
+#define SDL_ReadLE16 SDL_ReadLE16_renamed_SDL_ReadU16LE
+#define SDL_ReadLE32 SDL_ReadLE32_renamed_SDL_ReadU32LE
+#define SDL_ReadLE64 SDL_ReadLE64_renamed_SDL_ReadU64LE
+#define SDL_WriteBE16 SDL_WriteBE16_renamed_SDL_WriteU16BE
+#define SDL_WriteBE32 SDL_WriteBE32_renamed_SDL_WriteU32BE
+#define SDL_WriteBE64 SDL_WriteBE64_renamed_SDL_WriteU64BE
+#define SDL_WriteLE16 SDL_WriteLE16_renamed_SDL_WriteU16LE
+#define SDL_WriteLE32 SDL_WriteLE32_renamed_SDL_WriteU32LE
+#define SDL_WriteLE64 SDL_WriteLE64_renamed_SDL_WriteU64LE
 
 /* ##SDL_sensor.h */
 #define SDL_SensorClose SDL_SensorClose_renamed_SDL_CloseSensor

+ 254 - 113
include/SDL3/SDL_rwops.h

@@ -38,13 +38,21 @@
 extern "C" {
 #endif
 
-/* RWops Types */
-#define SDL_RWOPS_UNKNOWN   0U  /**< Unknown stream type */
-#define SDL_RWOPS_WINFILE   1U  /**< Win32 file */
-#define SDL_RWOPS_STDFILE   2U  /**< Stdio file */
-#define SDL_RWOPS_JNIFILE   3U  /**< Android asset */
-#define SDL_RWOPS_MEMORY    4U  /**< Memory stream */
-#define SDL_RWOPS_MEMORY_RO 5U  /**< Read-Only memory stream */
+/* RWops types */
+#define SDL_RWOPS_UNKNOWN   0   /**< Unknown stream type */
+#define SDL_RWOPS_WINFILE   1   /**< Win32 file */
+#define SDL_RWOPS_STDFILE   2   /**< Stdio file */
+#define SDL_RWOPS_JNIFILE   3   /**< Android asset */
+#define SDL_RWOPS_MEMORY    4   /**< Memory stream */
+#define SDL_RWOPS_MEMORY_RO 5   /**< Read-Only memory stream */
+
+/* RWops status, set by a read or write operation */
+#define SDL_RWOPS_STATUS_READY          0   /**< Everything is ready */
+#define SDL_RWOPS_STATUS_ERROR          1   /**< Read or write I/O error */
+#define SDL_RWOPS_STATUS_EOF            2   /**< End of file */
+#define SDL_RWOPS_STATUS_NOT_READY      3   /**< Non blocking I/O, not ready */
+#define SDL_RWOPS_STATUS_READONLY       4   /**< Tried to write a read-only buffer */
+#define SDL_RWOPS_STATUS_WRITEONLY      5   /**< Tried to read a write-only buffer */
 
 /**
  * This is the read/write operation structure -- very basic.
@@ -52,9 +60,11 @@ extern "C" {
 typedef struct SDL_RWops
 {
     /**
-     *  Return the size of the file in this rwops, or -1 if unknown
+     *  Return the number of bytes in this rwops
+     *
+     *  \return the total size of the data stream, or -1 on error.
      */
-    Sint64 (SDLCALL * size) (struct SDL_RWops * context);
+    Sint64 (SDLCALL *size)(struct SDL_RWops *context);
 
     /**
      *  Seek to \c offset relative to \c whence, one of stdio's whence values:
@@ -62,45 +72,33 @@ typedef struct SDL_RWops
      *
      *  \return the final offset in the data stream, or -1 on error.
      */
-    Sint64 (SDLCALL * seek) (struct SDL_RWops * context, Sint64 offset,
-                             int whence);
+    Sint64 (SDLCALL *seek)(struct SDL_RWops *context, Sint64 offset, int whence);
 
     /**
      *  Read up to \c size bytes from the data stream to the area pointed
      *  at by \c ptr.
      *
-     *  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.
+     *  \return the number of bytes read
      */
-    Sint64 (SDLCALL * read) (struct SDL_RWops * context, void *ptr,
-                             Sint64 size);
+    size_t (SDLCALL *read)(struct SDL_RWops *context, void *ptr, size_t size);
 
     /**
      *  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.
+     *  to data stream.
      *
-     *  \return the number of bytes written, which might be less than \c size,
-     *          and -1 on error.
+     *  \return the number of bytes written
      */
-    Sint64 (SDLCALL * write) (struct SDL_RWops * context, const void *ptr,
-                              Sint64 size);
+    size_t (SDLCALL *write)(struct SDL_RWops *context, const void *ptr, size_t size);
 
     /**
      *  Close and free an allocated SDL_RWops structure.
      *
      *  \return 0 if successful or -1 on write error when flushing data.
      */
-    int (SDLCALL * close) (struct SDL_RWops * context);
+    int (SDLCALL *close)(struct SDL_RWops *context);
 
     Uint32 type;
+    Uint32 status;
     union
     {
 #ifdef __ANDROID__
@@ -213,8 +211,7 @@ typedef struct SDL_RWops
  * \sa SDL_RWtell
  * \sa SDL_RWwrite
  */
-extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromFile(const char *file,
-                                                  const char *mode);
+extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromFile(const char *file, const char *mode);
 
 /**
  * Use this function to prepare a read-write memory buffer for use with
@@ -279,8 +276,7 @@ extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromMem(void *mem, size_t size);
  * \sa SDL_RWseek
  * \sa SDL_RWtell
  */
-extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromConstMem(const void *mem,
-                                                      size_t size);
+extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromConstMem(const void *mem, size_t size);
 
 /* @} *//* RWFrom functions */
 
@@ -289,7 +285,7 @@ extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromConstMem(const void *mem,
  * Use this function to allocate an empty, unpopulated SDL_RWops structure.
  *
  * Applications do not need to use this function unless they are providing
- * their own SDL_RWops implementation. If you just need a SDL_RWops to
+ * their own SDL_RWops implementation. If you just need an SDL_RWops to
  * read/write a common data source, you should use the built-in
  * implementations in SDL, like SDL_RWFromFile() or SDL_RWFromMem(), etc.
  *
@@ -315,7 +311,7 @@ extern DECLSPEC SDL_RWops *SDLCALL SDL_CreateRW(void);
  * SDL_CreateRW().
  *
  * Applications do not need to use this function unless they are providing
- * their own SDL_RWops implementation. If you just need a SDL_RWops to
+ * their own SDL_RWops implementation. If you just need an SDL_RWops to
  * read/write a common data source, you should use the built-in
  * implementations in SDL, like SDL_RWFromFile() or SDL_RWFromMem(), etc, and
  * call the **close** method on those SDL_RWops pointers when you are done
@@ -327,13 +323,13 @@ extern DECLSPEC SDL_RWops *SDLCALL SDL_CreateRW(void);
  * the programmer must be responsible for managing that memory in their
  * **close** method.
  *
- * \param area the SDL_RWops structure to be freed
+ * \param context the SDL_RWops structure to be freed
  *
  * \since This function is available since SDL 3.0.0.
  *
  * \sa SDL_CreateRW
  */
-extern DECLSPEC void SDLCALL SDL_DestroyRW(SDL_RWops * area);
+extern DECLSPEC void SDLCALL SDL_DestroyRW(SDL_RWops *context);
 
 #define SDL_RW_SEEK_SET 0       /**< Seek from the beginning of data */
 #define SDL_RW_SEEK_CUR 1       /**< Seek relative to current read point */
@@ -342,12 +338,8 @@ extern DECLSPEC void SDLCALL SDL_DestroyRW(SDL_RWops * area);
 /**
  * Use this function to get the size of the data stream in an SDL_RWops.
  *
- * Prior to SDL 2.0.10, this function was a macro.
- *
  * \param context the SDL_RWops to get the size of the data stream from
- * \returns the size of the data stream in the SDL_RWops on success, -1 if
- *          unknown or a negative error code on failure; call SDL_GetError()
- *          for more information.
+ * \returns the size of the data stream in the SDL_RWops on success or a negative error code on failure; call SDL_GetError() for more information.
  *
  * \since This function is available since SDL 3.0.0.
  */
@@ -369,14 +361,12 @@ extern DECLSPEC Sint64 SDLCALL SDL_RWsize(SDL_RWops *context);
  * SDL_RWseek() is actually a wrapper function that calls the SDL_RWops's
  * `seek` method appropriately, to simplify application development.
  *
- * Prior to SDL 2.0.10, this function was a macro.
- *
  * \param context a pointer to an SDL_RWops structure
  * \param offset an offset in bytes, relative to **whence** location; can be
  *               negative
  * \param whence any of `SDL_RW_SEEK_SET`, `SDL_RW_SEEK_CUR`,
  *               `SDL_RW_SEEK_END`
- * \returns the final offset in the data stream after the seek or -1 on error.
+ * \returns the final offset in the data stream after the seek or a negative error code on failure; call SDL_GetError() for more information.
  *
  * \since This function is available since SDL 3.0.0.
  *
@@ -388,8 +378,7 @@ extern DECLSPEC Sint64 SDLCALL SDL_RWsize(SDL_RWops *context);
  * \sa SDL_RWtell
  * \sa SDL_RWwrite
  */
-extern DECLSPEC Sint64 SDLCALL SDL_RWseek(SDL_RWops *context,
-                                          Sint64 offset, int whence);
+extern DECLSPEC Sint64 SDLCALL SDL_RWseek(SDL_RWops *context, Sint64 offset, int whence);
 
 /**
  * Determine the current read/write offset in an SDL_RWops data stream.
@@ -398,9 +387,7 @@ extern DECLSPEC Sint64 SDLCALL SDL_RWseek(SDL_RWops *context,
  * method, with an offset of 0 bytes from `SDL_RW_SEEK_CUR`, to simplify
  * application development.
  *
- * Prior to SDL 2.0.10, this function was a macro.
- *
- * \param context a SDL_RWops data stream object from which to get the current
+ * \param context an SDL_RWops data stream object from which to get the current
  *                offset
  * \returns the current offset in the stream, or -1 if the information can not
  *          be determined.
@@ -438,8 +425,7 @@ extern DECLSPEC Sint64 SDLCALL SDL_RWtell(SDL_RWops *context);
  * \param context a pointer to an SDL_RWops structure
  * \param ptr a pointer to a buffer to read data into
  * \param size the number of bytes to read from the data source.
- * \returns the number of bytes read, 0 at end of file, -1 on error, and -2
- *          for data not ready with a non-blocking context.
+ * \returns the number of bytes read, or 0 on end of file or other error.
  *
  * \since This function is available since SDL 3.0.0.
  *
@@ -450,7 +436,7 @@ extern DECLSPEC Sint64 SDLCALL SDL_RWtell(SDL_RWops *context);
  * \sa SDL_RWseek
  * \sa SDL_RWwrite
  */
-extern DECLSPEC Sint64 SDLCALL SDL_RWread(SDL_RWops *context, void *ptr, Sint64 size);
+extern DECLSPEC size_t SDLCALL SDL_RWread(SDL_RWops *context, void *ptr, size_t size);
 
 /**
  * Write to an SDL_RWops data stream.
@@ -488,8 +474,7 @@ extern DECLSPEC Sint64 SDLCALL SDL_RWread(SDL_RWops *context, void *ptr, Sint64
  * \sa SDL_RWread
  * \sa SDL_RWseek
  */
-extern DECLSPEC Sint64 SDLCALL SDL_RWwrite(SDL_RWops *context,
-                                           const void *ptr, Sint64 size);
+extern DECLSPEC size_t SDLCALL SDL_RWwrite(SDL_RWops *context, const void *ptr, size_t size);
 
 /**
  * Close and free an allocated SDL_RWops structure.
@@ -502,8 +487,6 @@ extern DECLSPEC Sint64 SDLCALL SDL_RWwrite(SDL_RWops *context,
  * Note that if this fails to flush the stream to disk, this function reports
  * an error, but the SDL_RWops is still invalid once this function returns.
  *
- * Prior to SDL 2.0.10, this function was a macro.
- *
  * \param context SDL_RWops structure to close
  * \returns 0 on success or a negative error code on failure; call
  *          SDL_GetError() for more information.
@@ -536,9 +519,7 @@ extern DECLSPEC int SDLCALL SDL_RWclose(SDL_RWops *context);
  *
  * \since This function is available since SDL 3.0.0.
  */
-extern DECLSPEC void *SDLCALL SDL_LoadFile_RW(SDL_RWops *src,
-                                              size_t *datasize,
-                                              SDL_bool freesrc);
+extern DECLSPEC void *SDLCALL SDL_LoadFile_RW(SDL_RWops *src, size_t *datasize, SDL_bool freesrc);
 
 /**
  * Load all the data from a file path.
@@ -549,9 +530,6 @@ extern DECLSPEC void *SDLCALL SDL_LoadFile_RW(SDL_RWops *src,
  *
  * The data should be freed with SDL_free().
  *
- * Prior to SDL 2.0.10, this function was a macro wrapping around
- * SDL_LoadFile_RW.
- *
  * \param file the path to read all available data from
  * \param datasize if not NULL, will store the number of bytes read
  * \returns the data, or NULL if there was an error.
@@ -571,14 +549,28 @@ extern DECLSPEC void *SDLCALL SDL_LoadFile(const char *file, size_t *datasize);
  * Use this function to read a byte from an SDL_RWops.
  *
  * \param src the SDL_RWops to read from
- * \returns the read byte on success or 0 on failure; call SDL_GetError() for
+ * \param value a pointer filled in with the data read
+ * \returns SDL_TRUE on success or SDL_FALSE on failure; call SDL_GetError() for
  *          more information.
  *
  * \since This function is available since SDL 3.0.0.
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_ReadU8(SDL_RWops *src, Uint8 *value);
+
+/**
+ * Use this function to read 16 bits of little-endian data from an SDL_RWops
+ * and return in native format.
  *
- * \sa SDL_WriteU8
+ * SDL byteswaps the data only if necessary, so the data returned will be in
+ * the native byte order.
+ *
+ * \param src the stream from which to read data
+ * \param value a pointer filled in with the data read
+ * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.0.0.
  */
-extern DECLSPEC Uint8 SDLCALL SDL_ReadU8(SDL_RWops * src);
+extern DECLSPEC SDL_bool SDLCALL SDL_ReadU16LE(SDL_RWops *src, Uint16 *value);
 
 /**
  * Use this function to read 16 bits of little-endian data from an SDL_RWops
@@ -588,13 +580,13 @@ extern DECLSPEC Uint8 SDLCALL SDL_ReadU8(SDL_RWops * src);
  * the native byte order.
  *
  * \param src the stream from which to read data
- * \returns 16 bits of data in the native byte order of the platform.
+ * \param value a pointer filled in with the data read
+ * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call SDL_GetError() for more information.
  *
  * \since This function is available since SDL 3.0.0.
  *
- * \sa SDL_ReadBE16
  */
-extern DECLSPEC Uint16 SDLCALL SDL_ReadLE16(SDL_RWops * src);
+extern DECLSPEC SDL_bool SDLCALL SDL_ReadS16LE(SDL_RWops *src, Sint16 *value);
 
 /**
  * Use this function to read 16 bits of big-endian data from an SDL_RWops and
@@ -604,13 +596,28 @@ extern DECLSPEC Uint16 SDLCALL SDL_ReadLE16(SDL_RWops * src);
  * the native byte order.
  *
  * \param src the stream from which to read data
- * \returns 16 bits of data in the native byte order of the platform.
+ * \param value a pointer filled in with the data read
+ * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call SDL_GetError() for more information.
  *
  * \since This function is available since SDL 3.0.0.
  *
- * \sa SDL_ReadLE16
  */
-extern DECLSPEC Uint16 SDLCALL SDL_ReadBE16(SDL_RWops * src);
+extern DECLSPEC SDL_bool SDLCALL SDL_ReadU16BE(SDL_RWops *src, Uint16 *value);
+
+/**
+ * Use this function to read 16 bits of big-endian data from an SDL_RWops and
+ * return in native format.
+ *
+ * SDL byteswaps the data only if necessary, so the data returned will be in
+ * the native byte order.
+ *
+ * \param src the stream from which to read data
+ * \param value a pointer filled in with the data read
+ * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.0.0.
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_ReadS16BE(SDL_RWops *src, Sint16 *value);
 
 /**
  * Use this function to read 32 bits of little-endian data from an SDL_RWops
@@ -620,13 +627,27 @@ extern DECLSPEC Uint16 SDLCALL SDL_ReadBE16(SDL_RWops * src);
  * the native byte order.
  *
  * \param src the stream from which to read data
- * \returns 32 bits of data in the native byte order of the platform.
+ * \param value a pointer filled in with the data read
+ * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call SDL_GetError() for more information.
  *
  * \since This function is available since SDL 3.0.0.
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_ReadU32LE(SDL_RWops *src, Uint32 *value);
+
+/**
+ * Use this function to read 32 bits of little-endian data from an SDL_RWops
+ * and return in native format.
  *
- * \sa SDL_ReadBE32
+ * SDL byteswaps the data only if necessary, so the data returned will be in
+ * the native byte order.
+ *
+ * \param src the stream from which to read data
+ * \param value a pointer filled in with the data read
+ * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.0.0.
  */
-extern DECLSPEC Uint32 SDLCALL SDL_ReadLE32(SDL_RWops * src);
+extern DECLSPEC SDL_bool SDLCALL SDL_ReadS32LE(SDL_RWops *src, Sint32 *value);
 
 /**
  * Use this function to read 32 bits of big-endian data from an SDL_RWops and
@@ -636,13 +657,27 @@ extern DECLSPEC Uint32 SDLCALL SDL_ReadLE32(SDL_RWops * src);
  * the native byte order.
  *
  * \param src the stream from which to read data
- * \returns 32 bits of data in the native byte order of the platform.
+ * \param value a pointer filled in with the data read
+ * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call SDL_GetError() for more information.
  *
  * \since This function is available since SDL 3.0.0.
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_ReadU32BE(SDL_RWops *src, Uint32 *value);
+
+/**
+ * Use this function to read 32 bits of big-endian data from an SDL_RWops and
+ * return in native format.
  *
- * \sa SDL_ReadLE32
+ * SDL byteswaps the data only if necessary, so the data returned will be in
+ * the native byte order.
+ *
+ * \param src the stream from which to read data
+ * \param value a pointer filled in with the data read
+ * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.0.0.
  */
-extern DECLSPEC Uint32 SDLCALL SDL_ReadBE32(SDL_RWops * src);
+extern DECLSPEC SDL_bool SDLCALL SDL_ReadS32BE(SDL_RWops *src, Sint32 *value);
 
 /**
  * Use this function to read 64 bits of little-endian data from an SDL_RWops
@@ -652,13 +687,27 @@ extern DECLSPEC Uint32 SDLCALL SDL_ReadBE32(SDL_RWops * src);
  * the native byte order.
  *
  * \param src the stream from which to read data
- * \returns 64 bits of data in the native byte order of the platform.
+ * \param value a pointer filled in with the data read
+ * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call SDL_GetError() for more information.
  *
  * \since This function is available since SDL 3.0.0.
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_ReadU64LE(SDL_RWops *src, Uint64 *value);
+
+/**
+ * Use this function to read 64 bits of little-endian data from an SDL_RWops
+ * and return in native format.
  *
- * \sa SDL_ReadBE64
+ * SDL byteswaps the data only if necessary, so the data returned will be in
+ * the native byte order.
+ *
+ * \param src the stream from which to read data
+ * \param value a pointer filled in with the data read
+ * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.0.0.
  */
-extern DECLSPEC Uint64 SDLCALL SDL_ReadLE64(SDL_RWops * src);
+extern DECLSPEC SDL_bool SDLCALL SDL_ReadS64LE(SDL_RWops *src, Sint64 *value);
 
 /**
  * Use this function to read 64 bits of big-endian data from an SDL_RWops and
@@ -668,13 +717,27 @@ extern DECLSPEC Uint64 SDLCALL SDL_ReadLE64(SDL_RWops * src);
  * the native byte order.
  *
  * \param src the stream from which to read data
- * \returns 64 bits of data in the native byte order of the platform.
+ * \param value a pointer filled in with the data read
+ * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call SDL_GetError() for more information.
  *
  * \since This function is available since SDL 3.0.0.
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_ReadU64BE(SDL_RWops *src, Uint64 *value);
+
+/**
+ * Use this function to read 64 bits of big-endian data from an SDL_RWops and
+ * return in native format.
  *
- * \sa SDL_ReadLE64
+ * SDL byteswaps the data only if necessary, so the data returned will be in
+ * the native byte order.
+ *
+ * \param src the stream from which to read data
+ * \param value a pointer filled in with the data read
+ * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.0.0.
  */
-extern DECLSPEC Uint64 SDLCALL SDL_ReadBE64(SDL_RWops * src);
+extern DECLSPEC SDL_bool SDLCALL SDL_ReadS64BE(SDL_RWops *src, Sint64 *value);
 /* @} *//* Read endian functions */
 
 /**
@@ -689,17 +752,14 @@ extern DECLSPEC Uint64 SDLCALL SDL_ReadBE64(SDL_RWops * src);
  *
  * \param dst the SDL_RWops to write to
  * \param value the byte value to write
- * \returns 1 on success or 0 on failure; call SDL_GetError() for more
- *          information.
+ * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call SDL_GetError() for more information.
  *
  * \since This function is available since SDL 3.0.0.
- *
- * \sa SDL_ReadU8
  */
-extern DECLSPEC size_t SDLCALL SDL_WriteU8(SDL_RWops * dst, Uint8 value);
+extern DECLSPEC SDL_bool SDLCALL SDL_WriteU8(SDL_RWops *dst, Uint8 value);
 
 /**
- * Use this function to write 16 bits in native format to a SDL_RWops as
+ * Use this function to write 16 bits in native format to an SDL_RWops as
  * little-endian data.
  *
  * SDL byteswaps the data only if necessary, so the application always
@@ -708,16 +768,30 @@ extern DECLSPEC size_t SDLCALL SDL_WriteU8(SDL_RWops * dst, Uint8 value);
  *
  * \param dst the stream to which data will be written
  * \param value the data to be written, in native format
- * \returns 1 on successful write, 0 on error.
+ * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call SDL_GetError() for more information.
  *
  * \since This function is available since SDL 3.0.0.
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_WriteU16LE(SDL_RWops *dst, Uint16 value);
+
+/**
+ * Use this function to write 16 bits in native format to an SDL_RWops as
+ * little-endian data.
+ *
+ * SDL byteswaps the data only if necessary, so the application always
+ * specifies native format, and the data written will be in little-endian
+ * format.
+ *
+ * \param dst the stream to which data will be written
+ * \param value the data to be written, in native format
+ * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call SDL_GetError() for more information.
  *
- * \sa SDL_WriteBE16
+ * \since This function is available since SDL 3.0.0.
  */
-extern DECLSPEC size_t SDLCALL SDL_WriteLE16(SDL_RWops * dst, Uint16 value);
+extern DECLSPEC SDL_bool SDLCALL SDL_WriteS16LE(SDL_RWops *dst, Sint16 value);
 
 /**
- * Use this function to write 16 bits in native format to a SDL_RWops as
+ * Use this function to write 16 bits in native format to an SDL_RWops as
  * big-endian data.
  *
  * SDL byteswaps the data only if necessary, so the application always
@@ -725,16 +799,29 @@ extern DECLSPEC size_t SDLCALL SDL_WriteLE16(SDL_RWops * dst, Uint16 value);
  *
  * \param dst the stream to which data will be written
  * \param value the data to be written, in native format
- * \returns 1 on successful write, 0 on error.
+ * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call SDL_GetError() for more information.
  *
  * \since This function is available since SDL 3.0.0.
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_WriteU16BE(SDL_RWops *dst, Uint16 value);
+
+/**
+ * Use this function to write 16 bits in native format to an SDL_RWops as
+ * big-endian data.
  *
- * \sa SDL_WriteLE16
+ * SDL byteswaps the data only if necessary, so the application always
+ * specifies native format, and the data written will be in big-endian format.
+ *
+ * \param dst the stream to which data will be written
+ * \param value the data to be written, in native format
+ * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.0.0.
  */
-extern DECLSPEC size_t SDLCALL SDL_WriteBE16(SDL_RWops * dst, Uint16 value);
+extern DECLSPEC SDL_bool SDLCALL SDL_WriteS16BE(SDL_RWops *dst, Sint16 value);
 
 /**
- * Use this function to write 32 bits in native format to a SDL_RWops as
+ * Use this function to write 32 bits in native format to an SDL_RWops as
  * little-endian data.
  *
  * SDL byteswaps the data only if necessary, so the application always
@@ -743,16 +830,30 @@ extern DECLSPEC size_t SDLCALL SDL_WriteBE16(SDL_RWops * dst, Uint16 value);
  *
  * \param dst the stream to which data will be written
  * \param value the data to be written, in native format
- * \returns 1 on successful write, 0 on error.
+ * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call SDL_GetError() for more information.
  *
  * \since This function is available since SDL 3.0.0.
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_WriteU32LE(SDL_RWops *dst, Uint32 value);
+
+/**
+ * Use this function to write 32 bits in native format to an SDL_RWops as
+ * little-endian data.
+ *
+ * SDL byteswaps the data only if necessary, so the application always
+ * specifies native format, and the data written will be in little-endian
+ * format.
+ *
+ * \param dst the stream to which data will be written
+ * \param value the data to be written, in native format
+ * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call SDL_GetError() for more information.
  *
- * \sa SDL_WriteBE32
+ * \since This function is available since SDL 3.0.0.
  */
-extern DECLSPEC size_t SDLCALL SDL_WriteLE32(SDL_RWops * dst, Uint32 value);
+extern DECLSPEC SDL_bool SDLCALL SDL_WriteS32LE(SDL_RWops *dst, Sint32 value);
 
 /**
- * Use this function to write 32 bits in native format to a SDL_RWops as
+ * Use this function to write 32 bits in native format to an SDL_RWops as
  * big-endian data.
  *
  * SDL byteswaps the data only if necessary, so the application always
@@ -760,16 +861,29 @@ extern DECLSPEC size_t SDLCALL SDL_WriteLE32(SDL_RWops * dst, Uint32 value);
  *
  * \param dst the stream to which data will be written
  * \param value the data to be written, in native format
- * \returns 1 on successful write, 0 on error.
+ * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call SDL_GetError() for more information.
  *
  * \since This function is available since SDL 3.0.0.
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_WriteU32BE(SDL_RWops *dst, Uint32 value);
+
+/**
+ * Use this function to write 32 bits in native format to an SDL_RWops as
+ * big-endian data.
+ *
+ * SDL byteswaps the data only if necessary, so the application always
+ * specifies native format, and the data written will be in big-endian format.
  *
- * \sa SDL_WriteLE32
+ * \param dst the stream to which data will be written
+ * \param value the data to be written, in native format
+ * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.0.0.
  */
-extern DECLSPEC size_t SDLCALL SDL_WriteBE32(SDL_RWops * dst, Uint32 value);
+extern DECLSPEC SDL_bool SDLCALL SDL_WriteS32BE(SDL_RWops *dst, Sint32 value);
 
 /**
- * Use this function to write 64 bits in native format to a SDL_RWops as
+ * Use this function to write 64 bits in native format to an SDL_RWops as
  * little-endian data.
  *
  * SDL byteswaps the data only if necessary, so the application always
@@ -778,16 +892,30 @@ extern DECLSPEC size_t SDLCALL SDL_WriteBE32(SDL_RWops * dst, Uint32 value);
  *
  * \param dst the stream to which data will be written
  * \param value the data to be written, in native format
- * \returns 1 on successful write, 0 on error.
+ * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call SDL_GetError() for more information.
  *
  * \since This function is available since SDL 3.0.0.
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_WriteU64LE(SDL_RWops *dst, Uint64 value);
+
+/**
+ * Use this function to write 64 bits in native format to an SDL_RWops as
+ * little-endian data.
+ *
+ * SDL byteswaps the data only if necessary, so the application always
+ * specifies native format, and the data written will be in little-endian
+ * format.
  *
- * \sa SDL_WriteBE64
+ * \param dst the stream to which data will be written
+ * \param value the data to be written, in native format
+ * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.0.0.
  */
-extern DECLSPEC size_t SDLCALL SDL_WriteLE64(SDL_RWops * dst, Uint64 value);
+extern DECLSPEC SDL_bool SDLCALL SDL_WriteS64LE(SDL_RWops *dst, Sint64 value);
 
 /**
- * Use this function to write 64 bits in native format to a SDL_RWops as
+ * Use this function to write 64 bits in native format to an SDL_RWops as
  * big-endian data.
  *
  * SDL byteswaps the data only if necessary, so the application always
@@ -795,13 +923,26 @@ extern DECLSPEC size_t SDLCALL SDL_WriteLE64(SDL_RWops * dst, Uint64 value);
  *
  * \param dst the stream to which data will be written
  * \param value the data to be written, in native format
- * \returns 1 on successful write, 0 on error.
+ * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call SDL_GetError() for more information.
  *
  * \since This function is available since SDL 3.0.0.
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_WriteU64BE(SDL_RWops *dst, Uint64 value);
+
+/**
+ * Use this function to write 64 bits in native format to an SDL_RWops as
+ * big-endian data.
+ *
+ * SDL byteswaps the data only if necessary, so the application always
+ * specifies native format, and the data written will be in big-endian format.
  *
- * \sa SDL_WriteLE64
+ * \param dst the stream to which data will be written
+ * \param value the data to be written, in native format
+ * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.0.0.
  */
-extern DECLSPEC size_t SDLCALL SDL_WriteBE64(SDL_RWops * dst, Uint64 value);
+extern DECLSPEC SDL_bool SDLCALL SDL_WriteU64BE(SDL_RWops *dst, Uint64 value);
 /* @} *//* Write endian functions */
 
 /* Ends C function definitions when using C++ */

+ 3 - 2
include/SDL3/SDL_surface.h

@@ -273,7 +273,8 @@ extern DECLSPEC SDL_Surface *SDLCALL SDL_LoadBMP(const char *file);
  *
  * \param surface the SDL_Surface structure containing the image to be saved
  * \param dst a data stream to save to
- * \param freedst non-zero to close the stream after being written
+ * \param freedst if SDL_TRUE, calls SDL_RWclose() on `dst` before returning,
+ *                even in the case of an error
  * \returns 0 on success or a negative error code on failure; call
  *          SDL_GetError() for more information.
  *
@@ -282,7 +283,7 @@ extern DECLSPEC SDL_Surface *SDLCALL SDL_LoadBMP(const char *file);
  * \sa SDL_LoadBMP_RW
  * \sa SDL_SaveBMP
  */
-extern DECLSPEC int SDLCALL SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst);
+extern DECLSPEC int SDLCALL SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, SDL_bool freedst);
 
 /**
  * Save a surface to a file.

+ 22 - 17
src/audio/SDL_wave.c

@@ -1553,7 +1553,7 @@ static int WaveReadPartialChunkData(SDL_RWops *src, WaveChunk *chunk, size_t len
             return -2;
         }
 
-        chunk->size = (size_t) SDL_RWread(src, chunk->data, length);
+        chunk->size = SDL_RWread(src, chunk->data, length);
         if (chunk->size != length) {
             /* Expected to be handled by the caller. */
         }
@@ -1614,16 +1614,20 @@ static int WaveReadFormat(WaveFile *file)
         return SDL_OutOfMemory();
     }
 
-    format->formattag = SDL_ReadLE16(fmtsrc);
+    if (!SDL_ReadU16LE(fmtsrc, &format->formattag) ||
+        !SDL_ReadU16LE(fmtsrc, &format->channels) ||
+        !SDL_ReadU32LE(fmtsrc, &format->frequency) ||
+        !SDL_ReadU32LE(fmtsrc, &format->byterate) ||
+        !SDL_ReadU16LE(fmtsrc, &format->blockalign)) {
+        return -1;
+    }
     format->encoding = format->formattag;
-    format->channels = SDL_ReadLE16(fmtsrc);
-    format->frequency = SDL_ReadLE32(fmtsrc);
-    format->byterate = SDL_ReadLE32(fmtsrc);
-    format->blockalign = SDL_ReadLE16(fmtsrc);
 
     /* This is PCM specific in the first version of the specification. */
     if (fmtlen >= 16) {
-        format->bitspersample = SDL_ReadLE16(fmtsrc);
+        if (!SDL_ReadU16LE(fmtsrc, &format->bitspersample)) {
+            return -1;
+        }
     } else if (format->encoding == PCM_CODE) {
         SDL_RWclose(fmtsrc);
         return SDL_SetError("Missing wBitsPerSample field in WAVE fmt chunk");
@@ -1631,7 +1635,9 @@ static int WaveReadFormat(WaveFile *file)
 
     /* The earlier versions also don't have this field. */
     if (fmtlen >= 18) {
-        format->extsize = SDL_ReadLE16(fmtsrc);
+        if (!SDL_ReadU16LE(fmtsrc, &format->extsize)) {
+            return -1;
+        }
     }
 
     if (format->formattag == EXTENSIBLE_CODE) {
@@ -1647,10 +1653,11 @@ static int WaveReadFormat(WaveFile *file)
             return SDL_SetError("Extensible WAVE header too small");
         }
 
-        format->validsamplebits = SDL_ReadLE16(fmtsrc);
+        if (!SDL_ReadU16LE(fmtsrc, &format->validsamplebits) ||
+            !SDL_ReadU32LE(fmtsrc, &format->channelmask) ||
+            SDL_RWread(fmtsrc, format->subformat, 16) != 16) {
+        }
         format->samplesperblock = format->validsamplebits;
-        format->channelmask = SDL_ReadLE32(fmtsrc);
-        SDL_RWread(fmtsrc, format->subformat, 16);
         format->encoding = WaveGetFormatGUIDEncoding(format);
     }
 
@@ -1802,9 +1809,9 @@ 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)) != sizeof(Uint32)) {
+        if (!SDL_ReadU32LE(src, &formtype)) {
             return SDL_SetError("Could not read RIFF form type");
-        } else if (SDL_SwapLE32(formtype) != WAVE) {
+        } else if (formtype != WAVE) {
             return SDL_SetError("RIFF form type is not WAVE (not a Waveform file)");
         }
     } else if (RIFFchunk.fourcc == WAVE) {
@@ -1891,10 +1898,8 @@ static int WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 *
                 } else {
                     /* Let's use src directly, it's just too convenient. */
                     Sint64 position = SDL_RWseek(src, chunk->position, SDL_RW_SEEK_SET);
-                    Uint32 samplelength;
-                    if (position == chunk->position && SDL_RWread(src, &samplelength, sizeof(Uint32)) == sizeof(Uint32)) {
+                    if (position == chunk->position && SDL_ReadU32LE(src, &file->fact.samplelength)) {
                         file->fact.status = 1;
-                        file->fact.samplelength = SDL_SwapLE32(samplelength);
                     } else {
                         file->fact.status = -1;
                     }
@@ -1937,7 +1942,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, SDL_RW_SEEK_SET) != (Sint64)position) {
                 return SDL_SetError("Could not seek to WAVE chunk data");
-            } else if (SDL_RWread(src, &tmp, 1) != 1) {
+            } else if (!SDL_ReadU8(src, &tmp)) {
                 return SDL_SetError("RIFF size truncates chunk");
             }
         }

+ 2 - 2
src/audio/disk/SDL_diskaudio.c

@@ -42,7 +42,7 @@ static void DISKAUDIO_WaitDevice(SDL_AudioDevice *device)
 
 static void DISKAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buffer_size)
 {
-    const Sint64 written = SDL_RWwrite(device->hidden->io, buffer, buffer_size);
+    const int written = (int)SDL_RWwrite(device->hidden->io, buffer, (size_t)buffer_size);
     if (written != buffer_size) { // If we couldn't write, assume fatal error for now
         SDL_AudioDeviceDisconnected(device);
     }
@@ -62,7 +62,7 @@ static int DISKAUDIO_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, in
     const int origbuflen = buflen;
 
     if (h->io) {
-        const int br = (int) SDL_RWread(h->io, buffer, (Sint64) buflen);
+        const int br = (int)SDL_RWread(h->io, buffer, (size_t)buflen);
         buflen -= br;
         buffer = ((Uint8 *)buffer) + br;
         if (buflen > 0) { // EOF (or error, but whatever).

+ 8 - 3
src/core/android/SDL_android.c

@@ -1983,13 +1983,18 @@ int Android_JNI_FileOpen(SDL_RWops *ctx,
     return 0;
 }
 
-Sint64 Android_JNI_FileRead(SDL_RWops *ctx, void *buffer, Sint64 size)
+size_t Android_JNI_FileRead(SDL_RWops *ctx, void *buffer, size_t size)
 {
     AAsset *asset = (AAsset *)ctx->hidden.androidio.asset;
-    return (Sint64) AAsset_read(asset, buffer, (size_t) size);
+    int bytes = AAsset_read(asset, buffer, size);
+    if (bytes < 0) {
+        SDL_SetError("AAsset_read() failed");
+        return 0;
+    }
+    return (size_t)bytes;
 }
 
-Sint64 Android_JNI_FileWrite(SDL_RWops *ctx, const void *buffer, Sint64 size)
+size_t Android_JNI_FileWrite(SDL_RWops *ctx, const void *buffer, size_t size)
 {
     return SDL_SetError("Cannot write to Android package filesystem");
 }

+ 2 - 2
src/core/android/SDL_android.h

@@ -66,8 +66,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);
-Sint64 Android_JNI_FileRead(SDL_RWops *ctx, void *buffer, Sint64 size);
-Sint64 Android_JNI_FileWrite(SDL_RWops *ctx, const void *buffer, Sint64 size);
+size_t Android_JNI_FileRead(SDL_RWops *ctx, void *buffer, size_t size);
+size_t Android_JNI_FileWrite(SDL_RWops *ctx, const void *buffer, size_t size);
 int Android_JNI_FileClose(SDL_RWops *ctx);
 
 /* Environment support */

+ 23 - 12
src/dynapi/SDL_dynapi.sym

@@ -504,12 +504,12 @@ SDL3_0.0.0 {
     SDL_RWtell;
     SDL_RWwrite;
     SDL_RaiseWindow;
-    SDL_ReadBE16;
-    SDL_ReadBE32;
-    SDL_ReadBE64;
-    SDL_ReadLE16;
-    SDL_ReadLE32;
-    SDL_ReadLE64;
+    SDL_ReadU16BE;
+    SDL_ReadU32BE;
+    SDL_ReadU64BE;
+    SDL_ReadU16LE;
+    SDL_ReadU32LE;
+    SDL_ReadU64LE;
     SDL_ReadU8;
     SDL_RegisterApp;
     SDL_RegisterEvents;
@@ -676,12 +676,12 @@ SDL3_0.0.0 {
     SDL_WinRTGetDeviceFamily;
     SDL_WinRTGetFSPathUNICODE;
     SDL_WinRTGetFSPathUTF8;
-    SDL_WriteBE16;
-    SDL_WriteBE32;
-    SDL_WriteBE64;
-    SDL_WriteLE16;
-    SDL_WriteLE32;
-    SDL_WriteLE64;
+    SDL_WriteU16BE;
+    SDL_WriteU32BE;
+    SDL_WriteU64BE;
+    SDL_WriteU16LE;
+    SDL_WriteU32LE;
+    SDL_WriteU64LE;
     SDL_WriteU8;
     SDL_abs;
     SDL_acos;
@@ -888,6 +888,17 @@ SDL3_0.0.0 {
     SDL_IsAudioDevicePaused;
     SDL_GetAudioStreamBinding;
     SDL_ShowWindowSystemMenu;
+    SDL_ReadS16LE;
+    SDL_ReadS16BE;
+    SDL_ReadS32LE;
+    SDL_ReadS32BE;
+    SDL_ReadS64LE;
+    SDL_ReadS64BE;
+    SDL_WriteS16LE;
+    SDL_WriteS16BE;
+    SDL_WriteS32LE;
+    SDL_WriteS32BE;
+    SDL_WriteS64LE;
     # extra symbols go here (don't modify this line)
   local: *;
 };

+ 23 - 12
src/dynapi/SDL_dynapi_overrides.h

@@ -528,12 +528,12 @@
 #define SDL_RWtell SDL_RWtell_REAL
 #define SDL_RWwrite SDL_RWwrite_REAL
 #define SDL_RaiseWindow SDL_RaiseWindow_REAL
-#define SDL_ReadBE16 SDL_ReadBE16_REAL
-#define SDL_ReadBE32 SDL_ReadBE32_REAL
-#define SDL_ReadBE64 SDL_ReadBE64_REAL
-#define SDL_ReadLE16 SDL_ReadLE16_REAL
-#define SDL_ReadLE32 SDL_ReadLE32_REAL
-#define SDL_ReadLE64 SDL_ReadLE64_REAL
+#define SDL_ReadU16BE SDL_ReadU16BE_REAL
+#define SDL_ReadU32BE SDL_ReadU32BE_REAL
+#define SDL_ReadU64BE SDL_ReadU64BE_REAL
+#define SDL_ReadU16LE SDL_ReadU16LE_REAL
+#define SDL_ReadU32LE SDL_ReadU32LE_REAL
+#define SDL_ReadU64LE SDL_ReadU64LE_REAL
 #define SDL_ReadU8 SDL_ReadU8_REAL
 #define SDL_RegisterApp SDL_RegisterApp_REAL
 #define SDL_RegisterEvents SDL_RegisterEvents_REAL
@@ -699,12 +699,12 @@
 #define SDL_WinRTGetDeviceFamily    SDL_WinRTGetDeviceFamily_REAL
 #define SDL_WinRTGetFSPathUNICODE   SDL_WinRTGetFSPathUNICODE_REAL
 #define SDL_WinRTGetFSPathUTF8  SDL_WinRTGetFSPathUTF8_REAL
-#define SDL_WriteBE16 SDL_WriteBE16_REAL
-#define SDL_WriteBE32 SDL_WriteBE32_REAL
-#define SDL_WriteBE64 SDL_WriteBE64_REAL
-#define SDL_WriteLE16 SDL_WriteLE16_REAL
-#define SDL_WriteLE32 SDL_WriteLE32_REAL
-#define SDL_WriteLE64 SDL_WriteLE64_REAL
+#define SDL_WriteU16BE SDL_WriteU16BE_REAL
+#define SDL_WriteU32BE SDL_WriteU32BE_REAL
+#define SDL_WriteU64BE SDL_WriteU64BE_REAL
+#define SDL_WriteU16LE SDL_WriteU16LE_REAL
+#define SDL_WriteU32LE SDL_WriteU32LE_REAL
+#define SDL_WriteU64LE SDL_WriteU64LE_REAL
 #define SDL_WriteU8 SDL_WriteU8_REAL
 #define SDL_abs SDL_abs_REAL
 #define SDL_acos SDL_acos_REAL
@@ -913,3 +913,14 @@
 #define SDL_IsAudioDevicePaused SDL_IsAudioDevicePaused_REAL
 #define SDL_GetAudioStreamBinding SDL_GetAudioStreamBinding_REAL
 #define SDL_ShowWindowSystemMenu SDL_ShowWindowSystemMenu_REAL
+#define SDL_ReadS16LE SDL_ReadS16LE_REAL
+#define SDL_ReadS16BE SDL_ReadS16BE_REAL
+#define SDL_ReadS32LE SDL_ReadS32LE_REAL
+#define SDL_ReadS32BE SDL_ReadS32BE_REAL
+#define SDL_ReadS64LE SDL_ReadS64LE_REAL
+#define SDL_ReadS64BE SDL_ReadS64BE_REAL
+#define SDL_WriteS16LE SDL_WriteS16LE_REAL
+#define SDL_WriteS16BE SDL_WriteS16BE_REAL
+#define SDL_WriteS32LE SDL_WriteS32LE_REAL
+#define SDL_WriteS32BE SDL_WriteS32BE_REAL
+#define SDL_WriteS64LE SDL_WriteS64LE_REAL

+ 29 - 18
src/dynapi/SDL_dynapi_procs.h

@@ -119,7 +119,7 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_IsDeXMode,(void),(),return)
 
 SDL_DYNAPI_PROC(void,SDL_AddEventWatch,(SDL_EventFilter a, void *b),(a,b),)
 SDL_DYNAPI_PROC(int,SDL_AddGamepadMapping,(const char *a),(a),return)
-SDL_DYNAPI_PROC(int,SDL_AddGamepadMappingsFromRW,(SDL_RWops *a, int b),(a,b),return)
+SDL_DYNAPI_PROC(int,SDL_AddGamepadMappingsFromRW,(SDL_RWops *a, SDL_bool b),(a,b),return)
 SDL_DYNAPI_PROC(int,SDL_AddHintCallback,(const char *a, SDL_HintCallback b, void *c),(a,b,c),return)
 SDL_DYNAPI_PROC(SDL_TimerID,SDL_AddTimer,(Uint32 a, SDL_TimerCallback b, void *c),(a,b,c),return)
 SDL_DYNAPI_PROC(int,SDL_AtomicAdd,(SDL_AtomicInt *a, int b),(a,b),return)
@@ -581,19 +581,19 @@ SDL_DYNAPI_PROC(SDL_RWops*,SDL_RWFromConstMem,(const void *a, size_t b),(a,b),re
 SDL_DYNAPI_PROC(SDL_RWops*,SDL_RWFromFile,(const char *a, const char *b),(a,b),return)
 SDL_DYNAPI_PROC(SDL_RWops*,SDL_RWFromMem,(void *a, size_t b),(a,b),return)
 SDL_DYNAPI_PROC(int,SDL_RWclose,(SDL_RWops *a),(a),return)
-SDL_DYNAPI_PROC(Sint64,SDL_RWread,(SDL_RWops *a, void *b, Sint64 c),(a,b,c),return)
+SDL_DYNAPI_PROC(size_t,SDL_RWread,(SDL_RWops *a, void *b, size_t c),(a,b,c),return)
 SDL_DYNAPI_PROC(Sint64,SDL_RWseek,(SDL_RWops *a, Sint64 b, int c),(a,b,c),return)
 SDL_DYNAPI_PROC(Sint64,SDL_RWsize,(SDL_RWops *a),(a),return)
 SDL_DYNAPI_PROC(Sint64,SDL_RWtell,(SDL_RWops *a),(a),return)
-SDL_DYNAPI_PROC(Sint64,SDL_RWwrite,(SDL_RWops *a, const void *b, Sint64 c),(a,b,c),return)
+SDL_DYNAPI_PROC(size_t,SDL_RWwrite,(SDL_RWops *a, const void *b, size_t c),(a,b,c),return)
 SDL_DYNAPI_PROC(int,SDL_RaiseWindow,(SDL_Window *a),(a),return)
-SDL_DYNAPI_PROC(Uint16,SDL_ReadBE16,(SDL_RWops *a),(a),return)
-SDL_DYNAPI_PROC(Uint32,SDL_ReadBE32,(SDL_RWops *a),(a),return)
-SDL_DYNAPI_PROC(Uint64,SDL_ReadBE64,(SDL_RWops *a),(a),return)
-SDL_DYNAPI_PROC(Uint16,SDL_ReadLE16,(SDL_RWops *a),(a),return)
-SDL_DYNAPI_PROC(Uint32,SDL_ReadLE32,(SDL_RWops *a),(a),return)
-SDL_DYNAPI_PROC(Uint64,SDL_ReadLE64,(SDL_RWops *a),(a),return)
-SDL_DYNAPI_PROC(Uint8,SDL_ReadU8,(SDL_RWops *a),(a),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_ReadU16BE,(SDL_RWops *a, Uint16 *b),(a,b),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_ReadU32BE,(SDL_RWops *a, Uint32 *b),(a,b),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_ReadU64BE,(SDL_RWops *a, Uint64 *b),(a,b),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_ReadU16LE,(SDL_RWops *a, Uint16 *b),(a,b),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_ReadU32LE,(SDL_RWops *a, Uint32 *b),(a,b),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_ReadU64LE,(SDL_RWops *a, Uint64 *b),(a,b),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_ReadU8,(SDL_RWops *a, Uint8 *b),(a,b),return)
 SDL_DYNAPI_PROC(Uint32,SDL_RegisterEvents,(int a),(a),return)
 SDL_DYNAPI_PROC(SDL_bool,SDL_RemoveTimer,(SDL_TimerID a),(a),return)
 SDL_DYNAPI_PROC(int,SDL_RenderClear,(SDL_Renderer *a),(a),return)
@@ -628,7 +628,7 @@ SDL_DYNAPI_PROC(int,SDL_RumbleJoystickTriggers,(SDL_Joystick *a, Uint16 b, Uint1
 SDL_DYNAPI_PROC(int,SDL_RunApp,(int a, char *b[], SDL_main_func c, void *d),(a,b,c,d),return)
 SDL_DYNAPI_PROC(size_t,SDL_SIMDGetAlignment,(void),(),return)
 SDL_DYNAPI_PROC(int,SDL_SaveBMP,(SDL_Surface *a, const char *b),(a,b),return)
-SDL_DYNAPI_PROC(int,SDL_SaveBMP_RW,(SDL_Surface *a, SDL_RWops *b, int c),(a,b,c),return)
+SDL_DYNAPI_PROC(int,SDL_SaveBMP_RW,(SDL_Surface *a, SDL_RWops *b, SDL_bool c),(a,b,c),return)
 SDL_DYNAPI_PROC(SDL_bool,SDL_ScreenKeyboardShown,(SDL_Window *a),(a),return)
 SDL_DYNAPI_PROC(SDL_bool,SDL_ScreenSaverEnabled,(void),(),return)
 SDL_DYNAPI_PROC(int,SDL_SendGamepadEffect,(SDL_Gamepad *a, const void *b, int c),(a,b,c),return)
@@ -750,13 +750,13 @@ SDL_DYNAPI_PROC(void,SDL_WaitThread,(SDL_Thread *a, int *b),(a,b),)
 SDL_DYNAPI_PROC(int,SDL_WarpMouseGlobal,(float a, float b),(a,b),return)
 SDL_DYNAPI_PROC(void,SDL_WarpMouseInWindow,(SDL_Window *a, float b, float c),(a,b,c),)
 SDL_DYNAPI_PROC(Uint32,SDL_WasInit,(Uint32 a),(a),return)
-SDL_DYNAPI_PROC(size_t,SDL_WriteBE16,(SDL_RWops *a, Uint16 b),(a,b),return)
-SDL_DYNAPI_PROC(size_t,SDL_WriteBE32,(SDL_RWops *a, Uint32 b),(a,b),return)
-SDL_DYNAPI_PROC(size_t,SDL_WriteBE64,(SDL_RWops *a, Uint64 b),(a,b),return)
-SDL_DYNAPI_PROC(size_t,SDL_WriteLE16,(SDL_RWops *a, Uint16 b),(a,b),return)
-SDL_DYNAPI_PROC(size_t,SDL_WriteLE32,(SDL_RWops *a, Uint32 b),(a,b),return)
-SDL_DYNAPI_PROC(size_t,SDL_WriteLE64,(SDL_RWops *a, Uint64 b),(a,b),return)
-SDL_DYNAPI_PROC(size_t,SDL_WriteU8,(SDL_RWops *a, Uint8 b),(a,b),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_WriteU16BE,(SDL_RWops *a, Uint16 b),(a,b),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_WriteU32BE,(SDL_RWops *a, Uint32 b),(a,b),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_WriteU64BE,(SDL_RWops *a, Uint64 b),(a,b),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_WriteU16LE,(SDL_RWops *a, Uint16 b),(a,b),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_WriteU32LE,(SDL_RWops *a, Uint32 b),(a,b),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_WriteU64LE,(SDL_RWops *a, Uint64 b),(a,b),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_WriteU8,(SDL_RWops *a, Uint8 b),(a,b),return)
 SDL_DYNAPI_PROC(int,SDL_abs,(int a),(a),return)
 SDL_DYNAPI_PROC(double,SDL_acos,(double a),(a),return)
 SDL_DYNAPI_PROC(float,SDL_acosf,(float a),(a),return)
@@ -957,3 +957,14 @@ SDL_DYNAPI_PROC(int,SDL_ResumeAudioDevice,(SDL_AudioDeviceID a),(a),return)
 SDL_DYNAPI_PROC(SDL_bool,SDL_IsAudioDevicePaused,(SDL_AudioDeviceID a),(a),return)
 SDL_DYNAPI_PROC(SDL_AudioDeviceID,SDL_GetAudioStreamBinding,(SDL_AudioStream *a),(a),return)
 SDL_DYNAPI_PROC(int,SDL_ShowWindowSystemMenu,(SDL_Window *a, int b, int c),(a,b,c),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_ReadS16LE,(SDL_RWops *a, Sint16 *b),(a,b),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_ReadS16BE,(SDL_RWops *a, Sint16 *b),(a,b),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_ReadS32LE,(SDL_RWops *a, Sint32 *b),(a,b),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_ReadS32BE,(SDL_RWops *a, Sint32 *b),(a,b),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_ReadS64LE,(SDL_RWops *a, Sint64 *b),(a,b),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_ReadS64BE,(SDL_RWops *a, Sint64 *b),(a,b),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_WriteS16LE,(SDL_RWops *a, Sint16 b),(a,b),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_WriteS16BE,(SDL_RWops *a, Sint16 b),(a,b),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_WriteS32LE,(SDL_RWops *a, Sint32 b),(a,b),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_WriteS32BE,(SDL_RWops *a, Sint32 b),(a,b),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_WriteS64LE,(SDL_RWops *a, Sint64 b),(a,b),return)

+ 333 - 203
src/file/SDL_rwops.c

@@ -67,10 +67,6 @@ static int SDLCALL windows_file_open(SDL_RWops *context, const char *filename, c
     DWORD must_exist, truncate;
     int a_mode;
 
-    if (context == NULL) {
-        return -1; /* failed (invalid call) */
-    }
-
     context->hidden.windowsio.h = INVALID_HANDLE_VALUE; /* mark this as unusable */
     context->hidden.windowsio.buffer.data = NULL;
     context->hidden.windowsio.buffer.size = 0;
@@ -135,10 +131,6 @@ static Sint64 SDLCALL windows_file_size(SDL_RWops *context)
 {
     LARGE_INTEGER size;
 
-    if (context == NULL || context->hidden.windowsio.h == INVALID_HANDLE_VALUE) {
-        return SDL_SetError("windows_file_size: invalid context/file not opened");
-    }
-
     if (!GetFileSizeEx(context->hidden.windowsio.h, &size)) {
         return WIN_SetError("windows_file_size");
     }
@@ -151,13 +143,9 @@ static Sint64 SDLCALL windows_file_seek(SDL_RWops *context, Sint64 offset, int w
     DWORD windowswhence;
     LARGE_INTEGER windowsoffset;
 
-    if (context == NULL || context->hidden.windowsio.h == INVALID_HANDLE_VALUE) {
-        return SDL_SetError("windows_file_seek: invalid context/file not opened");
-    }
-
     /* FIXME: We may be able to satisfy the seek within buffered data */
     if (whence == SDL_RW_SEEK_CUR && context->hidden.windowsio.buffer.left) {
-        offset -= (long)context->hidden.windowsio.buffer.left;
+        offset -= context->hidden.windowsio.buffer.left;
     }
     context->hidden.windowsio.buffer.left = 0;
 
@@ -182,27 +170,18 @@ static Sint64 SDLCALL windows_file_seek(SDL_RWops *context, Sint64 offset, int w
     return windowsoffset.QuadPart;
 }
 
-static Sint64 SDLCALL
-windows_file_read(SDL_RWops *context, void *ptr, Sint64 size)
+static size_t SDLCALL windows_file_read(SDL_RWops *context, void *ptr, size_t size)
 {
-    size_t total_need = (size_t) size;
+    size_t total_need = size;
     size_t total_read = 0;
     size_t read_ahead;
-    DWORD byte_read;
-
-    if (context == NULL || context->hidden.windowsio.h == INVALID_HANDLE_VALUE) {
-        return SDL_SetError("Invalid file handle");
-    } else if (!total_need) {
-        return 0;
-    }
-
+    DWORD bytes;
 
     if (context->hidden.windowsio.buffer.left > 0) {
         void *data = (char *)context->hidden.windowsio.buffer.data +
                      context->hidden.windowsio.buffer.size -
                      context->hidden.windowsio.buffer.left;
-        read_ahead =
-            SDL_min(total_need, context->hidden.windowsio.buffer.left);
+        read_ahead = SDL_min(total_need, context->hidden.windowsio.buffer.left);
         SDL_memcpy(ptr, data, read_ahead);
         context->hidden.windowsio.buffer.left -= read_ahead;
 
@@ -216,39 +195,37 @@ windows_file_read(SDL_RWops *context, void *ptr, Sint64 size)
 
     if (total_need < READAHEAD_BUFFER_SIZE) {
         if (!ReadFile(context->hidden.windowsio.h, context->hidden.windowsio.buffer.data,
-                      READAHEAD_BUFFER_SIZE, &byte_read, NULL)) {
-            return SDL_Error(SDL_EFREAD);
+                      READAHEAD_BUFFER_SIZE, &bytes, NULL)) {
+            SDL_Error(SDL_EFREAD);
+            return 0;
         }
-        read_ahead = SDL_min(total_need, (int)byte_read);
+        read_ahead = SDL_min(total_need, bytes);
         SDL_memcpy(ptr, context->hidden.windowsio.buffer.data, read_ahead);
-        context->hidden.windowsio.buffer.size = byte_read;
-        context->hidden.windowsio.buffer.left = byte_read - read_ahead;
+        context->hidden.windowsio.buffer.size = bytes;
+        context->hidden.windowsio.buffer.left = bytes - read_ahead;
         total_read += read_ahead;
     } else {
-        if (!ReadFile(context->hidden.windowsio.h, ptr, (DWORD)total_need, &byte_read, NULL)) {
-            return SDL_Error(SDL_EFREAD);
+        if (!ReadFile(context->hidden.windowsio.h, ptr, (DWORD)total_need, &bytes, NULL)) {
+            SDL_Error(SDL_EFREAD);
+            return 0;
         }
-        total_read += byte_read;
+        total_read += bytes;
     }
     return total_read;
 }
 
-static Sint64 SDLCALL
-windows_file_write(SDL_RWops *context, const void *ptr, Sint64 size)
+static size_t SDLCALL windows_file_write(SDL_RWops *context, const void *ptr, size_t size)
 {
-    const size_t total_bytes = (size_t) size;
-    DWORD byte_written;
-
-    if (context == NULL || context->hidden.windowsio.h == INVALID_HANDLE_VALUE) {
-        return SDL_SetError("Invalid file handle");
-    } else if (!total_bytes) {
-        return 0;
-    }
+    const size_t total_bytes = size;
+    DWORD bytes;
 
     if (context->hidden.windowsio.buffer.left) {
-        SetFilePointer(context->hidden.windowsio.h,
+        if (!SetFilePointer(context->hidden.windowsio.h,
                        -(LONG)context->hidden.windowsio.buffer.left, NULL,
-                       FILE_CURRENT);
+                       FILE_CURRENT)) {
+            SDL_Error(SDL_EFSEEK);
+            return 0;
+        }
         context->hidden.windowsio.buffer.left = 0;
     }
 
@@ -257,28 +234,30 @@ windows_file_write(SDL_RWops *context, const void *ptr, Sint64 size)
         LARGE_INTEGER windowsoffset;
         windowsoffset.QuadPart = 0;
         if (!SetFilePointerEx(context->hidden.windowsio.h, windowsoffset, &windowsoffset, FILE_END)) {
-            return SDL_Error(SDL_EFWRITE);
+            SDL_Error(SDL_EFSEEK);
+            return 0;
         }
     }
 
-    if (!WriteFile(context->hidden.windowsio.h, ptr, (DWORD)total_bytes, &byte_written, NULL)) {
-        return SDL_Error(SDL_EFWRITE);
+    if (!WriteFile(context->hidden.windowsio.h, ptr, (DWORD)total_bytes, &bytes, NULL)) {
+        SDL_Error(SDL_EFWRITE);
+        return 0;
     }
 
-    return (Sint64) byte_written;
+    return bytes;
 }
 
 static int SDLCALL windows_file_close(SDL_RWops *context)
 {
-    if (context) {
-        if (context->hidden.windowsio.h != INVALID_HANDLE_VALUE) {
-            CloseHandle(context->hidden.windowsio.h);
-            context->hidden.windowsio.h = INVALID_HANDLE_VALUE; /* to be sure */
-        }
+    if (context->hidden.windowsio.h != INVALID_HANDLE_VALUE) {
+        CloseHandle(context->hidden.windowsio.h);
+        context->hidden.windowsio.h = INVALID_HANDLE_VALUE; /* to be sure */
+    }
+    if (context->hidden.windowsio.buffer.data) {
         SDL_free(context->hidden.windowsio.buffer.data);
         context->hidden.windowsio.buffer.data = NULL;
-        SDL_DestroyRW(context);
     }
+    SDL_DestroyRW(context);
     return 0;
 }
 #endif /* defined(__WIN32__) || defined(__GDK__) */
@@ -323,20 +302,6 @@ static int SDLCALL windows_file_close(SDL_RWops *context)
 #define fseek_off_t long
 #endif
 
-static Sint64 SDLCALL stdio_size(SDL_RWops *context)
-{
-    Sint64 pos, size;
-
-    pos = SDL_RWseek(context, 0, SDL_RW_SEEK_CUR);
-    if (pos < 0) {
-        return -1;
-    }
-    size = SDL_RWseek(context, 0, SDL_RW_SEEK_END);
-
-    SDL_RWseek(context, pos, SDL_RW_SEEK_SET);
-    return size;
-}
-
 static Sint64 SDLCALL stdio_seek(SDL_RWops *context, Sint64 offset, int whence)
 {
     int stdiowhence;
@@ -371,41 +336,37 @@ static Sint64 SDLCALL stdio_seek(SDL_RWops *context, Sint64 offset, int whence)
     return SDL_Error(SDL_EFSEEK);
 }
 
-static Sint64 SDLCALL
-stdio_read(SDL_RWops *context, void *ptr, Sint64 size)
+static size_t SDLCALL stdio_read(SDL_RWops *context, void *ptr, size_t size)
 {
-    size_t nread;
+    size_t bytes;
 
-    nread = fread(ptr, 1, (size_t)size, (FILE *)context->hidden.stdio.fp);
-    if (nread == 0 && ferror((FILE *)context->hidden.stdio.fp)) {
-        return SDL_Error(SDL_EFREAD);
+    bytes = fread(ptr, 1, size, (FILE *)context->hidden.stdio.fp);
+    if (bytes == 0 && ferror((FILE *)context->hidden.stdio.fp)) {
+        SDL_Error(SDL_EFREAD);
     }
-    return (Sint64) nread;
+    return bytes;
 }
 
-static Sint64 SDLCALL
-stdio_write(SDL_RWops *context, const void *ptr, Sint64 size)
+static size_t SDLCALL stdio_write(SDL_RWops *context, const void *ptr, size_t size)
 {
-    size_t nwrote;
+    size_t bytes;
 
-    nwrote = fwrite(ptr, 1, (size_t)size, (FILE *)context->hidden.stdio.fp);
-    if (nwrote == 0 && ferror((FILE *)context->hidden.stdio.fp)) {
-        return SDL_Error(SDL_EFWRITE);
+    bytes = fwrite(ptr, 1, size, (FILE *)context->hidden.stdio.fp);
+    if (bytes == 0 && ferror((FILE *)context->hidden.stdio.fp)) {
+        SDL_Error(SDL_EFWRITE);
     }
-    return (Sint64) nwrote;
+    return bytes;
 }
 
 static int SDLCALL stdio_close(SDL_RWops *context)
 {
     int status = 0;
-    if (context) {
-        if (context->hidden.stdio.autoclose) {
-            if (fclose((FILE *)context->hidden.stdio.fp) != 0) {
-                status = SDL_Error(SDL_EFWRITE);
-            }
+    if (context->hidden.stdio.autoclose) {
+        if (fclose((FILE *)context->hidden.stdio.fp) != 0) {
+            status = SDL_Error(SDL_EFWRITE);
         }
-        SDL_DestroyRW(context);
     }
+    SDL_DestroyRW(context);
     return status;
 }
 
@@ -415,7 +376,6 @@ static SDL_RWops *SDL_RWFromFP(void *fp, SDL_bool autoclose)
 
     rwops = SDL_CreateRW();
     if (rwops != NULL) {
-        rwops->size = stdio_size;
         rwops->seek = stdio_seek;
         rwops->read = stdio_read;
         rwops->write = stdio_write;
@@ -432,7 +392,7 @@ static SDL_RWops *SDL_RWFromFP(void *fp, SDL_bool autoclose)
 
 static Sint64 SDLCALL mem_size(SDL_RWops *context)
 {
-    return (Sint64)(context->hidden.mem.stop - context->hidden.mem.base);
+    return (context->hidden.mem.stop - context->hidden.mem.base);
 }
 
 static Sint64 SDLCALL mem_seek(SDL_RWops *context, Sint64 offset, int whence)
@@ -462,43 +422,27 @@ static Sint64 SDLCALL mem_seek(SDL_RWops *context, Sint64 offset, int whence)
     return (Sint64)(context->hidden.mem.here - context->hidden.mem.base);
 }
 
-static Sint64 mem_io(SDL_RWops *context, void *dst, const void *src, Sint64 size)
+static size_t mem_io(SDL_RWops *context, void *dst, const void *src, size_t size)
 {
-    const Sint64 mem_available = (Sint64) (context->hidden.mem.stop - context->hidden.mem.here);
+    const size_t mem_available = (context->hidden.mem.stop - context->hidden.mem.here);
     if (size > mem_available) {
         size = mem_available;
     }
-    SDL_memcpy(dst, src, (size_t) size);
+    SDL_memcpy(dst, src, size);
     context->hidden.mem.here += size;
     return size;
 }
 
-static Sint64 SDLCALL
-mem_read(SDL_RWops *context, void *ptr, Sint64 size)
+static size_t SDLCALL mem_read(SDL_RWops *context, void *ptr, size_t size)
 {
     return mem_io(context, ptr, context->hidden.mem.here, size);
 }
 
-static Sint64 SDLCALL
-mem_write(SDL_RWops *context, const void *ptr, Sint64 size)
+static size_t SDLCALL mem_write(SDL_RWops *context, const void *ptr, size_t size)
 {
     return mem_io(context, context->hidden.mem.here, ptr, size);
 }
 
-static Sint64 SDLCALL
-mem_writeconst(SDL_RWops *context, const void *ptr, Sint64 size)
-{
-    return SDL_SetError("Can't write to read-only memory");
-}
-
-static int SDLCALL mem_close(SDL_RWops *context)
-{
-    if (context) {
-        SDL_DestroyRW(context);
-    }
-    return 0;
-}
-
 /* Functions to create SDL_RWops structures from various data sources */
 
 SDL_RWops *SDL_RWFromFile(const char *file, const char *mode)
@@ -596,13 +540,14 @@ SDL_RWops *SDL_RWFromFile(const char *file, const char *mode)
 SDL_RWops *SDL_RWFromMem(void *mem, size_t size)
 {
     SDL_RWops *rwops = NULL;
+
     if (mem == NULL) {
         SDL_InvalidParamError("mem");
-        return rwops;
+        return NULL;
     }
     if (!size) {
         SDL_InvalidParamError("size");
-        return rwops;
+        return NULL;
     }
 
     rwops = SDL_CreateRW();
@@ -611,7 +556,6 @@ SDL_RWops *SDL_RWFromMem(void *mem, size_t size)
         rwops->seek = mem_seek;
         rwops->read = mem_read;
         rwops->write = mem_write;
-        rwops->close = mem_close;
         rwops->hidden.mem.base = (Uint8 *)mem;
         rwops->hidden.mem.here = rwops->hidden.mem.base;
         rwops->hidden.mem.stop = rwops->hidden.mem.base + size;
@@ -623,13 +567,14 @@ SDL_RWops *SDL_RWFromMem(void *mem, size_t size)
 SDL_RWops *SDL_RWFromConstMem(const void *mem, size_t size)
 {
     SDL_RWops *rwops = NULL;
+
     if (mem == NULL) {
         SDL_InvalidParamError("mem");
-        return rwops;
+        return NULL;
     }
     if (!size) {
         SDL_InvalidParamError("size");
-        return rwops;
+        return NULL;
     }
 
     rwops = SDL_CreateRW();
@@ -637,8 +582,6 @@ SDL_RWops *SDL_RWFromConstMem(const void *mem, size_t size)
         rwops->size = mem_size;
         rwops->seek = mem_seek;
         rwops->read = mem_read;
-        rwops->write = mem_writeconst;
-        rwops->close = mem_close;
         rwops->hidden.mem.base = (Uint8 *)mem;
         rwops->hidden.mem.here = rwops->hidden.mem.base;
         rwops->hidden.mem.stop = rwops->hidden.mem.base + size;
@@ -649,29 +592,30 @@ SDL_RWops *SDL_RWFromConstMem(const void *mem, size_t size)
 
 SDL_RWops *SDL_CreateRW(void)
 {
-    SDL_RWops *area;
+    SDL_RWops *context;
 
-    area = (SDL_RWops *)SDL_malloc(sizeof(*area));
-    if (area == NULL) {
+    context = (SDL_RWops *)SDL_calloc(1, sizeof(*context));
+    if (context == NULL) {
         SDL_OutOfMemory();
     } else {
-        area->type = SDL_RWOPS_UNKNOWN;
+        context->type = SDL_RWOPS_UNKNOWN;
     }
-    return area;
+    return context;
 }
 
-void SDL_DestroyRW(SDL_RWops *area)
+void SDL_DestroyRW(SDL_RWops *context)
 {
-    SDL_free(area);
+    SDL_free(context);
 }
 
 /* Load all the data from an SDL data stream */
 void *SDL_LoadFile_RW(SDL_RWops *src, size_t *datasize, SDL_bool freesrc)
 {
-    static const Sint64 FILE_CHUNK_SIZE = 1024;
-    Sint64 size;
-    Sint64 size_read, size_total;
-    void *data = NULL, *newdata;
+    const int FILE_CHUNK_SIZE = 1024;
+    Sint64 size, size_total;
+    size_t size_read;
+    char *data = NULL, *newdata;
+    SDL_bool loading_chunks = SDL_FALSE;
 
     if (src == NULL) {
         SDL_InvalidParamError("src");
@@ -681,46 +625,52 @@ void *SDL_LoadFile_RW(SDL_RWops *src, size_t *datasize, SDL_bool freesrc)
     size = SDL_RWsize(src);
     if (size < 0) {
         size = FILE_CHUNK_SIZE;
+        loading_chunks = SDL_TRUE;
+    }
+    if (size >= SDL_SIZE_MAX) {
+        SDL_OutOfMemory();
+        goto done;
+    }
+    data = (char *)SDL_malloc((size_t)(size + 1));
+    if (!data) {
+        SDL_OutOfMemory();
+        goto done;
     }
-    data = SDL_malloc((size_t)(size + 1));
 
     size_total = 0;
     for (;;) {
-        if ((size_total + FILE_CHUNK_SIZE) > size) {
-            size = (size_total + FILE_CHUNK_SIZE);
-            newdata = SDL_realloc(data, (size_t)(size + 1));
-            if (newdata == NULL) {
-                SDL_free(data);
-                data = NULL;
-                SDL_OutOfMemory();
-                goto done;
+        if (loading_chunks) {
+            if ((size_total + FILE_CHUNK_SIZE) > size) {
+                size = (size_total + FILE_CHUNK_SIZE);
+                if (size >= SDL_SIZE_MAX) {
+                    newdata = NULL;
+                } else {
+                    newdata = SDL_realloc(data, (size_t)(size + 1));
+                }
+                if (newdata == NULL) {
+                    SDL_free(data);
+                    data = NULL;
+                    SDL_OutOfMemory();
+                    goto done;
+                }
+                data = newdata;
             }
-            data = newdata;
         }
 
-        size_read = SDL_RWread(src, (char *)data + size_total, size - size_total);
+        size_read = SDL_RWread(src, data + size_total, (size_t)(size - size_total));
         if (size_read > 0) {
             size_total += size_read;
             continue;
         }
-        if (size_read == 0) {
-            /* End of file */
-            break;
-        }
-        if (size_read == -2) {
-            /* Non-blocking I/O, should we wait here? */
-        }
 
-        /* Read error */
-        SDL_free(data);
-        data = NULL;
-        goto done;
+        /* The stream status will remain set for the caller to check */
+        break;
     }
 
     if (datasize) {
-        *datasize = (size_t) size_total;
+        *datasize = (size_t)size_total;
     }
-    ((char *)data)[size_total] = '\0';
+    data[size_total] = '\0';
 
 done:
     if (freesrc && src) {
@@ -731,134 +681,314 @@ done:
 
 void *SDL_LoadFile(const char *file, size_t *datasize)
 {
-    return SDL_LoadFile_RW(SDL_RWFromFile(file, "rb"), datasize, 1);
+    return SDL_LoadFile_RW(SDL_RWFromFile(file, "rb"), datasize, SDL_TRUE);
 }
 
 Sint64 SDL_RWsize(SDL_RWops *context)
 {
+    if (!context) {
+        return SDL_InvalidParamError("context");
+    }
+    if (!context->size) {
+        Sint64 pos, size;
+
+        pos = SDL_RWseek(context, 0, SDL_RW_SEEK_CUR);
+        if (pos < 0) {
+            return -1;
+        }
+        size = SDL_RWseek(context, 0, SDL_RW_SEEK_END);
+
+        SDL_RWseek(context, pos, SDL_RW_SEEK_SET);
+        return size;
+    }
     return context->size(context);
 }
 
 Sint64 SDL_RWseek(SDL_RWops *context, Sint64 offset, int whence)
 {
+    if (!context) {
+        return SDL_InvalidParamError("context");
+    }
+    if (!context->seek) {
+        return SDL_Unsupported();
+    }
     return context->seek(context, offset, whence);
 }
 
 Sint64 SDL_RWtell(SDL_RWops *context)
 {
-    return context->seek(context, 0, SDL_RW_SEEK_CUR);
+    return SDL_RWseek(context, 0, SDL_RW_SEEK_CUR);
 }
 
-Sint64 SDL_RWread(SDL_RWops *context, void *ptr, Sint64 size)
+size_t SDL_RWread(SDL_RWops *context, void *ptr, size_t size)
 {
-    return context->read(context, ptr, size);
+    size_t bytes;
+
+    if (!context) {
+        SDL_InvalidParamError("context");
+        return 0;
+    }
+    if (!context->read) {
+        context->status = SDL_RWOPS_STATUS_WRITEONLY;
+        SDL_Unsupported();
+        return 0;
+    }
+
+    context->status = SDL_RWOPS_STATUS_READY;
+    SDL_ClearError();
+
+    if (size == 0) {
+        return 0;
+    }
+
+    bytes = context->read(context, ptr, size);
+    if (bytes == 0 && context->status == SDL_RWOPS_STATUS_READY) {
+        if (*SDL_GetError()) {
+            context->status = SDL_RWOPS_STATUS_ERROR;
+        } else {
+            context->status = SDL_RWOPS_STATUS_EOF;
+        }
+    }
+    return bytes;
 }
 
-Sint64 SDL_RWwrite(SDL_RWops *context, const void *ptr, Sint64 size)
+size_t SDL_RWwrite(SDL_RWops *context, const void *ptr, size_t size)
 {
-    return context->write(context, ptr, size);
+    size_t bytes;
+
+    if (!context) {
+        SDL_InvalidParamError("context");
+        return 0;
+    }
+    if (!context->write) {
+        context->status = SDL_RWOPS_STATUS_READONLY;
+        SDL_Unsupported();
+        return 0;
+    }
+
+    context->status = SDL_RWOPS_STATUS_READY;
+    SDL_ClearError();
+
+    if (size == 0) {
+        return 0;
+    }
+
+    bytes = context->write(context, ptr, size);
+    if (bytes == 0 && context->status == SDL_RWOPS_STATUS_READY) {
+        context->status = SDL_RWOPS_STATUS_ERROR;
+    }
+    return bytes;
 }
 
 int SDL_RWclose(SDL_RWops *context)
 {
+    if (!context) {
+        return SDL_InvalidParamError("context");
+    }
+    if (!context->close) {
+        SDL_DestroyRW(context);
+        return 0;
+    }
     return context->close(context);
 }
 
 /* Functions for dynamically reading and writing endian-specific values */
 
-Uint8 SDL_ReadU8(SDL_RWops *src)
+SDL_bool SDL_ReadU8(SDL_RWops *src, Uint8 *value)
 {
-    Uint8 value = 0;
+    Uint8 data = 0;
+    SDL_bool result = SDL_FALSE;
 
-    SDL_RWread(src, &value, sizeof(value));
-    return value;
+    if (SDL_RWread(src, &data, sizeof(data)) == sizeof(data)) {
+        result = SDL_TRUE;
+    }
+    if (value) {
+        *value = data;
+    }
+    return result;
 }
 
-Uint16 SDL_ReadLE16(SDL_RWops *src)
+SDL_bool SDL_ReadU16LE(SDL_RWops *src, Uint16 *value)
 {
-    Uint16 value = 0;
+    Uint16 data = 0;
+    SDL_bool result = SDL_FALSE;
 
-    SDL_RWread(src, &value, sizeof(value));
-    return SDL_SwapLE16(value);
+    if (SDL_RWread(src, &data, sizeof(data)) == sizeof(data)) {
+        result = SDL_TRUE;
+    }
+    if (value) {
+        *value = SDL_SwapLE16(data);
+    }
+    return result;
+}
+
+SDL_bool SDL_ReadS16LE(SDL_RWops *src, Sint16 *value)
+{
+    return SDL_ReadU16LE(src, (Uint16 *)value);
 }
 
-Uint16 SDL_ReadBE16(SDL_RWops *src)
+SDL_bool SDL_ReadU16BE(SDL_RWops *src, Uint16 *value)
 {
-    Uint16 value = 0;
+    Uint16 data = 0;
+    SDL_bool result = SDL_FALSE;
 
-    SDL_RWread(src, &value, sizeof(value));
-    return SDL_SwapBE16(value);
+    if (SDL_RWread(src, &data, sizeof(data)) == sizeof(data)) {
+        result = SDL_TRUE;
+    }
+    if (value) {
+        *value = SDL_SwapBE16(data);
+    }
+    return result;
+}
+
+SDL_bool SDL_ReadS16BE(SDL_RWops *src, Sint16 *value)
+{
+    return SDL_ReadU16BE(src, (Uint16 *)value);
 }
 
-Uint32 SDL_ReadLE32(SDL_RWops *src)
+SDL_bool SDL_ReadU32LE(SDL_RWops *src, Uint32 *value)
 {
-    Uint32 value = 0;
+    Uint32 data = 0;
+    SDL_bool result = SDL_FALSE;
+
+    if (SDL_RWread(src, &data, sizeof(data)) == sizeof(data)) {
+        result = SDL_TRUE;
+    }
+    if (value) {
+        *value = SDL_SwapLE32(data);
+    }
+    return result;
+}
 
-    SDL_RWread(src, &value, sizeof(value));
-    return SDL_SwapLE32(value);
+SDL_bool SDL_ReadS32LE(SDL_RWops *src, Sint32 *value)
+{
+    return SDL_ReadU32LE(src, (Uint32 *)value);
 }
 
-Uint32 SDL_ReadBE32(SDL_RWops *src)
+SDL_bool SDL_ReadU32BE(SDL_RWops *src, Uint32 *value)
 {
-    Uint32 value = 0;
+    Uint32 data = 0;
+    SDL_bool result = SDL_FALSE;
 
-    SDL_RWread(src, &value, sizeof(value));
-    return SDL_SwapBE32(value);
+    if (SDL_RWread(src, &data, sizeof(data)) == sizeof(data)) {
+        result = SDL_TRUE;
+    }
+    if (value) {
+        *value = SDL_SwapBE32(data);
+    }
+    return result;
 }
 
-Uint64 SDL_ReadLE64(SDL_RWops *src)
+SDL_bool SDL_ReadS32BE(SDL_RWops *src, Sint32 *value)
 {
-    Uint64 value = 0;
+    return SDL_ReadU32BE(src, (Uint32 *)value);
+}
+
+SDL_bool SDL_ReadU64LE(SDL_RWops *src, Uint64 *value)
+{
+    Uint64 data = 0;
+    SDL_bool result = SDL_FALSE;
+
+    if (SDL_RWread(src, &data, sizeof(data)) == sizeof(data)) {
+        result = SDL_TRUE;
+    }
+    if (value) {
+        *value = SDL_SwapLE64(data);
+    }
+    return result;
+}
 
-    SDL_RWread(src, &value, sizeof(value));
-    return SDL_SwapLE64(value);
+SDL_bool SDL_ReadS64LE(SDL_RWops *src, Sint64 *value)
+{
+    return SDL_ReadU64LE(src, (Uint64 *)value);
 }
 
-Uint64 SDL_ReadBE64(SDL_RWops *src)
+SDL_bool SDL_ReadU64BE(SDL_RWops *src, Uint64 *value)
 {
-    Uint64 value = 0;
+    Uint64 data = 0;
+    SDL_bool result = SDL_FALSE;
 
-    SDL_RWread(src, &value, sizeof(value));
-    return SDL_SwapBE64(value);
+    if (SDL_RWread(src, &data, sizeof(data)) == sizeof(data)) {
+        result = SDL_TRUE;
+    }
+    if (value) {
+        *value = SDL_SwapBE64(data);
+    }
+    return result;
 }
 
-size_t SDL_WriteU8(SDL_RWops *dst, Uint8 value)
+SDL_bool SDL_ReadS64BE(SDL_RWops *src, Sint64 *value)
 {
-    return (SDL_RWwrite(dst, &value, sizeof(value)) == sizeof(value)) ? 1 : 0;
+    return SDL_ReadU64BE(src, (Uint64 *)value);
 }
 
-size_t SDL_WriteLE16(SDL_RWops *dst, Uint16 value)
+SDL_bool SDL_WriteU8(SDL_RWops *dst, Uint8 value)
+{
+    return (SDL_RWwrite(dst, &value, sizeof(value)) == sizeof(value)) ? SDL_TRUE : SDL_FALSE;
+}
+
+SDL_bool SDL_WriteU16LE(SDL_RWops *dst, Uint16 value)
 {
     const Uint16 swapped = SDL_SwapLE16(value);
-    return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? 1 : 0;
+    return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? SDL_TRUE : SDL_FALSE;
 }
 
-size_t SDL_WriteBE16(SDL_RWops *dst, Uint16 value)
+SDL_bool SDL_WriteS16LE(SDL_RWops *dst, Sint16 value)
+{
+    return SDL_WriteU16LE(dst, (Uint16)value);
+}
+
+SDL_bool SDL_WriteU16BE(SDL_RWops *dst, Uint16 value)
 {
     const Uint16 swapped = SDL_SwapBE16(value);
-    return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? 1 : 0;
+    return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? SDL_TRUE : SDL_FALSE;
+}
+
+SDL_bool SDL_WriteS16BE(SDL_RWops *dst, Sint16 value)
+{
+    return SDL_WriteU16BE(dst, (Uint16)value);
 }
 
-size_t SDL_WriteLE32(SDL_RWops *dst, Uint32 value)
+SDL_bool SDL_WriteU32LE(SDL_RWops *dst, Uint32 value)
 {
     const Uint32 swapped = SDL_SwapLE32(value);
-    return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? 1 : 0;
+    return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? SDL_TRUE : SDL_FALSE;
 }
 
-size_t SDL_WriteBE32(SDL_RWops *dst, Uint32 value)
+SDL_bool SDL_WriteS32LE(SDL_RWops *dst, Sint32 value)
+{
+    return SDL_WriteU32LE(dst, (Uint32)value);
+}
+
+SDL_bool SDL_WriteU32BE(SDL_RWops *dst, Uint32 value)
 {
     const Uint32 swapped = SDL_SwapBE32(value);
-    return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? 1 : 0;
+    return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? SDL_TRUE : SDL_FALSE;
 }
 
-size_t SDL_WriteLE64(SDL_RWops *dst, Uint64 value)
+SDL_bool SDL_WriteS32BE(SDL_RWops *dst, Sint32 value)
+{
+    return SDL_WriteU32BE(dst, (Uint32)value);
+}
+
+SDL_bool SDL_WriteU64LE(SDL_RWops *dst, Uint64 value)
 {
     const Uint64 swapped = SDL_SwapLE64(value);
-    return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? 1 : 0;
+    return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? SDL_TRUE : SDL_FALSE;
+}
+
+SDL_bool SDL_WriteS64LE(SDL_RWops *dst, Sint64 value)
+{
+    return SDL_WriteU64LE(dst, (Uint64)value);
 }
 
-size_t SDL_WriteBE64(SDL_RWops *dst, Uint64 value)
+SDL_bool SDL_WriteU64BE(SDL_RWops *dst, Uint64 value)
 {
     const Uint64 swapped = SDL_SwapBE64(value);
-    return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? 1 : 0;
+    return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? SDL_TRUE : SDL_FALSE;
+}
+
+SDL_bool SDL_WriteS64BE(SDL_RWops *dst, Sint64 value)
+{
+    return SDL_WriteU64BE(dst, (Uint64)value);
 }

+ 3 - 25
src/joystick/SDL_gamepad.c

@@ -1694,40 +1694,18 @@ static GamepadMapping_t *SDL_PrivateGetGamepadMapping(SDL_JoystickID instance_id
 /*
  * Add or update an entry into the Mappings Database
  */
-int SDL_AddGamepadMappingsFromRW(SDL_RWops *src, int freesrc)
+int SDL_AddGamepadMappingsFromRW(SDL_RWops *src, SDL_bool freesrc)
 {
     const char *platform = SDL_GetPlatform();
     int gamepads = 0;
     char *buf, *line, *line_end, *tmp, *comma, line_platform[64];
-    Sint64 db_size;
+    size_t db_size;
     size_t platform_len;
 
-    if (src == NULL) {
-        return SDL_InvalidParamError("src");
-    }
-    db_size = SDL_RWsize(src);
-
-    buf = (char *)SDL_malloc((size_t)db_size + 1);
+    buf = (char *)SDL_LoadFile_RW(src, &db_size, freesrc);
     if (buf == NULL) {
-        if (freesrc) {
-            SDL_RWclose(src);
-        }
         return SDL_SetError("Could not allocate space to read DB into memory");
     }
-
-    if (SDL_RWread(src, buf, db_size) != db_size) {
-        if (freesrc) {
-            SDL_RWclose(src);
-        }
-        SDL_free(buf);
-        return SDL_SetError("Could not read DB");
-    }
-
-    if (freesrc) {
-        SDL_RWclose(src);
-    }
-
-    buf[db_size] = '\0';
     line = buf;
 
     PushMappingChangeTracking();

+ 169 - 128
src/video/SDL_bmp.c

@@ -71,7 +71,7 @@ static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8)
 
     /* !!! FIXME: for all these reads, handle error vs eof? handle -2 if non-blocking? */
     for (;;) {
-        if (SDL_RWread(src, &ch, 1) <= 0) {
+        if (!SDL_ReadU8(src, &ch)) {
             return SDL_TRUE;
         }
         /*
@@ -80,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) <= 0) {
+            if (!SDL_ReadU8(src, &pixel)) {
                 return SDL_TRUE;
             }
             if (isRle8) { /* 256-color bitmap, compressed */
@@ -107,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) <= 0) {
+            if (!SDL_ReadU8(src, &ch)) {
                 return SDL_TRUE;
             }
             switch (ch) {
@@ -118,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) <= 0) {
+                if (!SDL_ReadU8(src, &ch)) {
                     return SDL_TRUE;
                 }
                 ofs += ch;
-                if (SDL_RWread(src, &ch, 1) <= 0) {
+                if (!SDL_ReadU8(src, &ch)) {
                     return SDL_TRUE;
                 }
                 bits -= (ch * pitch);
@@ -132,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) <= 0) {
+                        if (!SDL_ReadU8(src, &pixel)) {
                             return SDL_TRUE;
                         }
                         COPY_PIXEL(pixel);
@@ -141,7 +141,7 @@ static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8)
                     needsPad = (((ch + 1) >> 1) & 1); /* (ch+1)>>1: bytes size */
                     for (;;) {
                         Uint8 pixel;
-                        if (SDL_RWread(src, &pixel, 1) <= 0) {
+                        if (!SDL_ReadU8(src, &pixel)) {
                             return SDL_TRUE;
                         }
                         COPY_PIXEL(pixel >> 4);
@@ -155,7 +155,7 @@ static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8)
                     }
                 }
                 /* pad at even boundary */
-                if (needsPad && (SDL_RWread(src, &ch, 1) <= 0)) {
+                if (needsPad && !SDL_ReadU8(src, &ch)) {
                     return SDL_TRUE;
                 }
                 break;
@@ -195,7 +195,7 @@ static void CorrectAlphaChannel(SDL_Surface *surface)
 
 SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
 {
-    SDL_bool was_error;
+    SDL_bool was_error = SDL_TRUE;
     Sint64 fp_offset = 0;
     int bmpPitch;
     int i, pad;
@@ -235,42 +235,45 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
 
     /* Make sure we are passed a valid data source */
     surface = NULL;
-    was_error = SDL_FALSE;
     if (src == NULL) {
         SDL_InvalidParamError("src");
-        was_error = SDL_TRUE;
         goto done;
     }
 
     /* Read in the BMP file header */
     fp_offset = SDL_RWtell(src);
     if (fp_offset < 0) {
-        was_error = SDL_TRUE;
         goto done;
     }
     SDL_ClearError();
     if (SDL_RWread(src, magic, 2) != 2) {
-        SDL_Error(SDL_EFREAD);
-        was_error = SDL_TRUE;
         goto done;
     }
     if (SDL_strncmp(magic, "BM", 2) != 0) {
         SDL_SetError("File is not a Windows BMP file");
-        was_error = SDL_TRUE;
         goto done;
     }
-    /* bfSize      = */ SDL_ReadLE32(src);
-    /* bfReserved1 = */ SDL_ReadLE16(src);
-    /* bfReserved2 = */ SDL_ReadLE16(src);
-    bfOffBits = SDL_ReadLE32(src);
+    if (!SDL_ReadU32LE(src, NULL /* bfSize */) ||
+        !SDL_ReadU16LE(src, NULL /* bfReserved1 */) ||
+        !SDL_ReadU16LE(src, NULL /* bfReserved2 */) ||
+        !SDL_ReadU32LE(src, &bfOffBits)) {
+        goto done;
+    }
 
     /* Read the Win32 BITMAPINFOHEADER */
-    biSize = SDL_ReadLE32(src);
+    if (!SDL_ReadU32LE(src, &biSize)) {
+        goto done;
+    }
     if (biSize == 12) { /* really old BITMAPCOREHEADER */
-        biWidth = (Uint32)SDL_ReadLE16(src);
-        biHeight = (Uint32)SDL_ReadLE16(src);
-        /* biPlanes = */ SDL_ReadLE16(src);
-        biBitCount = SDL_ReadLE16(src);
+        Uint16 biWidth16, biHeight16;
+        if (!SDL_ReadU16LE(src, &biWidth16) ||
+            !SDL_ReadU16LE(src, &biHeight16) ||
+            !SDL_ReadU16LE(src, NULL /* biPlanes */) ||
+            !SDL_ReadU16LE(src, &biBitCount)) {
+            goto done;
+        }
+        biWidth = biWidth16;
+        biHeight = biHeight16;
         biCompression = BI_RGB;
         /* biSizeImage = 0; */
         /* biXPelsPerMeter = 0; */
@@ -279,16 +282,18 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
         /* biClrImportant = 0; */
     } else if (biSize >= 40) { /* some version of BITMAPINFOHEADER */
         Uint32 headerSize;
-        biWidth = SDL_ReadLE32(src);
-        biHeight = SDL_ReadLE32(src);
-        /* biPlanes = */ SDL_ReadLE16(src);
-        biBitCount = SDL_ReadLE16(src);
-        biCompression = SDL_ReadLE32(src);
-        /* biSizeImage = */ SDL_ReadLE32(src);
-        /* biXPelsPerMeter = */ SDL_ReadLE32(src);
-        /* biYPelsPerMeter = */ SDL_ReadLE32(src);
-        biClrUsed = SDL_ReadLE32(src);
-        /* biClrImportant = */ SDL_ReadLE32(src);
+        if (!SDL_ReadS32LE(src, &biWidth) ||
+            !SDL_ReadS32LE(src, &biHeight) ||
+            !SDL_ReadU16LE(src, NULL /* biPlanes */) ||
+            !SDL_ReadU16LE(src, &biBitCount) ||
+            !SDL_ReadU32LE(src, &biCompression) ||
+            !SDL_ReadU32LE(src, NULL /* biSizeImage */) ||
+            !SDL_ReadU32LE(src, NULL /* biXPelsPerMeter */) ||
+            !SDL_ReadU32LE(src, NULL /* biYPelsPerMeter */) ||
+            !SDL_ReadU32LE(src, &biClrUsed) ||
+            !SDL_ReadU32LE(src, NULL /* biClrImportant */)) {
+            goto done;
+        }
 
         /* 64 == BITMAPCOREHEADER2, an incompatible OS/2 2.x extension. Skip this stuff for now. */
         if (biSize != 64) {
@@ -301,24 +306,32 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
                following the legacy v1 info header, just past biSize. */
             if (biCompression == BI_BITFIELDS) {
                 haveRGBMasks = SDL_TRUE;
-                Rmask = SDL_ReadLE32(src);
-                Gmask = SDL_ReadLE32(src);
-                Bmask = SDL_ReadLE32(src);
+                if (!SDL_ReadU32LE(src, &Rmask) ||
+                    !SDL_ReadU32LE(src, &Gmask) ||
+                    !SDL_ReadU32LE(src, &Bmask)) {
+                    goto done;
+                }
 
                 /* ...v3 adds an alpha mask. */
                 if (biSize >= 56) { /* BITMAPV3INFOHEADER; adds alpha mask */
                     haveAlphaMask = SDL_TRUE;
-                    Amask = SDL_ReadLE32(src);
+                    if (!SDL_ReadU32LE(src, &Amask)) {
+                        goto done;
+                    }
                 }
             } else {
                 /* the mask fields are ignored for v2+ headers if not BI_BITFIELD. */
                 if (biSize >= 52) { /* BITMAPV2INFOHEADER; adds RGB masks */
-                    /*Rmask = */ SDL_ReadLE32(src);
-                    /*Gmask = */ SDL_ReadLE32(src);
-                    /*Bmask = */ SDL_ReadLE32(src);
+                    if (!SDL_ReadU32LE(src, NULL /* Rmask */) ||
+                        !SDL_ReadU32LE(src, NULL /* Gmask */) ||
+                        !SDL_ReadU32LE(src, NULL /* Bmask */)) {
+                        goto done;
+                    }
                 }
                 if (biSize >= 56) { /* BITMAPV3INFOHEADER; adds alpha mask */
-                    /*Amask = */ SDL_ReadLE32(src);
+                    if (!SDL_ReadU32LE(src, NULL /* Amask */)) {
+                        goto done;
+                    }
                 }
             }
 
@@ -331,12 +344,13 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
         /* skip any header bytes we didn't handle... */
         headerSize = (Uint32)(SDL_RWtell(src) - (fp_offset + 14));
         if (biSize > headerSize) {
-            SDL_RWseek(src, (biSize - headerSize), SDL_RW_SEEK_CUR);
+            if (SDL_RWseek(src, (biSize - headerSize), SDL_RW_SEEK_CUR) < 0) {
+                goto done;
+            }
         }
     }
     if (biWidth <= 0 || biHeight == 0) {
         SDL_SetError("BMP file with bad dimensions (%" SDL_PRIs32 "x%" SDL_PRIs32 ")", biWidth, biHeight);
-        was_error = SDL_TRUE;
         goto done;
     }
     if (biHeight < 0) {
@@ -348,7 +362,6 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
 
     /* Check for read error */
     if (SDL_strcmp(SDL_GetError(), "") != 0) {
-        was_error = SDL_TRUE;
         goto done;
     }
 
@@ -366,7 +379,6 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
     case 6:
     case 7:
         SDL_SetError("%d-bpp BMP images are not supported", biBitCount);
-        was_error = SDL_TRUE;
         goto done;
     default:
         ExpandBMP = 0;
@@ -431,7 +443,6 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
         surface = SDL_CreateSurface(biWidth, biHeight, format);
 
         if (surface == NULL) {
-            was_error = SDL_TRUE;
             goto done;
         }
     }
@@ -441,13 +452,11 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
     if (palette) {
         if (SDL_RWseek(src, fp_offset + 14 + biSize, SDL_RW_SEEK_SET) < 0) {
             SDL_Error(SDL_EFSEEK);
-            was_error = SDL_TRUE;
             goto done;
         }
 
         if (biBitCount >= 32) { /* we shift biClrUsed by this value later. */
             SDL_SetError("Unsupported or incorrect biBitCount field");
-            was_error = SDL_TRUE;
             goto done;
         }
 
@@ -459,26 +468,27 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
             biClrUsed = 1 << biBitCount; /* try forcing it? */
             if (biClrUsed > (Uint32)palette->ncolors) {
                 SDL_SetError("Unsupported or incorrect biClrUsed field");
-                was_error = SDL_TRUE;
                 goto done;
             }
         }
 
         if (biSize == 12) {
             for (i = 0; i < (int)biClrUsed; ++i) {
-                /* !!! FIXME: this should check for i/o errors! */
-                SDL_RWread(src, &palette->colors[i].b, 1);
-                SDL_RWread(src, &palette->colors[i].g, 1);
-                SDL_RWread(src, &palette->colors[i].r, 1);
+                if (!SDL_ReadU8(src, &palette->colors[i].b) ||
+                    !SDL_ReadU8(src, &palette->colors[i].g) ||
+                    !SDL_ReadU8(src, &palette->colors[i].r)) {
+                    goto done;
+                }
                 palette->colors[i].a = SDL_ALPHA_OPAQUE;
             }
         } else {
             for (i = 0; i < (int)biClrUsed; ++i) {
-                /* !!! FIXME: this should check for i/o errors! */
-                SDL_RWread(src, &palette->colors[i].b, 1);
-                SDL_RWread(src, &palette->colors[i].g, 1);
-                SDL_RWread(src, &palette->colors[i].r, 1);
-                SDL_RWread(src, &palette->colors[i].a, 1);
+                if (!SDL_ReadU8(src, &palette->colors[i].b) ||
+                    !SDL_ReadU8(src, &palette->colors[i].g) ||
+                    !SDL_ReadU8(src, &palette->colors[i].r) ||
+                    !SDL_ReadU8(src, &palette->colors[i].a)) {
+                    goto done;
+                }
 
                 /* According to Microsoft documentation, the fourth element
                    is reserved and must be zero, so we shouldn't treat it as
@@ -493,7 +503,6 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
     /* Read the surface pixels.  Note that the bmp image is upside down */
     if (SDL_RWseek(src, fp_offset + bfOffBits, SDL_RW_SEEK_SET) < 0) {
         SDL_Error(SDL_EFSEEK);
-        was_error = SDL_TRUE;
         goto done;
     }
     if ((biCompression == BI_RLE4) || (biCompression == BI_RLE8)) {
@@ -537,16 +546,13 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
             int shift = (8 - ExpandBMP);
             for (i = 0; i < surface->w; ++i) {
                 if (i % (8 / ExpandBMP) == 0) {
-                    if (SDL_RWread(src, &pixel, 1) != 1) {
-                        SDL_Error(SDL_EFREAD);
-                        was_error = SDL_TRUE;
+                    if (!SDL_ReadU8(src, &pixel)) {
                         goto done;
                     }
                 }
                 bits[i] = (pixel >> shift);
                 if (bits[i] >= biClrUsed) {
                     SDL_SetError("A BMP image contains a pixel with a color out of the palette");
-                    was_error = SDL_TRUE;
                     goto done;
                 }
                 pixel <<= ExpandBMP;
@@ -555,15 +561,12 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
 
         default:
             if (SDL_RWread(src, bits, surface->pitch) != surface->pitch) {
-                SDL_Error(SDL_EFREAD);
-                was_error = SDL_TRUE;
                 goto done;
             }
             if (biBitCount == 8 && palette && biClrUsed < (1u << biBitCount)) {
                 for (i = 0; i < surface->w; ++i) {
                     if (bits[i] >= biClrUsed) {
                         SDL_SetError("A BMP image contains a pixel with a color out of the palette");
-                        was_error = SDL_TRUE;
                         goto done;
                     }
                 }
@@ -598,7 +601,9 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
         if (pad) {
             Uint8 padbyte;
             for (i = 0; i < pad; ++i) {
-                SDL_RWread(src, &padbyte, 1);
+                if (!SDL_ReadU8(src, &padbyte)) {
+                    goto done;
+                }
             }
         }
         if (topDown) {
@@ -610,6 +615,9 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
     if (correctAlpha) {
         CorrectAlphaChannel(surface);
     }
+
+    was_error = SDL_FALSE;
+
 done:
     if (was_error) {
         if (src) {
@@ -629,15 +637,10 @@ SDL_Surface *SDL_LoadBMP(const char *file)
     return SDL_LoadBMP_RW(SDL_RWFromFile(file, "rb"), 1);
 }
 
-int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
+int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, SDL_bool freedst)
 {
-    /* !!! FIXME: this calls SDL_ClearError() and then checks if an error happened during this function to
-       !!! FIXME: decide if there was a problem, but there's risk of innocent things setting an error
-       !!! FIXME: string for innocent unrelated reasons, and also, an app supplying its own RWops
-       !!! FIXME: implementation may not set the error string on failure. We should check for i/o
-       !!! FIXME: failures as we go, and return early if one occurs. */
-
-    Sint64 fp_offset;
+    SDL_bool was_error = SDL_TRUE;
+    Sint64 fp_offset, new_offset;
     int i, pad;
     SDL_Surface *intermediate_surface;
     Uint8 *bits;
@@ -678,6 +681,11 @@ int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
     /* Make sure we have somewhere to save */
     intermediate_surface = NULL;
     if (dst) {
+        if (!surface) {
+            SDL_InvalidParamError("surface");
+            goto done;
+        }
+
 #ifdef SAVE_32BIT_BMP
         /* We can save alpha information in a 32-bit BMP */
         if (surface->format->BitsPerPixel >= 8 &&
@@ -693,6 +701,7 @@ int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
             } else {
                 SDL_SetError("%d bpp BMP files not supported",
                              surface->format->BitsPerPixel);
+                goto done;
             }
         } else if ((surface->format->BitsPerPixel == 24) && !save32bit &&
 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
@@ -707,32 +716,33 @@ int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
         ) {
             intermediate_surface = surface;
         } else {
-            SDL_PixelFormat format;
+            Uint32 pixel_format;
 
             /* If the surface has a colorkey or alpha channel we'll save a
                32-bit BMP with alpha channel, otherwise save a 24-bit BMP. */
             if (save32bit) {
-                SDL_InitFormat(&format, SDL_PIXELFORMAT_BGRA32);
+                pixel_format = SDL_PIXELFORMAT_BGRA32;
             } else {
-                SDL_InitFormat(&format, SDL_PIXELFORMAT_BGR24);
+                pixel_format = SDL_PIXELFORMAT_BGR24;
             }
-            intermediate_surface = SDL_ConvertSurface(surface, &format);
+            intermediate_surface = SDL_ConvertSurfaceFormat(surface, pixel_format);
             if (intermediate_surface == NULL) {
                 SDL_SetError("Couldn't convert image to %d bpp",
-                             format.BitsPerPixel);
+                             (int)SDL_BITSPERPIXEL(pixel_format));
+                goto done;
             }
         }
     } else {
         /* Set no error here because it may overwrite a more useful message from
            SDL_RWFromFile() if SDL_SaveBMP_RW() is called from SDL_SaveBMP(). */
-        return -1;
+        goto done;
     }
 
     if (save32bit) {
         saveLegacyBMP = SDL_GetHintBoolean(SDL_HINT_BMP_SAVE_LEGACY_FORMAT, SDL_FALSE);
     }
 
-    if (intermediate_surface && (SDL_LockSurface(intermediate_surface) == 0)) {
+    if (SDL_LockSurface(intermediate_surface) == 0) {
         const int bw = intermediate_surface->w * intermediate_surface->format->BytesPerPixel;
 
         /* Set the BMP file header values */
@@ -743,12 +753,16 @@ int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
 
         /* Write the BMP file header values */
         fp_offset = SDL_RWtell(dst);
-        SDL_ClearError();
-        SDL_RWwrite(dst, magic, 2);
-        SDL_WriteLE32(dst, bfSize);
-        SDL_WriteLE16(dst, bfReserved1);
-        SDL_WriteLE16(dst, bfReserved2);
-        SDL_WriteLE32(dst, bfOffBits);
+        if (fp_offset < 0) {
+            goto done;
+        }
+        if (SDL_RWwrite(dst, magic, 2) != 2 ||
+            !SDL_WriteU32LE(dst, bfSize) ||
+            !SDL_WriteU16LE(dst, bfReserved1) ||
+            !SDL_WriteU16LE(dst, bfReserved2) ||
+            !SDL_WriteU32LE(dst, bfOffBits)) {
+            goto done;
+        }
 
         /* Set the BMP info values */
         biSize = 40;
@@ -783,31 +797,39 @@ int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
         }
 
         /* Write the BMP info values */
-        SDL_WriteLE32(dst, biSize);
-        SDL_WriteLE32(dst, biWidth);
-        SDL_WriteLE32(dst, biHeight);
-        SDL_WriteLE16(dst, biPlanes);
-        SDL_WriteLE16(dst, biBitCount);
-        SDL_WriteLE32(dst, biCompression);
-        SDL_WriteLE32(dst, biSizeImage);
-        SDL_WriteLE32(dst, biXPelsPerMeter);
-        SDL_WriteLE32(dst, biYPelsPerMeter);
-        SDL_WriteLE32(dst, biClrUsed);
-        SDL_WriteLE32(dst, biClrImportant);
+        if (!SDL_WriteU32LE(dst, biSize) ||
+            !SDL_WriteS32LE(dst, biWidth) ||
+            !SDL_WriteS32LE(dst, biHeight) ||
+            !SDL_WriteU16LE(dst, biPlanes) ||
+            !SDL_WriteU16LE(dst, biBitCount) ||
+            !SDL_WriteU32LE(dst, biCompression) ||
+            !SDL_WriteU32LE(dst, biSizeImage) ||
+            !SDL_WriteU32LE(dst, biXPelsPerMeter) ||
+            !SDL_WriteU32LE(dst, biYPelsPerMeter) ||
+            !SDL_WriteU32LE(dst, biClrUsed) ||
+            !SDL_WriteU32LE(dst, biClrImportant)) {
+            goto done;
+        }
 
         /* Write the BMP info values for the version 4 header */
         if (save32bit && !saveLegacyBMP) {
-            SDL_WriteLE32(dst, bV4RedMask);
-            SDL_WriteLE32(dst, bV4GreenMask);
-            SDL_WriteLE32(dst, bV4BlueMask);
-            SDL_WriteLE32(dst, bV4AlphaMask);
-            SDL_WriteLE32(dst, bV4CSType);
+            if (!SDL_WriteU32LE(dst, bV4RedMask) ||
+                !SDL_WriteU32LE(dst, bV4GreenMask) ||
+                !SDL_WriteU32LE(dst, bV4BlueMask) ||
+                !SDL_WriteU32LE(dst, bV4AlphaMask) ||
+                !SDL_WriteU32LE(dst, bV4CSType)) {
+                goto done;
+            }
             for (i = 0; i < 3 * 3; i++) {
-                SDL_WriteLE32(dst, bV4Endpoints[i]);
+                if (!SDL_WriteU32LE(dst, bV4Endpoints[i])) {
+                    goto done;
+                }
+            }
+            if (!SDL_WriteU32LE(dst, bV4GammaRed) ||
+                !SDL_WriteU32LE(dst, bV4GammaGreen) ||
+                !SDL_WriteU32LE(dst, bV4GammaBlue)) {
+                goto done;
             }
-            SDL_WriteLE32(dst, bV4GammaRed);
-            SDL_WriteLE32(dst, bV4GammaGreen);
-            SDL_WriteLE32(dst, bV4GammaBlue);
         }
 
         /* Write the palette (in BGR color order) */
@@ -818,21 +840,25 @@ int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
             colors = intermediate_surface->format->palette->colors;
             ncolors = intermediate_surface->format->palette->ncolors;
             for (i = 0; i < ncolors; ++i) {
-                SDL_RWwrite(dst, &colors[i].b, 1);
-                SDL_RWwrite(dst, &colors[i].g, 1);
-                SDL_RWwrite(dst, &colors[i].r, 1);
-                SDL_RWwrite(dst, &colors[i].a, 1);
+                if (!SDL_WriteU8(dst, colors[i].b) ||
+                    !SDL_WriteU8(dst, colors[i].g) ||
+                    !SDL_WriteU8(dst, colors[i].r) ||
+                    !SDL_WriteU8(dst, colors[i].a)) {
+                    goto done;
+                }
             }
         }
 
         /* Write the bitmap offset */
         bfOffBits = (Uint32)(SDL_RWtell(dst) - fp_offset);
         if (SDL_RWseek(dst, fp_offset + 10, SDL_RW_SEEK_SET) < 0) {
-            SDL_Error(SDL_EFSEEK);
+            goto done;
+        }
+        if (!SDL_WriteU32LE(dst, bfOffBits)) {
+            goto done;
         }
-        SDL_WriteLE32(dst, bfOffBits);
         if (SDL_RWseek(dst, fp_offset + bfOffBits, SDL_RW_SEEK_SET) < 0) {
-            SDL_Error(SDL_EFSEEK);
+            goto done;
         }
 
         /* Write the bitmap image upside down */
@@ -841,38 +867,53 @@ int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
         while (bits > (Uint8 *)intermediate_surface->pixels) {
             bits -= intermediate_surface->pitch;
             if (SDL_RWwrite(dst, bits, bw) != bw) {
-                SDL_Error(SDL_EFWRITE);
-                break;
+                goto done;
             }
             if (pad) {
                 const Uint8 padbyte = 0;
                 for (i = 0; i < pad; ++i) {
-                    SDL_RWwrite(dst, &padbyte, 1);
+                    if (!SDL_WriteU8(dst, padbyte)) {
+                        goto done;
+                    }
                 }
             }
         }
 
         /* Write the BMP file size */
-        bfSize = (Uint32)(SDL_RWtell(dst) - fp_offset);
+        new_offset = SDL_RWtell(dst);
+        if (new_offset < 0) {
+            goto done;
+        }
+        bfSize = (Uint32)(new_offset - fp_offset);
         if (SDL_RWseek(dst, fp_offset + 2, SDL_RW_SEEK_SET) < 0) {
-            SDL_Error(SDL_EFSEEK);
+            goto done;
+        }
+        if (!SDL_WriteU32LE(dst, bfSize)) {
+            goto done;
         }
-        SDL_WriteLE32(dst, bfSize);
         if (SDL_RWseek(dst, fp_offset + bfSize, SDL_RW_SEEK_SET) < 0) {
-            SDL_Error(SDL_EFSEEK);
+            goto done;
         }
 
         /* Close it up.. */
         SDL_UnlockSurface(intermediate_surface);
-        if (intermediate_surface != surface) {
-            SDL_DestroySurface(intermediate_surface);
-        }
+
+        was_error = SDL_FALSE;
     }
 
+done:
+    if (intermediate_surface && intermediate_surface != surface) {
+        SDL_DestroySurface(intermediate_surface);
+    }
     if (freedst && dst) {
-        SDL_RWclose(dst);
+        if (SDL_RWclose(dst) < 0) {
+            was_error = SDL_TRUE;
+        }
+    }
+    if (was_error) {
+        return -1;
     }
-    return (SDL_strcmp(SDL_GetError(), "") == 0) ? 0 : -1;
+    return 0;
 }
 
 int SDL_SaveBMP(SDL_Surface *surface, const char *file)

+ 55 - 49
test/testautomation_rwops.c

@@ -95,11 +95,11 @@ static void RWopsTearDown(void *arg)
  * \sa SDL_RWseek
  * \sa SDL_RWread
  */
-static void testGenericRWopsValidations(SDL_RWops *rw, int write)
+static void testGenericRWopsValidations(SDL_RWops *rw, SDL_bool write)
 {
     char buf[sizeof(RWopsHelloWorldTestString)];
     Sint64 i;
-    Sint64 s;
+    size_t s;
     int seekPos = SDLTest_RandomIntegerInRange(4, 8);
 
     /* Clear buffer */
@@ -116,7 +116,7 @@ static void testGenericRWopsValidations(SDL_RWops *rw, int write)
     if (write) {
         SDLTest_AssertCheck(s == sizeof(RWopsHelloWorldTestString) - 1, "Verify result of writing one byte with SDL_RWwrite, expected 1, got %i", (int)s);
     } else {
-        SDLTest_AssertCheck(s == -1, "Verify result of writing with SDL_RWwrite, expected: 0, got %i", (int)s);
+        SDLTest_AssertCheck(s == 0, "Verify result of writing with SDL_RWwrite, expected: 0, got %i", (int)s);
     }
 
     /* Test seek to random position */
@@ -133,7 +133,7 @@ static void testGenericRWopsValidations(SDL_RWops *rw, int write)
     s = SDL_RWread(rw, buf, sizeof(RWopsHelloWorldTestString) - 1);
     SDLTest_AssertPass("Call to SDL_RWread succeeded");
     SDLTest_AssertCheck(
-        s == (size_t)(sizeof(RWopsHelloWorldTestString) - 1),
+        s == (sizeof(RWopsHelloWorldTestString) - 1),
         "Verify result from SDL_RWread, expected %i, got %i",
         (int)(sizeof(RWopsHelloWorldTestString) - 1),
         (int)s);
@@ -242,7 +242,7 @@ static int rwops_testMem(void *arg)
     SDLTest_AssertCheck(rw->type == SDL_RWOPS_MEMORY, "Verify RWops type is SDL_RWOPS_MEMORY; expected: %d, got: %" SDL_PRIu32, SDL_RWOPS_MEMORY, rw->type);
 
     /* Run generic tests */
-    testGenericRWopsValidations(rw, 1);
+    testGenericRWopsValidations(rw, SDL_TRUE);
 
     /* Close */
     result = SDL_RWclose(rw);
@@ -277,7 +277,7 @@ static int rwops_testConstMem(void *arg)
     SDLTest_AssertCheck(rw->type == SDL_RWOPS_MEMORY_RO, "Verify RWops type is SDL_RWOPS_MEMORY_RO; expected: %d, got: %" SDL_PRIu32, SDL_RWOPS_MEMORY_RO, rw->type);
 
     /* Run generic tests */
-    testGenericRWopsValidations(rw, 0);
+    testGenericRWopsValidations(rw, SDL_FALSE);
 
     /* Close handle */
     result = SDL_RWclose(rw);
@@ -324,7 +324,7 @@ static int rwops_testFileRead(void *arg)
 #endif
 
     /* Run generic tests */
-    testGenericRWopsValidations(rw, 0);
+    testGenericRWopsValidations(rw, SDL_FALSE);
 
     /* Close handle */
     result = SDL_RWclose(rw);
@@ -371,7 +371,7 @@ static int rwops_testFileWrite(void *arg)
 #endif
 
     /* Run generic tests */
-    testGenericRWopsValidations(rw, 1);
+    testGenericRWopsValidations(rw, SDL_TRUE);
 
     /* Close handle */
     result = SDL_RWclose(rw);
@@ -437,7 +437,7 @@ static int rwops_testCompareRWFromMemWithRWFromFile(void *arg)
         /* Read/seek from memory */
         rwops_mem = SDL_RWFromMem((void *)RWopsAlphabetString, slen);
         SDLTest_AssertPass("Call to SDL_RWFromMem()");
-        rv_mem = (size_t)SDL_RWread(rwops_mem, buffer_mem, size * 6);
+        rv_mem = SDL_RWread(rwops_mem, buffer_mem, size * 6);
         SDLTest_AssertPass("Call to SDL_RWread(mem, size=%d)", size * 6);
         sv_mem = SDL_RWseek(rwops_mem, 0, SEEK_END);
         SDLTest_AssertPass("Call to SDL_RWseek(mem,SEEK_END)");
@@ -448,7 +448,7 @@ static int rwops_testCompareRWFromMemWithRWFromFile(void *arg)
         /* Read/see from file */
         rwops_file = SDL_RWFromFile(RWopsAlphabetFilename, "r");
         SDLTest_AssertPass("Call to SDL_RWFromFile()");
-        rv_file = (size_t)SDL_RWread(rwops_file, buffer_file, size * 6);
+        rv_file = SDL_RWread(rwops_file, buffer_file, size * 6);
         SDLTest_AssertPass("Call to SDL_RWread(file, size=%d)", size * 6);
         sv_file = SDL_RWseek(rwops_file, 0, SEEK_END);
         SDLTest_AssertPass("Call to SDL_RWseek(file,SEEK_END)");
@@ -477,15 +477,14 @@ static int rwops_testCompareRWFromMemWithRWFromFile(void *arg)
  *
  * \sa SDL_RWFromFile
  * \sa SDL_RWClose
- * \sa SDL_ReadBE16
- * \sa SDL_WriteBE16
+ * \sa SDL_ReadU16BE
+ * \sa SDL_WriteU16BE
  */
 static int rwops_testFileWriteReadEndian(void *arg)
 {
     SDL_RWops *rw;
     Sint64 result;
     int mode;
-    size_t objectsWritten;
     Uint16 BE16value;
     Uint32 BE32value;
     Uint64 BE64value;
@@ -498,6 +497,7 @@ static int rwops_testFileWriteReadEndian(void *arg)
     Uint16 LE16test;
     Uint32 LE32test;
     Uint64 LE64test;
+    SDL_bool bresult;
     int cresult;
 
     for (mode = 0; mode < 3; mode++) {
@@ -545,24 +545,24 @@ static int rwops_testFileWriteReadEndian(void *arg)
         }
 
         /* Write test data */
-        objectsWritten = SDL_WriteBE16(rw, BE16value);
-        SDLTest_AssertPass("Call to SDL_WriteBE16()");
-        SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", (int)objectsWritten);
-        objectsWritten = SDL_WriteBE32(rw, BE32value);
-        SDLTest_AssertPass("Call to SDL_WriteBE32()");
-        SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", (int)objectsWritten);
-        objectsWritten = SDL_WriteBE64(rw, BE64value);
-        SDLTest_AssertPass("Call to SDL_WriteBE64()");
-        SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", (int)objectsWritten);
-        objectsWritten = SDL_WriteLE16(rw, LE16value);
-        SDLTest_AssertPass("Call to SDL_WriteLE16()");
-        SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", (int)objectsWritten);
-        objectsWritten = SDL_WriteLE32(rw, LE32value);
-        SDLTest_AssertPass("Call to SDL_WriteLE32()");
-        SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", (int)objectsWritten);
-        objectsWritten = SDL_WriteLE64(rw, LE64value);
-        SDLTest_AssertPass("Call to SDL_WriteLE64()");
-        SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", (int)objectsWritten);
+        bresult = SDL_WriteU16BE(rw, BE16value);
+        SDLTest_AssertPass("Call to SDL_WriteU16BE()");
+        SDLTest_AssertCheck(bresult == SDL_TRUE, "Validate object written, expected: SDL_TRUE, got: SDL_FALSE");
+        bresult = SDL_WriteU32BE(rw, BE32value);
+        SDLTest_AssertPass("Call to SDL_WriteU32BE()");
+        SDLTest_AssertCheck(bresult == SDL_TRUE, "Validate object written, expected: SDL_TRUE, got: SDL_FALSE");
+        bresult = SDL_WriteU64BE(rw, BE64value);
+        SDLTest_AssertPass("Call to SDL_WriteU64BE()");
+        SDLTest_AssertCheck(bresult == SDL_TRUE, "Validate object written, expected: SDL_TRUE, got: SDL_FALSE");
+        bresult = SDL_WriteU16LE(rw, LE16value);
+        SDLTest_AssertPass("Call to SDL_WriteU16LE()");
+        SDLTest_AssertCheck(bresult == SDL_TRUE, "Validate object written, expected: SDL_TRUE, got: SDL_FALSE");
+        bresult = SDL_WriteU32LE(rw, LE32value);
+        SDLTest_AssertPass("Call to SDL_WriteU32LE()");
+        SDLTest_AssertCheck(bresult == SDL_TRUE, "Validate object written, expected: SDL_TRUE, got: SDL_FALSE");
+        bresult = SDL_WriteU64LE(rw, LE64value);
+        SDLTest_AssertPass("Call to SDL_WriteU64LE()");
+        SDLTest_AssertCheck(bresult == SDL_TRUE, "Validate object written, expected: SDL_TRUE, got: SDL_FALSE");
 
         /* Test seek to start */
         result = SDL_RWseek(rw, 0, SDL_RW_SEEK_SET);
@@ -570,24 +570,30 @@ static int rwops_testFileWriteReadEndian(void *arg)
         SDLTest_AssertCheck(result == 0, "Verify result from position 0 with SDL_RWseek, expected 0, got %i", (int)result);
 
         /* Read test data */
-        BE16test = SDL_ReadBE16(rw);
-        SDLTest_AssertPass("Call to SDL_ReadBE16()");
-        SDLTest_AssertCheck(BE16test == BE16value, "Validate return value from SDL_ReadBE16, expected: %hu, got: %hu", BE16value, BE16test);
-        BE32test = SDL_ReadBE32(rw);
-        SDLTest_AssertPass("Call to SDL_ReadBE32()");
-        SDLTest_AssertCheck(BE32test == BE32value, "Validate return value from SDL_ReadBE32, expected: %" SDL_PRIu32 ", got: %" SDL_PRIu32, BE32value, BE32test);
-        BE64test = SDL_ReadBE64(rw);
-        SDLTest_AssertPass("Call to SDL_ReadBE64()");
-        SDLTest_AssertCheck(BE64test == BE64value, "Validate return value from SDL_ReadBE64, expected: %" SDL_PRIu64 ", got: %" SDL_PRIu64, BE64value, BE64test);
-        LE16test = SDL_ReadLE16(rw);
-        SDLTest_AssertPass("Call to SDL_ReadLE16()");
-        SDLTest_AssertCheck(LE16test == LE16value, "Validate return value from SDL_ReadLE16, expected: %hu, got: %hu", LE16value, LE16test);
-        LE32test = SDL_ReadLE32(rw);
-        SDLTest_AssertPass("Call to SDL_ReadLE32()");
-        SDLTest_AssertCheck(LE32test == LE32value, "Validate return value from SDL_ReadLE32, expected: %" SDL_PRIu32 ", got: %" SDL_PRIu32, LE32value, LE32test);
-        LE64test = SDL_ReadLE64(rw);
-        SDLTest_AssertPass("Call to SDL_ReadLE64()");
-        SDLTest_AssertCheck(LE64test == LE64value, "Validate return value from SDL_ReadLE64, expected: %" SDL_PRIu64 ", got: %" SDL_PRIu64, LE64value, LE64test);
+        bresult = SDL_ReadU16BE(rw, &BE16test);
+        SDLTest_AssertPass("Call to SDL_ReadU16BE()");
+        SDLTest_AssertCheck(bresult == SDL_TRUE, "Validate object read, expected: SDL_TRUE, got: SDL_FALSE");
+        SDLTest_AssertCheck(BE16test == BE16value, "Validate object read from SDL_ReadU16BE, expected: %hu, got: %hu", BE16value, BE16test);
+        bresult = SDL_ReadU32BE(rw, &BE32test);
+        SDLTest_AssertPass("Call to SDL_ReadU32BE()");
+        SDLTest_AssertCheck(bresult == SDL_TRUE, "Validate object read, expected: SDL_TRUE, got: SDL_FALSE");
+        SDLTest_AssertCheck(BE32test == BE32value, "Validate object read from SDL_ReadU32BE, expected: %" SDL_PRIu32 ", got: %" SDL_PRIu32, BE32value, BE32test);
+        bresult = SDL_ReadU64BE(rw, &BE64test);
+        SDLTest_AssertPass("Call to SDL_ReadU64BE()");
+        SDLTest_AssertCheck(bresult == SDL_TRUE, "Validate object read, expected: SDL_TRUE, got: SDL_FALSE");
+        SDLTest_AssertCheck(BE64test == BE64value, "Validate object read from SDL_ReadU64BE, expected: %" SDL_PRIu64 ", got: %" SDL_PRIu64, BE64value, BE64test);
+        bresult = SDL_ReadU16LE(rw, &LE16test);
+        SDLTest_AssertPass("Call to SDL_ReadU16LE()");
+        SDLTest_AssertCheck(bresult == SDL_TRUE, "Validate object read, expected: SDL_TRUE, got: SDL_FALSE");
+        SDLTest_AssertCheck(LE16test == LE16value, "Validate object read from SDL_ReadU16LE, expected: %hu, got: %hu", LE16value, LE16test);
+        bresult = SDL_ReadU32LE(rw, &LE32test);
+        SDLTest_AssertPass("Call to SDL_ReadU32LE()");
+        SDLTest_AssertCheck(bresult == SDL_TRUE, "Validate object read, expected: SDL_TRUE, got: SDL_FALSE");
+        SDLTest_AssertCheck(LE32test == LE32value, "Validate object read from SDL_ReadU32LE, expected: %" SDL_PRIu32 ", got: %" SDL_PRIu32, LE32value, LE32test);
+        bresult = SDL_ReadU64LE(rw, &LE64test);
+        SDLTest_AssertPass("Call to SDL_ReadU64LE()");
+        SDLTest_AssertCheck(bresult == SDL_TRUE, "Validate object read, expected: SDL_TRUE, got: SDL_FALSE");
+        SDLTest_AssertCheck(LE64test == LE64value, "Validate object read from SDL_ReadU64LE, expected: %" SDL_PRIu64 ", got: %" SDL_PRIu64, LE64value, LE64test);
 
         /* Close handle */
         cresult = SDL_RWclose(rw);

+ 60 - 60
test/testfile.c

@@ -55,7 +55,7 @@ rwops_error_quit(unsigned line, SDL_RWops *rwops)
 {
     SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "testfile.c(%d): failed\n", line);
     if (rwops) {
-        rwops->close(rwops); /* This calls SDL_DestroyRW(rwops); */
+        SDL_RWclose(rwops); /* This calls SDL_DestroyRW(rwops); */
     }
     cleanup();
     SDLTest_CommonDestroyState(state);
@@ -126,25 +126,25 @@ int main(int argc, char *argv[])
     if (rwops == NULL) {
         RWOP_ERR_QUIT(rwops);
     }
-    rwops->close(rwops);
+    SDL_RWclose(rwops);
     unlink(FBASENAME2);
     rwops = SDL_RWFromFile(FBASENAME2, "wb+");
     if (rwops == NULL) {
         RWOP_ERR_QUIT(rwops);
     }
-    rwops->close(rwops);
+    SDL_RWclose(rwops);
     unlink(FBASENAME2);
     rwops = SDL_RWFromFile(FBASENAME2, "ab");
     if (rwops == NULL) {
         RWOP_ERR_QUIT(rwops);
     }
-    rwops->close(rwops);
+    SDL_RWclose(rwops);
     unlink(FBASENAME2);
     rwops = SDL_RWFromFile(FBASENAME2, "ab+");
     if (rwops == NULL) {
         RWOP_ERR_QUIT(rwops);
     }
-    rwops->close(rwops);
+    SDL_RWclose(rwops);
     unlink(FBASENAME2);
     SDL_Log("test2 OK\n");
 
@@ -155,110 +155,110 @@ int main(int argc, char *argv[])
     if (rwops == NULL) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (10 != rwops->write(rwops, "1234567890", 10)) {
+    if (10 != SDL_RWwrite(rwops, "1234567890", 10)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (10 != rwops->write(rwops, "1234567890", 10)) {
+    if (10 != SDL_RWwrite(rwops, "1234567890", 10)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (7 != rwops->write(rwops, "1234567", 7)) {
+    if (7 != SDL_RWwrite(rwops, "1234567", 7)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (0 != rwops->seek(rwops, 0L, SDL_RW_SEEK_SET)) {
+    if (0 != SDL_RWseek(rwops, 0L, SDL_RW_SEEK_SET)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (-1 != rwops->read(rwops, test_buf, 1)) {
+    if (0 != SDL_RWread(rwops, test_buf, 1)) {
         RWOP_ERR_QUIT(rwops); /* we are in write only mode */
     }
 
-    rwops->close(rwops);
+    SDL_RWclose(rwops);
 
     rwops = SDL_RWFromFile(FBASENAME1, "rb"); /* read mode, file must exist */
     if (rwops == NULL) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (0 != rwops->seek(rwops, 0L, SDL_RW_SEEK_SET)) {
+    if (0 != SDL_RWseek(rwops, 0L, SDL_RW_SEEK_SET)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (20 != rwops->seek(rwops, -7, SDL_RW_SEEK_END)) {
+    if (20 != SDL_RWseek(rwops, -7, SDL_RW_SEEK_END)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (7 != rwops->read(rwops, test_buf, 7)) {
+    if (7 != SDL_RWread(rwops, test_buf, 7)) {
         RWOP_ERR_QUIT(rwops);
     }
     if (SDL_memcmp(test_buf, "1234567", 7) != 0) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (0 != rwops->read(rwops, test_buf, 1)) {
+    if (0 != SDL_RWread(rwops, test_buf, 1)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (0 != rwops->read(rwops, test_buf, 1000)) {
+    if (0 != SDL_RWread(rwops, test_buf, 1000)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (0 != rwops->seek(rwops, -27, SDL_RW_SEEK_CUR)) {
+    if (0 != SDL_RWseek(rwops, -27, SDL_RW_SEEK_CUR)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (27 != rwops->read(rwops, test_buf, 30)) {
+    if (27 != SDL_RWread(rwops, test_buf, 30)) {
         RWOP_ERR_QUIT(rwops);
     }
     if (SDL_memcmp(test_buf, "12345678901234567890", 20) != 0) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (-1 != rwops->write(rwops, test_buf, 1)) {
+    if (0 != SDL_RWwrite(rwops, test_buf, 1)) {
         RWOP_ERR_QUIT(rwops); /* readonly mode */
     }
 
-    rwops->close(rwops);
+    SDL_RWclose(rwops);
 
     /* test 3: same with w+ mode */
     rwops = SDL_RWFromFile(FBASENAME1, "wb+"); /* write + read + truncation */
     if (rwops == NULL) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (10 != rwops->write(rwops, "1234567890", 10)) {
+    if (10 != SDL_RWwrite(rwops, "1234567890", 10)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (10 != rwops->write(rwops, "1234567890", 10)) {
+    if (10 != SDL_RWwrite(rwops, "1234567890", 10)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (7 != rwops->write(rwops, "1234567", 7)) {
+    if (7 != SDL_RWwrite(rwops, "1234567", 7)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (0 != rwops->seek(rwops, 0L, SDL_RW_SEEK_SET)) {
+    if (0 != SDL_RWseek(rwops, 0L, SDL_RW_SEEK_SET)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (1 != rwops->read(rwops, test_buf, 1)) {
+    if (1 != SDL_RWread(rwops, test_buf, 1)) {
         RWOP_ERR_QUIT(rwops); /* we are in read/write mode */
     }
 
-    if (0 != rwops->seek(rwops, 0L, SDL_RW_SEEK_SET)) {
+    if (0 != SDL_RWseek(rwops, 0L, SDL_RW_SEEK_SET)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (20 != rwops->seek(rwops, -7, SDL_RW_SEEK_END)) {
+    if (20 != SDL_RWseek(rwops, -7, SDL_RW_SEEK_END)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (7 != rwops->read(rwops, test_buf, 7)) {
+    if (7 != SDL_RWread(rwops, test_buf, 7)) {
         RWOP_ERR_QUIT(rwops);
     }
     if (SDL_memcmp(test_buf, "1234567", 7) != 0) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (0 != rwops->read(rwops, test_buf, 1)) {
+    if (0 != SDL_RWread(rwops, test_buf, 1)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (0 != rwops->read(rwops, test_buf, 1000)) {
+    if (0 != SDL_RWread(rwops, test_buf, 1000)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (0 != rwops->seek(rwops, -27, SDL_RW_SEEK_CUR)) {
+    if (0 != SDL_RWseek(rwops, -27, SDL_RW_SEEK_CUR)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (27 != rwops->read(rwops, test_buf, 30)) {
+    if (27 != SDL_RWread(rwops, test_buf, 30)) {
         RWOP_ERR_QUIT(rwops);
     }
     if (SDL_memcmp(test_buf, "12345678901234567890", 20) != 0) {
         RWOP_ERR_QUIT(rwops);
     }
-    rwops->close(rwops);
+    SDL_RWclose(rwops);
     SDL_Log("test3 OK\n");
 
     /* test 4: same in r+ mode */
@@ -266,50 +266,50 @@ int main(int argc, char *argv[])
     if (rwops == NULL) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (10 != rwops->write(rwops, "1234567890", 10)) {
+    if (10 != SDL_RWwrite(rwops, "1234567890", 10)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (10 != rwops->write(rwops, "1234567890", 10)) {
+    if (10 != SDL_RWwrite(rwops, "1234567890", 10)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (7 != rwops->write(rwops, "1234567", 7)) {
+    if (7 != SDL_RWwrite(rwops, "1234567", 7)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (0 != rwops->seek(rwops, 0L, SDL_RW_SEEK_SET)) {
+    if (0 != SDL_RWseek(rwops, 0L, SDL_RW_SEEK_SET)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (1 != rwops->read(rwops, test_buf, 1)) {
+    if (1 != SDL_RWread(rwops, test_buf, 1)) {
         RWOP_ERR_QUIT(rwops); /* we are in read/write mode */
     }
 
-    if (0 != rwops->seek(rwops, 0L, SDL_RW_SEEK_SET)) {
+    if (0 != SDL_RWseek(rwops, 0L, SDL_RW_SEEK_SET)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (20 != rwops->seek(rwops, -7, SDL_RW_SEEK_END)) {
+    if (20 != SDL_RWseek(rwops, -7, SDL_RW_SEEK_END)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (7 != rwops->read(rwops, test_buf, 7)) {
+    if (7 != SDL_RWread(rwops, test_buf, 7)) {
         RWOP_ERR_QUIT(rwops);
     }
     if (SDL_memcmp(test_buf, "1234567", 7) != 0) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (0 != rwops->read(rwops, test_buf, 1)) {
+    if (0 != SDL_RWread(rwops, test_buf, 1)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (0 != rwops->read(rwops, test_buf, 1000)) {
+    if (0 != SDL_RWread(rwops, test_buf, 1000)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (0 != rwops->seek(rwops, -27, SDL_RW_SEEK_CUR)) {
+    if (0 != SDL_RWseek(rwops, -27, SDL_RW_SEEK_CUR)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (27 != rwops->read(rwops, test_buf, 30)) {
+    if (27 != SDL_RWread(rwops, test_buf, 30)) {
         RWOP_ERR_QUIT(rwops);
     }
     if (SDL_memcmp(test_buf, "12345678901234567890", 20) != 0) {
         RWOP_ERR_QUIT(rwops);
     }
-    rwops->close(rwops);
+    SDL_RWclose(rwops);
     SDL_Log("test4 OK\n");
 
     /* test5 : append mode */
@@ -317,56 +317,56 @@ int main(int argc, char *argv[])
     if (rwops == NULL) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (10 != rwops->write(rwops, "1234567890", 10)) {
+    if (10 != SDL_RWwrite(rwops, "1234567890", 10)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (10 != rwops->write(rwops, "1234567890", 10)) {
+    if (10 != SDL_RWwrite(rwops, "1234567890", 10)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (7 != rwops->write(rwops, "1234567", 7)) {
+    if (7 != SDL_RWwrite(rwops, "1234567", 7)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (0 != rwops->seek(rwops, 0L, SDL_RW_SEEK_SET)) {
+    if (0 != SDL_RWseek(rwops, 0L, SDL_RW_SEEK_SET)) {
         RWOP_ERR_QUIT(rwops);
     }
 
-    if (1 != rwops->read(rwops, test_buf, 1)) {
+    if (1 != SDL_RWread(rwops, test_buf, 1)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (0 != rwops->seek(rwops, 0L, SDL_RW_SEEK_SET)) {
+    if (0 != SDL_RWseek(rwops, 0L, SDL_RW_SEEK_SET)) {
         RWOP_ERR_QUIT(rwops);
     }
 
-    if (20 + 27 != rwops->seek(rwops, -7, SDL_RW_SEEK_END)) {
+    if (20 + 27 != SDL_RWseek(rwops, -7, SDL_RW_SEEK_END)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (7 != rwops->read(rwops, test_buf, 7)) {
+    if (7 != SDL_RWread(rwops, test_buf, 7)) {
         RWOP_ERR_QUIT(rwops);
     }
     if (SDL_memcmp(test_buf, "1234567", 7) != 0) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (0 != rwops->read(rwops, test_buf, 1)) {
+    if (0 != SDL_RWread(rwops, test_buf, 1)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (0 != rwops->read(rwops, test_buf, 1000)) {
+    if (0 != SDL_RWread(rwops, test_buf, 1000)) {
         RWOP_ERR_QUIT(rwops);
     }
 
-    if (27 != rwops->seek(rwops, -27, SDL_RW_SEEK_CUR)) {
+    if (27 != SDL_RWseek(rwops, -27, SDL_RW_SEEK_CUR)) {
         RWOP_ERR_QUIT(rwops);
     }
 
-    if (0 != rwops->seek(rwops, 0L, SDL_RW_SEEK_SET)) {
+    if (0 != SDL_RWseek(rwops, 0L, SDL_RW_SEEK_SET)) {
         RWOP_ERR_QUIT(rwops);
     }
-    if (30 != rwops->read(rwops, test_buf, 30)) {
+    if (30 != SDL_RWread(rwops, test_buf, 30)) {
         RWOP_ERR_QUIT(rwops);
     }
     if (SDL_memcmp(test_buf, "123456789012345678901234567123", 30) != 0) {
         RWOP_ERR_QUIT(rwops);
     }
-    rwops->close(rwops);
+    SDL_RWclose(rwops);
     SDL_Log("test5 OK\n");
     cleanup();
     SDLTest_CommonDestroyState(state);

+ 2 - 9
test/testime.c

@@ -108,7 +108,7 @@ static int unifont_init(const char *fontname)
     Uint8 hexBuffer[65];
     Uint32 numGlyphs = 0;
     int lineNumber = 1;
-    Sint64 bytesRead;
+    size_t bytesRead;
     SDL_RWops *hexFile;
     const size_t unifontGlyphSize = UNIFONT_NUM_GLYPHS * sizeof(struct UnifontGlyph);
     const size_t unifontTextureSize = UNIFONT_NUM_TEXTURES * state->num_windows * sizeof(void *);
@@ -150,11 +150,6 @@ static int unifont_init(const char *fontname)
         Uint32 codepoint;
 
         bytesRead = SDL_RWread(hexFile, hexBuffer, 9);
-        if (bytesRead < 0) {
-            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "error SDL_RWread\n");
-            return -1;
-        }
-
         if (numGlyphs > 0 && bytesRead == 0) {
             break; /* EOF */
         }
@@ -196,9 +191,7 @@ static int unifont_init(const char *fontname)
             return -1;
         }
 
-
-
-        if ((size_t)bytesRead < (33 - bytesOverread)) {
+        if (bytesRead < (33 - bytesOverread)) {
             SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Unexpected end of hex file.\n");
             return -1;
         }

+ 13 - 13
test/testresample.c

@@ -126,19 +126,19 @@ int main(int argc, char **argv)
     blockalign = (bitsize / 8) * cvtspec.channels;
     avgbytes = cvtspec.freq * blockalign;
 
-    SDL_WriteLE32(io, 0x46464952); /* RIFF */
-    SDL_WriteLE32(io, dst_len + 36);
-    SDL_WriteLE32(io, 0x45564157);                             /* WAVE */
-    SDL_WriteLE32(io, 0x20746D66);                             /* fmt */
-    SDL_WriteLE32(io, 16);                                     /* chunk size */
-    SDL_WriteLE16(io, SDL_AUDIO_ISFLOAT(spec.format) ? 3 : 1); /* uncompressed */
-    SDL_WriteLE16(io, cvtspec.channels);                       /* channels */
-    SDL_WriteLE32(io, cvtspec.freq);                           /* sample rate */
-    SDL_WriteLE32(io, avgbytes);                               /* average bytes per second */
-    SDL_WriteLE16(io, blockalign);                             /* block align */
-    SDL_WriteLE16(io, bitsize);                                /* significant bits per sample */
-    SDL_WriteLE32(io, 0x61746164);                             /* data */
-    SDL_WriteLE32(io, dst_len);                                /* size */
+    SDL_WriteU32LE(io, 0x46464952); /* RIFF */
+    SDL_WriteU32LE(io, dst_len + 36);
+    SDL_WriteU32LE(io, 0x45564157);                             /* WAVE */
+    SDL_WriteU32LE(io, 0x20746D66);                             /* fmt */
+    SDL_WriteU32LE(io, 16);                                     /* chunk size */
+    SDL_WriteU16LE(io, SDL_AUDIO_ISFLOAT(spec.format) ? 3 : 1); /* uncompressed */
+    SDL_WriteU16LE(io, cvtspec.channels);                       /* channels */
+    SDL_WriteU32LE(io, cvtspec.freq);                           /* sample rate */
+    SDL_WriteU32LE(io, avgbytes);                               /* average bytes per second */
+    SDL_WriteU16LE(io, blockalign);                             /* block align */
+    SDL_WriteU16LE(io, bitsize);                                /* significant bits per sample */
+    SDL_WriteU32LE(io, 0x61746164);                             /* data */
+    SDL_WriteU32LE(io, dst_len);                                /* size */
     SDL_RWwrite(io, dst_buf, dst_len);
 
     if (SDL_RWclose(io) == -1) {