Commit 39003c99 by Benjamin Kosnik Committed by Benjamin Kosnik

std_fstream.h (basic_filebuf): Change signature.


2001-05-07  Benjamin Kosnik  <bkoz@redhat.com>

	libstdc++/2523
	* include/bits/std_fstream.h (basic_filebuf): Change signature.
	* include/bits/fstream.tcc (basic_filebuf): Change bool argument
	to int_type, pass in buffer size info.
	* include/bits/std_streambuf.h (_M_is_indeterminate): Check for
	unbuffered situation.
	(underflow): Remove codecvt bits for the time being.
	* include/bits/istream.tcc (istream::sentry): Avoid sputbackc call.
	* include/bits/locale_facets.tcc (_M_extract): Cache dereference
	values from iterators, clean.
	* src/locale.cc: Ditto.
	* include/bits/sbuf_iter.h: Format.
	* src/ios.cc: Explicitly pass in buffer sizes at creation time.
	* testsuite/27_io/narrow_stream_objects.cc: Add tests.
	* testsuite/27_io/filebuf.cc: Tweaks.
	* testsuite/27_io/filebuf_members.cc: Tweaks.

From-SVN: r41908
parent eefd41e3
2001-05-07 Benjamin Kosnik <bkoz@redhat.com>
libstdc++/2523
* include/bits/std_fstream.h (basic_filebuf): Change signature.
* include/bits/fstream.tcc (basic_filebuf): Change bool argument
to int_type, pass in buffer size info.
* include/bits/std_streambuf.h (_M_is_indeterminate): Check for
unbuffered situation.
(underflow): Remove codecvt bits for the time being.
* include/bits/istream.tcc (istream::sentry): Avoid sputbackc call.
* include/bits/locale_facets.tcc (_M_extract): Cache dereference
values from iterators, clean.
* src/locale.cc: Ditto.
* include/bits/sbuf_iter.h: Format.
* src/ios.cc: Explicitly pass in buffer sizes at creation time.
* testsuite/27_io/narrow_stream_objects.cc: Add tests.
* testsuite/27_io/filebuf.cc: Tweaks.
* testsuite/27_io/filebuf_members.cc: Tweaks.
2001-05-07 Mark Mitchell <mark@codesourcery.com>
* config/os/solaris/solaris2.7/bits/os_defines.h
......
......@@ -90,7 +90,7 @@ namespace std
template<typename _CharT, typename _Traits>
basic_filebuf<_CharT, _Traits>::
basic_filebuf(__c_file_type* __f, bool __s, ios_base::openmode __mode)
basic_filebuf(__c_file_type* __f, ios_base::openmode __mode, int_type __s)
: __streambuf_type(), _M_file(NULL), _M_state_cur(__state_type()),
_M_state_beg(__state_type()), _M_last_overflowed(false)
{
......@@ -99,8 +99,9 @@ namespace std
if (this->is_open())
{
_M_mode = __mode;
if (!__s)
if (__s)
{
_M_buf_size_opt = __s;
_M_allocate_buffers();
_M_set_indeterminate();
}
......@@ -208,7 +209,9 @@ namespace std
{
int_type __ret = traits_type::eof();
bool __testin = _M_mode & ios_base::in;
bool __testout = _M_mode & ios_base::out;
// XXX Should re-enable codecvt bits disabled after 2.90.8.
if (__testin)
{
// Check for pback madness, and if so swich back to the
......@@ -223,8 +226,6 @@ namespace std
bool __testget = _M_in_cur && _M_in_beg < _M_in_cur;
bool __testinit = _M_is_indeterminate();
bool __testout = _M_mode & ios_base::out;
// Sync internal and external buffers.
// NB: __testget -> __testput as _M_buf_unified here.
if (__testget)
......@@ -238,7 +239,7 @@ namespace std
if (__testinit || __testget)
{
#if 1
// Assume buffered case, need to refill internal buffers.
streamsize __size = _M_file->xsgetn(_M_in_beg, _M_buf_size);
if (0 < __size)
{
......@@ -252,53 +253,7 @@ namespace std
{
// XXX Something is wrong, do error checking.
}
}
#else
// 2000-08-04 bkoz disable
// Part one: (Re)fill external buf (_M_file->_IO_*) from
// external byte sequence (whatever physical byte sink or
// FILE actually is.)
char_type* __conv_buf = static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * _M_buf_size));
streamsize __size = _M_file->xsgetn(__conv_buf, _M_buf_size);
// Part two: (Re)fill internal buf contents from external buf.
if (0 < __size)
{
_M_set_determinate(__size);
char* __conv_cur = __conv_buf;
_M_state_beg = _M_state_cur;
__res_type __r = _M_fcvt->in(_M_state_cur,
__conv_buf,
__conv_buf + __size,
const_cast<const char*&>(__conv_cur),
_M_in_beg, _M_in_end, _M_in_cur);
if (__r == codecvt_base::partial)
{
// XXX Retry with larger _M_buf size.
}
// Set pointers to internal and external buffers
// correctly. . .
if (__r != codecvt_base::error)
{
if (__testout)
_M_out_cur = _M_in_cur;
__ret = traits_type::to_int_type(*_M_in_cur);
}
// Part three: Sync the current internal buffer
// position with the (now overshot) external buffer
// position.
streamoff __p = _M_file->seekoff(0 - __size, ios_base::cur,
ios_base::in);
if (__p == -1)
{
// XXX Something is wrong, do error checking.
}
}
#endif
}
}
}
_M_last_overflowed = false;
......
......@@ -44,24 +44,16 @@ namespace std {
if (!__noskipws && (__in.flags() & ios_base::skipws))
{
const __int_type __eof = traits_type::eof();
__int_type __c = __int_type(0);
__streambuf_type* __sb = __in.rdbuf();
const __ctype_type* __ctype = __in._M_get_fctype_ios();
bool __testsp = true;
bool __testeof = false;
while (!__testeof && __testsp)
{
__c = __sb->sbumpc();
__testeof = __c == __eof;
__testsp = __ctype->is(ctype_base::space, __c);
}
__streambuf_type* __sb = __in.rdbuf();
__int_type __c = __sb->sgetc();
if (!__testeof && !__testsp)
__sb->sputbackc(__c);
while (__c != __eof && __ctype->is(ctype_base::space, __c))
__c = __sb->snextc();
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
//195. Should basic_istream::sentry's constructor ever set eofbit?
else
if (__c == __eof)
__in.setstate(ios_base::eofbit);
#endif
}
......
......@@ -189,15 +189,15 @@ namespace std
switch (__ev)
{
case ios_base::erase_event:
delete static_cast<_Format_cache<_CharT>*> (__p); __p = 0;
delete static_cast<_Format_cache<_CharT>*>(__p);
__p = 0;
break;
case ios_base::copyfmt_event:
// If just stored zero, the callback would get registered again.
try {
__p = new _Format_cache<_CharT>;
}
catch(...) {
}
try
{ __p = new _Format_cache<_CharT>; }
catch(...)
{ }
break;
case ios_base::imbue_event:
static_cast<_Format_cache<_CharT>*>(__p)->_M_valid = false;
......
......@@ -46,7 +46,12 @@ namespace std
typedef _Traits traits_type;
typedef basic_streambuf<_CharT, _Traits> streambuf_type;
typedef basic_ostream<_CharT, _Traits> ostream_type;
private:
streambuf_type* _M_sbuf;
bool _M_failed;
public:
inline
ostreambuf_iterator(ostream_type& __s) throw ()
: _M_sbuf(__s.rdbuf()), _M_failed(!_M_sbuf) { }
......@@ -72,10 +77,6 @@ namespace std
bool
failed() const throw()
{ return _M_failed; }
private:
streambuf_type* _M_sbuf;
bool _M_failed;
};
template<typename _CharT, typename _Traits>
......@@ -90,13 +91,12 @@ namespace std
// 24.5.3 Template class istreambuf_iterator
template<class _CharT, class _Traits>
template<typename _CharT, typename _Traits>
class istreambuf_iterator
: public iterator<input_iterator_tag, _CharT, typename _Traits::off_type,
_CharT*, _CharT&>
{
public:
// Types:
typedef _CharT char_type;
typedef _Traits traits_type;
......@@ -106,6 +106,18 @@ namespace std
// Non-standard Types:
typedef istreambuf_iterator<_CharT, _Traits> __istreambufiter_type;
private:
// 24.5.3 istreambuf_iterator
// p 1
// If the end of stream is reached (streambuf_type::sgetc()
// returns traits_type::eof()), the iterator becomes equal to
// the "end of stream" iterator value.
// NB: This implementation assumes the "end of stream" value
// is EOF, or -1.
streambuf_type* _M_sbuf;
int_type _M_c;
public:
istreambuf_iterator() throw()
: _M_sbuf(NULL), _M_c(-2) { }
......@@ -174,17 +186,6 @@ namespace std
return (__thiseof && __beof || (!__thiseof && !__beof));
}
#endif
private:
// 24.5.3 istreambuf_iterator
// p 1
// If the end of stream is reached (streambuf_type::sgetc()
// returns traits_type::eof()), the iterator becomes equal to
// the "end of stream" iterator value.
// NB: This implementation assumes the "end of stream" value
// is EOF, or -1.
streambuf_type* _M_sbuf;
int_type _M_c;
};
template<typename _CharT, typename _Traits>
......@@ -198,10 +199,5 @@ namespace std
operator!=(const istreambuf_iterator<_CharT, _Traits>& __a,
const istreambuf_iterator<_CharT, _Traits>& __b)
{ return !__a.equal(__b); }
} // namespace std
#endif
......@@ -86,7 +86,8 @@ namespace std
basic_filebuf();
// Non-standard ctor:
basic_filebuf(__c_file_type* __f, bool __s, ios_base::openmode __mode);
basic_filebuf(__c_file_type* __f, ios_base::openmode __mode,
int_type __s = static_cast<int_type>(BUFSIZ));
virtual
~basic_filebuf()
......
......@@ -251,17 +251,20 @@ namespace std
this->setg(_M_buf, _M_buf, _M_buf + __off);
if (__testout)
this->setp(_M_buf, _M_buf + __off);
}
bool
_M_is_indeterminate(void)
{
bool __ret = false;
if (_M_mode & ios_base::in)
__ret = _M_in_beg == _M_in_cur && _M_in_cur == _M_in_end;
if (_M_mode & ios_base::out)
__ret = _M_out_beg == _M_out_cur && _M_out_cur == _M_out_end;
// Don't return true if unbuffered.
if (_M_buf)
{
if (_M_mode & ios_base::in)
__ret = _M_in_beg == _M_in_cur && _M_in_cur == _M_in_end;
if (_M_mode & ios_base::out)
__ret = _M_out_beg == _M_out_cur && _M_out_cur == _M_out_end;
}
return __ret;
}
......@@ -350,7 +353,7 @@ namespace std
{
int_type __ret;
if (_M_in_cur && _M_in_cur < _M_in_end)
__ret = traits_type::to_int_type(*gptr());
__ret = traits_type::to_int_type(*(this->gptr()));
else
__ret = this->underflow();
return __ret;
......
......@@ -136,19 +136,21 @@ namespace std
void
ios_base::Init::_S_ios_create(bool __sync)
{
int __bufsize = __sync ? 0 : static_cast<int>(BUFSIZ);
// NB: The file std_iostream.h creates the four standard files
// with NULL buffers. At this point, we swap out these
new (&cout) ostream(new filebuf(stdout, __sync, ios_base::out));
new (&cin) istream(new filebuf(stdin, __sync, ios_base::in));
new (&cerr) ostream(new filebuf(stderr, __sync, ios_base::out));
// with NULL buffers. At this point, we swap out the dummy NULL
// buffers with the real deal.
new (&cout) ostream(new filebuf(stdout, ios_base::out, __bufsize));
new (&cin) istream(new filebuf(stdin, ios_base::in, 1));
new (&cerr) ostream(new filebuf(stderr, ios_base::out, __bufsize));
new (&clog) ostream(cerr.rdbuf());
cin.tie(&cout);
cerr.flags(ios_base::unitbuf);
#ifdef _GLIBCPP_USE_WCHAR_T
new (&wcout) wostream( new wfilebuf(stdout, __sync, ios_base::out));
new (&wcin) wistream(new wfilebuf(stdin, __sync, ios_base::in));
new (&wcerr) wostream(new wfilebuf(stderr, __sync, ios_base::out));
new (&wcout) wostream( new wfilebuf(stdout, ios_base::out, __bufsize));
new (&wcin) wistream(new wfilebuf(stdin, ios_base::in, 1));
new (&wcerr) wostream(new wfilebuf(stderr, ios_base::out, __bufsize));
new (&wclog) wostream(wcerr.rdbuf());
wcin.tie(&wcout);
wcerr.flags(ios_base::unitbuf);
......
......@@ -676,9 +676,9 @@ namespace std
// Stage 2: extract characters.
__cache_type const* __fmt = __cache_type::_S_get(__io);
bool __valid = __beg != __end;
// Fail quickly if !__valid
if (!__valid)
if (__beg == __end)
{
__err |= (ios_base::eofbit | ios_base::failbit);
return;
......@@ -694,14 +694,19 @@ namespace std
// Check first for sign
bool __testsign = false;
if ((__c == __lits[__cache_type::_S_minus])
|| (__c == __lits[__cache_type::_S_plus]))
|| (__c == __lits[__cache_type::_S_plus]))
{
__testsign = true;
__xtrc[__pos++] = __c;
++__beg;
__testsign = true;
// whitespace may follow a sign
while ((__beg != __end) && (isspace(*__beg)))
++__beg;
__c = * __beg;
// Whitespace may follow a sign
while ((__beg != __end) && (isspace(__c)))
{
++__beg;
__c = *__beg;
}
// There had better be more to come...
if (__beg == __end)
......@@ -712,20 +717,19 @@ namespace std
}
}
bool __testzero = false; // Has there been a leading zero?
// Now check if first character is a zero
__c = *__beg;
// Now check if first character is a zero.
bool __testzero = false;
if (__c == __lits[__cache_type::_S_digits])
{
__testzero = true;
++__beg;
__c = *__beg;
// We have to check for __beg == __end here. If so,
// a plain '0' (possibly with a sign) can be got rid of now
if (__beg == __end)
{
__xtrc[__pos++] = __c;
__xtrc[__pos++] = __lits[__cache_type::_S_digits];
__xtrc[__pos] = '\0';
__err |= ios_base::eofbit;
return;
......@@ -736,11 +740,11 @@ namespace std
if (!__fp && __base != 10 && __base != 8)
{
// Here, __base == 0 or 16
__c = *__beg;
if ((__c == __lits[__cache_type::_S_x])
|| (__c == __lits[__cache_type::_S_X]))
{
++__beg;
__c = *__beg;
__base = 16;
__testzero = false; // "0x" is not a leading zero
}
......@@ -751,9 +755,10 @@ namespace std
// Remove any more leading zeros
while (__beg != __end)
{
if (*__beg == __lits[__cache_type::_S_digits])
if (__c == __lits[__cache_type::_S_digits])
{
++__beg;
__c = *__beg;
__testzero = true;
}
else
......@@ -767,44 +772,45 @@ namespace std
// We may need to know if anything is found here. A leading zero
// (removed by now) would count.
bool __testunits = __testzero;
while (__valid && __beg != __end)
while (__beg != __end)
{
__valid = false;
__c = *__beg;
const char* __p = strchr(__fmt->_S_literals, __c);
const char* __p = strchr(__lits, __c);
// NB: strchr returns true for __c == 0x0
if (__p && __c)
{
// Try first for acceptable digit; record it if found
if ((__p >= &__lits[__cache_type::_S_digits]
&& __p < &__lits[__cache_type::_S_digits + __base])
|| (__p >= &__lits[__cache_type::_S_udigits]
&& __p < &__lits[__cache_type::_S_udigits + __base]))
{
__xtrc[__pos++] = __c;
++__sep_pos;
__valid = true;
__testunits = true;
}
}
else if (__c == __fmt->_M_thousands_sep
&& __fmt->_M_use_grouping)
{
if (__p && __c
&&((__p >= &__lits[__cache_type::_S_digits]
&& __p < &__lits[__cache_type::_S_digits + __base])
|| (__p >= &__lits[__cache_type::_S_udigits]
&& __p < &__lits[__cache_type::_S_udigits + __base])))
{
// Try first for acceptable digit; record it if found.
__xtrc[__pos++] = __c;
++__sep_pos;
__testunits = true;
++__beg;
__c = *__beg;
}
else if (__c == __fmt->_M_thousands_sep && __fmt->_M_use_grouping)
{
// NB: Thousands separator at the beginning of a string
// is a no-no, as is two consecutive thousands
// separators
// separators.
if (__sep_pos)
{
__grp += static_cast<char>(__sep_pos);
__sep_pos = 0;
__valid = true;
++__beg;
__c = *__beg;
}
else
__err |= ios_base::failbit;
{
__err |= ios_base::failbit;
break;
}
}
if (__valid)
++__beg;
else
// Not a valid input item.
break;
}
// Digit grouping is checked. If _M_groupings() doesn't
......@@ -852,7 +858,6 @@ namespace std
// That's it for integer types. Remaining code is for floating point
if (__fp && __beg != __end)
{
__c = *__beg;
// Check first for decimal point. There MUST be one if
// __testunits is false.
bool __testdec = false; // Is there a decimal point
......@@ -861,12 +866,13 @@ namespace std
{
__xtrc[__pos++] = '.';
++__beg;
__c = *__beg;
// Now we get any digits after the decimal point
// There MUST be some if __testunits is false.
while (__beg != __end)
{
__c = *__beg;
const char* __p = strchr(__fmt->_S_literals, __c);
const char* __p = strchr(__lits, __c);
if ((__p >= &__lits[__cache_type::_S_digits]
&& __p < &__lits[__cache_type::_S_digits + __base])
|| (__p >= &__lits[__cache_type::_S_udigits]
......@@ -874,6 +880,7 @@ namespace std
{
__xtrc[__pos++] = __c;
++__beg;
__c = *__beg;
__testdec = true;
}
else
......@@ -892,25 +899,28 @@ namespace std
// Now we may find an exponent
if (__beg != __end)
{
__c = *__beg;
if ((__c == __lits[__cache_type::_S_ee])
|| (__c == __lits[__cache_type::_S_Ee]))
{
__xtrc[__pos++] = __c;
++__beg;
__c = *__beg;
// Now there may be a sign
if (__beg != __end)
{
__c = *__beg;
if ((__c == __lits[__cache_type::_S_minus])
|| (__c == __lits[__cache_type::_S_plus]))
{
__xtrc[__pos++] = __c;
++__beg;
__c = *__beg;
// whitespace may follow a sign
while ((__beg != __end) && (isspace(*__beg)))
++__beg;
while ((__beg != __end) && (isspace(__c)))
{
++__beg;
__c = *__beg;
}
}
}
// And now there must be some digits
......@@ -922,8 +932,7 @@ namespace std
}
while (__beg != __end)
{
__c = *__beg;
const char* __p = strchr(__fmt->_S_literals, __c);
const char* __p = strchr(__lits, __c);
if ((__p >= &__lits[__cache_type::_S_digits]
&& __p < &__lits[__cache_type::_S_digits + __base])
|| (__p >= &__lits[__cache_type::_S_udigits]
......@@ -931,6 +940,7 @@ namespace std
{
__xtrc[__pos++] = __c;
++__beg;
__c = *__beg;
}
else
break;
......
......@@ -546,6 +546,9 @@ public:
operator<(const gnu_char_type& __lhs)
{ return character < __lhs.character; }
// default ctor
gnu_char_type() { }
// to_char_type
gnu_char_type(const unsigned long& __l) : character(__l) { }
......
......@@ -52,7 +52,7 @@ test_01()
FILE* f2 = fopen(name_01, "r");
VERIFY( f2 != NULL );
{
std::filebuf fb(f2, false, std::ios_base::in);
std::filebuf fb(f2, std::ios_base::in, 512);
}
close_num = fclose(f2);
VERIFY( close_num == 0 );
......
// 2000-08-02 bkoz
// Copyright (C) 2000 Free Software Foundation, Inc.
// Copyright (C) 2000, 2001 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
......@@ -93,11 +93,31 @@ test01()
return 0;
}
// libstdc++/2523
void test02()
{
int i;
cin >> i;
cout << "i == " << i << endl;
}
// libstdc++/2523
void test03()
{
ios_base::sync_with_stdio(false);
int i;
cin >> i;
cout << "i == " << i << endl;
}
int
main()
{
test01();
// test02();
// test03();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment