summaryrefslogtreecommitdiffstats
path: root/intl/uconv/tests/nsTestUConv.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'intl/uconv/tests/nsTestUConv.cpp')
-rw-r--r--intl/uconv/tests/nsTestUConv.cpp985
1 files changed, 985 insertions, 0 deletions
diff --git a/intl/uconv/tests/nsTestUConv.cpp b/intl/uconv/tests/nsTestUConv.cpp
new file mode 100644
index 000000000..505419a3f
--- /dev/null
+++ b/intl/uconv/tests/nsTestUConv.cpp
@@ -0,0 +1,985 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include <stdio.h>
+#include <string.h>
+#include "nsXPCOM.h"
+#include "nsIComponentManager.h"
+#include "nsIServiceManager.h"
+#include "nsISupports.h"
+#include "nsICharsetConverterManager.h"
+#include "nsIPlatformCharset.h"
+#include "nsReadableUtils.h"
+
+
+static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
+static NS_DEFINE_CID(kPlatformCharsetCID, NS_PLATFORMCHARSET_CID);
+
+/**
+ * Test program for the Unicode Converters.
+ *
+ * Error messages format inside of a test.
+ *
+ * - silent while all is OK.
+ *
+ * - "ERROR at T001.easyConversion.Convert() code=0xfffd.\n"
+ * - "ERROR at T001.easyConversion.ConvResLen expected=0x02 result=0x04.\n"
+ *
+ * - "Test Passed.\n" for a successful end.
+ *
+ * @created 01/Dec/1998
+ * @author Catalin Rotaru [CATA]
+ */
+
+//----------------------------------------------------------------------
+// Global variables and macros
+
+#define GENERAL_BUFFER 20000 // general purpose buffer; for Unicode divide by 2
+
+#define ARRAY_SIZE(_array) \
+ (sizeof(_array) / sizeof(_array[0]))
+
+nsICharsetConverterManager * ccMan = nullptr;
+
+/**
+ * Test data for Latin1 charset.
+ */
+
+char bLatin1_d0[] = {
+ "\x00\x0d\x7f\x80\xff"
+};
+
+char16_t cLatin1_d0[] = {
+ 0x0000,0x000d,0x007f,0x20ac,0x00ff
+};
+
+int32_t bLatin1_s0 = ARRAY_SIZE(bLatin1_d0)-1;
+int32_t cLatin1_s0 = ARRAY_SIZE(cLatin1_d0);
+
+//----------------------------------------------------------------------
+// Converter Manager test code
+
+nsresult testCharsetConverterManager()
+{
+ printf("\n[T001] CharsetConverterManager\n");
+
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------
+// Helper functions and macros for testing decoders and encoders
+
+#define CREATE_DECODER(_charset) \
+ nsIUnicodeDecoder * dec; \
+ nsAutoString str;str.AssignASCII(_charset); \
+ nsresult res = ccMan->GetUnicodeDecoder(&str,&dec); \
+ if (NS_FAILED(res)) { \
+ printf("ERROR at GetUnicodeDecoder() code=0x%x.\n",res); \
+ return res; \
+ }
+
+#define CREATE_ENCODER(_charset) \
+ nsIUnicodeEncoder * enc; \
+ nsAutoString str; str.AssignASCII(_charset); \
+ nsresult res = ccMan->GetUnicodeEncoder(&str,&enc); \
+ if (NS_FAILED(res)) { \
+ printf("ERROR at GetUnicodeEncoder() code=0x%x.\n",res); \
+ return res; \
+ }
+
+/**
+ * Decoder test.
+ *
+ * This method will test the conversion only.
+ */
+nsresult testDecoder(nsIUnicodeDecoder * aDec,
+ const char * aSrc, int32_t aSrcLength,
+ const char16_t * aRes, int32_t aResLength,
+ const char * aTestName)
+{
+ nsresult res;
+
+ // prepare for conversion
+ int32_t srcLen = aSrcLength;
+ char16_t dest[GENERAL_BUFFER/2];
+ int32_t destLen = GENERAL_BUFFER/2;
+
+ // conversion
+ res = aDec->Convert(aSrc, &srcLen, dest, &destLen);
+ // we want a perfect result here - the test data should be complete!
+ if (res != NS_OK) {
+ printf("ERROR at %s.easy.Decode() code=0x%x.\n",aTestName,res);
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ // compare results
+ if (aResLength != destLen) {
+ printf("ERROR at %s.easy.DecResLen expected=0x%x result=0x%x.\n",
+ aTestName, aResLength, destLen);
+ return NS_ERROR_UNEXPECTED;
+ }
+ for (int32_t i=0; i<aResLength; i++) if (aRes[i] != dest[i]) {
+ printf("ERROR at %s.easy.DecResChar[%d] expected=0x%x result=0x%x.\n",
+ aTestName, i, aRes[i], dest[i]);
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ return NS_OK;
+}
+
+/**
+ * Encoder test.
+ *
+ * This method will test the conversion only.
+ */
+nsresult testEncoder(nsIUnicodeEncoder * aEnc,
+ const char16_t * aSrc, int32_t aSrcLength,
+ const char * aRes, int32_t aResLength,
+ const char * aTestName)
+{
+ nsresult res;
+
+ // prepare for conversion
+ int32_t srcLen = 0;
+ char dest[GENERAL_BUFFER];
+ int32_t destLen = 0;
+ int32_t bcr, bcw;
+
+ // conversion
+ bcr = aSrcLength;
+ bcw = GENERAL_BUFFER;
+ res = aEnc->Convert(aSrc, &bcr, dest, &bcw);
+ srcLen += bcr;
+ destLen += bcw;
+ // we want a perfect result here - the test data should be complete!
+ if (res != NS_OK) {
+ printf("ERROR at %s.easy.Encode() code=0x%x.\n",aTestName,res);
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ // finish
+ bcw = GENERAL_BUFFER - destLen;
+ res = aEnc->Finish(dest + destLen, &bcw);
+ destLen += bcw;
+ // we want a perfect result here - the test data should be complete!
+ if (res != NS_OK) {
+ printf("ERROR at %s.easy.Finish() code=0x%x.\n",aTestName,res);
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ // compare results
+ if (aResLength != destLen) {
+ printf("ERROR at %s.easy.EncResLen expected=0x%x result=0x%x.\n",
+ aTestName, aResLength, destLen);
+ return NS_ERROR_UNEXPECTED;
+ }
+ for (int32_t i=0; i<aResLength; i++) if (aRes[i] != dest[i]) {
+ printf("ERROR at %s.easy.EncResChar[%d] expected=0x%x result=0x%x.\n",
+ aTestName, i, aRes[i], dest[i]);
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ return NS_OK;
+}
+
+/**
+ * Decoder test.
+ *
+ * This method will test a given converter under a given set of data and some
+ * very stressful conditions.
+ */
+nsresult testStressDecoder(nsIUnicodeDecoder * aDec,
+ const char * aSrc, int32_t aSrcLength,
+ const char16_t * aRes, int32_t aResLength,
+ const char * aTestName)
+{
+ nsresult res;
+
+ // get estimated length
+ int32_t estimatedLength;
+ res = aDec->GetMaxLength(aSrc, aSrcLength, &estimatedLength);
+ if (NS_FAILED(res)) {
+ printf("ERROR at %s.stress.Length() code=0x%x.\n",aTestName,res);
+ return res;
+ }
+ bool exactLength = (res == NS_EXACT_LENGTH);
+
+ // prepare for conversion
+ int32_t srcLen = 0;
+ int32_t srcOff = 0;
+ char16_t dest[1024];
+ int32_t destLen = 0;
+ int32_t destOff = 0;
+
+ // controlled conversion
+ for (;srcOff < aSrcLength;) {
+ res = aDec->Convert(aSrc + srcOff, &srcLen, dest + destOff, &destLen);
+ if (NS_FAILED(res)) {
+ printf("ERROR at %s.stress.Convert() code=0x%x.\n",aTestName,res);
+ return res;
+ }
+
+ srcOff+=srcLen;
+ destOff+=destLen;
+
+ // give a little input each time; it'll be consumed if enough output space
+ srcLen = 1;
+ // give output space only when requested: sadic!
+ if (res == NS_PARTIAL_MORE_OUTPUT) {
+ destLen = 1;
+ } else {
+ destLen = 0;
+ }
+ }
+
+ // we want perfect result here - the test data should be complete!
+ if (res != NS_OK) {
+ printf("ERROR at %s.stress.postConvert() code=0x%x.\n",aTestName,res);
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ // compare lengths
+ if (exactLength) {
+ if (destOff != estimatedLength) {
+ printf("ERROR at %s.stress.EstimatedLen expected=0x%x result=0x%x.\n",
+ aTestName, estimatedLength, destOff);
+ return NS_ERROR_UNEXPECTED;
+ }
+ } else {
+ if (destOff > estimatedLength) {
+ printf("ERROR at %s.stress.EstimatedLen expected<=0x%x result=0x%x.\n",
+ aTestName, estimatedLength, destOff);
+ return NS_ERROR_UNEXPECTED;
+ }
+ }
+
+ // compare results
+ if (aResLength != destOff) {
+ printf("ERROR at %s.stress.ConvResLen expected=0x%x result=0x%x.\n",
+ aTestName, aResLength, destOff);
+ return NS_ERROR_UNEXPECTED;
+ }
+ for (int32_t i=0; i<aResLength; i++) if (aRes[i] != dest[i]) {
+ printf("ERROR at %s.stress.ConvResChar[%d] expected=0x%x result=0x%x.\n",
+ aTestName, i, aRes[i], dest[i]);
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ return NS_OK;
+}
+
+/**
+ * Encoder test.
+ *
+ * This method will test a given converter under a given set of data and some
+ * very stressful conditions.
+ */
+nsresult testStressEncoder(nsIUnicodeEncoder * aEnc,
+ const char16_t * aSrc, int32_t aSrcLength,
+ const char * aRes, int32_t aResLength,
+ const char * aTestName)
+{
+ nsresult res;
+
+ // get estimated length
+ int32_t estimatedLength;
+ res = aEnc->GetMaxLength(aSrc, aSrcLength, &estimatedLength);
+ if (NS_FAILED(res)) {
+ printf("ERROR at %s.stress.Length() code=0x%x.\n",aTestName,res);
+ return res;
+ }
+ bool exactLength = (res == NS_OK_UENC_EXACTLENGTH);
+
+ // prepare for conversion
+ int32_t srcLen = 0;
+ int32_t srcOff = 0;
+ char dest[GENERAL_BUFFER];
+ int32_t destLen = 0;
+ int32_t destOff = 0;
+
+ // controlled conversion
+ for (;srcOff < aSrcLength;) {
+ res = aEnc->Convert(aSrc + srcOff, &srcLen, dest + destOff, &destLen);
+ if (NS_FAILED(res)) {
+ printf("ERROR at %s.stress.Convert() code=0x%x.\n",aTestName,res);
+ return res;
+ }
+
+ srcOff+=srcLen;
+ destOff+=destLen;
+
+ // give a little input each time; it'll be consumed if enough output space
+ srcLen = 1;
+ // give output space only when requested: sadic!
+ if (res == NS_OK_UENC_MOREOUTPUT) {
+ destLen = 1;
+ } else {
+ destLen = 0;
+ }
+ }
+
+ if (res != NS_OK) if (res != NS_OK_UENC_MOREOUTPUT) {
+ printf("ERROR at %s.stress.postConvert() code=0x%x.\n",aTestName,res);
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ for (;;) {
+ res = aEnc->Finish(dest + destOff, &destLen);
+ if (NS_FAILED(res)) {
+ printf("ERROR at %s.stress.Finish() code=0x%x.\n",aTestName,res);
+ return res;
+ }
+
+ destOff+=destLen;
+
+ // give output space only when requested: sadic!
+ if (res == NS_OK_UENC_MOREOUTPUT) {
+ destLen = 1;
+ } else break;
+ }
+
+ // compare lengths
+ if (exactLength) {
+ if (destOff != estimatedLength) {
+ printf("ERROR at %s.stress.EstimatedLen expected=0x%x result=0x%x.\n",
+ aTestName, estimatedLength, destOff);
+ return NS_ERROR_UNEXPECTED;
+ }
+ } else {
+ if (destOff > estimatedLength) {
+ printf("ERROR at %s.stress.EstimatedLen expected<=0x%x result=0x%x.\n",
+ aTestName, estimatedLength, destOff);
+ return NS_ERROR_UNEXPECTED;
+ }
+ }
+
+ // compare results
+ if (aResLength != destOff) {
+ printf("ERROR at %s.stress.ConvResLen expected=0x%x result=0x%x.\n",
+ aTestName, aResLength, destOff);
+ return NS_ERROR_UNEXPECTED;
+ }
+ for (int32_t i=0; i<aResLength; i++) if (aRes[i] != dest[i]) {
+ printf("ERROR at %s.stress.ConvResChar[%d] expected=0x%x result=0x%x.\n",
+ aTestName, i, aRes[i], dest[i]);
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ return NS_OK;
+}
+
+/**
+ * Reset decoder.
+ */
+nsresult resetDecoder(nsIUnicodeDecoder * aDec, const char * aTestName)
+{
+ nsresult res = aDec->Reset();
+
+ if (NS_FAILED(res)) {
+ printf("ERROR at %s.dec.Reset() code=0x%x.\n",aTestName,res);
+ return res;
+ }
+
+ return res;
+}
+
+/**
+ * Reset encoder.
+ */
+nsresult resetEncoder(nsIUnicodeEncoder * aEnc, const char * aTestName)
+{
+ nsresult res = aEnc->Reset();
+
+ if (NS_FAILED(res)) {
+ printf("ERROR at %s.enc.Reset() code=0x%x.\n",aTestName,res);
+ return res;
+ }
+
+ return res;
+}
+
+/**
+ * A standard decoder test.
+ */
+nsresult standardDecoderTest(char * aTestName, char * aCharset, char * aSrc,
+ int32_t aSrcLen, char16_t * aRes, int32_t aResLen)
+{
+ printf("\n[%s] Unicode <- %s\n", aTestName, aCharset);
+
+ // create converter
+ CREATE_DECODER(aCharset);
+
+ // test converter - easy test
+ res = testDecoder(dec, aSrc, aSrcLen, aRes, aResLen, aTestName);
+
+ // reset converter
+ if (NS_SUCCEEDED(res)) res = resetDecoder(dec, aTestName);
+
+ // test converter - stress test
+ if (NS_SUCCEEDED(res))
+ res = testStressDecoder(dec, aSrc, aSrcLen, aRes, aResLen, aTestName);
+
+ // release converter
+ NS_RELEASE(dec);
+
+ if (NS_FAILED(res)) {
+ return res;
+ } else {
+ printf("Test Passed.\n");
+ return NS_OK;
+ }
+}
+
+nsresult loadBinaryFile(char * aFile, char * aBuff, int32_t * aBuffLen)
+{
+ FILE * f = fopen(aFile, "rb");
+ if (!f) {
+ printf("ERROR at opening file: \"%s\".\n", aFile);
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ int32_t n = fread(aBuff, 1, *aBuffLen, f);
+ if (n >= *aBuffLen) {
+ printf("ERROR at reading from file \"%s\": too much input data.\n", aFile);
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ *aBuffLen = n;
+ fclose(f);
+ return NS_OK;
+}
+
+nsresult loadUnicodeFile(char * aFile, char16_t * aBuff, int32_t * aBuffLen)
+{
+ int32_t buffLen = 2*(*aBuffLen);
+
+ nsresult res = loadBinaryFile(aFile, (char *)aBuff, &buffLen);
+ if (NS_FAILED(res)) return res;
+
+ *aBuffLen = buffLen/2;
+ return NS_OK;
+}
+
+nsresult testDecoderFromFiles(char * aCharset, char * aSrcFile, char * aResultFile)
+{
+ // create converter
+ CREATE_DECODER(aCharset);
+
+ int32_t srcLen = GENERAL_BUFFER;
+ char src[GENERAL_BUFFER];
+ int32_t expLen = GENERAL_BUFFER/2;
+ char16_t exp[GENERAL_BUFFER/2];
+
+ res = loadBinaryFile(aSrcFile, src, &srcLen);
+ if (NS_FAILED(res)) return res;
+
+ res = loadUnicodeFile(aResultFile, exp, &expLen);
+ if (NS_FAILED(res)) return res;
+
+ // test converter - easy test
+ res = testDecoder(dec, src, srcLen, exp, expLen, "dec");
+
+ // release converter
+ NS_RELEASE(dec);
+
+ if (NS_FAILED(res)) {
+ return res;
+ } else {
+ printf("Test Passed.\n");
+ return NS_OK;
+ }
+
+ return NS_OK;
+}
+
+nsresult testEncoderFromFiles(char * aCharset, char * aSrcFile, char * aResultFile)
+{
+ // XXX write me
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------
+// Decoders testing functions
+
+/**
+ * Test the ISO2022JP decoder.
+ */
+nsresult testISO2022JPDecoder()
+{
+ char * testName = "T102";
+ printf("\n[%s] Unicode <- ISO2022JP\n", testName);
+
+ // create converter
+ CREATE_DECODER("iso-2022-jp");
+
+ // test data
+ char src[] = {"\x0d\x7f\xdd" "\x1b(J\xaa\xdc\x41" "\x1b$B\x21\x21" "\x1b$@\x32\x37" "\x1b(J\x1b(B\xcc"};
+ char16_t exp[] = {0x000d,0x007f,0xfffd, 0xff6a,0xFF9C,0x0041, 0x3000, 0x5378, 0xfffd};
+
+ // test converter - normal operation
+ res = testDecoder(dec, src, ARRAY_SIZE(src)-1, exp, ARRAY_SIZE(exp), testName);
+
+ // reset converter
+ if (NS_SUCCEEDED(res)) res = resetDecoder(dec, testName);
+
+ // test converter - stress test
+ if (NS_SUCCEEDED(res))
+ res = testStressDecoder(dec, src, ARRAY_SIZE(src)-1, exp, ARRAY_SIZE(exp), testName);
+
+ // release converter
+ NS_RELEASE(dec);
+
+ if (NS_FAILED(res)) {
+ return res;
+ } else {
+ printf("Test Passed.\n");
+ return NS_OK;
+ }
+}
+
+/**
+ * Test the EUCJP decoder.
+ */
+nsresult testEUCJPDecoder()
+{
+ char * testName = "T103";
+ printf("\n[%s] Unicode <- EUCJP\n", testName);
+
+ // create converter
+ CREATE_DECODER("euc-jp");
+
+ // test data
+ char src[] = {"\x45"};
+ char16_t exp[] = {0x0045};
+
+ // test converter - normal operation
+ res = testDecoder(dec, src, ARRAY_SIZE(src)-1, exp, ARRAY_SIZE(exp), testName);
+
+ // reset converter
+ if (NS_SUCCEEDED(res)) res = resetDecoder(dec, testName);
+
+ // test converter - stress test
+ if (NS_SUCCEEDED(res))
+ res = testStressDecoder(dec, src, ARRAY_SIZE(src)-1, exp, ARRAY_SIZE(exp), testName);
+
+ // release converter
+ NS_RELEASE(dec);
+
+ if (NS_FAILED(res)) {
+ return res;
+ } else {
+ printf("Test Passed.\n");
+ return NS_OK;
+ }
+}
+
+/**
+ * Test the ISO88597 decoder.
+ */
+nsresult testISO88597Decoder()
+{
+ char * testName = "T104";
+ printf("\n[%s] Unicode <- ISO88597\n", testName);
+
+ // create converter
+ CREATE_DECODER("iso-8859-7");
+
+ // test data
+ char src[] = {
+ "\x09\x0d\x20\x40"
+ "\x80\x98\xa3\xaf"
+ "\xa7\xb1\xb3\xc9"
+ "\xd9\xe3\xf4\xff"
+ };
+ char16_t exp[] = {
+ 0x0009, 0x000d, 0x0020, 0x0040,
+ 0xfffd, 0xfffd, 0x00a3, 0x2015,
+ 0x00a7, 0x00b1, 0x00b3, 0x0399,
+ 0x03a9, 0x03b3, 0x03c4, 0xfffd
+ };
+
+ // test converter - normal operation
+ res = testDecoder(dec, src, ARRAY_SIZE(src)-1, exp, ARRAY_SIZE(exp), testName);
+
+ // reset converter
+ if (NS_SUCCEEDED(res)) res = resetDecoder(dec, testName);
+
+ // test converter - stress test
+ if (NS_SUCCEEDED(res))
+ res = testStressDecoder(dec, src, ARRAY_SIZE(src)-1, exp, ARRAY_SIZE(exp), testName);
+
+ // release converter
+ NS_RELEASE(dec);
+
+ if (NS_FAILED(res)) {
+ return res;
+ } else {
+ printf("Test Passed.\n");
+ return NS_OK;
+ }
+}
+
+/**
+ * Test the SJIS decoder.
+ */
+nsresult testSJISDecoder()
+{
+ char * testName = "T105";
+ printf("\n[%s] Unicode <- SJIS\n", testName);
+
+ // create converter
+ CREATE_DECODER("Shift_JIS");
+
+ // test data
+ char src[] = {
+ "Japanese" /* English */
+ "\x8a\xbf\x8e\x9a" /* Kanji */
+ "\x83\x4a\x83\x5e\x83\x4a\x83\x69" /* Kantakana */
+ "\x82\xd0\x82\xe7\x82\xaa\x82\xc8" /* Hiragana */
+ "\x82\x50\x82\x51\x82\x52\x82\x60\x82\x61\x82\x62" /* full width 123ABC */
+ };
+ char16_t exp[] = {
+ 0x004A, 0x0061, 0x0070, 0x0061, 0x006E, 0x0065, 0x0073, 0x0065,
+ 0x6f22, 0x5b57,
+ 0x30ab, 0x30bf, 0x30ab, 0x30ca,
+ 0x3072, 0x3089, 0x304c, 0x306a,
+ 0xff11, 0xff12, 0xff13, 0xff21, 0xff22, 0xff23
+ };
+
+ // test converter - normal operation
+ res = testDecoder(dec, src, ARRAY_SIZE(src)-1, exp, ARRAY_SIZE(exp), testName);
+
+ // reset converter
+ if (NS_SUCCEEDED(res)) res = resetDecoder(dec, testName);
+
+ // test converter - stress test
+ if (NS_SUCCEEDED(res))
+ res = testStressDecoder(dec, src, ARRAY_SIZE(src)-1, exp, ARRAY_SIZE(exp), testName);
+
+ // release converter
+ NS_RELEASE(dec);
+
+ if (NS_FAILED(res)) {
+ return res;
+ } else {
+ printf("Test Passed.\n");
+ return NS_OK;
+ }
+}
+
+/**
+ * Test the UTF8 decoder.
+ */
+nsresult testUTF8Decoder()
+{
+ char * testName = "T106";
+ printf("\n[%s] Unicode <- UTF8\n", testName);
+
+ // create converter
+ CREATE_DECODER("utf-8");
+
+#ifdef NOPE // XXX decomment this when I have test data
+ // test data
+ char src[] = {};
+ char16_t exp[] = {};
+
+ // test converter - normal operation
+ res = testDecoder(dec, src, ARRAY_SIZE(src)-1, exp, ARRAY_SIZE(exp), testName);
+
+ // reset converter
+ if (NS_SUCCEEDED(res)) res = resetDecoder(dec, testName);
+
+ // test converter - stress test
+ if (NS_SUCCEEDED(res))
+ res = testStressDecoder(dec, src, ARRAY_SIZE(src)-1, exp, ARRAY_SIZE(exp), testName);
+#endif
+
+ // release converter
+ NS_RELEASE(dec);
+
+ if (NS_FAILED(res)) {
+ return res;
+ } else {
+ printf("Test Passed.\n");
+ return NS_OK;
+ }
+}
+
+//----------------------------------------------------------------------
+// Encoders testing functions
+
+/**
+ * Test the Latin1 encoder.
+ */
+nsresult testLatin1Encoder()
+{
+ char * testName = "T201";
+ printf("\n[%s] Unicode -> Latin1\n", testName);
+
+ // create converter
+ CREATE_ENCODER("iso-8859-1");
+ enc->SetOutputErrorBehavior(enc->kOnError_Replace, nullptr, 0x00cc);
+
+ // test data
+ char16_t src[] = {0x0001,0x0002,0xffff,0x00e3};
+ char exp[] = {"\x01\x02\xcc\xe3"};
+
+ // test converter - easy test
+ res = testEncoder(enc, src, ARRAY_SIZE(src), exp, ARRAY_SIZE(exp)-1, testName);
+
+ // reset converter
+ if (NS_SUCCEEDED(res)) res = resetEncoder(enc, testName);
+
+ // test converter - stress test
+ if (NS_SUCCEEDED(res))
+ res = testStressEncoder(enc, src, ARRAY_SIZE(src), exp, ARRAY_SIZE(exp)-1, testName);
+
+ // release converter
+ NS_RELEASE(enc);
+
+ if (NS_FAILED(res)) {
+ return res;
+ } else {
+ printf("Test Passed.\n");
+ return NS_OK;
+ }
+}
+
+/**
+ * Test the Shift-JIS encoder.
+ */
+nsresult testSJISEncoder()
+{
+ char * testName = "T202";
+ printf("\n[%s] Unicode -> SJIS\n", testName);
+
+ // create converter
+ CREATE_ENCODER("Shift_JIS");
+ enc->SetOutputErrorBehavior(enc->kOnError_Replace, nullptr, 0x00cc);
+
+ // test data
+ char16_t src[] = {
+ 0x004A, 0x0061, 0x0070, 0x0061, 0x006E, 0x0065, 0x0073, 0x0065,
+ 0x6f22, 0x5b57,
+ 0x30ab, 0x30bf, 0x30ab, 0x30ca,
+ 0x3072, 0x3089, 0x304c, 0x306a,
+ 0xff11, 0xff12, 0xff13, 0xff21, 0xff22, 0xff23
+ };
+ char exp[] = {
+ "Japanese" /* English */
+ "\x8a\xbf\x8e\x9a" /* Kanji */
+ "\x83\x4a\x83\x5e\x83\x4a\x83\x69" /* Kantakana */
+ "\x82\xd0\x82\xe7\x82\xaa\x82\xc8" /* Hiragana */
+ "\x82\x50\x82\x51\x82\x52\x82\x60\x82\x61\x82\x62" /* full width 123ABC */
+ };
+
+ // test converter - easy test
+ res = testEncoder(enc, src, ARRAY_SIZE(src), exp, ARRAY_SIZE(exp)-1, testName);
+
+ // reset converter
+ if (NS_SUCCEEDED(res)) res = resetEncoder(enc, testName);
+
+ // test converter - stress test
+ if (NS_SUCCEEDED(res))
+ res = testStressEncoder(enc, src, ARRAY_SIZE(src), exp, ARRAY_SIZE(exp)-1, testName);
+
+ // release converter
+ NS_RELEASE(enc);
+
+ if (NS_FAILED(res)) {
+ return res;
+ } else {
+ printf("Test Passed.\n");
+ return NS_OK;
+ }
+}
+
+/**
+ * Test the EUC-JP encoder.
+ */
+nsresult testEUCJPEncoder()
+{
+ char * testName = "T203";
+ printf("\n[%s] Unicode -> EUCJP\n", testName);
+
+ // create converter
+ CREATE_ENCODER("euc-jp");
+ enc->SetOutputErrorBehavior(enc->kOnError_Replace, nullptr, 0x00cc);
+
+ // test data
+ char16_t src[] = {0x0045, 0x0054};
+ char exp[] = {"\x45\x54"};
+
+ // test converter - easy test
+ res = testEncoder(enc, src, ARRAY_SIZE(src), exp, ARRAY_SIZE(exp)-1, testName);
+
+ // reset converter
+ if (NS_SUCCEEDED(res)) res = resetEncoder(enc, testName);
+
+ // test converter - stress test
+ if (NS_SUCCEEDED(res))
+ res = testStressEncoder(enc, src, ARRAY_SIZE(src), exp, ARRAY_SIZE(exp)-1, testName);
+
+ // release converter
+ NS_RELEASE(enc);
+
+ if (NS_FAILED(res)) {
+ return res;
+ } else {
+ printf("Test Passed.\n");
+ return NS_OK;
+ }
+}
+
+/**
+ * Test the ISO-2022-JP encoder.
+ */
+nsresult testISO2022JPEncoder()
+{
+ char * testName = "T204";
+ printf("\n[%s] Unicode -> ISO2022JP\n", testName);
+
+ // create converter
+ CREATE_ENCODER("iso-2022-jp");
+ enc->SetOutputErrorBehavior(enc->kOnError_Replace, nullptr, 0x00cc);
+
+ // test data
+ char16_t src[] = {0x000d,0x007f, 0xff6a,0xFF9C, 0x3000, 0x5378};
+ char exp[] = {"\x0d\x7f" "\x1b(J\xaa\xdc" "\x1b$@\x21\x21\x32\x37\x1b(B"};
+
+ // test converter - easy test
+ res = testEncoder(enc, src, ARRAY_SIZE(src), exp, ARRAY_SIZE(exp)-1, testName);
+
+ // reset converter
+ if (NS_SUCCEEDED(res)) res = resetEncoder(enc, testName);
+
+ // test converter - stress test
+ if (NS_SUCCEEDED(res))
+ res = testStressEncoder(enc, src, ARRAY_SIZE(src), exp, ARRAY_SIZE(exp)-1, testName);
+
+ // release converter
+ NS_RELEASE(enc);
+
+ if (NS_FAILED(res)) {
+ return res;
+ } else {
+ printf("Test Passed.\n");
+ return NS_OK;
+ }
+}
+
+nsresult testPlatformCharset()
+{
+ nsIPlatformCharset *cinfo;
+ nsresult res = CallGetService(kPlatformCharsetCID, &cinfo);
+ if (NS_FAILED(res)) {
+ printf("ERROR at GetService() code=0x%x.\n",res);
+ return res;
+ }
+
+ nsString value;
+ res = cinfo->GetCharset(kPlatformCharsetSel_PlainTextInClipboard , value);
+ printf("Clipboard plain text encoding = %s\n", NS_LossyConvertUTF16toASCII(value).get());
+
+ res = cinfo->GetCharset(kPlatformCharsetSel_FileName , value);
+ printf("File Name encoding = %s\n", NS_LossyConvertUTF16toASCII(value).get());
+
+ res = cinfo->GetCharset(kPlatformCharsetSel_Menu , value);
+ printf("Menu encoding = %s\n", NS_LossyConvertUTF16toASCII(value).get());
+
+ cinfo->Release();
+ return res;
+
+}
+
+//----------------------------------------------------------------------
+// Testing functions
+
+nsresult testAll()
+{
+ nsresult res;
+
+ // test the manager(s)
+ res = testCharsetConverterManager();
+ if (NS_FAILED(res)) return res;
+
+ testPlatformCharset();
+
+ // test decoders
+ standardDecoderTest("T101", "ISO-8859-1", bLatin1_d0, bLatin1_s0, cLatin1_d0, cLatin1_s0);
+ testISO2022JPDecoder();
+ testEUCJPDecoder();
+ testISO88597Decoder();
+ testSJISDecoder();
+ testUTF8Decoder();
+ testMUTF7Decoder();
+ testUTF7Decoder();
+
+ // test encoders
+ testLatin1Encoder();
+ testSJISEncoder();
+ testEUCJPEncoder();
+ testISO2022JPEncoder();
+ testMUTF7Encoder();
+ testUTF7Encoder();
+
+ // return
+ return NS_OK;
+}
+
+nsresult testFromArgs(int argc, char **argv)
+{
+ nsresult res = NS_OK;
+ if ((argc == 5) && (!strcmp(argv[1], "-tdec"))) {
+ res = testDecoderFromFiles(argv[2], argv[3], argv[4]);
+ } else if ((argc == 5) && (!strcmp(argv[1], "-tenc"))) {
+ res = testEncoderFromFiles(argv[2], argv[3], argv[4]);
+ } else {
+ printf("Usage:\n");
+ printf(" TestUConv.exe\n");
+ printf(" TestUConv.exe -tdec encoding inputEncodedFile expectedResultUnicodeFile\n");
+ printf(" TestUConv.exe -tenc encoding inputUnicodeFile expectedResultEncodedFile\n");
+ }
+
+ return res;
+}
+
+//----------------------------------------------------------------------
+// Main program functions
+
+nsresult init()
+{
+ nsresult rv = NS_InitXPCOM2(nullptr, nullptr, nullptr);
+ if (NS_FAILED(rv))
+ return rv;
+ return CallGetService(kCharsetConverterManagerCID, &ccMan);
+}
+
+nsresult done()
+{
+ NS_RELEASE(ccMan);
+ return NS_OK;
+}
+
+int main(int argc, char **argv)
+{
+ nsresult res;
+
+ res = init();
+ if (NS_FAILED(res)) return -1;
+
+ if (argc <= 1) {
+ printf("*** Unicode Converters Test ***\n");
+ res = testAll();
+ printf("\n***--------- Done --------***\n");
+ } else {
+ res = testFromArgs(argc, argv);
+ }
+
+ done();
+
+ if (NS_FAILED(res)) return -1;
+ else return 0;
+}