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

This commit is contained in:
Sam Lantinga 2023-01-04 22:29:16 -08:00
parent 5a42831345
commit 51a80d03ce
2 changed files with 25 additions and 22 deletions

View File

@ -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:
```c
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.

View File

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