From 130cd3e1df2476eda6e01c82ace326db4f85e24e Mon Sep 17 00:00:00 2001
From: Paolo Carlini <pcarlini@unitus.it>
Date: Mon, 17 Feb 2003 20:05:01 +0100
Subject: [PATCH] re PR libstdc++/9169 (filebuf output fails if codecvt<>::out
 returns noconv)

2003-02-17  Paolo Carlini  <pcarlini@unitus.it>

	PR libstdc++/9169
	* include/bits/fstream.tcc (_M_convert_to_external):
	Deal correctly with noconv, as prescribed by 27.8.1.4,p8.
	* testsuite/27_io/filebuf_virtuals.cc (test10): Add.

From-SVN: r63004
---
 libstdc++-v3/ChangeLog                        |  7 ++++
 libstdc++-v3/include/bits/fstream.tcc         | 10 ++++-
 .../testsuite/27_io/filebuf_virtuals.cc       | 41 +++++++++++++++++++
 3 files changed, 56 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 8901a98b569a..75d729b48214 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,10 @@
+2003-02-17  Paolo Carlini  <pcarlini@unitus.it>
+
+	PR libstdc++/9169
+	* include/bits/fstream.tcc (_M_convert_to_external):
+	Deal correctly with noconv, as prescribed by 27.8.1.4,p8.
+	* testsuite/27_io/filebuf_virtuals.cc (test10): Add.
+
 2003-02-13  Benjamin Kosnik  <bkoz@redhat.com>
 
 	* include/bits/c++config (_GLIBCPP_EXTERN_TEMPLATE): Define.
diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc
index 2c591c389a20..0c6e7b04b6bf 100644
--- a/libstdc++-v3/include/bits/fstream.tcc
+++ b/libstdc++-v3/include/bits/fstream.tcc
@@ -291,9 +291,15 @@ namespace std
 	  const char_type* __iend;
 	  __res_type __r = __cvt.out(_M_state_cur, __ibuf, __ibuf + __ilen, 
 		 		     __iend, __buf, __buf + __blen, __bend);
-	  // Result == ok, partial, noconv
-	  if (__r != codecvt_base::error)
+
+	  if (__r == codecvt_base::ok || __r == codecvt_base::partial)
 	    __blen = __bend - __buf;
+	  // Similarly to the always_noconv case above.
+	  else if (__r == codecvt_base::noconv)
+	    {
+	      __buf = reinterpret_cast<char*>(__ibuf);
+	      __blen = __ilen;
+	    }
 	  // Result == error
 	  else 
 	    __blen = 0;
diff --git a/libstdc++-v3/testsuite/27_io/filebuf_virtuals.cc b/libstdc++-v3/testsuite/27_io/filebuf_virtuals.cc
index 3090f315912d..843038aab482 100644
--- a/libstdc++-v3/testsuite/27_io/filebuf_virtuals.cc
+++ b/libstdc++-v3/testsuite/27_io/filebuf_virtuals.cc
@@ -584,6 +584,46 @@ void test09()
   VERIFY( r == filebuf::traits_type::eof() );
 }
 
+class Cvt_to_upper : public std::codecvt<char, char, mbstate_t>
+{
+  bool do_always_noconv() const throw()
+  {
+    return false;
+  }
+};
+
+// libstdc++/9169
+void test10()
+{
+  using namespace std;
+  bool test = true;
+
+  locale c_loc;
+  locale loc(c_loc, new Cvt_to_upper);
+
+  string str("abcdefghijklmnopqrstuvwxyz");
+  string tmp;
+
+  {
+    ofstream out;
+    out.imbue(loc);
+    out.open("filebuf_virtuals-4.txt");
+    copy(str.begin(), str.end(),
+	 ostreambuf_iterator<char>(out));
+  }
+
+  {
+    ifstream in;
+    in.open("filebuf_virtuals-4.txt");
+    copy(istreambuf_iterator<char>(in),
+	 istreambuf_iterator<char>(),
+	 back_inserter(tmp));
+  }
+
+  VERIFY( tmp.size() == str.size() );
+  VERIFY( tmp == str );
+}
+
 main() 
 {
   test01();
@@ -597,5 +637,6 @@ main()
   test07();
   test08();
   test09();
+  test10();
   return 0;
 }
-- 
GitLab