📄 codecvt_test.cpp
字号:
while (!istr.eof()); CPPUNIT_ASSERT( istr.eof() ); }# if 0 /* This test is broken, not sure if it is really possible to get a position in * a locale having a codecvt such as generator_codecvt. Maybe generator_codecvt * is not a valid theorical example of codecvt implementation. */ { ifstream istr(fileName); CPPUNIT_ASSERT( istr.good() ); CPPUNIT_ASSERT( !istr.eof() ); generator_codecvt codec(1); locale loc(locale::classic(), &codec); istr.imbue(loc); CPPUNIT_ASSERT( istr.good() ); CPPUNIT_ASSERT( (int)istr.tellg() == 0 ); int theoricalPos = 0; int theoricalTellg; do { char c = istr.get(); if (c == char_traits<char>::eof()) { break; } switch (c) { case 'a': case 'b': theoricalTellg = -1; break; case 'c': ++theoricalPos; default: ++theoricalPos; theoricalTellg = theoricalPos; break; } if ((int)istr.tellg() != theoricalTellg) { CPPUNIT_ASSERT( (int)istr.tellg() == theoricalTellg ); } } while (!istr.eof()); CPPUNIT_ASSERT( istr.eof() ); }# endif#endif}void CodecvtTest::in_out_test(){#if !defined (STLPORT) || !(defined (_STLP_NO_WCHAR_T) || !defined (_STLP_USE_EXCEPTIONS)) try { locale loc(""); typedef codecvt<wchar_t, char, mbstate_t> cdecvt_type; if (has_facet<cdecvt_type>(loc)) { cdecvt_type const& cdect = use_facet<cdecvt_type>(loc); { cdecvt_type::state_type state; memset(&state, 0, sizeof(cdecvt_type::state_type)); string from("abcdef"); const char* next_from; wchar_t to[1]; wchar_t *next_to; cdecvt_type::result res = cdect.in(state, from.data(), from.data() + from.size(), next_from, to, to + sizeof(to) / sizeof(wchar_t), next_to); CPPUNIT_ASSERT( res == cdecvt_type::ok ); CPPUNIT_ASSERT( next_from == from.data() + 1 ); CPPUNIT_ASSERT( next_to == &to[0] + 1 ); CPPUNIT_ASSERT( to[0] == L'a'); } { cdecvt_type::state_type state; memset(&state, 0, sizeof(cdecvt_type::state_type)); wstring from(L"abcdef"); const wchar_t* next_from; char to[1]; char *next_to; cdecvt_type::result res = cdect.out(state, from.data(), from.data() + from.size(), next_from, to, to + sizeof(to) / sizeof(char), next_to); CPPUNIT_ASSERT( res == cdecvt_type::ok ); CPPUNIT_ASSERT( next_from == from.data() + 1 ); CPPUNIT_ASSERT( next_to == &to[0] + 1 ); CPPUNIT_ASSERT( to[0] == 'a'); } } } catch (runtime_error const&) { } catch (...) { CPPUNIT_FAIL; }#endif}void CodecvtTest::length_test(){#if !defined (STLPORT) || !(defined (_STLP_NO_WCHAR_T) || !defined (_STLP_USE_EXCEPTIONS)) try { locale loc(""); typedef codecvt<wchar_t, char, mbstate_t> cdecvt_type; if (has_facet<cdecvt_type>(loc)) { cdecvt_type const& cdect = use_facet<cdecvt_type>(loc); { cdecvt_type::state_type state; memset(&state, 0, sizeof(cdecvt_type::state_type)); string from("abcdef"); int res = cdect.length(state, from.data(), from.data() + from.size(), from.size()); CPPUNIT_ASSERT( (size_t)res == from.size() ); } } } catch (runtime_error const&) { } catch (...) { CPPUNIT_FAIL; }#endif}#if !defined (STLPORT) || !(defined (_STLP_NO_WCHAR_T) || !defined (_STLP_USE_EXCEPTIONS))typedef std::codecvt<wchar_t, char, mbstate_t> my_codecvt_base;class my_codecvt : public my_codecvt_base {public: explicit my_codecvt(size_t r = 0) : my_codecvt_base(r) {}protected: virtual result do_in(state_type& /*state*/, const extern_type* first1, const extern_type* last1, const extern_type*& next1, intern_type* first2, intern_type* last2, intern_type*& next2) const { for ( next1 = first1, next2 = first2; next1 < last1; next1 += 2 ) { if ( (last1 - next1) < 2 || (last2 - next2) < 1 ) return partial; *next2++ = (intern_type)((*(next1 + 1) << 8) | (*next1 & 255)); } return ok; } virtual bool do_always_noconv() const __NO_THROW { return false; } virtual int do_max_length() const __NO_THROW { return 2; } virtual int do_encoding() const __NO_THROW { return 2; }};#endifvoid CodecvtTest::imbue_while_reading(){#if !defined (STLPORT) || !(defined (_STLP_NO_WCHAR_T) || !defined (_STLP_USE_EXCEPTIONS)) { wofstream ofs( "test.txt" ); const wchar_t buf[] = L" "; for ( int i = 0; i < 4098; ++i ) { ofs << buf[0]; } } wifstream ifs("test.txt"); // a file containing 4098 wchars ifs.imbue( locale(locale(), new my_codecvt) ); ifs.get(); ifs.seekg(0); ifs.imbue( locale() ); ifs.ignore(4096); int ch = ifs.get(); CPPUNIT_CHECK( ch != (int)WEOF );#endif}void CodecvtTest::special_encodings(){#if !defined (STLPORT) || (!defined (_STLP_NO_WCHAR_T) && defined (_STLP_USE_EXCEPTIONS)) { locale loc(locale::classic(), new codecvt_byname<wchar_t, char, mbstate_t>("C")); codecvt<wchar_t, char, mbstate_t> const& cvt = use_facet<codecvt<wchar_t, char, mbstate_t> >(loc); mbstate_t state; memset(&state, 0, sizeof(mbstate_t)); char c = '0'; const char *from_next; wchar_t wc; wchar_t *to_next; CPPUNIT_ASSERT( cvt.in(state, &c, &c + 1, from_next, &wc, &wc, to_next) == codecvt_base::ok ); CPPUNIT_ASSERT( to_next == &wc ); CPPUNIT_ASSERT( cvt.in(state, &c, &c + 1, from_next, &wc, &wc + 1, to_next) == codecvt_base::ok ); CPPUNIT_ASSERT( wc == L'0' ); CPPUNIT_ASSERT( to_next == &wc + 1 ); } try { wstring cp936_wstr; const string cp936_str = "\xd6\xd0\xb9\xfa\xc9\xe7\xbb\xe1\xbf\xc6\xd1\xa7\xd4\xba\xb7\xa2\xb2\xbc\x32\x30\x30\x38\xc4\xea\xa1\xb6\xbe\xad\xbc\xc3\xc0\xb6\xc6\xa4\xca\xe9\xa1\xb7\xd6\xb8\xb3\xf6\xa3\xac\x32\x30\x30\x37\xc4\xea\xd6\xd0\xb9\xfa\xbe\xad\xbc\xc3\xd4\xf6\xb3\xa4\xd3\xc9\xc6\xab\xbf\xec\xd7\xaa\xcf\xf2\xb9\xfd\xc8\xc8\xb5\xc4\xc7\xf7\xca\xc6\xc3\xf7\xcf\xd4\xd4\xa4\xbc\xc6\xc8\xab\xc4\xea\x47\x44\x50\xd4\xf6\xcb\xd9\xbd\xab\xb4\xef\x31\x31\x2e\x36\x25\xa1\xa3"; locale loc(locale::classic(), ".936", locale::ctype); codecvt<wchar_t, char, mbstate_t> const& cvt = use_facet<codecvt<wchar_t, char, mbstate_t> >(loc); mbstate_t state; memset(&state, 0, sizeof(mbstate_t)); codecvt_base::result res; { wchar_t wbuf[4096]; // Check we will have enough room for the generated wide string generated from the whole char buffer: int len = cvt.length(state, cp936_str.data(), cp936_str.data() + cp936_str.size(), sizeof(wbuf) / sizeof(wchar_t)); CPPUNIT_ASSERT( cp936_str.size() == (size_t)len ); const char *from_next; wchar_t *to_next; res = cvt.in(state, cp936_str.data(), cp936_str.data() + cp936_str.size(), from_next, wbuf, wbuf + sizeof(wbuf) / sizeof(wchar_t), to_next); CPPUNIT_ASSERT( res == codecvt_base::ok ); CPPUNIT_ASSERT( from_next == cp936_str.data() + cp936_str.size() ); cp936_wstr.assign(wbuf, to_next); } { const wchar_t *from_next; char buf[4096]; char *to_next; res = cvt.out(state, cp936_wstr.data(), cp936_wstr.data() + cp936_wstr.size(), from_next, buf, buf + sizeof(buf), to_next); CPPUNIT_ASSERT( res == codecvt_base::ok ); CPPUNIT_CHECK( string(buf, to_next) == cp936_str ); } } catch (const runtime_error&) { CPPUNIT_MESSAGE("Not enough platform localization support to check 936 code page encoding."); } try { const string utf8_str = "\xe4\xb8\xad\xe5\x9b\xbd\xe7\xa4\xbe\xe4\xbc\x9a\xe7\xa7\x91\xe5\xad\xa6\xe9\x99\xa2\xe5\x8f\x91\xe5\xb8\x83\x32\x30\x30\x38\xe5\xb9\xb4\xe3\x80\x8a\xe7\xbb\x8f\xe6\xb5\x8e\xe8\x93\x9d\xe7\x9a\xae\xe4\xb9\xa6\xe3\x80\x8b\xe6\x8c\x87\xe5\x87\xba\xef\xbc\x8c\x32\x30\x30\x37\xe5\xb9\xb4\xe4\xb8\xad\xe5\x9b\xbd\xe7\xbb\x8f\xe6\xb5\x8e\xe5\xa2\x9e\xe9\x95\xbf\xe7\x94\xb1\xe5\x81\x8f\xe5\xbf\xab\xe8\xbd\xac\xe5\x90\x91\xe8\xbf\x87\xe7\x83\xad\xe7\x9a\x84\xe8\xb6\x8b\xe5\x8a\xbf\xe6\x98\x8e\xe6\x98\xbe\xe9\xa2\x84\xe8\xae\xa1\xe5\x85\xa8\xe5\xb9\xb4\x47\x44\x50\xe5\xa2\x9e\xe9\x80\x9f\xe5\xb0\x86\xe8\xbe\xbe\x31\x31\x2e\x36\x25\xe3\x80\x82"; wstring utf8_wstr; locale loc(locale::classic(), new codecvt_byname<wchar_t, char, mbstate_t>(".utf8")); codecvt<wchar_t, char, mbstate_t> const& cvt = use_facet<codecvt<wchar_t, char, mbstate_t> >(loc); mbstate_t state; memset(&state, 0, sizeof(mbstate_t)); codecvt_base::result res; { wchar_t wbuf[4096]; // Check we will have enough room for the wide string generated from the whole char buffer: int len = cvt.length(state, utf8_str.data(), utf8_str.data() + utf8_str.size(), sizeof(wbuf) / sizeof(wchar_t)); CPPUNIT_ASSERT( utf8_str.size() == (size_t)len ); const char *from_next; wchar_t *to_next; res = cvt.in(state, utf8_str.data(), utf8_str.data() + utf8_str.size(), from_next, wbuf, wbuf + sizeof(wbuf) / sizeof(wchar_t), to_next); CPPUNIT_ASSERT( res == codecvt_base::ok ); CPPUNIT_ASSERT( from_next == utf8_str.data() + utf8_str.size() ); utf8_wstr.assign(wbuf, to_next); // Try to read one char after the other: wchar_t wc; const char* from = utf8_str.data(); const char* from_end = from + utf8_str.size(); from_next = utf8_str.data(); size_t length = 1; size_t windex = 0; while (from + length <= from_end) { res = cvt.in(state, from, from + length, from_next, &wc, &wc + 1, to_next); switch (res) { case codecvt_base::ok: // reset length: from = from_next; length = 1; CPPUNIT_ASSERT( wc == utf8_wstr[windex++] ); wc = 0; break; case codecvt_base::partial: if (from_next == from) // from_next hasn't move so we have to pass more chars ++length; else // char between from and from_next has been eaten, we simply restart // conversion from from_next: from = from_next; continue; case codecvt_base::error: case codecvt_base::noconv: CPPUNIT_FAIL; //break; } } CPPUNIT_ASSERT( windex == utf8_wstr.size() ); } { const wchar_t *from_next; char buf[4096]; char *to_next; res = cvt.out(state, utf8_wstr.data(), utf8_wstr.data() + utf8_wstr.size(), from_next, buf, buf + sizeof(buf), to_next); CPPUNIT_ASSERT( res == codecvt_base::ok ); CPPUNIT_CHECK( string(buf, to_next) == utf8_str ); } { // Check that an obviously wrong UTF8 encoded string is correctly detected: const string bad_utf8_str("\xdf\xdf\xdf\xdf\xdf"); wchar_t wc; const char *from_next; wchar_t *to_next; res = cvt.in(state, bad_utf8_str.data(), bad_utf8_str.data() + bad_utf8_str.size(), from_next, &wc, &wc + 1, to_next); CPPUNIT_ASSERT( res == codecvt_base::error ); } } catch (const runtime_error&) { CPPUNIT_MESSAGE("Not enough platform localization support to check UTF8 encoding."); }#endif}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -