re PR libstdc++/45628 (std::fstream::tellg invalidates I/O buffer)
2010-09-22 David Krauss <potswa@mac.com> PR libstdc++/45628 * include/bits/fstream.tcc (basic_filebuf::underflow): Add state transition to avoid modality requiring seekoff(0,ios::cur). (basic_filebuf::pbackfail): Likewise. (basic_filebuf::overflow): Likewise. (basic_filebuf::_M_seek): Avoid minor unnecessary conversion. (basic_filebuf::seekoff): Remove code to _M_get_ext_pos; make (0, ios::cur) a special case preserving buffer contents. (basic_filebuf::_M_get_ext_pos): New function to obtain status about codecvt extern_t buffer for overflow and seekoff. * include/std/fstream (basic_filebuf::_M_get_ext_pos): Likewise. * config/abi/pre/gnu.ver: Export new symbols. * testsuite/27_io/basic_filebuf/seekoff/char/45628-1.cc: New, verifies that seekoff(0, ios::cur) preserves buffers. * testsuite/27_io/basic_filebuf/seekoff/char/45628-2.cc: Likewise. for codecvt case. More lenient as it may still flush put area. * testsuite/27_io/basic_filebuf/seekoff/char/4.cc: Modify to check that seekoff is not required between read and write. * testsuite/27_io/basic_filebuf/seekoff/wchar_t/4.cc: Likewise. * testsuite/27_io/basic_filebuf/sync/wchar_t/1.cc: Remove. * testsuite/27_io/basic_filebuf/sync/wchar_t/1.cc: Likewise. * testsuite/util/testsuite_character.h (codecvt::do_length): Comply with 22.2.1.5.2/10 "Returns ... the LARGEST value in the range..." From-SVN: r164529
This commit is contained in:
parent
5d64ee190c
commit
3531cf5ef3
|
@ -1,3 +1,29 @@
|
|||
2010-09-22 David Krauss <potswa@mac.com>
|
||||
|
||||
PR libstdc++/45628
|
||||
* include/bits/fstream.tcc (basic_filebuf::underflow): Add state
|
||||
transition to avoid modality requiring seekoff(0,ios::cur).
|
||||
(basic_filebuf::pbackfail): Likewise.
|
||||
(basic_filebuf::overflow): Likewise.
|
||||
(basic_filebuf::_M_seek): Avoid minor unnecessary conversion.
|
||||
(basic_filebuf::seekoff): Remove code to _M_get_ext_pos; make
|
||||
(0, ios::cur) a special case preserving buffer contents.
|
||||
(basic_filebuf::_M_get_ext_pos): New function to obtain status
|
||||
about codecvt extern_t buffer for overflow and seekoff.
|
||||
* include/std/fstream (basic_filebuf::_M_get_ext_pos): Likewise.
|
||||
* config/abi/pre/gnu.ver: Export new symbols.
|
||||
* testsuite/27_io/basic_filebuf/seekoff/char/45628-1.cc: New,
|
||||
verifies that seekoff(0, ios::cur) preserves buffers.
|
||||
* testsuite/27_io/basic_filebuf/seekoff/char/45628-2.cc: Likewise.
|
||||
for codecvt case. More lenient as it may still flush put area.
|
||||
* testsuite/27_io/basic_filebuf/seekoff/char/4.cc: Modify to
|
||||
check that seekoff is not required between read and write.
|
||||
* testsuite/27_io/basic_filebuf/seekoff/wchar_t/4.cc: Likewise.
|
||||
* testsuite/27_io/basic_filebuf/sync/wchar_t/1.cc: Remove.
|
||||
* testsuite/27_io/basic_filebuf/sync/wchar_t/1.cc: Likewise.
|
||||
* testsuite/util/testsuite_character.h (codecvt::do_length): Comply
|
||||
with 22.2.1.5.2/10 "Returns ... the LARGEST value in the range..."
|
||||
|
||||
2010-09-22 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
* include/bits/functional_hash.h (__hash_base): Add.
|
||||
|
|
|
@ -332,7 +332,13 @@ GLIBCXX_3.4 {
|
|||
# std::basic_filebuf
|
||||
_ZNSt13basic_filebufI[cw]St11char_traitsI[cw]EEC*;
|
||||
_ZNSt13basic_filebufI[cw]St11char_traitsI[cw]EED*;
|
||||
_ZNSt13basic_filebufI[cw]St11char_traitsI[cw]EE[0-3]*;
|
||||
_ZNSt13basic_filebufI[cw]St11char_traitsI[cw]EE0*;
|
||||
_ZNSt13basic_filebufI[cw]St11char_traitsI[cw]EE13*;
|
||||
_ZNSt13basic_filebufI[cw]St11char_traitsI[cw]EE15*;
|
||||
_ZNSt13basic_filebufI[cw]St11char_traitsI[cw]EE16*;
|
||||
_ZNSt13basic_filebufI[cw]St11char_traitsI[cw]EE19*;
|
||||
_ZNSt13basic_filebufI[cw]St11char_traitsI[cw]EE2*;
|
||||
_ZNSt13basic_filebufI[cw]St11char_traitsI[cw]EE3*;
|
||||
_ZNSt13basic_filebufI[cw]St11char_traitsI[cw]EE4openEPKc*;
|
||||
_ZNSt13basic_filebufI[cw]St11char_traitsI[cw]EE4sync*;
|
||||
_ZNSt13basic_filebufI[cw]St11char_traitsI[cw]EE[5-9]*;
|
||||
|
@ -1178,6 +1184,9 @@ GLIBCXX_3.4.15 {
|
|||
_ZNSbIwSt11char_traitsIwESaIwEE4backEv;
|
||||
_ZNKSbIwSt11char_traitsIwESaIwEE4backEv;
|
||||
|
||||
# basic_filebuf::_M_get_ext_pos
|
||||
_ZNSt13basic_filebufI[cw]St11char_traitsI[cw]EE14_M_get_ext_pos*;
|
||||
|
||||
} GLIBCXX_3.4.14;
|
||||
|
||||
# Symbols in the support library (libsupc++) have their own tag.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// File based streams -*- C++ -*-
|
||||
|
||||
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||
// 2007, 2008, 2009
|
||||
// 2007, 2008, 2009, 2010
|
||||
// Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
|
@ -205,8 +205,16 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
|||
{
|
||||
int_type __ret = traits_type::eof();
|
||||
const bool __testin = _M_mode & ios_base::in;
|
||||
if (__testin && !_M_writing)
|
||||
if (__testin)
|
||||
{
|
||||
if (_M_writing)
|
||||
{
|
||||
__ret = overflow();
|
||||
if (__ret == traits_type::eof())
|
||||
return __ret;
|
||||
_M_set_buffer(-1);
|
||||
_M_writing = false;
|
||||
}
|
||||
// Check for pback madness, and if so switch back to the
|
||||
// normal buffers and jet outta here before expensive
|
||||
// fileops happen...
|
||||
|
@ -357,8 +365,16 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
|||
{
|
||||
int_type __ret = traits_type::eof();
|
||||
const bool __testin = _M_mode & ios_base::in;
|
||||
if (__testin && !_M_writing)
|
||||
if (__testin)
|
||||
{
|
||||
if (_M_writing)
|
||||
{
|
||||
__ret = overflow();
|
||||
if (__ret == traits_type::eof())
|
||||
return __ret;
|
||||
_M_set_buffer(-1);
|
||||
_M_writing = false;
|
||||
}
|
||||
// Remember whether the pback buffer is active, otherwise below
|
||||
// we may try to store in it a second char (libstdc++/9761).
|
||||
const bool __testpb = _M_pback_init;
|
||||
|
@ -410,8 +426,16 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
|||
int_type __ret = traits_type::eof();
|
||||
const bool __testeof = traits_type::eq_int_type(__c, __ret);
|
||||
const bool __testout = _M_mode & ios_base::out;
|
||||
if (__testout && !_M_reading)
|
||||
if (__testout)
|
||||
{
|
||||
if (_M_reading)
|
||||
{
|
||||
_M_destroy_pback();
|
||||
const int __gptr_off = _M_get_ext_pos(_M_state_last);
|
||||
if (_M_seek(__gptr_off, ios_base::cur, _M_state_last)
|
||||
== pos_type(off_type(-1)))
|
||||
return __ret;
|
||||
}
|
||||
if (this->pbase() < this->pptr())
|
||||
{
|
||||
// If appropriate, append the overflow char.
|
||||
|
@ -691,12 +715,20 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
|||
if (__width < 0)
|
||||
__width = 0;
|
||||
|
||||
pos_type __ret = pos_type(off_type(-1));
|
||||
pos_type __ret = pos_type(off_type(-1));
|
||||
const bool __testfail = __off != 0 && __width <= 0;
|
||||
if (this->is_open() && !__testfail)
|
||||
{
|
||||
// tellg and tellp queries do not affect any state, unless
|
||||
// ! always_noconv and the put sequence is not empty.
|
||||
// In that case, determining the position requires converting the
|
||||
// put sequence. That doesn't use ext_buf, so requires a flush.
|
||||
bool __no_movement = __way == ios_base::cur && __off == 0
|
||||
&& (!_M_writing || _M_codecvt->always_noconv());
|
||||
|
||||
// Ditch any pback buffers to avoid confusion.
|
||||
_M_destroy_pback();
|
||||
if (!__no_movement)
|
||||
_M_destroy_pback();
|
||||
|
||||
// Correct state at destination. Note that this is the correct
|
||||
// state for the current position during output, because
|
||||
|
@ -707,24 +739,23 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
|||
off_type __computed_off = __off * __width;
|
||||
if (_M_reading && __way == ios_base::cur)
|
||||
{
|
||||
if (_M_codecvt->always_noconv())
|
||||
__computed_off += this->gptr() - this->egptr();
|
||||
else
|
||||
__state = _M_state_last;
|
||||
__computed_off += _M_get_ext_pos(__state);
|
||||
}
|
||||
if (!__no_movement)
|
||||
__ret = _M_seek(__computed_off, __way, __state);
|
||||
else
|
||||
{
|
||||
if (_M_writing)
|
||||
__computed_off = this->pptr() - this->pbase();
|
||||
|
||||
off_type __file_off = _M_file.seekoff(0, ios_base::cur);
|
||||
if (__file_off != off_type(-1))
|
||||
{
|
||||
// Calculate offset from _M_ext_buf that corresponds
|
||||
// to gptr(). Note: uses _M_state_last, which
|
||||
// corresponds to eback().
|
||||
const int __gptr_off =
|
||||
_M_codecvt->length(_M_state_last, _M_ext_buf, _M_ext_next,
|
||||
this->gptr() - this->eback());
|
||||
__computed_off += _M_ext_buf + __gptr_off - _M_ext_end;
|
||||
|
||||
// _M_state_last is modified by codecvt::length() so
|
||||
// it now corresponds to gptr().
|
||||
__state = _M_state_last;
|
||||
__ret = __file_off + __computed_off;
|
||||
__ret.state(__state);
|
||||
}
|
||||
}
|
||||
__ret = _M_seek(__computed_off, __way, __state);
|
||||
}
|
||||
return __ret;
|
||||
}
|
||||
|
@ -756,21 +787,42 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
|||
pos_type __ret = pos_type(off_type(-1));
|
||||
if (_M_terminate_output())
|
||||
{
|
||||
// Returns pos_type(off_type(-1)) in case of failure.
|
||||
__ret = pos_type(_M_file.seekoff(__off, __way));
|
||||
if (__ret != pos_type(off_type(-1)))
|
||||
off_type __file_off = _M_file.seekoff(__off, __way);
|
||||
if (__file_off != off_type(-1))
|
||||
{
|
||||
_M_reading = false;
|
||||
_M_writing = false;
|
||||
_M_ext_next = _M_ext_end = _M_ext_buf;
|
||||
_M_set_buffer(-1);
|
||||
_M_state_cur = __state;
|
||||
__ret = __file_off;
|
||||
__ret.state(_M_state_cur);
|
||||
}
|
||||
}
|
||||
return __ret;
|
||||
}
|
||||
|
||||
// Returns the distance from the end of the ext buffer to the point
|
||||
// corresponding to gptr(). This is a negative value. Updates __state
|
||||
// from eback() correspondence to gptr().
|
||||
template<typename _CharT, typename _Traits>
|
||||
int basic_filebuf<_CharT, _Traits>::
|
||||
_M_get_ext_pos(__state_type& __state)
|
||||
{
|
||||
if (_M_codecvt->always_noconv())
|
||||
return this->gptr() - this->egptr();
|
||||
else
|
||||
{
|
||||
// Calculate offset from _M_ext_buf that corresponds to
|
||||
// gptr(). Precondition: __state == _M_state_last, which
|
||||
// corresponds to eback().
|
||||
const int __gptr_off =
|
||||
_M_codecvt->length(__state, _M_ext_buf, _M_ext_next,
|
||||
this->gptr() - this->eback());
|
||||
return _M_ext_buf + __gptr_off - _M_ext_end;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
bool
|
||||
basic_filebuf<_CharT, _Traits>::
|
||||
|
|
|
@ -351,9 +351,12 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
|||
seekpos(pos_type __pos,
|
||||
ios_base::openmode __mode = ios_base::in | ios_base::out);
|
||||
|
||||
// Common code for seekoff and seekpos
|
||||
// Common code for seekoff, seekpos, and overflow
|
||||
pos_type
|
||||
_M_seek(off_type __off, ios_base::seekdir __way, __state_type __state);
|
||||
|
||||
int
|
||||
_M_get_ext_pos(__state_type &__state);
|
||||
|
||||
virtual int
|
||||
sync();
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
// Copyright (C) 2010 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 3, 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 COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
// { dg-require-fileio "" }
|
||||
|
||||
#include <fstream>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_character.h>
|
||||
|
||||
const char name_01[] = "tmp_seekoff_45628.tst";
|
||||
|
||||
unsigned underflows, overflows;
|
||||
|
||||
class my_filebuf
|
||||
: public std::basic_filebuf<__gnu_test::pod_uchar>
|
||||
{
|
||||
virtual int_type
|
||||
underflow()
|
||||
{
|
||||
++underflows;
|
||||
return std::basic_filebuf<__gnu_test::pod_uchar>::underflow();
|
||||
}
|
||||
virtual int_type
|
||||
overflow(int_type c)
|
||||
{
|
||||
++overflows;
|
||||
return std::basic_filebuf<__gnu_test::pod_uchar>::overflow(c);
|
||||
}
|
||||
};
|
||||
|
||||
// libstdc++/45628
|
||||
void test01()
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
|
||||
using __gnu_test::pod_uchar;
|
||||
std::locale loc(std::locale::classic(),
|
||||
new std::codecvt<my_filebuf::traits_type::char_type, char,
|
||||
my_filebuf::traits_type::state_type>);
|
||||
|
||||
my_filebuf::pos_type opos[3], ipos[3];
|
||||
my_filebuf q;
|
||||
q.pubimbue(loc);
|
||||
|
||||
q.open(name_01, std::ios_base::in | std::ios_base::out
|
||||
| std::ios_base::trunc);
|
||||
|
||||
q.sputc(pod_uchar::from<char>('a'));
|
||||
opos[0] = q.pubseekoff(0, std::ios_base::cur);
|
||||
q.sputc(pod_uchar::from<char>('b'));
|
||||
opos[1] = q.pubseekoff(0, std::ios_base::cur);
|
||||
q.sputc(pod_uchar::from<char>('c'));
|
||||
opos[2] = q.pubseekoff(0, std::ios_base::cur);
|
||||
|
||||
VERIFY( overflows <= 9 ); // pubseekoff calls overflow twice if converting.
|
||||
// NB: checking opos==ipos is not very rigorous as long as it flushes, since
|
||||
// all positions will be at initial state.
|
||||
q.pubseekoff(0, std::ios_base::beg);
|
||||
|
||||
q.sbumpc();
|
||||
VERIFY( underflows == 1 );
|
||||
|
||||
ipos[0] = q.pubseekoff(0, std::ios_base::cur);
|
||||
VERIFY( ipos[0] == opos[0] );
|
||||
q.sbumpc();
|
||||
ipos[1] = q.pubseekoff(0, std::ios_base::cur);
|
||||
VERIFY( ipos[1] == opos[1] );
|
||||
q.sbumpc();
|
||||
ipos[2] = q.pubseekoff(0, std::ios_base::cur);
|
||||
VERIFY( ipos[2] == opos[2] );
|
||||
|
||||
VERIFY( underflows == 1 ); // pubseekoff never flushes get area
|
||||
|
||||
// Bonus test: check automatic mode switches.
|
||||
q.sputc(pod_uchar::from<char>('d'));
|
||||
|
||||
q.pubseekpos( ipos[1] );
|
||||
q.sputc(pod_uchar::from<char>('e'));
|
||||
|
||||
VERIFY( my_filebuf::traits_type::eq(
|
||||
my_filebuf::traits_type::to_char_type(q.sgetc()),
|
||||
pod_uchar::from<char>('d')) );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
|
@ -31,7 +31,7 @@ void test01()
|
|||
typedef filebuf::pos_type pos_type;
|
||||
const char name[] = "tmp_seekoff-4.tst";
|
||||
|
||||
const size_t size = 10;
|
||||
const size_t size = 12;
|
||||
char buf[size];
|
||||
streamsize n;
|
||||
|
||||
|
@ -46,7 +46,7 @@ void test01()
|
|||
VERIFY( n == 3 );
|
||||
VERIFY( !memcmp(buf, "abc", 3) );
|
||||
|
||||
fb.pubseekoff(0, ios_base::cur);
|
||||
// Check read => write without pubseekoff(0, ios_base::cur)
|
||||
|
||||
n = fb.sputn("ef", 2);
|
||||
VERIFY( n == 2 );
|
||||
|
@ -58,9 +58,17 @@ void test01()
|
|||
VERIFY( !memcmp(buf, "abcef", 5) );
|
||||
|
||||
fb.pubseekoff(0, ios_base::beg);
|
||||
n = fb.sputn("ghijkl", 6);
|
||||
VERIFY( n == 6 );
|
||||
n = fb.sputn("gh", 2);
|
||||
VERIFY( n == 2 );
|
||||
|
||||
// Check write => read without pubseekoff(0, ios_base::cur)
|
||||
|
||||
n = fb.sgetn( buf, 3 );
|
||||
VERIFY( !memcmp(buf, "cef", 3) );
|
||||
|
||||
n = fb.sputn("ijkl", 4);
|
||||
VERIFY( n == 4 );
|
||||
|
||||
fb.pubseekoff(0, ios_base::beg);
|
||||
n = fb.sgetn(buf, 2);
|
||||
VERIFY( n == 2 );
|
||||
|
@ -72,8 +80,8 @@ void test01()
|
|||
|
||||
fb.pubseekoff(0, ios_base::beg);
|
||||
n = fb.sgetn(buf, size);
|
||||
VERIFY( n == 9 );
|
||||
VERIFY( !memcmp(buf, "ghijklmno", 9) );
|
||||
VERIFY( n == 12 );
|
||||
VERIFY( !memcmp(buf, "ghcefijklmno", 12) );
|
||||
|
||||
fb.close();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
// Copyright (C) 2010 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 3, 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 COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
// { dg-require-fileio "" }
|
||||
|
||||
#include <fstream>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
const char name_01[] = "tmp_seekoff_45628.tst";
|
||||
|
||||
unsigned underflows, overflows;
|
||||
|
||||
class my_filebuf
|
||||
: public std::filebuf
|
||||
{
|
||||
virtual int_type
|
||||
underflow()
|
||||
{
|
||||
++underflows;
|
||||
return std::filebuf::underflow();
|
||||
}
|
||||
virtual int_type
|
||||
overflow(int_type c)
|
||||
{
|
||||
++overflows;
|
||||
return std::filebuf::overflow(c);
|
||||
}
|
||||
};
|
||||
|
||||
// libstdc++/45628
|
||||
void test01()
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
|
||||
my_filebuf q;
|
||||
q.open(name_01, std::ios_base::in | std::ios_base::out
|
||||
| std::ios_base::trunc);
|
||||
|
||||
q.sputc('a');
|
||||
q.pubseekoff(0, std::ios_base::cur);
|
||||
q.sputc('b');
|
||||
q.pubseekoff(0, std::ios_base::cur);
|
||||
q.sputc('c');
|
||||
q.pubseekoff(0, std::ios_base::cur);
|
||||
|
||||
VERIFY( overflows <= 1 ); // only initial sputc allowed to overflow
|
||||
q.pubseekoff(0, std::ios_base::beg);
|
||||
|
||||
q.sbumpc();
|
||||
VERIFY( underflows == 1 );
|
||||
|
||||
q.pubseekoff(0, std::ios_base::cur);
|
||||
q.sbumpc();
|
||||
q.pubseekoff(0, std::ios_base::cur);
|
||||
q.sbumpc();
|
||||
q.pubseekoff(0, std::ios_base::cur);
|
||||
|
||||
VERIFY( underflows == 1 );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
|
@ -31,7 +31,7 @@ void test01()
|
|||
typedef wfilebuf::pos_type pos_type;
|
||||
const char name[] = "tmp_seekoff-4.tst";
|
||||
|
||||
const size_t size = 10;
|
||||
const size_t size = 12;
|
||||
wchar_t buf[size];
|
||||
streamsize n;
|
||||
|
||||
|
@ -46,7 +46,7 @@ void test01()
|
|||
VERIFY( n == 3 );
|
||||
VERIFY( !wmemcmp(buf, L"abc", 3) );
|
||||
|
||||
fb.pubseekoff(0, ios_base::cur);
|
||||
// Check read => write without pubseekoff(0, ios_base::cur)
|
||||
|
||||
n = fb.sputn(L"ef", 2);
|
||||
VERIFY( n == 2 );
|
||||
|
@ -58,8 +58,16 @@ void test01()
|
|||
VERIFY( !wmemcmp(buf, L"abcef", 5) );
|
||||
|
||||
fb.pubseekoff(0, ios_base::beg);
|
||||
n = fb.sputn(L"ghijkl", 6);
|
||||
VERIFY( n == 6 );
|
||||
n = fb.sputn(L"gh", 2);
|
||||
VERIFY( n == 2 );
|
||||
|
||||
// Check write => read without pubseekoff(0, ios_base::cur)
|
||||
|
||||
n = fb.sgetn( buf, 3 );
|
||||
VERIFY( !memcmp(buf, L"cef", 3) );
|
||||
|
||||
n = fb.sputn(L"ijkl", 4);
|
||||
VERIFY( n == 4 );
|
||||
|
||||
fb.pubseekoff(0, ios_base::beg);
|
||||
n = fb.sgetn(buf, 2);
|
||||
|
@ -72,8 +80,8 @@ void test01()
|
|||
|
||||
fb.pubseekoff(0, ios_base::beg);
|
||||
n = fb.sgetn(buf, size);
|
||||
VERIFY( n == 9 );
|
||||
VERIFY( !wmemcmp(buf, L"ghijklmno", 9) );
|
||||
VERIFY( n == 12 );
|
||||
VERIFY( !wmemcmp(buf, L"ghcefijklmno", 12) );
|
||||
|
||||
fb.close();
|
||||
}
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
// Copyright (C) 2003, 2009 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 3, 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 COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
// 27.8.1.4 Overridden virtual functions
|
||||
|
||||
#include <fstream>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
void test01()
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
bool test __attribute__((unused)) = true;
|
||||
const char* name = "tmp_sync_1";
|
||||
|
||||
filebuf fb;
|
||||
|
||||
fb.open(name, ios_base::in | ios_base::out | ios_base::trunc);
|
||||
fb.sputn("abc", 3);
|
||||
|
||||
fb.pubseekoff(0, ios_base::beg);
|
||||
fb.sputc('1');
|
||||
|
||||
// Sync can't be used to switch from write mode to read mode.
|
||||
fb.pubsync();
|
||||
|
||||
filebuf::int_type c = fb.sbumpc();
|
||||
VERIFY( c == filebuf::traits_type::eof() );
|
||||
|
||||
fb.close();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
// Copyright (C) 2003, 2009 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 3, 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 COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
// 27.8.1.4 Overridden virtual functions
|
||||
|
||||
#include <fstream>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
void test01()
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
bool test __attribute__((unused)) = true;
|
||||
const char* name = "tmp_sync_1";
|
||||
|
||||
wfilebuf fb;
|
||||
|
||||
fb.open(name, ios_base::in | ios_base::out | ios_base::trunc);
|
||||
fb.sputn(L"abc", 3);
|
||||
|
||||
fb.pubseekoff(0, ios_base::beg);
|
||||
fb.sputc(L'1');
|
||||
|
||||
// Sync can't be used to switch from write mode to read mode.
|
||||
fb.pubsync();
|
||||
|
||||
wfilebuf::int_type c = fb.sbumpc();
|
||||
VERIFY( c == wfilebuf::traits_type::eof() );
|
||||
|
||||
fb.close();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
|
@ -294,7 +294,7 @@ namespace std
|
|||
const extern_type* end, size_t max) const
|
||||
{
|
||||
const extern_type* beg = from;
|
||||
while (from < end && max)
|
||||
while (from < end)
|
||||
{
|
||||
unsigned char c = *from;
|
||||
if (c & 0xc0)
|
||||
|
@ -304,6 +304,8 @@ namespace std
|
|||
++from;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (max == 0) break;
|
||||
|
||||
unsigned char tmp;
|
||||
if (state.value & 0x8)
|
||||
|
|
Loading…
Reference in New Issue