SDL 2.0
SDL_rwops.c
Go to the documentation of this file.
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2019 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/* We won't get fseeko64 on QNX if _LARGEFILE64_SOURCE is defined, but the
23 configure script knows the C runtime has it and enables it. */
24#ifndef __QNXNTO__
25/* Need this so Linux systems define fseek64o, ftell64o and off64_t */
26#define _LARGEFILE64_SOURCE
27#endif
28
29#include "../SDL_internal.h"
30
31#if defined(__WIN32__)
32#include "../core/windows/SDL_windows.h"
33#endif
34
35#ifdef HAVE_STDIO_H
36#include <stdio.h>
37#endif
38
39#ifdef HAVE_LIMITS_H
40#include <limits.h>
41#endif
42
43/* This file provides a general interface for SDL to read and write
44 data sources. It can easily be extended to files, memory, etc.
45*/
46
47#include "SDL_endian.h"
48#include "SDL_rwops.h"
49
50#ifdef __APPLE__
52#endif /* __APPLE__ */
53
54#ifdef __ANDROID__
55#include "../core/android/SDL_android.h"
56#include "SDL_system.h"
57#endif
58
59#if __NACL__
60#include "nacl_io/nacl_io.h"
61#endif
62
63#ifdef __WIN32__
64
65/* Functions to read/write Win32 API file pointers */
66
67#ifndef INVALID_SET_FILE_POINTER
68#define INVALID_SET_FILE_POINTER 0xFFFFFFFF
69#endif
70
71#define READAHEAD_BUFFER_SIZE 1024
72
73static int SDLCALL
74windows_file_open(SDL_RWops * context, const char *filename, const char *mode)
75{
76 UINT old_error_mode;
77 HANDLE h;
78 DWORD r_right, w_right;
79 DWORD must_exist, truncate;
80 int a_mode;
81
82 if (!context)
83 return -1; /* failed (invalid call) */
84
85 context->hidden.windowsio.h = INVALID_HANDLE_VALUE; /* mark this as unusable */
86 context->hidden.windowsio.buffer.data = NULL;
87 context->hidden.windowsio.buffer.size = 0;
88 context->hidden.windowsio.buffer.left = 0;
89
90 /* "r" = reading, file must exist */
91 /* "w" = writing, truncate existing, file may not exist */
92 /* "r+"= reading or writing, file must exist */
93 /* "a" = writing, append file may not exist */
94 /* "a+"= append + read, file may not exist */
95 /* "w+" = read, write, truncate. file may not exist */
96
97 must_exist = (SDL_strchr(mode, 'r') != NULL) ? OPEN_EXISTING : 0;
98 truncate = (SDL_strchr(mode, 'w') != NULL) ? CREATE_ALWAYS : 0;
99 r_right = (SDL_strchr(mode, '+') != NULL
100 || must_exist) ? GENERIC_READ : 0;
101 a_mode = (SDL_strchr(mode, 'a') != NULL) ? OPEN_ALWAYS : 0;
102 w_right = (a_mode || SDL_strchr(mode, '+')
103 || truncate) ? GENERIC_WRITE : 0;
104
105 if (!r_right && !w_right) /* inconsistent mode */
106 return -1; /* failed (invalid call) */
107
108 context->hidden.windowsio.buffer.data =
109 (char *) SDL_malloc(READAHEAD_BUFFER_SIZE);
110 if (!context->hidden.windowsio.buffer.data) {
111 return SDL_OutOfMemory();
112 }
113 /* Do not open a dialog box if failure */
114 old_error_mode =
115 SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
116
117 {
118 LPTSTR tstr = WIN_UTF8ToString(filename);
119 h = CreateFile(tstr, (w_right | r_right),
120 (w_right) ? 0 : FILE_SHARE_READ, NULL,
121 (must_exist | truncate | a_mode),
122 FILE_ATTRIBUTE_NORMAL, NULL);
123 SDL_free(tstr);
124 }
125
126 /* restore old behavior */
127 SetErrorMode(old_error_mode);
128
129 if (h == INVALID_HANDLE_VALUE) {
130 SDL_free(context->hidden.windowsio.buffer.data);
131 context->hidden.windowsio.buffer.data = NULL;
132 SDL_SetError("Couldn't open %s", filename);
133 return -2; /* failed (CreateFile) */
134 }
135 context->hidden.windowsio.h = h;
136 context->hidden.windowsio.append = a_mode ? SDL_TRUE : SDL_FALSE;
137
138 return 0; /* ok */
139}
140
141static Sint64 SDLCALL
142windows_file_size(SDL_RWops * context)
143{
144 LARGE_INTEGER size;
145
146 if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE) {
147 return SDL_SetError("windows_file_size: invalid context/file not opened");
148 }
149
150 if (!GetFileSizeEx(context->hidden.windowsio.h, &size)) {
151 return WIN_SetError("windows_file_size");
152 }
153
154 return size.QuadPart;
155}
156
157static Sint64 SDLCALL
158windows_file_seek(SDL_RWops * context, Sint64 offset, int whence)
159{
160 DWORD windowswhence;
161 LARGE_INTEGER windowsoffset;
162
163 if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE) {
164 return SDL_SetError("windows_file_seek: invalid context/file not opened");
165 }
166
167 /* FIXME: We may be able to satisfy the seek within buffered data */
168 if (whence == RW_SEEK_CUR && context->hidden.windowsio.buffer.left) {
169 offset -= (long)context->hidden.windowsio.buffer.left;
170 }
171 context->hidden.windowsio.buffer.left = 0;
172
173 switch (whence) {
174 case RW_SEEK_SET:
175 windowswhence = FILE_BEGIN;
176 break;
177 case RW_SEEK_CUR:
178 windowswhence = FILE_CURRENT;
179 break;
180 case RW_SEEK_END:
181 windowswhence = FILE_END;
182 break;
183 default:
184 return SDL_SetError("windows_file_seek: Unknown value for 'whence'");
185 }
186
187 windowsoffset.QuadPart = offset;
188 if (!SetFilePointerEx(context->hidden.windowsio.h, windowsoffset, &windowsoffset, windowswhence)) {
189 return WIN_SetError("windows_file_seek");
190 }
191 return windowsoffset.QuadPart;
192}
193
194static size_t SDLCALL
195windows_file_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum)
196{
197 size_t total_need;
198 size_t total_read = 0;
199 size_t read_ahead;
200 DWORD byte_read;
201
202 total_need = size * maxnum;
203
204 if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE
205 || !total_need)
206 return 0;
207
208 if (context->hidden.windowsio.buffer.left > 0) {
209 void *data = (char *) context->hidden.windowsio.buffer.data +
210 context->hidden.windowsio.buffer.size -
211 context->hidden.windowsio.buffer.left;
212 read_ahead =
213 SDL_min(total_need, context->hidden.windowsio.buffer.left);
214 SDL_memcpy(ptr, data, read_ahead);
215 context->hidden.windowsio.buffer.left -= read_ahead;
216
217 if (read_ahead == total_need) {
218 return maxnum;
219 }
220 ptr = (char *) ptr + read_ahead;
221 total_need -= read_ahead;
222 total_read += read_ahead;
223 }
224
225 if (total_need < READAHEAD_BUFFER_SIZE) {
226 if (!ReadFile
227 (context->hidden.windowsio.h, context->hidden.windowsio.buffer.data,
228 READAHEAD_BUFFER_SIZE, &byte_read, NULL)) {
230 return 0;
231 }
232 read_ahead = SDL_min(total_need, (int) byte_read);
233 SDL_memcpy(ptr, context->hidden.windowsio.buffer.data, read_ahead);
234 context->hidden.windowsio.buffer.size = byte_read;
235 context->hidden.windowsio.buffer.left = byte_read - read_ahead;
236 total_read += read_ahead;
237 } else {
238 if (!ReadFile
239 (context->hidden.windowsio.h, ptr, (DWORD)total_need, &byte_read, NULL)) {
241 return 0;
242 }
243 total_read += byte_read;
244 }
245 return (total_read / size);
246}
247
248static size_t SDLCALL
249windows_file_write(SDL_RWops * context, const void *ptr, size_t size,
250 size_t num)
251{
252
253 size_t total_bytes;
254 DWORD byte_written;
255 size_t nwritten;
256
257 total_bytes = size * num;
258
259 if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE
260 || total_bytes <= 0 || !size)
261 return 0;
262
263 if (context->hidden.windowsio.buffer.left) {
264 SetFilePointer(context->hidden.windowsio.h,
265 -(LONG)context->hidden.windowsio.buffer.left, NULL,
266 FILE_CURRENT);
267 context->hidden.windowsio.buffer.left = 0;
268 }
269
270 /* if in append mode, we must go to the EOF before write */
271 if (context->hidden.windowsio.append) {
272 if (SetFilePointer(context->hidden.windowsio.h, 0L, NULL, FILE_END) ==
273 INVALID_SET_FILE_POINTER) {
275 return 0;
276 }
277 }
278
279 if (!WriteFile
280 (context->hidden.windowsio.h, ptr, (DWORD)total_bytes, &byte_written, NULL)) {
282 return 0;
283 }
284
285 nwritten = byte_written / size;
286 return nwritten;
287}
288
289static int SDLCALL
290windows_file_close(SDL_RWops * context)
291{
292
293 if (context) {
294 if (context->hidden.windowsio.h != INVALID_HANDLE_VALUE) {
295 CloseHandle(context->hidden.windowsio.h);
296 context->hidden.windowsio.h = INVALID_HANDLE_VALUE; /* to be sure */
297 }
298 SDL_free(context->hidden.windowsio.buffer.data);
299 context->hidden.windowsio.buffer.data = NULL;
301 }
302 return 0;
303}
304#endif /* __WIN32__ */
305
306#ifdef HAVE_STDIO_H
307
308#ifdef HAVE_FOPEN64
309#define fopen fopen64
310#endif
311#ifdef HAVE_FSEEKO64
312#define fseek_off_t off64_t
313#define fseek fseeko64
314#define ftell ftello64
315#elif defined(HAVE_FSEEKO)
316#if defined(OFF_MIN) && defined(OFF_MAX)
317#define FSEEK_OFF_MIN OFF_MIN
318#define FSEEK_OFF_MAX OFF_MAX
319#elif defined(HAVE_LIMITS_H)
320/* POSIX doesn't specify the minimum and maximum macros for off_t so
321 * we have to improvise and dance around implementation-defined
322 * behavior. This may fail if the off_t type has padding bits or
323 * is not a two's-complement representation. The compilers will detect
324 * and eliminate the dead code if off_t has 64 bits.
325 */
326#define FSEEK_OFF_MAX (((((off_t)1 << (sizeof(off_t) * CHAR_BIT - 2)) - 1) << 1) + 1)
327#define FSEEK_OFF_MIN (-(FSEEK_OFF_MAX) - 1)
328#endif
329#define fseek_off_t off_t
330#define fseek fseeko
331#define ftell ftello
332#elif defined(HAVE__FSEEKI64)
333#define fseek_off_t __int64
334#define fseek _fseeki64
335#define ftell _ftelli64
336#else
337#ifdef HAVE_LIMITS_H
338#define FSEEK_OFF_MIN LONG_MIN
339#define FSEEK_OFF_MAX LONG_MAX
340#endif
341#define fseek_off_t long
342#endif
343
344/* Functions to read/write stdio file pointers */
345
346static Sint64 SDLCALL
347stdio_size(SDL_RWops * context)
348{
349 Sint64 pos, size;
350
351 pos = SDL_RWseek(context, 0, RW_SEEK_CUR);
352 if (pos < 0) {
353 return -1;
354 }
356
358 return size;
359}
360
361static Sint64 SDLCALL
362stdio_seek(SDL_RWops * context, Sint64 offset, int whence)
363{
364#if defined(FSEEK_OFF_MIN) && defined(FSEEK_OFF_MAX)
365 if (offset < (Sint64)(FSEEK_OFF_MIN) || offset > (Sint64)(FSEEK_OFF_MAX)) {
366 return SDL_SetError("Seek offset out of range");
367 }
368#endif
369
370 if (fseek(context->hidden.stdio.fp, (fseek_off_t)offset, whence) == 0) {
371 Sint64 pos = ftell(context->hidden.stdio.fp);
372 if (pos < 0) {
373 return SDL_SetError("Couldn't get stream offset");
374 }
375 return pos;
376 }
377 return SDL_Error(SDL_EFSEEK);
378}
379
380static size_t SDLCALL
381stdio_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum)
382{
383 size_t nread;
384
385 nread = fread(ptr, size, maxnum, context->hidden.stdio.fp);
386 if (nread == 0 && ferror(context->hidden.stdio.fp)) {
388 }
389 return nread;
390}
391
392static size_t SDLCALL
393stdio_write(SDL_RWops * context, const void *ptr, size_t size, size_t num)
394{
395 size_t nwrote;
396
397 nwrote = fwrite(ptr, size, num, context->hidden.stdio.fp);
398 if (nwrote == 0 && ferror(context->hidden.stdio.fp)) {
400 }
401 return nwrote;
402}
403
404static int SDLCALL
405stdio_close(SDL_RWops * context)
406{
407 int status = 0;
408 if (context) {
409 if (context->hidden.stdio.autoclose) {
410 /* WARNING: Check the return value here! */
411 if (fclose(context->hidden.stdio.fp) != 0) {
412 status = SDL_Error(SDL_EFWRITE);
413 }
414 }
416 }
417 return status;
418}
419#endif /* !HAVE_STDIO_H */
420
421/* Functions to read/write memory pointers */
422
423static Sint64 SDLCALL
425{
426 return (Sint64)(context->hidden.mem.stop - context->hidden.mem.base);
427}
428
429static Sint64 SDLCALL
431{
432 Uint8 *newpos;
433
434 switch (whence) {
435 case RW_SEEK_SET:
436 newpos = context->hidden.mem.base + offset;
437 break;
438 case RW_SEEK_CUR:
439 newpos = context->hidden.mem.here + offset;
440 break;
441 case RW_SEEK_END:
442 newpos = context->hidden.mem.stop + offset;
443 break;
444 default:
445 return SDL_SetError("Unknown value for 'whence'");
446 }
447 if (newpos < context->hidden.mem.base) {
448 newpos = context->hidden.mem.base;
449 }
450 if (newpos > context->hidden.mem.stop) {
451 newpos = context->hidden.mem.stop;
452 }
453 context->hidden.mem.here = newpos;
454 return (Sint64)(context->hidden.mem.here - context->hidden.mem.base);
455}
456
457static size_t SDLCALL
458mem_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum)
459{
460 size_t total_bytes;
461 size_t mem_available;
462
463 total_bytes = (maxnum * size);
464 if ((maxnum <= 0) || (size <= 0)
465 || ((total_bytes / maxnum) != (size_t) size)) {
466 return 0;
467 }
468
469 mem_available = (context->hidden.mem.stop - context->hidden.mem.here);
470 if (total_bytes > mem_available) {
471 total_bytes = mem_available;
472 }
473
474 SDL_memcpy(ptr, context->hidden.mem.here, total_bytes);
475 context->hidden.mem.here += total_bytes;
476
477 return (total_bytes / size);
478}
479
480static size_t SDLCALL
481mem_write(SDL_RWops * context, const void *ptr, size_t size, size_t num)
482{
483 if ((context->hidden.mem.here + (num * size)) > context->hidden.mem.stop) {
484 num = (context->hidden.mem.stop - context->hidden.mem.here) / size;
485 }
486 SDL_memcpy(context->hidden.mem.here, ptr, num * size);
487 context->hidden.mem.here += num * size;
488 return num;
489}
490
491static size_t SDLCALL
492mem_writeconst(SDL_RWops * context, const void *ptr, size_t size, size_t num)
493{
494 SDL_SetError("Can't write to read-only memory");
495 return 0;
496}
497
498static int SDLCALL
500{
501 if (context) {
503 }
504 return 0;
505}
506
507
508/* Functions to create SDL_RWops structures from various data sources */
509
510SDL_RWops *
511SDL_RWFromFile(const char *file, const char *mode)
512{
513 SDL_RWops *rwops = NULL;
514 if (!file || !*file || !mode || !*mode) {
515 SDL_SetError("SDL_RWFromFile(): No file or no mode specified");
516 return NULL;
517 }
518#if defined(__ANDROID__)
519#ifdef HAVE_STDIO_H
520 /* Try to open the file on the filesystem first */
521 if (*file == '/') {
522 FILE *fp = fopen(file, mode);
523 if (fp) {
524 return SDL_RWFromFP(fp, 1);
525 }
526 } else {
527 /* Try opening it from internal storage if it's a relative path */
528 char *path;
529 FILE *fp;
530
531 /* !!! FIXME: why not just "char path[PATH_MAX];" ? */
532 path = SDL_stack_alloc(char, PATH_MAX);
533 if (path) {
534 SDL_snprintf(path, PATH_MAX, "%s/%s",
536 fp = fopen(path, mode);
538 if (fp) {
539 return SDL_RWFromFP(fp, 1);
540 }
541 }
542 }
543#endif /* HAVE_STDIO_H */
544
545 /* Try to open the file from the asset system */
546 rwops = SDL_AllocRW();
547 if (!rwops)
548 return NULL; /* SDL_SetError already setup by SDL_AllocRW() */
549 if (Android_JNI_FileOpen(rwops, file, mode) < 0) {
550 SDL_FreeRW(rwops);
551 return NULL;
552 }
553 rwops->size = Android_JNI_FileSize;
554 rwops->seek = Android_JNI_FileSeek;
555 rwops->read = Android_JNI_FileRead;
558 rwops->type = SDL_RWOPS_JNIFILE;
559
560#elif defined(__WIN32__)
561 rwops = SDL_AllocRW();
562 if (!rwops)
563 return NULL; /* SDL_SetError already setup by SDL_AllocRW() */
564 if (windows_file_open(rwops, file, mode) < 0) {
565 SDL_FreeRW(rwops);
566 return NULL;
567 }
568 rwops->size = windows_file_size;
569 rwops->seek = windows_file_seek;
570 rwops->read = windows_file_read;
571 rwops->write = windows_file_write;
572 rwops->close = windows_file_close;
573 rwops->type = SDL_RWOPS_WINFILE;
574
575#elif HAVE_STDIO_H
576 {
577 #ifdef __APPLE__
578 FILE *fp = SDL_OpenFPFromBundleOrFallback(file, mode);
579 #elif __WINRT__
580 FILE *fp = NULL;
581 fopen_s(&fp, file, mode);
582 #else
583 FILE *fp = fopen(file, mode);
584 #endif
585 if (fp == NULL) {
586 SDL_SetError("Couldn't open %s", file);
587 } else {
588 rwops = SDL_RWFromFP(fp, 1);
589 }
590 }
591#else
592 SDL_SetError("SDL not compiled with stdio support");
593#endif /* !HAVE_STDIO_H */
594
595 return rwops;
596}
597
598#ifdef HAVE_STDIO_H
599SDL_RWops *
600SDL_RWFromFP(FILE * fp, SDL_bool autoclose)
601{
602 SDL_RWops *rwops = NULL;
603
604 rwops = SDL_AllocRW();
605 if (rwops != NULL) {
606 rwops->size = stdio_size;
607 rwops->seek = stdio_seek;
608 rwops->read = stdio_read;
609 rwops->write = stdio_write;
610 rwops->close = stdio_close;
611 rwops->hidden.stdio.fp = fp;
612 rwops->hidden.stdio.autoclose = autoclose;
613 rwops->type = SDL_RWOPS_STDFILE;
614 }
615 return rwops;
616}
617#else
618SDL_RWops *
619SDL_RWFromFP(void * fp, SDL_bool autoclose)
620{
621 SDL_SetError("SDL not compiled with stdio support");
622 return NULL;
623}
624#endif /* HAVE_STDIO_H */
625
626SDL_RWops *
627SDL_RWFromMem(void *mem, int size)
628{
629 SDL_RWops *rwops = NULL;
630 if (!mem) {
632 return rwops;
633 }
634 if (!size) {
635 SDL_InvalidParamError("size");
636 return rwops;
637 }
638
639 rwops = SDL_AllocRW();
640 if (rwops != NULL) {
641 rwops->size = mem_size;
642 rwops->seek = mem_seek;
643 rwops->read = mem_read;
644 rwops->write = mem_write;
645 rwops->close = mem_close;
646 rwops->hidden.mem.base = (Uint8 *) mem;
647 rwops->hidden.mem.here = rwops->hidden.mem.base;
648 rwops->hidden.mem.stop = rwops->hidden.mem.base + size;
649 rwops->type = SDL_RWOPS_MEMORY;
650 }
651 return rwops;
652}
653
654SDL_RWops *
655SDL_RWFromConstMem(const void *mem, int size)
656{
657 SDL_RWops *rwops = NULL;
658 if (!mem) {
660 return rwops;
661 }
662 if (!size) {
663 SDL_InvalidParamError("size");
664 return rwops;
665 }
666
667 rwops = SDL_AllocRW();
668 if (rwops != NULL) {
669 rwops->size = mem_size;
670 rwops->seek = mem_seek;
671 rwops->read = mem_read;
672 rwops->write = mem_writeconst;
673 rwops->close = mem_close;
674 rwops->hidden.mem.base = (Uint8 *) mem;
675 rwops->hidden.mem.here = rwops->hidden.mem.base;
676 rwops->hidden.mem.stop = rwops->hidden.mem.base + size;
677 rwops->type = SDL_RWOPS_MEMORY_RO;
678 }
679 return rwops;
680}
681
682SDL_RWops *
684{
685 SDL_RWops *area;
686
687 area = (SDL_RWops *) SDL_malloc(sizeof *area);
688 if (area == NULL) {
690 } else {
691 area->type = SDL_RWOPS_UNKNOWN;
692 }
693 return area;
694}
695
696void
698{
699 SDL_free(area);
700}
701
702/* Load all the data from an SDL data stream */
703void *
704SDL_LoadFile_RW(SDL_RWops * src, size_t *datasize, int freesrc)
705{
706 const int FILE_CHUNK_SIZE = 1024;
707 Sint64 size;
708 size_t size_read, size_total;
709 void *data = NULL, *newdata;
710
711 if (!src) {
713 return NULL;
714 }
715
717 if (size < 0) {
718 size = FILE_CHUNK_SIZE;
719 }
720 data = SDL_malloc((size_t)(size + 1));
721
722 size_total = 0;
723 for (;;) {
724 if ((((Sint64)size_total) + FILE_CHUNK_SIZE) > size) {
725 size = (size_total + FILE_CHUNK_SIZE);
726 newdata = SDL_realloc(data, (size_t)(size + 1));
727 if (!newdata) {
728 SDL_free(data);
729 data = NULL;
731 goto done;
732 }
733 data = newdata;
734 }
735
736 size_read = SDL_RWread(src, (char *)data+size_total, 1, (size_t)(size-size_total));
737 if (size_read == 0) {
738 break;
739 }
740 size_total += size_read;
741 }
742
743 if (datasize) {
744 *datasize = size_total;
745 }
746 ((char *)data)[size_total] = '\0';
747
748done:
749 if (freesrc && src) {
751 }
752 return data;
753}
754
755void *
756SDL_LoadFile(const char *file, size_t *datasize)
757{
758 return SDL_LoadFile_RW(SDL_RWFromFile(file, "rb"), datasize, 1);
759}
760
761Sint64
763{
764 return context->size(context);
765}
766
767Sint64
769{
770 return context->seek(context, offset, whence);
771}
772
773Sint64
775{
776 return context->seek(context, 0, RW_SEEK_CUR);
777}
778
779size_t
780SDL_RWread(SDL_RWops *context, void *ptr, size_t size, size_t maxnum)
781{
782 return context->read(context, ptr, size, maxnum);
783}
784
785size_t
786SDL_RWwrite(SDL_RWops *context, const void *ptr, size_t size, size_t num)
787{
788 return context->write(context, ptr, size, num);
789}
790
791int
793{
794 return context->close(context);
795}
796
797/* Functions for dynamically reading and writing endian-specific values */
798
799Uint8
801{
802 Uint8 value = 0;
803
804 SDL_RWread(src, &value, sizeof (value), 1);
805 return value;
806}
807
808Uint16
810{
811 Uint16 value = 0;
812
813 SDL_RWread(src, &value, sizeof (value), 1);
814 return SDL_SwapLE16(value);
815}
816
817Uint16
819{
820 Uint16 value = 0;
821
822 SDL_RWread(src, &value, sizeof (value), 1);
823 return SDL_SwapBE16(value);
824}
825
826Uint32
828{
829 Uint32 value = 0;
830
831 SDL_RWread(src, &value, sizeof (value), 1);
832 return SDL_SwapLE32(value);
833}
834
835Uint32
837{
838 Uint32 value = 0;
839
840 SDL_RWread(src, &value, sizeof (value), 1);
841 return SDL_SwapBE32(value);
842}
843
844Uint64
846{
847 Uint64 value = 0;
848
849 SDL_RWread(src, &value, sizeof (value), 1);
850 return SDL_SwapLE64(value);
851}
852
853Uint64
855{
856 Uint64 value = 0;
857
858 SDL_RWread(src, &value, sizeof (value), 1);
859 return SDL_SwapBE64(value);
860}
861
862size_t
864{
865 return SDL_RWwrite(dst, &value, sizeof (value), 1);
866}
867
868size_t
870{
871 const Uint16 swapped = SDL_SwapLE16(value);
872 return SDL_RWwrite(dst, &swapped, sizeof (swapped), 1);
873}
874
875size_t
877{
878 const Uint16 swapped = SDL_SwapBE16(value);
879 return SDL_RWwrite(dst, &swapped, sizeof (swapped), 1);
880}
881
882size_t
884{
885 const Uint32 swapped = SDL_SwapLE32(value);
886 return SDL_RWwrite(dst, &swapped, sizeof (swapped), 1);
887}
888
889size_t
891{
892 const Uint32 swapped = SDL_SwapBE32(value);
893 return SDL_RWwrite(dst, &swapped, sizeof (swapped), 1);
894}
895
896size_t
898{
899 const Uint64 swapped = SDL_SwapLE64(value);
900 return SDL_RWwrite(dst, &swapped, sizeof (swapped), 1);
901}
902
903size_t
905{
906 const Uint64 swapped = SDL_SwapBE64(value);
907 return SDL_RWwrite(dst, &swapped, sizeof (swapped), 1);
908}
909
910/* vi: set ts=4 sw=4 expandtab: */
size_t Android_JNI_FileRead(SDL_RWops *ctx, void *buffer, size_t size, size_t maxnum)
int Android_JNI_FileOpen(SDL_RWops *ctx, const char *fileName, const char *mode)
size_t Android_JNI_FileWrite(SDL_RWops *ctx, const void *buffer, size_t size, size_t num)
Sint64 Android_JNI_FileSize(SDL_RWops *ctx)
Sint64 Android_JNI_FileSeek(SDL_RWops *ctx, Sint64 offset, int whence)
int Android_JNI_FileClose(SDL_RWops *ctx)
unsigned int size_t
#define SDL_SetError
#define SDL_strchr
#define SDL_Error
#define SDL_AndroidGetInternalStoragePath
#define SDL_malloc
#define SDL_realloc
#define SDL_free
#define SDL_memcpy
#define SDL_snprintf
#define SDL_SwapLE32(X)
Definition: SDL_endian.h:233
#define SDL_SwapBE32(X)
Definition: SDL_endian.h:237
#define SDL_SwapBE16(X)
Definition: SDL_endian.h:236
#define SDL_SwapBE64(X)
Definition: SDL_endian.h:238
#define SDL_SwapLE64(X)
Definition: SDL_endian.h:234
#define SDL_SwapLE16(X)
Definition: SDL_endian.h:232
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
#define SDL_InvalidParamError(param)
Definition: SDL_error.h:54
@ SDL_EFSEEK
Definition: SDL_error.h:60
@ SDL_EFWRITE
Definition: SDL_error.h:59
@ SDL_EFREAD
Definition: SDL_error.h:58
#define SDLCALL
Definition: SDL_internal.h:49
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
GLenum mode
GLenum src
GLintptr offset
GLenum GLenum dst
GLsizeiptr size
GLsizei const GLchar *const * path
GLuint num
GLsizei const GLfloat * value
GLfloat GLfloat GLfloat GLfloat h
static Sint64 mem_size(SDL_RWops *context)
Definition: SDL_rwops.c:424
size_t SDL_WriteBE64(SDL_RWops *dst, Uint64 value)
Definition: SDL_rwops.c:904
static size_t mem_read(SDL_RWops *context, void *ptr, size_t size, size_t maxnum)
Definition: SDL_rwops.c:458
Uint16 SDL_ReadLE16(SDL_RWops *src)
Definition: SDL_rwops.c:809
Uint32 SDL_ReadLE32(SDL_RWops *src)
Definition: SDL_rwops.c:827
size_t SDL_RWread(SDL_RWops *context, void *ptr, size_t size, size_t maxnum)
Definition: SDL_rwops.c:780
Sint64 SDL_RWsize(SDL_RWops *context)
Definition: SDL_rwops.c:762
size_t SDL_WriteLE32(SDL_RWops *dst, Uint32 value)
Definition: SDL_rwops.c:883
size_t SDL_WriteLE16(SDL_RWops *dst, Uint16 value)
Definition: SDL_rwops.c:869
static size_t mem_writeconst(SDL_RWops *context, const void *ptr, size_t size, size_t num)
Definition: SDL_rwops.c:492
Uint16 SDL_ReadBE16(SDL_RWops *src)
Definition: SDL_rwops.c:818
static size_t mem_write(SDL_RWops *context, const void *ptr, size_t size, size_t num)
Definition: SDL_rwops.c:481
SDL_RWops * SDL_RWFromFile(const char *file, const char *mode)
Definition: SDL_rwops.c:511
size_t SDL_WriteBE16(SDL_RWops *dst, Uint16 value)
Definition: SDL_rwops.c:876
size_t SDL_WriteBE32(SDL_RWops *dst, Uint32 value)
Definition: SDL_rwops.c:890
Sint64 SDL_RWseek(SDL_RWops *context, Sint64 offset, int whence)
Definition: SDL_rwops.c:768
size_t SDL_RWwrite(SDL_RWops *context, const void *ptr, size_t size, size_t num)
Definition: SDL_rwops.c:786
SDL_RWops * SDL_RWFromFP(void *fp, SDL_bool autoclose)
Definition: SDL_rwops.c:619
SDL_RWops * SDL_RWFromMem(void *mem, int size)
Definition: SDL_rwops.c:627
Sint64 SDL_RWtell(SDL_RWops *context)
Definition: SDL_rwops.c:774
static int mem_close(SDL_RWops *context)
Definition: SDL_rwops.c:499
void SDL_FreeRW(SDL_RWops *area)
Definition: SDL_rwops.c:697
void * SDL_LoadFile_RW(SDL_RWops *src, size_t *datasize, int freesrc)
Definition: SDL_rwops.c:704
Uint64 SDL_ReadLE64(SDL_RWops *src)
Definition: SDL_rwops.c:845
SDL_RWops * SDL_AllocRW(void)
Definition: SDL_rwops.c:683
Uint64 SDL_ReadBE64(SDL_RWops *src)
Definition: SDL_rwops.c:854
size_t SDL_WriteU8(SDL_RWops *dst, Uint8 value)
Definition: SDL_rwops.c:863
Uint32 SDL_ReadBE32(SDL_RWops *src)
Definition: SDL_rwops.c:836
int SDL_RWclose(SDL_RWops *context)
Definition: SDL_rwops.c:792
Uint8 SDL_ReadU8(SDL_RWops *src)
Definition: SDL_rwops.c:800
SDL_RWops * SDL_RWFromConstMem(const void *mem, int size)
Definition: SDL_rwops.c:655
size_t SDL_WriteLE64(SDL_RWops *dst, Uint64 value)
Definition: SDL_rwops.c:897
void * SDL_LoadFile(const char *file, size_t *datasize)
Definition: SDL_rwops.c:756
static Sint64 mem_seek(SDL_RWops *context, Sint64 offset, int whence)
Definition: SDL_rwops.c:430
#define SDL_RWOPS_STDFILE
Definition: SDL_rwops.h:44
#define SDL_RWOPS_MEMORY
Definition: SDL_rwops.h:46
#define SDL_RWOPS_MEMORY_RO
Definition: SDL_rwops.h:47
#define RW_SEEK_END
Definition: SDL_rwops.h:176
#define RW_SEEK_CUR
Definition: SDL_rwops.h:175
#define SDL_RWOPS_UNKNOWN
Definition: SDL_rwops.h:42
#define RW_SEEK_SET
Definition: SDL_rwops.h:174
#define SDL_RWOPS_JNIFILE
Definition: SDL_rwops.h:45
#define SDL_RWOPS_WINFILE
Definition: SDL_rwops.h:43
SDL_bool
Definition: SDL_stdinc.h:162
@ SDL_TRUE
Definition: SDL_stdinc.h:164
@ SDL_FALSE
Definition: SDL_stdinc.h:163
#define SDL_stack_alloc(type, count)
Definition: SDL_stdinc.h:354
uint32_t Uint32
Definition: SDL_stdinc.h:203
uint64_t Uint64
Definition: SDL_stdinc.h:216
#define SDL_stack_free(data)
Definition: SDL_stdinc.h:355
#define SDL_min(x, y)
Definition: SDL_stdinc.h:406
uint16_t Uint16
Definition: SDL_stdinc.h:191
uint8_t Uint8
Definition: SDL_stdinc.h:179
int64_t Sint64
Definition: SDL_stdinc.h:210
#define WIN_UTF8ToString(S)
Definition: SDL_windows.h:47
int WIN_SetError(const char *prefix)
#define NULL
Definition: begin_code.h:167
int done
Definition: checkkeys.c:28
Uint32 type
Definition: SDL_rwops.h:93
size_t(* write)(struct SDL_RWops *context, const void *ptr, size_t size, size_t num)
Definition: SDL_rwops.h:83
FILE * fp
Definition: SDL_rwops.h:127
SDL_bool autoclose
Definition: SDL_rwops.h:126
Uint8 * stop
Definition: SDL_rwops.h:134
size_t(* read)(struct SDL_RWops *context, void *ptr, size_t size, size_t maxnum)
Definition: SDL_rwops.h:74
Uint8 * here
Definition: SDL_rwops.h:133
struct SDL_RWops::@9::@11 stdio
int(* close)(struct SDL_RWops *context)
Definition: SDL_rwops.h:91
Sint64(* seek)(struct SDL_RWops *context, Sint64 offset, int whence)
Definition: SDL_rwops.h:65
union SDL_RWops::@9 hidden
Sint64(* size)(struct SDL_RWops *context)
Definition: SDL_rwops.h:57
struct SDL_RWops::@9::@12 mem
Uint8 * base
Definition: SDL_rwops.h:132
static screen_context_t context
Definition: video.c:25