diff options
author | 3gg <3gg@shellblade.net> | 2025-08-30 16:53:58 -0700 |
---|---|---|
committer | 3gg <3gg@shellblade.net> | 2025-08-30 16:53:58 -0700 |
commit | 6aaedb813fa11ba0679c3051bc2eb28646b9506c (patch) | |
tree | 34acbfc9840e02cb4753e6306ea7ce978bf8b58e /src/contrib/SDL-3.2.20/include/SDL3/SDL_storage.h | |
parent | 8f228ade99dd3d4c8da9b78ade1815c9adf85c8f (diff) |
Update to SDL3
Diffstat (limited to 'src/contrib/SDL-3.2.20/include/SDL3/SDL_storage.h')
-rw-r--r-- | src/contrib/SDL-3.2.20/include/SDL3/SDL_storage.h | 682 |
1 files changed, 682 insertions, 0 deletions
diff --git a/src/contrib/SDL-3.2.20/include/SDL3/SDL_storage.h b/src/contrib/SDL-3.2.20/include/SDL3/SDL_storage.h new file mode 100644 index 0000000..6837eba --- /dev/null +++ b/src/contrib/SDL-3.2.20/include/SDL3/SDL_storage.h | |||
@@ -0,0 +1,682 @@ | |||
1 | /* | ||
2 | Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
4 | |||
5 | This software is provided 'as-is', without any express or implied | ||
6 | warranty. In no event will the authors be held liable for any damages | ||
7 | arising from the use of this software. | ||
8 | |||
9 | Permission is granted to anyone to use this software for any purpose, | ||
10 | including commercial applications, and to alter it and redistribute it | ||
11 | freely, subject to the following restrictions: | ||
12 | |||
13 | 1. The origin of this software must not be misrepresented; you must not | ||
14 | claim that you wrote the original software. If you use this software | ||
15 | in a product, an acknowledgment in the product documentation would be | ||
16 | appreciated but is not required. | ||
17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
18 | misrepresented as being the original software. | ||
19 | 3. This notice may not be removed or altered from any source distribution. | ||
20 | */ | ||
21 | |||
22 | /** | ||
23 | * # CategoryStorage | ||
24 | * | ||
25 | * The storage API is a high-level API designed to abstract away the | ||
26 | * portability issues that come up when using something lower-level (in SDL's | ||
27 | * case, this sits on top of the [Filesystem](CategoryFilesystem) and | ||
28 | * [IOStream](CategoryIOStream) subsystems). It is significantly more | ||
29 | * restrictive than a typical filesystem API, for a number of reasons: | ||
30 | * | ||
31 | * 1. **What to Access:** A common pitfall with existing filesystem APIs is | ||
32 | * the assumption that all storage is monolithic. However, many other | ||
33 | * platforms (game consoles in particular) are more strict about what _type_ | ||
34 | * of filesystem is being accessed; for example, game content and user data | ||
35 | * are usually two separate storage devices with entirely different | ||
36 | * characteristics (and possibly different low-level APIs altogether!). | ||
37 | * | ||
38 | * 2. **How to Access:** Another common mistake is applications assuming that | ||
39 | * all storage is universally writeable - again, many platforms treat game | ||
40 | * content and user data as two separate storage devices, and only user data | ||
41 | * is writeable while game content is read-only. | ||
42 | * | ||
43 | * 3. **When to Access:** The most common portability issue with filesystem | ||
44 | * access is _timing_ - you cannot always assume that the storage device is | ||
45 | * always accessible all of the time, nor can you assume that there are no | ||
46 | * limits to how long you have access to a particular device. | ||
47 | * | ||
48 | * Consider the following example: | ||
49 | * | ||
50 | * ```c | ||
51 | * void ReadGameData(void) | ||
52 | * { | ||
53 | * extern char** fileNames; | ||
54 | * extern size_t numFiles; | ||
55 | * for (size_t i = 0; i < numFiles; i += 1) { | ||
56 | * FILE *data = fopen(fileNames[i], "rwb"); | ||
57 | * if (data == NULL) { | ||
58 | * // Something bad happened! | ||
59 | * } else { | ||
60 | * // A bunch of stuff happens here | ||
61 | * fclose(data); | ||
62 | * } | ||
63 | * } | ||
64 | * } | ||
65 | * | ||
66 | * void ReadSave(void) | ||
67 | * { | ||
68 | * FILE *save = fopen("saves/save0.sav", "rb"); | ||
69 | * if (save == NULL) { | ||
70 | * // Something bad happened! | ||
71 | * } else { | ||
72 | * // A bunch of stuff happens here | ||
73 | * fclose(save); | ||
74 | * } | ||
75 | * } | ||
76 | * | ||
77 | * void WriteSave(void) | ||
78 | * { | ||
79 | * FILE *save = fopen("saves/save0.sav", "wb"); | ||
80 | * if (save == NULL) { | ||
81 | * // Something bad happened! | ||
82 | * } else { | ||
83 | * // A bunch of stuff happens here | ||
84 | * fclose(save); | ||
85 | * } | ||
86 | * } | ||
87 | * ``` | ||
88 | * | ||
89 | * Going over the bullet points again: | ||
90 | * | ||
91 | * 1. **What to Access:** This code accesses a global filesystem; game data | ||
92 | * and saves are all presumed to be in the current working directory (which | ||
93 | * may or may not be the game's installation folder!). | ||
94 | * | ||
95 | * 2. **How to Access:** This code assumes that content paths are writeable, | ||
96 | * and that save data is also writeable despite being in the same location as | ||
97 | * the game data. | ||
98 | * | ||
99 | * 3. **When to Access:** This code assumes that they can be called at any | ||
100 | * time, since the filesystem is always accessible and has no limits on how | ||
101 | * long the filesystem is being accessed. | ||
102 | * | ||
103 | * Due to these assumptions, the filesystem code is not portable and will fail | ||
104 | * under these common scenarios: | ||
105 | * | ||
106 | * - The game is installed on a device that is read-only, both content loading | ||
107 | * and game saves will fail or crash outright | ||
108 | * - Game/User storage is not implicitly mounted, so no files will be found | ||
109 | * for either scenario when a platform requires explicitly mounting | ||
110 | * filesystems | ||
111 | * - Save data may not be safe since the I/O is not being flushed or | ||
112 | * validated, so an error occurring elsewhere in the program may result in | ||
113 | * missing/corrupted save data | ||
114 | * | ||
115 | * When using SDL_Storage, these types of problems are virtually impossible to | ||
116 | * trip over: | ||
117 | * | ||
118 | * ```c | ||
119 | * void ReadGameData(void) | ||
120 | * { | ||
121 | * extern char** fileNames; | ||
122 | * extern size_t numFiles; | ||
123 | * | ||
124 | * SDL_Storage *title = SDL_OpenTitleStorage(NULL, 0); | ||
125 | * if (title == NULL) { | ||
126 | * // Something bad happened! | ||
127 | * } | ||
128 | * while (!SDL_StorageReady(title)) { | ||
129 | * SDL_Delay(1); | ||
130 | * } | ||
131 | * | ||
132 | * for (size_t i = 0; i < numFiles; i += 1) { | ||
133 | * void* dst; | ||
134 | * Uint64 dstLen = 0; | ||
135 | * | ||
136 | * if (SDL_GetStorageFileSize(title, fileNames[i], &dstLen) && dstLen > 0) { | ||
137 | * dst = SDL_malloc(dstLen); | ||
138 | * if (SDL_ReadStorageFile(title, fileNames[i], dst, dstLen)) { | ||
139 | * // A bunch of stuff happens here | ||
140 | * } else { | ||
141 | * // Something bad happened! | ||
142 | * } | ||
143 | * SDL_free(dst); | ||
144 | * } else { | ||
145 | * // Something bad happened! | ||
146 | * } | ||
147 | * } | ||
148 | * | ||
149 | * SDL_CloseStorage(title); | ||
150 | * } | ||
151 | * | ||
152 | * void ReadSave(void) | ||
153 | * { | ||
154 | * SDL_Storage *user = SDL_OpenUserStorage("libsdl", "Storage Example", 0); | ||
155 | * if (user == NULL) { | ||
156 | * // Something bad happened! | ||
157 | * } | ||
158 | * while (!SDL_StorageReady(user)) { | ||
159 | * SDL_Delay(1); | ||
160 | * } | ||
161 | * | ||
162 | * Uint64 saveLen = 0; | ||
163 | * if (SDL_GetStorageFileSize(user, "save0.sav", &saveLen) && saveLen > 0) { | ||
164 | * void* dst = SDL_malloc(saveLen); | ||
165 | * if (SDL_ReadStorageFile(user, "save0.sav", dst, saveLen)) { | ||
166 | * // A bunch of stuff happens here | ||
167 | * } else { | ||
168 | * // Something bad happened! | ||
169 | * } | ||
170 | * SDL_free(dst); | ||
171 | * } else { | ||
172 | * // Something bad happened! | ||
173 | * } | ||
174 | * | ||
175 | * SDL_CloseStorage(user); | ||
176 | * } | ||
177 | * | ||
178 | * void WriteSave(void) | ||
179 | * { | ||
180 | * SDL_Storage *user = SDL_OpenUserStorage("libsdl", "Storage Example", 0); | ||
181 | * if (user == NULL) { | ||
182 | * // Something bad happened! | ||
183 | * } | ||
184 | * while (!SDL_StorageReady(user)) { | ||
185 | * SDL_Delay(1); | ||
186 | * } | ||
187 | * | ||
188 | * extern void *saveData; // A bunch of stuff happened here... | ||
189 | * extern Uint64 saveLen; | ||
190 | * if (!SDL_WriteStorageFile(user, "save0.sav", saveData, saveLen)) { | ||
191 | * // Something bad happened! | ||
192 | * } | ||
193 | * | ||
194 | * SDL_CloseStorage(user); | ||
195 | * } | ||
196 | * ``` | ||
197 | * | ||
198 | * Note the improvements that SDL_Storage makes: | ||
199 | * | ||
200 | * 1. **What to Access:** This code explicitly reads from a title or user | ||
201 | * storage device based on the context of the function. | ||
202 | * | ||
203 | * 2. **How to Access:** This code explicitly uses either a read or write | ||
204 | * function based on the context of the function. | ||
205 | * | ||
206 | * 3. **When to Access:** This code explicitly opens the device when it needs | ||
207 | * to, and closes it when it is finished working with the filesystem. | ||
208 | * | ||
209 | * The result is an application that is significantly more robust against the | ||
210 | * increasing demands of platforms and their filesystems! | ||
211 | * | ||
212 | * A publicly available example of an SDL_Storage backend is the | ||
213 | * [Steam Cloud](https://partner.steamgames.com/doc/features/cloud) | ||
214 | * backend - you can initialize Steamworks when starting the program, and then | ||
215 | * SDL will recognize that Steamworks is initialized and automatically use | ||
216 | * ISteamRemoteStorage when the application opens user storage. More | ||
217 | * importantly, when you _open_ storage it knows to begin a "batch" of | ||
218 | * filesystem operations, and when you _close_ storage it knows to end and | ||
219 | * flush the batch. This is used by Steam to support | ||
220 | * [Dynamic Cloud Sync](https://steamcommunity.com/groups/steamworks/announcements/detail/3142949576401813670) | ||
221 | * ; users can save data on one PC, put the device to sleep, and then continue | ||
222 | * playing on another PC (and vice versa) with the save data fully | ||
223 | * synchronized across all devices, allowing for a seamless experience without | ||
224 | * having to do full restarts of the program. | ||
225 | * | ||
226 | * ## Notes on valid paths | ||
227 | * | ||
228 | * All paths in the Storage API use Unix-style path separators ('/'). Using a | ||
229 | * different path separator will not work, even if the underlying platform | ||
230 | * would otherwise accept it. This is to keep code using the Storage API | ||
231 | * portable between platforms and Storage implementations and simplify app | ||
232 | * code. | ||
233 | * | ||
234 | * Paths with relative directories ("." and "..") are forbidden by the Storage | ||
235 | * API. | ||
236 | * | ||
237 | * All valid UTF-8 strings (discounting the NULL terminator character and the | ||
238 | * '/' path separator) are usable for filenames, however, an underlying | ||
239 | * Storage implementation may not support particularly strange sequences and | ||
240 | * refuse to create files with those names, etc. | ||
241 | */ | ||
242 | |||
243 | #ifndef SDL_storage_h_ | ||
244 | #define SDL_storage_h_ | ||
245 | |||
246 | #include <SDL3/SDL_stdinc.h> | ||
247 | #include <SDL3/SDL_error.h> | ||
248 | #include <SDL3/SDL_filesystem.h> | ||
249 | #include <SDL3/SDL_properties.h> | ||
250 | |||
251 | #include <SDL3/SDL_begin_code.h> | ||
252 | |||
253 | /* Set up for C function definitions, even when using C++ */ | ||
254 | #ifdef __cplusplus | ||
255 | extern "C" { | ||
256 | #endif | ||
257 | |||
258 | /** | ||
259 | * Function interface for SDL_Storage. | ||
260 | * | ||
261 | * Apps that want to supply a custom implementation of SDL_Storage will fill | ||
262 | * in all the functions in this struct, and then pass it to SDL_OpenStorage to | ||
263 | * create a custom SDL_Storage object. | ||
264 | * | ||
265 | * It is not usually necessary to do this; SDL provides standard | ||
266 | * implementations for many things you might expect to do with an SDL_Storage. | ||
267 | * | ||
268 | * This structure should be initialized using SDL_INIT_INTERFACE() | ||
269 | * | ||
270 | * \since This struct is available since SDL 3.2.0. | ||
271 | * | ||
272 | * \sa SDL_INIT_INTERFACE | ||
273 | */ | ||
274 | typedef struct SDL_StorageInterface | ||
275 | { | ||
276 | /* The version of this interface */ | ||
277 | Uint32 version; | ||
278 | |||
279 | /* Called when the storage is closed */ | ||
280 | bool (SDLCALL *close)(void *userdata); | ||
281 | |||
282 | /* Optional, returns whether the storage is currently ready for access */ | ||
283 | bool (SDLCALL *ready)(void *userdata); | ||
284 | |||
285 | /* Enumerate a directory, optional for write-only storage */ | ||
286 | bool (SDLCALL *enumerate)(void *userdata, const char *path, SDL_EnumerateDirectoryCallback callback, void *callback_userdata); | ||
287 | |||
288 | /* Get path information, optional for write-only storage */ | ||
289 | bool (SDLCALL *info)(void *userdata, const char *path, SDL_PathInfo *info); | ||
290 | |||
291 | /* Read a file from storage, optional for write-only storage */ | ||
292 | bool (SDLCALL *read_file)(void *userdata, const char *path, void *destination, Uint64 length); | ||
293 | |||
294 | /* Write a file to storage, optional for read-only storage */ | ||
295 | bool (SDLCALL *write_file)(void *userdata, const char *path, const void *source, Uint64 length); | ||
296 | |||
297 | /* Create a directory, optional for read-only storage */ | ||
298 | bool (SDLCALL *mkdir)(void *userdata, const char *path); | ||
299 | |||
300 | /* Remove a file or empty directory, optional for read-only storage */ | ||
301 | bool (SDLCALL *remove)(void *userdata, const char *path); | ||
302 | |||
303 | /* Rename a path, optional for read-only storage */ | ||
304 | bool (SDLCALL *rename)(void *userdata, const char *oldpath, const char *newpath); | ||
305 | |||
306 | /* Copy a file, optional for read-only storage */ | ||
307 | bool (SDLCALL *copy)(void *userdata, const char *oldpath, const char *newpath); | ||
308 | |||
309 | /* Get the space remaining, optional for read-only storage */ | ||
310 | Uint64 (SDLCALL *space_remaining)(void *userdata); | ||
311 | } SDL_StorageInterface; | ||
312 | |||
313 | /* Check the size of SDL_StorageInterface | ||
314 | * | ||
315 | * If this assert fails, either the compiler is padding to an unexpected size, | ||
316 | * or the interface has been updated and this should be updated to match and | ||
317 | * the code using this interface should be updated to handle the old version. | ||
318 | */ | ||
319 | SDL_COMPILE_TIME_ASSERT(SDL_StorageInterface_SIZE, | ||
320 | (sizeof(void *) == 4 && sizeof(SDL_StorageInterface) == 48) || | ||
321 | (sizeof(void *) == 8 && sizeof(SDL_StorageInterface) == 96)); | ||
322 | |||
323 | /** | ||
324 | * An abstract interface for filesystem access. | ||
325 | * | ||
326 | * This is an opaque datatype. One can create this object using standard SDL | ||
327 | * functions like SDL_OpenTitleStorage or SDL_OpenUserStorage, etc, or create | ||
328 | * an object with a custom implementation using SDL_OpenStorage. | ||
329 | * | ||
330 | * \since This struct is available since SDL 3.2.0. | ||
331 | */ | ||
332 | typedef struct SDL_Storage SDL_Storage; | ||
333 | |||
334 | /** | ||
335 | * Opens up a read-only container for the application's filesystem. | ||
336 | * | ||
337 | * \param override a path to override the backend's default title root. | ||
338 | * \param props a property list that may contain backend-specific information. | ||
339 | * \returns a title storage container on success or NULL on failure; call | ||
340 | * SDL_GetError() for more information. | ||
341 | * | ||
342 | * \since This function is available since SDL 3.2.0. | ||
343 | * | ||
344 | * \sa SDL_CloseStorage | ||
345 | * \sa SDL_GetStorageFileSize | ||
346 | * \sa SDL_OpenUserStorage | ||
347 | * \sa SDL_ReadStorageFile | ||
348 | */ | ||
349 | extern SDL_DECLSPEC SDL_Storage * SDLCALL SDL_OpenTitleStorage(const char *override, SDL_PropertiesID props); | ||
350 | |||
351 | /** | ||
352 | * Opens up a container for a user's unique read/write filesystem. | ||
353 | * | ||
354 | * While title storage can generally be kept open throughout runtime, user | ||
355 | * storage should only be opened when the client is ready to read/write files. | ||
356 | * This allows the backend to properly batch file operations and flush them | ||
357 | * when the container has been closed; ensuring safe and optimal save I/O. | ||
358 | * | ||
359 | * \param org the name of your organization. | ||
360 | * \param app the name of your application. | ||
361 | * \param props a property list that may contain backend-specific information. | ||
362 | * \returns a user storage container on success or NULL on failure; call | ||
363 | * SDL_GetError() for more information. | ||
364 | * | ||
365 | * \since This function is available since SDL 3.2.0. | ||
366 | * | ||
367 | * \sa SDL_CloseStorage | ||
368 | * \sa SDL_GetStorageFileSize | ||
369 | * \sa SDL_GetStorageSpaceRemaining | ||
370 | * \sa SDL_OpenTitleStorage | ||
371 | * \sa SDL_ReadStorageFile | ||
372 | * \sa SDL_StorageReady | ||
373 | * \sa SDL_WriteStorageFile | ||
374 | */ | ||
375 | extern SDL_DECLSPEC SDL_Storage * SDLCALL SDL_OpenUserStorage(const char *org, const char *app, SDL_PropertiesID props); | ||
376 | |||
377 | /** | ||
378 | * Opens up a container for local filesystem storage. | ||
379 | * | ||
380 | * This is provided for development and tools. Portable applications should | ||
381 | * use SDL_OpenTitleStorage() for access to game data and | ||
382 | * SDL_OpenUserStorage() for access to user data. | ||
383 | * | ||
384 | * \param path the base path prepended to all storage paths, or NULL for no | ||
385 | * base path. | ||
386 | * \returns a filesystem storage container on success or NULL on failure; call | ||
387 | * SDL_GetError() for more information. | ||
388 | * | ||
389 | * \since This function is available since SDL 3.2.0. | ||
390 | * | ||
391 | * \sa SDL_CloseStorage | ||
392 | * \sa SDL_GetStorageFileSize | ||
393 | * \sa SDL_GetStorageSpaceRemaining | ||
394 | * \sa SDL_OpenTitleStorage | ||
395 | * \sa SDL_OpenUserStorage | ||
396 | * \sa SDL_ReadStorageFile | ||
397 | * \sa SDL_WriteStorageFile | ||
398 | */ | ||
399 | extern SDL_DECLSPEC SDL_Storage * SDLCALL SDL_OpenFileStorage(const char *path); | ||
400 | |||
401 | /** | ||
402 | * Opens up a container using a client-provided storage interface. | ||
403 | * | ||
404 | * Applications do not need to use this function unless they are providing | ||
405 | * their own SDL_Storage implementation. If you just need an SDL_Storage, you | ||
406 | * should use the built-in implementations in SDL, like SDL_OpenTitleStorage() | ||
407 | * or SDL_OpenUserStorage(). | ||
408 | * | ||
409 | * This function makes a copy of `iface` and the caller does not need to keep | ||
410 | * it around after this call. | ||
411 | * | ||
412 | * \param iface the interface that implements this storage, initialized using | ||
413 | * SDL_INIT_INTERFACE(). | ||
414 | * \param userdata the pointer that will be passed to the interface functions. | ||
415 | * \returns a storage container on success or NULL on failure; call | ||
416 | * SDL_GetError() for more information. | ||
417 | * | ||
418 | * \since This function is available since SDL 3.2.0. | ||
419 | * | ||
420 | * \sa SDL_CloseStorage | ||
421 | * \sa SDL_GetStorageFileSize | ||
422 | * \sa SDL_GetStorageSpaceRemaining | ||
423 | * \sa SDL_INIT_INTERFACE | ||
424 | * \sa SDL_ReadStorageFile | ||
425 | * \sa SDL_StorageReady | ||
426 | * \sa SDL_WriteStorageFile | ||
427 | */ | ||
428 | extern SDL_DECLSPEC SDL_Storage * SDLCALL SDL_OpenStorage(const SDL_StorageInterface *iface, void *userdata); | ||
429 | |||
430 | /** | ||
431 | * Closes and frees a storage container. | ||
432 | * | ||
433 | * \param storage a storage container to close. | ||
434 | * \returns true if the container was freed with no errors, false otherwise; | ||
435 | * call SDL_GetError() for more information. Even if the function | ||
436 | * returns an error, the container data will be freed; the error is | ||
437 | * only for informational purposes. | ||
438 | * | ||
439 | * \since This function is available since SDL 3.2.0. | ||
440 | * | ||
441 | * \sa SDL_OpenFileStorage | ||
442 | * \sa SDL_OpenStorage | ||
443 | * \sa SDL_OpenTitleStorage | ||
444 | * \sa SDL_OpenUserStorage | ||
445 | */ | ||
446 | extern SDL_DECLSPEC bool SDLCALL SDL_CloseStorage(SDL_Storage *storage); | ||
447 | |||
448 | /** | ||
449 | * Checks if the storage container is ready to use. | ||
450 | * | ||
451 | * This function should be called in regular intervals until it returns true - | ||
452 | * however, it is not recommended to spinwait on this call, as the backend may | ||
453 | * depend on a synchronous message loop. You might instead poll this in your | ||
454 | * game's main loop while processing events and drawing a loading screen. | ||
455 | * | ||
456 | * \param storage a storage container to query. | ||
457 | * \returns true if the container is ready, false otherwise. | ||
458 | * | ||
459 | * \since This function is available since SDL 3.2.0. | ||
460 | */ | ||
461 | extern SDL_DECLSPEC bool SDLCALL SDL_StorageReady(SDL_Storage *storage); | ||
462 | |||
463 | /** | ||
464 | * Query the size of a file within a storage container. | ||
465 | * | ||
466 | * \param storage a storage container to query. | ||
467 | * \param path the relative path of the file to query. | ||
468 | * \param length a pointer to be filled with the file's length. | ||
469 | * \returns true if the file could be queried or false on failure; call | ||
470 | * SDL_GetError() for more information. | ||
471 | * | ||
472 | * \since This function is available since SDL 3.2.0. | ||
473 | * | ||
474 | * \sa SDL_ReadStorageFile | ||
475 | * \sa SDL_StorageReady | ||
476 | */ | ||
477 | extern SDL_DECLSPEC bool SDLCALL SDL_GetStorageFileSize(SDL_Storage *storage, const char *path, Uint64 *length); | ||
478 | |||
479 | /** | ||
480 | * Synchronously read a file from a storage container into a client-provided | ||
481 | * buffer. | ||
482 | * | ||
483 | * The value of `length` must match the length of the file exactly; call | ||
484 | * SDL_GetStorageFileSize() to get this value. This behavior may be relaxed in | ||
485 | * a future release. | ||
486 | * | ||
487 | * \param storage a storage container to read from. | ||
488 | * \param path the relative path of the file to read. | ||
489 | * \param destination a client-provided buffer to read the file into. | ||
490 | * \param length the length of the destination buffer. | ||
491 | * \returns true if the file was read or false on failure; call SDL_GetError() | ||
492 | * for more information. | ||
493 | * | ||
494 | * \since This function is available since SDL 3.2.0. | ||
495 | * | ||
496 | * \sa SDL_GetStorageFileSize | ||
497 | * \sa SDL_StorageReady | ||
498 | * \sa SDL_WriteStorageFile | ||
499 | */ | ||
500 | extern SDL_DECLSPEC bool SDLCALL SDL_ReadStorageFile(SDL_Storage *storage, const char *path, void *destination, Uint64 length); | ||
501 | |||
502 | /** | ||
503 | * Synchronously write a file from client memory into a storage container. | ||
504 | * | ||
505 | * \param storage a storage container to write to. | ||
506 | * \param path the relative path of the file to write. | ||
507 | * \param source a client-provided buffer to write from. | ||
508 | * \param length the length of the source buffer. | ||
509 | * \returns true if the file was written or false on failure; call | ||
510 | * SDL_GetError() for more information. | ||
511 | * | ||
512 | * \since This function is available since SDL 3.2.0. | ||
513 | * | ||
514 | * \sa SDL_GetStorageSpaceRemaining | ||
515 | * \sa SDL_ReadStorageFile | ||
516 | * \sa SDL_StorageReady | ||
517 | */ | ||
518 | extern SDL_DECLSPEC bool SDLCALL SDL_WriteStorageFile(SDL_Storage *storage, const char *path, const void *source, Uint64 length); | ||
519 | |||
520 | /** | ||
521 | * Create a directory in a writable storage container. | ||
522 | * | ||
523 | * \param storage a storage container. | ||
524 | * \param path the path of the directory to create. | ||
525 | * \returns true on success or false on failure; call SDL_GetError() for more | ||
526 | * information. | ||
527 | * | ||
528 | * \since This function is available since SDL 3.2.0. | ||
529 | * | ||
530 | * \sa SDL_StorageReady | ||
531 | */ | ||
532 | extern SDL_DECLSPEC bool SDLCALL SDL_CreateStorageDirectory(SDL_Storage *storage, const char *path); | ||
533 | |||
534 | /** | ||
535 | * Enumerate a directory in a storage container through a callback function. | ||
536 | * | ||
537 | * This function provides every directory entry through an app-provided | ||
538 | * callback, called once for each directory entry, until all results have been | ||
539 | * provided or the callback returns either SDL_ENUM_SUCCESS or | ||
540 | * SDL_ENUM_FAILURE. | ||
541 | * | ||
542 | * This will return false if there was a system problem in general, or if a | ||
543 | * callback returns SDL_ENUM_FAILURE. A successful return means a callback | ||
544 | * returned SDL_ENUM_SUCCESS to halt enumeration, or all directory entries | ||
545 | * were enumerated. | ||
546 | * | ||
547 | * If `path` is NULL, this is treated as a request to enumerate the root of | ||
548 | * the storage container's tree. An empty string also works for this. | ||
549 | * | ||
550 | * \param storage a storage container. | ||
551 | * \param path the path of the directory to enumerate, or NULL for the root. | ||
552 | * \param callback a function that is called for each entry in the directory. | ||
553 | * \param userdata a pointer that is passed to `callback`. | ||
554 | * \returns true on success or false on failure; call SDL_GetError() for more | ||
555 | * information. | ||
556 | * | ||
557 | * \since This function is available since SDL 3.2.0. | ||
558 | * | ||
559 | * \sa SDL_StorageReady | ||
560 | */ | ||
561 | extern SDL_DECLSPEC bool SDLCALL SDL_EnumerateStorageDirectory(SDL_Storage *storage, const char *path, SDL_EnumerateDirectoryCallback callback, void *userdata); | ||
562 | |||
563 | /** | ||
564 | * Remove a file or an empty directory in a writable storage container. | ||
565 | * | ||
566 | * \param storage a storage container. | ||
567 | * \param path the path of the directory to enumerate. | ||
568 | * \returns true on success or false on failure; call SDL_GetError() for more | ||
569 | * information. | ||
570 | * | ||
571 | * \since This function is available since SDL 3.2.0. | ||
572 | * | ||
573 | * \sa SDL_StorageReady | ||
574 | */ | ||
575 | extern SDL_DECLSPEC bool SDLCALL SDL_RemoveStoragePath(SDL_Storage *storage, const char *path); | ||
576 | |||
577 | /** | ||
578 | * Rename a file or directory in a writable storage container. | ||
579 | * | ||
580 | * \param storage a storage container. | ||
581 | * \param oldpath the old path. | ||
582 | * \param newpath the new path. | ||
583 | * \returns true on success or false on failure; call SDL_GetError() for more | ||
584 | * information. | ||
585 | * | ||
586 | * \since This function is available since SDL 3.2.0. | ||
587 | * | ||
588 | * \sa SDL_StorageReady | ||
589 | */ | ||
590 | extern SDL_DECLSPEC bool SDLCALL SDL_RenameStoragePath(SDL_Storage *storage, const char *oldpath, const char *newpath); | ||
591 | |||
592 | /** | ||
593 | * Copy a file in a writable storage container. | ||
594 | * | ||
595 | * \param storage a storage container. | ||
596 | * \param oldpath the old path. | ||
597 | * \param newpath the new path. | ||
598 | * \returns true on success or false on failure; call SDL_GetError() for more | ||
599 | * information. | ||
600 | * | ||
601 | * \since This function is available since SDL 3.2.0. | ||
602 | * | ||
603 | * \sa SDL_StorageReady | ||
604 | */ | ||
605 | extern SDL_DECLSPEC bool SDLCALL SDL_CopyStorageFile(SDL_Storage *storage, const char *oldpath, const char *newpath); | ||
606 | |||
607 | /** | ||
608 | * Get information about a filesystem path in a storage container. | ||
609 | * | ||
610 | * \param storage a storage container. | ||
611 | * \param path the path to query. | ||
612 | * \param info a pointer filled in with information about the path, or NULL to | ||
613 | * check for the existence of a file. | ||
614 | * \returns true on success or false if the file doesn't exist, or another | ||
615 | * failure; call SDL_GetError() for more information. | ||
616 | * | ||
617 | * \since This function is available since SDL 3.2.0. | ||
618 | * | ||
619 | * \sa SDL_StorageReady | ||
620 | */ | ||
621 | extern SDL_DECLSPEC bool SDLCALL SDL_GetStoragePathInfo(SDL_Storage *storage, const char *path, SDL_PathInfo *info); | ||
622 | |||
623 | /** | ||
624 | * Queries the remaining space in a storage container. | ||
625 | * | ||
626 | * \param storage a storage container to query. | ||
627 | * \returns the amount of remaining space, in bytes. | ||
628 | * | ||
629 | * \since This function is available since SDL 3.2.0. | ||
630 | * | ||
631 | * \sa SDL_StorageReady | ||
632 | * \sa SDL_WriteStorageFile | ||
633 | */ | ||
634 | extern SDL_DECLSPEC Uint64 SDLCALL SDL_GetStorageSpaceRemaining(SDL_Storage *storage); | ||
635 | |||
636 | /** | ||
637 | * Enumerate a directory tree, filtered by pattern, and return a list. | ||
638 | * | ||
639 | * Files are filtered out if they don't match the string in `pattern`, which | ||
640 | * may contain wildcard characters `*` (match everything) and `?` (match one | ||
641 | * character). If pattern is NULL, no filtering is done and all results are | ||
642 | * returned. Subdirectories are permitted, and are specified with a path | ||
643 | * separator of '/'. Wildcard characters `*` and `?` never match a path | ||
644 | * separator. | ||
645 | * | ||
646 | * `flags` may be set to SDL_GLOB_CASEINSENSITIVE to make the pattern matching | ||
647 | * case-insensitive. | ||
648 | * | ||
649 | * The returned array is always NULL-terminated, for your iterating | ||
650 | * convenience, but if `count` is non-NULL, on return it will contain the | ||
651 | * number of items in the array, not counting the NULL terminator. | ||
652 | * | ||
653 | * If `path` is NULL, this is treated as a request to enumerate the root of | ||
654 | * the storage container's tree. An empty string also works for this. | ||
655 | * | ||
656 | * \param storage a storage container. | ||
657 | * \param path the path of the directory to enumerate, or NULL for the root. | ||
658 | * \param pattern the pattern that files in the directory must match. Can be | ||
659 | * NULL. | ||
660 | * \param flags `SDL_GLOB_*` bitflags that affect this search. | ||
661 | * \param count on return, will be set to the number of items in the returned | ||
662 | * array. Can be NULL. | ||
663 | * \returns an array of strings on success or NULL on failure; call | ||
664 | * SDL_GetError() for more information. The caller should pass the | ||
665 | * returned pointer to SDL_free when done with it. This is a single | ||
666 | * allocation that should be freed with SDL_free() when it is no | ||
667 | * longer needed. | ||
668 | * | ||
669 | * \threadsafety It is safe to call this function from any thread, assuming | ||
670 | * the `storage` object is thread-safe. | ||
671 | * | ||
672 | * \since This function is available since SDL 3.2.0. | ||
673 | */ | ||
674 | extern SDL_DECLSPEC char ** SDLCALL SDL_GlobStorageDirectory(SDL_Storage *storage, const char *path, const char *pattern, SDL_GlobFlags flags, int *count); | ||
675 | |||
676 | /* Ends C function definitions when using C++ */ | ||
677 | #ifdef __cplusplus | ||
678 | } | ||
679 | #endif | ||
680 | #include <SDL3/SDL_close_code.h> | ||
681 | |||
682 | #endif /* SDL_storage_h_ */ | ||