From 9933260f2f921ab10415b5042fc5f04fe1afce95 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Thu, 5 Mar 2015 13:36:21 +0000 Subject: [PATCH] locale_conv.h (wstring_convert::_M_conv): Handle noconv result. * include/bits/locale_conv.h (wstring_convert::_M_conv): Handle noconv result. * testsuite/22_locale/conversions/string/2.cc: Also test UTF-8. * testsuite/22_locale/conversions/string/3.cc: Likewise, and UTF-16. From-SVN: r221212 --- libstdc++-v3/ChangeLog | 7 +++ libstdc++-v3/include/bits/locale_conv.h | 7 +++ .../22_locale/conversions/string/2.cc | 21 +++++++- .../22_locale/conversions/string/3.cc | 48 ++++++++++++++++++- 4 files changed, 81 insertions(+), 2 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 16760dade1e..ed4edf8b89f 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,10 @@ +2015-03-05 Jonathan Wakely + + * include/bits/locale_conv.h (wstring_convert::_M_conv): Handle + noconv result. + * testsuite/22_locale/conversions/string/2.cc: Also test UTF-8. + * testsuite/22_locale/conversions/string/3.cc: Likewise, and UTF-16. + 2015-03-04 Jonathan Wakely PR libstdc++/64797 diff --git a/libstdc++-v3/include/bits/locale_conv.h b/libstdc++-v3/include/bits/locale_conv.h index b53754d1541..9b49617b7a9 100644 --- a/libstdc++-v3/include/bits/locale_conv.h +++ b/libstdc++-v3/include/bits/locale_conv.h @@ -213,6 +213,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION while (__result == codecvt_base::partial && __next != __last && (__outstr.size() - __outchars) < __maxlen); + if (__result == codecvt_base::noconv) + { + __outstr.assign(__first, __last); + _M_count = __outstr.size(); + return __outstr; + } + __outstr.resize(__outchars); _M_count = __next - __first; diff --git a/libstdc++-v3/testsuite/22_locale/conversions/string/2.cc b/libstdc++-v3/testsuite/22_locale/conversions/string/2.cc index 07d2b520e97..9341f8928c4 100644 --- a/libstdc++-v3/testsuite/22_locale/conversions/string/2.cc +++ b/libstdc++-v3/testsuite/22_locale/conversions/string/2.cc @@ -36,6 +36,24 @@ using std::u32string; // test conversion errors, with and without error strings void test01() +{ + typedef str_conv sc; + + const sc::byte_string berr = "invalid wide string"; + const sc::wide_string werr = u8"invalid byte string"; + + sc c(berr, werr); + string input = "Stop"; + input += char(0xFF); + string woutput = c.from_bytes(input); + VERIFY( input == woutput ); // noconv case doesn't detect invalid input + string winput = u8"Stop"; + winput += char(0xFF); + string output = c.to_bytes(winput); + VERIFY( winput == output ); // noconv case doesn't detect invalid input +} + +void test02() { typedef str_conv sc; @@ -53,7 +71,7 @@ void test01() VERIFY( berr == output ); } -void test02() +void test03() { typedef str_conv sc; @@ -75,4 +93,5 @@ int main() { test01(); test02(); + test03(); } diff --git a/libstdc++-v3/testsuite/22_locale/conversions/string/3.cc b/libstdc++-v3/testsuite/22_locale/conversions/string/3.cc index 7c4ac207cd8..6afa62ba2d1 100644 --- a/libstdc++-v3/testsuite/22_locale/conversions/string/3.cc +++ b/libstdc++-v3/testsuite/22_locale/conversions/string/3.cc @@ -30,11 +30,54 @@ template using str_conv = std::wstring_convert, Elem>; using std::string; +using std::u16string; using std::u32string; // test construction with state, for partial conversions void test01() +{ + typedef str_conv wsc; + + wsc c; + string input = u8"\u00a3 shillings pence"; + string woutput = c.from_bytes(input.substr(0, 1)); + auto partial_state = c.state(); + auto partial_count = c.converted(); + + auto woutput2 = c.from_bytes(u8"state reset on next conversion"); + VERIFY( woutput2 == u8"state reset on next conversion" ); + + wsc c2(new cvt, partial_state); + woutput += c2.from_bytes(input.substr(partial_count)); + VERIFY( u8"\u00a3 shillings pence" == woutput ); + + string roundtrip = c2.to_bytes(woutput); + VERIFY( input == roundtrip ); +} + +void test02() +{ + typedef str_conv wsc; + + wsc c; + string input = u8"\u00a3 shillings pence"; + u16string woutput = c.from_bytes(input.substr(0, 1)); + auto partial_state = c.state(); + auto partial_count = c.converted(); + + auto woutput2 = c.from_bytes(u8"state reset on next conversion"); + VERIFY( woutput2 == u"state reset on next conversion" ); + + wsc c2(new cvt, partial_state); + woutput += c2.from_bytes(input.substr(partial_count)); + VERIFY( u"\u00a3 shillings pence" == woutput ); + + string roundtrip = c2.to_bytes(woutput); + VERIFY( input == roundtrip ); +} + +void test03() { typedef str_conv wsc; @@ -44,7 +87,7 @@ void test01() auto partial_state = c.state(); auto partial_count = c.converted(); - auto woutput2 = c.from_bytes("state reset on next conversion"); + auto woutput2 = c.from_bytes(u8"state reset on next conversion"); VERIFY( woutput2 == U"state reset on next conversion" ); wsc c2(new cvt, partial_state); @@ -55,7 +98,10 @@ void test01() VERIFY( input == roundtrip ); } + int main() { test01(); + test02(); + test03(); } -- 2.30.2