This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

[v3] Fix stringbuf::setbuf vs string::assign


Hi,

that is, avoid a completely pointless and confusing string::assign
(which could also throw). After 4.1.0 is out, seems suited for the
branch too.

Tested x86-linux, in mainline.

Paolo.

////////////////
2006-02-19  Paolo Carlini  <pcarlini@suse.de>

	* include/std/std_sstream.h (basic_stringbuf<>::setbuf): Simply
	clear the internal _M_string, adjust _M_sync call.
	* include/bits/sstream.tcc (basic_stringbuf<>::_M_sync): Adjust
	consistently for calls from setbuf.
Index: include/bits/sstream.tcc
===================================================================
--- include/bits/sstream.tcc	(revision 111177)
+++ include/bits/sstream.tcc	(working copy)
@@ -225,9 +225,6 @@
       return __ret;
     }
 
-  // Assumes: contents of _M_string and internal buffer match exactly.
-  // __i == _M_in_cur - _M_in_beg
-  // __o == _M_out_cur - _M_out_beg
   template <class _CharT, class _Traits, class _Alloc>
     void
     basic_stringbuf<_CharT, _Traits, _Alloc>::
@@ -235,25 +232,28 @@
     {
       const bool __testin = _M_mode & ios_base::in;
       const bool __testout = _M_mode & ios_base::out;
-      char_type* __end = __base + _M_string.size();
-      
+      char_type* __endg = __base + _M_string.size();
+      char_type* __endp = __base + _M_string.capacity();
+
+      if (__base != _M_string.data())
+	{
+	  // setbuf: __i == size of buffer area (_M_string.size() == 0).
+	  __endg += __i;
+	  __i = 0;
+	  __endp = __endg;
+	}
+
       if (__testin)
-	this->setg(__base, __base + __i, __end);
+	this->setg(__base, __base + __i, __endg);
       if (__testout)
 	{
-	  // If __base comes from setbuf we cannot trust capacity()
-	  // to match the size of the buffer area:  in general, after
-	  // Step 1 in setbuf, _M_string.capacity() >= __n.
-	  if (__base == _M_string.data())
-	    this->setp(__base, __base + _M_string.capacity());
-	  else
-	    this->setp(__base, __end);
+	  this->setp(__base, __endp);
 	  this->pbump(__o);
 	  // egptr() always tracks the string end.  When !__testin,
 	  // for the correct functioning of the streambuf inlines
 	  // the other get area pointers are identical.
 	  if (!__testin)
-	    this->setg(__end, __end, __end);
+	    this->setg(__endg, __endg, __endg);
 	}
     }
 
Index: include/std/std_sstream.h
===================================================================
--- include/std/std_sstream.h	(revision 111177)
+++ include/std/std_sstream.h	(working copy)
@@ -211,10 +211,10 @@
 	    // things will quickly blow up.
 	    
 	    // Step 1: Destroy the current internal array.
-	    _M_string.assign(__s, __n);
+	    _M_string.clear();
 	    
 	    // Step 2: Use the external array.
-	    _M_sync(__s, 0, 0);
+	    _M_sync(__s, __n, 0);
 	  }
 	return this;
       }

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