re PR libstdc++/38678 ([DR XXX] istream::read() calls streambuf::sgetn())

2009-01-01  Paolo Carlini  <paolo.carlini@oracle.com>

	PR libstdc++/38678
	* include/std/istream (basic_istream<>::_M_read): New.
	* include/bits/istream.tcc (basic_istream<>::_M_read): Define.
	(basic_istream<>::read, basic_istream<>::readsome): Use it.
	* include/std/ostream (basic_ostream<>::_M_write_): New.
	(basic_ostream<>::_M_write): Adjust.
	* include/bits/ostream.tcc (basic_ostream<>::_M_write_): Define.
	* testsuite/27_io/basic_istream/read/char/38678.cc: New.
	* testsuite/27_io/basic_istream/read/wchar_t/38678.cc: Likewise.
	* testsuite/27_io/basic_ostream/write/char/38678.cc: Likewise.
	* testsuite/27_io/basic_ostream/write/wchar_t/38678.cc: Likewise.

From-SVN: r142994
This commit is contained in:
Paolo Carlini 2009-01-01 10:08:31 +00:00 committed by Paolo Carlini
parent edc31cc129
commit 91a96b33a9
9 changed files with 353 additions and 15 deletions

View file

@ -1,3 +1,17 @@
2009-01-01 Paolo Carlini <paolo.carlini@oracle.com>
PR libstdc++/38678
* include/std/istream (basic_istream<>::_M_read): New.
* include/bits/istream.tcc (basic_istream<>::_M_read): Define.
(basic_istream<>::read, basic_istream<>::readsome): Use it.
* include/std/ostream (basic_ostream<>::_M_write_): New.
(basic_ostream<>::_M_write): Adjust.
* include/bits/ostream.tcc (basic_ostream<>::_M_write_): Define.
* testsuite/27_io/basic_istream/read/char/38678.cc: New.
* testsuite/27_io/basic_istream/read/wchar_t/38678.cc: Likewise.
* testsuite/27_io/basic_ostream/write/char/38678.cc: Likewise.
* testsuite/27_io/basic_ostream/write/wchar_t/38678.cc: Likewise.
2008-12-22 Jonathan Larmour <jifl@eCosCentric.com>
* include/ext/concurrence.h: Fix __gthread_cond_t initialisation

View file

@ -1,7 +1,7 @@
// istream classes -*- C++ -*-
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
// 2006, 2007
// 2006, 2007, 2008, 2009
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@ -599,6 +599,22 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
return __c;
}
template<typename _CharT, typename _Traits>
streamsize
basic_istream<_CharT, _Traits>::
_M_read(char_type* __s, streamsize __n)
{
streamsize __ret = 0;
for (; __ret < __n; ++__ret, ++__s)
{
const int_type __c = this->rdbuf()->sbumpc();
if (traits_type::eq_int_type(__c, traits_type::eof()))
break;
traits_type::assign(*__s, traits_type::to_char_type(__c));
}
return __ret;
}
template<typename _CharT, typename _Traits>
basic_istream<_CharT, _Traits>&
basic_istream<_CharT, _Traits>::
@ -611,7 +627,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
try
{
_M_gcount = this->rdbuf()->sgetn(__s, __n);
_M_gcount = _M_read(__s, __n);
if (_M_gcount != __n)
__err |= (ios_base::eofbit | ios_base::failbit);
}
@ -643,7 +659,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
// Cannot compare int_type with streamsize generically.
const streamsize __num = this->rdbuf()->in_avail();
if (__num > 0)
_M_gcount = this->rdbuf()->sgetn(__s, std::min(__num, __n));
_M_gcount = _M_read(__s, std::min(__num, __n));
else if (__num == -1)
__err |= ios_base::eofbit;
}

View file

@ -1,7 +1,7 @@
// ostream classes -*- C++ -*-
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
// 2006, 2007
// 2006, 2007, 2008, 2009
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@ -182,6 +182,21 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
return *this;
}
template<typename _CharT, typename _Traits>
streamsize
basic_ostream<_CharT, _Traits>::
_M_write_(const char_type* __s, streamsize __n)
{
streamsize __ret = 0;
for (; __ret < __n; ++__ret, ++__s)
{
const int_type __c = this->rdbuf()->sputc(*__s);
if (traits_type::eq_int_type(__c, traits_type::eof()))
break;
}
return __ret;
}
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
basic_ostream<_CharT, _Traits>::

View file

@ -1,7 +1,7 @@
// Input streams -*- C++ -*-
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
// 2006, 2007, 2008
// 2006, 2007, 2008, 2009
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@ -586,11 +586,28 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
: _M_gcount(streamsize(0))
{ this->init(0); }
streamsize
_M_read(char_type* __s, streamsize __n);
template<typename _ValueT>
__istream_type&
_M_extract(_ValueT& __v);
};
template<>
inline streamsize
basic_istream<char>::
_M_read(char_type* __s, streamsize __n)
{ return this->rdbuf()->__streambuf_type::xsgetn(__s, __n); }
#ifdef _GLIBCXX_USE_WCHAR_T
template<>
inline streamsize
basic_istream<wchar_t>::
_M_read(char_type* __s, streamsize __n)
{ return this->rdbuf()->__streambuf_type::xsgetn(__s, __n); }
#endif
// Explicit specialization declarations, defined in src/istream.cc.
template<>
basic_istream<char>&

View file

@ -1,7 +1,7 @@
// Output streams -*- C++ -*-
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
// 2006, 2007, 2008
// 2006, 2007, 2008, 2009
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@ -286,15 +286,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
__ostream_type&
put(char_type __c);
// Core write functionality, without sentry.
void
_M_write(const char_type* __s, streamsize __n)
{
const streamsize __put = this->rdbuf()->sputn(__s, __n);
if (__put != __n)
this->setstate(ios_base::badbit);
}
/**
* @brief Character string insertion.
* @param s The array to insert.
@ -365,11 +356,36 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
basic_ostream()
{ this->init(0); }
void
_M_write(const char_type* __s, streamsize __n)
{
const streamsize __put = _M_write_(__s, __n);
if (__put != __n)
this->setstate(ios_base::badbit);
}
streamsize
_M_write_(const char_type* __s, streamsize __n);
template<typename _ValueT>
__ostream_type&
_M_insert(_ValueT __v);
};
template<>
inline streamsize
basic_ostream<char>::
_M_write_(const char_type* __s, streamsize __n)
{ return this->rdbuf()->__streambuf_type::xsputn(__s, __n); }
#ifdef _GLIBCXX_USE_WCHAR_T
template<>
inline streamsize
basic_ostream<wchar_t>::
_M_write_(const char_type* __s, streamsize __n)
{ return this->rdbuf()->__streambuf_type::xsputn(__s, __n); }
#endif
/**
* @brief Performs setup work for output streams.
*

View file

@ -0,0 +1,67 @@
// Copyright (C) 2009 Free Software Foundation
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 27.6.1.3 unformatted input functions
#include <istream>
#include <streambuf>
#include <testsuite_hooks.h>
// libstdc++/38678
void test01()
{
bool test __attribute__((unused)) = true;
static char x = '0';
struct : std::streambuf
{
char c;
int_type
underflow()
{
c = x++;
setg(&c, &c, &c + 1);
return traits_type::to_int_type(c);
}
std::streamsize
xsgetn(char*, std::streamsize)
{
VERIFY( !"xsgetn should not be called" );
return 0;
}
} sb;
std::istream in(&sb);
char s[4] = "";
in.read(s, 4);
VERIFY( in.good() );
VERIFY( 4 == in.gcount() );
VERIFY( '0' == s[0] && '1' == s[1] && '2' == s[2] && '3' == s[3] );
}
int main()
{
test01();
return 0;
}

View file

@ -0,0 +1,67 @@
// Copyright (C) 2009 Free Software Foundation
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 27.6.1.3 unformatted input functions
#include <istream>
#include <streambuf>
#include <testsuite_hooks.h>
// libstdc++/38678
void test01()
{
bool test __attribute__((unused)) = true;
static wchar_t x = L'0';
struct : std::wstreambuf
{
wchar_t c;
int_type
underflow()
{
c = x++;
setg(&c, &c, &c + 1);
return traits_type::to_int_type(c);
}
std::streamsize
xsgetn(wchar_t*, std::streamsize)
{
VERIFY( !"xsgetn should not be called" );
return 0;
}
} sb;
std::wistream in(&sb);
wchar_t s[4] = L"";
in.read(s, 4);
VERIFY( in.good() );
VERIFY( 4 == in.gcount() );
VERIFY( L'0' == s[0] && L'1' == s[1] && L'2' == s[2] && L'3' == s[3] );
}
int main()
{
test01();
return 0;
}

View file

@ -0,0 +1,63 @@
// Copyright (C) 2009 Free Software Foundation
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 27.6.2.6 unformatted output functions
#include <ostream>
#include <streambuf>
#include <testsuite_hooks.h>
// libstdc++/38678
void test01()
{
bool test __attribute__((unused)) = true;
static char s[4] = "";
static unsigned i = 0;
struct : std::streambuf
{
int_type
overflow(int_type c)
{
s[i++] = traits_type::to_char_type(c);
return traits_type::not_eof(c);
}
std::streamsize
xsputn(const char*, std::streamsize)
{
VERIFY( !"xsputn should not be called" );
return 0;
}
} sb;
std::ostream out(&sb);
out.write("0123", 4);
VERIFY( out.good() );
VERIFY( 4 == i );
VERIFY( '0' == s[0] && '1' == s[1] && '2' == s[2] && '3' == s[3] );
}
int main()
{
test01();
return 0;
}

View file

@ -0,0 +1,63 @@
// Copyright (C) 2009 Free Software Foundation
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 27.6.2.6 unformatted output functions
#include <ostream>
#include <streambuf>
#include <testsuite_hooks.h>
// libstdc++/38678
void test01()
{
bool test __attribute__((unused)) = true;
static wchar_t s[4] = L"";
static unsigned i = 0;
struct : std::wstreambuf
{
int_type
overflow(int_type c)
{
s[i++] = traits_type::to_char_type(c);
return traits_type::not_eof(c);
}
std::streamsize
xsputn(const wchar_t*, std::streamsize)
{
VERIFY( !"xsputn should not be called" );
return 0;
}
} sb;
std::wostream out(&sb);
out.write(L"0123", 4);
VERIFY( out.good() );
VERIFY( 4 == i );
VERIFY( L'0' == s[0] && L'1' == s[1] && L'2' == s[2] && L'3' == s[3] );
}
int main()
{
test01();
return 0;
}