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

📄 file_io.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 2 页
字号:
	return error ;} /* psf_set_stdio *//* Win32 */ voidpsf_set_file (SF_PRIVATE *psf, int fd){	HANDLE handle ;	long osfhandle ;	osfhandle = _get_osfhandle (fd) ;	handle = (HANDLE) osfhandle ;	if (GetFileType (handle) == FILE_TYPE_DISK)		psf->filedes = (int) handle ;	else		psf->filedes = fd ;} /* psf_set_file *//* Win32 */ intpsf_filedes_valid (SF_PRIVATE *psf){	return (((HANDLE) psf->filedes) != INVALID_HANDLE_VALUE) ? SF_TRUE : SF_FALSE ;} /* psf_set_file *//* Win32 */ sf_count_tpsf_fseek (SF_PRIVATE *psf, sf_count_t offset, int whence){	sf_count_t new_position ;	LONG lDistanceToMove, lDistanceToMoveHigh ;	DWORD dwMoveMethod ;	DWORD dwResult, dwError ;	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 ((HANDLE) psf->filedes, 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 *//* Win32 */ 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 ;	DWORD dwNumberOfBytesRead ;	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 ((HANDLE) psf->filedes, ((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 *//* Win32 */ 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 ;	DWORD dwNumberOfBytesWritten ;	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 ((HANDLE) psf->filedes, ((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 *//* Win32 */ sf_count_tpsf_ftell (SF_PRIVATE *psf){	sf_count_t pos ;	LONG lDistanceToMoveLow, lDistanceToMoveHigh ;	DWORD dwResult, dwError ;	if (psf->is_pipe)		return psf->pipeoffset ;	lDistanceToMoveLow = 0 ;	lDistanceToMoveHigh = 0 ;	dwResult = SetFilePointer ((HANDLE) psf->filedes, 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 *//* Win32 */ intpsf_close_fd (int fd){	if (CloseHandle ((HANDLE) fd) == 0)		return -1 ;	return 0 ;} /* psf_close_fd *//* Win32 */ sf_count_tpsf_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 ((HANDLE) psf->filedes, &(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 *//* Win32 */ intpsf_is_pipe (SF_PRIVATE *psf){	if (GetFileType ((HANDLE) psf->filedes) == FILE_TYPE_DISK)		return SF_FALSE ;	/* Default to maximum safety. */	return SF_TRUE ;} /* psf_is_pipe *//* Win32 */ sf_count_tpsf_get_filelen_fd (int fd){	sf_count_t filelen ;	DWORD dwFileSizeLow, dwFileSizeHigh, dwError = NO_ERROR ;	dwFileSizeLow = GetFileSize ((HANDLE) fd, &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_fd *//* Win32 */ intpsf_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 ((HANDLE) psf->filedes, 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 ((HANDLE) psf->filedes) == 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 <io.h>#include <direct.h>#ifndef HAVE_SSIZE_Ttypedef long ssize_t ;#endif/* Win32 */ intpsf_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->filedes = open (pathname, oflag) ;	else		psf->filedes = open (pathname, oflag, mode) ;	if (psf->filedes == -1)		psf_log_syserr (psf, errno) ;	return psf->filedes ;} /* psf_fopen *//* Win32 */ 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 = _lseeki64 (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 = _lseeki64 (psf->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->filedes) ;	else		new_position = _lseeki64 (psf->filedes, offset, whence) ;	if (new_position < 0)		psf_log_syserr (psf, errno) ;	new_position -= psf->fileoffset ;	return new_position ;} /* psf_fseek *//* Win32 */ 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 ;		} ;	return total / bytes ;} /* psf_fread *//* Win32 */ 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 ;		} ;	return total / bytes ;} /* psf_fwrite *//* Win32 */ sf_count_tpsf_ftell (SF_PRIVATE *psf){	sf_count_t pos ;	pos = _telli64 (psf->filedes) ;	if (pos == ((sf_count_t) -1))	{	psf_log_syserr (psf, errno) ;		return -1 ;		} ;	return pos - psf->fileoffset ;} /* psf_ftell *//* Win32 */ intpsf_fclose (SF_PRIVATE *psf){	int retval ;	while ((retval = close (psf->filedes)) == -1 && errno == EINTR)		/* Do nothing. */ ;	if (retval == -1)		psf_log_syserr (psf, errno) ;	psf->filedes = -1 ;	return retval ;} /* psf_fclose *//* Win32 */ 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 *//* Win32 */ intpsf_is_pipe (SF_PRIVATE *psf){	struct stat statbuf ;	/* Not sure if this works. */	if (fstat (psf->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_tpsf_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->filedes, &statbuf))	{	psf_log_syserr (psf, errno) ;		return (sf_count_t) -1 ;		} ;	return statbuf.st_size ;#else	sf_count_t current, filelen ;	if ((current = _telli64 (psf->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->filedes, 0, SEEK_END) ;	if ((filelen = _lseeki64 (psf->filedes, 0, SEEK_END)) < 0)	{	psf_log_syserr (psf, errno) ;		return (sf_count_t) -1 ;		} ;	if (filelen > current)		_lseeki64 (psf->filedes, current, SEEK_SET) ;	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 :			filelen = 0 ;		} ;	return filelen ;#endif} /* psf_get_filelen *//* Win32 */ intpsf_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->filedes, len) ;	if (retval == -1)		psf_log_syserr (psf, errno) ;	return retval ;} /* psf_ftruncate */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 */#endif/*** Do not edit or modify anything in this comment block.** The arch-tag line is a file identity tag for the GNU Arch** revision control system.**** arch-tag: 749740d7-ecc7-47bd-8cf7-600f31d32e6d*/

⌨️ 快捷键说明

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