⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file_io.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** Copyright (C) 2002-2004 Erik de Castro Lopo <erikd@mega-nerd.com>** Copyright (C) 2003 Ross Bencina <rbencina@iprimus.com.au>**** 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.*//*** This header file MUST be included before the others to ensure that** large file support is enabled.*/#include "config.h"#include <stdio.h>#include <stdlib.h>#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#if (HAVE_DECL_S_IRGRP == 0)#include "sf_unistd.h"#endif#include <string.h>#include <fcntl.h>#include <errno.h>#include <sys/stat.h>#if (defined (__MWERKS__) && defined (macintosh))typedef int ssize_t ;#include <Files.h>#endif#include "sndfile.h"#include "common.h"#define	SENSIBLE_SIZE	(0x40000000)static int psf_open_fd (const char * path, int mode) ;static int psf_close_fd (int fd) ;static void psf_log_syserr (SF_PRIVATE *psf, int error) ;static sf_count_t psf_get_filelen_fd (int fd) ;intpsf_fopen (SF_PRIVATE *psf, const char *pathname, int open_mode){	psf->error = 0 ;	psf->filedes = psf_open_fd (pathname, open_mode) ;	if (psf->filedes == - SFE_BAD_OPEN_MODE)	{	psf->error = SFE_BAD_OPEN_MODE ;		psf->filedes = -1 ;		return psf->error ;		} ;	if (psf->filedes == -1)		psf_log_syserr (psf, errno) ;	psf->mode = open_mode ;	return psf->error ;} /* psf_fopen */intpsf_fclose (SF_PRIVATE *psf){	int retval ;	if (psf->do_not_close_descriptor)	{	psf->filedes = -1 ;		return 0 ;		} ;	if ((retval = psf_close_fd (psf->filedes)) == -1)		psf_log_syserr (psf, errno) ;	psf->filedes = -1 ;	return retval ;} /* psf_fclose */intpsf_open_rsrc (SF_PRIVATE *psf, int open_mode){	char *fname ;	if (psf->rsrcdes > 0)		return 0 ;	/* Test for MacOSX style resource fork on HPFS or HPFS+ filesystems. */	LSF_SNPRINTF (psf->rsrcpath, sizeof (psf->rsrcpath), "%s/rsrc", psf->filepath) ;	psf->error = SFE_NO_ERROR ;	if ((psf->rsrcdes = psf_open_fd (psf->rsrcpath, open_mode)) >= 0)	{	psf->rsrclength = psf_get_filelen_fd (psf->rsrcdes) ;		if (psf->rsrclength < 100)		{	psf->error = SFE_SD2_BAD_RSRC ;			return psf->error ;			} ;		return SFE_NO_ERROR ;		} ;	if (psf->rsrcdes == - SFE_BAD_OPEN_MODE)	{	psf->error = SFE_BAD_OPEN_MODE ;		return psf->error ;		} ;	/*	** Now try for a resource fork stored as a separate file.	** Grab the un-adulterated filename again.	*/	LSF_SNPRINTF (psf->rsrcpath, sizeof (psf->rsrcpath), "%s", psf->filepath) ;	if ((fname = strrchr (psf->rsrcpath, '/')) != NULL)		fname ++ ;	else if ((fname = strrchr (psf->rsrcpath, '\\')) != NULL)		fname ++ ;	else		fname = psf->rsrcpath ;	memmove (fname + 2, fname, strlen (fname) + 1) ;	fname [0] = '.' ;	fname [1] = '_' ;	psf->error = SFE_NO_ERROR ;	if ((psf->rsrcdes = psf_open_fd (psf->rsrcpath, open_mode)) >= 0)	{	psf->rsrclength = psf_get_filelen_fd (psf->rsrcdes) ;		return SFE_NO_ERROR ;		} ;	if (psf->rsrcdes == -1)		psf_log_syserr (psf, errno) ;	psf->rsrcdes = -1 ;	return psf->error ;} /* psf_open_rsrc */intpsf_close_rsrc (SF_PRIVATE *psf){	psf_close_fd (psf->rsrcdes) ;	psf->rsrcdes = -1 ;	return 0 ;} /* psf_close_rsrc */sf_count_tpsf_get_filelen (SF_PRIVATE *psf){	sf_count_t	filelen ;	filelen = psf_get_filelen_fd (psf->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->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 */#if ((defined (WIN32) || defined (_WIN32)) == 0)/*------------------------------------------------------------------------------** Win32 stuff at the bottom of the file. Unix and other sensible OSes here.*/intpsf_set_stdio (SF_PRIVATE *psf, int mode){	int	error = 0 ;	switch (mode)	{	case SFM_RDWR :				error = SFE_OPEN_PIPE_RDWR ;				break ;		case SFM_READ :				psf->filedes = 0 ;				break ;		case SFM_WRITE :				psf->filedes = 1 ;				break ;		default :				error = SFE_BAD_OPEN_MODE ;				break ;		} ;	psf->filelength = 0 ;	return error ;} /* psf_set_stdio */voidpsf_set_file (SF_PRIVATE *psf, int fd){	psf->filedes = fd ;} /* psf_set_file */intpsf_filedes_valid (SF_PRIVATE *psf){	return (psf->filedes >= 0) ? SF_TRUE : SF_FALSE ;} /* psf_set_file */sf_count_tpsf_fseek (SF_PRIVATE *psf, sf_count_t offset, int whence){	sf_count_t	new_position ;	switch (whence)	{	case SEEK_SET :				offset += psf->fileoffset ;				break ;		case SEEK_END :				if (psf->mode == SFM_WRITE)				{	new_position = lseek (psf->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->filedes, 0, SEEK_END) + offset ;				break ;		default :				/* No need to do anything about SEEK_CUR. */				break ;		} ;	new_position = lseek (psf->filedes, offset, whence) ;	if (new_position < 0)		psf_log_syserr (psf, errno) ;	new_position -= psf->fileoffset ;	return new_position ;} /* psf_fseek */sf_count_tpsf_fread (void *ptr, sf_count_t bytes, sf_count_t items, SF_PRIVATE *psf){	sf_count_t total = 0 ;	ssize_t	count ;	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->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_tpsf_fwrite (const void *ptr, sf_count_t bytes, sf_count_t items, SF_PRIVATE *psf){	sf_count_t total = 0 ;	ssize_t	count ;	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->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_tpsf_ftell (SF_PRIVATE *psf){	sf_count_t pos ;	if (psf->is_pipe)		return psf->pipeoffset ;	pos = lseek (psf->filedes, 0, SEEK_CUR) ;	if (pos == ((sf_count_t) -1))	{	psf_log_syserr (psf, errno) ;		return -1 ;		} ;	return pos - psf->fileoffset ;} /* psf_ftell */intpsf_close_fd (int fd){	int retval ;	while ((retval = close (fd)) == -1 && errno == EINTR)		/* Do nothing. */ ;	return retval ;} /* psf_close_fd */sf_count_tpsf_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->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 */intpsf_is_pipe (SF_PRIVATE *psf){	struct stat statbuf ;	if (fstat (psf->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_tpsf_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 ;/* Cygwin seems to need this. */#if (defined (__CYGWIN__) && HAVE_FSYNC)	fsync (psf->filedes) ;#endif	if (fstat (fd, &statbuf) == -1)		return (sf_count_t) -1 ;	return statbuf.st_size ;} /* psf_get_filelen_fd */intpsf_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 ;#if (defined (__MWERKS__) && defined (macintosh))	retval = FSSetForkSize (psf->filedes, fsFromStart, len) ;#else	retval = ftruncate (psf->filedes, len) ;#endif	if (retval == -1)		psf_log_syserr (psf, errno) ;	return retval ;} /* psf_ftruncate */static intpsf_open_fd (const char * pathname, int open_mode){	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	** "config.h" being included after <stdio.h>.	*/	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 (open_mode)	{	case SFM_READ :				oflag = O_RDONLY ;				mode = 0 ;				break ;		case SFM_WRITE :				oflag = O_WRONLY | O_CREAT | O_TRUNC ;				mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ;				break ;		case SFM_RDWR :				oflag = O_RDWR | O_CREAT ;				mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ;				break ;		default :				return - SFE_BAD_OPEN_MODE ;				break ;		} ;#if defined (__CYGWIN__)	oflag |= O_BINARY ;#endif	if (mode == 0)		fd = open (pathname, oflag) ;	else		fd = open (pathname, oflag, mode) ;	return fd ;} /* psf_open_fd */static voidpsf_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 ;		LSF_SNPRINTF (psf->syserr, sizeof (psf->syserr), "System error : %s.", strerror (error)) ;		} ;	return ;} /* psf_log_syserr */#elif	OS_IS_WIN32/* Win32 file i/o functions implemented using native Win32 API */#include <windows.h>#include <io.h>#ifndef HAVE_SSIZE_Ttypedef long ssize_t ;#endif/* Win32 */ static intpsf_open_fd (const char * pathname, int open_mode){	DWORD dwDesiredAccess ;	DWORD dwShareMode ;	DWORD dwCreationDistribution ;	HANDLE handle ;	switch (open_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 - SFE_BAD_OPEN_MODE ;		} ;	handle = CreateFile (			pathname,					/* 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 -1 ;	return (int) handle ;} /* psf_open_fd *//* Win32 */ static voidpsf_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			) ;		LSF_SNPRINTF (psf->syserr, sizeof (psf->syserr), "System error : %s", lpMsgBuf) ;		LocalFree (lpMsgBuf) ;		} ;	return ;} /* psf_log_syserr *//* Win32 */ intpsf_set_stdio (SF_PRIVATE *psf, int mode){	HANDLE	handle = NULL ;	int	error = 0 ;	switch (mode)	{	case SFM_RDWR :				error = SFE_OPEN_PIPE_RDWR ;				break ;		case SFM_READ :				handle = GetStdHandle (STD_INPUT_HANDLE) ;				psf->do_not_close_descriptor = 1 ;				break ;		case SFM_WRITE :				handle = GetStdHandle (STD_OUTPUT_HANDLE) ;				psf->do_not_close_descriptor = 1 ;				break ;		default :				error = SFE_BAD_OPEN_MODE ;				break ;		} ;	psf->filedes = (int) handle ;	psf->filelength = 0 ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -