This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [Patch] Fix seek to beg after grow bug


Benjamin Kosnik wrote:

Ok?

Ok. Are you going to put in the sputc part of 9404 at some point?

Oh, well, that is the _easy_ part ;)

The only reason why I didn't do that already is that, if picky about this kind of issues,
there are also a few more, I'm afraid...

... and 9404 itself it's really tough if we want clean and neat code as you taught me to
strive for, otherwise what you find attached already 'works'...
(i.e. passes the testsuite + 9404)

Paolo.

diff -urN libstdc++-v3-orig/include/bits/sstream.tcc libstdc++-v3/include/bits/sstream.tcc
--- libstdc++-v3-orig/include/bits/sstream.tcc	2003-01-16 21:30:23.000000000 +0100
+++ libstdc++-v3/include/bits/sstream.tcc	2003-02-15 10:28:08.000000000 +0100
@@ -91,6 +91,8 @@
 	{
 	  if (!__testeof)
 	    {
+	      // We can implement this exponential grow policy in
+	      // the light of the resolution of DR 169 (TC).
 	      __size_type __len = std::max(this->_M_buf_size, 
 					   this->_M_buf_size_opt);
 	      __len *= 2;
@@ -102,7 +104,6 @@
 		  // Force-allocate, re-sync.
 		  _M_string = this->str();
 		  _M_string.reserve(__len);
-		  this->_M_buf_size = __len;
 		  _M_really_sync(this->_M_in_cur - this->_M_in_beg, 
 				 this->_M_out_cur - this->_M_out_beg);
 		  *this->_M_out_cur = traits_type::to_char_type(__c);
@@ -144,7 +145,7 @@
 	  if (__testout || __testboth)
 	    {
 	      __curo = this->pptr();
-	      __endo = this->epptr();
+	      __endo = this->_M_out_end;
 	    }
 
 	  off_type __newoffi = 0;
diff -urN libstdc++-v3-orig/include/std/std_sstream.h libstdc++-v3/include/std/std_sstream.h
--- libstdc++-v3-orig/include/std/std_sstream.h	2003-01-23 19:56:00.000000000 +0100
+++ libstdc++-v3/include/std/std_sstream.h	2003-02-15 14:39:34.000000000 +0100
@@ -140,7 +140,7 @@
 	    // _M_string, and may not be the correct size of the
 	    // current stringbuf internal buffer.
 	    __size_type __len = _M_string.size();
-	    if (this->_M_out_cur > this->_M_out_beg)
+	    if (this->_M_out_end > this->_M_out_beg)
 	      __len = std::max(__size_type(this->_M_out_end 
 					   - this->_M_out_beg), __len);
 	    return __string_type(this->_M_out_beg, this->_M_out_beg + __len);
@@ -174,13 +174,6 @@
       void
       _M_stringbuf_init(ios_base::openmode __mode)
       {
-	// _M_buf_size is a convenient alias for "what the streambuf
-	// thinks the allocated size of the string really is." This is
-	// necessary as ostringstreams are implemented with the
-	// streambufs having control of the allocation and
-	// re-allocation of the internal string object, _M_string.
-	this->_M_buf_size = _M_string.size();
-
 	// NB: Start ostringstream buffers at 512 bytes. This is an
 	// experimental value (pronounced "arbitrary" in some of the
 	// hipper english-speaking countries), and can be changed to
@@ -188,7 +181,7 @@
 	this->_M_buf_size_opt = 512;
 	this->_M_mode = __mode;
 	if (this->_M_mode & (ios_base::ate | ios_base::app))
-	  _M_really_sync(0, this->_M_buf_size);
+	  _M_really_sync(0, _M_string.size());
 	else
 	  _M_really_sync(0, 0);
       }
@@ -261,6 +254,14 @@
 	char_type* __base = const_cast<char_type*>(_M_string.data());
 	bool __testin = this->_M_mode & ios_base::in;
 	bool __testout = this->_M_mode & ios_base::out;
+
+	// _M_buf_size is a convenient alias for "what the streambuf
+	// thinks the allocated size of the string really is." This is
+	// necessary as ostringstreams are implemented with the
+	// streambufs having control of the allocation and
+	// re-allocation of the internal string object, _M_string.
+	this->_M_buf_size = _M_string.capacity();
+	
 	__size_type __len = _M_string.size();
 
 	this->_M_buf = __base;
diff -urN libstdc++-v3-orig/include/std/std_streambuf.h libstdc++-v3/include/std/std_streambuf.h
--- libstdc++-v3-orig/include/std/std_streambuf.h	2003-01-23 23:53:35.000000000 +0100
+++ libstdc++-v3/include/std/std_streambuf.h	2003-02-15 15:41:45.000000000 +0100
@@ -643,7 +643,15 @@
       pptr() const { return _M_out_cur; }
 
       char_type* 
-      epptr() const { return _M_out_end; }
+      epptr() const
+      { 
+	// Using allocated buffer.
+	if (_M_out_beg == _M_buf)
+	  return _M_out_beg + _M_buf_size;
+	// Using non-allocated buffer.
+	else
+	  return _M_out_end;
+      }
       //@}
 
       /**
diff -urN libstdc++-v3-orig/testsuite/27_io/stringbuf_virtuals.cc libstdc++-v3/testsuite/27_io/stringbuf_virtuals.cc
--- libstdc++-v3-orig/testsuite/27_io/stringbuf_virtuals.cc	2003-01-23 23:53:35.000000000 +0100
+++ libstdc++-v3/testsuite/27_io/stringbuf_virtuals.cc	2003-02-15 10:06:37.000000000 +0100
@@ -92,6 +92,45 @@
   VERIFY( ob.getloc() == loc_de );
 }
 
+bool called = false;
+
+class Derived_stringbuf : public std::stringbuf
+{
+public:
+  int_type overflow(int_type c)
+  {
+    called = true;
+    return std::stringbuf::overflow(c);
+  }
+  
+  const char_type* pub_epptr() const
+  {
+    return epptr();
+  }
+  
+  const char_type* pub_pptr() const
+  {
+    return pptr();
+  }
+};
+
+// libstdc++/9404
+void test09()
+{
+  bool test = true;
+
+  Derived_stringbuf dsbuf;
+  dsbuf.sputc('S');
+  VERIFY( called );
+  
+  called = false;
+  dsbuf.sputc('i');
+  VERIFY( !called );
+
+  dsbuf.sputc('l');
+  VERIFY( dsbuf.str() == "Sil" );
+}
+
 int main() 
 {
   using namespace std;
@@ -106,5 +145,6 @@
   test02(in3, false);
 
   test08();
+  test09();
   return 0;
 }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]