Index: /trunk/BNC/src/bncrinex.cpp
===================================================================
--- /trunk/BNC/src/bncrinex.cpp	(revision 4480)
+++ /trunk/BNC/src/bncrinex.cpp	(revision 4481)
@@ -77,6 +77,4 @@
   _headerWritten = false;
   _reconnectFlag = false;
-  _reloadTable   = false;
-  _reloadDone    = false;
 
   bncSettings settings;
@@ -155,5 +153,5 @@
   QStringList table;
   bncTableDlg::getFullTable(_ntripVersion, _mountPoint.host(), 
-                            _mountPoint.port(), table, _reloadTable);
+                            _mountPoint.port(), table, true);
   QString net;
   QStringListIterator it(table);
@@ -206,49 +204,9 @@
     query->waitForRequestResult(url, outData);
     if (query->status() == bncNetQuery::finished) {
-      _headerLines.clear();
-      bool firstLineRead = false;
+      irc = success;
       QTextStream in(outData);
-      QString line = in.readLine();
-      while ( !line.isNull() ) {
-        if (line.indexOf("MARKER NAME") != -1) {
-          irc = success;
-        }
-        if (line.indexOf("RINEX VERSION") != -1) {
-          if (_rinexVers == 3) {
-            _headerLines.append("     3.00           OBSERVATION DATA"
-                                "    M (MIXED)"
-                                "           RINEX VERSION / TYPE");
-          }
-          else {
-            _headerLines.append("     2.11           OBSERVATION DATA"
-                                "    M (MIXED)"
-                                "           RINEX VERSION / TYPE");
-          }
-          _headerLines.append("PGM / RUN BY / DATE");
-          firstLineRead = true;
-        }
-        else if (firstLineRead) {
-          if (line.indexOf("END OF HEADER") != -1) {
-            _headerLines.append("# / TYPES OF OBSERV");
-            if (_rinexVers == 2) {
-              _headerLines.append(
-                    QString("     1     1").leftJustified(60, ' ', true) +
-                    "WAVELENGTH FACT L1/2");
-            }
-            _headerLines.append("TIME OF FIRST OBS");
-            _headerLines.append( line );
-            break;
-          }
-          else {
-            _headerLines.append( line );
-          }
-        }
-        line = in.readLine();
-      }
-    } 
-    else {
-      delete query;
-      return failure;
-    }
+      _header.read(&in);
+    }
+
     delete query;
   }
@@ -265,12 +223,6 @@
   QFile skl(_sklName);
   if ( skl.exists() && skl.open(QIODevice::ReadOnly) ) {
-    _headerLines.clear();
     QTextStream in(&skl);
-    while ( !in.atEnd() ) {
-      _headerLines.append( in.readLine() );
-      if (_headerLines.last().indexOf("END OF HEADER") != -1) {
-        break;
-      }
-    }
+    _header.read(&in);
   }
 
@@ -281,18 +233,6 @@
     QDate currDate = currentDateAndTimeGPS().date();
     if ( !_skeletonDate.isValid() || _skeletonDate != currDate ) {
-      if ( downloadSkeleton() == success) {
-        _skeletonDate = currDate;
-        _reloadDone = false;
-      }
-      else {
-        if(!_reloadDone) {
-          _reloadTable = true;
-          if ( downloadSkeleton() == success) {
-            _skeletonDate = currDate;
-          }
-          _reloadTable = false;
-          _reloadDone = true;
-        }
-      }
+      downloadSkeleton();
+      _skeletonDate = currDate;
     }
   }
@@ -436,139 +376,12 @@
   // --------------------
   readSkeleton();
-  if (_headerLines.size() > 0) {
-    bool typesOfObservationsWritten = false;
-    QStringListIterator it(_headerLines);
-    while (it.hasNext()) {
-      QString line = it.next();
-      if      (line.indexOf("PGM / RUN BY / DATE") != -1) {
-        if (_rinexVers == 3) {
-          QString hlp = currentDateAndTimeGPS().toString("yyyyMMdd hhmmss UTC").leftJustified(20, ' ', true);
-          _out << _pgmName.toAscii().data() << _userName.toAscii().data() 
-               << hlp.toAscii().data() << "PGM / RUN BY / DATE" << endl;
-        }
-        else {
-          QString hlp = currentDateAndTimeGPS().date().toString("dd-MMM-yyyy").leftJustified(20, ' ', true);
-          _out << _pgmName.toAscii().data() << _userName.toAscii().data() 
-               << hlp.toAscii().data() << "PGM / RUN BY / DATE" << endl;
-        }
-      }
-      else if ( !typesOfObservationsWritten &&
-                (line.indexOf("# / TYPES OF OBSERV") != -1 || 
-                 line.indexOf("SYS / # / OBS TYPES") != -1) ) {
-        typesOfObservationsWritten = true;
-        writeObsTypes();
-      }
-      else if (line.indexOf("TIME OF FIRST OBS") != -1) {
-        _out << datTim.toString("  yyyy    MM    dd"
-                                "    hh    mm   ss.zzz0000").toAscii().data();
-        _out << "     GPS         TIME OF FIRST OBS"    << endl;
-        QString hlp = (format.left(6) + QString(" %1").arg(_mountPoint.host() + 
-                      _mountPoint.path())).leftJustified(60, ' ', true);
-        _out << hlp.toAscii().data() << "COMMENT" << endl;
-      }
-      else if (line.indexOf("MARKER NAME") != -1) {
-        if (_rinexVers == 3) {
-          _out << line.toAscii().data() << endl;
-          _out << setw(71) << "GEODETIC                                                    MARKER TYPE" << endl;
-        } 
-        else {
-          _out << line.toAscii().data() << endl;
-        }
-      }
-      else if (line.indexOf("END OF HEADER") != -1) {
-        if (!typesOfObservationsWritten) {
-          writeObsTypes();
-        }
-        _out << line.toAscii().data() << endl;
-        break;
-      }
-      else {
-        _out << line.toAscii().data() << endl;
-      }
-    }
-  }
-
-  // Write Dummy Header
-  // ------------------
-  else {
-    double antennaNEU[3]; antennaNEU[0] = antennaNEU[1] = antennaNEU[2] = 0.0;
-    
-    if (_rinexVers == 3) {
-      _out << "     3.00           OBSERVATION DATA    M (MIXED)           RINEX VERSION / TYPE" << endl;
-      QString hlp = currentDateAndTimeGPS().toString("yyyyMMdd hhmmss UTC").leftJustified(20, ' ', true);
-      _out << _pgmName.toAscii().data() << _userName.toAscii().data() 
-           << hlp.toAscii().data() << "PGM / RUN BY / DATE" << endl;
-    }
-    else {
-      _out << "     2.11           OBSERVATION DATA    M (MIXED)           RINEX VERSION / TYPE" << endl;
-      QString hlp = currentDateAndTimeGPS().date().toString("dd-MMM-yyyy").leftJustified(20, ' ', true);
-      _out << _pgmName.toAscii().data() << _userName.toAscii().data() 
-           << hlp.toAscii().data() << "PGM / RUN BY / DATE" << endl;
-    }
-    _out.setf(ios::left);
-    _out << setw(60) << _statID.data()                               << "MARKER NAME"          << endl;
-    if (_rinexVers == 3) {
-      _out << setw(60) << "unknown"                                  << "MARKER TYPE      "    << endl;
-    }
-    _out << setw(60) << "unknown             unknown"                << "OBSERVER / AGENCY"    << endl;
-    _out << setw(20) << "unknown"    
-         << setw(20) << "unknown"
-         << setw(20) << "unknown"                                    << "REC # / TYPE / VERS"  << endl;
-    _out << setw(20) << "unknown"
-         << setw(20) << "unknown"
-         << setw(20) << " "                                          << "ANT # / TYPE"         << endl;
-    _out.unsetf(ios::left);
-    _out << setw(14) << setprecision(4) << _approxPos[0]
-         << setw(14) << setprecision(4) << _approxPos[1]
-         << setw(14) << setprecision(4) << _approxPos[2] 
-         << "                  "                                     << "APPROX POSITION XYZ"  << endl;
-    _out << setw(14) << setprecision(4) << antennaNEU[0]
-         << setw(14) << setprecision(4) << antennaNEU[1]
-         << setw(14) << setprecision(4) << antennaNEU[2] 
-         << "                  "                                     << "ANTENNA: DELTA H/E/N" << endl;
-        
-    writeObsTypes();
-
-    _out << datTim.toString("  yyyy    MM    dd"
-                                "    hh    mm   ss.zzz0000").toAscii().data();
-    _out << "     GPS         TIME OF FIRST OBS"    << endl;
-    QString hlp = (format.left(6) + QString(" %1").arg(_mountPoint.host() + 
-          _mountPoint.path())).leftJustified(60, ' ', true);
-    _out << hlp.toAscii().data() << "COMMENT" << endl;
-
-    if (_nmea == "yes") {
-    hlp = ("NMEA LAT=" + _latitude + " " + "LONG=" + _longitude).leftJustified(60, ' ',true);
-    _out << hlp.toAscii().data() << "COMMENT" << endl; }
-
-    _out << "                                                            END OF HEADER"        << endl;
-  }
+
+  QByteArray headerLines;
+  QTextStream outHlp(&headerLines);
+  _header.write(&outHlp);
+  outHlp.flush();
+  _out << headerLines.data();
 
   _headerWritten = true;
-}
-
-// 
-////////////////////////////////////////////////////////////////////////////
-void bncRinex::writeObsTypes() {
-  if (_rinexVers == 3) {
-    QMapIterator<char, QVector<QString> > it(_rnxTypes);
-    while (it.hasNext()) {
-      it.next();
-      char sys                      = it.key();
-      const QVector<QString>& types = it.value();
-      QString hlp;
-      QTextStream(&hlp) << QString("%1  %2").arg(sys).arg(types.size(), 3);
-      for (int ii = 0; ii < types.size(); ii++) {
-        QTextStream(&hlp) << QString(" %1").arg(types[ii], -3);   
-        if ((ii+1) % 13 == 0 || ii == types.size()-1) {
-          _out << QString(hlp.leftJustified(60) + "SYS / # / OBS TYPES\n").toAscii().data();
-          hlp = QString().leftJustified(6);
-        }
-      }
-    }
-  }
-  else {
-    _out << "     1     1                                                WAVELENGTH FACT L1/2" << endl;
-    _out << "     8    C1    P1    L1    S1    C2    P2    L2    S2      # / TYPES OF OBSERV"  << endl;
-  }
 }
 
Index: /trunk/BNC/src/bncrinex.h
===================================================================
--- /trunk/BNC/src/bncrinex.h	(revision 4480)
+++ /trunk/BNC/src/bncrinex.h	(revision 4481)
@@ -30,4 +30,5 @@
 
 #include "bncconst.h"
+#include "rinex/rnxobsfile.h"
 
 class t_obs;
@@ -66,5 +67,4 @@
    void closeFile();
    t_irc downloadSkeleton();
-   void writeObsTypes();
 
    QByteArray    _statID;
@@ -72,5 +72,4 @@
    QList<t_obs>  _obs;
    std::ofstream _out;
-   QStringList   _headerLines;
    bool          _headerWritten;
    QDateTime     _nextCloseEpoch;
@@ -87,6 +86,4 @@
    QDate         _skeletonDate;
    int           _rinexVers;
-   bool          _reloadTable;
-   bool          _reloadDone;
    double        _approxPos[3];
    int           _samplingRate;
@@ -97,4 +94,6 @@
 
    QMap<char, QVector<QString> > _rnxTypes;
+
+   t_rnxObsHeader _header;
 };
 
Index: /trunk/BNC/src/combination/bnccomb.cpp
===================================================================
--- /trunk/BNC/src/combination/bnccomb.cpp	(revision 4480)
+++ /trunk/BNC/src/combination/bnccomb.cpp	(revision 4481)
@@ -37,5 +37,4 @@
 const double sigObs        =   0.05;
 
-const int MAXPRN_GPS     = 32;
 const int MAXPRN_GLONASS = 24;
 
Index: /trunk/BNC/src/rinex/reqcedit.cpp
===================================================================
--- /trunk/BNC/src/rinex/reqcedit.cpp	(revision 4480)
+++ /trunk/BNC/src/rinex/reqcedit.cpp	(revision 4481)
@@ -180,5 +180,5 @@
         txtMap["COMMENT"]  = comment;
       }
-      outObsFile.writeHeader(&txtMap);
+      obsFile->header().write(obsFile->stream(), &txtMap);
     }
     else {
Index: /trunk/BNC/src/rinex/rnxobsfile.cpp
===================================================================
--- /trunk/BNC/src/rinex/rnxobsfile.cpp	(revision 4480)
+++ /trunk/BNC/src/rinex/rnxobsfile.cpp	(revision 4481)
@@ -203,4 +203,128 @@
 }
 
+// Write Header
+////////////////////////////////////////////////////////////////////////////
+void t_rnxObsHeader::write(QTextStream* stream,
+                           const QMap<QString, QString>* txtMap) const {
+
+  bncApp* app = (bncApp*) qApp;
+
+  QString     runBy = app->userName();
+  QStringList comments;
+
+  if (txtMap) {
+    QMapIterator<QString, QString> it(*txtMap);
+    while (it.hasNext()) {
+      it.next();
+      if      (it.key() == "RUN BY") {
+        runBy = it.value();
+      }
+      else if (it.key() == "COMMENT") {
+        comments = it.value().split("\\n", QString::SkipEmptyParts);
+      }
+    }
+  }
+
+  *stream << QString("%1           Observation data    Mixed")
+    .arg(_version, 9, 'f', 2)
+    .leftJustified(60)
+           << "RINEX VERSION / TYPE\n";
+
+  const QString fmtDate = (_version < 3.0) ? "dd-MMM-yy hh:mm"
+                                                  : "yyyyMMdd hhmmss UTC";
+  *stream << QString("%1%2%3")
+    .arg(app->pgmName(), -20)
+    .arg(runBy.trimmed().left(20), -20)
+    .arg(QDateTime::currentDateTime().toUTC().toString(fmtDate), -20)
+    .leftJustified(60)
+           << "PGM / RUN BY / DATE\n";
+
+  QStringListIterator itCmnt(comments);
+  while (itCmnt.hasNext()) {
+    *stream << itCmnt.next().trimmed().left(60).leftJustified(60) << "COMMENT\n";
+  }
+
+  *stream << QString("%1")
+    .arg(_markerName, -60)
+    .leftJustified(60)
+           << "MARKER NAME\n";
+
+  if (!_markerNumber.isEmpty()) {
+    *stream << QString("%1")
+      .arg(_markerNumber, -20)
+      .leftJustified(60)
+             << "MARKER NUMBER\n";
+  }
+
+  *stream << QString("%1%2")
+    .arg(_observer, -20)
+    .arg(_agency,   -40)
+    .leftJustified(60)
+           << "OBSERVER / AGENCY\n";
+
+  *stream << QString("%1%2%3")
+    .arg(_receiverNumber,  -20)
+    .arg(_receiverType,    -20)
+    .arg(_receiverVersion, -20)
+    .leftJustified(60)
+           << "REC # / TYPE / VERS\n";
+
+  *stream << QString("%1%2")
+    .arg(_antennaNumber, -20)
+    .arg(_antennaName,   -20)
+    .leftJustified(60)
+           << "ANT # / TYPE\n";
+
+  *stream << QString("%1%2%3")
+    .arg(_xyz(1), 14, 'f', 4)
+    .arg(_xyz(2), 14, 'f', 4)
+    .arg(_xyz(3), 14, 'f', 4)
+    .leftJustified(60)
+           << "APPROX POSITION XYZ\n";
+
+  *stream << QString("%1%2%3")
+    .arg(_antNEU(3), 14, 'f', 4)
+    .arg(_antNEU(2), 14, 'f', 4)
+    .arg(_antNEU(1), 14, 'f', 4)
+    .leftJustified(60)
+           << "ANTENNA: DELTA H/E/N\n";
+
+  if (_version < 3.0) {
+    int defaultWlFact1 = _wlFactorsL1[1];
+    int defaultWlFact2 = _wlFactorsL2[1];  // TODO check all prns
+    *stream << QString("%1%2")
+      .arg(defaultWlFact1, 6)
+      .arg(defaultWlFact2, 6)
+      .leftJustified(60)
+             << "WAVELENGTH FACT L1/2\n";
+  }
+
+  *stream << obsTypesStrings().join("");
+
+  *stream << QString("%1")
+    .arg(_interval, 10, 'f', 3)
+    .leftJustified(60)
+           << "INTERVAL\n";
+
+  unsigned year, month, day, hour, min;
+  double sec;
+  _startTime.civil_date(year, month, day);
+  _startTime.civil_time(hour, min, sec);
+  *stream << QString("%1%2%3%4%5%6%7")
+    .arg(year, 6)
+    .arg(month, 6)
+    .arg(day, 6)
+    .arg(hour, 6)
+    .arg(min, 6)
+    .arg(sec, 13, 'f', 7)
+    .arg("GPS", 8)
+    .leftJustified(60)
+           << "TIME OF FIRST OBS\n";
+
+  *stream << QString()
+    .leftJustified(60)
+           << "END OF HEADER\n";
+}
+
 // Number of Observation Types (satellite-system specific)
 ////////////////////////////////////////////////////////////////////////////
@@ -233,4 +357,42 @@
     }
   }
+}
+
+// Write Observation Types
+////////////////////////////////////////////////////////////////////////////
+QStringList t_rnxObsHeader::obsTypesStrings() const {
+
+  QStringList strList;
+
+  if (_version < 3.0) {
+    QString hlp;
+    QTextStream(&hlp) << QString("%1").arg(_obsTypesV2.size(), 6);
+    for (int ii = 0; ii < _obsTypesV2.size(); ii++) {
+      QTextStream(&hlp) << QString("%1").arg(_obsTypesV2[ii], 6);   
+      if ((ii+1) % 9 == 0 || ii == _obsTypesV2.size()-1) {
+        strList.append(hlp.leftJustified(60) + "# / TYPES OF OBSERV\n");
+        hlp = QString().leftJustified(6);
+      }
+    }
+  }
+  else {
+    QMapIterator<char, QVector<QString> > it(_obsTypesV3);
+    while (it.hasNext()) {
+      it.next();
+      char sys                      = it.key();
+      const QVector<QString>& types = it.value();
+      QString hlp;
+      QTextStream(&hlp) << QString("%1  %2").arg(sys).arg(types.size(), 3);
+      for (int ii = 0; ii < types.size(); ii++) {
+        QTextStream(&hlp) << QString(" %1").arg(types[ii], -3);   
+        if ((ii+1) % 13 == 0 || ii == types.size()-1) {
+          strList.append(hlp.leftJustified(60) + "SYS / # / OBS TYPES\n");
+          hlp = QString().leftJustified(6);
+        }
+      }
+    }
+  }
+
+  return strList;
 }
 
@@ -643,165 +805,4 @@
 }
 
-// Write Header
-////////////////////////////////////////////////////////////////////////////
-void t_rnxObsFile::writeHeader(const QMap<QString, QString>* txtMap) {
-
-  bncApp* app = (bncApp*) qApp;
-
-  QString     runBy = app->userName();
-  QStringList comments;
-
-  if (txtMap) {
-    QMapIterator<QString, QString> it(*txtMap);
-    while (it.hasNext()) {
-      it.next();
-      if      (it.key() == "RUN BY") {
-        runBy = it.value();
-      }
-      else if (it.key() == "COMMENT") {
-        comments = it.value().split("\\n", QString::SkipEmptyParts);
-      }
-    }
-  }
-
-  *_stream << QString("%1           Observation data    Mixed")
-    .arg(_header._version, 9, 'f', 2)
-    .leftJustified(60)
-           << "RINEX VERSION / TYPE\n";
-
-  const QString fmtDate = (version() < 3.0) ? "dd-MMM-yy hh:mm"
-                                            : "yyyyMMdd hhmmss UTC";
-  *_stream << QString("%1%2%3")
-    .arg(app->pgmName(), -20)
-    .arg(runBy.trimmed().left(20), -20)
-    .arg(QDateTime::currentDateTime().toUTC().toString(fmtDate), -20)
-    .leftJustified(60)
-           << "PGM / RUN BY / DATE\n";
-
-  QStringListIterator itCmnt(comments);
-  while (itCmnt.hasNext()) {
-    *_stream << itCmnt.next().trimmed().left(60).leftJustified(60) << "COMMENT\n";
-  }
-
-  *_stream << QString("%1")
-    .arg(_header._markerName, -60)
-    .leftJustified(60)
-           << "MARKER NAME\n";
-
-  if (!_header._markerNumber.isEmpty()) {
-    *_stream << QString("%1")
-      .arg(_header._markerNumber, -20)
-      .leftJustified(60)
-             << "MARKER NUMBER\n";
-  }
-
-  *_stream << QString("%1%2")
-    .arg(_header._observer, -20)
-    .arg(_header._agency,   -40)
-    .leftJustified(60)
-           << "OBSERVER / AGENCY\n";
-
-  *_stream << QString("%1%2%3")
-    .arg(_header._receiverNumber,  -20)
-    .arg(_header._receiverType,    -20)
-    .arg(_header._receiverVersion, -20)
-    .leftJustified(60)
-           << "REC # / TYPE / VERS\n";
-
-  *_stream << QString("%1%2")
-    .arg(_header._antennaNumber, -20)
-    .arg(_header._antennaName,   -20)
-    .leftJustified(60)
-           << "ANT # / TYPE\n";
-
-  *_stream << QString("%1%2%3")
-    .arg(_header._xyz(1), 14, 'f', 4)
-    .arg(_header._xyz(2), 14, 'f', 4)
-    .arg(_header._xyz(3), 14, 'f', 4)
-    .leftJustified(60)
-           << "APPROX POSITION XYZ\n";
-
-  *_stream << QString("%1%2%3")
-    .arg(_header._antNEU(3), 14, 'f', 4)
-    .arg(_header._antNEU(2), 14, 'f', 4)
-    .arg(_header._antNEU(1), 14, 'f', 4)
-    .leftJustified(60)
-           << "ANTENNA: DELTA H/E/N\n";
-
-  if (_header._version < 3.0) {
-    int defaultWlFact1 = _header._wlFactorsL1[1];
-    int defaultWlFact2 = _header._wlFactorsL2[1];  // TODO check all prns
-    *_stream << QString("%1%2")
-      .arg(defaultWlFact1, 6)
-      .arg(defaultWlFact2, 6)
-      .leftJustified(60)
-             << "WAVELENGTH FACT L1/2\n";
-  }
-
-  *_stream << obsTypesStrings().join("");
-
-  *_stream << QString("%1")
-    .arg(_header._interval, 10, 'f', 3)
-    .leftJustified(60)
-           << "INTERVAL\n";
-
-  unsigned year, month, day, hour, min;
-  double sec;
-  _header._startTime.civil_date(year, month, day);
-  _header._startTime.civil_time(hour, min, sec);
-  *_stream << QString("%1%2%3%4%5%6%7")
-    .arg(year, 6)
-    .arg(month, 6)
-    .arg(day, 6)
-    .arg(hour, 6)
-    .arg(min, 6)
-    .arg(sec, 13, 'f', 7)
-    .arg("GPS", 8)
-    .leftJustified(60)
-           << "TIME OF FIRST OBS\n";
-
-  *_stream << QString()
-    .leftJustified(60)
-           << "END OF HEADER\n";
-}
-
-// Write Observation Types
-////////////////////////////////////////////////////////////////////////////
-QStringList t_rnxObsFile::obsTypesStrings() {
-
-  QStringList strList;
-
-  if (_header._version < 3.0) {
-    QString hlp;
-    QTextStream(&hlp) << QString("%1").arg(_header._obsTypesV2.size(), 6);
-    for (int ii = 0; ii < _header._obsTypesV2.size(); ii++) {
-      QTextStream(&hlp) << QString("%1").arg(_header._obsTypesV2[ii], 6);   
-      if ((ii+1) % 9 == 0 || ii == _header._obsTypesV2.size()-1) {
-        strList.append(hlp.leftJustified(60) + "# / TYPES OF OBSERV\n");
-        hlp = QString().leftJustified(6);
-      }
-    }
-  }
-  else {
-    QMapIterator<char, QVector<QString> > it(_header._obsTypesV3);
-    while (it.hasNext()) {
-      it.next();
-      char sys                      = it.key();
-      const QVector<QString>& types = it.value();
-      QString hlp;
-      QTextStream(&hlp) << QString("%1  %2").arg(sys).arg(types.size(), 3);
-      for (int ii = 0; ii < types.size(); ii++) {
-        QTextStream(&hlp) << QString(" %1").arg(types[ii], -3);   
-        if ((ii+1) % 13 == 0 || ii == types.size()-1) {
-          strList.append(hlp.leftJustified(60) + "SYS / # / OBS TYPES\n");
-          hlp = QString().leftJustified(6);
-        }
-      }
-    }
-  }
-
-  return strList;
-}
-
 // Write Data Epoch
 ////////////////////////////////////////////////////////////////////////////
@@ -1068,5 +1069,5 @@
 
   if (!same) {
-    QStringList strLst = obsTypesStrings();
+    QStringList strLst = _header.obsTypesStrings();
     int numBlanks = _header._version < 3.0 ? 26 : 29;
     *_stream << QString().leftJustified(numBlanks)
Index: /trunk/BNC/src/rinex/rnxobsfile.h
===================================================================
--- /trunk/BNC/src/rinex/rnxobsfile.h	(revision 4480)
+++ /trunk/BNC/src/rinex/rnxobsfile.h	(revision 4481)
@@ -46,4 +46,7 @@
   int             nTypes(char sys) const;
   const QString&  obsType(char sys, int index) const;
+  QStringList     obsTypesStrings() const;
+  void            write(QTextStream* stream,
+                        const QMap<QString, QString>* txtMap = 0) const;
 
   static const QString          _emptyStr;
@@ -134,7 +137,7 @@
   void setHeader(const t_rnxObsHeader& header, double version);
   void checkNewHeader(const t_rnxObsHeader& header);
-  void writeHeader(const QMap<QString, QString>* txtMap = 0);
-  QStringList obsTypesStrings();
   void writeEpoch(const t_rnxEpo* epo);
+
+  QTextStream* stream() {return _stream;}
 
  private:
