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]

[Patch] Fix libstdc++/12868


Hi,

I may be wrong, but in the current framework seems really easy to
fix the problem: seekoff does everything needed and we have only
to take care dealing correctly with codecvt.in returning error
while __iend - this->eback() > 0.

Tested x86-linux. OK with everyone?

Paolo.

////////////
2003-11-16  Paolo Carlini  <pcarlini@suse.de>

	PR libstdc++/12868
	* include/bits/fstream.tcc (imbue): For encodings != -1 is
	always ok to imbue a new locale, provided seekoff(0, cur, ...)
	doesn't fail, of course.
	(underflow): In order for the above to work, deal gracefully
	with _M_codecvt->in returning codecvt_base::error while 
	(__ilen = __iend - this->eback()) > 0: it just means __ilen
	correctly converted internal characters before an error.	
	* testsuite/27_io/basic_filebuf/imbue/wchar_t/12868.cc: New.
diff -urN libstdc++-v3-orig/include/bits/fstream.tcc libstdc++-v3/include/bits/fstream.tcc
--- libstdc++-v3-orig/include/bits/fstream.tcc	2003-11-13 10:46:09.000000000 +0100
+++ libstdc++-v3/include/bits/fstream.tcc	2003-11-16 15:07:30.000000000 +0100
@@ -269,9 +269,7 @@
 		  __r = _M_codecvt->in(_M_state_cur, _M_ext_next,
 				       _M_ext_end, _M_ext_next, this->eback(), 
 				       this->eback() + __buflen, __iend);
-		  if (__r == codecvt_base::ok || __r == codecvt_base::partial)
-		    __ilen = __iend - this->eback();
-		  else if (__r == codecvt_base::noconv)
+		  if (__r == codecvt_base::noconv)
 		    {
 		      size_t __avail = _M_ext_end - _M_ext_buf;
 		      __ilen = std::min(__avail, __buflen);
@@ -279,11 +277,15 @@
 					reinterpret_cast<char_type*>(_M_ext_buf), __ilen);
 		      _M_ext_next = _M_ext_buf + __ilen;
 		    }
-		  else 
-		    {
-		      __ilen = 0;
-		      break;
-		    }
+		  else
+		    __ilen = __iend - this->eback();
+		  
+		  // _M_codecvt->in may return error while __ilen > 0: this is
+		  // ok, and actually occurs in case of mixed encodings (e.g.,
+		  // XML files).
+		  if (__r == codecvt_base::error)
+		    break;
+
 		  __rlen = 1;
 		}
 	      while (!__got_eof && __ilen == 0);
@@ -747,13 +749,13 @@
 	  bool __testfail = false;
 	  if (this->is_open())
 	    {
-	      const bool __testbeg =
+	      const bool __testseek =
 		this->seekoff(0, ios_base::cur, this->_M_mode) ==
-		pos_type(off_type(0));
+		pos_type(off_type(-1));
 	      const bool __teststate =
 		__check_facet(_M_codecvt).encoding() == -1;
 
-	      __testfail = !__testbeg || __teststate;
+	      __testfail = __testseek || __teststate;
 	    }
 
 	  if (!__testfail)
@@ -762,13 +764,6 @@
 		_M_codecvt = &use_facet<__codecvt_type>(__loc);
 	      else
 		_M_codecvt = 0;
-
-	      // NB This may require the reconversion of previously
-	      // converted chars. This in turn may cause the
-	      // reconstruction of the original file. YIKES!!  This
-	      // implementation interprets this requirement as requiring
-	      // the file position be at the beginning, and a stateless
-	      // encoding, or that the filebuf be closed. Opinions may differ.
 	    }
 	}
     }
diff -urN libstdc++-v3-orig/testsuite/27_io/basic_filebuf/imbue/wchar_t/12868.cc libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/12868.cc
--- libstdc++-v3-orig/testsuite/27_io/basic_filebuf/imbue/wchar_t/12868.cc	1970-01-01 01:00:00.000000000 +0100
+++ libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/12868.cc	2003-11-16 15:30:24.000000000 +0100
@@ -0,0 +1,60 @@
+// 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.
+
+// 27.8.1.4 Overridden virtual functions
+
+#include <ostream>
+#include <fstream>
+#include <locale>
+#include <string>
+#include <testsuite_hooks.h>
+
+// libstdc++/12868
+void test01()
+{
+  using namespace std;
+  bool test __attribute__((unused)) = true;
+
+  locale loc_is(__gnu_test::try_named_locale("is_IS"));
+  
+  {
+    wofstream out("tmp_12868");
+    out << L"<? xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
+    out.imbue(loc_is);
+    VERIFY( out.rdbuf()->getloc() == loc_is );
+    out << L"<greeting>Hall\u00f3 heimur</greeting>\n";
+  }
+
+  {
+    wifstream in("tmp_12868");
+    wstring str;
+    getline(in, str);
+    if (str.find(L"encoding=\"UTF-8\"") != wstring::npos)
+      {
+	in.imbue(loc_is);
+	VERIFY( in.rdbuf()->getloc() == loc_is );
+      }
+    getline(in, str);
+    VERIFY( str == L"<greeting>Hall\u00f3 heimur</greeting>" );
+  }
+}
+
+int main()
+{
+  test01();
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]