OSDN Git Service

2003-11-18 Paolo Carlini <pcarlini@suse.de>
authorpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 18 Nov 2003 08:21:38 +0000 (08:21 +0000)
committerpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 18 Nov 2003 08:21:38 +0000 (08:21 +0000)
PR libstdc++/12868
* include/bits/fstream.tcc (imbue): For encodings != -1 it's
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@73697 138bc75d-0d04-0410-961f-82ee72b054a4

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/fstream.tcc
libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/12868.cc [new file with mode: 0644]

index 4bce163..88079fd 100644 (file)
@@ -1,3 +1,15 @@
+2003-11-18  Paolo Carlini  <pcarlini@suse.de>
+
+       PR libstdc++/12868
+       * include/bits/fstream.tcc (imbue): For encodings != -1 it's
+       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.
+
 2003-11-17  Paolo Carlini  <pcarlini@suse.de>
 
        * include/bits/locale_facets.tcc: Fix typo in comment.
index 0104711..0e1e36d 100644 (file)
@@ -269,9 +269,7 @@ namespace std
                  __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 @@ namespace std
                                        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 @@ namespace std
          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 @@ namespace std
                _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 --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/12868.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/12868.cc
new file mode 100644 (file)
index 0000000..8e4484b
--- /dev/null
@@ -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();
+}