SDL: rwops: Add SDL_GetRWStatus, make the statuses into an enum.

From cc58da4c63c51c64ccf28ca017cde6fb5e55b859 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Wed, 13 Mar 2024 12:29:17 -0400
Subject: [PATCH] rwops: Add SDL_GetRWStatus, make the statuses into an enum.

---
 include/SDL3/SDL_rwops.h          | 37 +++++++++++++++++++++++++------
 src/dynapi/SDL_dynapi.sym         |  1 +
 src/dynapi/SDL_dynapi_overrides.h |  1 +
 src/dynapi/SDL_dynapi_procs.h     |  1 +
 src/file/SDL_rwops.c              | 12 +++++++++-
 5 files changed, 44 insertions(+), 8 deletions(-)

diff --git a/include/SDL3/SDL_rwops.h b/include/SDL3/SDL_rwops.h
index a99bddeb837e5..1caddb340322e 100644
--- a/include/SDL3/SDL_rwops.h
+++ b/include/SDL3/SDL_rwops.h
@@ -40,13 +40,15 @@ extern "C" {
 #endif
 
 /* RWops status, set by a read or write operation */
-/* !!! FIXME: make this an enum? */
-#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 */
+typedef enum SDL_RWopsStatus
+{
+    SDL_RWOPS_STATUS_READY,     /**< Everything is ready */
+    SDL_RWOPS_STATUS_ERROR,     /**< Read or write I/O error */
+    SDL_RWOPS_STATUS_EOF,       /**< End of file */
+    SDL_RWOPS_STATUS_NOT_READY, /**< Non blocking I/O, not ready */
+    SDL_RWOPS_STATUS_READONLY,  /**< Tried to write a read-only buffer */
+    SDL_RWOPS_STATUS_WRITEONLY  /**< Tried to read a write-only buffer */
+} SDL_RWopsStatus;
 
 typedef struct SDL_RWopsInterface
 {
@@ -318,6 +320,27 @@ extern DECLSPEC SDL_PropertiesID SDLCALL SDL_GetRWProperties(SDL_RWops *context)
 #define SDL_RW_SEEK_CUR 1       /**< Seek relative to current read point */
 #define SDL_RW_SEEK_END 2       /**< Seek relative to the end of data */
 
+/**
+ * Query the stream status of a RWops.
+ *
+ * This information can be useful to decide if a short read or write was
+ * due to an error, an EOF, or a non-blocking operation that isn't yet
+ * ready to complete.
+ *
+ * A RWops's status is only expected to change after a SDL_ReadRW or
+ * SDL_WriteRW call; don't expect it to change if you just call this
+ * query function in a tight loop.
+ *
+ * \param context the SDL_RWops to query.
+ * \returns an SDL_RWopsStatus enum with the current state.
+ *
+ * \threadsafety This function should not be called at the same time that
+ *               another thread is operating on the same SDL_RWops.
+ *
+ * \since This function is available since SDL 3.0.0.
+ */
+extern DECLSPEC SDL_RWopsStatus SDLCALL SDL_GetRWStatus(SDL_RWops *context);
+
 /**
  * Use this function to get the size of the data stream in an SDL_RWops.
  *
diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym
index 52c9bf387eeba..06d19f46f8eb2 100644
--- a/src/dynapi/SDL_dynapi.sym
+++ b/src/dynapi/SDL_dynapi.sym
@@ -978,6 +978,7 @@ SDL3_0.0.0 {
     SDL_ShowOpenFolderDialog;
     SDL_OpenRW;
     SDL_CloseRW;
+    SDL_GetRWStatus;
     # extra symbols go here (don't modify this line)
   local: *;
 };
diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h
index aec8ec7bc660d..58d44b9aed8e0 100644
--- a/src/dynapi/SDL_dynapi_overrides.h
+++ b/src/dynapi/SDL_dynapi_overrides.h
@@ -1003,3 +1003,4 @@
 #define SDL_ShowOpenFolderDialog SDL_ShowOpenFolderDialog_REAL
 #define SDL_OpenRW SDL_OpenRW_REAL
 #define SDL_CloseRW SDL_CloseRW_REAL
+#define SDL_GetRWStatus SDL_GetRWStatus_REAL
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index 516bfd291c384..c106976adff61 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -1028,3 +1028,4 @@ SDL_DYNAPI_PROC(void,SDL_ShowSaveFileDialog,(SDL_DialogFileCallback a, void *b,
 SDL_DYNAPI_PROC(void,SDL_ShowOpenFolderDialog,(SDL_DialogFileCallback a, void *b, SDL_Window *c, const char *d, int e),(a,b,c,d,e),)
 SDL_DYNAPI_PROC(SDL_RWops*,SDL_OpenRW,(const SDL_RWopsInterface *a, void *b),(a,b),return)
 SDL_DYNAPI_PROC(int,SDL_CloseRW,(SDL_RWops *a),(a),return)
+SDL_DYNAPI_PROC(SDL_RWopsStatus,SDL_GetRWStatus,(SDL_RWops *a),(a),return)
diff --git a/src/file/SDL_rwops.c b/src/file/SDL_rwops.c
index 97182e1abcb6c..3edfb6f68285d 100644
--- a/src/file/SDL_rwops.c
+++ b/src/file/SDL_rwops.c
@@ -40,7 +40,7 @@ struct SDL_RWops
 {
     SDL_RWopsInterface iface;
     void *userdata;
-    Uint32 status;
+    SDL_RWopsStatus status;
     SDL_PropertiesID props;
 };
 
@@ -724,6 +724,16 @@ SDL_RWops *SDL_RWFromConstMem(const void *mem, size_t size)
     return rwops;
 }
 
+SDL_RWopsStatus SDL_GetRWStatus(SDL_RWops *context)
+{
+    if (!context) {
+        SDL_InvalidParamError("context");
+        return SDL_RWOPS_STATUS_ERROR;
+    }
+    return context->status;
+}
+
+
 SDL_RWops *SDL_OpenRW(const SDL_RWopsInterface *iface, void *userdata)
 {
     if (!iface) {