stdcxx-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From se...@apache.org
Subject svn commit: r379032 - in /incubator/stdcxx/trunk/include: sstream sstream.cc
Date Mon, 20 Feb 2006 06:17:47 GMT
Author: sebor
Date: Sun Feb 19 22:17:45 2006
New Revision: 379032

URL: http://svn.apache.org/viewcvs?rev=379032&view=rev
Log:
2006-02-19  Martin Sebor  <sebor@roguewave.com>

	STDCXX-149
	* sstream (str): Simplified.
	(showmanyc): Outlined a virtual function.
	(_C_strlen): Returned (pptr - pbase) in out mode instead of
	(epptr - pbase) as per DR 432.
	(_C_catchup): New inline function called to let egptr catch up
	with pptr.
	* sstream.cc (str): Set egptr (et al) to point to the end of the
	controlling sequence even when not in "in" mode as an efficient
	way of implementing the "high mark" referred to in DR 432.
	(showmanyc): Outlined and called _C_catchup.
	(overflow): Called _C_catchup to allow the function to succeed
	even when (gptr < egptr) initially. Handled epptr pointing prior
	to the very end of the buffer. After reallocation set epptr to
	oint to the very end of the buffer and not just one past pptr
	(as per DR 169 and DR 432). Called _C_Catchip to let egptr get
	caught up with pptr.
	(underflow): Returned successfully if argument is eof regardless
	of openmode to strictly conform to the requirements.
	(seekoff): Simplified, called _C_catchup, and handled offsets
	pointing to uninitialized storage as required in DR 432.
	(seekpos): Implemented completely in terms of seekoff.

Modified:
    incubator/stdcxx/trunk/include/sstream
    incubator/stdcxx/trunk/include/sstream.cc

Modified: incubator/stdcxx/trunk/include/sstream
URL: http://svn.apache.org/viewcvs/incubator/stdcxx/trunk/include/sstream?rev=379032&r1=379031&r2=379032&view=diff
==============================================================================
--- incubator/stdcxx/trunk/include/sstream (original)
+++ incubator/stdcxx/trunk/include/sstream Sun Feb 19 22:17:45 2006
@@ -115,9 +115,9 @@
     }
 
     _EXPLICIT
-    basic_stringbuf (const _C_string_type&, 
+    basic_stringbuf (const _C_string_type&,
                      ios_base::openmode = _RW::__rw_in_out);
-    
+
     // extension
     _EXPLICIT
     basic_stringbuf (const char_type*,
@@ -126,8 +126,7 @@
     virtual ~basic_stringbuf ();
     
     _C_string_type str () const {
-        return _C_strlen () == 0 ? _C_string_type ()
-            : _C_string_type (this->_C_buffer, _C_strlen ());
+        return _C_string_type (this->_C_buffer, _C_strlen ());
     }
 
 #ifdef _RWSTD_NO_EXT_STRINGBUF_STR
@@ -144,20 +143,17 @@
     void str (const _C_string_type &__str) {
         str (__str.data (), __str.size ());
     }
-    
+
 protected:
     
-    virtual streamsize showmanyc () {
-        return this->gptr () < this->egptr () ?
-            streamsize (this->egptr () - this->gptr ()) : 0;
-    }
+    virtual streamsize showmanyc ();
     
     virtual int_type overflow (int_type = traits_type::eof ());
 
     virtual int_type pbackfail (int_type = traits_type::eof ());
 
     virtual int_type underflow ();
-    
+
     virtual pos_type
     seekoff (off_type, ios_base::seekdir, ios_base::openmode =
              _RW::__rw_in_out);
@@ -168,15 +164,20 @@
     virtual basic_streambuf<char_type, traits_type>*
     setbuf (char_type*, streamsize);
 
-    // non-standard convenience functions
+private:
+
+    // returns the length of the underlying sequence as specified
+    // by 27.7.1.2, p1
     streamsize _C_strlen () const {
-        return streamsize (this->_C_is_in () ? this->egptr () - this->eback ()
-                                             : this->epptr () - this->pbase ());
+        return ios_base::in == (this->_C_state & (ios_base::in | ios_base::out))
+            ? this->egptr () - this->eback () : this->pptr () - this->pbase ();
     }
 
-private:
-
     _RWSTD_STREAMSIZE _C_grow (_RWSTD_STREAMSIZE, _RWSTD_STREAMSIZE) const;
+
+    // called from overflow, underflow, et al to get egptr()
+    // caught up with pptr()
+    void _C_catchup (char_type*);
 };
 
 
@@ -189,6 +190,34 @@
         _RWSTD_NEW_CAPACITY (_C_string_type, (_C_string_type*)0, __from);
 
     return __new_cap < __to ? __to : __new_cap;
+}
+
+
+template <class _CharT, class _Traits, class _Allocator>
+inline void
+basic_stringbuf<_CharT, _Traits, _Allocator>::
+_C_catchup (char_type *__gbeg)
+{
+    if (this->egptr () < this->pptr ()) {
+
+        if (this->_C_is_in ()) {
+        
+            // in in|out mode use the relative offset of gptr ()
+            // from eback() to set the new gptr() and use egptr()
+            // as the "high mark" (see LWG issue 432)
+            char_type* const __gptr = __gbeg + (this->gptr () - this->eback ());
+
+            this->setg (__gbeg, __gptr, this->pptr ());
+        }
+        else {
+
+            // in out only mode use egptr() as the "high mark"
+            // (see LWG issue 432)
+            this->setg (this->pptr (), this->pptr (), this->pptr ());
+        }
+
+        _RWSTD_ASSERT (this->_C_is_valid ());
+    }
 }
 
 

Modified: incubator/stdcxx/trunk/include/sstream.cc
URL: http://svn.apache.org/viewcvs/incubator/stdcxx/trunk/include/sstream.cc?rev=379032&r1=379031&r2=379032&view=diff
==============================================================================
--- incubator/stdcxx/trunk/include/sstream.cc (original)
+++ incubator/stdcxx/trunk/include/sstream.cc Sun Feb 19 22:17:45 2006
@@ -83,7 +83,7 @@
         this->_C_bufsize = 0;
     }
     else {
-        if (this->_C_bufsize < __slen)  {
+        if (this->_C_bufsize < _Streamsize (__slen))  {
 
             // buffer too small - need to reallocate
             if (this->_C_own_buf ())
@@ -101,9 +101,15 @@
         
         if (this->_C_is_in ())
             this->setg (this->_C_buffer, this->_C_buffer, __bufend);
+        else {
+            // when not in in mode set all get pointers to the same
+            // value and use egptr() as the "high mark" (see LWG
+            // issue 432)
+            this->setg (__bufend, __bufend, __bufend);
+        }
         
         if (this->_C_is_out ()) {
-            this->setp (this->_C_buffer, __bufend);
+            this->setp (this->_C_buffer, this->_C_buffer + this->_C_bufsize);
             
             if (this->_C_state & (ios_base::app | ios_base::ate))
                 this->pbump (__slen);   // seek to end 
@@ -113,7 +119,21 @@
 
 
 template <class _CharT, class _Traits, class _Allocator>
-_TYPENAME basic_stringbuf<_CharT, _Traits, _Allocator>::int_type
+/* virtual */ streamsize
+basic_stringbuf<_CharT, _Traits, _Allocator>::
+showmanyc ()
+{
+    _RWSTD_ASSERT (this->_C_is_valid ());
+
+    // get egptr() caught up with pptr()
+    _C_catchup (this->eback ());
+
+    return streamsize (this->egptr () - this->gptr ());
+}
+
+
+template <class _CharT, class _Traits, class _Allocator>
+/* virtual */ _TYPENAME basic_stringbuf<_CharT, _Traits, _Allocator>::int_type
 basic_stringbuf<_CharT, _Traits, _Allocator>::
 underflow ()
 {
@@ -125,6 +145,14 @@
 
         return traits_type::to_int_type (*this->gptr ());
     }
+    else if (this->gptr () < this->pptr ()) {
+
+        // get egptr() caught up with pptr()
+        _C_catchup (this->eback ());
+
+        if (this->gptr () < this->egptr ())
+            return traits_type::to_int_type (*this->gptr ());
+    }
 
     return traits_type::eof ();
 }
@@ -137,58 +165,66 @@
 {
     _RWSTD_ASSERT (this->_C_is_valid ());
 
+    // 27.7.1.3, p5, bullet 2 of C++ '03: when (c == eof)
+    // indicate success even when not in out mode
+    if (this->_C_is_eof (__c))
+        return traits_type::not_eof (__c);
+    
     if (!this->_C_is_out ()) 
         return traits_type::eof ();
     
-    if (this->_C_is_eof (__c))
-        return  traits_type::not_eof (__c);
-    
-    typedef _RWSTD_STREAMSIZE _Streamsize;
-
-    const _Streamsize __slen = _C_strlen ();
+    char_type* const __bufend = this->_C_buffer + this->_C_bufsize;
     
-    // reallocate space if necessary
+    if (this->epptr () < __bufend) {
+        // bump up epptr() keeping pbase() and pptr() unchanged
 
-    if (!(this->epptr () < this->_C_buf_end ())) {
+        const _RWSTD_STREAMSIZE __off = this->pptr () - this->pbase ();
+        this->setp (this->pbase (), __bufend);
+        this->pbump (__off);
+    }
+    else if (this->pptr () == this->epptr ()) {
+        // allocate new or reallocate existing buffer
 
         typedef _RWSTD_ALLOC_TYPE (allocator_type, char_type) _ValueAlloc;
 
-        // calculate size of buffer to allocate
-        const _Streamsize __new_size =
+        // calculate size of the new buffer to allocate
+        const _RWSTD_STREAMSIZE __new_size =
             _C_grow (this->_C_bufsize + 1, this->_C_bufsize);
         
-        char_type* __new_buf = _ValueAlloc ().allocate (__new_size);
+        char_type* const __new_buf = _ValueAlloc ().allocate (__new_size);
            
-        if (this->_C_buffer) {  // need to copy the old buffer to new buffer
-            traits_type::copy (__new_buf, this->_C_buffer, __slen);   
+        // compute the length of the output sequence
+        const _RWSTD_STREAMSIZE __slen = this->pptr () - this->pbase ();
+
+        if (this->_C_buffer) {
+            // copy the contents of the old buffer to the new one
+            traits_type::copy (__new_buf, this->_C_buffer, __slen);
+
+            // deallocate the old buffer if owned
             if (this->_C_own_buf ()) 
                 _ValueAlloc ().deallocate (this->_C_buffer, this->_C_bufsize);
         }
+
         this->_C_own_buf (true);
         this->_C_bufsize = __new_size;
         this->_C_buffer  = __new_buf;
-    }
 
-    // increment the end put pointer by one position
-    this->setp (this->_C_buffer, this->_C_buffer + __slen + 1);
-    this->pbump (__slen);
-
-    // set get area if in in|out mode 
-    if (this->_C_is_inout ()) {
-        // use the relative offset of gptr () from eback() to set the new gptr
-        // although they are invalid, the offset is still valid
-        char_type* __gptr_new =   this->_C_buffer
-                                + (this->gptr () - this->eback ());  
-        // N.B. pptr() has already been incremented  
-        this->setg (this->_C_buffer, __gptr_new, this->epptr());
+        // set the put area
+        this->setp (this->_C_buffer, this->_C_buffer + this->_C_bufsize);
+        this->pbump (__slen);
     }
 
-    return this->sputc (traits_type::to_char_type (__c));
+    const int_type __retval = this->sputc (traits_type::to_char_type (__c));
+
+    // get egptr() caught up with the value of pptr() after the call
+    _C_catchup (this->_C_buffer);
+
+    return __retval;
 }
 
 
 template<class _CharT, class _Traits, class _Allocator>
-_TYPENAME basic_stringbuf<_CharT, _Traits, _Allocator>::int_type
+/* virtual */ _TYPENAME basic_stringbuf<_CharT, _Traits, _Allocator>::int_type
 basic_stringbuf<_CharT, _Traits, _Allocator>::
 pbackfail (int_type __c)
 {
@@ -220,7 +256,7 @@
 
 
 template<class _CharT, class _Traits, class _Allocator>
-basic_streambuf<_CharT, _Traits>*
+/* virtual */ basic_streambuf<_CharT, _Traits>*
 basic_stringbuf<_CharT, _Traits, _Allocator>::
 setbuf (char_type* __buf, _RWSTD_STREAMSIZE __n)
 {
@@ -259,22 +295,15 @@
     this->setp (this->_C_buffer, this->_C_buffer + __slen);
     this->pbump (__pptr_off);   // ... and restore it
  
-    // set get area if in in|out mode
-    if (this->_C_is_inout()) {
-        // use the relative offset of gptr () from eback() to set the new gptr
-        // (although the pointers are invalid, the offset is still valid)
-        char_type* const __gptr_new =
-            this->_C_buffer + (this->gptr () - this->eback ());
-
-        this->setg (this->_C_buffer, __gptr_new, this->epptr());
-    }
+    // get egptr() caught up with pptr()
+    _C_catchup (this->_C_buffer);
     
     return this;
 }
 
 
 template<class _CharT, class _Traits, class _Allocator>
-_TYPENAME basic_stringbuf<_CharT, _Traits, _Allocator>::pos_type
+/* virtual */ _TYPENAME basic_stringbuf<_CharT, _Traits, _Allocator>::pos_type
 basic_stringbuf<_CharT, _Traits, _Allocator>::
 seekoff (off_type __off, ios_base::seekdir __way, ios_base::openmode __which)
 {
@@ -285,122 +314,77 @@
                    || ios_base::cur == __way
                    || ios_base::end == __way);
         
-    typedef _RWSTD_STREAMSIZE _Streamsize;
+    _RWSTD_STREAMSIZE __newoff = -1;
 
-    _Streamsize __newoff = 0;
+    // get egptr() caught up with pptr()
+    _C_catchup (this->eback ());
 
     if (__which & ios_base::in) {
+
         if (!this->_C_is_in () || !this->gptr ())
             return pos_type (off_type (-1));
+
         // do the checks for in|out mode here
-        if (__which & ios_base::out) {
-            if ((__way & ios_base::cur) || !this->_C_is_out ())
-                return pos_type (off_type (-1));
-        }     
-        switch (__way) {
+        if (   __which & ios_base::out
+            && (ios_base::cur == __way || !this->_C_is_out ()))
+            return pos_type (off_type (-1));
 
-        case ios_base::beg:
-            __newoff = 0;
-            break;
-            
-        case ios_base::cur:
-            __newoff = _Streamsize (this->gptr () - this->eback ());
-            break;
-        
-        case ios_base::end:
-            __newoff = _Streamsize (this->egptr () - this->eback ());
+        switch (__way) {
+        case ios_base::beg: __newoff = 0; break;
+        case ios_base::cur: __newoff = this->gptr () - this->eback (); break;
+        case ios_base::end: __newoff = this->egptr () - this->eback (); break;
         }
 
-        if (   (__newoff + __off) < 0
-            || (this->egptr () - this->eback ()) < (__newoff + __off))
-            return pos_type (off_type (-1));
+        __newoff += __off;
 
-        this->setg (this->eback (),
-                    this->eback () + __newoff + __off,
-                    this->egptr ());
+        if ( __newoff < 0 || (this->egptr () - this->eback ()) < __newoff)
+            return pos_type (off_type (-1));
 
+        this->setg (this->eback (), this->eback () + __newoff, this->egptr ());
     }
     
     if (__which & ios_base::out) {
+
         if (!this->_C_is_out () || !this->pptr ())
             return pos_type (off_type (-1));
 
-        switch (__way) {
+        // egptr() is used as the "high mark" even when not in "in" mode
+        _RWSTD_ASSERT (0 != this->egptr ());
 
-        case ios_base::beg:
-            __newoff = 0;
-            break;
-            
-        case ios_base::cur:
-            __newoff = _Streamsize (this->pptr () - this->pbase ());
-            break;
-            
-        case ios_base::end:
-            __newoff = _Streamsize (this->epptr () - this->pbase ());
-            break;
+        // compute the number of initialized characters in the buffer
+        // (see LWG issue 432)
+        const _RWSTD_STREAMSIZE __high = this->egptr () - this->pbase ();
+        const _RWSTD_STREAMSIZE __cur  = this->pptr () - this->pbase ();
+
+        switch (__way) {
+        case ios_base::beg: __newoff = 0; break;
+        case ios_base::cur: __newoff = __cur; break;
+        case ios_base::end: __newoff = __high; break;
         }
-        
-        if (   (__newoff + __off) < 0
-            || (this->epptr () - this->pbase ()) < (__newoff + __off))
+
+        __newoff += __off;
+
+        if (__newoff < 0 || __high < __newoff)
             return pos_type (off_type (-1));
 
-        this->setp (this->pbase (), this->epptr ());
-        this->pbump (__newoff + __off);
+        // bump pptr up (or down) to the new position
+        this->pbump (__newoff - __cur);
     }
 
-    return pos_type (__newoff + __off);
+    _RWSTD_ASSERT (this->_C_is_valid ());
+
+    return __newoff < 0 ? pos_type (off_type (-1)) : pos_type (__newoff);
 }
 
 
 template<class _CharT, class _Traits, class _Allocator>
-_TYPENAME basic_stringbuf<_CharT, _Traits, _Allocator>::pos_type
+/* virtual */ _TYPENAME basic_stringbuf<_CharT, _Traits, _Allocator>::pos_type
 basic_stringbuf<_CharT, _Traits, _Allocator>::
-seekpos (pos_type __sp, ios_base::openmode __which)
+seekpos (pos_type __pos, ios_base::openmode __which)
 {
     _RWSTD_ASSERT (this->_C_is_valid ());
 
-#if !defined (__GNUG__) || __GNUG__ != 4 || __GNUC_MINOR__ != 0
-
-    const _RWSTD_STREAMSIZE __newoff = off_type (__sp);
-
-#else   // !gcc 4.0
-
-    // work around gcc 4.0.0 bug #454
-    _RWSTD_STREAMSIZE __newoff = off_type (__sp);
-
-#endif   // gcc 4.0
-    
-    // return invalid pos if no positioning operation succeeds
-    pos_type __retval = pos_type (off_type (-1));
-     
-    if (__newoff < 0)
-        return __retval;
-
-    // see 27.7.1.3 p.11 for required conditions 
-    if ((__which & ios_base::in) && this->_C_is_in () && this->gptr())
{
-        
-        if ((this->eback () + __newoff) > this->egptr ())
-            return pos_type (off_type (-1));
-        
-        this->setg (this->eback (),
-                    this->eback () + __newoff,
-                    this->egptr ());
-
-        __retval = __sp;
-    }
-        
-    if ((__which & ios_base::out) && this->_C_is_out () && this->pptr())
{
-
-        if ((this->pbase () + __newoff) > this->epptr ()) 
-            return pos_type (off_type (-1));
-        
-        this->setp (this->pbase (), this->epptr ());
-        this->pbump (__newoff);
-
-        __retval = __sp;
-    }
-    
-    return __retval;
+    return pos_type (basic_stringbuf::seekoff (__pos, ios_base::beg, __which));
 }
 
 



Mime
View raw message