Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

rw_mag.c

Go to the documentation of this file.
00001 /*
00002  *   THIS FILE IS UNDER RCS - DO NOT MODIFY UNLESS YOU HAVE
00003  *   CHECKED IT OUT USING THE COMMAND CHECKOUT.
00004  *
00005  *    $Id: rw__mag_8c-source.html 2161 2006-05-19 16:55:03Z paulf $
00006  *
00007  *    Revision history:
00008  *     $Log$
00008  *     Revision 1.1  2006/05/19 16:55:02  paulf
00008  *     first inclusion
00008  *
00009  *     Revision 1.11  2002/06/28 21:03:57  lucky
00010  *     Fixed reading of mag phases -- it would not properly read float
00011  *     values for amplitude and period
00012  *
00013  *     Revision 1.10  2001/08/07 16:54:17  lucky
00014  *     Pre v6.0 checkin
00015  *
00016  *     Revision 1.9  2001/06/07 20:51:49  lucky
00017  *     Modified wr_mag so that it checks for NULL strings. Before, if qid was null,
00018  *     wr_mag would produce an invalid TYPE_MAGNITUDE message which could not
00019  *     be parsed by rd_mag. This is not good, given that the qid is not known
00020  *     in the review system.
00021  *
00022  *     Revision 1.8  2001/06/07 19:48:28  lucky
00023  *     rd_chan_mag_lucky renamed to rd_chan_mag. The old rd_chan_mag is still
00024  *     available as rd_chan_mag_Pete.
00025  *
00026  *     Revision 1.7  2001/05/31 21:09:02  lucky
00027  *     Addedd rd_chan_mag_lucky; I don't think that rd_chan_mag in its original form
00028  *     works. There are numerical comparisons of pointers, and other visible problems.
00029  *
00030  *     Revision 1.6  2001/05/26 21:04:59  lombard
00031  *     Changed ML_INFO struct to MAG_CHAN_INFO struct to make it more
00032  *     generic; now this struct should work with most mag types.
00033  *     Fixed a number of obvious bugs and cleaned up the code.
00034  *     But the parsers still have not been tested and this may not work.
00035  *
00036  *     Revision 1.5  2001/05/02 20:58:45  alex
00037  *     *** empty log message ***
00038  *
00039  *     Revision 1.4  2001/05/01 22:38:48  davidk
00040  *     moved the MagNames table out of the header file and into rw_mag.c
00041  *
00042  *     Revision 1.3  2001/05/01 20:26:02  davidk
00043  *     Modified several new functions added by Alex, so that they compile and do not impede the
00044  *     release.  The new functions have been added, but have not properly been tested and debugged,
00045  *     at all.
00046  *
00047  *     Revision 1.2  2001/04/29 00:15:29  alex
00048  *     Alex: changes for mag type int and string, and added alternate parsing routines.
00049  *
00050  *     Revision 1.1  2001/03/31 00:44:58  lombard
00051  *     Initial revision
00052  *
00053  *
00054  *
00055  */
00056 
00057 /* rw_mag.c
00058  *
00059  * Contains functions in that convert from a
00060  * TYPE_MAGNITUDE message to a structure and visa versa.
00061  *
00062  * written by Pete Lombard   February, 2001
00063  */
00064 
00065 #include <stdio.h>
00066 #include <string.h>
00067 #include <earthworm.h>
00068 #include <rw_mag.h>
00069 
00070 /* Internal Function Prototypes */
00071 static int strappend( char *s1, int s1max, char *s2 );
00072 static int tokenlength( char *begtok, char c );
00073 
00074 /********************************************************************
00075  * rd_mag()                                                         *
00076  * Reads an ascii TYPE_MAGNITUDE message and fills in a MAG_INFO    *
00077  * structure which must be allocated by the caller                  *
00078  * If, in addition, the caller allocates space for auxiliary        *
00079  * structures at pMag->pMagAux (number of bytes in pMag->size_aux), *
00080  * then rd_mag will call the appropriate function to decode the     *
00081  * remainder of the message into appropriate structures.            *
00082  * Currently supported magnitude types are: Ml                      *
00083  * Returns 0 on success                                             *
00084  *        -1 on parsing errors                                      *
00085  *        -2 on insufficient space in pMagAux                       *
00086  ********************************************************************/
00087 int rd_mag( char *msg, int msgLen, MAG_INFO *pMag)
00088 {
00089   size_t size_aux;
00090   char *pMagAux;
00091 
00092   size_aux = pMag->size_aux;
00093   pMagAux = (char *)pMag->pMagAux;
00094   memset(pMag, 0, sizeof(MAG_INFO));
00095 
00096   switch ( sscanf( msg
00097                  , "%s MAG %d %s %lf %s %d %d %lf %lf %lf %d %s %d %d"
00098                  ,  pMag->qid
00099                  , &pMag->imagtype
00100                  ,  pMag->szmagtype
00101                  , &pMag->mag
00102                  ,  pMag->algorithm
00103                  , &pMag->nstations
00104                  , &pMag->nchannels
00105                  , &pMag->error
00106                  , &pMag->quality
00107                  , &pMag->mindist
00108                  , &pMag->azimuth
00109                  ,  pMag->qauthor
00110                  , &pMag->origin_version
00111                  , &pMag->qdds_version
00112          )       )
00113   {
00114     case 12:  /* old-style, no origin version, qdds version numbers */
00115          pMag->origin_version = 0;
00116          pMag->qdds_version = 0;
00117          break;
00118     case 13:  /* new-style, with origin version, no qdds version */
00119          pMag->qdds_version = 0;
00120          break;
00121     case 14:  /* new-style, with both number */
00122          break;
00123     default:
00124          return( -1 );
00125   }
00126   
00127   if (pMagAux && size_aux > 0)
00128   {
00129     pMag->size_aux = size_aux;
00130     pMag->pMagAux = pMagAux;
00131     
00132     /* Read the rest of a Mag message */
00133     if (pMag->pMagAux != NULL)
00134         {
00135          return( rd_chan_mag(msg, msgLen, (MAG_CHAN_INFO *)pMag->pMagAux,
00136                           pMag->size_aux) );
00137         }
00138   }
00139   
00140   return( 0 );
00141 }
00142 
00143 /*****************************************************************
00144  * rd_chan_mag()                                                 *
00145  * Reads an ascii TYPE_MAGNITUDE Ml message and fills in         *
00146  * MAG_CHAN_INFO structures.                                     *
00147  * This function can be called by rd_mag if sufficient space is  *
00148  * allocated by its caller. Or it may be called after rd_mag     *
00149  * when the caller has allocated space for `nchannels' of        *
00150  * MAG_CHAN_INFO structures.                                     *
00151  * Returns 0 on success                                          *
00152  *        -1 on parsing errors                                   *
00153  *        -2 on insufficient space in pMagAux                    *
00154  *****************************************************************/
00155 int rd_chan_mag ( char *msg, int msglen, MAG_CHAN_INFO *pMci, int size_ml)
00156 {
00157   char     *line;
00158   char     *begtok;
00159   char     *tmpMsg;     /* local copy of msg */
00160   int       len;       /* length (bytes) of the next token */
00161   int       nchan;     /* number of channels read from msg so far */
00162   int       nML;       /* number of MAG_CHAN_INFO structures we can use */
00163   int       rc;
00164   int           index;
00165   
00166   memset(pMci, 0, size_ml);
00167   nML = size_ml / sizeof(MAG_CHAN_INFO);
00168 
00169   tmpMsg = (char *) malloc (msglen);
00170   strcpy (tmpMsg, msg);
00171 
00172   nchan = 0;
00173 
00174   /* Skip the first line */
00175   len = tokenlength (tmpMsg, '\n'); 
00176 
00177   index = len + 1;
00178 
00179   /* Read next line from the message into working buffer */
00180   while(index < (msglen-1))
00181   {
00182         /* Process next line */
00183         line = tmpMsg + index;
00184     len = tokenlength(line, '\n' ); 
00185         line[len] = '\0';
00186     index = index + len + 1;
00187 
00188     begtok = line;
00189     while( begtok[0] == ' ' && begtok[0] != '\0') begtok++;    /* go to 1st non-blank char */
00190     if( begtok[0] == '\0' ) return( -1 );
00191     len = tokenlength( begtok, '.' );
00192     if( len >= TRACE_STA_LEN ) return( -1 );
00193     strncpy( pMci[nchan].sta, begtok, len );
00194         pMci[nchan].sta[len] = '\0';
00195     begtok += len + 1;
00196 
00197     len = tokenlength( begtok, '.' );
00198     if( len >= TRACE_CHAN_LEN ) return( -1 );
00199     strncpy( pMci[nchan].comp, begtok, len );
00200         pMci[nchan].comp[len] = '\0';
00201     begtok += len + 1;
00202 
00203     len = tokenlength( begtok, ' ' );
00204     if( len >= TRACE_NET_LEN ) return( -1 );
00205     strncpy( pMci[nchan].net, begtok, len );
00206         pMci[nchan].net[len] = '\0';
00207     begtok += len + 1;
00208 
00209     while( begtok[0] == ' ' && begtok[0] != '\0' ) begtok++;    /* go to next non-blank char */
00210     if ( (rc = sscanf(begtok, "%lf %lf %lf %E %lf %f %E %lf %f",
00211                       &(pMci[nchan].mag), &(pMci[nchan].dist), &(pMci[nchan].corr),
00212                       &(pMci[nchan].Amp1), &(pMci[nchan].Time1), &(pMci[nchan].Period1),
00213                       &(pMci[nchan].Amp2), &(pMci[nchan].Time2), 
00214                       &(pMci[nchan].Period2))) != 9)
00215     {
00216       if (rc == 6)
00217       {
00218         pMci[nchan].Amp2 = pMci[nchan].Time2 = pMci[nchan].Period2 = -1.0;
00219         continue;
00220       }
00221       return( -1 );
00222     }
00223 
00224     nchan = nchan + 1;
00225 
00226   }
00227 
00228   return 0;
00229 }
00230 
00231 
00232 
00233 /*******************************************************************
00234  * wr_mag()                                                        *
00235  * Reads a MAG_INFO structure and writes an ascii TYPE_MAGNITUDE   *
00236  * message (null terminated)                                       *
00237  * Returns 0 on success, -1 on failure (potential buffer overflow) *
00238  *******************************************************************/
00239 int wr_mag( MAG_INFO *pMag, char *buf, int buflen )
00240 {
00241   char     tmp[256]; /* working buffer */
00242   char     qid[256]; 
00243   char     szmagtype[256]; 
00244   char     algorithm[256]; 
00245   char     qauthor[256]; 
00246 
00247   memset( buf, 0, (size_t)buflen );    /* zero output buffer */
00248 
00249   /* 
00250    * We should check for null strings, if for nothing else than to 
00251    * avoid mis-formatted message trickling down the system. LV 6/2001
00252    */
00253         if (strlen (pMag->qid) == 0)
00254                 strcpy (qid, "UNKNOWN");
00255         else
00256                 strcpy (qid, pMag->qid);
00257  
00258         if (strlen (pMag->szmagtype) == 0)
00259                 strcpy (szmagtype, "UNKNOWN");
00260         else
00261                 strcpy (szmagtype, pMag->szmagtype);
00262  
00263         if (strlen (pMag->algorithm) == 0)
00264                 strcpy (algorithm, "UNKNOWN");
00265         else
00266                 strcpy (algorithm, pMag->algorithm);
00267  
00268         if (strlen (pMag->qauthor) == 0)
00269                 strcpy (qauthor, "UNKNOWN");
00270         else
00271                 strcpy (qauthor, pMag->qauthor);
00272  
00273   sprintf(tmp, "%s MAG %d %s %0.2f %s %d %d %0.2f %0.2f %0.2f %d %s %d %d\n",
00274           qid, pMag->imagtype, szmagtype, pMag->mag, algorithm, 
00275           pMag->nstations, pMag->nchannels, pMag->error, pMag->quality,
00276           pMag->mindist, pMag->azimuth, qauthor, pMag->origin_version
00277           , pMag->qdds_version
00278           );
00279    
00280   if ( strappend( buf, buflen, tmp ) ) return( -1 );
00281    
00282   if (pMag->pMagAux != NULL)
00283   {
00284       return( wr_chan_mag( (MAG_CHAN_INFO *)pMag->pMagAux, pMag->nchannels, 
00285                            buf, buflen) );
00286   }
00287    
00288   return( 0 );
00289 }
00290 
00291 /*******************************************************************
00292  * wr_chan_mag()                                                   *
00293  * Reads MAG_CHAN_INFO structures and appends to an ascii          *
00294  * TYPE_MAGNITUDE message (null terminated)                        *
00295  * Normally this would be called by wr_mag().                      *
00296  * Returns 0 on success, -1 on failure (potential buffer overflow) *
00297  *******************************************************************/
00298 int wr_chan_mag( MAG_CHAN_INFO *pMci, int nchannels, char *buf, int buflen )
00299 {
00300   int i;
00301   char line[256];
00302   
00303   for (i = 0; i < nchannels; i++)
00304   {
00305     sprintf(line, 
00306             "%s.%s.%s %.2f %.2f %.2f %9.2E %9.2f %9.2f %9.2E %9.2f %9.2f\n",
00307             /*s  c  n mag  dist corr Amp1 Time1 Period1 Amp2 Time2 Period2 */
00308             pMci[i].sta, pMci[i].comp, pMci[i].net, 
00309                         pMci[i].mag, pMci[i].dist, pMci[i].corr, 
00310             pMci[i].Amp1,
00311             ( (pMci[i].Time1 < 0.0) ? -1.0 : pMci[i].Time1),
00312             ( (pMci[i].Period1 < 0.0) ? -1.0 : pMci[i].Period1),
00313             pMci[i].Amp2,
00314             ( (pMci[i].Time2 < 0.0) ? -1.0 : pMci[i].Time2),
00315             ( (pMci[i].Period2 < 0.0) ? -1.0 : pMci[i].Period2));
00316     
00317       if ( strappend(buf, buflen, line))
00318         return( -1 );
00319   }
00320   return( 0 );
00321 }
00322 
00323  
00324 /********************************************************************
00325  * strappend() append second null-terminated character string to    *
00326  * the first as long as there's enough room in the target buffer    * 
00327  * for both strings an the null-byte                                *
00328  ********************************************************************/
00329 static int strappend( char *s1, int s1max, char *s2 )
00330 {
00331   if( (int)strlen(s1)+(int)strlen(s2)+1 > s1max ) return( -1 );
00332   strcat( s1, s2 );
00333   return( 0 );
00334 }
00335 
00336 /********************************************************************
00337  * tokenlength() given a null-terminated character string and a     *
00338  * character that delimits the end of a token, tokenlength returns  * 
00339  * the length (in bytes) of the next token. If the character wasn't * 
00340  * found, tokenlength returns the length of the string.             *
00341  ********************************************************************/
00342 static int tokenlength( char *begtok, char c )
00343 {
00344   char    *endtok;   /* points to the end of this token */
00345 
00346   endtok = strchr( begtok, c );
00347   if( endtok == NULL ) return( (int)strlen(begtok) );
00348   return( (int)(endtok-begtok) );
00349 }

Generated on Tue May 6 09:16:08 2003 for Earthworm Libs by doxygen1.3-rc3