1 /*
2   Simple DirectMedia Layer
3   Copyright (C) 1997-2016 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 /* Need this so Linux systems define fseek64o, ftell64o and off64_t */
22 #define _LARGEFILE64_SOURCE
23 #include "../SDL_internal.h"
24 
25 #if defined(__WIN32__)
26 #include "../core/windows/SDL_windows.h"
27 #endif
28 
29 
30 /* This file provides a general interface for SDL to read and write
31    data sources.  It can easily be extended to files, memory, etc.
32 */
33 
34 #include "SDL_endian.h"
35 #include "SDL_rwops.h"
36 
37 #ifdef __APPLE__
38 #include "cocoa/SDL_rwopsbundlesupport.h"
39 #endif /* __APPLE__ */
40 
41 #ifdef __ANDROID__
42 #include "../core/android/SDL_android.h"
43 #include "SDL_system.h"
44 #endif
45 
46 #if __NACL__
47 #include "nacl_io/nacl_io.h"
48 #endif
49 
50 #ifdef __WIN32__
51 
52 /* Functions to read/write Win32 API file pointers */
53 
54 #ifndef INVALID_SET_FILE_POINTER
55 #define INVALID_SET_FILE_POINTER 0xFFFFFFFF
56 #endif
57 
58 #define READAHEAD_BUFFER_SIZE   1024
59 
60 static int SDLCALL
windows_file_open(SDL_RWops * context,const char * filename,const char * mode)61 windows_file_open(SDL_RWops * context, const char *filename, const char *mode)
62 {
63     UINT old_error_mode;
64     HANDLE h;
65     DWORD r_right, w_right;
66     DWORD must_exist, truncate;
67     int a_mode;
68 
69     if (!context)
70         return -1;              /* failed (invalid call) */
71 
72     context->hidden.windowsio.h = INVALID_HANDLE_VALUE;   /* mark this as unusable */
73     context->hidden.windowsio.buffer.data = NULL;
74     context->hidden.windowsio.buffer.size = 0;
75     context->hidden.windowsio.buffer.left = 0;
76 
77     /* "r" = reading, file must exist */
78     /* "w" = writing, truncate existing, file may not exist */
79     /* "r+"= reading or writing, file must exist            */
80     /* "a" = writing, append file may not exist             */
81     /* "a+"= append + read, file may not exist              */
82     /* "w+" = read, write, truncate. file may not exist    */
83 
84     must_exist = (SDL_strchr(mode, 'r') != NULL) ? OPEN_EXISTING : 0;
85     truncate = (SDL_strchr(mode, 'w') != NULL) ? CREATE_ALWAYS : 0;
86     r_right = (SDL_strchr(mode, '+') != NULL
87                || must_exist) ? GENERIC_READ : 0;
88     a_mode = (SDL_strchr(mode, 'a') != NULL) ? OPEN_ALWAYS : 0;
89     w_right = (a_mode || SDL_strchr(mode, '+')
90                || truncate) ? GENERIC_WRITE : 0;
91 
92     if (!r_right && !w_right)   /* inconsistent mode */
93         return -1;              /* failed (invalid call) */
94 
95     context->hidden.windowsio.buffer.data =
96         (char *) SDL_malloc(READAHEAD_BUFFER_SIZE);
97     if (!context->hidden.windowsio.buffer.data) {
98         return SDL_OutOfMemory();
99     }
100     /* Do not open a dialog box if failure */
101     old_error_mode =
102         SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
103 
104     {
105         LPTSTR tstr = WIN_UTF8ToString(filename);
106         h = CreateFile(tstr, (w_right | r_right),
107                        (w_right) ? 0 : FILE_SHARE_READ, NULL,
108                        (must_exist | truncate | a_mode),
109                        FILE_ATTRIBUTE_NORMAL, NULL);
110         SDL_free(tstr);
111     }
112 
113     /* restore old behavior */
114     SetErrorMode(old_error_mode);
115 
116     if (h == INVALID_HANDLE_VALUE) {
117         SDL_free(context->hidden.windowsio.buffer.data);
118         context->hidden.windowsio.buffer.data = NULL;
119         SDL_SetError("Couldn't open %s", filename);
120         return -2;              /* failed (CreateFile) */
121     }
122     context->hidden.windowsio.h = h;
123     context->hidden.windowsio.append = a_mode ? SDL_TRUE : SDL_FALSE;
124 
125     return 0;                   /* ok */
126 }
127 
128 static Sint64 SDLCALL
windows_file_size(SDL_RWops * context)129 windows_file_size(SDL_RWops * context)
130 {
131     LARGE_INTEGER size;
132 
133     if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE) {
134         return SDL_SetError("windows_file_size: invalid context/file not opened");
135     }
136 
137     if (!GetFileSizeEx(context->hidden.windowsio.h, &size)) {
138         return WIN_SetError("windows_file_size");
139     }
140 
141     return size.QuadPart;
142 }
143 
144 static Sint64 SDLCALL
windows_file_seek(SDL_RWops * context,Sint64 offset,int whence)145 windows_file_seek(SDL_RWops * context, Sint64 offset, int whence)
146 {
147     DWORD windowswhence;
148     LARGE_INTEGER windowsoffset;
149 
150     if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE) {
151         return SDL_SetError("windows_file_seek: invalid context/file not opened");
152     }
153 
154     /* FIXME: We may be able to satisfy the seek within buffered data */
155     if (whence == RW_SEEK_CUR && context->hidden.windowsio.buffer.left) {
156         offset -= (long)context->hidden.windowsio.buffer.left;
157     }
158     context->hidden.windowsio.buffer.left = 0;
159 
160     switch (whence) {
161     case RW_SEEK_SET:
162         windowswhence = FILE_BEGIN;
163         break;
164     case RW_SEEK_CUR:
165         windowswhence = FILE_CURRENT;
166         break;
167     case RW_SEEK_END:
168         windowswhence = FILE_END;
169         break;
170     default:
171         return SDL_SetError("windows_file_seek: Unknown value for 'whence'");
172     }
173 
174     windowsoffset.QuadPart = offset;
175     if (!SetFilePointerEx(context->hidden.windowsio.h, windowsoffset, &windowsoffset, windowswhence)) {
176         return WIN_SetError("windows_file_seek");
177     }
178     return windowsoffset.QuadPart;
179 }
180 
181 static size_t SDLCALL
windows_file_read(SDL_RWops * context,void * ptr,size_t size,size_t maxnum)182 windows_file_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum)
183 {
184     size_t total_need;
185     size_t total_read = 0;
186     size_t read_ahead;
187     DWORD byte_read;
188 
189     total_need = size * maxnum;
190 
191     if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE
192         || !total_need)
193         return 0;
194 
195     if (context->hidden.windowsio.buffer.left > 0) {
196         void *data = (char *) context->hidden.windowsio.buffer.data +
197             context->hidden.windowsio.buffer.size -
198             context->hidden.windowsio.buffer.left;
199         read_ahead =
200             SDL_min(total_need, context->hidden.windowsio.buffer.left);
201         SDL_memcpy(ptr, data, read_ahead);
202         context->hidden.windowsio.buffer.left -= read_ahead;
203 
204         if (read_ahead == total_need) {
205             return maxnum;
206         }
207         ptr = (char *) ptr + read_ahead;
208         total_need -= read_ahead;
209         total_read += read_ahead;
210     }
211 
212     if (total_need < READAHEAD_BUFFER_SIZE) {
213         if (!ReadFile
214             (context->hidden.windowsio.h, context->hidden.windowsio.buffer.data,
215              READAHEAD_BUFFER_SIZE, &byte_read, NULL)) {
216             SDL_Error(SDL_EFREAD);
217             return 0;
218         }
219         read_ahead = SDL_min(total_need, (int) byte_read);
220         SDL_memcpy(ptr, context->hidden.windowsio.buffer.data, read_ahead);
221         context->hidden.windowsio.buffer.size = byte_read;
222         context->hidden.windowsio.buffer.left = byte_read - read_ahead;
223         total_read += read_ahead;
224     } else {
225         if (!ReadFile
226             (context->hidden.windowsio.h, ptr, (DWORD)total_need, &byte_read, NULL)) {
227             SDL_Error(SDL_EFREAD);
228             return 0;
229         }
230         total_read += byte_read;
231     }
232     return (total_read / size);
233 }
234 
235 static size_t SDLCALL
windows_file_write(SDL_RWops * context,const void * ptr,size_t size,size_t num)236 windows_file_write(SDL_RWops * context, const void *ptr, size_t size,
237                  size_t num)
238 {
239 
240     size_t total_bytes;
241     DWORD byte_written;
242     size_t nwritten;
243 
244     total_bytes = size * num;
245 
246     if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE
247         || total_bytes <= 0 || !size)
248         return 0;
249 
250     if (context->hidden.windowsio.buffer.left) {
251         SetFilePointer(context->hidden.windowsio.h,
252                        -(LONG)context->hidden.windowsio.buffer.left, NULL,
253                        FILE_CURRENT);
254         context->hidden.windowsio.buffer.left = 0;
255     }
256 
257     /* if in append mode, we must go to the EOF before write */
258     if (context->hidden.windowsio.append) {
259         if (SetFilePointer(context->hidden.windowsio.h, 0L, NULL, FILE_END) ==
260             INVALID_SET_FILE_POINTER) {
261             SDL_Error(SDL_EFWRITE);
262             return 0;
263         }
264     }
265 
266     if (!WriteFile
267         (context->hidden.windowsio.h, ptr, (DWORD)total_bytes, &byte_written, NULL)) {
268         SDL_Error(SDL_EFWRITE);
269         return 0;
270     }
271 
272     nwritten = byte_written / size;
273     return nwritten;
274 }
275 
276 static int SDLCALL
windows_file_close(SDL_RWops * context)277 windows_file_close(SDL_RWops * context)
278 {
279 
280     if (context) {
281         if (context->hidden.windowsio.h != INVALID_HANDLE_VALUE) {
282             CloseHandle(context->hidden.windowsio.h);
283             context->hidden.windowsio.h = INVALID_HANDLE_VALUE;   /* to be sure */
284         }
285         SDL_free(context->hidden.windowsio.buffer.data);
286         context->hidden.windowsio.buffer.data = NULL;
287         SDL_FreeRW(context);
288     }
289     return 0;
290 }
291 #endif /* __WIN32__ */
292 
293 #ifdef HAVE_STDIO_H
294 
295 /* Functions to read/write stdio file pointers */
296 
297 static Sint64 SDLCALL
stdio_size(SDL_RWops * context)298 stdio_size(SDL_RWops * context)
299 {
300     Sint64 pos, size;
301 
302     pos = SDL_RWseek(context, 0, RW_SEEK_CUR);
303     if (pos < 0) {
304         return -1;
305     }
306     size = SDL_RWseek(context, 0, RW_SEEK_END);
307 
308     SDL_RWseek(context, pos, RW_SEEK_SET);
309     return size;
310 }
311 
312 static Sint64 SDLCALL
stdio_seek(SDL_RWops * context,Sint64 offset,int whence)313 stdio_seek(SDL_RWops * context, Sint64 offset, int whence)
314 {
315 #ifdef HAVE_FSEEKO64
316     if (fseeko64(context->hidden.stdio.fp, (off64_t)offset, whence) == 0) {
317         return ftello64(context->hidden.stdio.fp);
318     }
319 #elif defined(HAVE_FSEEKO)
320     if (fseeko(context->hidden.stdio.fp, (off_t)offset, whence) == 0) {
321         return ftello(context->hidden.stdio.fp);
322     }
323 #elif defined(HAVE__FSEEKI64)
324     if (_fseeki64(context->hidden.stdio.fp, offset, whence) == 0) {
325         return _ftelli64(context->hidden.stdio.fp);
326     }
327 #else
328     if (fseek(context->hidden.stdio.fp, offset, whence) == 0) {
329         return ftell(context->hidden.stdio.fp);
330     }
331 #endif
332     return SDL_Error(SDL_EFSEEK);
333 }
334 
335 static size_t SDLCALL
stdio_read(SDL_RWops * context,void * ptr,size_t size,size_t maxnum)336 stdio_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum)
337 {
338     size_t nread;
339 
340     nread = fread(ptr, size, maxnum, context->hidden.stdio.fp);
341     if (nread == 0 && ferror(context->hidden.stdio.fp)) {
342         SDL_Error(SDL_EFREAD);
343     }
344     return nread;
345 }
346 
347 static size_t SDLCALL
stdio_write(SDL_RWops * context,const void * ptr,size_t size,size_t num)348 stdio_write(SDL_RWops * context, const void *ptr, size_t size, size_t num)
349 {
350     size_t nwrote;
351 
352     nwrote = fwrite(ptr, size, num, context->hidden.stdio.fp);
353     if (nwrote == 0 && ferror(context->hidden.stdio.fp)) {
354         SDL_Error(SDL_EFWRITE);
355     }
356     return nwrote;
357 }
358 
359 static int SDLCALL
stdio_close(SDL_RWops * context)360 stdio_close(SDL_RWops * context)
361 {
362     int status = 0;
363     if (context) {
364         if (context->hidden.stdio.autoclose) {
365             /* WARNING:  Check the return value here! */
366             if (fclose(context->hidden.stdio.fp) != 0) {
367                 status = SDL_Error(SDL_EFWRITE);
368             }
369         }
370         SDL_FreeRW(context);
371     }
372     return status;
373 }
374 #endif /* !HAVE_STDIO_H */
375 
376 /* Functions to read/write memory pointers */
377 
378 static Sint64 SDLCALL
mem_size(SDL_RWops * context)379 mem_size(SDL_RWops * context)
380 {
381     return (Sint64)(context->hidden.mem.stop - context->hidden.mem.base);
382 }
383 
384 static Sint64 SDLCALL
mem_seek(SDL_RWops * context,Sint64 offset,int whence)385 mem_seek(SDL_RWops * context, Sint64 offset, int whence)
386 {
387     Uint8 *newpos;
388 
389     switch (whence) {
390     case RW_SEEK_SET:
391         newpos = context->hidden.mem.base + offset;
392         break;
393     case RW_SEEK_CUR:
394         newpos = context->hidden.mem.here + offset;
395         break;
396     case RW_SEEK_END:
397         newpos = context->hidden.mem.stop + offset;
398         break;
399     default:
400         return SDL_SetError("Unknown value for 'whence'");
401     }
402     if (newpos < context->hidden.mem.base) {
403         newpos = context->hidden.mem.base;
404     }
405     if (newpos > context->hidden.mem.stop) {
406         newpos = context->hidden.mem.stop;
407     }
408     context->hidden.mem.here = newpos;
409     return (Sint64)(context->hidden.mem.here - context->hidden.mem.base);
410 }
411 
412 static size_t SDLCALL
mem_read(SDL_RWops * context,void * ptr,size_t size,size_t maxnum)413 mem_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum)
414 {
415     size_t total_bytes;
416     size_t mem_available;
417 
418     total_bytes = (maxnum * size);
419     if ((maxnum <= 0) || (size <= 0)
420         || ((total_bytes / maxnum) != (size_t) size)) {
421         return 0;
422     }
423 
424     mem_available = (context->hidden.mem.stop - context->hidden.mem.here);
425     if (total_bytes > mem_available) {
426         total_bytes = mem_available;
427     }
428 
429     SDL_memcpy(ptr, context->hidden.mem.here, total_bytes);
430     context->hidden.mem.here += total_bytes;
431 
432     return (total_bytes / size);
433 }
434 
435 static size_t SDLCALL
mem_write(SDL_RWops * context,const void * ptr,size_t size,size_t num)436 mem_write(SDL_RWops * context, const void *ptr, size_t size, size_t num)
437 {
438     if ((context->hidden.mem.here + (num * size)) > context->hidden.mem.stop) {
439         num = (context->hidden.mem.stop - context->hidden.mem.here) / size;
440     }
441     SDL_memcpy(context->hidden.mem.here, ptr, num * size);
442     context->hidden.mem.here += num * size;
443     return num;
444 }
445 
446 static size_t SDLCALL
mem_writeconst(SDL_RWops * context,const void * ptr,size_t size,size_t num)447 mem_writeconst(SDL_RWops * context, const void *ptr, size_t size, size_t num)
448 {
449     SDL_SetError("Can't write to read-only memory");
450     return 0;
451 }
452 
453 static int SDLCALL
mem_close(SDL_RWops * context)454 mem_close(SDL_RWops * context)
455 {
456     if (context) {
457         SDL_FreeRW(context);
458     }
459     return 0;
460 }
461 
462 
463 /* Functions to create SDL_RWops structures from various data sources */
464 
465 SDL_RWops *
SDL_RWFromFile(const char * file,const char * mode)466 SDL_RWFromFile(const char *file, const char *mode)
467 {
468     SDL_RWops *rwops = NULL;
469     if (!file || !*file || !mode || !*mode) {
470         SDL_SetError("SDL_RWFromFile(): No file or no mode specified");
471         return NULL;
472     }
473 #if defined(__ANDROID__)
474 #ifdef HAVE_STDIO_H
475     /* Try to open the file on the filesystem first */
476     if (*file == '/') {
477         FILE *fp = fopen(file, mode);
478         if (fp) {
479             return SDL_RWFromFP(fp, 1);
480         }
481     } else {
482         /* Try opening it from internal storage if it's a relative path */
483         char *path;
484         FILE *fp;
485 
486         path = SDL_stack_alloc(char, PATH_MAX);
487         if (path) {
488             SDL_snprintf(path, PATH_MAX, "%s/%s",
489                          SDL_AndroidGetInternalStoragePath(), file);
490             fp = fopen(path, mode);
491             SDL_stack_free(path);
492             if (fp) {
493                 return SDL_RWFromFP(fp, 1);
494             }
495         }
496     }
497 #endif /* HAVE_STDIO_H */
498 
499     /* Try to open the file from the asset system */
500     rwops = SDL_AllocRW();
501     if (!rwops)
502         return NULL;            /* SDL_SetError already setup by SDL_AllocRW() */
503     if (Android_JNI_FileOpen(rwops, file, mode) < 0) {
504         SDL_FreeRW(rwops);
505         return NULL;
506     }
507     rwops->size = Android_JNI_FileSize;
508     rwops->seek = Android_JNI_FileSeek;
509     rwops->read = Android_JNI_FileRead;
510     rwops->write = Android_JNI_FileWrite;
511     rwops->close = Android_JNI_FileClose;
512     rwops->type = SDL_RWOPS_JNIFILE;
513 
514 #elif defined(__WIN32__)
515     rwops = SDL_AllocRW();
516     if (!rwops)
517         return NULL;            /* SDL_SetError already setup by SDL_AllocRW() */
518     if (windows_file_open(rwops, file, mode) < 0) {
519         SDL_FreeRW(rwops);
520         return NULL;
521     }
522     rwops->size = windows_file_size;
523     rwops->seek = windows_file_seek;
524     rwops->read = windows_file_read;
525     rwops->write = windows_file_write;
526     rwops->close = windows_file_close;
527     rwops->type = SDL_RWOPS_WINFILE;
528 
529 #elif HAVE_STDIO_H
530     {
531         #ifdef __APPLE__
532         FILE *fp = SDL_OpenFPFromBundleOrFallback(file, mode);
533         #elif __WINRT__
534         FILE *fp = NULL;
535         fopen_s(&fp, file, mode);
536         #else
537         FILE *fp = fopen(file, mode);
538         #endif
539         if (fp == NULL) {
540             SDL_SetError("Couldn't open %s", file);
541         } else {
542             rwops = SDL_RWFromFP(fp, 1);
543         }
544     }
545 #else
546     SDL_SetError("SDL not compiled with stdio support");
547 #endif /* !HAVE_STDIO_H */
548 
549     return rwops;
550 }
551 
552 #ifdef HAVE_STDIO_H
553 SDL_RWops *
SDL_RWFromFP(FILE * fp,SDL_bool autoclose)554 SDL_RWFromFP(FILE * fp, SDL_bool autoclose)
555 {
556     SDL_RWops *rwops = NULL;
557 
558     rwops = SDL_AllocRW();
559     if (rwops != NULL) {
560         rwops->size = stdio_size;
561         rwops->seek = stdio_seek;
562         rwops->read = stdio_read;
563         rwops->write = stdio_write;
564         rwops->close = stdio_close;
565         rwops->hidden.stdio.fp = fp;
566         rwops->hidden.stdio.autoclose = autoclose;
567         rwops->type = SDL_RWOPS_STDFILE;
568     }
569     return rwops;
570 }
571 #else
572 SDL_RWops *
SDL_RWFromFP(void * fp,SDL_bool autoclose)573 SDL_RWFromFP(void * fp, SDL_bool autoclose)
574 {
575     SDL_SetError("SDL not compiled with stdio support");
576     return NULL;
577 }
578 #endif /* HAVE_STDIO_H */
579 
580 SDL_RWops *
SDL_RWFromMem(void * mem,int size)581 SDL_RWFromMem(void *mem, int size)
582 {
583     SDL_RWops *rwops = NULL;
584     if (!mem) {
585       SDL_InvalidParamError("mem");
586       return rwops;
587     }
588     if (!size) {
589       SDL_InvalidParamError("size");
590       return rwops;
591     }
592 
593     rwops = SDL_AllocRW();
594     if (rwops != NULL) {
595         rwops->size = mem_size;
596         rwops->seek = mem_seek;
597         rwops->read = mem_read;
598         rwops->write = mem_write;
599         rwops->close = mem_close;
600         rwops->hidden.mem.base = (Uint8 *) mem;
601         rwops->hidden.mem.here = rwops->hidden.mem.base;
602         rwops->hidden.mem.stop = rwops->hidden.mem.base + size;
603         rwops->type = SDL_RWOPS_MEMORY;
604     }
605     return rwops;
606 }
607 
608 SDL_RWops *
SDL_RWFromConstMem(const void * mem,int size)609 SDL_RWFromConstMem(const void *mem, int size)
610 {
611     SDL_RWops *rwops = NULL;
612     if (!mem) {
613       SDL_InvalidParamError("mem");
614       return rwops;
615     }
616     if (!size) {
617       SDL_InvalidParamError("size");
618       return rwops;
619     }
620 
621     rwops = SDL_AllocRW();
622     if (rwops != NULL) {
623         rwops->size = mem_size;
624         rwops->seek = mem_seek;
625         rwops->read = mem_read;
626         rwops->write = mem_writeconst;
627         rwops->close = mem_close;
628         rwops->hidden.mem.base = (Uint8 *) mem;
629         rwops->hidden.mem.here = rwops->hidden.mem.base;
630         rwops->hidden.mem.stop = rwops->hidden.mem.base + size;
631         rwops->type = SDL_RWOPS_MEMORY_RO;
632     }
633     return rwops;
634 }
635 
636 SDL_RWops *
SDL_AllocRW(void)637 SDL_AllocRW(void)
638 {
639     SDL_RWops *area;
640 
641     area = (SDL_RWops *) SDL_malloc(sizeof *area);
642     if (area == NULL) {
643         SDL_OutOfMemory();
644     } else {
645         area->type = SDL_RWOPS_UNKNOWN;
646     }
647     return area;
648 }
649 
650 void
SDL_FreeRW(SDL_RWops * area)651 SDL_FreeRW(SDL_RWops * area)
652 {
653     SDL_free(area);
654 }
655 
656 /* Functions for dynamically reading and writing endian-specific values */
657 
658 Uint8
SDL_ReadU8(SDL_RWops * src)659 SDL_ReadU8(SDL_RWops * src)
660 {
661     Uint8 value = 0;
662 
663     SDL_RWread(src, &value, sizeof (value), 1);
664     return value;
665 }
666 
667 Uint16
SDL_ReadLE16(SDL_RWops * src)668 SDL_ReadLE16(SDL_RWops * src)
669 {
670     Uint16 value = 0;
671 
672     SDL_RWread(src, &value, sizeof (value), 1);
673     return SDL_SwapLE16(value);
674 }
675 
676 Uint16
SDL_ReadBE16(SDL_RWops * src)677 SDL_ReadBE16(SDL_RWops * src)
678 {
679     Uint16 value = 0;
680 
681     SDL_RWread(src, &value, sizeof (value), 1);
682     return SDL_SwapBE16(value);
683 }
684 
685 Uint32
SDL_ReadLE32(SDL_RWops * src)686 SDL_ReadLE32(SDL_RWops * src)
687 {
688     Uint32 value = 0;
689 
690     SDL_RWread(src, &value, sizeof (value), 1);
691     return SDL_SwapLE32(value);
692 }
693 
694 Uint32
SDL_ReadBE32(SDL_RWops * src)695 SDL_ReadBE32(SDL_RWops * src)
696 {
697     Uint32 value = 0;
698 
699     SDL_RWread(src, &value, sizeof (value), 1);
700     return SDL_SwapBE32(value);
701 }
702 
703 Uint64
SDL_ReadLE64(SDL_RWops * src)704 SDL_ReadLE64(SDL_RWops * src)
705 {
706     Uint64 value = 0;
707 
708     SDL_RWread(src, &value, sizeof (value), 1);
709     return SDL_SwapLE64(value);
710 }
711 
712 Uint64
SDL_ReadBE64(SDL_RWops * src)713 SDL_ReadBE64(SDL_RWops * src)
714 {
715     Uint64 value = 0;
716 
717     SDL_RWread(src, &value, sizeof (value), 1);
718     return SDL_SwapBE64(value);
719 }
720 
721 size_t
SDL_WriteU8(SDL_RWops * dst,Uint8 value)722 SDL_WriteU8(SDL_RWops * dst, Uint8 value)
723 {
724     return SDL_RWwrite(dst, &value, sizeof (value), 1);
725 }
726 
727 size_t
SDL_WriteLE16(SDL_RWops * dst,Uint16 value)728 SDL_WriteLE16(SDL_RWops * dst, Uint16 value)
729 {
730     const Uint16 swapped = SDL_SwapLE16(value);
731     return SDL_RWwrite(dst, &swapped, sizeof (swapped), 1);
732 }
733 
734 size_t
SDL_WriteBE16(SDL_RWops * dst,Uint16 value)735 SDL_WriteBE16(SDL_RWops * dst, Uint16 value)
736 {
737     const Uint16 swapped = SDL_SwapBE16(value);
738     return SDL_RWwrite(dst, &swapped, sizeof (swapped), 1);
739 }
740 
741 size_t
SDL_WriteLE32(SDL_RWops * dst,Uint32 value)742 SDL_WriteLE32(SDL_RWops * dst, Uint32 value)
743 {
744     const Uint32 swapped = SDL_SwapLE32(value);
745     return SDL_RWwrite(dst, &swapped, sizeof (swapped), 1);
746 }
747 
748 size_t
SDL_WriteBE32(SDL_RWops * dst,Uint32 value)749 SDL_WriteBE32(SDL_RWops * dst, Uint32 value)
750 {
751     const Uint32 swapped = SDL_SwapBE32(value);
752     return SDL_RWwrite(dst, &swapped, sizeof (swapped), 1);
753 }
754 
755 size_t
SDL_WriteLE64(SDL_RWops * dst,Uint64 value)756 SDL_WriteLE64(SDL_RWops * dst, Uint64 value)
757 {
758     const Uint64 swapped = SDL_SwapLE64(value);
759     return SDL_RWwrite(dst, &swapped, sizeof (swapped), 1);
760 }
761 
762 size_t
SDL_WriteBE64(SDL_RWops * dst,Uint64 value)763 SDL_WriteBE64(SDL_RWops * dst, Uint64 value)
764 {
765     const Uint64 swapped = SDL_SwapBE64(value);
766     return SDL_RWwrite(dst, &swapped, sizeof (swapped), 1);
767 }
768 
769 /* vi: set ts=4 sw=4 expandtab: */
770