Added an API to get the size of a file - WARNING! ABI CHANGE!
authorSam Lantinga <slouken@libsdl.org>
Sat, 03 Nov 2012 18:43:36 -0700
changeset 6642b716011e53ce
parent 6641 45187a87d35b
child 6643 673aed697ce6
Added an API to get the size of a file - WARNING! ABI CHANGE!
configure
configure.in
include/SDL_config.h.in
include/SDL_rwops.h
src/core/android/SDL_android.cpp
src/core/android/SDL_android.h
src/file/SDL_rwops.c
     1.1 --- a/configure	Sat Nov 03 12:11:49 2012 -0400
     1.2 +++ b/configure	Sat Nov 03 18:43:36 2012 -0700
     1.3 @@ -16688,7 +16688,7 @@
     1.4  rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
     1.5  fi
     1.6  
     1.7 -    for ac_func in malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove strlen strlcpy strlcat strdup _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp sscanf snprintf vsnprintf sigaction setjmp nanosleep sysconf sysctlbyname
     1.8 +    for ac_func in malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove strlen strlcpy strlcat strdup _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp sscanf snprintf vsnprintf fseeko fseeko64 sigaction setjmp nanosleep sysconf sysctlbyname
     1.9  do :
    1.10    as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
    1.11  ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
     2.1 --- a/configure.in	Sat Nov 03 12:11:49 2012 -0400
     2.2 +++ b/configure.in	Sat Nov 03 18:43:36 2012 -0700
     2.3 @@ -237,7 +237,7 @@
     2.4          AC_DEFINE(HAVE_MPROTECT, 1, [ ])
     2.5          ]),
     2.6      )
     2.7 -    AC_CHECK_FUNCS(malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove strlen strlcpy strlcat strdup _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp sscanf snprintf vsnprintf sigaction setjmp nanosleep sysconf sysctlbyname)
     2.8 +    AC_CHECK_FUNCS(malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove strlen strlcpy strlcat strdup _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp sscanf snprintf vsnprintf fseeko fseeko64 sigaction setjmp nanosleep sysconf sysctlbyname)
     2.9  
    2.10      AC_CHECK_LIB(m, pow, [LIBS="$LIBS -lm"; EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lm"])
    2.11      AC_CHECK_FUNCS(atan atan2 ceil copysign cos cosf fabs floor log pow scalbn sin sinf sqrt)
     3.1 --- a/include/SDL_config.h.in	Sat Nov 03 12:11:49 2012 -0400
     3.2 +++ b/include/SDL_config.h.in	Sat Nov 03 18:43:36 2012 -0700
     3.3 @@ -139,6 +139,8 @@
     3.4  #undef HAVE_SIN
     3.5  #undef HAVE_SINF
     3.6  #undef HAVE_SQRT
     3.7 +#undef HAVE_FSEEKO
     3.8 +#undef HAVE_FSEEKO64
     3.9  #undef HAVE_SIGACTION
    3.10  #undef HAVE_SA_SIGACTION
    3.11  #undef HAVE_SETJMP
     4.1 --- a/include/SDL_rwops.h	Sat Nov 03 12:11:49 2012 -0400
     4.2 +++ b/include/SDL_rwops.h	Sat Nov 03 18:43:36 2012 -0700
     4.3 @@ -46,13 +46,18 @@
     4.4  typedef struct SDL_RWops
     4.5  {
     4.6      /**
     4.7 +     *  Return the size of the file in this rwops, or -1 if unknown
     4.8 +     */
     4.9 +    Sint64 (SDLCALL * size) (struct SDL_RWops * context);
    4.10 +
    4.11 +    /**
    4.12       *  Seek to \c offset relative to \c whence, one of stdio's whence values:
    4.13       *  RW_SEEK_SET, RW_SEEK_CUR, RW_SEEK_END
    4.14       *  
    4.15       *  \return the final offset in the data stream.
    4.16       */
    4.17 -    long (SDLCALL * seek) (struct SDL_RWops * context, long offset,
    4.18 -                           int whence);
    4.19 +    Sint64 (SDLCALL * seek) (struct SDL_RWops * context, Sint64 offset,
    4.20 +                             int whence);
    4.21  
    4.22      /**
    4.23       *  Read up to \c maxnum objects each of size \c size from the data
    4.24 @@ -60,8 +65,8 @@
    4.25       *  
    4.26       *  \return the number of objects read, or 0 at error or end of file.
    4.27       */
    4.28 -    size_t(SDLCALL * read) (struct SDL_RWops * context, void *ptr,
    4.29 -                            size_t size, size_t maxnum);
    4.30 +    size_t (SDLCALL * read) (struct SDL_RWops * context, void *ptr,
    4.31 +                             size_t size, size_t maxnum);
    4.32  
    4.33      /**
    4.34       *  Write exactly \c num objects each of size \c size from the area
    4.35 @@ -69,8 +74,8 @@
    4.36       *  
    4.37       *  \return the number of objects written, or 0 at error or end of file.
    4.38       */
    4.39 -    size_t(SDLCALL * write) (struct SDL_RWops * context, const void *ptr,
    4.40 -                             size_t size, size_t num);
    4.41 +    size_t (SDLCALL * write) (struct SDL_RWops * context, const void *ptr,
    4.42 +                              size_t size, size_t num);
    4.43  
    4.44      /**
    4.45       *  Close and free an allocated SDL_RWops structure.
    4.46 @@ -166,6 +171,7 @@
    4.47   *  Macros to easily read and write from an SDL_RWops structure.
    4.48   */
    4.49  /*@{*/
    4.50 +#define SDL_RWsize(ctx)	        (ctx)->size(ctx)
    4.51  #define SDL_RWseek(ctx, offset, whence)	(ctx)->seek(ctx, offset, whence)
    4.52  #define SDL_RWtell(ctx)			(ctx)->seek(ctx, 0, RW_SEEK_CUR)
    4.53  #define SDL_RWread(ctx, ptr, size, n)	(ctx)->read(ctx, ptr, size, n)
     5.1 --- a/src/core/android/SDL_android.cpp	Sat Nov 03 12:11:49 2012 -0400
     5.2 +++ b/src/core/android/SDL_android.cpp	Sat Nov 03 18:43:36 2012 -0700
     5.3 @@ -696,9 +696,14 @@
     5.4  }
     5.5  
     5.6  
     5.7 -extern "C" long Android_JNI_FileSeek(SDL_RWops* ctx, long offset, int whence)
     5.8 +extern "C" Sint64 Android_JNI_FileSize(SDL_RWops* ctx)
     5.9  {
    5.10 -    long newPosition;
    5.11 +    return ctx->hidden.androidio.size;
    5.12 +}
    5.13 +
    5.14 +extern "C" Sint64 Android_JNI_FileSeek(SDL_RWops* ctx, Sint64 offset, int whence)
    5.15 +{
    5.16 +    Sint64 newPosition;
    5.17  
    5.18      switch (whence) {
    5.19          case RW_SEEK_SET:
    5.20 @@ -714,27 +719,27 @@
    5.21              SDL_SetError("Unknown value for 'whence'");
    5.22              return -1;
    5.23      }
    5.24 +
    5.25 +    /* Validate the new position */
    5.26      if (newPosition < 0) {
    5.27 -        newPosition = 0;
    5.28 +        SDL_Error(SDL_EFSEEK);
    5.29 +        return -1;
    5.30      }
    5.31      if (newPosition > ctx->hidden.androidio.size) {
    5.32          newPosition = ctx->hidden.androidio.size;
    5.33      }
    5.34  
    5.35 -    long movement = newPosition - ctx->hidden.androidio.position;
    5.36 -    jobject inputStream = (jobject)ctx->hidden.androidio.inputStreamRef;
    5.37 -
    5.38 +    Sint64 movement = newPosition - ctx->hidden.androidio.position;
    5.39      if (movement > 0) {
    5.40          unsigned char buffer[1024];
    5.41  
    5.42          // The easy case where we're seeking forwards
    5.43          while (movement > 0) {
    5.44 -            long amount = (long) sizeof (buffer);
    5.45 +            Sint64 amount = sizeof (buffer);
    5.46              if (amount > movement) {
    5.47                  amount = movement;
    5.48              }
    5.49              size_t result = Android_JNI_FileRead(ctx, buffer, 1, amount);
    5.50 -
    5.51              if (result <= 0) {
    5.52                  // Failed to read/skip the required amount, so fail
    5.53                  return -1;
    5.54 @@ -742,6 +747,7 @@
    5.55  
    5.56              movement -= result;
    5.57          }
    5.58 +
    5.59      } else if (movement < 0) {
    5.60          // We can't seek backwards so we have to reopen the file and seek
    5.61          // forwards which obviously isn't very efficient
    5.62 @@ -750,8 +756,6 @@
    5.63          Android_JNI_FileSeek(ctx, newPosition, RW_SEEK_SET);
    5.64      }
    5.65  
    5.66 -    ctx->hidden.androidio.position = newPosition;
    5.67 -
    5.68      return ctx->hidden.androidio.position;
    5.69  }
    5.70  
     6.1 --- a/src/core/android/SDL_android.h	Sat Nov 03 12:11:49 2012 -0400
     6.2 +++ b/src/core/android/SDL_android.h	Sat Nov 03 18:43:36 2012 -0700
     6.3 @@ -45,7 +45,8 @@
     6.4  #include "SDL_rwops.h"
     6.5  
     6.6  int Android_JNI_FileOpen(SDL_RWops* ctx, const char* fileName, const char* mode);
     6.7 -long Android_JNI_FileSeek(SDL_RWops* ctx, long offset, int whence);
     6.8 +Sint64 Android_JNI_FileSize(SDL_RWops* ctx);
     6.9 +Sint64 Android_JNI_FileSeek(SDL_RWops* ctx, Sint64 offset, int whence);
    6.10  size_t Android_JNI_FileRead(SDL_RWops* ctx, void* buffer, size_t size, size_t maxnum);
    6.11  size_t Android_JNI_FileWrite(SDL_RWops* ctx, const void* buffer, size_t size, size_t num);
    6.12  int Android_JNI_FileClose(SDL_RWops* ctx);
     7.1 --- a/src/file/SDL_rwops.c	Sat Nov 03 12:11:49 2012 -0400
     7.2 +++ b/src/file/SDL_rwops.c	Sat Nov 03 18:43:36 2012 -0700
     7.3 @@ -121,11 +121,29 @@
     7.4      return 0;                   /* ok */
     7.5  }
     7.6  
     7.7 -static long SDLCALL
     7.8 -windows_file_seek(SDL_RWops * context, long offset, int whence)
     7.9 +static Sint64 SDLCALL
    7.10 +windows_file_size(SDL_RWops * context)
    7.11 +{
    7.12 +    LARGE_INTEGER size;
    7.13 +
    7.14 +    if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE) {
    7.15 +        SDL_SetError("windows_file_size: invalid context/file not opened");
    7.16 +        return -1;
    7.17 +    }
    7.18 +
    7.19 +    if (!GetFileSizeEx(context->hidden.windowsio.h, &size)) {
    7.20 +        WIN_SetError("windows_file_size");
    7.21 +        return -1;
    7.22 +    }
    7.23 +
    7.24 +    return size.QuadPart;
    7.25 +}
    7.26 +
    7.27 +static Sint64 SDLCALL
    7.28 +windows_file_seek(SDL_RWops * context, Sint64 offset, int whence)
    7.29  {
    7.30      DWORD windowswhence;
    7.31 -    long file_pos;
    7.32 +    LARGE_INTEGER windowsoffset;
    7.33  
    7.34      if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE) {
    7.35          SDL_SetError("windows_file_seek: invalid context/file not opened");
    7.36 @@ -153,14 +171,12 @@
    7.37          return -1;
    7.38      }
    7.39  
    7.40 -    file_pos =
    7.41 -        SetFilePointer(context->hidden.windowsio.h, offset, NULL, windowswhence);
    7.42 -
    7.43 -    if (file_pos != INVALID_SET_FILE_POINTER)
    7.44 -        return file_pos;        /* success */
    7.45 -
    7.46 -    SDL_Error(SDL_EFSEEK);
    7.47 -    return -1;                  /* error */
    7.48 +    windowsoffset.QuadPart = offset;
    7.49 +    if (!SetFilePointerEx(context->hidden.windowsio.h, windowsoffset, &windowsoffset, windowswhence)) {
    7.50 +        WIN_SetError("windows_file_seek");
    7.51 +        return -1;
    7.52 +    }
    7.53 +    return windowsoffset.QuadPart;
    7.54  }
    7.55  
    7.56  static size_t SDLCALL
    7.57 @@ -281,15 +297,39 @@
    7.58  
    7.59  /* Functions to read/write stdio file pointers */
    7.60  
    7.61 -static long SDLCALL
    7.62 -stdio_seek(SDL_RWops * context, long offset, int whence)
    7.63 +static Sint64 SDLCALL
    7.64 +stdio_size(SDL_RWops * context)
    7.65  {
    7.66 +    Sint64 pos, size;
    7.67 +
    7.68 +    pos = SDL_RWseek(context, 0, RW_SEEK_CUR);
    7.69 +    if (pos < 0) {
    7.70 +        return -1;
    7.71 +    }
    7.72 +    size = SDL_RWseek(context, 0, RW_SEEK_END);
    7.73 +
    7.74 +    SDL_RWseek(context, pos, RW_SEEK_SET);
    7.75 +    return size;
    7.76 +}
    7.77 +
    7.78 +static Sint64 SDLCALL
    7.79 +stdio_seek(SDL_RWops * context, Sint64 offset, int whence)
    7.80 +{
    7.81 +#ifdef HAVE_FSEEKO64
    7.82 +    if (fseek64o(context->hidden.stdio.fp, (off64_t)offset, whence) == 0) {
    7.83 +        return ftell64o(context->hidden.stdio.fp);
    7.84 +    }
    7.85 +#elif defined(HAVE_FSEEKO)
    7.86 +    if (fseeko(context->hidden.stdio.fp, (off_t)offset, whence) == 0) {
    7.87 +        return ftello(context->hidden.stdio.fp);
    7.88 +    }
    7.89 +#else
    7.90      if (fseek(context->hidden.stdio.fp, offset, whence) == 0) {
    7.91          return (ftell(context->hidden.stdio.fp));
    7.92 -    } else {
    7.93 -        SDL_Error(SDL_EFSEEK);
    7.94 -        return (-1);
    7.95      }
    7.96 +#endif
    7.97 +    SDL_Error(SDL_EFSEEK);
    7.98 +    return (-1);
    7.99  }
   7.100  
   7.101  static size_t SDLCALL
   7.102 @@ -336,8 +376,14 @@
   7.103  
   7.104  /* Functions to read/write memory pointers */
   7.105  
   7.106 -static long SDLCALL
   7.107 -mem_seek(SDL_RWops * context, long offset, int whence)
   7.108 +static Sint64 SDLCALL
   7.109 +mem_size(SDL_RWops * context)
   7.110 +{
   7.111 +    return (Sint64)(context->hidden.mem.stop - context->hidden.mem.base);
   7.112 +}
   7.113 +
   7.114 +static Sint64 SDLCALL
   7.115 +mem_seek(SDL_RWops * context, Sint64 offset, int whence)
   7.116  {
   7.117      Uint8 *newpos;
   7.118  
   7.119 @@ -362,7 +408,7 @@
   7.120          newpos = context->hidden.mem.stop;
   7.121      }
   7.122      context->hidden.mem.here = newpos;
   7.123 -    return (long)(context->hidden.mem.here - context->hidden.mem.base);
   7.124 +    return (Sint64)(context->hidden.mem.here - context->hidden.mem.base);
   7.125  }
   7.126  
   7.127  static size_t SDLCALL
   7.128 @@ -460,6 +506,7 @@
   7.129          SDL_FreeRW(rwops);
   7.130          return NULL;
   7.131      }
   7.132 +    rwops->size = Android_JNI_FileSize;
   7.133      rwops->seek = Android_JNI_FileSeek;
   7.134      rwops->read = Android_JNI_FileRead;
   7.135      rwops->write = Android_JNI_FileWrite;
   7.136 @@ -473,6 +520,7 @@
   7.137          SDL_FreeRW(rwops);
   7.138          return NULL;
   7.139      }
   7.140 +    rwops->size = windows_file_size;
   7.141      rwops->seek = windows_file_seek;
   7.142      rwops->read = windows_file_read;
   7.143      rwops->write = windows_file_write;
   7.144 @@ -513,6 +561,7 @@
   7.145  
   7.146      rwops = SDL_AllocRW();
   7.147      if (rwops != NULL) {
   7.148 +        rwops->size = stdio_size;
   7.149          rwops->seek = stdio_seek;
   7.150          rwops->read = stdio_read;
   7.151          rwops->write = stdio_write;
   7.152 @@ -538,6 +587,7 @@
   7.153  
   7.154      rwops = SDL_AllocRW();
   7.155      if (rwops != NULL) {
   7.156 +        rwops->size = mem_size;
   7.157          rwops->seek = mem_seek;
   7.158          rwops->read = mem_read;
   7.159          rwops->write = mem_write;
   7.160 @@ -556,6 +606,7 @@
   7.161  
   7.162      rwops = SDL_AllocRW();
   7.163      if (rwops != NULL) {
   7.164 +        rwops->size = mem_size;
   7.165          rwops->seek = mem_seek;
   7.166          rwops->read = mem_read;
   7.167          rwops->write = mem_writeconst;