SDL: Be really explicit about needing to check for negative error codes with SDL_RWread()

From 51a80d03ceee5ebb59003e2da9cef45256b17d34 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Wed, 4 Jan 2023 22:29:16 -0800
Subject: [PATCH] Be really explicit about needing to check for negative error
 codes with SDL_RWread()

---
 docs/README-migration.md | 42 ++++++++++++++++++++++------------------
 include/SDL3/SDL_rwops.h |  5 ++---
 2 files changed, 25 insertions(+), 22 deletions(-)

diff --git a/docs/README-migration.md b/docs/README-migration.md
index 2a36287536f3..1c24459761c2 100644
--- a/docs/README-migration.md
+++ b/docs/README-migration.md
@@ -531,35 +531,39 @@ Previously they looked more like stdio:
 
 ```c
 size_t SDL_RWread(SDL_RWops *context, void *ptr, size_t size, size_t maxnum);
+size_t SDL_RWwrite(SDL_RWops *context, const void *ptr, size_t size, size_t maxnum);

But now they look more like POSIX:

Sint64 SDL_RWread(SDL_RWops *context, void *ptr, Sint64 size);
+Sint64 SDL_RWwrite(SDL_RWops *context, const void *ptr, Sint64 size);

-Previously they tried to read/write size objects of maxnum bytes each. Now they try to read/write size bytes, which solves concerns about what should happen to the file pointer if only a fraction of an object could be read, etc. The return value is different, too. For reading:
+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).

– SDL_RWread returns the number of bytes read, which will be less than requested on error or EOF.
– If there was an error but some bytes were read, it will return the number of bytes read.
– On error when no bytes were read, it returns -1.
– For non-blocking RWops (new to SDL3!), if we are neither at an error or EOF but it would require blocking to read more data, it returns -2.

-For writing:

– SDL_RWwrite returns the number of bytes written, which might be less on error or if the RWops is non-blocking.
– If there was an error but some bytes were written, it will return the number of bytes written.
– On error when no bytes were written, it returns -1.
– For non-blocking RWops (new to SDL3!), if we are not at an error but it would require blocking to write more data, it returns -2.

-As you can see, RWops can now be non-blocking! There is no API in SDL to
-toggle a RWops to (non-)blocking mode, they must be created as such. The
-existing SDL_RWFrom* functions do not create non-blocking objects, so existing
-code (and much of the code you would care to write by default) does not have
-to contend with this behavior.
+Code that used to look like this:
+```

  • if (!SDL_RWread(context, ptr, size, 1)) {
  •    ... handle error
    
  • }
    + +should be changed to: +
  • if (SDL_RWread(context, ptr, size) != size) {
  •    ... handle error
    
  • }
    + +or, if you're using a custom non-blocking context or are handling variable size data: +
  • Sint64 amount = SDL_RWread(context, ptr, maxsize);
  • if (amount < 0) {
  •    ... handle error
    
  • }
    +```

+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.

diff --git a/include/SDL3/SDL_rwops.h b/include/SDL3/SDL_rwops.h
index bc92b7500add…bc96918b886c 100644
— a/include/SDL3/SDL_rwops.h
+++ b/include/SDL3/SDL_rwops.h
@@ -434,7 +434,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, or 0 at end of file, or -1 on error.
    • \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.
    • \since This function is available since SDL 3.0.0.

@@ -445,8 +445,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 Sint64 SDLCALL SDL_RWread(SDL_RWops *context, void *ptr, Sint64 size);

/**

  • Write to an SDL_RWops data stream.