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

📄 fileutils.c

📁 C编写的格式转换程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	      	      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);	}            /* Set file position offset for beginning of record */      if ( fpos != NULL )	*fpos = msfp->filepos - detsize;            /* Test if this is the last record */      if ( last )	if ( ms_ateof (msfp->fp) )	  *last = 1;            msfp->readlen = detsize;      msr_free (ppmsr);            if ( (retcode = msr_unpack (msfp->rawrec, msfp->readlen, ppmsr, dataflag, verbose)) != MS_NOERROR )	{	  if ( msfp->fp )	    { fclose (msfp->fp); msfp->fp = NULL; }	  msr_free (ppmsr);	  if ( msfp->rawrec )	    { free (msfp->rawrec); msfp->rawrec = NULL; }	  return retcode;	}            /* Set record length if it was not already done */      if ( (*ppmsr)->reclen == 0 )	(*ppmsr)->reclen = msfp->readlen;            msfp->recordcount++;      return MS_NOERROR;    }    /* Read subsequent records or initial forced length record */  for (;;)    {      /* 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, 1, msfp->readlen, msfp->fp)) < 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;	    }	  	  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);            /* Set file position offset for beginning of record */      if ( fpos != NULL )	*fpos = msfp->filepos - msfp->readlen;            if ( last )	if ( ms_ateof (msfp->fp) )	  *last = 1;            if ( skipnotdata )	{	  if ( MS_ISVALIDHEADER(msfp->rawrec) )	    {	      break;	    }	  else 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);	    }	}      else	break;    }    if ( (retcode = msr_unpack (msfp->rawrec, msfp->readlen, ppmsr, dataflag, verbose)) != MS_NOERROR )    {      if ( msfp->fp )	{ fclose (msfp->fp); msfp->fp = NULL; }      msr_free (ppmsr);      if ( msfp->rawrec )	{ free (msfp->rawrec); msfp->rawrec = NULL; }            return retcode;    }    /* Set record length if it was not already done */  if ( (*ppmsr)->reclen == 0 )    {      (*ppmsr)->reclen = msfp->readlen;    }  /* Test that any detected record length is the same as the read length */  else if ( (*ppmsr)->reclen != msfp->readlen )    {      ms_log (2, "Detected record length (%d) != read length (%d)\n",	      (*ppmsr)->reclen, msfp->readlen);            return MS_WRONGLENGTH;    }    msfp->recordcount++;  return MS_NOERROR;}  /* End of ms_readmsr_r() *//********************************************************************* * ms_readtraces: * * This routine will open and read all Mini-SEED records in specified * file and populate a trace group.  This routine is thread safe. * * 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. * * Returns MS_NOERROR and populates an MSTraceGroup struct at *ppmstg * on successful read, otherwise returns a libmseed error code (listed * in libmseed.h). *********************************************************************/intms_readtraces (MSTraceGroup **ppmstg, char *msfile, int reclen,	       double timetol, double sampratetol, flag dataquality,	       flag skipnotdata, flag dataflag, flag verbose){  MSRecord *msr = 0;  MSFileParam *msfp = 0;  int retcode;    if ( ! ppmstg )    return MS_GENERROR;    /* Initialize MSTraceGroup if needed */  if ( ! *ppmstg )    {      *ppmstg = mst_initgroup (*ppmstg);            if ( ! *ppmstg )	return MS_GENERROR;    }    /* Loop over the input file */  while ( (retcode = ms_readmsr_r (&msfp, &msr, msfile, reclen, NULL, NULL,				   skipnotdata, dataflag, verbose)) == MS_NOERROR)    {      mst_addmsrtogroup (*ppmstg, msr, dataquality, timetol, sampratetol);    }    /* Reset return code to MS_NOERROR on successful read by ms_readmsr() */  if ( retcode == MS_ENDOFFILE )    retcode = MS_NOERROR;    ms_readmsr_r (&msfp, &msr, NULL, 0, NULL, NULL, 0, 0, 0);    return retcode;}  /* End of ms_readtraces() *//******************************************************************** * ms_find_reclen: * * Determine SEED data record length with the following steps: * * 1) determine that the buffer contains a SEED data record by * verifying known signatures (fields with known limited values) * * 2) search the record up to recbuflen bytes for a 1000 blockette. * * 3) If no blockette 1000 is found and fileptr is not NULL, read the * next 48 bytes from the file and determine if it is the fixed second * of another record or blank/noise record, thereby implying the * record length is recbuflen.  The original read position of the file * is restored. * * Returns: * -1 : data record not detected or error *  0 : data record detected but could not determine length * >0 : size of the record in bytes *********************************************************************/intms_find_reclen ( const char *recbuf, int recbuflen, FILE *fileptr ){  uint16_t blkt_offset;    /* Byte offset for next blockette */  uint8_t swapflag  = 0;   /* Byte swapping flag */  uint8_t foundlen = 0;    /* Found record length */  int32_t reclen = -1;     /* Size of record in bytes */    uint16_t blkt_type;  uint16_t next_blkt;    struct fsdh_s *fsdh;  struct blkt_1000_s *blkt_1000;  char nextfsdh[NEXTHDRLEN];    /* Check for valid fixed section of header */  if ( ! MS_ISVALIDHEADER(recbuf) )    return -1;    fsdh = (struct fsdh_s *) recbuf;    /* Check to see if byte swapping is needed (bogus year makes good test) */  if ( (fsdh->start_time.year < 1900) ||       (fsdh->start_time.year > 2050) )    swapflag = 1;    blkt_offset = fsdh->blockette_offset;    /* Swap order of blkt_offset if needed */  if ( swapflag ) ms_gswap2 (&blkt_offset);    /* Loop through blockettes as long as number is non-zero and viable */  while ( blkt_offset != 0 &&	  blkt_offset <= recbuflen )    {      memcpy (&blkt_type, recbuf + blkt_offset, 2);      memcpy (&next_blkt, recbuf + blkt_offset + 2, 2);            if ( swapflag )	{	  ms_gswap2 (&blkt_type);	  ms_gswap2 (&next_blkt);	}            /* Found a 1000 blockette, not truncated */      if ( blkt_type == 1000  &&	   (blkt_offset + 4 + sizeof(struct blkt_1000_s)) <= recbuflen )	{          blkt_1000 = (struct blkt_1000_s *) (recbuf + blkt_offset + 4);	            foundlen = 1;	            /* Calculate record size in bytes as 2^(blkt_1000->reclen) */	  reclen = (unsigned int) 1 << blkt_1000->reclen;	  	  break;        }            blkt_offset = next_blkt;    }    /* If record length was not determined by a 1000 blockette scan the file   * and search for the next record */  if ( reclen == -1 && fileptr )    {      /* Read data into record buffer */      if ( (ms_fread (nextfsdh, 1, NEXTHDRLEN, fileptr)) < NEXTHDRLEN )	{	  /* If no the EOF an error occured (short read) */	  if ( ! feof (fileptr) )	    {	      ms_log (2, "ms_find_reclen(): Error reading file\n");	      return -1;	    }	  /* If EOF the record length is recbuflen */	  else	    {	      foundlen = 1;	      reclen = recbuflen;	    }	}      else	{	  /* Rewind file read pointer */	  if ( lmp_fseeko (fileptr, -NEXTHDRLEN, SEEK_CUR) )	    {	      ms_log (2, "ms_find_reclen(): %s\n", strerror(errno));	      return -1;	    }	  	  /* Check for next fixed header */	  if ( MS_ISVALIDHEADER((char *)nextfsdh) || MS_ISVALIDBLANK((char *)nextfsdh) )	    {	      foundlen = 1;	      reclen = recbuflen;	    }	}    }    if ( ! foundlen )    return 0;  else    return reclen;}  /* End of ms_find_reclen() *//********************************************************************* * ms_readpackinfo: * * Read packed file info: chksum and header, parse and return the size * in bytes for the following data records. * * In general a pack file includes a packed file identifier at the * very beginning, followed by pack header for a data block, followed * by the data block, followed by a chksum for the data block.  The * pack header, data block and chksum are then repeated for each data * block in the file: * *   ID    HDR     DATA    CHKSUM    HDR     DATA    CHKSUM * |----|-------|--....--|--------|-------|--....--|--------| ... * *      |________ repeats ________| * * The HDR section contains fixed width ASCII fields identifying the * data in the next section and it's length in bytes.  With this * information the offset of the next CHKSUM and HDR are completely * predictable. * * This routine's purpose is to read the CHKSUM and HDR bytes in * between the DATA sections and parse the size of the data section * from the header section. * * packtypes[type][0]: length of pack header length * packtypes[type][1]: length of size field in pack header * packtypes[type][2]: chksum length following data blocks, skipped * * Returns the data size of the block that follows, 0 on EOF or -1 * error. *********************************************************************/static intms_readpackinfo (int packtype, FILE *stream){  char hdrstr[30];  int datasize;    /* Skip CHKSUM section */  if ( lmp_fseeko (stream, packtypes[packtype][2], SEEK_CUR) )    {      return -1;    }    if ( ms_ateof (stream) )    return 0;    /* Read HDR section */  if ( (ms_fread (hdrstr, 1, packtypes[packtype][0], stream)) < packtypes[packtype][0] )    {      return -1;    }  /* Make sure header string is NULL terminated */  hdrstr[packtypes[packtype][0]] = '\0';    /* Extract next section data size */  sscanf (&hdrstr[packtypes[packtype][0] - packtypes[packtype][1]], " %d", &datasize);    return datasize;}  /* End of ms_readpackinfo() *//********************************************************************* * ms_fread: * * A wrapper for fread that handles EOF and error conditions. * * Returns the return value from fread. *********************************************************************/static intms_fread (char *buf, int size, int num, FILE *stream){  int read = 0;    read = fread (buf, size, num, stream);    if ( read <= 0 && size && num )    {      if ( ferror (stream) )	ms_log (2, "ms_fread(): Cannot read input file\n");            else if ( ! feof (stream) )	ms_log (2, "ms_fread(): Unknown return from fread()\n");    }    return read;}  /* End of ms_fread() *//********************************************************************* * ms_ateof: * * Check if stream is at the end-of-file by reading a single character * and unreading it if necessary. * * Returns 1 if stream is at EOF otherwise 0. *********************************************************************/static intms_ateof (FILE *stream){  int c;    c = getc (stream);    if ( c == EOF )    {      if ( ferror (stream) )	ms_log (2, "ms_ateof(): Error reading next character from stream\n");            else if ( feof (stream) )	return 1;            else	ms_log (2, "ms_ateof(): Unknown error reading next character from stream\n");    }  else    {      if ( ungetc (c, stream) == EOF )	ms_log (2, "ms_ateof(): Error ungetting character\n");    }    return 0;}  /* End of ms_ateof() */

⌨️ 快捷键说明

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