fstream.tcc (_M_underflow): Do not special case the unbuffered case...

2003-06-09  Paolo Carlini  <pcarlini@unitus.it>

	* include/bits/fstream.tcc (_M_underflow): Do not special
	case the unbuffered case, which really means simply a one char
	get area.
	(basic_filebuf): Initialize _M_buf_size.
	(setbuf): Unbuffered means _M_buf_size == 1, since only
	_M_buf_size - 1 == 0 chars are going to be used for the
	put area and 1 for the get area.
	* include/std/std_streambuf.h (_M_buf_size): Move to basic_filebuf.
	(~basic_streambuf): Tweak.
	(basic_streambuf): Do not initialize _M_buf_size.
	* include/std/std_fstream.h (_M_buf_size): Add from basic_streambuf.
	(~basic_filebuf): Tweak.
	(_M_set_buffer): Tweak, considering that _M_buf_size == 1 is the
	unbuffered situation (i.e., put area pointers NULL).
	* include/bits/streambuf.tcc (sbumpc): Clean up.
	* testsuite/27_io/basic_filebuf/sputbackc/char/1.cc: Split into...
	* testsuite/27_io/basic_filebuf/sputbackc/char/1-in.cc: New.
	* testsuite/27_io/basic_filebuf/sputbackc/char/1-io.cc: New.
	* testsuite/27_io/basic_filebuf/sputbackc/char/1-out.cc: New.
	* testsuite/27_io/basic_filebuf/sputbackc/char/2-in.cc: New.
	* testsuite/27_io/basic_filebuf/sputbackc/char/2-io.cc: New.
	* testsuite/27_io/basic_filebuf/sputbackc/char/2-out.cc: New.

From-SVN: r67686
This commit is contained in:
Paolo Carlini 2003-06-10 02:05:49 +02:00 committed by Paolo Carlini
parent 22597a82ee
commit f10eea7bae
11 changed files with 621 additions and 118 deletions

View file

@ -1,3 +1,28 @@
2003-06-09 Paolo Carlini <pcarlini@unitus.it>
* include/bits/fstream.tcc (_M_underflow): Do not special
case the unbuffered case, which really means simply a one char
get area.
(basic_filebuf): Initialize _M_buf_size.
(setbuf): Unbuffered means _M_buf_size == 1, since only
_M_buf_size - 1 == 0 chars are going to be used for the
put area and 1 for the get area.
* include/std/std_streambuf.h (_M_buf_size): Move to basic_filebuf.
(~basic_streambuf): Tweak.
(basic_streambuf): Do not initialize _M_buf_size.
* include/std/std_fstream.h (_M_buf_size): Add from basic_streambuf.
(~basic_filebuf): Tweak.
(_M_set_buffer): Tweak, considering that _M_buf_size == 1 is the
unbuffered situation (i.e., put area pointers NULL).
* include/bits/streambuf.tcc (sbumpc): Clean up.
* testsuite/27_io/basic_filebuf/sputbackc/char/1.cc: Split into...
* testsuite/27_io/basic_filebuf/sputbackc/char/1-in.cc: New.
* testsuite/27_io/basic_filebuf/sputbackc/char/1-io.cc: New.
* testsuite/27_io/basic_filebuf/sputbackc/char/1-out.cc: New.
* testsuite/27_io/basic_filebuf/sputbackc/char/2-in.cc: New.
* testsuite/27_io/basic_filebuf/sputbackc/char/2-io.cc: New.
* testsuite/27_io/basic_filebuf/sputbackc/char/2-out.cc: New.
2003-06-09 Phil Edwards <pme@gcc.gnu.org>
* acinclude.m4: Move all AM_CONDITIONAL calls out.

View file

@ -71,9 +71,9 @@ namespace std
template<typename _CharT, typename _Traits>
basic_filebuf<_CharT, _Traits>::
basic_filebuf() : __streambuf_type(), _M_file(&_M_lock),
_M_state_cur(__state_type()), _M_state_beg(__state_type()), _M_buf(NULL),
_M_buf_allocated(false),_M_last_overflowed(false),
_M_filepos(0), _M_pback(char_type()), _M_pback_cur_save(0),
_M_state_cur(__state_type()), _M_state_beg(__state_type()),
_M_buf(NULL), _M_buf_size(BUFSIZ), _M_buf_allocated(false),
_M_last_overflowed(false), _M_filepos(0), _M_pback_cur_save(0),
_M_pback_end_save(0), _M_pback_init(false), _M_codecvt(0)
{
this->_M_buf_unified = true;
@ -193,102 +193,64 @@ namespace std
// fileops happen...
_M_destroy_pback();
const size_t __buflen = this->_M_buf_size
? this->_M_buf_size - 1 : 0;
if (__buflen)
const size_t __buflen = this->_M_buf_size > 1
? this->_M_buf_size - 1 : 1;
if (this->_M_in_cur < this->_M_in_end)
{
if (this->_M_in_cur < this->_M_in_end)
{
__ret = traits_type::to_int_type(*this->_M_in_cur);
if (__bump)
_M_move_in_cur(1);
return __ret;
}
__ret = traits_type::to_int_type(*this->_M_in_cur);
if (__bump)
_M_move_in_cur(1);
return __ret;
}
// Sync internal and external buffers.
if (__testout && this->_M_out_beg < this->_M_out_lim)
this->overflow();
// Get and convert input sequence.
streamsize __elen = 0;
streamsize __ilen = 0;
if (__check_facet(_M_codecvt).always_noconv())
{
__elen = _M_file.xsgetn(reinterpret_cast<char*>(this->_M_in_beg), __buflen);
__ilen = __elen;
}
else
{
char* __buf = static_cast<char*>(__builtin_alloca(__buflen));
__elen = _M_file.xsgetn(__buf, __buflen);
const char* __eend;
char_type* __iend;
codecvt_base::result __r;
__r = _M_codecvt->in(_M_state_cur, __buf, __buf + __elen,
__eend, this->_M_in_beg,
this->_M_in_beg + __buflen, __iend);
if (__r == codecvt_base::ok)
__ilen = __iend - this->_M_in_beg;
else if (__r == codecvt_base::noconv)
{
traits_type::copy(this->_M_in_beg,
reinterpret_cast<char_type*>(__buf),
__elen);
__ilen = __elen;
}
else
{
// Unwind.
__ilen = 0;
_M_file.seekoff(-__elen, ios_base::cur, ios_base::in);
}
}
if (__ilen > 0)
{
_M_set_buffer(__ilen);
__ret = traits_type::to_int_type(*this->_M_in_cur);
if (__bump)
_M_move_in_cur(1);
}
// Sync internal and external buffers.
if (__testout && this->_M_out_beg < this->_M_out_lim)
this->overflow();
// Get and convert input sequence.
streamsize __elen = 0;
streamsize __ilen = 0;
if (__check_facet(_M_codecvt).always_noconv())
{
__elen = _M_file.xsgetn(reinterpret_cast<char*>(this->_M_in_beg), __buflen);
__ilen = __elen;
}
else
{
// Unbuffered.
char __buf;
if (_M_file.xsgetn(&__buf, 1) > 0)
char* __buf = static_cast<char*>(__builtin_alloca(__buflen));
__elen = _M_file.xsgetn(__buf, __buflen);
const char* __eend;
char_type* __iend;
codecvt_base::result __r;
__r = _M_codecvt->in(_M_state_cur, __buf, __buf + __elen,
__eend, this->_M_in_beg,
this->_M_in_beg + __buflen, __iend);
if (__r == codecvt_base::ok)
__ilen = __iend - this->_M_in_beg;
else if (__r == codecvt_base::noconv)
{
if (__check_facet(_M_codecvt).always_noconv())
{
char_type* __cp = reinterpret_cast<char_type*>(&__buf);
__ret = traits_type::to_int_type(*__cp);
}
else
{
char_type __c;
const char* __eend;
char_type* __iend;
codecvt_base::result __r;
__r = _M_codecvt->in(_M_state_cur, &__buf, &__buf + 1,
__eend, &__c, &__c + 1, __iend);
if (__r == codecvt_base::ok
|| __r == codecvt_base::noconv)
__ret = traits_type::to_int_type(__c);
}
// Need to put back this extracted character so that
// sgetc will not advance the input stream iff
// underflow, but cannot call pbackfail directly as
// it calls underflow... which leads to a recursive
// showdown.
if (!__bump)
{
_M_create_pback();
*this->_M_in_cur = traits_type::to_char_type(__ret);
}
traits_type::copy(this->_M_in_beg,
reinterpret_cast<char_type*>(__buf),
__elen);
__ilen = __elen;
}
else
{
// Unwind.
__ilen = 0;
_M_file.seekoff(-__elen, ios_base::cur, ios_base::in);
}
}
if (__ilen > 0)
{
_M_set_buffer(__ilen);
__ret = traits_type::to_int_type(*this->_M_in_cur);
if (__bump)
_M_move_in_cur(1);
}
}
_M_last_overflowed = false;
return __ret;
@ -467,7 +429,7 @@ namespace std
setbuf(char_type* __s, streamsize __n)
{
if (!this->is_open() && __s == 0 && __n == 0)
this->_M_buf_size = 0;
this->_M_buf_size = 1;
else if (__s && __n > 1)
{
// This is implementation-defined behavior, and assumes that

View file

@ -48,12 +48,8 @@ namespace std
if (_M_in_cur < _M_in_end)
{
char_type __c = *this->_M_in_cur;
_M_move_in_cur(1);
__ret = traits_type::to_int_type(__c);
if (_M_buf_size)
_M_move_in_cur(1);
else
this->underflow();
}
else
__ret = this->uflow();

View file

@ -121,6 +121,15 @@ namespace std
*/
char_type* _M_buf;
/**
* @if maint
* Actual size of internal buffer. This number is equal to the size
* of the put area + 1 position, reserved for the overflow char of
* a full area.
* @endif
*/
size_t _M_buf_size;
// Set iff _M_buf is allocated memory from _M_allocate_internal_buffer.
/**
* @if maint
@ -206,6 +215,7 @@ namespace std
~basic_filebuf()
{
this->close();
_M_buf_size = 0;
_M_last_overflowed = false;
}
@ -429,17 +439,15 @@ namespace std
{
const bool __testin = this->_M_mode & ios_base::in;
const bool __testout = this->_M_mode & ios_base::out;
if (this->_M_buf_size)
if (__testin)
this->setg(this->_M_buf, this->_M_buf, this->_M_buf + __off);
if (__testout && this->_M_buf_size > 1)
{
if (__testin)
this->setg(this->_M_buf, this->_M_buf, this->_M_buf + __off);
if (__testout)
{
this->setp(this->_M_buf, this->_M_buf + this->_M_buf_size - 1);
this->_M_out_lim += __off;
}
_M_filepos = this->_M_buf + __off;
this->setp(this->_M_buf, this->_M_buf + this->_M_buf_size - 1);
this->_M_out_lim += __off;
}
_M_filepos = this->_M_buf + __off;
}
};

View file

@ -195,15 +195,6 @@ namespace std
*/
bool _M_buf_unified;
/**
* @if maint
* Actual size of internal buffer. This number is equal to the size
* of the put area + 1 position, reserved for the overflow char of
* a full area.
* @endif
*/
size_t _M_buf_size;
/**
* @if maint
* Place to stash in || out || in | out settings for current streambuf.
@ -267,7 +258,6 @@ namespace std
~basic_streambuf()
{
_M_buf_unified = false;
_M_buf_size = 0;
_M_mode = ios_base::openmode(0);
}
@ -468,8 +458,8 @@ namespace std
*/
basic_streambuf()
: _M_in_beg(0), _M_in_cur(0), _M_in_end(0),
_M_out_beg(0), _M_out_cur(0), _M_out_end(0),_M_out_lim(0),
_M_buf_unified(false), _M_buf_size(BUFSIZ),
_M_out_beg(0), _M_out_cur(0), _M_out_end(0),
_M_out_lim(0), _M_buf_unified(false),
_M_mode(ios_base::openmode(0)),_M_buf_locale(locale())
{ }

View file

@ -0,0 +1,92 @@
// 2001-05-21 Benjamin Kosnik <bkoz@redhat.com>
// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
//
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 27.8.1.4 Overridden virtual functions
#include <fstream>
#include <testsuite_hooks.h>
#include <testsuite_io.h>
// @require@ %-*.tst %-*.txt
// @diff@ %-*.tst %*.txt
const char name_01[] = "sgetc.txt"; // file with data in it
// Test overloaded virtual functions.
void test01()
{
using namespace std;
using namespace __gnu_cxx_test;
typedef std::filebuf::int_type int_type;
typedef filebuf::traits_type traits_type;
bool test = true;
int_type c1, c2, c3;
// int_type sputbackc(char_type c)
// if in_cur not avail || ! traits::eq(c, gptr() [-1]), return pbfail
// otherwise decrements in_cur and returns *gptr()
// in
{
constraint_filebuf fb_01; // in
fb_01.open(name_01, ios::in);
VERIFY( !fb_01.write_position() );
c1 = fb_01.sbumpc();
VERIFY( c1 == '/' );
c2 = fb_01.sputbackc('/');
VERIFY( c1 == c2 );
c3 = fb_01.sgetc();
VERIFY( c3 == c2 );
c3 = fb_01.sbumpc();
VERIFY( c3 == c2 );
fb_01.sbumpc();
c3 = fb_01.sbumpc();
VERIFY( c3 == ' ' );
c1 = fb_01.sgetc();
c2 = fb_01.sputbackc('a');
VERIFY( c2 == 'a' );
c3 = fb_01.sbumpc();
VERIFY( c3 == c2 );
c3 = fb_01.sgetc();
VERIFY( c1 == c3 );
fb_01.pubseekoff(5, ios_base::beg, ios_base::in);
c1 = fb_01.sgetc();
VERIFY( c1 == '0' );
fb_01.sbumpc();
c1 = fb_01.sbumpc();
VERIFY( c1 == '1' );
c2 = fb_01.sputbackc('b');
VERIFY( c2 == 'b' );
fb_01.sbumpc();
c3 = fb_01.sbumpc();
VERIFY( c3 == '1' );
c3 = fb_01.sbumpc();
VERIFY( c3 == '7' );
VERIFY( !fb_01.write_position() );
VERIFY( fb_01.read_position() );
}
}
main()
{
test01();
return 0;
}

View file

@ -0,0 +1,99 @@
// 2001-05-21 Benjamin Kosnik <bkoz@redhat.com>
// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
//
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 27.8.1.4 Overridden virtual functions
#include <fstream>
#include <testsuite_hooks.h>
#include <testsuite_io.h>
// @require@ %-*.tst %-*.txt
// @diff@ %-*.tst %*.txt
const char name_01[] = "tmp_sputbackc_1io.tst"; // empty file, need to create
void test01()
{
using namespace std;
using namespace __gnu_cxx_test;
typedef filebuf::int_type int_type;
typedef filebuf::traits_type traits_type;
typedef size_t size_type;
bool test = true;
streamsize strmsz_1, strmsz_2;
int_type c1, c2, c3;
// int_type sputbackc(char_type c)
// if in_cur not avail || ! traits::eq(c, gptr() [-1]), return pbfail
// otherwise decrements in_cur and returns *gptr()
// in | out
{
constraint_filebuf fb_01;
fb_01.open(name_01, ios_base::out | ios_base::in | ios_base::trunc);
VERIFY( fb_01.write_position() );
VERIFY( !fb_01.read_position() );
strmsz_1 = fb_01.sputn("racadabras", 10);//"abracadabras or what?"
strmsz_2 = fb_01.sputn(", i wanna reach out and", 10);
c1 = fb_01.sgetc(); // -1
c2 = fb_01.sputbackc('z');
strmsz_2 = fb_01.in_avail();
c3 = fb_01.sgetc();
VERIFY( c3 == c2 );
VERIFY( c1 != c3 );
VERIFY( 1 == strmsz_2 );
//test for _in_cur == _in_beg
// fb_01._M_out_beg = "bd23456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZracada" etc
fb_01.pubseekoff(10, std::ios_base::beg,
std::ios_base::in | std::ios_base::out);
fb_01.sputc('m');
strmsz_1 = fb_01.in_avail();
c1 = fb_01.sgetc();
fb_01.snextc();
c2 = fb_01.sputbackc('z');
strmsz_2 = fb_01.in_avail();
c3 = fb_01.sgetc();
VERIFY( c1 != c2 );
VERIFY( c3 == c2 );
VERIFY( c1 != c3 );
VERIFY( c2 == 'z' );
// test for replacing char with identical one
fb_01.snextc();
fb_01.sputc('u');
fb_01.sputc('v');
fb_01.sputc('a');
strmsz_1 = fb_01.in_avail();
c2 = fb_01.sputbackc('a');
strmsz_2 = fb_01.in_avail();
c3 = fb_01.sgetc();
VERIFY( c3 == c2 );
VERIFY( strmsz_1 + 1 == strmsz_2 );
VERIFY( fb_01.write_position() );
VERIFY( fb_01.read_position() );
}
}
main()
{
test01();
return 0;
}

View file

@ -0,0 +1,70 @@
// 2001-05-21 Benjamin Kosnik <bkoz@redhat.com>
// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
//
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 27.8.1.4 Overridden virtual functions
#include <fstream>
#include <testsuite_hooks.h>
#include <testsuite_io.h>
// @require@ %-*.tst %-*.txt
// @diff@ %-*.tst %*.txt
const char name_01[] = "tmp_sputbackc_1out.tst"; // empty file, need to create
// Test overloaded virtual functions.
void test01()
{
using namespace std;
using namespace __gnu_cxx_test;
typedef std::filebuf::int_type int_type;
typedef filebuf::traits_type traits_type;
bool test = true;
int_type c1, c2, c3;
// int_type sputbackc(char_type c)
// if in_cur not avail || ! traits::eq(c, gptr() [-1]), return pbfail
// otherwise decrements in_cur and returns *gptr()
// out
{
constraint_filebuf fb_01; // out
fb_01.open(name_01, ios::out | ios::trunc);
VERIFY( fb_01.write_position() );
VERIFY( !fb_01.read_position() );
c1 = fb_01.sgetc();
VERIFY( c1 == traits_type::eof() );
c2 = fb_01.sputbackc('a');
VERIFY( c2 == traits_type::eof() );
fb_01.sbumpc();
c1 = fb_01.sbumpc();
c2 = fb_01.sputbackc('a');
VERIFY( c1 == c2 );
VERIFY( fb_01.write_position() );
VERIFY( !fb_01.read_position() );
}
}
main()
{
test01();
return 0;
}

View file

@ -0,0 +1,92 @@
// 2001-05-21 Benjamin Kosnik <bkoz@redhat.com>
// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
//
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 27.8.1.4 Overridden virtual functions
#include <fstream>
#include <testsuite_hooks.h>
#include <testsuite_io.h>
// @require@ %-*.tst %-*.txt
// @diff@ %-*.tst %*.txt
const char name_01[] = "sgetc.txt"; // file with data in it
// Test overloaded virtual functions.
void test01()
{
using namespace std;
using namespace __gnu_cxx_test;
typedef std::filebuf::int_type int_type;
typedef filebuf::traits_type traits_type;
bool test = true;
int_type c1, c2, c3;
// int_type sputbackc(char_type c)
// if in_cur not avail || ! traits::eq(c, gptr() [-1]), return pbfail
// otherwise decrements in_cur and returns *gptr()
// in
{
constraint_filebuf fb_01; // in
fb_01.pubsetbuf(0, 0);
fb_01.open(name_01, ios::in);
VERIFY( fb_01.unbuffered() );
c1 = fb_01.sbumpc();
VERIFY( c1 == '/' );
c2 = fb_01.sputbackc('/');
VERIFY( c1 == c2 );
c3 = fb_01.sgetc();
VERIFY( c3 == c2 );
c3 = fb_01.sbumpc();
VERIFY( c3 == c2 );
fb_01.sbumpc();
c3 = fb_01.sbumpc();
VERIFY( c3 == ' ' );
c1 = fb_01.sgetc();
c2 = fb_01.sputbackc('a');
VERIFY( c2 == 'a' );
c3 = fb_01.sbumpc();
VERIFY( c3 == c2 );
c3 = fb_01.sgetc();
VERIFY( c1 == c3 );
fb_01.pubseekoff(5, ios_base::beg, ios_base::in);
c1 = fb_01.sgetc();
VERIFY( c1 == '0' );
fb_01.sbumpc();
c1 = fb_01.sbumpc();
VERIFY( c1 == '1' );
c2 = fb_01.sputbackc('b');
VERIFY( c2 == 'b' );
fb_01.sbumpc();
c3 = fb_01.sbumpc();
VERIFY( c3 == '1' );
c3 = fb_01.sbumpc();
VERIFY( c3 == '7' );
VERIFY( fb_01.unbuffered() );
}
}
main()
{
test01();
return 0;
}

View file

@ -0,0 +1,98 @@
// 2001-05-21 Benjamin Kosnik <bkoz@redhat.com>
// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
//
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 27.8.1.4 Overridden virtual functions
#include <fstream>
#include <testsuite_hooks.h>
#include <testsuite_io.h>
// @require@ %-*.tst %-*.txt
// @diff@ %-*.tst %*.txt
const char name_01[] = "tmp_sputbackc_2io.tst"; // empty file, need to create
void test01()
{
using namespace std;
using namespace __gnu_cxx_test;
typedef filebuf::int_type int_type;
typedef filebuf::traits_type traits_type;
typedef size_t size_type;
bool test = true;
streamsize strmsz_1, strmsz_2;
int_type c1, c2, c3;
// int_type sputbackc(char_type c)
// if in_cur not avail || ! traits::eq(c, gptr() [-1]), return pbfail
// otherwise decrements in_cur and returns *gptr()
// in | out
{
constraint_filebuf fb_01;
fb_01.pubsetbuf(0, 0);
fb_01.open(name_01, ios_base::out | ios_base::in | ios_base::trunc);
VERIFY( fb_01.unbuffered() );
strmsz_1 = fb_01.sputn("racadabras", 10);//"abracadabras or what?"
strmsz_2 = fb_01.sputn(", i wanna reach out and", 10);
c1 = fb_01.sgetc(); // -1
c2 = fb_01.sputbackc('z');
strmsz_2 = fb_01.in_avail();
c3 = fb_01.sgetc();
VERIFY( c3 == c2 );
VERIFY( c1 != c3 );
VERIFY( 1 == strmsz_2 );
//test for _in_cur == _in_beg
// fb_01._M_out_beg = "bd23456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZracada" etc
fb_01.pubseekoff(10, std::ios_base::beg,
std::ios_base::in | std::ios_base::out);
fb_01.sputc('m');
strmsz_1 = fb_01.in_avail();
c1 = fb_01.sgetc();
fb_01.snextc();
c2 = fb_01.sputbackc('z');
strmsz_2 = fb_01.in_avail();
c3 = fb_01.sgetc();
VERIFY( c1 != c2 );
VERIFY( c3 == c2 );
VERIFY( c1 != c3 );
VERIFY( c2 == 'z' );
// test for replacing char with identical one
fb_01.snextc();
fb_01.sputc('u');
fb_01.sputc('v');
fb_01.sputc('a');
strmsz_1 = fb_01.in_avail();
c2 = fb_01.sputbackc('a');
strmsz_2 = fb_01.in_avail();
c3 = fb_01.sgetc();
VERIFY( c3 == c2 );
VERIFY( strmsz_1 == strmsz_2 );
VERIFY( fb_01.unbuffered() );
}
}
main()
{
test01();
return 0;
}

View file

@ -0,0 +1,71 @@
// 2001-05-21 Benjamin Kosnik <bkoz@redhat.com>
// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
//
// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 27.8.1.4 Overridden virtual functions
#include <fstream>
#include <testsuite_hooks.h>
#include <testsuite_io.h>
// @require@ %-*.tst %-*.txt
// @diff@ %-*.tst %*.txt
const char name_01[] = "tmp_sputbackc_2out.tst"; // empty file, need to create
// Test overloaded virtual functions.
void test01()
{
using namespace std;
using namespace __gnu_cxx_test;
typedef std::filebuf::int_type int_type;
typedef filebuf::traits_type traits_type;
bool test = true;
int_type c1, c2, c3;
// int_type sputbackc(char_type c)
// if in_cur not avail || ! traits::eq(c, gptr() [-1]), return pbfail
// otherwise decrements in_cur and returns *gptr()
// out
{
constraint_filebuf fb_01; // out
fb_01.pubsetbuf(0, 0);
fb_01.open(name_01, ios::out | ios::trunc);
VERIFY( fb_01.unbuffered() );
VERIFY( !fb_01.read_position() );
c1 = fb_01.sgetc();
VERIFY( c1 == traits_type::eof() );
c2 = fb_01.sputbackc('a');
VERIFY( c2 == traits_type::eof() );
fb_01.sbumpc();
c1 = fb_01.sbumpc();
c2 = fb_01.sputbackc('a');
VERIFY( c1 == c2 );
VERIFY( fb_01.unbuffered() );
VERIFY( !fb_01.read_position() );
}
}
main()
{
test01();
return 0;
}