X-Git-Url: https://scm.cri.ensmp.fr/git/Faustine.git/blobdiff_plain/1059e1cc0c2ecfa237406949aa26155b6a5b9154..66f23d4fabf89ad09adbd4dfc15ac6b5b2b7da83:/interpretor/lib/src/libsndfile-1.0.25/src/file_io.c diff --git a/interpretor/lib/src/libsndfile-1.0.25/src/file_io.c b/interpretor/lib/src/libsndfile-1.0.25/src/file_io.c deleted file mode 100644 index 44f1b5a..0000000 --- a/interpretor/lib/src/libsndfile-1.0.25/src/file_io.c +++ /dev/null @@ -1,1547 +0,0 @@ -/* -** Copyright (C) 2002-2011 Erik de Castro Lopo -** Copyright (C) 2003 Ross Bencina -** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU Lesser General Public License as published by -** the Free Software Foundation; either version 2.1 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU Lesser General Public License for more details. -** -** You should have received a copy of the GNU Lesser General Public License -** along with this program; if not, write to the Free Software -** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -/* -** The file is split into three sections as follows: -** - The top section (USE_WINDOWS_API == 0) for Linux, Unix and MacOSX -** systems (including Cygwin). -** - The middle section (USE_WINDOWS_API == 1) for microsoft windows -** (including MinGW) using the native windows API. -** - A legacy windows section which attempted to work around grevious -** bugs in microsoft's POSIX implementation. -*/ - -/* -** The header file sfconfig.h MUST be included before the others to ensure -** that large file support is enabled correctly on Unix systems. -*/ - -#include "sfconfig.h" - -#include -#include - -#if HAVE_UNISTD_H -#include -#endif - -#if (HAVE_DECL_S_IRGRP == 0) -#include -#endif - -#include -#include -#include -#include - -#include "sndfile.h" -#include "common.h" - -#define SENSIBLE_SIZE (0x40000000) - -/* -** Neat solution to the Win32/OS2 binary file flage requirement. -** If O_BINARY isn't already defined by the inclusion of the system -** headers, set it to zero. -*/ -#ifndef O_BINARY -#define O_BINARY 0 -#endif - -static void psf_log_syserr (SF_PRIVATE *psf, int error) ; - -#if (USE_WINDOWS_API == 0) - -/*------------------------------------------------------------------------------ -** Win32 stuff at the bottom of the file. Unix and other sensible OSes here. -*/ - -static int psf_close_fd (int fd) ; -static int psf_open_fd (PSF_FILE * pfile) ; -static sf_count_t psf_get_filelen_fd (int fd) ; - -int -psf_fopen (SF_PRIVATE *psf) -{ - psf->error = 0 ; - psf->file.filedes = psf_open_fd (&psf->file) ; - - if (psf->file.filedes == - SFE_BAD_OPEN_MODE) - { psf->error = SFE_BAD_OPEN_MODE ; - psf->file.filedes = -1 ; - return psf->error ; - } ; - - if (psf->file.filedes == -1) - psf_log_syserr (psf, errno) ; - - return psf->error ; -} /* psf_fopen */ - -int -psf_fclose (SF_PRIVATE *psf) -{ int retval ; - - if (psf->virtual_io) - return 0 ; - - if (psf->file.do_not_close_descriptor) - { psf->file.filedes = -1 ; - return 0 ; - } ; - - if ((retval = psf_close_fd (psf->file.filedes)) == -1) - psf_log_syserr (psf, errno) ; - - psf->file.filedes = -1 ; - - return retval ; -} /* psf_fclose */ - -int -psf_open_rsrc (SF_PRIVATE *psf) -{ - if (psf->rsrc.filedes > 0) - return 0 ; - - /* Test for MacOSX style resource fork on HPFS or HPFS+ filesystems. */ - snprintf (psf->rsrc.path.c, sizeof (psf->rsrc.path.c), "%s/rsrc", psf->file.path.c) ; - psf->error = SFE_NO_ERROR ; - if ((psf->rsrc.filedes = psf_open_fd (&psf->rsrc)) >= 0) - { psf->rsrclength = psf_get_filelen_fd (psf->rsrc.filedes) ; - if (psf->rsrclength > 0 || (psf->rsrc.mode & SFM_WRITE)) - return SFE_NO_ERROR ; - psf_close_fd (psf->rsrc.filedes) ; - psf->rsrc.filedes = -1 ; - } ; - - if (psf->rsrc.filedes == - SFE_BAD_OPEN_MODE) - { psf->error = SFE_BAD_OPEN_MODE ; - return psf->error ; - } ; - - /* - ** Now try for a resource fork stored as a separate file in the same - ** directory, but preceded with a dot underscore. - */ - snprintf (psf->rsrc.path.c, sizeof (psf->rsrc.path.c), "%s._%s", psf->file.dir.c, psf->file.name.c) ; - psf->error = SFE_NO_ERROR ; - if ((psf->rsrc.filedes = psf_open_fd (&psf->rsrc)) >= 0) - { psf->rsrclength = psf_get_filelen_fd (psf->rsrc.filedes) ; - return SFE_NO_ERROR ; - } ; - - /* - ** Now try for a resource fork stored in a separate file in the - ** .AppleDouble/ directory. - */ - snprintf (psf->rsrc.path.c, sizeof (psf->rsrc.path.c), "%s.AppleDouble/%s", psf->file.dir.c, psf->file.name.c) ; - psf->error = SFE_NO_ERROR ; - if ((psf->rsrc.filedes = psf_open_fd (&psf->rsrc)) >= 0) - { psf->rsrclength = psf_get_filelen_fd (psf->rsrc.filedes) ; - return SFE_NO_ERROR ; - } ; - - /* No resource file found. */ - if (psf->rsrc.filedes == -1) - psf_log_syserr (psf, errno) ; - - psf->rsrc.filedes = -1 ; - - return psf->error ; -} /* psf_open_rsrc */ - -sf_count_t -psf_get_filelen (SF_PRIVATE *psf) -{ sf_count_t filelen ; - - if (psf->virtual_io) - return psf->vio.get_filelen (psf->vio_user_data) ; - - filelen = psf_get_filelen_fd (psf->file.filedes) ; - - if (filelen == -1) - { psf_log_syserr (psf, errno) ; - return (sf_count_t) -1 ; - } ; - - if (filelen == -SFE_BAD_STAT_SIZE) - { psf->error = SFE_BAD_STAT_SIZE ; - return (sf_count_t) -1 ; - } ; - - switch (psf->file.mode) - { case SFM_WRITE : - filelen = filelen - psf->fileoffset ; - break ; - - case SFM_READ : - if (psf->fileoffset > 0 && psf->filelength > 0) - filelen = psf->filelength ; - break ; - - case SFM_RDWR : - /* - ** Cannot open embedded files SFM_RDWR so we don't need to - ** subtract psf->fileoffset. We already have the answer we - ** need. - */ - break ; - - default : - /* Shouldn't be here, so return error. */ - filelen = -1 ; - } ; - - return filelen ; -} /* psf_get_filelen */ - -int -psf_close_rsrc (SF_PRIVATE *psf) -{ psf_close_fd (psf->rsrc.filedes) ; - psf->rsrc.filedes = -1 ; - return 0 ; -} /* psf_close_rsrc */ - -int -psf_set_stdio (SF_PRIVATE *psf) -{ int error = 0 ; - - switch (psf->file.mode) - { case SFM_RDWR : - error = SFE_OPEN_PIPE_RDWR ; - break ; - - case SFM_READ : - psf->file.filedes = 0 ; - break ; - - case SFM_WRITE : - psf->file.filedes = 1 ; - break ; - - default : - error = SFE_BAD_OPEN_MODE ; - break ; - } ; - psf->filelength = 0 ; - - return error ; -} /* psf_set_stdio */ - -void -psf_set_file (SF_PRIVATE *psf, int fd) -{ psf->file.filedes = fd ; -} /* psf_set_file */ - -int -psf_file_valid (SF_PRIVATE *psf) -{ return (psf->file.filedes >= 0) ? SF_TRUE : SF_FALSE ; -} /* psf_set_file */ - -sf_count_t -psf_fseek (SF_PRIVATE *psf, sf_count_t offset, int whence) -{ sf_count_t current_pos, new_position ; - - if (psf->virtual_io) - return psf->vio.seek (offset, whence, psf->vio_user_data) ; - - current_pos = psf_ftell (psf) ; - - switch (whence) - { case SEEK_SET : - offset += psf->fileoffset ; - break ; - - case SEEK_END : - if (psf->file.mode == SFM_WRITE) - { new_position = lseek (psf->file.filedes, offset, whence) ; - - if (new_position < 0) - psf_log_syserr (psf, errno) ; - - return new_position - psf->fileoffset ; - } ; - - /* Transform SEEK_END into a SEEK_SET, ie find the file - ** length add the requested offset (should be <= 0) to - ** get the offset wrt the start of file. - */ - whence = SEEK_SET ; - offset = lseek (psf->file.filedes, 0, SEEK_END) + offset ; - break ; - - case SEEK_CUR : - /* Translate a SEEK_CUR into a SEEK_SET. */ - offset += current_pos ; - whence = SEEK_SET ; - break ; - - default : - /* We really should not be here. */ - psf_log_printf (psf, "psf_fseek : whence is %d *****.\n", whence) ; - return 0 ; - } ; - - if (current_pos != offset) - new_position = lseek (psf->file.filedes, offset, whence) ; - else - new_position = offset ; - - if (new_position < 0) - psf_log_syserr (psf, errno) ; - - new_position -= psf->fileoffset ; - - return new_position ; -} /* psf_fseek */ - -sf_count_t -psf_fread (void *ptr, sf_count_t bytes, sf_count_t items, SF_PRIVATE *psf) -{ sf_count_t total = 0 ; - ssize_t count ; - - if (psf->virtual_io) - return psf->vio.read (ptr, bytes*items, psf->vio_user_data) / bytes ; - - items *= bytes ; - - /* Do this check after the multiplication above. */ - if (items <= 0) - return 0 ; - - while (items > 0) - { /* Break the read down to a sensible size. */ - count = (items > SENSIBLE_SIZE) ? SENSIBLE_SIZE : (ssize_t) items ; - - count = read (psf->file.filedes, ((char*) ptr) + total, (size_t) count) ; - - if (count == -1) - { if (errno == EINTR) - continue ; - - psf_log_syserr (psf, errno) ; - break ; - } ; - - if (count == 0) - break ; - - total += count ; - items -= count ; - } ; - - if (psf->is_pipe) - psf->pipeoffset += total ; - - return total / bytes ; -} /* psf_fread */ - -sf_count_t -psf_fwrite (const void *ptr, sf_count_t bytes, sf_count_t items, SF_PRIVATE *psf) -{ sf_count_t total = 0 ; - ssize_t count ; - - if (psf->virtual_io) - return psf->vio.write (ptr, bytes*items, psf->vio_user_data) / bytes ; - - items *= bytes ; - - /* Do this check after the multiplication above. */ - if (items <= 0) - return 0 ; - - while (items > 0) - { /* Break the writes down to a sensible size. */ - count = (items > SENSIBLE_SIZE) ? SENSIBLE_SIZE : items ; - - count = write (psf->file.filedes, ((const char*) ptr) + total, count) ; - - if (count == -1) - { if (errno == EINTR) - continue ; - - psf_log_syserr (psf, errno) ; - break ; - } ; - - if (count == 0) - break ; - - total += count ; - items -= count ; - } ; - - if (psf->is_pipe) - psf->pipeoffset += total ; - - return total / bytes ; -} /* psf_fwrite */ - -sf_count_t -psf_ftell (SF_PRIVATE *psf) -{ sf_count_t pos ; - - if (psf->virtual_io) - return psf->vio.tell (psf->vio_user_data) ; - - if (psf->is_pipe) - return psf->pipeoffset ; - - pos = lseek (psf->file.filedes, 0, SEEK_CUR) ; - - if (pos == ((sf_count_t) -1)) - { psf_log_syserr (psf, errno) ; - return -1 ; - } ; - - return pos - psf->fileoffset ; -} /* psf_ftell */ - -static int -psf_close_fd (int fd) -{ int retval ; - - if (fd < 0) - return 0 ; - - while ((retval = close (fd)) == -1 && errno == EINTR) - /* Do nothing. */ ; - - return retval ; -} /* psf_close_fd */ - -sf_count_t -psf_fgets (char *buffer, sf_count_t bufsize, SF_PRIVATE *psf) -{ sf_count_t k = 0 ; - sf_count_t count ; - - while (k < bufsize - 1) - { count = read (psf->file.filedes, &(buffer [k]), 1) ; - - if (count == -1) - { if (errno == EINTR) - continue ; - - psf_log_syserr (psf, errno) ; - break ; - } ; - - if (count == 0 || buffer [k++] == '\n') - break ; - } ; - - buffer [k] = 0 ; - - return k ; -} /* psf_fgets */ - -int -psf_is_pipe (SF_PRIVATE *psf) -{ struct stat statbuf ; - - if (psf->virtual_io) - return SF_FALSE ; - - if (fstat (psf->file.filedes, &statbuf) == -1) - { psf_log_syserr (psf, errno) ; - /* Default to maximum safety. */ - return SF_TRUE ; - } ; - - if (S_ISFIFO (statbuf.st_mode) || S_ISSOCK (statbuf.st_mode)) - return SF_TRUE ; - - return SF_FALSE ; -} /* psf_is_pipe */ - -static sf_count_t -psf_get_filelen_fd (int fd) -{ struct stat statbuf ; - - /* - ** Sanity check. - ** If everything is OK, this will be optimised out. - */ - if (sizeof (statbuf.st_size) == 4 && sizeof (sf_count_t) == 8) - return (sf_count_t) -SFE_BAD_STAT_SIZE ; - - if (fstat (fd, &statbuf) == -1) - return (sf_count_t) -1 ; - - return statbuf.st_size ; -} /* psf_get_filelen_fd */ - -int -psf_ftruncate (SF_PRIVATE *psf, sf_count_t len) -{ int retval ; - - /* Returns 0 on success, non-zero on failure. */ - if (len < 0) - return -1 ; - - if ((sizeof (off_t) < sizeof (sf_count_t)) && len > 0x7FFFFFFF) - return -1 ; - - retval = ftruncate (psf->file.filedes, len) ; - - if (retval == -1) - psf_log_syserr (psf, errno) ; - - return retval ; -} /* psf_ftruncate */ - -void -psf_init_files (SF_PRIVATE *psf) -{ psf->file.filedes = -1 ; - psf->rsrc.filedes = -1 ; - psf->file.savedes = -1 ; -} /* psf_init_files */ - -void -psf_use_rsrc (SF_PRIVATE *psf, int on_off) -{ - if (on_off) - { if (psf->file.filedes != psf->rsrc.filedes) - { psf->file.savedes = psf->file.filedes ; - psf->file.filedes = psf->rsrc.filedes ; - } ; - } - else if (psf->file.filedes == psf->rsrc.filedes) - psf->file.filedes = psf->file.savedes ; - - return ; -} /* psf_use_rsrc */ - -static int -psf_open_fd (PSF_FILE * pfile) -{ int fd, oflag, mode ; - - /* - ** Sanity check. If everything is OK, this test and the printfs will - ** be optimised out. This is meant to catch the problems caused by - ** "sfconfig.h" being included after . - */ - if (sizeof (off_t) != sizeof (sf_count_t)) - { puts ("\n\n*** Fatal error : sizeof (off_t) != sizeof (sf_count_t)") ; - puts ("*** This means that libsndfile was not configured correctly.\n") ; - exit (1) ; - } ; - - switch (pfile->mode) - { case SFM_READ : - oflag = O_RDONLY | O_BINARY ; - mode = 0 ; - break ; - - case SFM_WRITE : - oflag = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY ; - mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ; - break ; - - case SFM_RDWR : - oflag = O_RDWR | O_CREAT | O_BINARY ; - mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ; - break ; - - default : - return - SFE_BAD_OPEN_MODE ; - break ; - } ; - - if (mode == 0) - fd = open (pfile->path.c, oflag) ; - else - fd = open (pfile->path.c, oflag, mode) ; - - return fd ; -} /* psf_open_fd */ - -static void -psf_log_syserr (SF_PRIVATE *psf, int error) -{ - /* Only log an error if no error has been set yet. */ - if (psf->error == 0) - { psf->error = SFE_SYSTEM ; - snprintf (psf->syserr, sizeof (psf->syserr), "System error : %s.", strerror (error)) ; - } ; - - return ; -} /* psf_log_syserr */ - -void -psf_fsync (SF_PRIVATE *psf) -{ -#if HAVE_FSYNC - if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR) - fsync (psf->file.filedes) ; -#else - psf = NULL ; -#endif -} /* psf_fsync */ - -#elif USE_WINDOWS_API - -/* Win32 file i/o functions implemented using native Win32 API */ - -#include -#include - -static int psf_close_handle (HANDLE handle) ; -static HANDLE psf_open_handle (PSF_FILE * pfile) ; -static sf_count_t psf_get_filelen_handle (HANDLE handle) ; - -/* USE_WINDOWS_API */ int -psf_fopen (SF_PRIVATE *psf) -{ - psf->error = 0 ; - psf->file.handle = psf_open_handle (&psf->file) ; - - if (psf->file.handle == NULL) - psf_log_syserr (psf, GetLastError ()) ; - - return psf->error ; -} /* psf_fopen */ - -/* USE_WINDOWS_API */ int -psf_fclose (SF_PRIVATE *psf) -{ int retval ; - - if (psf->virtual_io) - return 0 ; - - if (psf->file.do_not_close_descriptor) - { psf->file.handle = NULL ; - return 0 ; - } ; - - if ((retval = psf_close_handle (psf->file.handle)) == -1) - psf_log_syserr (psf, GetLastError ()) ; - - psf->file.handle = NULL ; - - return retval ; -} /* psf_fclose */ - -/* USE_WINDOWS_API */ int -psf_open_rsrc (SF_PRIVATE *psf) -{ - if (psf->rsrc.handle != NULL) - return 0 ; - - /* Test for MacOSX style resource fork on HPFS or HPFS+ filesystems. */ - snprintf (psf->rsrc.path.c, sizeof (psf->rsrc.path.c), "%s/rsrc", psf->file.path.c) ; - psf->error = SFE_NO_ERROR ; - if ((psf->rsrc.handle = psf_open_handle (&psf->rsrc)) != NULL) - { psf->rsrclength = psf_get_filelen_handle (psf->rsrc.handle) ; - return SFE_NO_ERROR ; - } ; - - /* - ** Now try for a resource fork stored as a separate file in the same - ** directory, but preceded with a dot underscore. - */ - snprintf (psf->rsrc.path.c, sizeof (psf->rsrc.path.c), "%s._%s", psf->file.dir.c, psf->file.name.c) ; - psf->error = SFE_NO_ERROR ; - if ((psf->rsrc.handle = psf_open_handle (&psf->rsrc)) != NULL) - { psf->rsrclength = psf_get_filelen_handle (psf->rsrc.handle) ; - return SFE_NO_ERROR ; - } ; - - /* - ** Now try for a resource fork stored in a separate file in the - ** .AppleDouble/ directory. - */ - snprintf (psf->rsrc.path.c, sizeof (psf->rsrc.path.c), "%s.AppleDouble/%s", psf->file.dir.c, psf->file.name.c) ; - psf->error = SFE_NO_ERROR ; - if ((psf->rsrc.handle = psf_open_handle (&psf->rsrc)) != NULL) - { psf->rsrclength = psf_get_filelen_handle (psf->rsrc.handle) ; - return SFE_NO_ERROR ; - } ; - - /* No resource file found. */ - if (psf->rsrc.handle == NULL) - psf_log_syserr (psf, GetLastError ()) ; - - psf->rsrc.handle = NULL ; - - return psf->error ; -} /* psf_open_rsrc */ - -/* USE_WINDOWS_API */ sf_count_t -psf_get_filelen (SF_PRIVATE *psf) -{ sf_count_t filelen ; - - if (psf->virtual_io) - return psf->vio.get_filelen (psf->vio_user_data) ; - - filelen = psf_get_filelen_handle (psf->file.handle) ; - - if (filelen == -1) - { psf_log_syserr (psf, errno) ; - return (sf_count_t) -1 ; - } ; - - if (filelen == -SFE_BAD_STAT_SIZE) - { psf->error = SFE_BAD_STAT_SIZE ; - return (sf_count_t) -1 ; - } ; - - switch (psf->file.mode) - { case SFM_WRITE : - filelen = filelen - psf->fileoffset ; - break ; - - case SFM_READ : - if (psf->fileoffset > 0 && psf->filelength > 0) - filelen = psf->filelength ; - break ; - - case SFM_RDWR : - /* - ** Cannot open embedded files SFM_RDWR so we don't need to - ** subtract psf->fileoffset. We already have the answer we - ** need. - */ - break ; - - default : - /* Shouldn't be here, so return error. */ - filelen = -1 ; - } ; - - return filelen ; -} /* psf_get_filelen */ - -/* USE_WINDOWS_API */ void -psf_init_files (SF_PRIVATE *psf) -{ psf->file.handle = NULL ; - psf->rsrc.handle = NULL ; - psf->file.hsaved = NULL ; -} /* psf_init_files */ - -/* USE_WINDOWS_API */ void -psf_use_rsrc (SF_PRIVATE *psf, int on_off) -{ - if (on_off) - { if (psf->file.handle != psf->rsrc.handle) - { psf->file.hsaved = psf->file.handle ; - psf->file.handle = psf->rsrc.handle ; - } ; - } - else if (psf->file.handle == psf->rsrc.handle) - psf->file.handle = psf->file.hsaved ; - - return ; -} /* psf_use_rsrc */ - -/* USE_WINDOWS_API */ static HANDLE -psf_open_handle (PSF_FILE * pfile) -{ DWORD dwDesiredAccess ; - DWORD dwShareMode ; - DWORD dwCreationDistribution ; - HANDLE handle ; - - switch (pfile->mode) - { case SFM_READ : - dwDesiredAccess = GENERIC_READ ; - dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE ; - dwCreationDistribution = OPEN_EXISTING ; - break ; - - case SFM_WRITE : - dwDesiredAccess = GENERIC_WRITE ; - dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE ; - dwCreationDistribution = CREATE_ALWAYS ; - break ; - - case SFM_RDWR : - dwDesiredAccess = GENERIC_READ | GENERIC_WRITE ; - dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE ; - dwCreationDistribution = OPEN_ALWAYS ; - break ; - - default : - return NULL ; - } ; - - if (pfile->use_wchar) - handle = CreateFileW ( - pfile->path.wc, /* pointer to name of the file */ - dwDesiredAccess, /* access (read-write) mode */ - dwShareMode, /* share mode */ - 0, /* pointer to security attributes */ - dwCreationDistribution, /* how to create */ - FILE_ATTRIBUTE_NORMAL, /* file attributes (could use FILE_FLAG_SEQUENTIAL_SCAN) */ - NULL /* handle to file with attributes to copy */ - ) ; - else - handle = CreateFile ( - pfile->path.c, /* pointer to name of the file */ - dwDesiredAccess, /* access (read-write) mode */ - dwShareMode, /* share mode */ - 0, /* pointer to security attributes */ - dwCreationDistribution, /* how to create */ - FILE_ATTRIBUTE_NORMAL, /* file attributes (could use FILE_FLAG_SEQUENTIAL_SCAN) */ - NULL /* handle to file with attributes to copy */ - ) ; - - if (handle == INVALID_HANDLE_VALUE) - return NULL ; - - return handle ; -} /* psf_open_handle */ - -/* USE_WINDOWS_API */ static void -psf_log_syserr (SF_PRIVATE *psf, int error) -{ LPVOID lpMsgBuf ; - - /* Only log an error if no error has been set yet. */ - if (psf->error == 0) - { psf->error = SFE_SYSTEM ; - - FormatMessage ( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - error, - MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &lpMsgBuf, - 0, - NULL - ) ; - - snprintf (psf->syserr, sizeof (psf->syserr), "System error : %s", (char*) lpMsgBuf) ; - LocalFree (lpMsgBuf) ; - } ; - - return ; -} /* psf_log_syserr */ - - -/* USE_WINDOWS_API */ int -psf_close_rsrc (SF_PRIVATE *psf) -{ psf_close_handle (psf->rsrc.handle) ; - psf->rsrc.handle = NULL ; - return 0 ; -} /* psf_close_rsrc */ - - -/* USE_WINDOWS_API */ int -psf_set_stdio (SF_PRIVATE *psf) -{ HANDLE handle = NULL ; - int error = 0 ; - - switch (psf->file.mode) - { case SFM_RDWR : - error = SFE_OPEN_PIPE_RDWR ; - break ; - - case SFM_READ : - handle = GetStdHandle (STD_INPUT_HANDLE) ; - psf->file.do_not_close_descriptor = 1 ; - break ; - - case SFM_WRITE : - handle = GetStdHandle (STD_OUTPUT_HANDLE) ; - psf->file.do_not_close_descriptor = 1 ; - break ; - - default : - error = SFE_BAD_OPEN_MODE ; - break ; - } ; - - psf->file.handle = handle ; - psf->filelength = 0 ; - - return error ; -} /* psf_set_stdio */ - -/* USE_WINDOWS_API */ void -psf_set_file (SF_PRIVATE *psf, int fd) -{ HANDLE handle ; - intptr_t osfhandle ; - - osfhandle = _get_osfhandle (fd) ; - handle = (HANDLE) osfhandle ; - - psf->file.handle = handle ; -} /* psf_set_file */ - -/* USE_WINDOWS_API */ int -psf_file_valid (SF_PRIVATE *psf) -{ if (psf->file.handle == NULL) - return SF_FALSE ; - if (psf->file.handle == INVALID_HANDLE_VALUE) - return SF_FALSE ; - return SF_TRUE ; -} /* psf_set_file */ - -/* USE_WINDOWS_API */ sf_count_t -psf_fseek (SF_PRIVATE *psf, sf_count_t offset, int whence) -{ sf_count_t new_position ; - LONG lDistanceToMove, lDistanceToMoveHigh ; - DWORD dwMoveMethod ; - DWORD dwResult, dwError ; - - if (psf->virtual_io) - return psf->vio.seek (offset, whence, psf->vio_user_data) ; - - switch (whence) - { case SEEK_SET : - offset += psf->fileoffset ; - dwMoveMethod = FILE_BEGIN ; - break ; - - case SEEK_END : - dwMoveMethod = FILE_END ; - break ; - - default : - dwMoveMethod = FILE_CURRENT ; - break ; - } ; - - lDistanceToMove = (DWORD) (offset & 0xFFFFFFFF) ; - lDistanceToMoveHigh = (DWORD) ((offset >> 32) & 0xFFFFFFFF) ; - - dwResult = SetFilePointer (psf->file.handle, lDistanceToMove, &lDistanceToMoveHigh, dwMoveMethod) ; - - if (dwResult == 0xFFFFFFFF) - dwError = GetLastError () ; - else - dwError = NO_ERROR ; - - if (dwError != NO_ERROR) - { psf_log_syserr (psf, dwError) ; - return -1 ; - } ; - - new_position = (dwResult + ((__int64) lDistanceToMoveHigh << 32)) - psf->fileoffset ; - - return new_position ; -} /* psf_fseek */ - -/* USE_WINDOWS_API */ sf_count_t -psf_fread (void *ptr, sf_count_t bytes, sf_count_t items, SF_PRIVATE *psf) -{ sf_count_t total = 0 ; - ssize_t count ; - DWORD dwNumberOfBytesRead ; - - if (psf->virtual_io) - return psf->vio.read (ptr, bytes*items, psf->vio_user_data) / bytes ; - - items *= bytes ; - - /* Do this check after the multiplication above. */ - if (items <= 0) - return 0 ; - - while (items > 0) - { /* Break the writes down to a sensible size. */ - count = (items > SENSIBLE_SIZE) ? SENSIBLE_SIZE : (ssize_t) items ; - - if (ReadFile (psf->file.handle, ((char*) ptr) + total, count, &dwNumberOfBytesRead, 0) == 0) - { psf_log_syserr (psf, GetLastError ()) ; - break ; - } - else - count = dwNumberOfBytesRead ; - - if (count == 0) - break ; - - total += count ; - items -= count ; - } ; - - if (psf->is_pipe) - psf->pipeoffset += total ; - - return total / bytes ; -} /* psf_fread */ - -/* USE_WINDOWS_API */ sf_count_t -psf_fwrite (const void *ptr, sf_count_t bytes, sf_count_t items, SF_PRIVATE *psf) -{ sf_count_t total = 0 ; - ssize_t count ; - DWORD dwNumberOfBytesWritten ; - - if (psf->virtual_io) - return psf->vio.write (ptr, bytes * items, psf->vio_user_data) / bytes ; - - items *= bytes ; - - /* Do this check after the multiplication above. */ - if (items <= 0) - return 0 ; - - while (items > 0) - { /* Break the writes down to a sensible size. */ - count = (items > SENSIBLE_SIZE) ? SENSIBLE_SIZE : (ssize_t) items ; - - if (WriteFile (psf->file.handle, ((const char*) ptr) + total, count, &dwNumberOfBytesWritten, 0) == 0) - { psf_log_syserr (psf, GetLastError ()) ; - break ; - } - else - count = dwNumberOfBytesWritten ; - - if (count == 0) - break ; - - total += count ; - items -= count ; - } ; - - if (psf->is_pipe) - psf->pipeoffset += total ; - - return total / bytes ; -} /* psf_fwrite */ - -/* USE_WINDOWS_API */ sf_count_t -psf_ftell (SF_PRIVATE *psf) -{ sf_count_t pos ; - LONG lDistanceToMoveLow, lDistanceToMoveHigh ; - DWORD dwResult, dwError ; - - if (psf->virtual_io) - return psf->vio.tell (psf->vio_user_data) ; - - if (psf->is_pipe) - return psf->pipeoffset ; - - lDistanceToMoveLow = 0 ; - lDistanceToMoveHigh = 0 ; - - dwResult = SetFilePointer (psf->file.handle, lDistanceToMoveLow, &lDistanceToMoveHigh, FILE_CURRENT) ; - - if (dwResult == 0xFFFFFFFF) - dwError = GetLastError () ; - else - dwError = NO_ERROR ; - - if (dwError != NO_ERROR) - { psf_log_syserr (psf, dwError) ; - return -1 ; - } ; - - pos = (dwResult + ((__int64) lDistanceToMoveHigh << 32)) ; - - return pos - psf->fileoffset ; -} /* psf_ftell */ - -/* USE_WINDOWS_API */ static int -psf_close_handle (HANDLE handle) -{ if (handle == NULL) - return 0 ; - - if (CloseHandle (handle) == 0) - return -1 ; - - return 0 ; -} /* psf_close_handle */ - -/* USE_WINDOWS_API */ sf_count_t -psf_fgets (char *buffer, sf_count_t bufsize, SF_PRIVATE *psf) -{ sf_count_t k = 0 ; - sf_count_t count ; - DWORD dwNumberOfBytesRead ; - - while (k < bufsize - 1) - { if (ReadFile (psf->file.handle, &(buffer [k]), 1, &dwNumberOfBytesRead, 0) == 0) - { psf_log_syserr (psf, GetLastError ()) ; - break ; - } - else - { count = dwNumberOfBytesRead ; - /* note that we only check for '\n' not other line endings such as CRLF */ - if (count == 0 || buffer [k++] == '\n') - break ; - } ; - } ; - - buffer [k] = 0 ; - - return k ; -} /* psf_fgets */ - -/* USE_WINDOWS_API */ int -psf_is_pipe (SF_PRIVATE *psf) -{ - if (psf->virtual_io) - return SF_FALSE ; - - if (GetFileType (psf->file.handle) == FILE_TYPE_DISK) - return SF_FALSE ; - - /* Default to maximum safety. */ - return SF_TRUE ; -} /* psf_is_pipe */ - -/* USE_WINDOWS_API */ sf_count_t -psf_get_filelen_handle (HANDLE handle) -{ sf_count_t filelen ; - DWORD dwFileSizeLow, dwFileSizeHigh, dwError = NO_ERROR ; - - dwFileSizeLow = GetFileSize (handle, &dwFileSizeHigh) ; - - if (dwFileSizeLow == 0xFFFFFFFF) - dwError = GetLastError () ; - - if (dwError != NO_ERROR) - return (sf_count_t) -1 ; - - filelen = dwFileSizeLow + ((__int64) dwFileSizeHigh << 32) ; - - return filelen ; -} /* psf_get_filelen_handle */ - -/* USE_WINDOWS_API */ void -psf_fsync (SF_PRIVATE *psf) -{ FlushFileBuffers (psf->file.handle) ; -} /* psf_fsync */ - - -/* USE_WINDOWS_API */ int -psf_ftruncate (SF_PRIVATE *psf, sf_count_t len) -{ int retval = 0 ; - LONG lDistanceToMoveLow, lDistanceToMoveHigh ; - DWORD dwResult, dwError = NO_ERROR ; - - /* This implementation trashes the current file position. - ** should it save and restore it? what if the current position is past - ** the new end of file? - */ - - /* Returns 0 on success, non-zero on failure. */ - if (len < 0) - return 1 ; - - lDistanceToMoveLow = (DWORD) (len & 0xFFFFFFFF) ; - lDistanceToMoveHigh = (DWORD) ((len >> 32) & 0xFFFFFFFF) ; - - dwResult = SetFilePointer (psf->file.handle, lDistanceToMoveLow, &lDistanceToMoveHigh, FILE_BEGIN) ; - - if (dwResult == 0xFFFFFFFF) - dwError = GetLastError () ; - - if (dwError != NO_ERROR) - { retval = -1 ; - psf_log_syserr (psf, dwError) ; - } - else - { /* Note: when SetEndOfFile is used to extend a file, the contents of the - ** new portion of the file is undefined. This is unlike chsize(), - ** which guarantees that the new portion of the file will be zeroed. - ** Not sure if this is important or not. - */ - if (SetEndOfFile (psf->file.handle) == 0) - { retval = -1 ; - psf_log_syserr (psf, GetLastError ()) ; - } ; - } ; - - return retval ; -} /* psf_ftruncate */ - - -#else -/* Win32 file i/o functions implemented using Unix-style file i/o API */ - -/* Win32 has a 64 file offset seek function: -** -** __int64 _lseeki64 (int handle, __int64 offset, int origin) ; -** -** It also has a 64 bit fstat function: -** -** int fstati64 (int, struct _stati64) ; -** -** but the fscking thing doesn't work!!!!! The file size parameter returned -** by this function is only valid up until more data is written at the end of -** the file. That makes this function completely 100% useless. -*/ - -#include -#include - -/* Win32 */ int -psf_fopen (SF_PRIVATE *psf, const char *pathname, int open_mode) -{ int oflag, mode ; - - switch (open_mode) - { case SFM_READ : - oflag = O_RDONLY | O_BINARY ; - mode = 0 ; - break ; - - case SFM_WRITE : - oflag = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY ; - mode = S_IRUSR | S_IWUSR | S_IRGRP ; - break ; - - case SFM_RDWR : - oflag = O_RDWR | O_CREAT | O_BINARY ; - mode = S_IRUSR | S_IWUSR | S_IRGRP ; - break ; - - default : - psf->error = SFE_BAD_OPEN_MODE ; - return -1 ; - break ; - } ; - - if (mode == 0) - psf->file.filedes = open (pathname, oflag) ; - else - psf->file.filedes = open (pathname, oflag, mode) ; - - if (psf->file.filedes == -1) - psf_log_syserr (psf, errno) ; - - return psf->file.filedes ; -} /* psf_fopen */ - -/* Win32 */ sf_count_t -psf_fseek (SF_PRIVATE *psf, sf_count_t offset, int whence) -{ sf_count_t new_position ; - - if (psf->virtual_io) - return psf->vio.seek (offset, whence, psf->vio_user_data) ; - - switch (whence) - { case SEEK_SET : - offset += psf->fileoffset ; - break ; - - case SEEK_END : - if (psf->file.mode == SFM_WRITE) - { new_position = _lseeki64 (psf->file.filedes, offset, whence) ; - - if (new_position < 0) - psf_log_syserr (psf, errno) ; - - return new_position - psf->fileoffset ; - } ; - - /* Transform SEEK_END into a SEEK_SET, ie find the file - ** length add the requested offset (should be <= 0) to - ** get the offset wrt the start of file. - */ - whence = SEEK_SET ; - offset = _lseeki64 (psf->file.filedes, 0, SEEK_END) + offset ; - break ; - - default : - /* No need to do anything about SEEK_CUR. */ - break ; - } ; - - /* - ** Bypass weird Win32-ism if necessary. - ** _lseeki64() returns an "invalid parameter" error if called with the - ** offset == 0 and whence == SEEK_CUR. - *** Use the _telli64() function instead. - */ - if (offset == 0 && whence == SEEK_CUR) - new_position = _telli64 (psf->file.filedes) ; - else - new_position = _lseeki64 (psf->file.filedes, offset, whence) ; - - if (new_position < 0) - psf_log_syserr (psf, errno) ; - - new_position -= psf->fileoffset ; - - return new_position ; -} /* psf_fseek */ - -/* Win32 */ sf_count_t -psf_fread (void *ptr, sf_count_t bytes, sf_count_t items, SF_PRIVATE *psf) -{ sf_count_t total = 0 ; - ssize_t count ; - - if (psf->virtual_io) - return psf->vio.read (ptr, bytes*items, psf->vio_user_data) / bytes ; - - items *= bytes ; - - /* Do this check after the multiplication above. */ - if (items <= 0) - return 0 ; - - while (items > 0) - { /* Break the writes down to a sensible size. */ - count = (items > SENSIBLE_SIZE) ? SENSIBLE_SIZE : (ssize_t) items ; - - count = read (psf->file.filedes, ((char*) ptr) + total, (size_t) count) ; - - if (count == -1) - { if (errno == EINTR) - continue ; - - psf_log_syserr (psf, errno) ; - break ; - } ; - - if (count == 0) - break ; - - total += count ; - items -= count ; - } ; - - return total / bytes ; -} /* psf_fread */ - -/* Win32 */ sf_count_t -psf_fwrite (const void *ptr, sf_count_t bytes, sf_count_t items, SF_PRIVATE *psf) -{ sf_count_t total = 0 ; - ssize_t count ; - - if (psf->virtual_io) - return psf->vio.write (ptr, bytes*items, psf->vio_user_data) / bytes ; - - items *= bytes ; - - /* Do this check after the multiplication above. */ - if (items <= 0) - return 0 ; - - while (items > 0) - { /* Break the writes down to a sensible size. */ - count = (items > SENSIBLE_SIZE) ? SENSIBLE_SIZE : items ; - - count = write (psf->file.filedes, ((const char*) ptr) + total, count) ; - - if (count == -1) - { if (errno == EINTR) - continue ; - - psf_log_syserr (psf, errno) ; - break ; - } ; - - if (count == 0) - break ; - - total += count ; - items -= count ; - } ; - - return total / bytes ; -} /* psf_fwrite */ - -/* Win32 */ sf_count_t -psf_ftell (SF_PRIVATE *psf) -{ sf_count_t pos ; - - if (psf->virtual_io) - return psf->vio.tell (psf->vio_user_data) ; - - pos = _telli64 (psf->file.filedes) ; - - if (pos == ((sf_count_t) -1)) - { psf_log_syserr (psf, errno) ; - return -1 ; - } ; - - return pos - psf->fileoffset ; -} /* psf_ftell */ - -/* Win32 */ int -psf_fclose (SF_PRIVATE *psf) -{ int retval ; - - while ((retval = close (psf->file.filedes)) == -1 && errno == EINTR) - /* Do nothing. */ ; - - if (retval == -1) - psf_log_syserr (psf, errno) ; - - psf->file.filedes = -1 ; - - return retval ; -} /* psf_fclose */ - -/* Win32 */ sf_count_t -psf_fgets (char *buffer, sf_count_t bufsize, SF_PRIVATE *psf) -{ sf_count_t k = 0 ; - sf_count_t count ; - - while (k < bufsize - 1) - { count = read (psf->file.filedes, &(buffer [k]), 1) ; - - if (count == -1) - { if (errno == EINTR) - continue ; - - psf_log_syserr (psf, errno) ; - break ; - } ; - - if (count == 0 || buffer [k++] == '\n') - break ; - } ; - - buffer [k] = 0 ; - - return k ; -} /* psf_fgets */ - -/* Win32 */ int -psf_is_pipe (SF_PRIVATE *psf) -{ struct stat statbuf ; - - if (psf->virtual_io) - return SF_FALSE ; - - /* Not sure if this works. */ - if (fstat (psf->file.filedes, &statbuf) == -1) - { psf_log_syserr (psf, errno) ; - /* Default to maximum safety. */ - return SF_TRUE ; - } ; - - /* These macros are defined in Win32/unistd.h. */ - if (S_ISFIFO (statbuf.st_mode) || S_ISSOCK (statbuf.st_mode)) - return SF_TRUE ; - - return SF_FALSE ; -} /* psf_checkpipe */ - -/* Win32 */ sf_count_t -psf_get_filelen (SF_PRIVATE *psf) -{ -#if 0 - /* - ** Windoze is SOOOOO FUCKED!!!!!!! - ** This code should work but doesn't. Why? - ** Code below does work. - */ - struct _stati64 statbuf ; - - if (_fstati64 (psf->file.filedes, &statbuf)) - { psf_log_syserr (psf, errno) ; - return (sf_count_t) -1 ; - } ; - - return statbuf.st_size ; -#else - sf_count_t current, filelen ; - - if (psf->virtual_io) - return psf->vio.get_filelen (psf->vio_user_data) ; - - if ((current = _telli64 (psf->file.filedes)) < 0) - { psf_log_syserr (psf, errno) ; - return (sf_count_t) -1 ; - } ; - - /* - ** Lets face it, windoze if FUBAR!!! - ** - ** For some reason, I have to call _lseeki64() TWICE to get to the - ** end of the file. - ** - ** This might have been avoided if windows had implemented the POSIX - ** standard function fsync() but NO, that would have been too easy. - ** - ** I am VERY close to saying that windoze will no longer be supported - ** by libsndfile and changing the license to GPL at the same time. - */ - - _lseeki64 (psf->file.filedes, 0, SEEK_END) ; - - if ((filelen = _lseeki64 (psf->file.filedes, 0, SEEK_END)) < 0) - { psf_log_syserr (psf, errno) ; - return (sf_count_t) -1 ; - } ; - - if (filelen > current) - _lseeki64 (psf->file.filedes, current, SEEK_SET) ; - - switch (psf->file.mode) - { case SFM_WRITE : - filelen = filelen - psf->fileoffset ; - break ; - - case SFM_READ : - if (psf->fileoffset > 0 && psf->filelength > 0) - filelen = psf->filelength ; - break ; - - case SFM_RDWR : - /* - ** Cannot open embedded files SFM_RDWR so we don't need to - ** subtract psf->fileoffset. We already have the answer we - ** need. - */ - break ; - - default : - filelen = 0 ; - } ; - - return filelen ; -#endif -} /* psf_get_filelen */ - -/* Win32 */ int -psf_ftruncate (SF_PRIVATE *psf, sf_count_t len) -{ int retval ; - - /* Returns 0 on success, non-zero on failure. */ - if (len < 0) - return 1 ; - - /* The global village idiots at micorsoft decided to implement - ** nearly all the required 64 bit file offset functions except - ** for one, truncate. The fscking morons! - ** - ** This is not 64 bit file offset clean. Somone needs to clean - ** this up. - */ - if (len > 0x7FFFFFFF) - return -1 ; - - retval = chsize (psf->file.filedes, len) ; - - if (retval == -1) - psf_log_syserr (psf, errno) ; - - return retval ; -} /* psf_ftruncate */ - - -static void -psf_log_syserr (SF_PRIVATE *psf, int error) -{ - /* Only log an error if no error has been set yet. */ - if (psf->error == 0) - { psf->error = SFE_SYSTEM ; - snprintf (psf->syserr, sizeof (psf->syserr), "System error : %s", strerror (error)) ; - } ; - - return ; -} /* psf_log_syserr */ - -#endif -