void RinexNavHeader::reallyGetRecord(FFStream& ffs) throw(std::exception, FFStreamError, StringException) { RinexNavStream& strm = dynamic_cast<RinexNavStream&>(ffs); // if already read, just return if (strm.headerRead == true) return; valid = 0; // clear out anything that was unsuccessfully read the first commentList.clear(); while (! (valid & endValid)) { string line; strm.formattedGetLine(line); StringUtils::stripTrailing(line); if (line.length()==0) continue; else if (line.length()<60 || line.length()>80) { FFStreamError e("Invalid line length"); GPSTK_THROW(e); } string thisLabel(line, 60, 20); if (thisLabel == versionString) { version = asDouble(line.substr(0,20)); fileType = strip(line.substr(20,20)); if ( (fileType[0] != 'N') && (fileType[0] != 'n')) { FFStreamError e("This isn't a Rinex Nav file"); GPSTK_THROW(e); } valid |= versionValid; } else if (thisLabel == runByString) { fileProgram = strip(line.substr(0,20)); fileAgency = strip(line.substr(20,20)); date = strip(line.substr(40,20)); valid |= runByValid; } else if (thisLabel == commentString) { commentList.push_back(strip(line.substr(0,60))); valid |= commentValid; } else if (thisLabel == ionAlphaString) { for(int i = 0; i < 4; i++) ionAlpha[i] = gpstk::StringUtils::for2doub(line.substr(2 + 12 * i,12)); valid |= ionAlphaValid; } else if (thisLabel == ionBetaString) { for(int i = 0; i < 4; i++) ionBeta[i] = gpstk::StringUtils::for2doub(line.substr(2 + 12 * i,12)); valid |= ionBetaValid; } else if (thisLabel == deltaUTCString) { A0 = gpstk::StringUtils::for2doub(line.substr(3,19)); A1 = gpstk::StringUtils::for2doub(line.substr(22,19)); UTCRefTime = asInt(line.substr(41,9)); UTCRefWeek = asInt(line.substr(50,9)); valid |= deltaUTCValid; } else if (thisLabel == leapSecondsString) { leapSeconds = asInt(line.substr(0,6)); valid |= leapSecondsValid; } else if (thisLabel == endOfHeader) { valid |= endValid; } else { throw(FFStreamError("Unknown header label at line " + asString<size_t>(strm.lineNumber))); } } unsigned long allValid; if (version == 2.0) allValid = allValid20; else if (version == 2.1) allValid = allValid21; else if (version == 2.11) allValid = allValid211; else { FFStreamError e("Unknown or unsupported RINEX version " + asString(version)); GPSTK_THROW(e); } if ( (allValid & valid) != allValid) { FFStreamError e("Incomplete or invalid header"); GPSTK_THROW(e); } // we got here, so something must be right... strm.header = *this; strm.headerRead = true; }
void RinexMetHeader::reallyGetRecord(FFStream& ffs) throw(std::exception, FFStreamError, gpstk::StringUtils::StringException) { RinexMetStream& strm = dynamic_cast<RinexMetStream&>(ffs); // if already read, just return if (strm.headerRead == true) return; valid = 0; // clear out structures in case the last read was a partial header // and there's cruft left commentList.clear(); obsTypeList.clear(); sensorTypeList.clear(); sensorPosList.clear(); int numObs; while (! (valid & endValid)) { string line; strm.formattedGetLine(line); if (line.length()<60 || line.length()>81) { FFStreamError e("Bad line length"); GPSTK_THROW(e); } string thisLabel(line, 60, 20); if (thisLabel == versionString) { version = asDouble(line.substr(0,20)); fileType = strip(line.substr(20,20)); if ( (fileType[0] != 'M') && (fileType[0] != 'm')) { FFStreamError e("This isn't a Rinex Met file"); GPSTK_THROW(e); } valid |= versionValid; } else if (thisLabel == runByString) { fileProgram = strip(line.substr(0,20)); fileAgency = strip(line.substr(20,20)); date = strip(line.substr(40,20)); valid |= runByValid; } else if (thisLabel == commentString) { commentList.push_back(strip(line.substr(0,60))); valid |= commentValid; } else if (thisLabel == markerNameString) { markerName = strip(line.substr(0,60)); valid |= markerNameValid; } else if (thisLabel == markerNumberString) { markerNumber = strip(line.substr(0,20)); valid |= markerNumberValid; } else if (thisLabel == obsTypeString) { // read the first line if (! (valid & obsTypeValid)) { numObs = gpstk::StringUtils::asInt(line.substr(0,6)); for (int i = 0; (i < numObs) && (i < maxObsPerLine); i++) { int currPos = i * 6 + 6; if (line.substr(currPos, 4) != string(4, ' ')) { FFStreamError e("Format error for line type " + obsTypeString); GPSTK_THROW(e); } obsTypeList.push_back(convertObsType(line.substr(currPos + 4, 2))); } valid |= obsTypeValid; } // read continuation lines else { int currentObsTypes = obsTypeList.size(); for (int i = currentObsTypes; (i < numObs) && (i < (maxObsPerLine + currentObsTypes)); i++) { int currPos = (i % maxObsPerLine) * 6 + 6; if (line.substr(currPos, 4) != string(4,' ')) { FFStreamError e("Format error for line type " + obsTypeString); GPSTK_THROW(e); } obsTypeList.push_back(convertObsType(line.substr(currPos + 4, 2))); } } } else if (thisLabel == sensorTypeString) { if (line.substr(40,6) != string(6, ' ')) { FFStreamError e("Format error for line type " + sensorTypeString); GPSTK_THROW(e); } sensorType st; st.model = strip(line.substr(0,20)); st.type = strip(line.substr(20,20)); st.accuracy = asDouble(line.substr(46,9)); st.obsType = convertObsType(line.substr(57,2)); sensorTypeList.push_back(st); // only set this valid if there are exactly // the same number in both lists if (sensorTypeList.size() == obsTypeList.size()) { valid |= sensorTypeValid; } else { valid &= ~(long)sensorTypeValid; } } else if (thisLabel == sensorPosString) { // read XYZ and H and obs type sensorPosType sp; sp.position[0] = asDouble(line.substr(0,14)); sp.position[1] = asDouble(line.substr(14,14)); sp.position[2] = asDouble(line.substr(28,14)); sp.height = asDouble(line.substr(42,14)); sp.obsType = convertObsType(line.substr(57,2)); sensorPosList.push_back(sp); // only barometer is required, so // set it valid only if you see that record. if (sp.obsType == PR) { valid |= sensorPosValid; } } else if (thisLabel == endOfHeader) { valid |= endValid; } else { FFStreamError e("Unknown header label " + thisLabel); GPSTK_THROW(e); } } unsigned long allValid; if (version == 2.0) allValid = allValid20; else if (version == 2.1) allValid = allValid21; else { FFStreamError e("Unknown or unsupported RINEX version " + asString(version)); GPSTK_THROW(e); } if ( (allValid & valid) != allValid) { string errstr("Incomplete or invalid header: missing: "); errstr += bitString(allValid & ~valid); FFStreamError err(errstr); GPSTK_THROW(err); } // we got here, so something must be right... strm.header = *this; strm.headerRead = true; }