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

📄 ffio.c

📁 一个用来实现偏微分方程中网格的计算库
💻 C
📖 第 1 页 / 共 2 页
字号:
	ffp->bf_extent = *sizehintp;	assert(ffp->bf_base == NULL);	/* this is separate allocation because it may grow */	ffp->bf_base = malloc(ffp->bf_extent);	if(ffp->bf_base == NULL)	{		ffp->bf_extent = 0;		return ENOMEM;	}	/* else */	return ENOERR;}static voidncio_ffio_init(ncio *const nciop){	ncio_ffio *ffp = (ncio_ffio *)nciop->pvt;	*((ncio_relfunc **)&nciop->rel) = ncio_ffio_rel; /* cast away const */	*((ncio_getfunc **)&nciop->get) = ncio_ffio_get; /* cast away const */	*((ncio_movefunc **)&nciop->move) = ncio_ffio_move; /* cast away const */	*((ncio_syncfunc **)&nciop->sync) = ncio_ffio_sync; /* cast away const */	*((ncio_freefunc **)&nciop->free) = ncio_ffio_free; /* cast away const */	ffp->pos = -1;	ffp->bf_offset = OFF_NONE;	ffp->bf_extent = 0;	ffp->bf_cnt = 0;	ffp->bf_base = NULL;}/* */static voidncio_free(ncio *nciop){	if(nciop == NULL)		return;	if(nciop->free != NULL)		nciop->free(nciop->pvt);		free(nciop);}static ncio *ncio_new(const char *path, int ioflags){	size_t sz_ncio = M_RNDUP(sizeof(ncio));	size_t sz_path = M_RNDUP(strlen(path) +1);	size_t sz_ncio_pvt;	ncio *nciop; #if ALWAYS_NC_SHARE /* DEBUG */	fSet(ioflags, NC_SHARE);#endif	if(fIsSet(ioflags, NC_SHARE))		fprintf(stderr, "NC_SHARE not implemented for ffio\n");	sz_ncio_pvt = sizeof(ncio_ffio);	nciop = (ncio *) malloc(sz_ncio + sz_path + sz_ncio_pvt);	if(nciop == NULL)		return NULL;		nciop->ioflags = ioflags;	*((int *)&nciop->fd) = -1; /* cast away const */	nciop->path = (char *) ((char *)nciop + sz_ncio);	(void) strcpy((char *)nciop->path, path); /* cast away const */				/* cast away const */	*((void **)&nciop->pvt) = (void *)(nciop->path + sz_path);	ncio_ffio_init(nciop);	return nciop;}/* put all the FFIO assign specific code here * returns a pointer to an internal static char location * which may change when the function is called again * if the returned pointer is NULL this indicates that an error occured * check errno for the netCDF error value *//* prototype fortran subroutines */#ifdef __crayx1void ASNQFILE(const char *filename, const char *attribute, int *istat, int flen, int alen);void ASNFILE(const char *filename, const char *attribute, int *istat, int flen, int alen);#elsevoid ASNQFILE(_fcd filename, _fcd attribute, int *istat);void ASNFILE(_fcd filename, _fcd attribute, int *istat);#endif#define BUFLEN 256static const char *ncio_ffio_assign(const char *filename) {	static char buffer[BUFLEN];	int istat;#ifndef __crayx1	_fcd fnp, fbp;#endif	char *envstr;	char *xtra_assign;	char emptystr='\0';/* put things into known states */	memset(buffer,'\0',BUFLEN);	errno = ENOERR;/* set up Fortran character pointers */#ifdef __crayx1	ASNQFILE(filename, buffer, &istat, strlen(filename)+1, BUFLEN);#else	fnp = _cptofcd((char *)filename, strlen(filename));	fbp = _cptofcd(buffer, BUFLEN);/* see if the user has "assigned" to this file */	ASNQFILE(fnp, fbp, &istat);#endif	if (istat == 0) {	/* user has already specified an assign */		return buffer;	} else if (istat > 0 || istat < -1) {	/* error occured */		errno = EINVAL;		return (const char *) NULL;	} /* istat = -1 -> no assign for file */	envstr = getenv("NETCDF_FFIOSPEC");	if(envstr == (char *) NULL) {		 envstr = "bufa:336:2";		/* this should be macroized */	}		/* Insertion by Olaf Heudecker, AWI-Bremerhaven, 12.8.1998	   to allow more versatile FFIO-assigns */	/* this is unnecessary and could have been included	 * into the NETCDF_FFIOSPEC environment variable */	xtra_assign = getenv("NETCDF_XFFIOSPEC");	if(xtra_assign == (char *) NULL) {		xtra_assign=&emptystr;	}	if (strlen(envstr)+strlen(xtra_assign) + 4 > BUFLEN) {	/* Error: AssignCommand too long */		errno=E2BIG;		return (const char *) NULL;	}	(void) sprintf(buffer,"-F %s %s", envstr,xtra_assign);#ifdef __crayx1	ASNFILE(filename, buffer, &istat, strlen(filename)+1, strlen(buffer)+1);#else	fbp = _cptofcd(buffer, strlen(buffer));	ASNFILE(fnp, fbp, &istat);#endif	if (istat == 0) {	/* success */		return buffer;	} else {		/* error */		errno = EINVAL;		return (const char *) NULL;	}}/* Public below this point *//* TODO: Is this reasonable for this platform? */static const size_t NCIO_MINBLOCKSIZE = 256;static const size_t NCIO_MAXBLOCKSIZE = 268435456; /* sanity check, about X_SIZE_T_MAX/8 */intncio_create(const char *path, int ioflags,	size_t initialsz,	off_t igeto, size_t igetsz, size_t *sizehintp,	ncio **nciopp, void **const igetvpp){	ncio *nciop;	const char *ControlString;	int oflags = (O_RDWR|O_CREAT|O_TRUNC);	int fd;	int status;	struct ffsw stat;	if(initialsz < (size_t)igeto + igetsz)		initialsz = (size_t)igeto + igetsz;	fSet(ioflags, NC_WRITE);	if(path == NULL || *path == 0)		return EINVAL;	nciop = ncio_new(path, ioflags);	if(nciop == NULL)		return ENOMEM;	if ((ControlString = ncio_ffio_assign(path)) == (const char *)NULL) {		/* an error occured - just punt */		status = errno;		goto unwind_new;	}#ifdef NOFFFLUSH	/* test whether the global layer is being called for	 * this file ... if so then can't call FFIO ffflush()	 * RKO 06/26/98	 */	if (strstr(ControlString,"global") != (char *) NULL) {		/* use no ffflush version */		*((ncio_syncfunc **)&nciop->sync)			= ncio_ffio_sync_noffflush;	}#endif	if(fIsSet(ioflags, NC_NOCLOBBER))		fSet(oflags, O_EXCL);	/* Orig: fd = ffopens(path, oflags, 0666, 0, &stat, ControlString); */	fd = ffopen(path, oflags, 0666, 0, &stat);	if(fd < 0)	{		status = errno;		goto unwind_new;	}	*((int *)&nciop->fd) = fd; /* cast away const */	if(*sizehintp < NCIO_MINBLOCKSIZE || *sizehintp > NCIO_MAXBLOCKSIZE)	{		/* Use default */		*sizehintp = blksize(fd);	}	else	{		*sizehintp = M_RNDUP(*sizehintp);	}	status = ncio_ffio_init2(nciop, sizehintp);	if(status != ENOERR)		goto unwind_open;	if(initialsz != 0)	{		status = fgrow(fd, (off_t)initialsz);		if(status != ENOERR)			goto unwind_open;	}	if(igetsz != 0)	{		status = nciop->get(nciop,				igeto, igetsz,                        	RGN_WRITE,                        	igetvpp);		if(status != ENOERR)			goto unwind_open;	}	*nciopp = nciop;	return ENOERR;unwind_open:	(void) ffclose(fd);	/* ?? unlink */	/*FALLTHRU*/unwind_new:	ncio_free(nciop);	return status;}intncio_open(const char *path,	int ioflags,	off_t igeto, size_t igetsz, size_t *sizehintp,	ncio **nciopp, void **const igetvpp){	ncio *nciop;	const char *ControlString;	int oflags = fIsSet(ioflags, NC_WRITE) ? O_RDWR : O_RDONLY;	int fd;	int status;	struct ffsw stat;	if(path == NULL || *path == 0)		return EINVAL;	nciop = ncio_new(path, ioflags);	if(nciop == NULL)		return ENOMEM;	if ((ControlString = ncio_ffio_assign(path)) == (const char *)NULL) {		/* an error occured - just punt */		status = errno;		goto unwind_new;	}#ifdef NOFFFLUSH	/* test whether the global layer is being called for	 * this file ... if so then can't call FFIO ffflush()	 * RKO 06/26/98	 */	if (strstr(ControlString,"global") != (char *) NULL) {		/* use no ffflush version */		*((ncio_syncfunc **)&nciop->sync)			= ncio_ffio_sync_noffflush;	}#endif	/* Orig: fd = ffopens(path, oflags, 0, 0, &stat, ControlString); */	fd = ffopen(path, oflags, 0, 0, &stat);	if(fd < 0)	{		status = errno;		goto unwind_new;	}	*((int *)&nciop->fd) = fd; /* cast away const */	if(*sizehintp < NCIO_MINBLOCKSIZE || *sizehintp > NCIO_MAXBLOCKSIZE)	{		/* Use default */		*sizehintp = blksize(fd);	}	else	{		*sizehintp = M_RNDUP(*sizehintp);	}	status = ncio_ffio_init2(nciop, sizehintp);	if(status != ENOERR)		goto unwind_open;	if(igetsz != 0)	{		status = nciop->get(nciop,				igeto, igetsz,                        	0,                        	igetvpp);		if(status != ENOERR)			goto unwind_open;	}	*nciopp = nciop;	return ENOERR;unwind_open:	(void) ffclose(fd);	/*FALLTHRU*/unwind_new:	ncio_free(nciop);	return status;}/*  * Get file size in bytes.   * Is use of ffseek() really necessary, or could we use standard fstat() call * and get st_size member? */intncio_filesize(ncio *nciop, off_t *filesizep){    off_t filesize, current, reset;    if(nciop == NULL)	return EINVAL;    current = ffseek(nciop->fd, 0, SEEK_CUR);  /* save current */    *filesizep = ffseek(nciop->fd, 0, SEEK_END); /* get size */    reset = ffseek(nciop->fd, current, SEEK_SET); /* reset */     if(reset != current)	return EINVAL;    return ENOERR;}/* * Sync any changes to disk, then extend file so its size is length. * This is only intended to be called before close, if the file is * open for writing and the actual size does not match the calculated * size, perhaps as the result of having been previously written in * NOFILL mode. */intncio_pad_length(ncio *nciop, off_t length){	int status = ENOERR;	if(nciop == NULL)		return EINVAL;	if(!fIsSet(nciop->ioflags, NC_WRITE))	        return EPERM; /* attempt to write readonly file */	status = nciop->sync(nciop);	if(status != ENOERR)	        return status;	status = fgrow2(nciop->fd, length);	if(status != ENOERR)	        return errno;	return ENOERR;}int ncio_close(ncio *nciop, int doUnlink){	/*         * TODO: I believe this function is lacking the de-assignment of the         * Fortran LUN assigned by ASNFILE in ncio_ffio_assign(...) -- SRE         * 2002-07-10.	 */	int status = ENOERR;	if(nciop == NULL)		return EINVAL;	status = nciop->sync(nciop);	(void) ffclose(nciop->fd);		if(doUnlink)		(void) unlink(nciop->path);	ncio_free(nciop);	return status;}

⌨️ 快捷键说明

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