diff src/zfstream.cc @ 6777:4775fc1aa728

[project @ 2007-07-18 16:32:51 by dbateman]
author dbateman
date Wed, 18 Jul 2007 16:32:52 +0000
parents 6e5835ef21f8
children f966543d105f
line wrap: on
line diff
--- a/src/zfstream.cc
+++ b/src/zfstream.cc
@@ -207,6 +207,47 @@
     return 0;
 }
 
+// Puts back a character to the stream in two cases. Firstly, when there
+// is no putback position available, and secondly when the character putback
+// differs from the one in the file. We can only support the first case 
+// with gzipped files.
+gzfilebuf::int_type
+gzfilebuf::pbackfail (gzfilebuf::int_type c)
+{
+  if (this->is_open())
+    {
+      if (gzseek (file, this->gptr() - this->egptr() - 1, SEEK_CUR) < 0)
+	return traits_type::eof();
+  
+      // Invalidates contents of the buffer
+      enable_buffer ();
+
+      // Attempt to fill internal buffer from gzipped file
+      // (buffer must be guaranteed to exist...)
+      int bytes_read = gzread(file, buffer, buffer_size);
+      // Indicates error or EOF
+      if (bytes_read <= 0)
+	{
+	  // Reset get area
+	  this->setg(buffer, buffer, buffer);
+	  return traits_type::eof();
+	}
+
+      // Make all bytes read from file available as get area
+      this->setg(buffer, buffer, buffer + bytes_read);
+
+      // If next character in get area differs from putback character
+      // flag a failure
+      gzfilebuf::int_type ret = traits_type::to_int_type(*(this->gptr()));
+      if (ret != c)
+	return traits_type::eof();
+      else
+	return ret;
+    }
+  else
+    return traits_type::eof();
+}
+
 // Fill get area from gzipped file
 gzfilebuf::int_type
 gzfilebuf::underflow()