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