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