This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hi, This patch adds a new stream buffer class, wstdiobuf, for use with wcin. This is a template so it can be easily extended to narrow characters as well. Benefits over stdio_filebuf include: * Fully syncronized with stdin. It is possible to mix operations on wcin with wide character operations on stdin. * sgetc() no longer corrupts the stream (libstdc++/9520). * Much faster than both buffered and unbuffered stdio_filebuf (for 3.4 at least). * Handles multibyte character sets. Testsuite files are attached, tested on linux on x86. Petur 2003-02-23 Petur Runolfsson <peturr02 at ru dot is> PR libstdc++/9520 * include/Makefile.am (ext_headers): Add ext/stdiobuf.h. * include/ext/stdiobuf.h: New file. * src/ext-inst.cc: Add stdiobuf instantiation. * src/globals.cc: Change type of buf_wcin to wstdiobuf. * src/ios.cc (ios_base::Init::_S_ios_create, ios_base::Init::_S_ios_destroy): Likewise. Index: include/Makefile.am =================================================================== RCS file: /home/petur/cvsroot/gcc/libstdc++-v3/include/Makefile.am,v retrieving revision 1.1.1.1 diff -c -3 -p -r1.1.1.1 Makefile.am *** include/Makefile.am 15 Feb 2003 18:16:18 -0000 1.1.1.1 --- include/Makefile.am 21 Feb 2003 13:46:18 -0000 *************** ext_headers = \ *** 226,231 **** --- 226,232 ---- ${ext_srcdir}/rope \ ${ext_srcdir}/ropeimpl.h \ ${ext_srcdir}/slist \ + ${ext_srcdir}/stdiobuf.h \ ${ext_srcdir}/stl_hash_fun.h \ ${ext_srcdir}/stl_hashtable.h \ ${ext_srcdir}/stl_rope.h Index: include/ext/stdiobuf.h =================================================================== RCS file: include/ext/stdiobuf.h diff -N include/ext/stdiobuf.h *** /dev/null 1 Jan 1970 00:00:00 -0000 --- include/ext/stdiobuf.h 21 Feb 2003 16:07:06 -0000 *************** *** 0 **** --- 1,131 ---- + // Syncronized stream buffer for FILEs -*- C++ -*- + + // Copyright (C) 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. + + // As a special exception, you may use this file as part of a free software + // library without restriction. Specifically, if other files instantiate + // templates or use macros or inline functions from this file, or you compile + // this file and link it with other files to produce an executable, this + // file does not by itself cause the resulting executable to be covered by + // the GNU General Public License. This exception does not however + // invalidate any other reasons why the executable file might be covered by + // the GNU General Public License. + + /** @file ext/stdiobuf.h + * This file is a GNU extension to the Standard C++ Library. + */ + + #ifndef _EXT_STDIOBUF_H + #define _EXT_STDIOBUF_H + + #pragma GCC system_header + #include <streambuf> + #include <cwchar> + #include <cstdio> + + namespace __gnu_cxx + { + // Simple wrapper for FILE* that encapsulates differences between + // char and wchar_t based functions. + template<typename _CharT> + class _Stdio_file; + + #ifdef _GLIBCPP_USE_WCHAR_T + template<> + class _Stdio_file<wchar_t> + { + public: + explicit _Stdio_file(std::FILE* __file) + : _M_file(__file) + { } + + std::wint_t sbumpc() + { return std::getwc(_M_file); } + + std::wint_t sputbackc(std::wint_t __c) + { return std::ungetwc(__c, _M_file); } + + std::size_t sgetn(wchar_t* __s, std::size_t __n) + { + std::size_t __ret = 0; + while (__ret < __n) + { + std::wint_t __c = std::getwc(_M_file); + if (__c == WEOF) + break; + __s[__ret] = __c; + __ret++; + } + return __ret; + } + + private: + std::FILE* _M_file; + }; + #endif + + // Fully syncronized stream buffer for FILEs + // "Syncronized" means: + // * sbumpc() is equivalent to get[w]c(f) + // * sputbackc(c) is equivalent to unget[w]c(c, f) + // * sgetc() is equivalent to unget[w]c(get[w]c(f), f) + // There is no traits parameter since this requires that + // traits_type::eof() == [W]EOF and int_type == int|wint_t + template<typename _CharT> + class basic_stdiobuf : public std::basic_streambuf<_CharT> + { + public: + typedef _CharT char_type; + typedef typename std::basic_streambuf<_CharT>::traits_type traits_type; + typedef typename traits_type::int_type int_type; + + private: + _Stdio_file<_CharT> _M_stdio_file; + + public: + explicit basic_stdiobuf(std::FILE* __file) + : _M_stdio_file(__file) + { } + + virtual ~basic_stdiobuf() + { } + + protected: + virtual int_type underflow() + { + int_type __c = _M_stdio_file.sbumpc(); + return _M_stdio_file.sputbackc(__c); + } + + virtual int_type uflow() + { return _M_stdio_file.sbumpc(); } + + virtual std::streamsize xsgetn(char_type* __s, std::streamsize __n) + { return _M_stdio_file.sgetn(__s, __n); } + + virtual int_type pbackfail(int_type __c = traits_type::eof()) + { return _M_stdio_file.sputbackc(__c); } + }; + + #ifdef _GLIBCPP_USE_WCHAR_T + typedef basic_stdiobuf<wchar_t> wstdiobuf; + #endif + } // namespace __gnu_cxx + + #endif /* _EXT_STDIOBUF_H */ Index: src/ext-inst.cc =================================================================== RCS file: /home/petur/cvsroot/gcc/libstdc++-v3/src/ext-inst.cc,v retrieving revision 1.1.1.1 diff -c -3 -p -r1.1.1.1 ext-inst.cc *** src/ext-inst.cc 15 Feb 2003 18:16:19 -0000 1.1.1.1 --- src/ext-inst.cc 21 Feb 2003 16:22:24 -0000 *************** *** 1,6 **** // Explicit instantiation file. ! // Copyright (C) 2001, 2002 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 --- 1,6 ---- // Explicit instantiation file. ! // 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 *************** *** 33,38 **** --- 33,39 ---- #include <ext/rope> #include <ext/stdio_filebuf.h> + #include <ext/stdiobuf.h> namespace __gnu_cxx { *************** namespace __gnu_cxx *** 58,62 **** --- 59,65 ---- _S_fetch(_Rope_RopeRep<wchar_t, std::allocator<wchar_t> >*, size_type); template class stdio_filebuf<wchar_t>; + + template class basic_stdiobuf<wchar_t>; #endif } // namespace __gnu_cxx Index: src/globals.cc =================================================================== RCS file: /home/petur/cvsroot/gcc/libstdc++-v3/src/globals.cc,v retrieving revision 1.1.1.1 diff -c -3 -p -r1.1.1.1 globals.cc *** src/globals.cc 15 Feb 2003 18:16:19 -0000 1.1.1.1 --- src/globals.cc 21 Feb 2003 16:03:06 -0000 *************** *** 32,37 **** --- 32,38 ---- #include <ostream> #include <locale> #include <ext/stdio_filebuf.h> + #include <ext/stdiobuf.h> // On AIX, and perhaps other systems, library initialization order is // not guaranteed. For example, the static initializers for the main *************** namespace __gnu_cxx *** 199,206 **** typedef char fake_wfilebuf[sizeof(stdio_filebuf<wchar_t>)] __attribute__ ((aligned(__alignof__(stdio_filebuf<wchar_t>)))); fake_wfilebuf buf_wcout; - fake_wfilebuf buf_wcin; fake_wfilebuf buf_wcerr; #endif // Globals for once-only runtime initialization of mutex objects. This --- 200,210 ---- typedef char fake_wfilebuf[sizeof(stdio_filebuf<wchar_t>)] __attribute__ ((aligned(__alignof__(stdio_filebuf<wchar_t>)))); fake_wfilebuf buf_wcout; fake_wfilebuf buf_wcerr; + + typedef char fake_wstdiobuf[sizeof(wstdiobuf)] + __attribute__ ((aligned(__alignof__(wstdiobuf)))); + fake_wstdiobuf buf_wcin; #endif // Globals for once-only runtime initialization of mutex objects. This Index: src/ios.cc =================================================================== RCS file: /home/petur/cvsroot/gcc/libstdc++-v3/src/ios.cc,v retrieving revision 1.1.1.2 diff -c -3 -p -r1.1.1.2 ios.cc *** src/ios.cc 22 Feb 2003 15:51:20 -0000 1.1.1.2 --- src/ios.cc 22 Feb 2003 15:55:12 -0000 *************** *** 38,43 **** --- 38,44 ---- #include <fstream> #include <bits/atomicity.h> #include <ext/stdio_filebuf.h> + #include <ext/stdiobuf.h> #ifdef _GLIBCPP_HAVE_UNISTD_H #include <unistd.h> #endif *************** namespace __gnu_cxx *** 51,57 **** #ifdef _GLIBCPP_USE_WCHAR_T extern stdio_filebuf<wchar_t> buf_wcout; ! extern stdio_filebuf<wchar_t> buf_wcin; extern stdio_filebuf<wchar_t> buf_wcerr; #endif } // namespace __gnu_cxx --- 52,58 ---- #ifdef _GLIBCPP_USE_WCHAR_T extern stdio_filebuf<wchar_t> buf_wcout; ! extern wstdiobuf buf_wcin; extern stdio_filebuf<wchar_t> buf_wcerr; #endif } // namespace __gnu_cxx *************** namespace std *** 182,188 **** #ifdef _GLIBCPP_USE_WCHAR_T new (&buf_wcout) stdio_filebuf<wchar_t>(stdout, ios_base::out, __out_size); ! new (&buf_wcin) stdio_filebuf<wchar_t>(stdin, ios_base::in, __in_size); new (&buf_wcerr) stdio_filebuf<wchar_t>(stderr, ios_base::out, __out_size); new (&wcout) wostream(&buf_wcout); new (&wcin) wistream(&buf_wcin); --- 183,189 ---- #ifdef _GLIBCPP_USE_WCHAR_T new (&buf_wcout) stdio_filebuf<wchar_t>(stdout, ios_base::out, __out_size); ! new (&buf_wcin) wstdiobuf(stdin); new (&buf_wcerr) stdio_filebuf<wchar_t>(stderr, ios_base::out, __out_size); new (&wcout) wostream(&buf_wcout); new (&wcin) wistream(&buf_wcin); *************** namespace std *** 205,211 **** #ifdef _GLIBCPP_USE_WCHAR_T buf_wcout.~stdio_filebuf(); ! buf_wcin.~stdio_filebuf(); buf_wcerr.~stdio_filebuf(); #endif } --- 206,212 ---- #ifdef _GLIBCPP_USE_WCHAR_T buf_wcout.~stdio_filebuf(); ! buf_wcin.~wstdiobuf(); buf_wcerr.~stdio_filebuf(); #endif }
Attachment:
testsuite.tar.gz
Description: testsuite.tar.gz
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |