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

📄 fileutils.c

📁 C编写的格式转换程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************** * * Routines to manage files of Mini-SEED. * * Written by Chad Trabant, ORFEUS/EC-Project MEREDIAN * * modified: 2008.161 ***************************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <errno.h>#include "libmseed.h"/* Byte stream length for read-ahead header fingerprinting */#define NEXTHDRLEN 48static int ms_readpackinfo (int packtype, FILE *stream);static int ms_fread (char *buf, int size, int num, FILE *stream);static int ms_ateof (FILE *stream);/* Pack type parameters for the 8 defined types: * [type] : [hdrlen] [sizelen] [chksumlen] */int8_t packtypes[9][3] = {  { 0, 0, 0 },  { 8, 8, 8 },  { 11, 8, 8 },  { 11, 8, 8 },  { 11, 8, 8 },  { 11, 8, 8 },  { 13, 8, 8 },  { 15, 8, 8 },  { 22, 15, 10 }};/* Initialize the global file reading parameters */MSFileParam gMSFileParam = {NULL, NULL, "", 1, MINRECLEN, 0, 0, 0, 0};/********************************************************************** * ms_readmsr: * * This routine is a simple wrapper for ms_readmsr_r() that uses the * global file reading parameters.  This routine is not thread safe * and cannot be used to read more than one file at a time. * * See the comments with ms_readmsr_r() for return values and further * description of arguments. *********************************************************************/intms_readmsr (MSRecord **ppmsr, char *msfile, int reclen, off_t *fpos,	    int *last, flag skipnotdata, flag dataflag, flag verbose){  MSFileParam *msfp = &gMSFileParam;    return ms_readmsr_r (&msfp, ppmsr, msfile, reclen, fpos,		       last, skipnotdata, dataflag, verbose);}  /* End of ms_readmsr() *//********************************************************************** * ms_readmsr_r: * * This routine will open and read, with subsequent calls, all * Mini-SEED records in specified file. * * All static file reading parameters are stored in a MSFileParam * struct and returned (via a pointer to a pointer) for the calling * routine to use in subsequent calls.  A MSFileParam struct will be * allocated if necessary.  This routine is thread safe and can be * used to read multiple files in parallel as long as the file reading * parameters are managed appropriately. * * If reclen is 0 the length of the first record is automatically * detected, all subsequent records are then expected to have the same * length as the first. * * If reclen is negative the length of every record is automatically * detected. * * For auto detection of record length the record must include a 1000 * blockette.  This routine will search up to 8192 bytes into the * record for the 1000 blockette. * * If *fpos is not NULL it will be updated to reflect the file * position (offset from the beginning in bytes) from where the * returned record was read. * * If *last is not NULL it will be set to 1 when the last record in * the file is being returned, otherwise it will be 0. * * If the skipnotdata flag is true any data chunks read that do not * have vald data record indicators (D, R, Q, M, etc.) will be skipped. * * dataflag will be passed directly to msr_unpack(). * * After reading all the records in a file the controlling program * should call it one last time with msfile set to NULL.  This will * close the file and free allocated memory. * * Returns MS_NOERROR and populates an MSRecord struct at *ppmsr on * successful read, returns MS_ENDOFFILE on EOF, otherwise returns a * libmseed error code (listed in libmseed.h) and *ppmsr is set to * NULL. *********************************************************************/intms_readmsr_r (MSFileParam **ppmsfp, MSRecord **ppmsr, char *msfile,	      int reclen, off_t *fpos, int *last, flag skipnotdata,	      flag dataflag, flag verbose){   MSFileParam *msfp;  int packdatasize;  int autodetexp = 8;  int prevreadlen;  int detsize;  int retcode = MS_NOERROR;    if ( ! ppmsr )    return MS_GENERROR;    if ( ! ppmsfp )    return MS_GENERROR;    msfp = *ppmsfp;    /* Initialize the file read parameters if needed */  if ( ! msfp )    {      msfp = (MSFileParam *) malloc (sizeof (MSFileParam));            if ( msfp == NULL )	{	  ms_log (2, "ms_readmsr_r(): Cannot allocate memory\n");	  return MS_GENERROR;	}            /* Redirect the supplied pointer to the allocted params */      *ppmsfp = msfp;            msfp->fp = NULL;      msfp->rawrec = NULL;      msfp->filename[0] = '\0';      msfp->autodet = 1;      msfp->readlen = MINRECLEN;      msfp->packtype = 0;      msfp->packhdroffset = 0;      msfp->filepos = 0;      msfp->recordcount = 0;    }    /* When cleanup is requested */  if ( msfile == NULL )    {      msr_free (ppmsr);            if ( msfp->fp != NULL )	fclose (msfp->fp);            if ( msfp->rawrec != NULL )	free (msfp->rawrec);            /* If the file parameters are the global parameters reset them */      if ( *ppmsfp == &gMSFileParam )	{	  gMSFileParam.fp = NULL;	  gMSFileParam.rawrec = NULL;	  gMSFileParam.filename[0] = '\0';	  gMSFileParam.autodet = 1;	  gMSFileParam.readlen = MINRECLEN;	  gMSFileParam.packtype = 0;	  gMSFileParam.packhdroffset = 0;	  gMSFileParam.filepos = 0;	  gMSFileParam.recordcount = 0;	}      /* Otherwise free the MSFileParam */      else	{	  free (*ppmsfp);	  *ppmsfp = NULL;	}            return MS_NOERROR;    }    /* Sanity check: track if we are reading the same file */  if ( msfp->fp && strncmp (msfile, msfp->filename, sizeof(msfp->filename)) )    {      ms_log (2, "ms_readmsr() called with a different file name before being reset\n");            /* Close previous file and reset needed variables */      if ( msfp->fp != NULL )	fclose (msfp->fp);            msfp->fp = NULL;      msfp->autodet = 1;      msfp->readlen = MINRECLEN;      msfp->packtype = 0;      msfp->packhdroffset = 0;      msfp->filepos = 0;      msfp->recordcount = 0;    }    /* Open the file if needed, redirect to stdin if file is "-" */  if ( msfp->fp == NULL )    {      /* Store the filename for tracking */      strncpy (msfp->filename, msfile, sizeof(msfp->filename) - 1);      msfp->filename[sizeof(msfp->filename) - 1] = '\0';            if ( strcmp (msfile, "-") == 0 )	{	  msfp->fp = stdin;	}      else if ( (msfp->fp = fopen (msfile, "rb")) == NULL )	{	  ms_log (2, "Cannot open file: %s (%s)\n", msfile, strerror (errno));	  	  msr_free (ppmsr);	  	  return MS_GENERROR;	}    }    /* Force the record length if specified */  if ( reclen > 0 && msfp->autodet )    {      msfp->readlen = reclen;      msfp->autodet = 0;            msfp->rawrec = (char *) malloc (msfp->readlen);            if ( msfp->rawrec == NULL )	{	  ms_log (2, "ms_readmsr_r(): Cannot allocate memory\n");	  return MS_GENERROR;	}    }  /* If reclen is negative reset readlen for autodetection */  if ( reclen < 0 )    msfp->readlen = (unsigned int) 1 << autodetexp;    /* Zero the last record indicator */  if ( last )    *last = 0;    /* Autodetect the record length */  if ( msfp->autodet || reclen < 0 )    {      detsize = 0;      prevreadlen = 0;      while ( detsize <= 0 && msfp->readlen <= 8192 )	{	  msfp->rawrec = (char *) realloc (msfp->rawrec, msfp->readlen);	  	  if ( msfp->rawrec == NULL )	    {	      ms_log (2, "ms_readmsr_r(): Cannot reallocate memory\n");	      return MS_GENERROR;	    }	  	  /* Read packed file info */	  if ( msfp->packtype && msfp->filepos == msfp->packhdroffset )	    {	      if ( (packdatasize = ms_readpackinfo (msfp->packtype, msfp->fp)) <= 0 )		{		  if ( msfp->fp )		    { fclose (msfp->fp); msfp->fp = NULL; }		  msr_free (ppmsr);		  if ( msfp->rawrec )		    { free (msfp->rawrec); msfp->rawrec = NULL; }		  		  if ( packdatasize == 0 )		    return MS_ENDOFFILE;		  else		    return MS_GENERROR;		}	      	      msfp->filepos = lmp_ftello (msfp->fp);	      	      /* File position + data size */	      msfp->packhdroffset = msfp->filepos + packdatasize;	      	      if ( verbose > 1 )		ms_log (1, "Read packed file header at offset %lld (%d bytes follow)\n",			(long long int) (msfp->filepos - packtypes[msfp->packtype][0] - packtypes[msfp->packtype][2]),			packdatasize);	    }	  	  /* Read data into record buffer */	  if ( (ms_fread (msfp->rawrec + prevreadlen, 1, (msfp->readlen - prevreadlen), msfp->fp)) < (msfp->readlen - prevreadlen) )	    {	      if ( ! feof (msfp->fp) )		{		  ms_log (2, "Short read at %d bytes during length detection\n", msfp->readlen);		  retcode = MS_GENERROR;		}	      else		{		  retcode = MS_ENDOFFILE;		}	      if ( msfp->recordcount == 0 )		{		  if ( verbose > 0 )		    ms_log (2, "%s: No data records read, not SEED?\n", msfile);		  retcode = MS_NOTSEED;		}	      	      if ( msfp->fp )		{ fclose (msfp->fp); msfp->fp = NULL; }	      msr_free (ppmsr);	      if ( msfp->rawrec )		{ free (msfp->rawrec); msfp->rawrec = NULL; }	      	      return retcode;	    }	  	  msfp->filepos = lmp_ftello (msfp->fp);	  	  /* Determine record length:	   * If packed file and we are at the next info, length is implied.	   * Otherwise use ms_find_reclen() */	  if ( msfp->packtype && msfp->packhdroffset == msfp->filepos )	    {	      detsize = msfp->readlen;	      break;	    }	  else if ( (detsize = ms_find_reclen (msfp->rawrec, msfp->readlen, msfp->fp)) > 0 )	    {	      break;	    }	  	  /* Test for packed file signature at the beginning of the file */	  if ( *(msfp->rawrec) == 'P' && msfp->filepos == MINRECLEN && detsize == -1 )	    {	      msfp->packtype = 0;	      	      /* Set pack spacer length according to type */	      if ( ! memcmp ("PED", msfp->rawrec, 3) )		msfp->packtype = 1;	      else if ( ! memcmp ("PSD", msfp->rawrec, 3) )		msfp->packtype = 2;	      else if ( ! memcmp ("PLC", msfp->rawrec, 3) )		msfp->packtype = 6;	      else if ( ! memcmp ("PQI", msfp->rawrec, 3) )		msfp->packtype = 7;	      else if ( ! memcmp ("PLS", msfp->rawrec, 3) )		msfp->packtype = 8;	      	      /* Read first pack header section, compensate for "pack identifier" (10 bytes) */	      if ( msfp->packtype )		{		  char hdrstr[30];		  		  if ( verbose > 0 )		    ms_log (1, "Detected packed file (%3.3s: type %d)\n", msfp->rawrec, msfp->packtype);		  		  /* Read pack length from end of pack header accounting for initial 10 characters */		  memset (hdrstr, 0, sizeof(hdrstr));		  memcpy (hdrstr, msfp->rawrec + (packtypes[msfp->packtype][0] + 10 - packtypes[msfp->packtype][1]),			  packtypes[msfp->packtype][1]);		  sscanf (hdrstr, " %d", &packdatasize);		  		  /* Next pack header offset: Pack ID + pack hdr + data size */		  msfp->packhdroffset = 10 + packtypes[msfp->packtype][0] + packdatasize;		  		  if ( verbose > 1 )		    ms_log (1, "Read packed file header at beginning of file (%d bytes follow)\n",			    packdatasize);		}	    }	  	  /* Skip if data record or packed file not detected */	  if ( detsize == -1 && skipnotdata && ! msfp->packtype )	    {	      if ( verbose > 1 )		{		  if ( MS_ISVALIDBLANK((char *)msfp->rawrec) )		    ms_log (1, "Skipped %d bytes of blank/noise record at byte offset %lld\n",			    msfp->readlen, (long long) msfp->filepos - msfp->readlen);		  else		    ms_log (1, "Skipped %d bytes of non-data record at byte offset %lld\n",			    msfp->readlen, (long long) msfp->filepos - msfp->readlen);		}	    }	  /* Otherwise read more */	  else	    {	      /* Compensate for first packed file "identifier" section (10 bytes) */	      if ( msfp->filepos == MINRECLEN && msfp->packtype )		{		  /* Shift first data record to beginning of buffer */		  memmove (msfp->rawrec, msfp->rawrec + (packtypes[msfp->packtype][0] + 10),			   msfp->readlen - (packtypes[msfp->packtype][0] + 10));		  		  prevreadlen = msfp->readlen - (packtypes[msfp->packtype][0] + 10);		}	      /* Increase read length to the next record size up */	      else		{		  prevreadlen = msfp->readlen;		  autodetexp++;		  msfp->readlen = (unsigned int) 1 << autodetexp;		}	    }	}            if ( detsize <= 0 )	{	  ms_log (2, "Cannot detect record length at byte offset %lld: %s\n",		  (long long) msfp->filepos - msfp->readlen, msfile);	  	  if ( msfp->fp )	    { fclose (msfp->fp); msfp->fp = NULL; }	  msr_free (ppmsr);	  if ( msfp->rawrec )	    { free (msfp->rawrec); msfp->rawrec = NULL; }	  	  return MS_NOTSEED;	}            msfp->autodet = 0;            if ( verbose > 0 )	ms_log (1, "Detected record length of %d bytes\n", detsize);            if ( detsize < MINRECLEN || detsize > MAXRECLEN )	{	  ms_log (2, "Detected record length is out of range: %d\n", detsize);	  	  if ( msfp->fp )	    { fclose (msfp->fp); msfp->fp = NULL; }	  msr_free (ppmsr);	  if ( msfp->rawrec )	    { free (msfp->rawrec); msfp->rawrec = NULL; }	  	  return MS_OUTOFRANGE;	}            msfp->rawrec = (char *) realloc (msfp->rawrec, detsize);      if ( msfp->rawrec == NULL )	{	  ms_log (2, "ms_readmsr_r(): Cannot allocate memory\n");	  return MS_GENERROR;	}            /* Read the rest of the first record */      if ( (detsize - msfp->readlen) > 0 )	{	  if ( (ms_fread (msfp->rawrec+msfp->readlen, 1, detsize-msfp->readlen, msfp->fp)) < (detsize-msfp->readlen) )	    {	      if ( ! feof (msfp->fp) )		{		  ms_log (2, "Short read at %d bytes during length detection\n", msfp->readlen);		  retcode = MS_GENERROR;		}	      else		{		  retcode = MS_ENDOFFILE;		}	      if ( msfp->recordcount == 0 )		{		  if ( verbose > 0 )		    ms_log (2, "%s: No data records read, not SEED?\n", msfile);		  retcode = MS_NOTSEED;		}

⌨️ 快捷键说明

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