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

📄 logrec.c

📁 seed格式数据解压程序,地震分析人员必备
💻 C
字号:
/*===========================================================================*//* UTIG DMC        |             logrec                    | Logrec          *//*===========================================================================*//*	Name:		init_logrec, open_logrec, put_logrec	Purpose:	SEED logical record output buffering * * this package allows output physical blocking of SEED logical records. * It supports any number of files (up to the system limit) at once. * It provides blocking and numbering services, and permits the * caller to most efficiently buffer long reads without compromising * modularity. This package is much simpler than the Unix buffering * scheme, and is oriented to SEED requirements specifcally, and * very large amounts of data. It does not have much internal consistency * checking at present.Usage:	void init_logrec()	int set_logrec( file, n )	struct io_buf open_logrec( file, lrecl, precl, &err )	struct io_buf close_logrec( file, &err )	struct io_buf put_logrec( file, buf, nbytes, flush, &err )	Input:			Output:			Externals:	Warnings:		Errors:			Fatals:	Called by:	the world	Calls to:	sprintf, strncpy, bcopy, write	Algorithm:		Notes:			Problems:	probably not Ansi C	References:		Language:	Sun OS 3.5 C	Written:	mark wiederspahn	Revisions:	mm/dd/yy  pgmr name  change				26oct89	mw	change				write one end of file at volume flush.				we don't care if output is a disk file; ignore error.				end_volume at close_logrec (not just flush_volume).*/#include <sys/types.h>#include <sys/ioctl.h>#include <sys/mtio.h>#include "output.h"struct logbuf {	/* internal to logrec.c and output_data.c */	int seqno;	/* sequence number last written, 0..999999 */	int lrecl;	/* logical record size, 0 = no memory buffer */	int precl;	/* physical record size, 0 = no memory buffer */	char *base;	/* base addr of this buffer */	struct io_buf buf;	/* where is it, and how much left? */	} buffer[NFILE];static struct mtop mtfunc;	/* for writing eofs *//* * called once per program to initialize the logrec database * no errors are possible. */void init_logrec(){int	i;	for( i=0; i<NFILE; i++ )	{		buffer[i].seqno = 0;		buffer[i].lrecl = 0;		buffer[i].precl = 0;		buffer[i].base = NULL;		buffer[i].buf.len = 0;		buffer[i].buf.addr = NULL;	}}/* * called to set the sequence number ( n >= 0 ) or * get its current value ( n < 0 ); always returns * current value if no error */int set_logrec( file, n )FILE		*file;		/* file pointer */int			n;			/* sequence number, or -1 */{	if( fileno(file) >= 0 && fileno(file) < NFILE )	{		if( n >= 0 ) buffer[fileno(file)].seqno = n;		return( buffer[fileno(file)].seqno ); 	}	else	{		return( -1 );	}}		/* * called once per file to allocate memory and set up pointers * errors: *	if returned io_buf.addr == NULL, and io_buf.len = 0 *	the file was bad, lrecl or precl make no sense, (err=2) *	or no buffer space could be obtained (err=1). */struct io_buf open_logrec( file, lrecl, precl, err )FILE	*file;			/* open file */int		lrecl;			/* logical record length */int		precl;			/* physical record length */int		*err;			/* error status:						 * 0 = ok						 * 1 = get memory failed						 * 2 = calling args illegal						 */{struct io_buf bad;	bad.addr = NULL;	/* return junk if really bad params */	bad.len = 0;	if( fileno(file) >= 0 && fileno(file) < NFILE &&		lrecl > 512 && lrecl < 8192 &&					/* see SEED doc */		precl > 512 && precl < 65536 &&					/* phys limit of mt */		precl%lrecl == 0 && precl/lrecl >= 1 )			/* must fit evenly */		{			if( (buffer[fileno(file)].base =				buffer[fileno(file)].buf.addr =				(char *)malloc(precl)) == NULL )			{				*err = 1;				return( bad );								/* no memory */			}			else			{				*err = 0;									 /* success */				buffer[fileno(file)].lrecl = lrecl;				buffer[fileno(file)].precl =					buffer[fileno(file)].buf.len =								precl;				return( buffer[fileno(file)].buf );			}		}		else			*err = 2;			return( bad );									/* bad input */}/* * close out a logical record stream. This routine flushes the file, * and also writes an eof mark on tapes only. */struct io_buf close_logrec( file, err )FILE		*file;		/* open file pointer */int			*err;		/* return status */{struct io_buf result;		/* return me if bad file */	result.addr = NULL;		/* return junk if really bad params */	result.len = 0;	if( fileno(file) >= 0 && fileno(file) < NFILE )	{		result = put_logrec( file, NULL, 0, 2, err );		free( buffer[fileno(file)].base );		buffer[fileno(file)].base =			buffer[fileno(file)].buf.addr = NULL;		buffer[fileno(file)].precl =			buffer[fileno(file)].lrecl = 			buffer[fileno(file)].buf.len = 0;		*err = 0;		return( buffer[fileno(file)].buf );				/* success */			}	else	{		*err = 1;		return( result );									/* failure */	}}/* * called to output a logical record. The number of contiguous bytes * is in "nbytes", which may be zero. This serves as an inital request * to obtain the best location to read data into to minimize data movement. * * flushing the volume writes one end of file on tapes. */struct io_buf put_logrec( file, buf, nbytes, flush, err )FILE	*file;			/* open output file */char	*buf;			/* source of data to be output */int	nbytes;			/* number of bytes in buf to output */int	flush;			/* flag for type of flushing, if any:				 * 0 = no flush to be done. nbytes must be mod lrecl				 * 1 = flush out physical record buffer with noise				 * 2 = flush physical record, plus end volume (eof?)				 */int	*err;			/* return status code:				 * 0 = all ok				 * ? = failure				 */{int len;			/* lengths of various things */int fd;				/* file descriptor, index into buffer data */register char *p;		/* fast fill pointer */struct io_buf bad;		/* return me if bad file */char	digits[7];		/* temp digit string */static int bytes_so_far = 0;	bad.addr = NULL;	/* return junk if really bad params */	bad.len = 0;/* * if the file pointer is bogus, do nothing */	fd = fileno(file);	if( fd >= 0 && fd < NFILE )	{/* * if there is no physical record buffer, die an immediate death */		if( buffer[fd].base == NULL )			{			*err = 1;			return( buffer[fd].buf );			}/* * Now that the worst mistakes are past us, assume no further errors. * if there is possibly anything to move, determine how much and do it */		*err = 0;		if( nbytes >= 0 )		{			len = nbytes;			if( len > buffer[fd].buf.len )				len = buffer[fd].buf.len;			if( len > 0 && buf != buffer[fd].buf.addr )				bcopy( buf, buffer[fd].buf.addr,len );				/*			buffer[fd].lrecl = Lrecl; *//* * for each logical record, put the sequence number in */			while( len > 0 )			{				if ((bytes_so_far % Lrecl) == 0)					buffer[fd].seqno++;				bytes_so_far += buffer[fd].lrecl;				sprintf( digits, "%.6d", buffer[fd].seqno );				strncpy( buffer[fd].buf.addr, digits, 6 );				len -= buffer[fd].lrecl;				buffer[fd].buf.len -= buffer[fd].lrecl;				buffer[fd].buf.addr += buffer[fd].lrecl;			}/* * if we are flushing, fill logical records with spaces, and datatype = space; * even noise records get proper sequence numbers. However, if the physical * record buffer is completely empty, do no flush at all. */			if( flush > 0 )			{				if( buffer[fd].buf.len != buffer[fd].precl )				{					while( buffer[fd].buf.len > 0 )					{						p = buffer[fd].buf.addr;						len = buffer[fd].lrecl;						while( len-- ) *p++ = SPACE;						if ((bytes_so_far  % Lrecl) == 0)							buffer[fd].seqno++;						bytes_so_far += buffer[fd].lrecl;						sprintf( digits, "%.6d", buffer[fd].seqno );						strncpy( buffer[fd].buf.addr, digits, 6 );						len -= buffer[fd].lrecl;						buffer[fd].buf.len -= buffer[fd].lrecl;						buffer[fd].buf.addr += buffer[fd].lrecl;					}				}			}/* * if the physical record is full, output it now, and show empty phys buffer */			if( buffer[fd].buf.len <= 0 )			{				if( write( fd,					buffer[fd].base,					buffer[fd].precl ) < 0)					*err = 2;				buffer[fd].buf.len = buffer[fd].precl;				buffer[fd].buf.addr = buffer[fd].base;				memset(buffer[fd].base, ' ', buffer[fd].precl);			}/* * if we are volume flushing a non-empty volume, write an eof */			if( flush == 2 && buffer[fd].seqno != 0 )			{				mtfunc.mt_op = MTWEOF;				mtfunc.mt_count = 1;				ioctl( fd, MTIOCTOP, &mtfunc  );			}		}		return( buffer[fd].buf );	}	else	{		*err = 3;								/* return for bad fd */		return( bad );		}	}/* ----------------------------------------------------------------------- */struct io_buf flush_buff( file, len)FILE    *file;              /* open output file */int len;{	int fd;                 /* file descriptor, index into buffer data */	int num_bytes_left;	char wrkstr[100];/* * if the file pointer is bogus, do nothing */        fd = fileno(file);        if( fd >= 0 && fd < NFILE )        {	}        if(write(fd, buffer[fd].base,  buffer[fd].buf.addr - buffer[fd].base) < 0)	{		sprintf(wrkstr, "flush_buff: bad write!");		error_handler(WARNING, wrkstr);	}        buffer[fd].buf.len = buffer[fd].precl;        buffer[fd].buf.addr = buffer[fd].base;	memset(buffer[fd].base, ' ', buffer[fd].precl);	return(buffer[fd].buf);	}

⌨️ 快捷键说明

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