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