Timothy B. Terriberry
2013-May-05 14:54 UTC
[PATCH] Use fgetpos/fsetpos for 64-bit win32 fseek/ftell.
This should work on pre-Vista versions of Windows without requiring the distribution of any extra runtime libraries. --- include/share/compat.h | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/include/share/compat.h b/include/share/compat.h index 222de65..f6a1500 100644 --- a/include/share/compat.h +++ b/include/share/compat.h @@ -45,18 +45,54 @@ #else # include <unistd.h> #endif #if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__ #include <sys/types.h> /* for off_t */ #define FLAC__off_t __int64 /* use this instead of off_t to fix the 2 GB limit */ #if !defined __MINGW32__ -#define fseeko _fseeki64 -#define ftello _ftelli64 +#include <stdio.h> +#define FLAC__off_t_MAX ((2*(((FLAC__off_t)1<<62)-1))|1) +static __inline int +fseeko(FILE *stream, FLAC__off_t offset, int whence) +{ + FLAC__off_t pos; + if(whence == SEEK_CUR) { + int ret; + ret = fgetpos(stream, (fpos_t *)&pos); + if(ret) { + return ret; + } + } + else if(whence == SEEK_END) { + pos = _filelengthi64(_fileno(stream)); + } + else if(whence == SEEK_SET) { + pos = 0; + } + else { + errno = EINVAL; + return -1; + } + if(pos < 0 || offset < -pos || offset > FLAC__off_t_MAX - pos) { + /* MSVCRT maps ERROR_NEGATIVE_SEEK to EINVAL. */ + errno = EINVAL; + return -1; + } + pos += offset; + return fsetpos(stream, (fpos_t *)&pos); +} + +static __inline FLAC__off_t +ftello(FILE *stream) +{ + FLAC__off_t pos; + return fgetpos(stream, (fpos_t *)&pos) ? -1 : pos; +} #else /* MinGW */ #if !defined(HAVE_FSEEKO) #define fseeko fseeko64 #define ftello ftello64 #endif #endif #else #define FLAC__off_t off_t -- 1.7.12 --------------010000020009030100080103--