1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/uconv/tests/TestUConv.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,531 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "nsIServiceManager.h" 1.10 +#include "nsICharsetConverterManager.h" 1.11 +#include "nsUCSupport.h" 1.12 +#include "nsString.h" 1.13 +#include "nsIStringEnumerator.h" 1.14 +#include "nsTArray.h" 1.15 + 1.16 +//---------------------------------------------------------------------------- 1.17 +// Global functions and data [declaration] 1.18 + 1.19 +#define ARRAY_SIZE(_array) (sizeof(_array) / sizeof(_array[0])) 1.20 +#define SMALL_BUFFER_SIZE 512 1.21 +#define MED_BUFFER_SIZE 1024 1.22 +#define BIG_BUFFER_SIZE 2048 1.23 + 1.24 +static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID); 1.25 + 1.26 +//---------------------------------------------------------------------------- 1.27 +// Class nsTestLog [declaration] 1.28 + 1.29 +/** 1.30 + * A Logging class for test programs. 1.31 + * 1.32 + * This simple test program will not trigger a component registration. So 1.33 + * Mozilla has to be run once before running this, so that the necessary 1.34 + * components will be registered. Also, please observe that the ContractID's are 1.35 + * case sensitive now! 1.36 + * 1.37 + * @created 28/Mar/2000 1.38 + * @author Catalin Rotaru [CATA] 1.39 + */ 1.40 +class nsTestLog 1.41 +{ 1.42 +private: 1.43 + 1.44 + static const char * kTraceDelimiter; 1.45 + 1.46 + nsAutoCString mTrace; 1.47 + 1.48 +public: 1.49 + 1.50 + void AddTrace(const char * aTrace); 1.51 + void DelTrace(const char * aTrace); 1.52 + void PrintError(const char * aCall, const int aError); 1.53 + void PrintError(const char * aCall, const char * aMessage); 1.54 +}; 1.55 + 1.56 +//---------------------------------------------------------------------------- 1.57 +// Class nsTestUConv [declaration] 1.58 + 1.59 +/** 1.60 + * The main class of the program. 1.61 + * 1.62 + * XXX Create a very general set of "bug and regression" test cases and the 1.63 + * one in TestTempBug() 1.64 + * XXX Apply the new argument style (pointers) to the converters interfaces 1.65 + * 1.66 + * @created 28/Mar/2000 1.67 + * @author Catalin Rotaru [CATA] 1.68 + */ 1.69 +class nsTestUConv 1.70 +{ 1.71 +private: 1.72 + 1.73 + nsTestLog mLog; 1.74 + 1.75 + /** 1.76 + * Run the built-in set of self tests for encoders. 1.77 + */ 1.78 + nsresult TestEncoders(); 1.79 + 1.80 + /** 1.81 + * Run the built-in set of self tests for decoders. 1.82 + */ 1.83 + nsresult TestDecoders(); 1.84 + 1.85 + /** 1.86 + * Run the built-in set of self tests for the CharsetManager. 1.87 + */ 1.88 + nsresult TestCharsetManager(); 1.89 + 1.90 + /** 1.91 + * Display charset detectors and their attributes. 1.92 + */ 1.93 + nsresult DisplayDetectors(); 1.94 + 1.95 + /** 1.96 + * Display charsets and their attributes. 1.97 + */ 1.98 + nsresult DisplayCharsets(); 1.99 + 1.100 + /** 1.101 + * Run a temporary debug test. This method is ment as a placeholder when some 1.102 + * quick debugging is needed. 1.103 + */ 1.104 + nsresult TestTempBug(); 1.105 + 1.106 + nsresult Encode(char16_t ** aSrc, char16_t * aSrcEnd, char ** aDest, 1.107 + char * aDestEnd, const nsAFlatCString& aCharset); 1.108 + 1.109 + /** 1.110 + * Bridge methods between the new argument style (poiters) and the old one 1.111 + * (lengths). To be removed when the converter interfaces will switch to the 1.112 + * new style. 1.113 + * 1.114 + * This wraps an encoder Convert() call. 1.115 + */ 1.116 + nsresult ConvertEncode(char16_t ** aSrc, char16_t * aSrcEnd, char ** aDest, 1.117 + char * aDestEnd, nsIUnicodeEncoder * aEncoder); 1.118 + 1.119 + /** 1.120 + * This wraps an encoder Finish() call. 1.121 + */ 1.122 + nsresult FinishEncode(char ** aDest, char * aDestEnd, 1.123 + nsIUnicodeEncoder * aEncoder); 1.124 + 1.125 + void PrintSpaces(int aCount); 1.126 + 1.127 +public: 1.128 + 1.129 + /** 1.130 + * Main method of the program. 1.131 + */ 1.132 + nsresult Main(int aArgC, char ** aArgV); 1.133 +}; 1.134 + 1.135 +//---------------------------------------------------------------------------- 1.136 +// Global functions and data [implementation] 1.137 + 1.138 +int main(int argc, char ** argv) 1.139 +{ 1.140 + nsTestUConv testObj; 1.141 + nsresult res; 1.142 + 1.143 + res = testObj.Main(argc, argv); 1.144 + return (NS_FAILED(res)); 1.145 +} 1.146 + 1.147 +//---------------------------------------------------------------------------- 1.148 +// Class nsTestLog [implementation] 1.149 + 1.150 +const char * nsTestLog::kTraceDelimiter = "."; 1.151 + 1.152 +void nsTestLog::AddTrace(const char * aTrace) 1.153 +{ 1.154 + mTrace.Append(aTrace); 1.155 + mTrace.Append(kTraceDelimiter); 1.156 +} 1.157 + 1.158 +void nsTestLog::DelTrace(const char * aTrace) 1.159 +{ 1.160 + mTrace.Truncate(mTrace.Length() - strlen(aTrace) - strlen(kTraceDelimiter)); 1.161 +} 1.162 + 1.163 +void nsTestLog::PrintError(const char * aCall, const int aError) 1.164 +{ 1.165 + const char * trace = mTrace.get(); 1.166 + printf("ERROR at %s%s code=0x%x.\n", trace, aCall, aError); 1.167 +} 1.168 + 1.169 +void nsTestLog::PrintError(const char * aCall, const char * aMessage) 1.170 +{ 1.171 + const char * trace = mTrace.get(); 1.172 + printf("ERROR at %s%s reason: %s.\n", trace, aCall, aMessage); 1.173 +} 1.174 + 1.175 +//---------------------------------------------------------------------------- 1.176 +// Class nsTestUConv [implementation] 1.177 + 1.178 +nsresult nsTestUConv::TestEncoders() 1.179 +{ 1.180 + const char * trace = "TestEncoders"; 1.181 + mLog.AddTrace(trace); 1.182 + nsresult res = NS_OK; 1.183 + 1.184 + nsCOMPtr<nsICharsetConverterManager> ccMan = 1.185 + do_GetService(kCharsetConverterManagerCID, &res); 1.186 + if (NS_FAILED(res)) return res; 1.187 + 1.188 + nsCOMPtr<nsIUTF8StringEnumerator> encoders; 1.189 + res = ccMan->GetEncoderList(getter_AddRefs(encoders)); 1.190 + if (NS_FAILED(res)) return res; 1.191 + 1.192 + bool hasMore; 1.193 + encoders->HasMore(&hasMore); 1.194 + 1.195 + nsAutoCString charset; 1.196 + while (hasMore) { 1.197 + encoders->GetNext(charset); 1.198 + 1.199 + encoders->HasMore(&hasMore); 1.200 + } 1.201 + 1.202 + mLog.DelTrace(trace); 1.203 + return res; 1.204 +} 1.205 + 1.206 +nsresult nsTestUConv::TestDecoders() 1.207 +{ 1.208 + const char * trace = "TestDecoders"; 1.209 + mLog.AddTrace(trace); 1.210 + nsresult res = NS_OK; 1.211 + 1.212 + // XXX write me 1.213 + 1.214 + mLog.DelTrace(trace); 1.215 + return res; 1.216 +} 1.217 + 1.218 +nsresult nsTestUConv::TestCharsetManager() 1.219 +{ 1.220 + const char * trace = "TestCharsetManager"; 1.221 + mLog.AddTrace(trace); 1.222 + nsresult res = NS_OK; 1.223 + nsAutoString name; 1.224 + nsCOMPtr<nsIAtom> csAtom; 1.225 + 1.226 + nsCOMPtr<nsICharsetConverterManager> ccMan = 1.227 + do_GetService(kCharsetConverterManagerCID, &res); 1.228 + if (NS_FAILED(res)) { 1.229 + mLog.PrintError("NS_WITH_SERVICE", res); 1.230 + return res; 1.231 + } 1.232 + 1.233 + mLog.DelTrace(trace); 1.234 + return res; 1.235 +} 1.236 + 1.237 +nsresult nsTestUConv::DisplayDetectors() 1.238 +{ 1.239 + const char * trace = "DisplayDetectors"; 1.240 + mLog.AddTrace(trace); 1.241 + nsresult res = NS_OK; 1.242 + 1.243 + nsCOMPtr<nsICharsetConverterManager> ccMan = 1.244 + do_GetService(kCharsetConverterManagerCID, &res); 1.245 + if (NS_FAILED(res)) { 1.246 + mLog.PrintError("NS_WITH_SERVICE", res); 1.247 + return res; 1.248 + } 1.249 + 1.250 + // charset detectors 1.251 + nsCOMPtr<nsIUTF8StringEnumerator> detectors; 1.252 + 1.253 + res = ccMan->GetCharsetDetectorList(getter_AddRefs(detectors)); 1.254 + if (NS_FAILED(res)) { 1.255 + mLog.PrintError("GetCharsetDetectorList()", res); 1.256 + return res; 1.257 + } 1.258 + 1.259 + printf("***** Character Set Detectors *****\n"); 1.260 + 1.261 + bool hasMore; 1.262 + detectors->HasMore(&hasMore); 1.263 + while (hasMore) { 1.264 + nsAutoCString detectorName; 1.265 + res = detectors->GetNext(detectorName); 1.266 + if (NS_FAILED(res)) { 1.267 + mLog.PrintError("GetNext()", res); 1.268 + return res; 1.269 + } 1.270 + 1.271 + printf("%s", detectorName.get()); 1.272 + PrintSpaces(36 - detectorName.Length()); // align to hard coded column number 1.273 + 1.274 + nsAutoString title; 1.275 + res = ccMan->GetCharsetTitle(detectorName.get(), title); 1.276 + if (NS_FAILED(res)) title.SetLength(0); 1.277 + printf("\"%s\"\n", NS_LossyConvertUTF16toASCII(title).get()); 1.278 + 1.279 + detectors->HasMore(&hasMore); 1.280 + } 1.281 + 1.282 + mLog.DelTrace(trace); 1.283 + return NS_OK; 1.284 +} 1.285 + 1.286 +nsresult nsTestUConv::DisplayCharsets() 1.287 +{ 1.288 + const char * trace = "DisplayCharsets"; 1.289 + mLog.AddTrace(trace); 1.290 + nsresult res = NS_OK; 1.291 + 1.292 + nsCOMPtr<nsICharsetConverterManager> ccMan = 1.293 + do_GetService(kCharsetConverterManagerCID, &res); 1.294 + if (NS_FAILED(res)) { 1.295 + mLog.PrintError("NS_WITH_SERVICE", res); 1.296 + return res; 1.297 + } 1.298 + 1.299 + nsCOMPtr<nsIUTF8StringEnumerator> decoders; 1.300 + nsCOMPtr<nsIUTF8StringEnumerator> encoders; 1.301 + 1.302 + res = ccMan->GetDecoderList(getter_AddRefs(decoders)); 1.303 + if (NS_FAILED(res)) { 1.304 + mLog.PrintError("GetDecoderList()", res); 1.305 + return res; 1.306 + } 1.307 + 1.308 + res = ccMan->GetEncoderList(getter_AddRefs(encoders)); 1.309 + if (NS_FAILED(res)) { 1.310 + mLog.PrintError("GetEncoderList()", res); 1.311 + return res; 1.312 + } 1.313 + 1.314 + 1.315 + printf("***** Character Sets *****\n"); 1.316 + 1.317 + uint32_t encCount = 0, decCount = 0; 1.318 + uint32_t basicEncCount = 0, basicDecCount = 0; 1.319 + 1.320 + nsTArray<nsCString> allCharsets; 1.321 + 1.322 + nsAutoCString charset; 1.323 + bool hasMore; 1.324 + encoders->HasMore(&hasMore); 1.325 + while (hasMore) { 1.326 + res = encoders->GetNext(charset); 1.327 + if (NS_SUCCEEDED(res)) 1.328 + allCharsets.AppendElement(charset); 1.329 + 1.330 + encoders->HasMore(&hasMore); 1.331 + } 1.332 + 1.333 + nsAutoString prop, str; 1.334 + uint32_t count = allCharsets.Length(); 1.335 + for (uint32_t i = 0; i < count; i++) { 1.336 + 1.337 + const nsCString& charset = allCharsets[i]; 1.338 + printf("%s", charset.get()); 1.339 + PrintSpaces(24 - charset.Length()); // align to hard coded column number 1.340 + 1.341 + 1.342 + nsCOMPtr<nsIUnicodeDecoder> dec; 1.343 + res = ccMan->GetUnicodeDecoder(charset.get(), getter_AddRefs(dec)); 1.344 + if (NS_FAILED(res)) printf (" "); 1.345 + else { 1.346 + printf("D"); 1.347 + decCount++; 1.348 + } 1.349 +#ifdef DEBUG 1.350 + // show the "basic" decoder classes 1.351 + if (dec) { 1.352 + nsCOMPtr<nsIBasicDecoder> isBasic = do_QueryInterface(dec); 1.353 + if (isBasic) { 1.354 + basicDecCount++; 1.355 + printf("b"); 1.356 + } 1.357 + else printf(" "); 1.358 + } 1.359 + else printf(" "); 1.360 +#endif 1.361 + 1.362 + nsCOMPtr<nsIUnicodeEncoder> enc; 1.363 + res = ccMan->GetUnicodeEncoder(charset.get(), getter_AddRefs(enc)); 1.364 + if (NS_FAILED(res)) printf (" "); 1.365 + else { 1.366 + printf("E"); 1.367 + encCount++; 1.368 + } 1.369 + 1.370 +#ifdef DEBUG 1.371 + if (enc) { 1.372 + nsCOMPtr<nsIBasicEncoder> isBasic = do_QueryInterface(enc); 1.373 + if (isBasic) { 1.374 + basicEncCount++; 1.375 + printf("b"); 1.376 + } 1.377 + else printf(" "); 1.378 + } 1.379 + else printf(" "); 1.380 +#endif 1.381 + 1.382 + printf(" "); 1.383 + 1.384 + prop.AssignLiteral(".notForBrowser"); 1.385 + res = ccMan->GetCharsetData(charset.get(), prop.get(), str); 1.386 + if (dec && (NS_FAILED(res))) printf ("B"); 1.387 + else printf("X"); 1.388 + 1.389 + prop.AssignLiteral(".notForComposer"); 1.390 + res = ccMan->GetCharsetData(charset.get(), prop.get(), str); 1.391 + if (enc && (NS_FAILED(res))) printf ("C"); 1.392 + else printf("X"); 1.393 + 1.394 + prop.AssignLiteral(".notForMailView"); 1.395 + res = ccMan->GetCharsetData(charset.get(), prop.get(), str); 1.396 + if (dec && (NS_FAILED(res))) printf ("V"); 1.397 + else printf("X"); 1.398 + 1.399 + prop.AssignLiteral(".notForMailEdit"); 1.400 + res = ccMan->GetCharsetData(charset.get(), prop.get(), str); 1.401 + if (enc && (NS_FAILED(res))) printf ("E"); 1.402 + else printf("X"); 1.403 + 1.404 + printf("(%3d, %3d) ", encCount, decCount); 1.405 + res = ccMan->GetCharsetTitle(charset.get(), str); 1.406 + if (NS_FAILED(res)) str.SetLength(0); 1.407 + NS_LossyConvertUTF16toASCII buff2(str); 1.408 + printf(" \"%s\"\n", buff2.get()); 1.409 + } 1.410 + 1.411 + printf("%u of %u decoders are basic (%d%%)\n", 1.412 + basicDecCount, decCount, (basicDecCount * 100) / decCount); 1.413 + 1.414 + printf("%u of %u encoders are basic (%d%%)\n", 1.415 + basicEncCount, encCount, (basicEncCount * 100) / encCount); 1.416 + mLog.DelTrace(trace); 1.417 + return NS_OK; 1.418 +} 1.419 + 1.420 +nsresult nsTestUConv::TestTempBug() 1.421 +{ 1.422 + const char * trace = "TestTempBug"; 1.423 + mLog.AddTrace(trace); 1.424 + nsresult res = NS_OK; 1.425 + 1.426 + NS_NAMED_LITERAL_CSTRING(charset, "ISO-2022-JP"); 1.427 + char16_t src[] = {0x0043, 0x004e, 0x0045, 0x0054, 0x0020, 0x004A, 0x0061, 1.428 + 0x0070, 0x0061, 0x006E, 0x0020, 0x7DE8, 0x96C6, 0x5C40}; 1.429 + char16_t * srcEnd = src + ARRAY_SIZE(src); 1.430 + char dest[BIG_BUFFER_SIZE]; 1.431 + char * destEnd = dest + BIG_BUFFER_SIZE; 1.432 + 1.433 + char16_t * p = src; 1.434 + char * q = dest; 1.435 + res = Encode(&p, srcEnd, &q, destEnd, charset); 1.436 + 1.437 + mLog.DelTrace(trace); 1.438 + return res; 1.439 +} 1.440 + 1.441 +nsresult nsTestUConv::Encode(char16_t ** aSrc, char16_t * aSrcEnd, 1.442 + char ** aDest, char * aDestEnd, 1.443 + const nsAFlatCString& aCharset) 1.444 +{ 1.445 + const char * trace = "Encode"; 1.446 + mLog.AddTrace(trace); 1.447 + nsresult res = NS_OK; 1.448 + 1.449 + nsCOMPtr<nsICharsetConverterManager> ccMan = 1.450 + do_GetService(kCharsetConverterManagerCID, &res); 1.451 + if (NS_FAILED(res)) { 1.452 + mLog.PrintError("NS_WITH_SERVICE", res); 1.453 + return res; 1.454 + } 1.455 + 1.456 + nsCOMPtr<nsIUnicodeEncoder> enc; 1.457 + res = ccMan->GetUnicodeEncoder(aCharset.get(), getter_AddRefs(enc)); 1.458 + if (NS_FAILED(res)) { 1.459 + mLog.PrintError("GetUnicodeEncoder()", res); 1.460 + return res; 1.461 + } 1.462 + 1.463 + res = ConvertEncode(aSrc, aSrcEnd, aDest, aDestEnd, enc); 1.464 + if (NS_FAILED(res)) { 1.465 + mLog.PrintError("Convert()", res); 1.466 + return res; 1.467 + } 1.468 + 1.469 + res = FinishEncode(aDest, aDestEnd, enc); 1.470 + if (NS_FAILED(res)) { 1.471 + mLog.PrintError("Finish()", res); 1.472 + return res; 1.473 + } 1.474 + 1.475 + mLog.DelTrace(trace); 1.476 + return res; 1.477 +} 1.478 + 1.479 +nsresult nsTestUConv::ConvertEncode(char16_t ** aSrc, char16_t * aSrcEnd, 1.480 + char ** aDest, char * aDestEnd, 1.481 + nsIUnicodeEncoder * aEncoder) 1.482 +{ 1.483 + char16_t * src = (*aSrc); 1.484 + char * dest = (*aDest); 1.485 + int32_t srcLen = aSrcEnd - src; 1.486 + int32_t destLen = aDestEnd - dest; 1.487 + 1.488 + nsresult res = aEncoder->Convert(src, &srcLen, dest, &destLen); 1.489 + 1.490 + (*aSrc) = src + srcLen; 1.491 + (*aDest) = dest + destLen; 1.492 + return res; 1.493 +} 1.494 + 1.495 +nsresult nsTestUConv::FinishEncode(char ** aDest, char * aDestEnd, 1.496 + nsIUnicodeEncoder * aEncoder) 1.497 +{ 1.498 + char * dest = (*aDest); 1.499 + int32_t destLen = aDestEnd - dest; 1.500 + 1.501 + nsresult res = aEncoder->Finish(dest, &destLen); 1.502 + 1.503 + (*aDest) = dest + destLen; 1.504 + return res; 1.505 +} 1.506 + 1.507 +void nsTestUConv::PrintSpaces(int aCount) 1.508 +{ 1.509 + for (int i = 0; i < aCount; i++) printf(" "); 1.510 +} 1.511 + 1.512 +nsresult nsTestUConv::Main(int aArgC, char ** aArgV) 1.513 +{ 1.514 + const char * trace = "Main"; 1.515 + mLog.AddTrace(trace); 1.516 + nsresult res = NS_OK; 1.517 + 1.518 + if (aArgC < 2) { 1.519 + // no arguments were passed to the program, so we just run the self tests 1.520 + res = TestCharsetManager(); 1.521 + if (NS_SUCCEEDED(res)) res = TestEncoders(); 1.522 + if (NS_SUCCEEDED(res)) res = TestDecoders(); 1.523 + } else if (!strcmp(aArgV[1], "-tempbug")) { 1.524 + // we are testing a temporary bug 1.525 + res = TestTempBug(); 1.526 + } else if (!strcmp(aArgV[1], "-display")) { 1.527 + // display all the available data 1.528 + res = DisplayDetectors(); 1.529 + if (NS_SUCCEEDED(res)) res = DisplayCharsets(); 1.530 + } 1.531 + 1.532 + mLog.DelTrace(trace); 1.533 + return res; 1.534 +}