Added SDL_OpenFileStorage() for local file storage

main
Sam Lantinga 2024-03-16 09:08:00 -07:00
parent ee0a23c7ab
commit ec3ba387d1
7 changed files with 78 additions and 5 deletions

View File

@ -85,8 +85,8 @@ extern DECLSPEC SDL_Storage *SDLCALL SDL_OpenTitleStorage(const char *override,
* *
* While title storage can generally be kept open throughout runtime, user * While title storage can generally be kept open throughout runtime, user
* storage should only be opened when the client is ready to read/write files. * storage should only be opened when the client is ready to read/write files.
* This allows the backend to properly batch R/W operations and flush them * This allows the backend to properly batch file operations and flush them when
* when the container has been closed; ensuring safe and optimal save I/O. * the container has been closed; ensuring safe and optimal save I/O.
* *
* \param org the name of your organization * \param org the name of your organization
* \param app the name of your application * \param app the name of your application
@ -107,6 +107,26 @@ extern DECLSPEC SDL_Storage *SDLCALL SDL_OpenTitleStorage(const char *override,
*/ */
extern DECLSPEC SDL_Storage *SDLCALL SDL_OpenUserStorage(const char *org, const char *app, SDL_PropertiesID props); extern DECLSPEC SDL_Storage *SDLCALL SDL_OpenUserStorage(const char *org, const char *app, SDL_PropertiesID props);
/**
* Opens up a container for local filesystem storage.
*
* This is provided for development and tools. Portable applications should use SDL_OpenTitleStorage() for access to game data and SDL_OpenUserStorage() for access to user data.
*
* \param path the base path prepended to all storage paths, or NULL for no base path
* \returns a filesystem storage container on success or NULL on failure; call SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_OpenStorage
* \sa SDL_CloseStorage
* \sa SDL_StorageReady
* \sa SDL_GetStorageFileSize
* \sa SDL_ReadStorageFile
* \sa SDL_WriteStorageFile
* \sa SDL_GetStorageSpaceRemaining
*/
extern DECLSPEC SDL_Storage *SDLCALL SDL_OpenFileStorage(const char *path);
/** /**
* Opens up a container using a client-provided storage interface. * Opens up a container using a client-provided storage interface.
* *

View File

@ -993,6 +993,7 @@ SDL3_0.0.0 {
SDL_RenamePath; SDL_RenamePath;
SDL_GetPathInfo; SDL_GetPathInfo;
SDL_FileTimeToWindows; SDL_FileTimeToWindows;
SDL_OpenFileStorage;
# extra symbols go here (don't modify this line) # extra symbols go here (don't modify this line)
local: *; local: *;
}; };

View File

@ -1018,3 +1018,4 @@
#define SDL_RenamePath SDL_RenamePath_REAL #define SDL_RenamePath SDL_RenamePath_REAL
#define SDL_GetPathInfo SDL_GetPathInfo_REAL #define SDL_GetPathInfo SDL_GetPathInfo_REAL
#define SDL_FileTimeToWindows SDL_FileTimeToWindows_REAL #define SDL_FileTimeToWindows SDL_FileTimeToWindows_REAL
#define SDL_OpenFileStorage SDL_OpenFileStorage_REAL

View File

@ -1043,3 +1043,4 @@ SDL_DYNAPI_PROC(int,SDL_RemovePath,(const char *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_RenamePath,(const char *a, const char *b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_RenamePath,(const char *a, const char *b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_GetPathInfo,(const char *a, SDL_PathInfo *b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_GetPathInfo,(const char *a, SDL_PathInfo *b),(a,b),return)
SDL_DYNAPI_PROC(void,SDL_FileTimeToWindows,(Sint64 a, Uint32 *b, Uint32 *c),(a,b,c),) SDL_DYNAPI_PROC(void,SDL_FileTimeToWindows,(Sint64 a, Uint32 *b, Uint32 *c),(a,b,c),)
SDL_DYNAPI_PROC(SDL_Storage*,SDL_OpenFileStorage,(const char *a),(a),return)

View File

@ -137,6 +137,11 @@ SDL_Storage *SDL_OpenUserStorage(const char *org, const char *app, SDL_Propertie
return storage; return storage;
} }
SDL_Storage *SDL_OpenFileStorage(const char *path)
{
return GENERIC_OpenFileStorage(path);
}
SDL_Storage *SDL_OpenStorage(const SDL_StorageInterface *iface, void *userdata) SDL_Storage *SDL_OpenStorage(const SDL_StorageInterface *iface, void *userdata)
{ {
SDL_Storage *storage; SDL_Storage *storage;

View File

@ -46,4 +46,6 @@ extern TitleStorageBootStrap GENERIC_titlebootstrap;
extern UserStorageBootStrap GENERIC_userbootstrap; extern UserStorageBootStrap GENERIC_userbootstrap;
extern UserStorageBootStrap STEAM_userbootstrap; extern UserStorageBootStrap STEAM_userbootstrap;
extern SDL_Storage *GENERIC_OpenFileStorage(const char *path);
#endif /* SDL_sysstorage_h_ */ #endif /* SDL_sysstorage_h_ */

View File

@ -25,10 +25,16 @@
static char *GENERIC_INTERNAL_CreateFullPath(const char *base, const char *relative) static char *GENERIC_INTERNAL_CreateFullPath(const char *base, const char *relative)
{ {
size_t fulllen = SDL_strlen(base) + SDL_strlen(relative) + 1; size_t len = 0;
char *result = (char*) SDL_malloc(fulllen);
if (base) {
len += SDL_strlen(base);
}
len += SDL_strlen(relative) + 1;
char *result = (char*) SDL_malloc(len);
if (result != NULL) { if (result != NULL) {
SDL_snprintf(result, fulllen, "%s%s", base, relative); SDL_snprintf(result, len, "%s%s", base, relative);
} }
return result; return result;
} }
@ -186,3 +192,40 @@ UserStorageBootStrap GENERIC_userbootstrap = {
"SDL generic user storage driver", "SDL generic user storage driver",
GENERIC_User_Create GENERIC_User_Create
}; };
static const SDL_StorageInterface GENERIC_file_iface = {
GENERIC_StorageClose,
GENERIC_StorageReady,
GENERIC_StorageFileSize,
GENERIC_StorageReadFile,
GENERIC_StorageWriteFile,
GENERIC_StorageSpaceRemaining
};
SDL_Storage *GENERIC_OpenFileStorage(const char *path)
{
SDL_Storage *result;
size_t len = 0;
char *basepath = NULL;
if (path) {
len += SDL_strlen(path);
}
if (len > 0) {
if (path[len-1] == '/') {
basepath = SDL_strdup(path);
if (!basepath) {
return NULL;
}
} else {
if (SDL_asprintf(&basepath, "%s/", path) < 0) {
return NULL;
}
}
}
result = SDL_OpenStorage(&GENERIC_file_iface, basepath);
if (result == NULL) {
SDL_free(basepath);
}
return result;
}