michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include michael@0: #include "nsXPCOM.h" michael@0: #include "nsIEntityConverter.h" michael@0: #include "nsISaveAsCharset.h" michael@0: #include "nsCOMPtr.h" michael@0: #include "nsIUnicodeNormalizer.h" michael@0: #include "nsStringAPI.h" michael@0: #include "nsUnicharUtils.h" michael@0: #include "nsMemory.h" michael@0: #include "nsComponentManagerUtils.h" michael@0: #include "nsServiceManagerUtils.h" michael@0: michael@0: NS_DEFINE_CID(kEntityConverterCID, NS_ENTITYCONVERTER_CID); michael@0: NS_DEFINE_CID(kSaveAsCharsetCID, NS_SAVEASCHARSET_CID); michael@0: NS_DEFINE_CID(kUnicodeNormalizerCID, NS_UNICODE_NORMALIZER_CID); michael@0: michael@0: #define TESTLEN 32 michael@0: #define T2LEN TESTLEN michael@0: #define T3LEN TESTLEN michael@0: #define T4LEN TESTLEN michael@0: michael@0: // test data for ToUpper michael@0: static char16_t t2data [T2LEN+1] = { michael@0: 0x0031 , // 0 michael@0: 0x0019 , // 1 michael@0: 0x0043 , // 2 michael@0: 0x0067 , // 3 michael@0: 0x00C8 , // 4 michael@0: 0x00E9 , // 5 michael@0: 0x0147 , // 6 michael@0: 0x01C4 , // 7 michael@0: 0x01C6 , // 8 michael@0: 0x01C5 , // 9 michael@0: 0x03C0 , // 10 michael@0: 0x03B2 , // 11 michael@0: 0x0438 , // 12 michael@0: 0x04A5 , // 13 michael@0: 0x05D0 , // 14 michael@0: 0x0A20 , // 15 michael@0: 0x30B0 , // 16 michael@0: 0x5185 , // 17 michael@0: 0xC021 , // 18 michael@0: 0xFF48 , // 19 michael@0: 0x01C7 , // 20 michael@0: 0x01C8 , // 21 michael@0: 0x01C9 , // 22 michael@0: 0x01CA , // 23 michael@0: 0x01CB , // 24 michael@0: 0x01CC , // 25 michael@0: 0x01F1 , // 26 michael@0: 0x01F2 , // 27 michael@0: 0x01F3 , // 28 michael@0: 0x0250 , // 29 michael@0: 0x0271 , // 30 michael@0: 0xA641 , // 31 michael@0: 0x00 michael@0: }; michael@0: // expected result for ToUpper michael@0: static char16_t t2result[T2LEN+1] = { michael@0: 0x0031 , // 0 michael@0: 0x0019 , // 1 michael@0: 0x0043 , // 2 michael@0: 0x0047 , // 3 michael@0: 0x00C8 , // 4 michael@0: 0x00C9 , // 5 michael@0: 0x0147 , // 6 michael@0: 0x01C4 , // 7 michael@0: 0x01C4 , // 8 michael@0: 0x01C4 , // 9 michael@0: 0x03A0 , // 10 michael@0: 0x0392 , // 11 michael@0: 0x0418 , // 12 michael@0: 0x04A4 , // 13 michael@0: 0x05D0 , // 14 michael@0: 0x0A20 , // 15 michael@0: 0x30B0 , // 16 michael@0: 0x5185 , // 17 michael@0: 0xC021 , // 18 michael@0: 0xFF28 , // 19 michael@0: 0x01C7 , // 20 michael@0: 0x01C7 , // 21 michael@0: 0x01C7 , // 22 michael@0: 0x01CA , // 23 michael@0: 0x01CA , // 24 michael@0: 0x01CA , // 25 michael@0: 0x01F1 , // 26 michael@0: 0x01F1 , // 27 michael@0: 0x01F1 , // 28 michael@0: 0x2C6F , // 29 michael@0: 0x2C6E , // 30 michael@0: 0xA640 , // 31 michael@0: 0x00 michael@0: }; michael@0: // test data for ToLower michael@0: static char16_t t3data [T3LEN+1] = { michael@0: 0x0031 , // 0 michael@0: 0x0019 , // 1 michael@0: 0x0043 , // 2 michael@0: 0x0067 , // 3 michael@0: 0x00C8 , // 4 michael@0: 0x00E9 , // 5 michael@0: 0x0147 , // 6 michael@0: 0x01C4 , // 7 michael@0: 0x01C6 , // 8 michael@0: 0x01C5 , // 9 michael@0: 0x03A0 , // 10 michael@0: 0x0392 , // 11 michael@0: 0x0418 , // 12 michael@0: 0x04A4 , // 13 michael@0: 0x05D0 , // 14 michael@0: 0x0A20 , // 15 michael@0: 0x30B0 , // 16 michael@0: 0x5187 , // 17 michael@0: 0xC023 , // 18 michael@0: 0xFF28 , // 19 michael@0: 0x01C7 , // 20 michael@0: 0x01C8 , // 21 michael@0: 0x01C9 , // 22 michael@0: 0x01CA , // 23 michael@0: 0x01CB , // 24 michael@0: 0x01CC , // 25 michael@0: 0x01F1 , // 26 michael@0: 0x01F2 , // 27 michael@0: 0x01F3 , // 28 michael@0: 0x2C6F , // 29 michael@0: 0x2C6E , // 30 michael@0: 0xA640 , // 31 michael@0: 0x00 michael@0: }; michael@0: // expected result for ToLower michael@0: static char16_t t3result[T3LEN+1] = { michael@0: 0x0031 , // 0 michael@0: 0x0019 , // 1 michael@0: 0x0063 , // 2 michael@0: 0x0067 , // 3 michael@0: 0x00E8 , // 4 michael@0: 0x00E9 , // 5 michael@0: 0x0148 , // 6 michael@0: 0x01C6 , // 7 michael@0: 0x01C6 , // 8 michael@0: 0x01C6 , // 9 michael@0: 0x03C0 , // 10 michael@0: 0x03B2 , // 11 michael@0: 0x0438 , // 12 michael@0: 0x04A5 , // 13 michael@0: 0x05D0 , // 14 michael@0: 0x0A20 , // 15 michael@0: 0x30B0 , // 16 michael@0: 0x5187 , // 17 michael@0: 0xC023 , // 18 michael@0: 0xFF48 , // 19 michael@0: 0x01C9 , // 20 michael@0: 0x01C9 , // 21 michael@0: 0x01C9 , // 22 michael@0: 0x01CC , // 23 michael@0: 0x01CC , // 24 michael@0: 0x01CC , // 25 michael@0: 0x01F3 , // 26 michael@0: 0x01F3 , // 27 michael@0: 0x01F3 , // 28 michael@0: 0x0250 , // 29 michael@0: 0x0271 , // 30 michael@0: 0xA641 , // 31 michael@0: 0x00 michael@0: }; michael@0: // test data for ToTitle michael@0: static char16_t t4data [T4LEN+2] = { michael@0: 0x0031 , // 0 michael@0: 0x0019 , // 1 michael@0: 0x0043 , // 2 michael@0: 0x0067 , // 3 michael@0: 0x00C8 , // 4 michael@0: 0x00E9 , // 5 michael@0: 0x0147 , // 6 michael@0: 0x01C4 , // 7 michael@0: 0x01C6 , // 8 michael@0: 0x01C5 , // 9 michael@0: 0x03C0 , // 10 michael@0: 0x03B2 , // 11 michael@0: 0x0438 , // 12 michael@0: 0x04A5 , // 13 michael@0: 0x05D0 , // 14 michael@0: 0x0A20 , // 15 michael@0: 0x30B0 , // 16 michael@0: 0x5189 , // 17 michael@0: 0xC013 , // 18 michael@0: 0xFF52 , // 19 michael@0: 0x01C7 , // 20 michael@0: 0x01C8 , // 21 michael@0: 0x01C9 , // 22 michael@0: 0x01CA , // 23 michael@0: 0x01CB , // 24 michael@0: 0x01CC , // 25 michael@0: 0x01F1 , // 26 michael@0: 0x01F2 , // 27 michael@0: 0x01F3 , // 28 michael@0: 0x0250 , // 29 michael@0: 0x0271 , // 30 michael@0: 0xA641 , // 31 michael@0: 0x0041 , // Dummy entry to prevent overflow michael@0: 0x00 michael@0: }; michael@0: // expected result for ToTitle michael@0: static char16_t t4result[T4LEN+2] = { michael@0: 0x0031 , // 0 michael@0: 0x0019 , // 1 michael@0: 0x0043 , // 2 michael@0: 0x0047 , // 3 michael@0: 0x00C8 , // 4 michael@0: 0x00C9 , // 5 michael@0: 0x0147 , // 6 michael@0: 0x01C4 , // 7 michael@0: 0x01C5 , // 8 michael@0: 0x01C5 , // 9 michael@0: 0x03A0 , // 10 michael@0: 0x0392 , // 11 michael@0: 0x0418 , // 12 michael@0: 0x04A4 , // 13 michael@0: 0x05D0 , // 14 michael@0: 0x0A20 , // 15 michael@0: 0x30B0 , // 16 michael@0: 0x5189 , // 17 michael@0: 0xC013 , // 18 michael@0: 0xFF32 , // 19 michael@0: 0x01C7 , // 20 michael@0: 0x01C8 , // 21 michael@0: 0x01C8 , // 22 michael@0: 0x01CA , // 23 michael@0: 0x01CB , // 24 michael@0: 0x01CB , // 25 michael@0: 0x01F1 , // 26 michael@0: 0x01F2 , // 27 michael@0: 0x01F2 , // 28 michael@0: 0x2C6F , // 29 michael@0: 0x2C6E , // 30 michael@0: 0xA640 , // 31 michael@0: 0x0041 , // Dummy entry to prevent overflow michael@0: 0x00 michael@0: }; michael@0: michael@0: static unsigned char t6lhs[] = { michael@0: 0x31 , // 0 michael@0: 0x19 , // 1 michael@0: 0x43 , // 2 michael@0: 0x67 , // 3 michael@0: 0xC3, 0x88 , // 4 michael@0: 0xC3, 0xA9 , // 5 michael@0: 0xC5, 0x87 , // 6 michael@0: 0xC7, 0x84 , // 7 michael@0: 0xC7, 0x86 , // 8 michael@0: 0xC7, 0x85 , // 9 michael@0: 0xCF, 0x80 , // 10 michael@0: 0xCE, 0xB2 , // 11 michael@0: 0xD0, 0xB8 , // 12 michael@0: 0xD2, 0xA5 , // 13 michael@0: 0xD7, 0x90 , // 14 michael@0: 0xE0, 0xA8, 0xA0 , // 15 michael@0: 0xE3, 0x82, 0xB0 , // 16 michael@0: 0xE5, 0x86, 0x85 , // 17 michael@0: 0xEC, 0x80, 0xA1 , // 18 michael@0: 0xEF, 0xBD, 0x88 , // 19 michael@0: 0xC7, 0x87 , // 20 michael@0: 0xC7, 0x88 , // 21 michael@0: 0xC7, 0x89 , // 22 michael@0: 0xC7, 0x8A , // 23 michael@0: 0xC7, 0x8B , // 24 michael@0: 0xC7, 0x8C , // 25 michael@0: 0xC7, 0xB1 , // 26 michael@0: 0xC7, 0xB2 , // 27 michael@0: 0xC7, 0xB3 , // 28 michael@0: 0xC9, 0x90 , // 29 michael@0: 0xC9, 0xB1 , // 30 michael@0: 0xEA, 0x99, 0x81 , // 31 michael@0: 0x00 michael@0: }; michael@0: michael@0: static unsigned char t6rhs[] = { michael@0: 0x31 , // 0 michael@0: 0x19 , // 1 michael@0: 0x43 , // 2 michael@0: 0x47 , // 3 michael@0: 0xC3, 0x88 , // 4 michael@0: 0xC3, 0x89 , // 5 michael@0: 0xC5, 0x87 , // 6 michael@0: 0xC7, 0x84 , // 7 michael@0: 0xC7, 0x84 , // 8 michael@0: 0xC7, 0x84 , // 9 michael@0: 0xCE, 0xA0 , // 10 michael@0: 0xCE, 0x92 , // 11 michael@0: 0xD0, 0x98 , // 12 michael@0: 0xD2, 0xA4 , // 13 michael@0: 0xD7, 0x90 , // 14 michael@0: 0xE0, 0xA8, 0xA0 , // 15 michael@0: 0xE3, 0x82, 0xB0 , // 16 michael@0: 0xE5, 0x86, 0x85 , // 17 michael@0: 0xEC, 0x80, 0xA1 , // 18 michael@0: 0xEF, 0xBC, 0xA8 , // 19 michael@0: 0xC7, 0x87 , // 20 michael@0: 0xC7, 0x87 , // 21 michael@0: 0xC7, 0x87 , // 22 michael@0: 0xC7, 0x8a , // 23 michael@0: 0xC7, 0x8a , // 24 michael@0: 0xC7, 0x8a , // 25 michael@0: 0xC7, 0xB1 , // 26 michael@0: 0xC7, 0xB1 , // 27 michael@0: 0xC7, 0xB1 , // 28 michael@0: 0xE2, 0xB1, 0xAF , // 29 michael@0: 0xE2, 0xB1, 0xAE , // 30 michael@0: 0xEA, 0x99, 0x80 , // 31 michael@0: 0x00 michael@0: }; michael@0: michael@0: static const char *t7lhs = "aBcDeFGHIJKL1!!2!!a!uuuu"; michael@0: static const char *t7rhs = "AbCdEFghijkL1!!2!!A!UUuU"; michael@0: michael@0: static const char *t8lhs = "aazzz"; michael@0: static const char *t8rhs = "aBa"; michael@0: michael@0: static const char *t9lhs = "@a"; michael@0: static const char *t9rhs = "`a"; michael@0: michael@0: bool CharByCharCompareEqual(const char *a, const char *b, michael@0: uint32_t aLen, uint32_t bLen) michael@0: { michael@0: // Do basically a CaseInsensitiveCompare(), but using michael@0: // CaseInsensitiveUTF8CharsEqual(). michael@0: michael@0: const char *aEnd = a + aLen; michael@0: const char *bEnd = b + bLen; michael@0: while (a < aEnd && b < bEnd) { michael@0: bool err; michael@0: if (!CaseInsensitiveUTF8CharsEqual(a, b, aEnd, bEnd, &a, &b, &err) || err) michael@0: return false; michael@0: } michael@0: return true; michael@0: } michael@0: michael@0: void TestCaseConversion() michael@0: { michael@0: printf("==========================\n"); michael@0: printf("Start case conversion test\n"); michael@0: printf("==========================\n"); michael@0: michael@0: int i; michael@0: char16_t buf[256]; michael@0: michael@0: printf("Test 1 - ToUpper(char16_t, char16_t*):\n"); michael@0: for(i=0;i < T2LEN ; i++) michael@0: { michael@0: char16_t ch = ToUpperCase(t2data[i]); michael@0: if(ch != t2result[i]) michael@0: printf("\tFailed!! result unexpected %d\n", i); michael@0: } michael@0: michael@0: michael@0: printf("Test 2 - ToLower(char16_t, char16_t*):\n"); michael@0: for(i=0;i < T3LEN; i++) michael@0: { michael@0: char16_t ch = ToLowerCase(t3data[i]); michael@0: if(ch != t3result[i]) michael@0: printf("\tFailed!! result unexpected %d\n", i); michael@0: } michael@0: michael@0: printf("Test 3 - ToTitle(char16_t, char16_t*):\n"); michael@0: for(i=0;i < T4LEN; i++) michael@0: { michael@0: char16_t ch = ToTitleCase(t4data[i]); michael@0: if(ch != t4result[i]) michael@0: printf("\tFailed!! result unexpected %d\n", i); michael@0: } michael@0: michael@0: printf("Test 4 - ToUpper(char16_t*, char16_t*, uint32_t):\n"); michael@0: ToUpperCase(t2data, buf, T2LEN); michael@0: for(i = 0; i < T2LEN; i++) michael@0: { michael@0: if(buf[i] != t2result[i]) michael@0: { michael@0: printf("\tFailed!! result unexpected %d\n", i); michael@0: break; michael@0: } michael@0: } michael@0: michael@0: printf("Test 5 - ToLower(char16_t*, char16_t*, uint32_t):\n"); michael@0: ToLowerCase(t3data, buf, T3LEN); michael@0: for(i = 0; i < T3LEN; i++) michael@0: { michael@0: if(buf[i] != t3result[i]) michael@0: { michael@0: printf("\tFailed!! result unexpected %d\n", i); michael@0: break; michael@0: } michael@0: } michael@0: michael@0: printf("Test 6 - CaseInsensitiveCompare UTF-8 (1):\n"); michael@0: if (CaseInsensitiveCompare((char*)t6lhs, (char*)t6rhs, sizeof(t6lhs), sizeof(t6rhs))) michael@0: printf("\tFailed!\n"); michael@0: if (!CharByCharCompareEqual((char*)t6lhs, (char*)t6rhs, sizeof(t6lhs), sizeof(t6rhs))) michael@0: printf("\tFailed character-by-character comparison!\n"); michael@0: michael@0: printf("Test 7 - CaseInsensitiveCompare UTF-8 (2):\n"); michael@0: if (CaseInsensitiveCompare(t7lhs, t7rhs, strlen(t7lhs), strlen(t7rhs))) michael@0: printf("\tFailed!\n"); michael@0: if (!CharByCharCompareEqual(t7lhs, t7rhs, sizeof(t7lhs), sizeof(t7rhs))) michael@0: printf("\tFailed character-by-character comparison!\n"); michael@0: michael@0: printf("Test 8a - CaseInsensitiveCompare UTF-8 (3):\n"); michael@0: if (CaseInsensitiveCompare(t8lhs, t8rhs, strlen(t8lhs), strlen(t8rhs)) != -1) michael@0: printf("\tFailed!\n"); michael@0: if (CharByCharCompareEqual(t8lhs, t8rhs, strlen(t8lhs), strlen(t8rhs))) michael@0: printf("\tFailed character-by-character comparison!\n"); michael@0: michael@0: printf("Test 8b - CaseInsensitiveCompare UTF-8 (4):\n"); michael@0: if (CaseInsensitiveCompare(t8rhs, t8lhs, strlen(t8rhs), strlen(t8lhs)) != 1) michael@0: printf("\tFailed!\n"); michael@0: michael@0: // This test may seem a bit strange. But it's actually an easy bug to make michael@0: // if we tried to be clever and say that two ASCII characters x and y are michael@0: // case-insensitively equal if (x & ~0x20) == (y & ~0x20). michael@0: printf("Test 9 - CaseInsensitiveCompare UTF-8 (5):\n"); michael@0: if (CaseInsensitiveCompare(t9rhs, t9lhs, strlen(t9lhs), strlen(t9rhs)) != 1) michael@0: printf("\tFailed!\n"); michael@0: if (CharByCharCompareEqual(t9lhs, t9rhs, strlen(t9lhs), strlen(t9rhs))) michael@0: printf("\tFailed character-by-character comparison!\n"); michael@0: michael@0: printf("===========================\n"); michael@0: printf("Finish case conversion test\n"); michael@0: printf("===========================\n"); michael@0: } michael@0: michael@0: static void FuzzOneInvalidCaseConversion() michael@0: { michael@0: uint32_t aLen = rand() % 32; michael@0: uint32_t bLen = rand() % 32; michael@0: michael@0: // We could use a static length-32 buffer for these, but then Valgrind michael@0: // wouldn't be able to detect errors. michael@0: unsigned char *aBuf = (unsigned char*)malloc(aLen * sizeof(unsigned char)); michael@0: unsigned char *bBuf = (unsigned char*)malloc(bLen * sizeof(unsigned char)); michael@0: michael@0: for (uint32_t i = 0; i < aLen; i++) { michael@0: aBuf[i] = rand() & 0xff; michael@0: } michael@0: michael@0: for (uint32_t i = 0; i < bLen; i++) { michael@0: bBuf[i] = rand() & 0xff; michael@0: } michael@0: michael@0: if (!CaseInsensitiveCompare((char*)aBuf, (char*)bBuf, aLen, bLen)) michael@0: printf("\tSurprise, two random strings compared insensitively as equal!\n"); michael@0: if (CharByCharCompareEqual((char*)aBuf, (char*)bBuf, aLen, bLen)) michael@0: printf("\tSurprise, two random strings compared as exactly equal!\n"); michael@0: michael@0: free(aBuf); michael@0: free(bBuf); michael@0: } michael@0: michael@0: static void FuzzCaseConversion() michael@0: { michael@0: printf("==========================\n"); michael@0: printf("Start fuzz case conversion\n"); michael@0: printf("==========================\n"); michael@0: michael@0: srand(0); michael@0: michael@0: printf("Fuzzing invalid UTF8 data...\n"); michael@0: for (uint32_t i = 0; i < 100000; i++) { michael@0: FuzzOneInvalidCaseConversion(); michael@0: } michael@0: michael@0: printf("===========================\n"); michael@0: printf("Finish fuzz case conversion\n"); michael@0: printf("===========================\n"); michael@0: } michael@0: michael@0: static void TestEntityConversion(uint32_t version) michael@0: { michael@0: printf("==============================\n"); michael@0: printf("Start nsIEntityConverter Test \n"); michael@0: printf("==============================\n"); michael@0: michael@0: uint32_t i; michael@0: nsString inString; michael@0: char16_t uChar; michael@0: nsresult res; michael@0: michael@0: michael@0: inString.Assign(NS_ConvertASCIItoUTF16("\xA0\xA1\xA2\xA3")); michael@0: uChar = (char16_t) 8364; //euro michael@0: inString.Append(&uChar, 1); michael@0: uChar = (char16_t) 9830; // michael@0: inString.Append(&uChar, 1); michael@0: michael@0: nsCOMPtr entityConv = do_CreateInstance(kEntityConverterCID, &res);; michael@0: if (NS_FAILED(res)) {printf("\tFailed!! return value != NS_OK\n"); return;} michael@0: michael@0: const char16_t *data; michael@0: uint32_t length = NS_StringGetData(inString, &data); michael@0: michael@0: // convert char by char michael@0: for (i = 0; i < length; i++) { michael@0: char *entity = nullptr; michael@0: res = entityConv->ConvertToEntity(data[i], version, &entity); michael@0: if (NS_SUCCEEDED(res) && entity) { michael@0: printf("%c %s\n", data[i], entity); michael@0: nsMemory::Free(entity); michael@0: } michael@0: } michael@0: michael@0: // convert at once as a string michael@0: char16_t *entities; michael@0: res = entityConv->ConvertToEntities(inString.get(), version, &entities); michael@0: if (NS_SUCCEEDED(res) && entities) { michael@0: for (char16_t *centity = entities; *centity; ++centity) { michael@0: printf("%c", (char) *centity); michael@0: if (';' == (char) *centity) michael@0: printf("\n"); michael@0: } michael@0: nsMemory::Free(entities); michael@0: } michael@0: michael@0: printf("==============================\n"); michael@0: printf("Finish nsIEntityConverter Test \n"); michael@0: printf("==============================\n\n"); michael@0: } michael@0: michael@0: static void TestSaveAsCharset() michael@0: { michael@0: printf("==============================\n"); michael@0: printf("Start nsISaveAsCharset Test \n"); michael@0: printf("==============================\n"); michael@0: michael@0: nsresult res; michael@0: michael@0: nsString inString; michael@0: inString.Assign(NS_ConvertASCIItoUTF16("\x61\x62\x80\xA0\x63")); michael@0: char *outString; michael@0: michael@0: const char16_t *data; michael@0: uint32_t length = NS_StringGetData(inString, &data); michael@0: michael@0: // first, dump input string michael@0: for (uint32_t i = 0; i < length; i++) { michael@0: printf("%c ", data[i]); michael@0: } michael@0: printf("\n"); michael@0: michael@0: nsCOMPtr saveAsCharset = do_CreateInstance(kSaveAsCharsetCID, &res); michael@0: if (NS_FAILED(res)) {printf("\tFailed!! return value != NS_OK\n");} michael@0: michael@0: printf("ISO-8859-1 attr_plainTextDefault entityNone\n"); michael@0: res = saveAsCharset->Init("ISO-8859-1", michael@0: nsISaveAsCharset::attr_plainTextDefault, michael@0: nsIEntityConverter::entityNone); michael@0: if (NS_FAILED(res)) {printf("\tFailed!! return value != NS_OK\n");} michael@0: res = saveAsCharset->Convert(inString.get(), &outString); michael@0: if (NS_FAILED(res)) {printf("\tFailed!! return value != NS_OK\n");} michael@0: if (!outString) {printf("\tFailed!! output null\n");} michael@0: else {printf("%s\n", outString); nsMemory::Free(outString);} michael@0: michael@0: printf("ISO-2022-JP attr_plainTextDefault entityNone\n"); michael@0: res = saveAsCharset->Init("ISO-2022-JP", michael@0: nsISaveAsCharset::attr_plainTextDefault, michael@0: nsIEntityConverter::entityNone); michael@0: if (NS_FAILED(res)) {printf("\tFailed!! return value != NS_OK\n");} michael@0: res = saveAsCharset->Convert(inString.get(), &outString); michael@0: if (NS_FAILED(res)) {printf("\tFailed!! return value != NS_OK\n");} michael@0: if (!outString) {printf("\tFailed!! output null\n");} michael@0: else {printf("%s\n", outString); nsMemory::Free(outString);} michael@0: if (NS_ERROR_UENC_NOMAPPING == res) { michael@0: outString = ToNewUTF8String(inString); michael@0: if (!outString) {printf("\tFailed!! output null\n");} michael@0: else {printf("Fall back to UTF-8: %s\n", outString); nsMemory::Free(outString);} michael@0: } michael@0: michael@0: printf("ISO-2022-JP attr_FallbackQuestionMark entityNone\n"); michael@0: res = saveAsCharset->Init("ISO-2022-JP", michael@0: nsISaveAsCharset::attr_FallbackQuestionMark, michael@0: nsIEntityConverter::entityNone); michael@0: if (NS_FAILED(res)) {printf("\tFailed!! return value != NS_OK\n");} michael@0: res = saveAsCharset->Convert(inString.get(), &outString); michael@0: if (NS_FAILED(res)) {printf("\tFailed!! return value != NS_OK\n");} michael@0: if (!outString) {printf("\tFailed!! output null\n");} michael@0: else {printf("%s\n", outString); nsMemory::Free(outString);} michael@0: michael@0: printf("ISO-2022-JP attr_FallbackEscapeU entityNone\n"); michael@0: res = saveAsCharset->Init("ISO-2022-JP", michael@0: nsISaveAsCharset::attr_FallbackEscapeU, michael@0: nsIEntityConverter::entityNone); michael@0: if (NS_FAILED(res)) {printf("\tFailed!! return value != NS_OK\n");} michael@0: res = saveAsCharset->Convert(inString.get(), &outString); michael@0: if (NS_FAILED(res)) {printf("\tFailed!! return value != NS_OK\n");} michael@0: if (!outString) {printf("\tFailed!! output null\n");} michael@0: else {printf("%s\n", outString); nsMemory::Free(outString);} michael@0: michael@0: printf("ISO-8859-1 attr_htmlTextDefault html40Latin1\n"); michael@0: res = saveAsCharset->Init("ISO-8859-1", michael@0: nsISaveAsCharset::attr_htmlTextDefault, michael@0: nsIEntityConverter::html40Latin1); michael@0: if (NS_FAILED(res)) {printf("\tFailed!! return value != NS_OK\n");} michael@0: res = saveAsCharset->Convert(inString.get(), &outString); michael@0: if (NS_ERROR_UENC_NOMAPPING != res && NS_FAILED(res)) {printf("\tFailed!! return value != NS_OK\n");} michael@0: if (!outString) {printf("\tFailed!! output null\n");} michael@0: else {printf("%s\n", outString); nsMemory::Free(outString);} michael@0: michael@0: printf("ISO-8859-1 attr_FallbackHexNCR+attr_EntityAfterCharsetConv html40Latin1 \n"); michael@0: res = saveAsCharset->Init("ISO-8859-1", michael@0: nsISaveAsCharset::attr_FallbackHexNCR + michael@0: nsISaveAsCharset::attr_EntityAfterCharsetConv, michael@0: nsIEntityConverter::html40Latin1); michael@0: if (NS_FAILED(res)) {printf("\tFailed!! return value != NS_OK\n");} michael@0: res = saveAsCharset->Convert(inString.get(), &outString); michael@0: if (NS_ERROR_UENC_NOMAPPING != res && NS_FAILED(res)) {printf("\tFailed!! return value != NS_OK\n");} michael@0: if (!outString) {printf("\tFailed!! output null\n");} michael@0: else {printf("%s\n", outString); nsMemory::Free(outString);} michael@0: michael@0: michael@0: printf("==============================\n"); michael@0: printf("Finish nsISaveAsCharset Test \n"); michael@0: printf("==============================\n\n"); michael@0: } michael@0: michael@0: static char16_t normStr[] = michael@0: { michael@0: 0x00E1, michael@0: 0x0061, michael@0: 0x0301, michael@0: 0x0107, michael@0: 0x0063, michael@0: 0x0301, michael@0: 0x0000 michael@0: }; michael@0: michael@0: static char16_t nfdForm[] = michael@0: { michael@0: 0x0061, michael@0: 0x0301, michael@0: 0x0061, michael@0: 0x0301, michael@0: 0x0063, michael@0: 0x0301, michael@0: 0x0063, michael@0: 0x0301, michael@0: 0x0000 michael@0: }; michael@0: michael@0: void TestNormalization() michael@0: { michael@0: printf("==============================\n"); michael@0: printf("Start nsIUnicodeNormalizer Test \n"); michael@0: printf("==============================\n"); michael@0: nsIUnicodeNormalizer *t = nullptr; michael@0: nsresult res; michael@0: res = CallGetService(kUnicodeNormalizerCID, &t); michael@0: michael@0: printf("Test 1 - GetService():\n"); michael@0: if(NS_FAILED(res) || !t) { michael@0: printf("\t1st Norm GetService failed\n"); michael@0: } else { michael@0: NS_RELEASE(t); michael@0: } michael@0: michael@0: res = CallGetService(kUnicodeNormalizerCID, &t); michael@0: michael@0: if(NS_FAILED(res) || !t) { michael@0: printf("\t2nd GetService failed\n"); michael@0: } else { michael@0: printf("Test 2 - NormalizeUnicode(uint32_t, const nsAString&, nsAString&):\n"); michael@0: nsAutoString resultStr; michael@0: res = t->NormalizeUnicodeNFD(nsDependentString(normStr), resultStr); michael@0: if (resultStr.Equals(nsDependentString(nfdForm))) { michael@0: printf(" Succeeded in NFD UnicodeNormalizer test. \n"); michael@0: } else { michael@0: printf(" Failed in NFD UnicodeNormalizer test. \n"); michael@0: } michael@0: michael@0: NS_RELEASE(t); michael@0: } michael@0: printf("==============================\n"); michael@0: printf("Finish nsIUnicodeNormalizer Test \n"); michael@0: printf("==============================\n"); michael@0: michael@0: } michael@0: michael@0: michael@0: int main(int argc, char** argv) { michael@0: michael@0: nsresult rv = NS_InitXPCOM2(nullptr, nullptr, nullptr); michael@0: if (NS_FAILED(rv)) { michael@0: printf("NS_InitXPCOM2 failed\n"); michael@0: return 1; michael@0: } michael@0: michael@0: // -------------------------------------------- michael@0: michael@0: TestCaseConversion(); michael@0: michael@0: // -------------------------------------------- michael@0: michael@0: FuzzCaseConversion(); michael@0: michael@0: // -------------------------------------------- michael@0: michael@0: TestEntityConversion(nsIEntityConverter::html40); michael@0: michael@0: // -------------------------------------------- michael@0: michael@0: TestSaveAsCharset(); michael@0: michael@0: // -------------------------------------------- michael@0: michael@0: TestNormalization(); michael@0: michael@0: // -------------------------------------------- michael@0: printf("Finish All The Test Cases\n"); michael@0: michael@0: return 0; michael@0: }