This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: [Patch] Fix seek to beg after grow bug
- From: Paolo Carlini <pcarlini at unitus dot it>
- To: Benjamin Kosnik <bkoz at redhat dot com>
- Cc: "libstdc++ at gcc dot gnu dot org" <libstdc++ at gcc dot gnu dot org>
- Date: Tue, 18 Feb 2003 21:30:34 +0100
- Subject: Re: [Patch] Fix seek to beg after grow bug
- References: <3E529279.9070206@unitus.it> <20030218142354.5954ddd5.bkoz@redhat.com>
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;
}