+ size_t len;
+
+#if wxUSE_UNICODE
+ wxConvLibc.cWC2MB(L"", 0, &len);
+#else // !wxUSE_UNICODE
+ wxConvLibc.cMB2WC("", 0, &len);
+#endif // wxUSE_UNICODE/!wxUSE_UNICODE
+
+ CPPUNIT_ASSERT_EQUAL( 0, len );
+
+#if wxUSE_UNICODE
+ // check that when we convert a fixed number of characters we obtain the
+ // expected return value
+ CPPUNIT_ASSERT_EQUAL( 0, wxConvLibc.ToWChar(NULL, 0, "", 0) );
+ CPPUNIT_ASSERT_EQUAL( 1, wxConvLibc.ToWChar(NULL, 0, "x", 1) );
+ CPPUNIT_ASSERT_EQUAL( 2, wxConvLibc.ToWChar(NULL, 0, "x", 2) );
+ CPPUNIT_ASSERT_EQUAL( 2, wxConvLibc.ToWChar(NULL, 0, "xy", 2) );
+#endif // wxUSE_UNICODE
+}
+
+void UnicodeTestCase::ConversionWithNULs()
+{
+#if wxUSE_UNICODE
+ static const size_t lenNulString = 10;
+
+ wxString szTheString(L"The\0String", wxConvLibc, lenNulString);
+ wxCharBuffer theBuffer = szTheString.mb_str();
+
+ CPPUNIT_ASSERT( memcmp(theBuffer.data(), "The\0String",
+ lenNulString + 1) == 0 );
+
+ wxString szTheString2("The\0String", wxConvLocal, lenNulString);
+ CPPUNIT_ASSERT_EQUAL( lenNulString, szTheString2.length() );
+ CPPUNIT_ASSERT( wxTmemcmp(szTheString2.c_str(), L"The\0String",
+ lenNulString + 1) == 0 );
+#else // !wxUSE_UNICODE
+ wxString szTheString("TheString");
+ szTheString.insert(3, 1, '\0');
+ wxWCharBuffer theBuffer = szTheString.wc_str(wxConvLibc);
+
+ CPPUNIT_ASSERT( memcmp(theBuffer.data(), L"The\0String", 11 * sizeof(wchar_t)) == 0 );
+
+ wxString szLocalTheString("TheString");
+ szLocalTheString.insert(3, 1, '\0');
+ wxWCharBuffer theLocalBuffer = szLocalTheString.wc_str(wxConvLocal);
+
+ CPPUNIT_ASSERT( memcmp(theLocalBuffer.data(), L"The\0String", 11 * sizeof(wchar_t)) == 0 );
+#endif // wxUSE_UNICODE/!wxUSE_UNICODE
+}
+
+void UnicodeTestCase::ConversionUTF7()
+{
+ static const StringConversionData utf7data[] =
+ {
+ // normal fragments
+ StringConversionData("+AKM-", L"\xa3"),
+ StringConversionData("+AOk-t+AOk-", L"\xe9t\xe9"),
+
+ // this one is an alternative valid encoding of the same string
+ StringConversionData("+AOk-t+AOk", L"\xe9t\xe9",
+ StringConversionData::ONLY_MB2WC),
+
+ // some special cases
+ StringConversionData("+-", L"+"),
+ StringConversionData("+--", L"+-"),
+
+ // the following are invalid UTF-7 sequences
+ StringConversionData("\xa3", NULL),
+ StringConversionData("+", NULL),
+ StringConversionData("+~", NULL),
+ StringConversionData("a+", NULL),
+ };
+
+ for ( size_t n = 0; n < WXSIZEOF(utf7data); n++ )
+ {
+ const StringConversionData& d = utf7data[n];
+
+ // converting to/from UTF-7 using iconv() currently doesn't work
+ // because of several problems:
+ // - GetMBNulLen() doesn't return correct result (iconv converts L'\0'
+ // to an incomplete and anyhow nonsensical "+AA" string)
+ // - iconv refuses to convert "+-" (although it converts "+-\n" just
+ // fine, go figure)
+ //
+ // I have no idea how to fix this so just disable the test for now
+#if 0
+ d.Test(n, wxCSConv("utf-7"));
+#endif
+ d.Test(n, wxConvUTF7);
+ }
+}
+
+void UnicodeTestCase::ConversionUTF8()
+{
+ static const StringConversionData utf8data[] =
+ {
+#ifdef wxHAVE_U_ESCAPE
+ StringConversionData("\xc2\xa3", L"\u00a3"),
+#endif
+ StringConversionData("\xc2", NULL),
+ };
+
+ wxCSConv conv(wxT("utf-8"));
+ for ( size_t n = 0; n < WXSIZEOF(utf8data); n++ )
+ {
+ const StringConversionData& d = utf8data[n];
+ d.Test(n, conv);
+ d.Test(n, wxConvUTF8);
+ }
+}
+
+void UnicodeTestCase::ConversionUTF16()
+{
+ static const StringConversionData utf16data[] =
+ {
+#ifdef wxHAVE_U_ESCAPE
+ StringConversionData(
+ "\x04\x1f\x04\x40\x04\x38\x04\x32\x04\x35\x04\x42\0\0",
+ L"\u041f\u0440\u0438\u0432\u0435\u0442"),
+ StringConversionData(
+ "\x01\0\0b\x01\0\0a\x01\0\0r\0\0",
+ L"\u0100b\u0100a\u0100r"),
+#endif
+ StringConversionData("\0f\0o\0o\0\0", L"foo"),