/*************************************************************************** * A program for libmseed parsing tests. * * This file is part of the miniSEED Library. * * Copyright (c) 2023 Chad Trabant, EarthScope Data Services * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ***************************************************************************/ #include #include #include #include #include #include #define PACKAGE "lm_parse" #define VERSION "[libmseed " LIBMSEED_VERSION " " PACKAGE " ]" static flag verbose = 0; static flag ppackets = 0; static flag basicsum = 0; static flag tracegap = 0; static flag splitversion = 0; static int printraw = 0; static int printdata = 0; static int reclen = -1; static char *inputfile = NULL; static int parameter_proc (int argcount, char **argvec); static void usage (void); /* Binary I/O for Windows platforms */ #ifdef LMP_WIN #include unsigned int _CRT_fmode = _O_BINARY; #endif int main (int argc, char **argv) { MS3TraceList *mstl = 0; MS3Record *msr = 0; uint32_t flags = 0; int64_t totalrecs = 0; int64_t totalsamps = 0; int retcode; /* Process command line arguments */ if (parameter_proc (argc, argv) < 0) return -1; /* Validate CRC and unpack data samples */ flags |= MSF_VALIDATECRC; /* Parse byte range from file/URL path name if present */ flags |= MSF_PNAMERANGE; if (printdata) flags |= MSF_UNPACKDATA; if (tracegap) mstl = mstl3_init (NULL); /* Loop over the input file */ while ((retcode = ms3_readmsr (&msr, inputfile, flags, verbose)) == MS_NOERROR) { totalrecs++; totalsamps += msr->samplecnt; if (tracegap) { mstl3_addmsr (mstl, msr, splitversion, 1, flags, NULL); } else { if ( printraw ) { if (msr->formatversion == 3) ms_parse_raw3 (msr->record, msr->reclen, ppackets); else ms_parse_raw2 (msr->record, msr->reclen, ppackets, -1); } else { msr3_print (msr, ppackets); } if (printdata && msr->numsamples > 0) { int line, col, cnt, samplesize; int lines = (msr->numsamples / 6) + 1; void *sptr; if ((samplesize = ms_samplesize (msr->sampletype)) == 0) { ms_log (2, "Unrecognized sample type: '%c'\n", msr->sampletype); } if (msr->sampletype == 't') { char *text = (char *)msr->datasamples; int length = msr->numsamples; ms_log (0, "Text data:\n"); /* Print maximum log message segments */ while (length > (MAX_LOG_MSG_LENGTH - 1)) { ms_log (0, "%.*s", (MAX_LOG_MSG_LENGTH - 1), text); text += MAX_LOG_MSG_LENGTH - 1; length -= MAX_LOG_MSG_LENGTH - 1; } /* Print any remaining TEXT and add a newline */ if (length > 0) { ms_log (0, "%.*s\n", length, text); } else { ms_log (0, "\n"); } } else for (cnt = 0, line = 0; line < lines; line++) { for (col = 0; col < 6; col++) { if (cnt < msr->numsamples) { sptr = (char *)msr->datasamples + (cnt * samplesize); if (msr->sampletype == 'i') ms_log (0, "%10d ", *(int32_t *)sptr); else if (msr->sampletype == 'f') ms_log (0, "%10.8g ", *(float *)sptr); else if (msr->sampletype == 'd') ms_log (0, "%10.10g ", *(double *)sptr); cnt++; } } ms_log (0, "\n"); /* If only printing the first 6 samples break out here */ if (printdata == 1) break; } } } } if (retcode != MS_ENDOFFILE) ms_log (2, "Cannot read %s: %s\n", inputfile, ms_errorstr (retcode)); if (tracegap) mstl3_printtracelist (mstl, ISOMONTHDAY_Z, 1, 1, splitversion); /* Make sure everything is cleaned up */ ms3_readmsr (&msr, NULL, flags, 0); if (mstl) mstl3_free (&mstl, 0); if (basicsum) ms_log (1, "Records: %" PRId64 ", Samples: %" PRId64 "\n", totalrecs, totalsamps); return 0; } /* End of main() */ /*************************************************************************** * parameter_proc(): * Process the command line arguments. * * Returns 0 on success, and -1 on failure ***************************************************************************/ static int parameter_proc (int argcount, char **argvec) { int optind; /* Process all command line arguments */ for (optind = 1; optind < argcount; optind++) { if (strcmp (argvec[optind], "-V") == 0) { ms_log (1, "%s version: %s\n", PACKAGE, VERSION); exit (0); } else if (strcmp (argvec[optind], "-h") == 0) { usage (); exit (0); } else if (strncmp (argvec[optind], "-v", 2) == 0) { verbose += strspn (&argvec[optind][1], "v"); } else if (strncmp (argvec[optind], "-p", 2) == 0) { ppackets += strspn (&argvec[optind][1], "p"); } else if (strncmp (argvec[optind], "-z", 2) == 0) { printraw = 1; } else if (strncmp (argvec[optind], "-d", 2) == 0) { printdata = 1; } else if (strncmp (argvec[optind], "-D", 2) == 0) { printdata = 2; } else if (strcmp (argvec[optind], "-P") == 0) { splitversion = 1; } else if (strncmp (argvec[optind], "-tg", 3) == 0) { tracegap = 1; } else if (strcmp (argvec[optind], "-s") == 0) { basicsum = 1; } else if (strcmp (argvec[optind], "-r") == 0) { reclen = atoi (argvec[++optind]); } else if (strncmp (argvec[optind], "-", 1) == 0 && strlen (argvec[optind]) > 1) { ms_log (2, "Unknown option: %s\n", argvec[optind]); exit (1); } else if (inputfile == NULL) { inputfile = argvec[optind]; } else { ms_log (2, "Unknown option: %s\n", argvec[optind]); exit (1); } } /* Make sure an inputfile was specified */ if (!inputfile) { ms_log (2, "No input file was specified\n\n"); ms_log (1, "%s version %s\n\n", PACKAGE, VERSION); ms_log (1, "Try %s -h for usage\n", PACKAGE); exit (1); } /* Add program name and version to User-Agent for URL-based requests */ if (libmseed_url_support() && ms3_url_useragent(PACKAGE, VERSION)) return -1; /* Report the program version */ if (verbose) ms_log (1, "%s version: %s\n", PACKAGE, VERSION); return 0; } /* End of parameter_proc() */ /*************************************************************************** * usage(): * Print the usage message and exit. ***************************************************************************/ static void usage (void) { fprintf (stderr, "%s version: %s\n\n", PACKAGE, VERSION); fprintf (stderr, "Usage: %s [options] file\n\n", PACKAGE); fprintf (stderr, " ## Options ##\n" " -V Report program version\n" " -h Show this usage message\n" " -v Be more verbose, multiple flags can be used\n" " -p Print details of header, multiple flags can be used\n" " -z Print raw details of header\n" " -d Print first 6 sample values\n" " -D Print all sample values\n" " -P Additionally group traces by data publication version\n" " -tg Print trace listing with gap information\n" " -s Print a basic summary after processing a file\n" " -r bytes Specify record length in bytes, required if no Blockette 1000\n" "\n" " file File of miniSEED records\n" "\n"); } /* End of usage() */