Added filesystem operations to SDL_Storage

This commit is contained in:
Sam Lantinga
2024-03-17 08:39:43 -07:00
parent 7a088527c1
commit f460f42e70
4 changed files with 355 additions and 113 deletions
+88 -7
View File
@@ -29,7 +29,7 @@
#define SDL_storage_h_
#include <SDL3/SDL_stdinc.h>
#include <SDL3/SDL_mutex.h>
#include <SDL3/SDL_filesystem.h>
#include <SDL3/SDL_properties.h>
#include <SDL3/SDL_begin_code.h>
@@ -43,17 +43,36 @@ extern "C" {
typedef struct SDL_StorageInterface
{
/* Called when the storage is closed */
int (SDLCALL *close)(void *userdata);
/* Optional, returns whether the storage is currently ready for access */
SDL_bool (SDLCALL *ready)(void *userdata);
int (SDLCALL *fileSize)(void *userdata, const char *path, Uint64 *length);
/* Enumerate a directory, optional for write-only storage */
int (SDLCALL *enumerate)(void *userdata, const char *path, SDL_EnumerateDirectoryCallback callback, void *callback_userdata);
int (SDLCALL *readFile)(void *userdata, const char *path, void *destination, Uint64 length);
/* Get path information, optional for write-only storage */
int (SDLCALL *info)(void *userdata, const char *path, SDL_PathInfo *info);
int (SDLCALL *writeFile)(void *userdata, const char *path, const void *source, Uint64 length);
/* Read a file from storage, optional for write-only storage */
int (SDLCALL *read_file)(void *userdata, const char *path, void *destination, Uint64 length);
/* Write a file to storage, optional for read-only storage */
int (SDLCALL *write_file)(void *userdata, const char *path, const void *source, Uint64 length);
/* Create a directory, optional for read-only storage */
int (SDLCALL *mkdir)(void *userdata, const char *path);
/* Remove a file or empty directory, optional for read-only storage */
int (SDLCALL *remove)(void *userdata, const char *path);
/* Rename a path, optional for read-only storage */
int (SDLCALL *rename)(void *userdata, const char *oldpath, const char *newpath);
/* Get the space remaining, optional for read-only storage */
Uint64 (SDLCALL *space_remaining)(void *userdata);
Uint64 (SDLCALL *spaceRemaining)(void *userdata);
} SDL_StorageInterface;
typedef struct SDL_Storage SDL_Storage;
@@ -267,6 +286,70 @@ extern DECLSPEC int SDLCALL SDL_ReadStorageFile(SDL_Storage *storage, const char
*/
extern DECLSPEC int SDL_WriteStorageFile(SDL_Storage *storage, const char *path, const void *source, Uint64 length);
/**
* Create a directory in a writable storage container.
*
* \param storage a storage container
* \param path the path of the directory to create
* \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*/
extern DECLSPEC int SDLCALL SDL_CreateStorageDirectory(SDL_Storage *storage, const char *path);
/**
* Enumerate a directory in a storage container.
*
* \param storage a storage container
* \param path the path of the directory to enumerate
* \param callback a function that is called for each entry in the directory
* \param userdata a pointer that is passed to `callback`
* \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*/
extern DECLSPEC int SDLCALL SDL_EnumerateStorageDirectory(SDL_Storage *storage, const char *path, SDL_EnumerateDirectoryCallback callback, void *userdata);
/**
* Remove a file or an empty directory in a writable storage container.
*
* \param storage a storage container
* \param path the path of the directory to enumerate
* \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*/
extern DECLSPEC int SDLCALL SDL_RemoveStoragePath(SDL_Storage *storage, const char *path);
/**
* Rename a file or directory in a writable storage container.
*
* \param storage a storage container
* \param oldpath the old path
* \param newpath the new path
* \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*/
extern DECLSPEC int SDLCALL SDL_RenameStoragePath(SDL_Storage *storage, const char *oldpath, const char *newpath);
/**
* Get information about a filesystem path in a storage container.
*
* \param storage a storage container
* \param path the path to query
* \param info a pointer filled in with information about the path
* \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*/
extern DECLSPEC int SDLCALL SDL_GetStoragePathInfo(SDL_Storage *storage, const char *path, SDL_PathInfo *info);
/**
* Queries the remaining space in a storage container.
*
@@ -282,9 +365,7 @@ extern DECLSPEC int SDL_WriteStorageFile(SDL_Storage *storage, const char *path,
* \sa SDL_StorageReady
* \sa SDL_GetStorageFileSize
* \sa SDL_ReadStorageFile
* \sa SDL_ReadStorageFileAsync
* \sa SDL_WriteStorageFile
* \sa SDL_WriteStorageFileAsync
*/
extern DECLSPEC Uint64 SDLCALL SDL_GetStorageSpaceRemaining(SDL_Storage *storage);
+104 -12
View File
@@ -152,7 +152,7 @@ SDL_Storage *SDL_OpenStorage(const SDL_StorageInterface *iface, void *userdata)
}
storage = (SDL_Storage*) SDL_malloc(sizeof(SDL_Storage));
if (storage == NULL) {
if (!storage) {
SDL_OutOfMemory();
return NULL;
}
@@ -185,41 +185,133 @@ SDL_bool SDL_StorageReady(SDL_Storage *storage)
int SDL_GetStorageFileSize(SDL_Storage *storage, const char *path, Uint64 *length)
{
CHECK_STORAGE_MAGIC()
SDL_PathInfo info;
return storage->iface.fileSize(storage->userdata, path, length);
if (SDL_GetStoragePathInfo(storage, path, &info) < 0) {
return -1;
}
if (length) {
*length = info.size;
}
return 0;
}
int SDL_ReadStorageFile(SDL_Storage *storage, const char *path, void *destination, Uint64 length)
{
CHECK_STORAGE_MAGIC()
if (storage->iface.readFile == NULL) {
return SDL_SetError("Storage container does not have read capability");
if (!path) {
return SDL_InvalidParamError("path");
}
return storage->iface.readFile(storage->userdata, path, destination, length);
if (!storage->iface.read_file) {
return SDL_Unsupported();
}
return storage->iface.read_file(storage->userdata, path, destination, length);
}
int SDL_WriteStorageFile(SDL_Storage *storage, const char *path, const void *source, Uint64 length)
{
CHECK_STORAGE_MAGIC()
if (storage->iface.writeFile == NULL) {
return SDL_SetError("Storage container does not have write capability");
if (!path) {
return SDL_InvalidParamError("path");
}
return storage->iface.writeFile(storage->userdata, path, source, length);
if (!storage->iface.write_file) {
return SDL_Unsupported();
}
return storage->iface.write_file(storage->userdata, path, source, length);
}
int SDL_CreateStorageDirectory(SDL_Storage *storage, const char *path)
{
CHECK_STORAGE_MAGIC()
if (!path) {
return SDL_InvalidParamError("path");
}
if (!storage->iface.mkdir) {
return SDL_Unsupported();
}
return storage->iface.mkdir(storage->userdata, path);
}
int SDL_EnumerateStorageDirectory(SDL_Storage *storage, const char *path, SDL_EnumerateDirectoryCallback callback, void *userdata)
{
CHECK_STORAGE_MAGIC()
if (!path) {
return SDL_InvalidParamError("path");
}
if (!storage->iface.enumerate) {
return SDL_Unsupported();
}
return storage->iface.enumerate(storage->userdata, path, callback, userdata);
}
int SDL_RemoveStoragePath(SDL_Storage *storage, const char *path)
{
CHECK_STORAGE_MAGIC()
if (!path) {
return SDL_InvalidParamError("path");
}
if (!storage->iface.remove) {
return SDL_Unsupported();
}
return storage->iface.remove(storage->userdata, path);
}
int SDL_RenameStoragePath(SDL_Storage *storage, const char *oldpath, const char *newpath)
{
CHECK_STORAGE_MAGIC()
if (!oldpath) {
return SDL_InvalidParamError("oldpath");
}
if (!newpath) {
return SDL_InvalidParamError("newpath");
}
if (!storage->iface.rename) {
return SDL_Unsupported();
}
return storage->iface.rename(storage->userdata, oldpath, newpath);
}
int SDL_GetStoragePathInfo(SDL_Storage *storage, const char *path, SDL_PathInfo *info)
{
CHECK_STORAGE_MAGIC()
if (!path) {
return SDL_InvalidParamError("path");
}
if (!storage->iface.info) {
return SDL_Unsupported();
}
return storage->iface.info(storage->userdata, path, info);
}
Uint64 SDL_GetStorageSpaceRemaining(SDL_Storage *storage)
{
CHECK_STORAGE_MAGIC_RET(0)
if (storage->iface.spaceRemaining == NULL) {
SDL_SetError("Storage container does not have write capability");
if (!storage->iface.space_remaining) {
SDL_Unsupported();
return 0;
}
return storage->iface.spaceRemaining(storage->userdata);
return storage->iface.space_remaining(storage->userdata);
}
File diff suppressed because it is too large Load Diff
+36 -19
View File
@@ -40,7 +40,7 @@ typedef struct STEAM_RemoteStorage
#include "SDL_steamstorage_proc.h"
} STEAM_RemoteStorage;
static int STEAM_UserStorageClose(void *userdata)
static int STEAM_CloseStorage(void *userdata)
{
int result = 0;
STEAM_RemoteStorage *steam = (STEAM_RemoteStorage*) userdata;
@@ -55,25 +55,30 @@ static int STEAM_UserStorageClose(void *userdata)
return result;
}
static SDL_bool STEAM_UserStorageReady(void *userdata)
static SDL_bool STEAM_StorageReady(void *userdata)
{
return SDL_TRUE;
}
static int STEAM_UserStorageFileSize(void *userdata, const char *path, Uint64 *length)
static int STEAM_GetStoragePathInfo(void *userdata, const char *path, SDL_PathInfo *info)
{
STEAM_RemoteStorage *steam = (STEAM_RemoteStorage*) userdata;
void *steamremotestorage = steam->SteamAPI_SteamRemoteStorage_v016();
if (steamremotestorage == NULL) {
return SDL_SetError("SteamRemoteStorage unavailable");
}
*length = steam->SteamAPI_ISteamRemoteStorage_GetFileSize(steamremotestorage, path);
if (info) {
SDL_zerop(info);
info->type = SDL_PATHTYPE_FILE;
info->size = steam->SteamAPI_ISteamRemoteStorage_GetFileSize(steamremotestorage, path);
}
return 0;
}
static int STEAM_UserStorageReadFile(void *userdata, const char *path, void *destination, Uint64 length)
static int STEAM_ReadStorageFile(void *userdata, const char *path, void *destination, Uint64 length)
{
int retval;
int result = -1;
STEAM_RemoteStorage *steam = (STEAM_RemoteStorage*) userdata;
void *steamremotestorage = steam->SteamAPI_SteamRemoteStorage_v016();
if (steamremotestorage == NULL) {
@@ -82,13 +87,17 @@ static int STEAM_UserStorageReadFile(void *userdata, const char *path, void *des
if (length > SDL_MAX_SINT32) {
return SDL_SetError("SteamRemoteStorage only supports INT32_MAX read size");
}
retval = steam->SteamAPI_ISteamRemoteStorage_FileRead(steamremotestorage, path, destination, (Sint32) length) == length;
return retval - 1;
if (steam->SteamAPI_ISteamRemoteStorage_FileRead(steamremotestorage, path, destination, (Sint32) length) == length) {
result = 0;
} else {
SDL_SetError("SteamAPI_ISteamRemoteStorage_FileRead() failed");
}
return result;
}
static int STEAM_UserStorageWriteFile(void *userdata, const char *path, const void *source, Uint64 length)
static int STEAM_WriteStorageFile(void *userdata, const char *path, const void *source, Uint64 length)
{
int retval;
int result = -1;
STEAM_RemoteStorage *steam = (STEAM_RemoteStorage*) userdata;
void *steamremotestorage = steam->SteamAPI_SteamRemoteStorage_v016();
if (steamremotestorage == NULL) {
@@ -97,11 +106,15 @@ static int STEAM_UserStorageWriteFile(void *userdata, const char *path, const vo
if (length > SDL_MAX_SINT32) {
return SDL_SetError("SteamRemoteStorage only supports INT32_MAX write size");
}
retval = steam->SteamAPI_ISteamRemoteStorage_FileWrite(steamremotestorage, path, source, (Sint32) length) == length;
return retval - 1;
if (steam->SteamAPI_ISteamRemoteStorage_FileWrite(steamremotestorage, path, source, (Sint32) length) == length) {
result = 0;
} else {
SDL_SetError("SteamAPI_ISteamRemoteStorage_FileRead() failed");
}
return result;
}
static Uint64 STEAM_UserStorageSpaceRemaining(void *userdata)
static Uint64 STEAM_GetStorageSpaceRemaining(void *userdata)
{
Uint64 total, remaining;
STEAM_RemoteStorage *steam = (STEAM_RemoteStorage*) userdata;
@@ -118,12 +131,16 @@ static Uint64 STEAM_UserStorageSpaceRemaining(void *userdata)
}
static const SDL_StorageInterface STEAM_user_iface = {
STEAM_UserStorageClose,
STEAM_UserStorageReady,
STEAM_UserStorageFileSize,
STEAM_UserStorageReadFile,
STEAM_UserStorageWriteFile,
STEAM_UserStorageSpaceRemaining
STEAM_CloseStorage,
STEAM_StorageReady,
NULL, /* enumerate */
STEAM_GetStoragePathInfo,
STEAM_ReadStorageFile,
STEAM_WriteStorageFile,
NULL, /* mkdir */
NULL, /* remove */
NULL, /* rename */
STEAM_GetStorageSpaceRemaining
};
static SDL_Storage *STEAM_User_Create(const char *org, const char *app, SDL_PropertiesID props)