Index: trunk/BNC/RTCM/RTCM2.cpp
===================================================================
--- trunk/BNC/RTCM/RTCM2.cpp	(revision 708)
+++ trunk/BNC/RTCM/RTCM2.cpp	(revision 709)
@@ -45,4 +45,6 @@
 //   2008/03/04  AHA  Fixed problems with PRN 32
 //   2008/03/05  AHA  Implemeted fix for Trimble 4000SSI receivers
+//   2008/03/07  AHA  Major revision of input buffer handling 
+//   2008/03/07  AHA  Removed unnecessary failure flag
 //
 // (c) DLR/GSOC
@@ -63,5 +65,5 @@
 // undersized packets in get(Unsigned)Bits
 
-#define DEBUG 0    
+#define DEBUG 0
 
 // Activate (1) or deactivate (0) rounding of measurement epochs to 100ms
@@ -136,10 +138,4 @@
 void ThirtyBitWord::clear() {
   W = 0;
-};
-
-// Failure indicator for input operations
-
-bool ThirtyBitWord::fail() const {
-  return failure; 
 };
 
@@ -259,5 +255,4 @@
 
 
-
 // Append a byte with six data bits
 
@@ -275,5 +270,5 @@
   // Bits 7 and 6 (of 0..7) must be "01" for valid data bytes
   if ( (b & 0x40) != 0x40 ) {
-    failure = true;
+    // We simply skip the invalid input byte and leave the word unchanged
     return;
   };
@@ -290,10 +285,10 @@
 // Get next 30bit word from string
 
-void ThirtyBitWord::get(string& buf) {
+void ThirtyBitWord::get(const string& buf) {
 
   // Check if string is long enough
    
   if (buf.size()<5) {
-    failure = true;
+    // Ignore; users should avoid this case prior to calling get()
     return;
   };
@@ -302,13 +297,11 @@
   
   for (int i=0; i<5; i++) append(buf[i]);
-  buf.erase(0,5);
 
 #if (DEBUG>0) 
   if (!validParity()) {
-    cerr << "Parity error " 
+    cerr << "Parity error in get()" 
          << bitset<32>(all()) << endl;
   };
 #endif
-  failure = false;
 
 };
@@ -328,9 +321,8 @@
 #if (DEBUG>0) 
   if (!validParity()) {
-    cerr << "Parity error " 
+    cerr << "Parity error in get()" 
          << bitset<32>(all()) << endl;
   };
 #endif
-  failure = false;
 
 };
@@ -340,31 +332,28 @@
 void ThirtyBitWord::getHeader(string& buf) {
 
-  unsigned int W_old = W;
+  const int wordLen = 5; // Number of bytes representing a 30-bit word
+  const int spare   = 1; // Number of spare words for resync of parity
+                         // (same value as inRTCM2packet::getPacket()) 
   unsigned int i;
   
   i=0;
-  while (!isHeader() || i<5 ) {
-    // Check if string is long enough; if not restore old word and exit
-    if (buf.size()<i+1) {
-      W = W_old;
-      failure = true;
-      return;
-    };
+  while (!isHeader() && i<buf.size() ) {
     // Process byte
-    append(buf[i]); i++;
-  };
-
-  // Remove processed bytes from buffer
-  
-  buf.erase(0,i);
+    append(buf[i]);
+    // Increment count
+    i++;
+  };
+
+  // Remove processed bytes from buffer. Retain also the previous word to
+  // allow a resync if getHeader() is called repeatedly on the same buffer.
+  if (i>=(1+spare)*wordLen) buf.erase(0,i-(1+spare)*wordLen);
 
 #if (DEBUG>0) 
   if (!validParity()) {
-    cerr << "Parity error " 
+    cerr << "Parity error in getHeader()" 
          << bitset<32>(all()) << endl;
   };
 #endif
-  failure = false;
-
+  
 };
 
@@ -385,9 +374,8 @@
 #if (DEBUG>0) 
   if (!validParity()) {
-    cerr << "Parity error " 
+    cerr << "Parity error in getHeader()" 
          << bitset<32>(all()) << endl;
   };
 #endif
-  failure = false;
 
 };
@@ -443,33 +431,69 @@
 void RTCM2packet::getPacket(std::string& buf) {
 
-  int           n;
-  ThirtyBitWord W_old = W;
-  string        buf_old = buf;
-  
-  // Try to read a full packet. If the input buffer is too short
-  // clear all data and restore the latest 30-bit word prior to 
-  // the getPacket call. The empty header word will indicate
-  // an invalid message, which signals an unsuccessful getPacket()
-  // call.
-   
-  W.getHeader(buf); 
-  H1 = W.value(); 
-  if (W.fail()) { clear(); W=W_old; buf=buf_old; return; };
-  if (!W.validParity()) { clear(); return; };
-  
-  W.get(buf);       
-  H2 = W.value(); 
-  if (W.fail()) { clear(); W=W_old; buf=buf_old; return; };
-  if (!W.validParity()) { clear(); return; };
+  const int wordLen = 5; // Number of bytes representing a 30-bit word
+  const int spare   = 1; // Number of spare words for resync of parity
+                         // (same value as used in ThirtyBitWord::getHeader)
+  unsigned int n;
+  
+  // Try to read a full packet. Processed bytes are removed from the input 
+  // buffer except for the latest spare*wordLen bytes to restore the parity 
+  // bytes upon subseqeunt calls of getPAcket().
+  
+  // Locate and read the first header word
+  W.getHeader(buf);
+  if (!W.isHeader()) { 
+    // No header found; try again next time. buf retains only the spare
+    // words. The packet contents is cleared to indicate an unsuccessful
+    // termination of getPacket().
+    clear();
+    return; 
+  };
+  H1 = W.value();
+  
+  // Do we have enough bytes to read the next word? If not, the packet 
+  // contents is cleared to indicate an unsuccessful termination. The
+  // previously read spare and header bytes are retained in the buffer
+  // for use in the next call of getPacket().
+  if (buf.size()<(spare+2)*wordLen) { clear(); return; };
+  
+  // Read the second header word
+  W.get(buf.substr((spare+1)*wordLen,buf.size()-1-(spare+1)*wordLen));  
+  H2 = W.value();
+  if (!W.validParity()) { 
+    // Invalid H2 word; delete first buffer byte and try to resynch next time.
+    // The packet contents is cleared to indicate an unsuccessful termination.
+    clear(); 
+    buf.erase(0,1); 
+    return; 
+  };
 
   n = nDataWords();
+  
+  // Do we have enough bytes to read the next word? If not, the packet 
+  // contents is cleared to indicate an unsuccessful termination. The
+  // previously read spare and header bytes are retained in the buffer
+  // for use in the next call of getPacket().
+  if (buf.size()<(spare+2+n)*wordLen) { clear(); return; };
+  
   DW.resize(n);
-  for (int i=0; i<n; i++) {
-    W.get(buf); 
-    DW[i] = W.value(); 
-    if (W.fail()) { clear(); W=W_old; buf=buf_old; return; };
-    if (!W.validParity()) { clear(); return; };
-  };
-
+  for (unsigned int i=0; i<n; i++) {
+    W.get(buf.substr((spare+2+i)*wordLen,buf.size()-1-(spare+2+i)*wordLen)); 
+    DW[i] = W.value();
+    if (!W.validParity()) { 
+      // Invalid data word; delete first byte and try to resynch next time.
+      // The packet contents is cleared to indicate an unsuccessful termination.
+      clear(); 
+      buf.erase(0,1); 
+      return; 
+    };
+  };
+
+  // Successful packet extraction; delete total number of message bytes 
+  // from buffer. 
+  // Note: a total of "spare" words remain in the buffer to enable a
+  // parity resynchronization when searching the next header.
+  
+  buf.erase(0,(n+2)*wordLen);
+  
   return;
   
@@ -487,9 +511,9 @@
   W.getHeader(inp); 
   H1 = W.value(); 
-  if (W.fail() || !W.validParity()) { clear(); return; }
+  if (inp.fail() || !W.isHeader()) { clear(); return; }
   
   W.get(inp);       
   H2 = W.value(); 
-  if (W.fail() || !W.validParity()) { clear(); return; }
+  if (inp.fail() || !W.validParity()) { clear(); return; }
 
   n = nDataWords();
@@ -498,5 +522,5 @@
     W.get(inp); 
     DW[i] = W.value(); 
-    if (W.fail() || !W.validParity()) { clear(); return; }
+    if (inp.fail() || !W.validParity()) { clear(); return; }
   };
 
