intl/uconv/tests/TestUConv.cpp

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "nsIServiceManager.h"
michael@0 7 #include "nsICharsetConverterManager.h"
michael@0 8 #include "nsUCSupport.h"
michael@0 9 #include "nsString.h"
michael@0 10 #include "nsIStringEnumerator.h"
michael@0 11 #include "nsTArray.h"
michael@0 12
michael@0 13 //----------------------------------------------------------------------------
michael@0 14 // Global functions and data [declaration]
michael@0 15
michael@0 16 #define ARRAY_SIZE(_array) (sizeof(_array) / sizeof(_array[0]))
michael@0 17 #define SMALL_BUFFER_SIZE 512
michael@0 18 #define MED_BUFFER_SIZE 1024
michael@0 19 #define BIG_BUFFER_SIZE 2048
michael@0 20
michael@0 21 static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
michael@0 22
michael@0 23 //----------------------------------------------------------------------------
michael@0 24 // Class nsTestLog [declaration]
michael@0 25
michael@0 26 /**
michael@0 27 * A Logging class for test programs.
michael@0 28 *
michael@0 29 * This simple test program will not trigger a component registration. So
michael@0 30 * Mozilla has to be run once before running this, so that the necessary
michael@0 31 * components will be registered. Also, please observe that the ContractID's are
michael@0 32 * case sensitive now!
michael@0 33 *
michael@0 34 * @created 28/Mar/2000
michael@0 35 * @author Catalin Rotaru [CATA]
michael@0 36 */
michael@0 37 class nsTestLog
michael@0 38 {
michael@0 39 private:
michael@0 40
michael@0 41 static const char * kTraceDelimiter;
michael@0 42
michael@0 43 nsAutoCString mTrace;
michael@0 44
michael@0 45 public:
michael@0 46
michael@0 47 void AddTrace(const char * aTrace);
michael@0 48 void DelTrace(const char * aTrace);
michael@0 49 void PrintError(const char * aCall, const int aError);
michael@0 50 void PrintError(const char * aCall, const char * aMessage);
michael@0 51 };
michael@0 52
michael@0 53 //----------------------------------------------------------------------------
michael@0 54 // Class nsTestUConv [declaration]
michael@0 55
michael@0 56 /**
michael@0 57 * The main class of the program.
michael@0 58 *
michael@0 59 * XXX Create a very general set of "bug and regression" test cases and the
michael@0 60 * one in TestTempBug()
michael@0 61 * XXX Apply the new argument style (pointers) to the converters interfaces
michael@0 62 *
michael@0 63 * @created 28/Mar/2000
michael@0 64 * @author Catalin Rotaru [CATA]
michael@0 65 */
michael@0 66 class nsTestUConv
michael@0 67 {
michael@0 68 private:
michael@0 69
michael@0 70 nsTestLog mLog;
michael@0 71
michael@0 72 /**
michael@0 73 * Run the built-in set of self tests for encoders.
michael@0 74 */
michael@0 75 nsresult TestEncoders();
michael@0 76
michael@0 77 /**
michael@0 78 * Run the built-in set of self tests for decoders.
michael@0 79 */
michael@0 80 nsresult TestDecoders();
michael@0 81
michael@0 82 /**
michael@0 83 * Run the built-in set of self tests for the CharsetManager.
michael@0 84 */
michael@0 85 nsresult TestCharsetManager();
michael@0 86
michael@0 87 /**
michael@0 88 * Display charset detectors and their attributes.
michael@0 89 */
michael@0 90 nsresult DisplayDetectors();
michael@0 91
michael@0 92 /**
michael@0 93 * Display charsets and their attributes.
michael@0 94 */
michael@0 95 nsresult DisplayCharsets();
michael@0 96
michael@0 97 /**
michael@0 98 * Run a temporary debug test. This method is ment as a placeholder when some
michael@0 99 * quick debugging is needed.
michael@0 100 */
michael@0 101 nsresult TestTempBug();
michael@0 102
michael@0 103 nsresult Encode(char16_t ** aSrc, char16_t * aSrcEnd, char ** aDest,
michael@0 104 char * aDestEnd, const nsAFlatCString& aCharset);
michael@0 105
michael@0 106 /**
michael@0 107 * Bridge methods between the new argument style (poiters) and the old one
michael@0 108 * (lengths). To be removed when the converter interfaces will switch to the
michael@0 109 * new style.
michael@0 110 *
michael@0 111 * This wraps an encoder Convert() call.
michael@0 112 */
michael@0 113 nsresult ConvertEncode(char16_t ** aSrc, char16_t * aSrcEnd, char ** aDest,
michael@0 114 char * aDestEnd, nsIUnicodeEncoder * aEncoder);
michael@0 115
michael@0 116 /**
michael@0 117 * This wraps an encoder Finish() call.
michael@0 118 */
michael@0 119 nsresult FinishEncode(char ** aDest, char * aDestEnd,
michael@0 120 nsIUnicodeEncoder * aEncoder);
michael@0 121
michael@0 122 void PrintSpaces(int aCount);
michael@0 123
michael@0 124 public:
michael@0 125
michael@0 126 /**
michael@0 127 * Main method of the program.
michael@0 128 */
michael@0 129 nsresult Main(int aArgC, char ** aArgV);
michael@0 130 };
michael@0 131
michael@0 132 //----------------------------------------------------------------------------
michael@0 133 // Global functions and data [implementation]
michael@0 134
michael@0 135 int main(int argc, char ** argv)
michael@0 136 {
michael@0 137 nsTestUConv testObj;
michael@0 138 nsresult res;
michael@0 139
michael@0 140 res = testObj.Main(argc, argv);
michael@0 141 return (NS_FAILED(res));
michael@0 142 }
michael@0 143
michael@0 144 //----------------------------------------------------------------------------
michael@0 145 // Class nsTestLog [implementation]
michael@0 146
michael@0 147 const char * nsTestLog::kTraceDelimiter = ".";
michael@0 148
michael@0 149 void nsTestLog::AddTrace(const char * aTrace)
michael@0 150 {
michael@0 151 mTrace.Append(aTrace);
michael@0 152 mTrace.Append(kTraceDelimiter);
michael@0 153 }
michael@0 154
michael@0 155 void nsTestLog::DelTrace(const char * aTrace)
michael@0 156 {
michael@0 157 mTrace.Truncate(mTrace.Length() - strlen(aTrace) - strlen(kTraceDelimiter));
michael@0 158 }
michael@0 159
michael@0 160 void nsTestLog::PrintError(const char * aCall, const int aError)
michael@0 161 {
michael@0 162 const char * trace = mTrace.get();
michael@0 163 printf("ERROR at %s%s code=0x%x.\n", trace, aCall, aError);
michael@0 164 }
michael@0 165
michael@0 166 void nsTestLog::PrintError(const char * aCall, const char * aMessage)
michael@0 167 {
michael@0 168 const char * trace = mTrace.get();
michael@0 169 printf("ERROR at %s%s reason: %s.\n", trace, aCall, aMessage);
michael@0 170 }
michael@0 171
michael@0 172 //----------------------------------------------------------------------------
michael@0 173 // Class nsTestUConv [implementation]
michael@0 174
michael@0 175 nsresult nsTestUConv::TestEncoders()
michael@0 176 {
michael@0 177 const char * trace = "TestEncoders";
michael@0 178 mLog.AddTrace(trace);
michael@0 179 nsresult res = NS_OK;
michael@0 180
michael@0 181 nsCOMPtr<nsICharsetConverterManager> ccMan =
michael@0 182 do_GetService(kCharsetConverterManagerCID, &res);
michael@0 183 if (NS_FAILED(res)) return res;
michael@0 184
michael@0 185 nsCOMPtr<nsIUTF8StringEnumerator> encoders;
michael@0 186 res = ccMan->GetEncoderList(getter_AddRefs(encoders));
michael@0 187 if (NS_FAILED(res)) return res;
michael@0 188
michael@0 189 bool hasMore;
michael@0 190 encoders->HasMore(&hasMore);
michael@0 191
michael@0 192 nsAutoCString charset;
michael@0 193 while (hasMore) {
michael@0 194 encoders->GetNext(charset);
michael@0 195
michael@0 196 encoders->HasMore(&hasMore);
michael@0 197 }
michael@0 198
michael@0 199 mLog.DelTrace(trace);
michael@0 200 return res;
michael@0 201 }
michael@0 202
michael@0 203 nsresult nsTestUConv::TestDecoders()
michael@0 204 {
michael@0 205 const char * trace = "TestDecoders";
michael@0 206 mLog.AddTrace(trace);
michael@0 207 nsresult res = NS_OK;
michael@0 208
michael@0 209 // XXX write me
michael@0 210
michael@0 211 mLog.DelTrace(trace);
michael@0 212 return res;
michael@0 213 }
michael@0 214
michael@0 215 nsresult nsTestUConv::TestCharsetManager()
michael@0 216 {
michael@0 217 const char * trace = "TestCharsetManager";
michael@0 218 mLog.AddTrace(trace);
michael@0 219 nsresult res = NS_OK;
michael@0 220 nsAutoString name;
michael@0 221 nsCOMPtr<nsIAtom> csAtom;
michael@0 222
michael@0 223 nsCOMPtr<nsICharsetConverterManager> ccMan =
michael@0 224 do_GetService(kCharsetConverterManagerCID, &res);
michael@0 225 if (NS_FAILED(res)) {
michael@0 226 mLog.PrintError("NS_WITH_SERVICE", res);
michael@0 227 return res;
michael@0 228 }
michael@0 229
michael@0 230 mLog.DelTrace(trace);
michael@0 231 return res;
michael@0 232 }
michael@0 233
michael@0 234 nsresult nsTestUConv::DisplayDetectors()
michael@0 235 {
michael@0 236 const char * trace = "DisplayDetectors";
michael@0 237 mLog.AddTrace(trace);
michael@0 238 nsresult res = NS_OK;
michael@0 239
michael@0 240 nsCOMPtr<nsICharsetConverterManager> ccMan =
michael@0 241 do_GetService(kCharsetConverterManagerCID, &res);
michael@0 242 if (NS_FAILED(res)) {
michael@0 243 mLog.PrintError("NS_WITH_SERVICE", res);
michael@0 244 return res;
michael@0 245 }
michael@0 246
michael@0 247 // charset detectors
michael@0 248 nsCOMPtr<nsIUTF8StringEnumerator> detectors;
michael@0 249
michael@0 250 res = ccMan->GetCharsetDetectorList(getter_AddRefs(detectors));
michael@0 251 if (NS_FAILED(res)) {
michael@0 252 mLog.PrintError("GetCharsetDetectorList()", res);
michael@0 253 return res;
michael@0 254 }
michael@0 255
michael@0 256 printf("***** Character Set Detectors *****\n");
michael@0 257
michael@0 258 bool hasMore;
michael@0 259 detectors->HasMore(&hasMore);
michael@0 260 while (hasMore) {
michael@0 261 nsAutoCString detectorName;
michael@0 262 res = detectors->GetNext(detectorName);
michael@0 263 if (NS_FAILED(res)) {
michael@0 264 mLog.PrintError("GetNext()", res);
michael@0 265 return res;
michael@0 266 }
michael@0 267
michael@0 268 printf("%s", detectorName.get());
michael@0 269 PrintSpaces(36 - detectorName.Length()); // align to hard coded column number
michael@0 270
michael@0 271 nsAutoString title;
michael@0 272 res = ccMan->GetCharsetTitle(detectorName.get(), title);
michael@0 273 if (NS_FAILED(res)) title.SetLength(0);
michael@0 274 printf("\"%s\"\n", NS_LossyConvertUTF16toASCII(title).get());
michael@0 275
michael@0 276 detectors->HasMore(&hasMore);
michael@0 277 }
michael@0 278
michael@0 279 mLog.DelTrace(trace);
michael@0 280 return NS_OK;
michael@0 281 }
michael@0 282
michael@0 283 nsresult nsTestUConv::DisplayCharsets()
michael@0 284 {
michael@0 285 const char * trace = "DisplayCharsets";
michael@0 286 mLog.AddTrace(trace);
michael@0 287 nsresult res = NS_OK;
michael@0 288
michael@0 289 nsCOMPtr<nsICharsetConverterManager> ccMan =
michael@0 290 do_GetService(kCharsetConverterManagerCID, &res);
michael@0 291 if (NS_FAILED(res)) {
michael@0 292 mLog.PrintError("NS_WITH_SERVICE", res);
michael@0 293 return res;
michael@0 294 }
michael@0 295
michael@0 296 nsCOMPtr<nsIUTF8StringEnumerator> decoders;
michael@0 297 nsCOMPtr<nsIUTF8StringEnumerator> encoders;
michael@0 298
michael@0 299 res = ccMan->GetDecoderList(getter_AddRefs(decoders));
michael@0 300 if (NS_FAILED(res)) {
michael@0 301 mLog.PrintError("GetDecoderList()", res);
michael@0 302 return res;
michael@0 303 }
michael@0 304
michael@0 305 res = ccMan->GetEncoderList(getter_AddRefs(encoders));
michael@0 306 if (NS_FAILED(res)) {
michael@0 307 mLog.PrintError("GetEncoderList()", res);
michael@0 308 return res;
michael@0 309 }
michael@0 310
michael@0 311
michael@0 312 printf("***** Character Sets *****\n");
michael@0 313
michael@0 314 uint32_t encCount = 0, decCount = 0;
michael@0 315 uint32_t basicEncCount = 0, basicDecCount = 0;
michael@0 316
michael@0 317 nsTArray<nsCString> allCharsets;
michael@0 318
michael@0 319 nsAutoCString charset;
michael@0 320 bool hasMore;
michael@0 321 encoders->HasMore(&hasMore);
michael@0 322 while (hasMore) {
michael@0 323 res = encoders->GetNext(charset);
michael@0 324 if (NS_SUCCEEDED(res))
michael@0 325 allCharsets.AppendElement(charset);
michael@0 326
michael@0 327 encoders->HasMore(&hasMore);
michael@0 328 }
michael@0 329
michael@0 330 nsAutoString prop, str;
michael@0 331 uint32_t count = allCharsets.Length();
michael@0 332 for (uint32_t i = 0; i < count; i++) {
michael@0 333
michael@0 334 const nsCString& charset = allCharsets[i];
michael@0 335 printf("%s", charset.get());
michael@0 336 PrintSpaces(24 - charset.Length()); // align to hard coded column number
michael@0 337
michael@0 338
michael@0 339 nsCOMPtr<nsIUnicodeDecoder> dec;
michael@0 340 res = ccMan->GetUnicodeDecoder(charset.get(), getter_AddRefs(dec));
michael@0 341 if (NS_FAILED(res)) printf (" ");
michael@0 342 else {
michael@0 343 printf("D");
michael@0 344 decCount++;
michael@0 345 }
michael@0 346 #ifdef DEBUG
michael@0 347 // show the "basic" decoder classes
michael@0 348 if (dec) {
michael@0 349 nsCOMPtr<nsIBasicDecoder> isBasic = do_QueryInterface(dec);
michael@0 350 if (isBasic) {
michael@0 351 basicDecCount++;
michael@0 352 printf("b");
michael@0 353 }
michael@0 354 else printf(" ");
michael@0 355 }
michael@0 356 else printf(" ");
michael@0 357 #endif
michael@0 358
michael@0 359 nsCOMPtr<nsIUnicodeEncoder> enc;
michael@0 360 res = ccMan->GetUnicodeEncoder(charset.get(), getter_AddRefs(enc));
michael@0 361 if (NS_FAILED(res)) printf (" ");
michael@0 362 else {
michael@0 363 printf("E");
michael@0 364 encCount++;
michael@0 365 }
michael@0 366
michael@0 367 #ifdef DEBUG
michael@0 368 if (enc) {
michael@0 369 nsCOMPtr<nsIBasicEncoder> isBasic = do_QueryInterface(enc);
michael@0 370 if (isBasic) {
michael@0 371 basicEncCount++;
michael@0 372 printf("b");
michael@0 373 }
michael@0 374 else printf(" ");
michael@0 375 }
michael@0 376 else printf(" ");
michael@0 377 #endif
michael@0 378
michael@0 379 printf(" ");
michael@0 380
michael@0 381 prop.AssignLiteral(".notForBrowser");
michael@0 382 res = ccMan->GetCharsetData(charset.get(), prop.get(), str);
michael@0 383 if (dec && (NS_FAILED(res))) printf ("B");
michael@0 384 else printf("X");
michael@0 385
michael@0 386 prop.AssignLiteral(".notForComposer");
michael@0 387 res = ccMan->GetCharsetData(charset.get(), prop.get(), str);
michael@0 388 if (enc && (NS_FAILED(res))) printf ("C");
michael@0 389 else printf("X");
michael@0 390
michael@0 391 prop.AssignLiteral(".notForMailView");
michael@0 392 res = ccMan->GetCharsetData(charset.get(), prop.get(), str);
michael@0 393 if (dec && (NS_FAILED(res))) printf ("V");
michael@0 394 else printf("X");
michael@0 395
michael@0 396 prop.AssignLiteral(".notForMailEdit");
michael@0 397 res = ccMan->GetCharsetData(charset.get(), prop.get(), str);
michael@0 398 if (enc && (NS_FAILED(res))) printf ("E");
michael@0 399 else printf("X");
michael@0 400
michael@0 401 printf("(%3d, %3d) ", encCount, decCount);
michael@0 402 res = ccMan->GetCharsetTitle(charset.get(), str);
michael@0 403 if (NS_FAILED(res)) str.SetLength(0);
michael@0 404 NS_LossyConvertUTF16toASCII buff2(str);
michael@0 405 printf(" \"%s\"\n", buff2.get());
michael@0 406 }
michael@0 407
michael@0 408 printf("%u of %u decoders are basic (%d%%)\n",
michael@0 409 basicDecCount, decCount, (basicDecCount * 100) / decCount);
michael@0 410
michael@0 411 printf("%u of %u encoders are basic (%d%%)\n",
michael@0 412 basicEncCount, encCount, (basicEncCount * 100) / encCount);
michael@0 413 mLog.DelTrace(trace);
michael@0 414 return NS_OK;
michael@0 415 }
michael@0 416
michael@0 417 nsresult nsTestUConv::TestTempBug()
michael@0 418 {
michael@0 419 const char * trace = "TestTempBug";
michael@0 420 mLog.AddTrace(trace);
michael@0 421 nsresult res = NS_OK;
michael@0 422
michael@0 423 NS_NAMED_LITERAL_CSTRING(charset, "ISO-2022-JP");
michael@0 424 char16_t src[] = {0x0043, 0x004e, 0x0045, 0x0054, 0x0020, 0x004A, 0x0061,
michael@0 425 0x0070, 0x0061, 0x006E, 0x0020, 0x7DE8, 0x96C6, 0x5C40};
michael@0 426 char16_t * srcEnd = src + ARRAY_SIZE(src);
michael@0 427 char dest[BIG_BUFFER_SIZE];
michael@0 428 char * destEnd = dest + BIG_BUFFER_SIZE;
michael@0 429
michael@0 430 char16_t * p = src;
michael@0 431 char * q = dest;
michael@0 432 res = Encode(&p, srcEnd, &q, destEnd, charset);
michael@0 433
michael@0 434 mLog.DelTrace(trace);
michael@0 435 return res;
michael@0 436 }
michael@0 437
michael@0 438 nsresult nsTestUConv::Encode(char16_t ** aSrc, char16_t * aSrcEnd,
michael@0 439 char ** aDest, char * aDestEnd,
michael@0 440 const nsAFlatCString& aCharset)
michael@0 441 {
michael@0 442 const char * trace = "Encode";
michael@0 443 mLog.AddTrace(trace);
michael@0 444 nsresult res = NS_OK;
michael@0 445
michael@0 446 nsCOMPtr<nsICharsetConverterManager> ccMan =
michael@0 447 do_GetService(kCharsetConverterManagerCID, &res);
michael@0 448 if (NS_FAILED(res)) {
michael@0 449 mLog.PrintError("NS_WITH_SERVICE", res);
michael@0 450 return res;
michael@0 451 }
michael@0 452
michael@0 453 nsCOMPtr<nsIUnicodeEncoder> enc;
michael@0 454 res = ccMan->GetUnicodeEncoder(aCharset.get(), getter_AddRefs(enc));
michael@0 455 if (NS_FAILED(res)) {
michael@0 456 mLog.PrintError("GetUnicodeEncoder()", res);
michael@0 457 return res;
michael@0 458 }
michael@0 459
michael@0 460 res = ConvertEncode(aSrc, aSrcEnd, aDest, aDestEnd, enc);
michael@0 461 if (NS_FAILED(res)) {
michael@0 462 mLog.PrintError("Convert()", res);
michael@0 463 return res;
michael@0 464 }
michael@0 465
michael@0 466 res = FinishEncode(aDest, aDestEnd, enc);
michael@0 467 if (NS_FAILED(res)) {
michael@0 468 mLog.PrintError("Finish()", res);
michael@0 469 return res;
michael@0 470 }
michael@0 471
michael@0 472 mLog.DelTrace(trace);
michael@0 473 return res;
michael@0 474 }
michael@0 475
michael@0 476 nsresult nsTestUConv::ConvertEncode(char16_t ** aSrc, char16_t * aSrcEnd,
michael@0 477 char ** aDest, char * aDestEnd,
michael@0 478 nsIUnicodeEncoder * aEncoder)
michael@0 479 {
michael@0 480 char16_t * src = (*aSrc);
michael@0 481 char * dest = (*aDest);
michael@0 482 int32_t srcLen = aSrcEnd - src;
michael@0 483 int32_t destLen = aDestEnd - dest;
michael@0 484
michael@0 485 nsresult res = aEncoder->Convert(src, &srcLen, dest, &destLen);
michael@0 486
michael@0 487 (*aSrc) = src + srcLen;
michael@0 488 (*aDest) = dest + destLen;
michael@0 489 return res;
michael@0 490 }
michael@0 491
michael@0 492 nsresult nsTestUConv::FinishEncode(char ** aDest, char * aDestEnd,
michael@0 493 nsIUnicodeEncoder * aEncoder)
michael@0 494 {
michael@0 495 char * dest = (*aDest);
michael@0 496 int32_t destLen = aDestEnd - dest;
michael@0 497
michael@0 498 nsresult res = aEncoder->Finish(dest, &destLen);
michael@0 499
michael@0 500 (*aDest) = dest + destLen;
michael@0 501 return res;
michael@0 502 }
michael@0 503
michael@0 504 void nsTestUConv::PrintSpaces(int aCount)
michael@0 505 {
michael@0 506 for (int i = 0; i < aCount; i++) printf(" ");
michael@0 507 }
michael@0 508
michael@0 509 nsresult nsTestUConv::Main(int aArgC, char ** aArgV)
michael@0 510 {
michael@0 511 const char * trace = "Main";
michael@0 512 mLog.AddTrace(trace);
michael@0 513 nsresult res = NS_OK;
michael@0 514
michael@0 515 if (aArgC < 2) {
michael@0 516 // no arguments were passed to the program, so we just run the self tests
michael@0 517 res = TestCharsetManager();
michael@0 518 if (NS_SUCCEEDED(res)) res = TestEncoders();
michael@0 519 if (NS_SUCCEEDED(res)) res = TestDecoders();
michael@0 520 } else if (!strcmp(aArgV[1], "-tempbug")) {
michael@0 521 // we are testing a temporary bug
michael@0 522 res = TestTempBug();
michael@0 523 } else if (!strcmp(aArgV[1], "-display")) {
michael@0 524 // display all the available data
michael@0 525 res = DisplayDetectors();
michael@0 526 if (NS_SUCCEEDED(res)) res = DisplayCharsets();
michael@0 527 }
michael@0 528
michael@0 529 mLog.DelTrace(trace);
michael@0 530 return res;
michael@0 531 }

mercurial