Return-Path: Delivered-To: apmail-stdcxx-commits-archive@www.apache.org Received: (qmail 97689 invoked from network); 7 Feb 2008 19:30:45 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 7 Feb 2008 19:30:45 -0000 Received: (qmail 3006 invoked by uid 500); 7 Feb 2008 19:30:38 -0000 Delivered-To: apmail-stdcxx-commits-archive@stdcxx.apache.org Received: (qmail 2989 invoked by uid 500); 7 Feb 2008 19:30:38 -0000 Mailing-List: contact commits-help@stdcxx.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@stdcxx.apache.org Delivered-To: mailing list commits@stdcxx.apache.org Received: (qmail 2980 invoked by uid 99); 7 Feb 2008 19:30:37 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 07 Feb 2008 11:30:37 -0800 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 07 Feb 2008 19:30:08 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 234FC1A983A; Thu, 7 Feb 2008 11:30:16 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r619587 - in /stdcxx/trunk/include: istream.cc streambuf Date: Thu, 07 Feb 2008 19:30:15 -0000 To: commits@stdcxx.apache.org From: vitek@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20080207193016.234FC1A983A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: vitek Date: Thu Feb 7 11:30:14 2008 New Revision: 619587 URL: http://svn.apache.org/viewvc?rev=619587&view=rev Log: 2008-02-07 Travis Vitek STDCXX-249 * include/istream.cc (operator>>): Read stream data in blocks where possible for efficiency. * include/streambuf: Add operator>> as friend for access to protected member functions. Modified: stdcxx/trunk/include/istream.cc stdcxx/trunk/include/streambuf Modified: stdcxx/trunk/include/istream.cc URL: http://svn.apache.org/viewvc/stdcxx/trunk/include/istream.cc?rev=619587&r1=619586&r2=619587&view=diff ============================================================================== --- stdcxx/trunk/include/istream.cc (original) +++ stdcxx/trunk/include/istream.cc Thu Feb 7 11:30:14 2008 @@ -788,40 +788,136 @@ { _RWSTD_ASSERT (0 != __is.rdbuf ()); + const _TYPENAME basic_istream<_CharT, _Traits>::sentry + __ipfx (__is /* , noskipws = false */); + ios_base::iostate __err = ios_base::goodbit; - _RWSTD_SIZE_T __gcount = 0; + typedef _RWSTD_SIZE_T _SizeT; - _TRY { + // count of characters read from stream + _SizeT __gcount = 0; - const _TYPENAME basic_istream<_CharT, _Traits>::sentry - __ipfx (__is /* , noskipws = false */); + _TRY { if (__ipfx) { - basic_streambuf<_CharT, _Traits>* const __rdbuf = __is.rdbuf (); - - // FIXME: code commented out to work around an HP aCC 3.14.10 - // bug #JAGac86264 - - // typedef _TYPENAME - // basic_string<_CharT, _Traits, _Allocator>::size_type + __str.clear (); - const _RWSTD_SIZE_T __maxlen = + // maximum number of characters we can read + _RWSTD_SIZE_T __n = __is.width () ? __is.width () : __str.max_size (); - __str.clear (); + basic_streambuf<_CharT, _Traits>* const __rdbuf = __is.rdbuf (); const ctype<_CharT> &__ctp = _USE_FACET (ctype<_CharT>, __is.getloc ()); - // increment gcount only _after_ sbumpc() but _before_ - // the subsequent call to sgetc() to correctly reflect - // the number of extracted characters in the presence - // of exceptions thrown from streambuf virtuals - for ( ; __maxlen != __gcount; __rdbuf->sbumpc (), ++__gcount) { +#ifndef _RWSTD_NO_FRIEND_TEMPLATE - const _TYPENAME _Traits::int_type __c (__rdbuf->sgetc ()); + while (__n != 0) { + + const _CharT* const __gptr = __rdbuf->gptr (); + const _CharT* const __egptr = __rdbuf->egptr (); + + // maximum number of characters would want to extract + _SizeT __navail = __egptr - __gptr; + if (__n < __navail) + __navail = __n; + + if (__navail) { + + // find the delimeter in the squence if it exists, or + // get pointer to end of sequence + const _CharT* __pdel = __gptr; + for (/**/; __pdel != __egptr; ++__pdel) { + + const _TYPENAME _Traits::int_type + __c = _Traits::to_int_type(*__pdel); + + if (_Traits::eq_int_type (__c, _Traits::eof ())) { + __err = ios_base::eofbit; + break; + } + + if (__ctp.is (__ctp.space, *__pdel)) + break; + } + + // __pdel is either pointing to a delimiter or one past + // the end of the input stream get area. if it is past + // the end, then set it to null. + if (__pdel == __egptr) { + __pdel = 0; + } + + if (__pdel) { + __navail = __pdel - __gptr + 1; + __n -= __navail - 1; + } + else if (__n == __navail) + __n -= --__navail; + else + __n -= __navail; + + // store characters excluding the delimiter + __str.append (__gptr, __navail - !!__pdel); + + __gcount += __navail; + + // advance gptr() by the number of extracted + // characters, including the delimiter + __rdbuf->gbump (__navail); + + // we found a delimiter before the end of the get area, + // break out of outer loop + if (__pdel) { + break; + } + + if (2 > __n && _SizeT (__egptr - __gptr) != __navail) { + __err = ios_base::failbit; + break; + } + } + else { + + // n data in buffer, trigger underflow() + // note that streambuf may be unbuffered + const _TYPENAME _Traits::int_type + __c = __rdbuf->sgetc (); + + if (_Traits::eq_int_type (__c, _Traits::eof ())) { + __err = ios_base::eofbit; + break; + } + + // convert to char_type so that isspace works correctly + const _TYPENAME _Traits::char_type + __ch = _Traits::to_char_type (__c); + + if (__ctp.is (__ctp.space, __ch)) + break; + + __str.push_back (__ch); + --__n; + + __rdbuf->sbumpc (); + + // increment gcount only _after_ sbumpc() but _before_ + // the subsequent call to sgetc() to correctly reflect + // the number of extracted characters in the presence + // of exceptions thrown from streambuf virtuals + ++__gcount; + } + } + +#else // if defined (_RWSTD_NO_FRIEND_TEMPLATE) + + for ( ; __n != 0; ) { + + const _TYPENAME _Traits::int_type + __c (__rdbuf->sgetc ()); if (_Traits::eq_int_type (__c, _Traits::eof ())) { __err = ios_base::eofbit; @@ -836,13 +932,24 @@ break; __str.push_back (__ch); + --__n; + + __rdbuf->sbumpc (); + + // increment gcount only _after_ sbumpc() but _before_ + // the subsequent call to sgetc() to correctly reflect + // the number of extracted characters in the presence + // of exceptions thrown from streambuf virtuals + ++__gcount; } +#endif // if defined (_RWSTD_NO_FRIEND_TEMPLATE) + __is.width (0); } } _CATCH (...) { - __is.setstate (__is.badbit | _RW::__rw_rethrow); + __is.setstate (ios_base::badbit | _RW::__rw_rethrow); } if (!__gcount) @@ -852,7 +959,7 @@ __is.setstate (__err); return __is; -} +} _EXPORT Modified: stdcxx/trunk/include/streambuf URL: http://svn.apache.org/viewvc/stdcxx/trunk/include/streambuf?rev=619587&r1=619586&r2=619587&view=diff ============================================================================== --- stdcxx/trunk/include/streambuf (original) +++ stdcxx/trunk/include/streambuf Thu Feb 7 11:30:14 2008 @@ -415,6 +415,12 @@ getline (basic_istream<_Char2, _Traits2>&, basic_string<_Char2, _Traits2, _Allocator>&, _Char2); + _EXPORT + template + friend basic_istream<_Char2, _Traits2>& + operator>> (basic_istream<_Char2, _Traits2>&, + basic_string<_Char2, _Traits2, _Allocator>&); + #endif // _RWSTD_NO_FRIEND_TEMPLATE };