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
This commit is contained in:
Sam Lantinga 2023-08-06 13:51:03 -07:00
parent c03f5b4b69
commit b903ccf945
20 changed files with 1154 additions and 754 deletions

View file

@ -2690,3 +2690,63 @@ typedef SDL_cond, SDL_Condition;
- SDL_strtokr - SDL_strtokr
+ SDL_strtok_r + 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
(...)

View file

@ -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: But now they look more like POSIX:
```c ```c
Sint64 SDL_RWread(SDL_RWops *context, void *ptr, Sint64 size); size_t SDL_RWread(SDL_RWops *context, void *ptr, size_t size);
Sint64 SDL_RWwrite(SDL_RWops *context, const void *ptr, Sint64 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: Code that used to look like this:
``` ```
size_t custom_read(void *ptr, size_t size, size_t nitems, SDL_RWops *stream) 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: should be changed to:
``` ```
size_t custom_read(void *ptr, size_t size, size_t nitems, SDL_RWops *stream) size_t custom_read(void *ptr, size_t size, size_t nitems, SDL_RWops *stream)
{ {
Sint64 amount = SDL_RWread(stream, ptr, size * nitems); size_t bytes = SDL_RWread(stream, ptr, size * nitems);
if (amount <= 0) { return (bytes / size);
return 0;
}
return (size_t)(amount / 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. 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: 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> #include <stdio.h>
static Sint64 SDLCALL static Sint64 SDLCALL stdio_seek(SDL_RWops *context, Sint64 offset, int whence)
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; int stdiowhence;
@ -988,54 +965,46 @@ stdio_seek(SDL_RWops * context, Sint64 offset, int whence)
return SDL_Error(SDL_EFSEEK); return SDL_Error(SDL_EFSEEK);
} }
static Sint64 SDLCALL static size_t SDLCALL stdio_read(SDL_RWops *context, void *ptr, size_t size)
stdio_read(SDL_RWops * context, void *ptr, Sint64 size)
{ {
size_t nread; size_t bytes;
nread = fread(ptr, 1, (size_t) size, (FILE *)context->hidden.stdio.fp); bytes = fread(ptr, 1, size, (FILE *)context->hidden.stdio.fp);
if (nread == 0 && ferror((FILE *)context->hidden.stdio.fp)) { if (bytes == 0 && ferror((FILE *)context->hidden.stdio.fp)) {
return SDL_Error(SDL_EFREAD); SDL_Error(SDL_EFREAD);
} }
return (Sint64) nread; return bytes;
} }
static Sint64 SDLCALL static size_t SDLCALL stdio_write(SDL_RWops *context, const void *ptr, size_t size)
stdio_write(SDL_RWops * context, const void *ptr, Sint64 size)
{ {
size_t nwrote; size_t bytes;
nwrote = fwrite(ptr, 1, (size_t) size, (FILE *)context->hidden.stdio.fp); bytes = fwrite(ptr, 1, size, (FILE *)context->hidden.stdio.fp);
if (nwrote == 0 && ferror((FILE *)context->hidden.stdio.fp)) { if (bytes == 0 && ferror((FILE *)context->hidden.stdio.fp)) {
return SDL_Error(SDL_EFWRITE); SDL_Error(SDL_EFWRITE);
} }
return (Sint64) nwrote; return bytes;
} }
static int SDLCALL static int SDLCALL stdio_close(SDL_RWops *context)
stdio_close(SDL_RWops * context)
{ {
int status = 0; int status = 0;
if (context) { if (context->hidden.stdio.autoclose) {
if (context->hidden.stdio.autoclose) { if (fclose((FILE *)context->hidden.stdio.fp) != 0) {
/* WARNING: Check the return value here! */ status = SDL_Error(SDL_EFWRITE);
if (fclose((FILE *)context->hidden.stdio.fp) != 0) {
status = SDL_Error(SDL_EFWRITE);
}
} }
SDL_DestroyRW(context);
} }
SDL_DestroyRW(context);
return status; return status;
} }
SDL_RWops * SDL_RWops *SDL_RWFromFP(void *fp, SDL_bool autoclose)
SDL_RWFromFP(void *fp, SDL_bool autoclose)
{ {
SDL_RWops *rwops = NULL; SDL_RWops *rwops = NULL;
rwops = SDL_CreateRW(); rwops = SDL_CreateRW();
if (rwops != NULL) { if (rwops != NULL) {
rwops->size = stdio_size;
rwops->seek = stdio_seek; rwops->seek = stdio_seek;
rwops->read = stdio_read; rwops->read = stdio_read;
rwops->write = stdio_write; 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: The following functions have been renamed:
* SDL_AllocRW() => SDL_CreateRW() * SDL_AllocRW() => SDL_CreateRW()
* SDL_FreeRW() => SDL_DestroyRW() * 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 ## SDL_sensor.h

View file

@ -176,7 +176,8 @@ extern DECLSPEC int SDLCALL SDL_AddGamepadMapping(const char *mapping);
* constrained environment. * constrained environment.
* *
* \param src the data stream for the mappings to be added * \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() * \returns the number of mappings added or -1 on error; call SDL_GetError()
* for more information. * for more information.
* *
@ -186,7 +187,7 @@ extern DECLSPEC int SDLCALL SDL_AddGamepadMapping(const char *mapping);
* \sa SDL_AddGamepadMappingsFromFile * \sa SDL_AddGamepadMappingsFromFile
* \sa SDL_GetGamepadMappingForGUID * \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. * Load a set of gamepad mappings from a file.

View file

@ -423,6 +423,18 @@
#define RW_SEEK_SET SDL_RW_SEEK_SET #define RW_SEEK_SET SDL_RW_SEEK_SET
#define SDL_AllocRW SDL_CreateRW #define SDL_AllocRW SDL_CreateRW
#define SDL_FreeRW SDL_DestroyRW #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 */ /* ##SDL_sensor.h */
#define SDL_SensorClose SDL_CloseSensor #define SDL_SensorClose SDL_CloseSensor
@ -863,6 +875,18 @@
#define RW_SEEK_SET RW_SEEK_SET_renamed_SDL_RW_SEEK_SET #define RW_SEEK_SET RW_SEEK_SET_renamed_SDL_RW_SEEK_SET
#define SDL_AllocRW SDL_AllocRW_renamed_SDL_CreateRW #define SDL_AllocRW SDL_AllocRW_renamed_SDL_CreateRW
#define SDL_FreeRW SDL_FreeRW_renamed_SDL_DestroyRW #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 */ /* ##SDL_sensor.h */
#define SDL_SensorClose SDL_SensorClose_renamed_SDL_CloseSensor #define SDL_SensorClose SDL_SensorClose_renamed_SDL_CloseSensor

View file

@ -38,13 +38,21 @@
extern "C" { extern "C" {
#endif #endif
/* RWops Types */ /* RWops types */
#define SDL_RWOPS_UNKNOWN 0U /**< Unknown stream type */ #define SDL_RWOPS_UNKNOWN 0 /**< Unknown stream type */
#define SDL_RWOPS_WINFILE 1U /**< Win32 file */ #define SDL_RWOPS_WINFILE 1 /**< Win32 file */
#define SDL_RWOPS_STDFILE 2U /**< Stdio file */ #define SDL_RWOPS_STDFILE 2 /**< Stdio file */
#define SDL_RWOPS_JNIFILE 3U /**< Android asset */ #define SDL_RWOPS_JNIFILE 3 /**< Android asset */
#define SDL_RWOPS_MEMORY 4U /**< Memory stream */ #define SDL_RWOPS_MEMORY 4 /**< Memory stream */
#define SDL_RWOPS_MEMORY_RO 5U /**< Read-Only 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. * This is the read/write operation structure -- very basic.
@ -52,9 +60,11 @@ extern "C" {
typedef struct SDL_RWops 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: * 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. * \return the final offset in the data stream, or -1 on error.
*/ */
Sint64 (SDLCALL * seek) (struct SDL_RWops * context, Sint64 offset, Sint64 (SDLCALL *seek)(struct SDL_RWops *context, Sint64 offset, int whence);
int whence);
/** /**
* Read up to \c size bytes from the data stream to the area pointed * Read up to \c size bytes from the data stream to the area pointed
* at by \c ptr. * at by \c ptr.
* *
* It is an error to use a negative \c size, but this parameter is * \return the number of bytes read
* 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.
*/ */
Sint64 (SDLCALL * read) (struct SDL_RWops * context, void *ptr, size_t (SDLCALL *read)(struct SDL_RWops *context, void *ptr, size_t size);
Sint64 size);
/** /**
* Write exactly \c size bytes from the area pointed at by \c ptr * 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, * to data stream.
* etc). Returns -1 on error when nothing was written.
* *
* It is an error to use a negative \c size, but this parameter is * \return the number of bytes written
* signed so you definitely cannot overflow the return value on a
* successful run with enormous amounts of data.
*
* \return the number of bytes written, which might be less than \c size,
* and -1 on error.
*/ */
Sint64 (SDLCALL * write) (struct SDL_RWops * context, const void *ptr, size_t (SDLCALL *write)(struct SDL_RWops *context, const void *ptr, size_t size);
Sint64 size);
/** /**
* Close and free an allocated SDL_RWops structure. * Close and free an allocated SDL_RWops structure.
* *
* \return 0 if successful or -1 on write error when flushing data. * \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 type;
Uint32 status;
union union
{ {
#ifdef __ANDROID__ #ifdef __ANDROID__
@ -213,8 +211,7 @@ typedef struct SDL_RWops
* \sa SDL_RWtell * \sa SDL_RWtell
* \sa SDL_RWwrite * \sa SDL_RWwrite
*/ */
extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromFile(const char *file, extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromFile(const char *file, const char *mode);
const char *mode);
/** /**
* Use this function to prepare a read-write memory buffer for use with * 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_RWseek
* \sa SDL_RWtell * \sa SDL_RWtell
*/ */
extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromConstMem(const void *mem, extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromConstMem(const void *mem, size_t size);
size_t size);
/* @} *//* RWFrom functions */ /* @} *//* 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. * Use this function to allocate an empty, unpopulated SDL_RWops structure.
* *
* Applications do not need to use this function unless they are providing * 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 * read/write a common data source, you should use the built-in
* implementations in SDL, like SDL_RWFromFile() or SDL_RWFromMem(), etc. * implementations in SDL, like SDL_RWFromFile() or SDL_RWFromMem(), etc.
* *
@ -315,7 +311,7 @@ extern DECLSPEC SDL_RWops *SDLCALL SDL_CreateRW(void);
* SDL_CreateRW(). * SDL_CreateRW().
* *
* Applications do not need to use this function unless they are providing * 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 * read/write a common data source, you should use the built-in
* implementations in SDL, like SDL_RWFromFile() or SDL_RWFromMem(), etc, and * implementations in SDL, like SDL_RWFromFile() or SDL_RWFromMem(), etc, and
* call the **close** method on those SDL_RWops pointers when you are done * 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 * the programmer must be responsible for managing that memory in their
* **close** method. * **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. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_CreateRW * \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_SET 0 /**< Seek from the beginning of data */
#define SDL_RW_SEEK_CUR 1 /**< Seek relative to current read point */ #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. * 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 * \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 * \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.
* unknown or a negative error code on failure; call SDL_GetError()
* for more information.
* *
* \since This function is available since SDL 3.0.0. * \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 * SDL_RWseek() is actually a wrapper function that calls the SDL_RWops's
* `seek` method appropriately, to simplify application development. * `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 context a pointer to an SDL_RWops structure
* \param offset an offset in bytes, relative to **whence** location; can be * \param offset an offset in bytes, relative to **whence** location; can be
* negative * negative
* \param whence any of `SDL_RW_SEEK_SET`, `SDL_RW_SEEK_CUR`, * \param whence any of `SDL_RW_SEEK_SET`, `SDL_RW_SEEK_CUR`,
* `SDL_RW_SEEK_END` * `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. * \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_RWtell
* \sa SDL_RWwrite * \sa SDL_RWwrite
*/ */
extern DECLSPEC Sint64 SDLCALL SDL_RWseek(SDL_RWops *context, extern DECLSPEC Sint64 SDLCALL SDL_RWseek(SDL_RWops *context, Sint64 offset, int whence);
Sint64 offset, int whence);
/** /**
* Determine the current read/write offset in an SDL_RWops data stream. * 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 * method, with an offset of 0 bytes from `SDL_RW_SEEK_CUR`, to simplify
* application development. * application development.
* *
* Prior to SDL 2.0.10, this function was a macro. * \param context an SDL_RWops data stream object from which to get the current
*
* \param context a SDL_RWops data stream object from which to get the current
* offset * offset
* \returns the current offset in the stream, or -1 if the information can not * \returns the current offset in the stream, or -1 if the information can not
* be determined. * 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 context a pointer to an SDL_RWops structure
* \param ptr a pointer to a buffer to read data into * \param ptr a pointer to a buffer to read data into
* \param size the number of bytes to read from the data source. * \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 * \returns the number of bytes read, or 0 on end of file or other error.
* for data not ready with a non-blocking context.
* *
* \since This function is available since SDL 3.0.0. * \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_RWseek
* \sa SDL_RWwrite * \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. * 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_RWread
* \sa SDL_RWseek * \sa SDL_RWseek
*/ */
extern DECLSPEC Sint64 SDLCALL SDL_RWwrite(SDL_RWops *context, extern DECLSPEC size_t SDLCALL SDL_RWwrite(SDL_RWops *context, const void *ptr, size_t size);
const void *ptr, Sint64 size);
/** /**
* Close and free an allocated SDL_RWops structure. * 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 * 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. * 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 * \param context SDL_RWops structure to close
* \returns 0 on success or a negative error code on failure; call * \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information. * 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. * \since This function is available since SDL 3.0.0.
*/ */
extern DECLSPEC void *SDLCALL SDL_LoadFile_RW(SDL_RWops *src, extern DECLSPEC void *SDLCALL SDL_LoadFile_RW(SDL_RWops *src, size_t *datasize, SDL_bool freesrc);
size_t *datasize,
SDL_bool freesrc);
/** /**
* Load all the data from a file path. * 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(). * 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 file the path to read all available data from
* \param datasize if not NULL, will store the number of bytes read * \param datasize if not NULL, will store the number of bytes read
* \returns the data, or NULL if there was an error. * \returns the data, or NULL if there was an error.
@ -571,14 +549,13 @@ extern DECLSPEC void *SDLCALL SDL_LoadFile(const char *file, size_t *datasize);
* Use this function to read a byte from an SDL_RWops. * Use this function to read a byte from an SDL_RWops.
* *
* \param src the SDL_RWops to read from * \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. * more information.
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
*
* \sa SDL_WriteU8
*/ */
extern DECLSPEC Uint8 SDLCALL SDL_ReadU8(SDL_RWops * src); 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 * Use this function to read 16 bits of little-endian data from an SDL_RWops
@ -588,13 +565,28 @@ extern DECLSPEC Uint8 SDLCALL SDL_ReadU8(SDL_RWops * src);
* the native byte order. * the native byte order.
* *
* \param src the stream from which to read data * \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.
*/
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
* 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. * \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 * 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. * the native byte order.
* *
* \param src the stream from which to read data * \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. * \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 * 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. * the native byte order.
* *
* \param src the stream from which to read data * \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. * \since This function is available since SDL 3.0.0.
*
* \sa SDL_ReadBE32
*/ */
extern DECLSPEC Uint32 SDLCALL SDL_ReadLE32(SDL_RWops * src); 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.
*
* 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_ReadS32LE(SDL_RWops *src, Sint32 *value);
/** /**
* Use this function to read 32 bits of big-endian data from an SDL_RWops and * 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. * the native byte order.
* *
* \param src the stream from which to read data * \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. * \since This function is available since SDL 3.0.0.
*
* \sa SDL_ReadLE32
*/ */
extern DECLSPEC Uint32 SDLCALL SDL_ReadBE32(SDL_RWops * src); 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.
*
* 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_ReadS32BE(SDL_RWops *src, Sint32 *value);
/** /**
* Use this function to read 64 bits of little-endian data from an SDL_RWops * 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. * the native byte order.
* *
* \param src the stream from which to read data * \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. * \since This function is available since SDL 3.0.0.
*
* \sa SDL_ReadBE64
*/ */
extern DECLSPEC Uint64 SDLCALL SDL_ReadLE64(SDL_RWops * src); 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.
*
* 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_ReadS64LE(SDL_RWops *src, Sint64 *value);
/** /**
* Use this function to read 64 bits of big-endian data from an SDL_RWops and * 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. * the native byte order.
* *
* \param src the stream from which to read data * \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. * \since This function is available since SDL 3.0.0.
*
* \sa SDL_ReadLE64
*/ */
extern DECLSPEC Uint64 SDLCALL SDL_ReadBE64(SDL_RWops * src); 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.
*
* 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_ReadS64BE(SDL_RWops *src, Sint64 *value);
/* @} *//* Read endian functions */ /* @} *//* 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 dst the SDL_RWops to write to
* \param value the byte value to write * \param value the byte value to write
* \returns 1 on success or 0 on failure; call SDL_GetError() for more * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call SDL_GetError() for more information.
* information.
* *
* \since This function is available since SDL 3.0.0. * \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. * little-endian data.
* *
* SDL byteswaps the data only if necessary, so the application always * SDL byteswaps the data only if necessary, so the application always
@ -708,33 +768,14 @@ extern DECLSPEC size_t SDLCALL SDL_WriteU8(SDL_RWops * dst, Uint8 value);
* *
* \param dst the stream to which data will be written * \param dst the stream to which data will be written
* \param value the data to be written, in native format * \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. * \since This function is available since SDL 3.0.0.
*
* \sa SDL_WriteBE16
*/ */
extern DECLSPEC size_t SDLCALL SDL_WriteLE16(SDL_RWops * dst, Uint16 value); extern DECLSPEC SDL_bool SDLCALL SDL_WriteU16LE(SDL_RWops *dst, Uint16 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
* 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 1 on successful write, 0 on error.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_WriteLE16
*/
extern DECLSPEC size_t SDLCALL SDL_WriteBE16(SDL_RWops * dst, Uint16 value);
/**
* Use this function to write 32 bits in native format to a SDL_RWops as
* little-endian data. * little-endian data.
* *
* SDL byteswaps the data only if necessary, so the application always * SDL byteswaps the data only if necessary, so the application always
@ -743,16 +784,14 @@ extern DECLSPEC size_t SDLCALL SDL_WriteBE16(SDL_RWops * dst, Uint16 value);
* *
* \param dst the stream to which data will be written * \param dst the stream to which data will be written
* \param value the data to be written, in native format * \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. * \since This function is available since SDL 3.0.0.
*
* \sa SDL_WriteBE32
*/ */
extern DECLSPEC size_t SDLCALL SDL_WriteLE32(SDL_RWops * dst, Uint32 value); extern DECLSPEC SDL_bool SDLCALL SDL_WriteS16LE(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 16 bits in native format to an SDL_RWops as
* big-endian data. * big-endian data.
* *
* SDL byteswaps the data only if necessary, so the application always * SDL byteswaps the data only if necessary, so the application always
@ -760,16 +799,29 @@ extern DECLSPEC size_t SDLCALL SDL_WriteLE32(SDL_RWops * dst, Uint32 value);
* *
* \param dst the stream to which data will be written * \param dst the stream to which data will be written
* \param value the data to be written, in native format * \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. * \since This function is available since SDL 3.0.0.
*
* \sa SDL_WriteLE32
*/ */
extern DECLSPEC size_t SDLCALL SDL_WriteBE32(SDL_RWops * dst, Uint32 value); extern DECLSPEC SDL_bool SDLCALL SDL_WriteU16BE(SDL_RWops *dst, Uint16 value);
/** /**
* Use this function to write 64 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
* 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 SDL_bool SDLCALL SDL_WriteS16BE(SDL_RWops *dst, Sint16 value);
/**
* Use this function to write 32 bits in native format to an SDL_RWops as
* little-endian data. * little-endian data.
* *
* SDL byteswaps the data only if necessary, so the application always * SDL byteswaps the data only if necessary, so the application always
@ -778,16 +830,30 @@ extern DECLSPEC size_t SDLCALL SDL_WriteBE32(SDL_RWops * dst, Uint32 value);
* *
* \param dst the stream to which data will be written * \param dst the stream to which data will be written
* \param value the data to be written, in native format * \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. * \since This function is available since SDL 3.0.0.
*
* \sa SDL_WriteBE64
*/ */
extern DECLSPEC size_t SDLCALL SDL_WriteLE64(SDL_RWops * dst, Uint64 value); extern DECLSPEC SDL_bool SDLCALL SDL_WriteU32LE(SDL_RWops *dst, Uint32 value);
/** /**
* Use this function to write 64 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
* 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.
*
* \since This function is available since SDL 3.0.0.
*/
extern DECLSPEC SDL_bool SDLCALL SDL_WriteS32LE(SDL_RWops *dst, Sint32 value);
/**
* Use this function to write 32 bits in native format to an SDL_RWops as
* big-endian data. * big-endian data.
* *
* SDL byteswaps the data only if necessary, so the application always * SDL byteswaps the data only if necessary, so the application always
@ -795,13 +861,88 @@ extern DECLSPEC size_t SDLCALL SDL_WriteLE64(SDL_RWops * dst, Uint64 value);
* *
* \param dst the stream to which data will be written * \param dst the stream to which data will be written
* \param value the data to be written, in native format * \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. * \since This function is available since SDL 3.0.0.
*
* \sa SDL_WriteLE64
*/ */
extern DECLSPEC size_t SDLCALL SDL_WriteBE64(SDL_RWops * dst, Uint64 value); 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.
*
* \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 SDL_bool SDLCALL SDL_WriteS32BE(SDL_RWops *dst, Sint32 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.
*
* \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 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.
*
* \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 SDL_bool SDLCALL SDL_WriteS64LE(SDL_RWops *dst, Sint64 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.
*
* \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 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.
*
* \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 SDL_bool SDLCALL SDL_WriteU64BE(SDL_RWops *dst, Uint64 value);
/* @} *//* Write endian functions */ /* @} *//* Write endian functions */
/* Ends C function definitions when using C++ */ /* Ends C function definitions when using C++ */

View file

@ -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 surface the SDL_Surface structure containing the image to be saved
* \param dst a data stream to save to * \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 * \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information. * 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_LoadBMP_RW
* \sa SDL_SaveBMP * \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. * Save a surface to a file.

View file

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

View file

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

View file

@ -1983,13 +1983,18 @@ int Android_JNI_FileOpen(SDL_RWops *ctx,
return 0; 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; 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"); return SDL_SetError("Cannot write to Android package filesystem");
} }

View file

@ -66,8 +66,8 @@ extern SDL_bool Android_IsChromebook(void);
int Android_JNI_FileOpen(SDL_RWops *ctx, const char *fileName, const char *mode); int Android_JNI_FileOpen(SDL_RWops *ctx, const char *fileName, const char *mode);
Sint64 Android_JNI_FileSize(SDL_RWops *ctx); Sint64 Android_JNI_FileSize(SDL_RWops *ctx);
Sint64 Android_JNI_FileSeek(SDL_RWops *ctx, Sint64 offset, int whence); Sint64 Android_JNI_FileSeek(SDL_RWops *ctx, Sint64 offset, int whence);
Sint64 Android_JNI_FileRead(SDL_RWops *ctx, void *buffer, Sint64 size); size_t Android_JNI_FileRead(SDL_RWops *ctx, void *buffer, size_t size);
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);
int Android_JNI_FileClose(SDL_RWops *ctx); int Android_JNI_FileClose(SDL_RWops *ctx);
/* Environment support */ /* Environment support */

View file

@ -504,12 +504,12 @@ SDL3_0.0.0 {
SDL_RWtell; SDL_RWtell;
SDL_RWwrite; SDL_RWwrite;
SDL_RaiseWindow; SDL_RaiseWindow;
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_ReadU8; SDL_ReadU8;
SDL_RegisterApp; SDL_RegisterApp;
SDL_RegisterEvents; SDL_RegisterEvents;
@ -676,12 +676,12 @@ SDL3_0.0.0 {
SDL_WinRTGetDeviceFamily; SDL_WinRTGetDeviceFamily;
SDL_WinRTGetFSPathUNICODE; SDL_WinRTGetFSPathUNICODE;
SDL_WinRTGetFSPathUTF8; SDL_WinRTGetFSPathUTF8;
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_WriteU8; SDL_WriteU8;
SDL_abs; SDL_abs;
SDL_acos; SDL_acos;
@ -888,6 +888,17 @@ SDL3_0.0.0 {
SDL_IsAudioDevicePaused; SDL_IsAudioDevicePaused;
SDL_GetAudioStreamBinding; SDL_GetAudioStreamBinding;
SDL_ShowWindowSystemMenu; 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) # extra symbols go here (don't modify this line)
local: *; local: *;
}; };

View file

@ -528,12 +528,12 @@
#define SDL_RWtell SDL_RWtell_REAL #define SDL_RWtell SDL_RWtell_REAL
#define SDL_RWwrite SDL_RWwrite_REAL #define SDL_RWwrite SDL_RWwrite_REAL
#define SDL_RaiseWindow SDL_RaiseWindow_REAL #define SDL_RaiseWindow SDL_RaiseWindow_REAL
#define SDL_ReadBE16 SDL_ReadBE16_REAL #define SDL_ReadU16BE SDL_ReadU16BE_REAL
#define SDL_ReadBE32 SDL_ReadBE32_REAL #define SDL_ReadU32BE SDL_ReadU32BE_REAL
#define SDL_ReadBE64 SDL_ReadBE64_REAL #define SDL_ReadU64BE SDL_ReadU64BE_REAL
#define SDL_ReadLE16 SDL_ReadLE16_REAL #define SDL_ReadU16LE SDL_ReadU16LE_REAL
#define SDL_ReadLE32 SDL_ReadLE32_REAL #define SDL_ReadU32LE SDL_ReadU32LE_REAL
#define SDL_ReadLE64 SDL_ReadLE64_REAL #define SDL_ReadU64LE SDL_ReadU64LE_REAL
#define SDL_ReadU8 SDL_ReadU8_REAL #define SDL_ReadU8 SDL_ReadU8_REAL
#define SDL_RegisterApp SDL_RegisterApp_REAL #define SDL_RegisterApp SDL_RegisterApp_REAL
#define SDL_RegisterEvents SDL_RegisterEvents_REAL #define SDL_RegisterEvents SDL_RegisterEvents_REAL
@ -699,12 +699,12 @@
#define SDL_WinRTGetDeviceFamily SDL_WinRTGetDeviceFamily_REAL #define SDL_WinRTGetDeviceFamily SDL_WinRTGetDeviceFamily_REAL
#define SDL_WinRTGetFSPathUNICODE SDL_WinRTGetFSPathUNICODE_REAL #define SDL_WinRTGetFSPathUNICODE SDL_WinRTGetFSPathUNICODE_REAL
#define SDL_WinRTGetFSPathUTF8 SDL_WinRTGetFSPathUTF8_REAL #define SDL_WinRTGetFSPathUTF8 SDL_WinRTGetFSPathUTF8_REAL
#define SDL_WriteBE16 SDL_WriteBE16_REAL #define SDL_WriteU16BE SDL_WriteU16BE_REAL
#define SDL_WriteBE32 SDL_WriteBE32_REAL #define SDL_WriteU32BE SDL_WriteU32BE_REAL
#define SDL_WriteBE64 SDL_WriteBE64_REAL #define SDL_WriteU64BE SDL_WriteU64BE_REAL
#define SDL_WriteLE16 SDL_WriteLE16_REAL #define SDL_WriteU16LE SDL_WriteU16LE_REAL
#define SDL_WriteLE32 SDL_WriteLE32_REAL #define SDL_WriteU32LE SDL_WriteU32LE_REAL
#define SDL_WriteLE64 SDL_WriteLE64_REAL #define SDL_WriteU64LE SDL_WriteU64LE_REAL
#define SDL_WriteU8 SDL_WriteU8_REAL #define SDL_WriteU8 SDL_WriteU8_REAL
#define SDL_abs SDL_abs_REAL #define SDL_abs SDL_abs_REAL
#define SDL_acos SDL_acos_REAL #define SDL_acos SDL_acos_REAL
@ -913,3 +913,14 @@
#define SDL_IsAudioDevicePaused SDL_IsAudioDevicePaused_REAL #define SDL_IsAudioDevicePaused SDL_IsAudioDevicePaused_REAL
#define SDL_GetAudioStreamBinding SDL_GetAudioStreamBinding_REAL #define SDL_GetAudioStreamBinding SDL_GetAudioStreamBinding_REAL
#define SDL_ShowWindowSystemMenu SDL_ShowWindowSystemMenu_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

View file

@ -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(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_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(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(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) 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_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(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(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_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_RWsize,(SDL_RWops *a),(a),return)
SDL_DYNAPI_PROC(Sint64,SDL_RWtell,(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(int,SDL_RaiseWindow,(SDL_Window *a),(a),return)
SDL_DYNAPI_PROC(Uint16,SDL_ReadBE16,(SDL_RWops *a),(a),return) SDL_DYNAPI_PROC(SDL_bool,SDL_ReadU16BE,(SDL_RWops *a, Uint16 *b),(a,b),return)
SDL_DYNAPI_PROC(Uint32,SDL_ReadBE32,(SDL_RWops *a),(a),return) SDL_DYNAPI_PROC(SDL_bool,SDL_ReadU32BE,(SDL_RWops *a, Uint32 *b),(a,b),return)
SDL_DYNAPI_PROC(Uint64,SDL_ReadBE64,(SDL_RWops *a),(a),return) SDL_DYNAPI_PROC(SDL_bool,SDL_ReadU64BE,(SDL_RWops *a, Uint64 *b),(a,b),return)
SDL_DYNAPI_PROC(Uint16,SDL_ReadLE16,(SDL_RWops *a),(a),return) SDL_DYNAPI_PROC(SDL_bool,SDL_ReadU16LE,(SDL_RWops *a, Uint16 *b),(a,b),return)
SDL_DYNAPI_PROC(Uint32,SDL_ReadLE32,(SDL_RWops *a),(a),return) SDL_DYNAPI_PROC(SDL_bool,SDL_ReadU32LE,(SDL_RWops *a, Uint32 *b),(a,b),return)
SDL_DYNAPI_PROC(Uint64,SDL_ReadLE64,(SDL_RWops *a),(a),return) SDL_DYNAPI_PROC(SDL_bool,SDL_ReadU64LE,(SDL_RWops *a, Uint64 *b),(a,b),return)
SDL_DYNAPI_PROC(Uint8,SDL_ReadU8,(SDL_RWops *a),(a),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(Uint32,SDL_RegisterEvents,(int a),(a),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_RemoveTimer,(SDL_TimerID 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) 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(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(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,(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_ScreenKeyboardShown,(SDL_Window *a),(a),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_ScreenSaverEnabled,(void),(),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) 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(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(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(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(SDL_bool,SDL_WriteU16BE,(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(SDL_bool,SDL_WriteU32BE,(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(SDL_bool,SDL_WriteU64BE,(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(SDL_bool,SDL_WriteU16LE,(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(SDL_bool,SDL_WriteU32LE,(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(SDL_bool,SDL_WriteU64LE,(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_WriteU8,(SDL_RWops *a, Uint8 b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_abs,(int a),(a),return) SDL_DYNAPI_PROC(int,SDL_abs,(int a),(a),return)
SDL_DYNAPI_PROC(double,SDL_acos,(double a),(a),return) SDL_DYNAPI_PROC(double,SDL_acos,(double a),(a),return)
SDL_DYNAPI_PROC(float,SDL_acosf,(float 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_bool,SDL_IsAudioDevicePaused,(SDL_AudioDeviceID a),(a),return)
SDL_DYNAPI_PROC(SDL_AudioDeviceID,SDL_GetAudioStreamBinding,(SDL_AudioStream *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(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)

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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