1 | /* |
2 | Simple DirectMedia Layer |
3 | Copyright (C) 1997-2021 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 | * \file SDL_rwops.h |
24 | * |
25 | * This file provides a general interface for SDL to read and write |
26 | * data streams. It can easily be extended to files, memory, etc. |
27 | */ |
28 | |
29 | #ifndef SDL_rwops_h_ |
30 | #define SDL_rwops_h_ |
31 | |
32 | #include "SDL_stdinc.h" |
33 | #include "SDL_error.h" |
34 | |
35 | #include "begin_code.h" |
36 | /* Set up for C function definitions, even when using C++ */ |
37 | #ifdef __cplusplus |
38 | extern "C" { |
39 | #endif |
40 | |
41 | /* RWops Types */ |
42 | #define SDL_RWOPS_UNKNOWN 0U /**< Unknown stream type */ |
43 | #define SDL_RWOPS_WINFILE 1U /**< Win32 file */ |
44 | #define SDL_RWOPS_STDFILE 2U /**< Stdio file */ |
45 | #define SDL_RWOPS_JNIFILE 3U /**< Android asset */ |
46 | #define SDL_RWOPS_MEMORY 4U /**< Memory stream */ |
47 | #define SDL_RWOPS_MEMORY_RO 5U /**< Read-Only memory stream */ |
48 | #if defined(__VITA__) |
49 | #define SDL_RWOPS_VITAFILE 6U /**< Vita file */ |
50 | #endif |
51 | |
52 | /** |
53 | * This is the read/write operation structure -- very basic. |
54 | */ |
55 | typedef struct SDL_RWops |
56 | { |
57 | /** |
58 | * Return the size of the file in this rwops, or -1 if unknown |
59 | */ |
60 | Sint64 (SDLCALL * size) (struct SDL_RWops * context); |
61 | |
62 | /** |
63 | * Seek to \c offset relative to \c whence, one of stdio's whence values: |
64 | * RW_SEEK_SET, RW_SEEK_CUR, RW_SEEK_END |
65 | * |
66 | * \return the final offset in the data stream, or -1 on error. |
67 | */ |
68 | Sint64 (SDLCALL * seek) (struct SDL_RWops * context, Sint64 offset, |
69 | int whence); |
70 | |
71 | /** |
72 | * Read up to \c maxnum objects each of size \c size from the data |
73 | * stream to the area pointed at by \c ptr. |
74 | * |
75 | * \return the number of objects read, or 0 at error or end of file. |
76 | */ |
77 | size_t (SDLCALL * read) (struct SDL_RWops * context, void *ptr, |
78 | size_t size, size_t maxnum); |
79 | |
80 | /** |
81 | * Write exactly \c num objects each of size \c size from the area |
82 | * pointed at by \c ptr to data stream. |
83 | * |
84 | * \return the number of objects written, or 0 at error or end of file. |
85 | */ |
86 | size_t (SDLCALL * write) (struct SDL_RWops * context, const void *ptr, |
87 | size_t size, size_t num); |
88 | |
89 | /** |
90 | * Close and free an allocated SDL_RWops structure. |
91 | * |
92 | * \return 0 if successful or -1 on write error when flushing data. |
93 | */ |
94 | int (SDLCALL * close) (struct SDL_RWops * context); |
95 | |
96 | Uint32 type; |
97 | union |
98 | { |
99 | #if defined(__ANDROID__) |
100 | struct |
101 | { |
102 | void *asset; |
103 | } androidio; |
104 | #elif defined(__WIN32__) |
105 | struct |
106 | { |
107 | SDL_bool append; |
108 | void *h; |
109 | struct |
110 | { |
111 | void *data; |
112 | size_t size; |
113 | size_t left; |
114 | } buffer; |
115 | } windowsio; |
116 | #elif defined(__VITA__) |
117 | struct |
118 | { |
119 | int h; |
120 | struct |
121 | { |
122 | void *data; |
123 | size_t size; |
124 | size_t left; |
125 | } buffer; |
126 | } vitaio; |
127 | #endif |
128 | |
129 | #ifdef HAVE_STDIO_H |
130 | struct |
131 | { |
132 | SDL_bool autoclose; |
133 | FILE *fp; |
134 | } stdio; |
135 | #endif |
136 | struct |
137 | { |
138 | Uint8 *base; |
139 | Uint8 *here; |
140 | Uint8 *stop; |
141 | } mem; |
142 | struct |
143 | { |
144 | void *data1; |
145 | void *data2; |
146 | } unknown; |
147 | } hidden; |
148 | |
149 | } SDL_RWops; |
150 | |
151 | |
152 | /** |
153 | * \name RWFrom functions |
154 | * |
155 | * Functions to create SDL_RWops structures from various data streams. |
156 | */ |
157 | /* @{ */ |
158 | |
159 | extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromFile(const char *file, |
160 | const char *mode); |
161 | |
162 | #ifdef HAVE_STDIO_H |
163 | extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromFP(FILE * fp, |
164 | SDL_bool autoclose); |
165 | #else |
166 | extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromFP(void * fp, |
167 | SDL_bool autoclose); |
168 | #endif |
169 | |
170 | extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromMem(void *mem, int size); |
171 | extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromConstMem(const void *mem, |
172 | int size); |
173 | |
174 | /* @} *//* RWFrom functions */ |
175 | |
176 | |
177 | extern DECLSPEC SDL_RWops *SDLCALL SDL_AllocRW(void); |
178 | extern DECLSPEC void SDLCALL SDL_FreeRW(SDL_RWops * area); |
179 | |
180 | #define RW_SEEK_SET 0 /**< Seek from the beginning of data */ |
181 | #define RW_SEEK_CUR 1 /**< Seek relative to current read point */ |
182 | #define RW_SEEK_END 2 /**< Seek relative to the end of data */ |
183 | |
184 | /** |
185 | * Use this macro to get the size of the data stream in an SDL_RWops. |
186 | * |
187 | * \param context the SDL_RWops to get the size of the data stream from |
188 | * \returns the size of the data stream in the SDL_RWops on success, -1 if |
189 | * unknown or a negative error code on failure; call SDL_GetError() |
190 | * for more information. |
191 | * |
192 | * \since This function is available since SDL 2.0.0. |
193 | */ |
194 | extern DECLSPEC Sint64 SDLCALL SDL_RWsize(SDL_RWops *context); |
195 | |
196 | /** |
197 | * Seek within an SDL_RWops data stream. |
198 | * |
199 | * This function seeks to byte `offset`, relative to `whence`. |
200 | * |
201 | * `whence` may be any of the following values: |
202 | * |
203 | * - `RW_SEEK_SET`: seek from the beginning of data |
204 | * - `RW_SEEK_CUR`: seek relative to current read point |
205 | * - `RW_SEEK_END`: seek relative to the end of data |
206 | * |
207 | * If this stream can not seek, it will return -1. |
208 | * |
209 | * SDL_RWseek() is actually a wrapper function that calls the SDL_RWops's |
210 | * `seek` method appropriately, to simplify application development. |
211 | * |
212 | * \param context a pointer to an SDL_RWops structure |
213 | * \param offset an offset in bytes, relative to **whence** location; can be |
214 | * negative |
215 | * \param whence any of `RW_SEEK_SET`, `RW_SEEK_CUR`, `RW_SEEK_END` |
216 | * \returns the final offset in the data stream after the seek or -1 on error. |
217 | * |
218 | * \sa SDL_RWclose |
219 | * \sa SDL_RWFromConstMem |
220 | * \sa SDL_RWFromFile |
221 | * \sa SDL_RWFromFP |
222 | * \sa SDL_RWFromMem |
223 | * \sa SDL_RWread |
224 | * \sa SDL_RWtell |
225 | * \sa SDL_RWwrite |
226 | */ |
227 | extern DECLSPEC Sint64 SDLCALL SDL_RWseek(SDL_RWops *context, |
228 | Sint64 offset, int whence); |
229 | |
230 | /** |
231 | * Determine the current read/write offset in an SDL_RWops data stream. |
232 | * |
233 | * SDL_RWtell is actually a wrapper function that calls the SDL_RWops's |
234 | * `seek` method, with an offset of 0 bytes from `RW_SEEK_CUR`, to simplify |
235 | * application development. |
236 | * |
237 | * \param context a SDL_RWops data stream object from which to get the current |
238 | * offset |
239 | * \returns the current offset in the stream, or -1 if the information can not |
240 | * be determined. |
241 | * |
242 | * \sa SDL_RWclose |
243 | * \sa SDL_RWFromConstMem |
244 | * \sa SDL_RWFromFile |
245 | * \sa SDL_RWFromFP |
246 | * \sa SDL_RWFromMem |
247 | * \sa SDL_RWread |
248 | * \sa SDL_RWseek |
249 | * \sa SDL_RWwrite |
250 | */ |
251 | extern DECLSPEC Sint64 SDLCALL SDL_RWtell(SDL_RWops *context); |
252 | |
253 | /** |
254 | * Read from a data source. |
255 | * |
256 | * This function reads up to `maxnum` objects each of size `size` from the |
257 | * data source to the area pointed at by `ptr`. This function may read less |
258 | * objects than requested. It will return zero when there has been an error or |
259 | * the data stream is completely read. |
260 | * |
261 | * SDL_RWread() is actually a function wrapper that calls the SDL_RWops's |
262 | * `read` method appropriately, to simplify application development. |
263 | * |
264 | * \param context a pointer to an SDL_RWops structure |
265 | * \param ptr a pointer to a buffer to read data into |
266 | * \param size the size of each object to read, in bytes |
267 | * \param maxnum the maximum number of objects to be read |
268 | * \returns the number of objects read, or 0 at error or end of file; call |
269 | * SDL_GetError() for more information. |
270 | * |
271 | * \sa SDL_RWclose |
272 | * \sa SDL_RWFromConstMem |
273 | * \sa SDL_RWFromFile |
274 | * \sa SDL_RWFromFP |
275 | * \sa SDL_RWFromMem |
276 | * \sa SDL_RWseek |
277 | * \sa SDL_RWwrite |
278 | */ |
279 | extern DECLSPEC size_t SDLCALL SDL_RWread(SDL_RWops *context, |
280 | void *ptr, size_t size, |
281 | size_t maxnum); |
282 | |
283 | /** |
284 | * Write to an SDL_RWops data stream. |
285 | * |
286 | * This function writes exactly `num` objects each of size `size` from the |
287 | * area pointed at by `ptr` to the stream. If this fails for any reason, |
288 | * it'll return less than `num` to demonstrate how far the write progressed. |
289 | * On success, it returns `num`. |
290 | * |
291 | * SDL_RWwrite is actually a function wrapper that calls the SDL_RWops's |
292 | * `write` method appropriately, to simplify application development. |
293 | * |
294 | * \param context a pointer to an SDL_RWops structure |
295 | * \param ptr a pointer to a buffer containing data to write |
296 | * \param size the size of an object to write, in bytes |
297 | * \param num the number of objects to write |
298 | * \returns the number of objects written, which will be less than **num** on |
299 | * error; call SDL_GetError() for more information. |
300 | * |
301 | * \sa SDL_RWclose |
302 | * \sa SDL_RWFromConstMem |
303 | * \sa SDL_RWFromFile |
304 | * \sa SDL_RWFromFP |
305 | * \sa SDL_RWFromMem |
306 | * \sa SDL_RWread |
307 | * \sa SDL_RWseek |
308 | */ |
309 | extern DECLSPEC size_t SDLCALL SDL_RWwrite(SDL_RWops *context, |
310 | const void *ptr, size_t size, |
311 | size_t num); |
312 | |
313 | /** |
314 | * Close and free an allocated SDL_RWops structure. |
315 | * |
316 | * SDL_RWclose() closes and cleans up the SDL_RWops stream. It releases any |
317 | * resources used by the stream and frees the SDL_RWops itself with |
318 | * SDL_FreeRW(). This returns 0 on success, or -1 if the stream failed to |
319 | * flush to its output (e.g. to disk). |
320 | * |
321 | * Note that if this fails to flush the stream to disk, this function reports |
322 | * an error, but the SDL_RWops is still invalid once this function returns. |
323 | * |
324 | * SDL_RWclose() is actually a macro that calls the SDL_RWops's `close` |
325 | * method appropriately, to simplify application development. |
326 | * |
327 | * \param context SDL_RWops structure to close |
328 | * \returns 0 on success or a negative error code on failure; call |
329 | * SDL_GetError() for more information. |
330 | * |
331 | * \sa SDL_RWFromConstMem |
332 | * \sa SDL_RWFromFile |
333 | * \sa SDL_RWFromFP |
334 | * \sa SDL_RWFromMem |
335 | * \sa SDL_RWread |
336 | * \sa SDL_RWseek |
337 | * \sa SDL_RWwrite |
338 | */ |
339 | extern DECLSPEC int SDLCALL SDL_RWclose(SDL_RWops *context); |
340 | |
341 | /** |
342 | * Load all the data from an SDL data stream. |
343 | * |
344 | * The data is allocated with a zero byte at the end (null terminated) for |
345 | * convenience. This extra byte is not included in the value reported via |
346 | * `datasize`. |
347 | * |
348 | * The data should be freed with SDL_free(). |
349 | * |
350 | * \param src the SDL_RWops to read all available data from |
351 | * \param datasize if not NULL, will store the number of bytes read |
352 | * \param freesrc if non-zero, calls SDL_RWclose() on `src` before returning |
353 | * \returns the data, or NULL if there was an error. |
354 | */ |
355 | extern DECLSPEC void *SDLCALL SDL_LoadFile_RW(SDL_RWops *src, |
356 | size_t *datasize, |
357 | int freesrc); |
358 | |
359 | /** |
360 | * Load all the data from a file path. |
361 | * |
362 | * The data is allocated with a zero byte at the end (null terminated) for |
363 | * convenience. This extra byte is not included in the value reported via |
364 | * `datasize`. |
365 | * |
366 | * The data should be freed with SDL_free(). |
367 | * |
368 | * \param file the path to read all available data from |
369 | * \param datasize if not NULL, will store the number of bytes read |
370 | * \returns the data, or NULL if there was an error. |
371 | */ |
372 | extern DECLSPEC void *SDLCALL SDL_LoadFile(const char *file, size_t *datasize); |
373 | |
374 | /** |
375 | * \name Read endian functions |
376 | * |
377 | * Read an item of the specified endianness and return in native format. |
378 | */ |
379 | /* @{ */ |
380 | extern DECLSPEC Uint8 SDLCALL SDL_ReadU8(SDL_RWops * src); |
381 | extern DECLSPEC Uint16 SDLCALL SDL_ReadLE16(SDL_RWops * src); |
382 | extern DECLSPEC Uint16 SDLCALL SDL_ReadBE16(SDL_RWops * src); |
383 | extern DECLSPEC Uint32 SDLCALL SDL_ReadLE32(SDL_RWops * src); |
384 | extern DECLSPEC Uint32 SDLCALL SDL_ReadBE32(SDL_RWops * src); |
385 | extern DECLSPEC Uint64 SDLCALL SDL_ReadLE64(SDL_RWops * src); |
386 | extern DECLSPEC Uint64 SDLCALL SDL_ReadBE64(SDL_RWops * src); |
387 | /* @} *//* Read endian functions */ |
388 | |
389 | /** |
390 | * \name Write endian functions |
391 | * |
392 | * Write an item of native format to the specified endianness. |
393 | */ |
394 | /* @{ */ |
395 | extern DECLSPEC size_t SDLCALL SDL_WriteU8(SDL_RWops * dst, Uint8 value); |
396 | extern DECLSPEC size_t SDLCALL SDL_WriteLE16(SDL_RWops * dst, Uint16 value); |
397 | extern DECLSPEC size_t SDLCALL SDL_WriteBE16(SDL_RWops * dst, Uint16 value); |
398 | extern DECLSPEC size_t SDLCALL SDL_WriteLE32(SDL_RWops * dst, Uint32 value); |
399 | extern DECLSPEC size_t SDLCALL SDL_WriteBE32(SDL_RWops * dst, Uint32 value); |
400 | extern DECLSPEC size_t SDLCALL SDL_WriteLE64(SDL_RWops * dst, Uint64 value); |
401 | extern DECLSPEC size_t SDLCALL SDL_WriteBE64(SDL_RWops * dst, Uint64 value); |
402 | /* @} *//* Write endian functions */ |
403 | |
404 | /* Ends C function definitions when using C++ */ |
405 | #ifdef __cplusplus |
406 | } |
407 | #endif |
408 | #include "close_code.h" |
409 | |
410 | #endif /* SDL_rwops_h_ */ |
411 | |
412 | /* vi: set ts=4 sw=4 expandtab: */ |
413 | |