Bug 448909 - Need more controls WHATWG Video tag (followup patch). r=mconnor
[wine-gecko.git] / intl / uconv / tests / TestUConv.cpp
blob56e721521a3b0d9328960ef5c426ad242dfafe6a
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is Mozilla Communicator client code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #include "nsIServiceManager.h"
39 #include "nsICharsetConverterManager.h"
40 #include "nsUCSupport.h"
41 #include "nsString.h"
42 #include "nsIStringEnumerator.h"
43 #include "nsVoidArray.h"
45 //----------------------------------------------------------------------------
46 // Global functions and data [declaration]
48 #define ARRAY_SIZE(_array) (sizeof(_array) / sizeof(_array[0]))
49 #define SMALL_BUFFER_SIZE 512
50 #define MED_BUFFER_SIZE 1024
51 #define BIG_BUFFER_SIZE 2048
53 static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
55 //----------------------------------------------------------------------------
56 // Class nsTestLog [declaration]
58 /**
59 * A Logging class for test programs.
61 * This simple test program will not trigger a component registration. So
62 * Mozilla has to be run once before running this, so that the necessary
63 * components will be registered. Also, please observe that the ContractID's are
64 * case sensitive now!
66 * @created 28/Mar/2000
67 * @author Catalin Rotaru [CATA]
69 class nsTestLog
71 private:
73 static const char * kTraceDelimiter;
75 nsCAutoString mTrace;
77 public:
79 void AddTrace(char * aTrace);
80 void DelTrace(char * aTrace);
81 void PrintError(char * aCall, int aError);
82 void PrintError(char * aCall, char * aMessage);
85 //----------------------------------------------------------------------------
86 // Class nsTestUConv [declaration]
88 /**
89 * The main class of the program.
91 * XXX Create a very general set of "bug and regression" test cases and the
92 * one in TestTempBug()
93 * XXX Apply the new argument style (pointers) to the converters interfaces
95 * @created 28/Mar/2000
96 * @author Catalin Rotaru [CATA]
98 class nsTestUConv
100 private:
102 nsTestLog mLog;
105 * Run the built-in set of self tests for encoders.
107 nsresult TestEncoders();
110 * Run the built-in set of self tests for decoders.
112 nsresult TestDecoders();
115 * Run the built-in set of self tests for the CharsetManager.
117 nsresult TestCharsetManager();
120 * Display charset detectors and their attributes.
122 nsresult DisplayDetectors();
125 * Display charsets and their attributes.
127 nsresult DisplayCharsets();
130 * Run a temporary debug test. This method is ment as a placeholder when some
131 * quick debugging is needed.
133 nsresult TestTempBug();
135 nsresult Encode(PRUnichar ** aSrc, PRUnichar * aSrcEnd, char ** aDest,
136 char * aDestEnd, const nsAFlatCString& aCharset);
139 * Bridge methods between the new argument style (poiters) and the old one
140 * (lengths). To be removed when the converter interfaces will switch to the
141 * new style.
143 * This wraps an encoder Convert() call.
145 nsresult ConvertEncode(PRUnichar ** aSrc, PRUnichar * aSrcEnd, char ** aDest,
146 char * aDestEnd, nsIUnicodeEncoder * aEncoder);
149 * This wraps an encoder Finish() call.
151 nsresult FinishEncode(char ** aDest, char * aDestEnd,
152 nsIUnicodeEncoder * aEncoder);
154 void PrintSpaces(int aCount);
156 public:
159 * Main method of the program.
161 nsresult Main(int aArgC, char ** aArgV);
164 //----------------------------------------------------------------------------
165 // Global functions and data [implementation]
167 int main(int argc, char ** argv)
169 nsTestUConv testObj;
170 nsresult res;
172 res = testObj.Main(argc, argv);
173 return (NS_FAILED(res));
176 //----------------------------------------------------------------------------
177 // Class nsTestLog [implementation]
179 const char * nsTestLog::kTraceDelimiter = ".";
181 void nsTestLog::AddTrace(char * aTrace)
183 mTrace.Append(aTrace);
184 mTrace.Append(kTraceDelimiter);
187 void nsTestLog::DelTrace(char * aTrace)
189 mTrace.Truncate(mTrace.Length() - strlen(aTrace) - strlen(kTraceDelimiter));
192 void nsTestLog::PrintError(char * aCall, int aError)
194 const char * trace = mTrace.get();
195 printf("ERROR at %s%s code=0x%x.\n", trace, aCall, aError);
198 void nsTestLog::PrintError(char * aCall, char * aMessage)
200 const char * trace = mTrace.get();
201 printf("ERROR at %s%s reason: %s.\n", trace, aCall, aMessage);
204 //----------------------------------------------------------------------------
205 // Class nsTestUConv [implementation]
207 nsresult nsTestUConv::TestEncoders()
209 char * trace = "TestEncoders";
210 mLog.AddTrace(trace);
211 nsresult res = NS_OK;
213 nsCOMPtr<nsICharsetConverterManager> ccMan =
214 do_GetService(kCharsetConverterManagerCID, &res);
215 if (NS_FAILED(res)) return res;
217 nsCOMPtr<nsIUTF8StringEnumerator> encoders;
218 res = ccMan->GetEncoderList(getter_AddRefs(encoders));
219 if (NS_FAILED(res)) return res;
221 PRUint32 encoderCount=0;
223 PRBool hasMore;
224 encoders->HasMore(&hasMore);
226 nsCAutoString charset;
227 while (hasMore) {
228 encoders->GetNext(charset);
230 encoders->HasMore(&hasMore);
233 mLog.DelTrace(trace);
234 return res;
237 nsresult nsTestUConv::TestDecoders()
239 char * trace = "TestDecoders";
240 mLog.AddTrace(trace);
241 nsresult res = NS_OK;
243 // XXX write me
245 mLog.DelTrace(trace);
246 return res;
249 nsresult nsTestUConv::TestCharsetManager()
251 char * trace = "TestCharsetManager";
252 mLog.AddTrace(trace);
253 nsresult res = NS_OK;
254 nsAutoString name;
255 nsCOMPtr<nsIAtom> csAtom;
257 nsCOMPtr<nsICharsetConverterManager> ccMan =
258 do_GetService(kCharsetConverterManagerCID, &res);
259 if (NS_FAILED(res)) {
260 mLog.PrintError("NS_WITH_SERVICE", res);
261 return res;
264 mLog.DelTrace(trace);
265 return res;
268 nsresult nsTestUConv::DisplayDetectors()
270 char * trace = "DisplayDetectors";
271 mLog.AddTrace(trace);
272 nsresult res = NS_OK;
274 nsCOMPtr<nsICharsetConverterManager> ccMan =
275 do_GetService(kCharsetConverterManagerCID, &res);
276 if (NS_FAILED(res)) {
277 mLog.PrintError("NS_WITH_SERVICE", res);
278 return res;
281 // charset detectors
282 nsCOMPtr<nsIUTF8StringEnumerator> detectors;
284 res = ccMan->GetCharsetDetectorList(getter_AddRefs(detectors));
285 if (NS_FAILED(res)) {
286 mLog.PrintError("GetCharsetDetectorList()", res);
287 return res;
290 printf("***** Character Set Detectors *****\n");
292 PRBool hasMore;
293 detectors->HasMore(&hasMore);
294 while (hasMore) {
295 nsCAutoString detectorName;
296 res = detectors->GetNext(detectorName);
297 if (NS_FAILED(res)) {
298 mLog.PrintError("GetNext()", res);
299 return res;
302 printf("%s", detectorName.get());
303 PrintSpaces(36 - detectorName.Length()); // align to hard coded column number
305 nsAutoString title;
306 res = ccMan->GetCharsetTitle(detectorName.get(), title);
307 if (NS_FAILED(res)) title.SetLength(0);
308 printf("\"%s\"\n", NS_LossyConvertUTF16toASCII(title).get());
310 detectors->HasMore(&hasMore);
313 mLog.DelTrace(trace);
314 return NS_OK;
317 nsresult nsTestUConv::DisplayCharsets()
319 char * trace = "DisplayCharsets";
320 mLog.AddTrace(trace);
321 nsresult res = NS_OK;
323 nsCOMPtr<nsICharsetConverterManager> ccMan =
324 do_GetService(kCharsetConverterManagerCID, &res);
325 if (NS_FAILED(res)) {
326 mLog.PrintError("NS_WITH_SERVICE", res);
327 return res;
330 nsCOMPtr<nsIUTF8StringEnumerator> decoders;
331 nsCOMPtr<nsIUTF8StringEnumerator> encoders;
333 res = ccMan->GetDecoderList(getter_AddRefs(decoders));
334 if (NS_FAILED(res)) {
335 mLog.PrintError("GetDecoderList()", res);
336 return res;
339 res = ccMan->GetEncoderList(getter_AddRefs(encoders));
340 if (NS_FAILED(res)) {
341 mLog.PrintError("GetEncoderList()", res);
342 return res;
346 printf("***** Character Sets *****\n");
348 PRUint32 encCount = 0, decCount = 0;
349 PRUint32 basicEncCount = 0, basicDecCount = 0;
351 nsCStringArray allCharsets;
353 nsCAutoString charset;
354 PRBool hasMore;
355 encoders->HasMore(&hasMore);
356 while (hasMore) {
357 res = encoders->GetNext(charset);
358 if (NS_SUCCEEDED(res))
359 allCharsets.AppendCString(charset);
361 encoders->HasMore(&hasMore);
364 nsAutoString prop, str;
365 PRUint32 count = allCharsets.Count();
366 for (PRUint32 i = 0; i < count; i++) {
368 const nsCString* charset = allCharsets[i];
369 printf("%s", charset->get());
370 PrintSpaces(24 - charset->Length()); // align to hard coded column number
373 nsCOMPtr<nsIUnicodeDecoder> dec = NULL;
374 res = ccMan->GetUnicodeDecoder(charset->get(), getter_AddRefs(dec));
375 if (NS_FAILED(res)) printf (" ");
376 else {
377 printf("D");
378 decCount++;
380 #ifdef NS_DEBUG
381 // show the "basic" decoder classes
382 if (dec) {
383 nsCOMPtr<nsIBasicDecoder> isBasic = do_QueryInterface(dec);
384 if (isBasic) {
385 basicDecCount++;
386 printf("b");
388 else printf(" ");
390 else printf(" ");
391 #endif
393 nsCOMPtr<nsIUnicodeEncoder> enc = NULL;
394 res = ccMan->GetUnicodeEncoder(charset->get(), getter_AddRefs(enc));
395 if (NS_FAILED(res)) printf (" ");
396 else {
397 printf("E");
398 encCount++;
401 #ifdef NS_DEBUG
402 if (enc) {
403 nsCOMPtr<nsIBasicEncoder> isBasic = do_QueryInterface(enc);
404 if (isBasic) {
405 basicEncCount++;
406 printf("b");
408 else printf(" ");
410 else printf(" ");
411 #endif
413 printf(" ");
415 prop.AssignLiteral(".notForBrowser");
416 res = ccMan->GetCharsetData(charset->get(), prop.get(), str);
417 if ((dec != NULL) && (NS_FAILED(res))) printf ("B");
418 else printf("X");
420 prop.AssignLiteral(".notForComposer");
421 res = ccMan->GetCharsetData(charset->get(), prop.get(), str);
422 if ((enc != NULL) && (NS_FAILED(res))) printf ("C");
423 else printf("X");
425 prop.AssignLiteral(".notForMailView");
426 res = ccMan->GetCharsetData(charset->get(), prop.get(), str);
427 if ((dec != NULL) && (NS_FAILED(res))) printf ("V");
428 else printf("X");
430 prop.AssignLiteral(".notForMailEdit");
431 res = ccMan->GetCharsetData(charset->get(), prop.get(), str);
432 if ((enc != NULL) && (NS_FAILED(res))) printf ("E");
433 else printf("X");
435 printf("(%3d, %3d) ", encCount, decCount);
436 res = ccMan->GetCharsetTitle(charset->get(), str);
437 if (NS_FAILED(res)) str.SetLength(0);
438 NS_LossyConvertUTF16toASCII buff2(str);
439 printf(" \"%s\"\n", buff2.get());
442 printf("%u of %u decoders are basic (%d%%)\n",
443 basicDecCount, decCount, (basicDecCount * 100) / decCount);
445 printf("%u of %u encoders are basic (%d%%)\n",
446 basicEncCount, encCount, (basicEncCount * 100) / encCount);
447 mLog.DelTrace(trace);
448 return NS_OK;
451 nsresult nsTestUConv::TestTempBug()
453 char * trace = "TestTempBug";
454 mLog.AddTrace(trace);
455 nsresult res = NS_OK;
457 NS_NAMED_LITERAL_CSTRING(charset, "ISO-2022-JP");
458 PRUnichar src[] = {0x0043, 0x004e, 0x0045, 0x0054, 0x0020, 0x004A, 0x0061,
459 0x0070, 0x0061, 0x006E, 0x0020, 0x7DE8, 0x96C6, 0x5C40};
460 PRUnichar * srcEnd = src + ARRAY_SIZE(src);
461 char dest[BIG_BUFFER_SIZE];
462 char * destEnd = dest + BIG_BUFFER_SIZE;
464 PRUnichar * p = src;
465 char * q = dest;
466 res = Encode(&p, srcEnd, &q, destEnd, charset);
468 mLog.DelTrace(trace);
469 return res;
472 nsresult nsTestUConv::Encode(PRUnichar ** aSrc, PRUnichar * aSrcEnd,
473 char ** aDest, char * aDestEnd,
474 const nsAFlatCString& aCharset)
476 char * trace = "Encode";
477 mLog.AddTrace(trace);
478 nsresult res = NS_OK;
480 nsCOMPtr<nsICharsetConverterManager> ccMan =
481 do_GetService(kCharsetConverterManagerCID, &res);
482 if (NS_FAILED(res)) {
483 mLog.PrintError("NS_WITH_SERVICE", res);
484 return res;
487 nsCOMPtr<nsIUnicodeEncoder> enc;
488 res = ccMan->GetUnicodeEncoder(aCharset.get(), getter_AddRefs(enc));
489 if (NS_FAILED(res)) {
490 mLog.PrintError("GetUnicodeEncoder()", res);
491 return res;
494 res = ConvertEncode(aSrc, aSrcEnd, aDest, aDestEnd, enc);
495 if (NS_FAILED(res)) {
496 mLog.PrintError("Convert()", res);
497 return res;
500 res = FinishEncode(aDest, aDestEnd, enc);
501 if (NS_FAILED(res)) {
502 mLog.PrintError("Finish()", res);
503 return res;
506 mLog.DelTrace(trace);
507 return res;
510 nsresult nsTestUConv::ConvertEncode(PRUnichar ** aSrc, PRUnichar * aSrcEnd,
511 char ** aDest, char * aDestEnd,
512 nsIUnicodeEncoder * aEncoder)
514 PRUnichar * src = (*aSrc);
515 char * dest = (*aDest);
516 PRInt32 srcLen = aSrcEnd - src;
517 PRInt32 destLen = aDestEnd - dest;
519 nsresult res = aEncoder->Convert(src, &srcLen, dest, &destLen);
521 (*aSrc) = src + srcLen;
522 (*aDest) = dest + destLen;
523 return res;
526 nsresult nsTestUConv::FinishEncode(char ** aDest, char * aDestEnd,
527 nsIUnicodeEncoder * aEncoder)
529 char * dest = (*aDest);
530 PRInt32 destLen = aDestEnd - dest;
532 nsresult res = aEncoder->Finish(dest, &destLen);
534 (*aDest) = dest + destLen;
535 return res;
538 void nsTestUConv::PrintSpaces(int aCount)
540 for (int i = 0; i < aCount; i++) printf(" ");
543 nsresult nsTestUConv::Main(int aArgC, char ** aArgV)
545 char * trace = "Main";
546 mLog.AddTrace(trace);
547 nsresult res = NS_OK;
549 if (aArgC < 2) {
550 // no arguments were passed to the program, so we just run the self tests
551 res = TestCharsetManager();
552 if (NS_SUCCEEDED(res)) res = TestEncoders();
553 if (NS_SUCCEEDED(res)) res = TestDecoders();
554 } else if (!strcmp(aArgV[1], "-tempbug")) {
555 // we are testing a temporary bug
556 res = TestTempBug();
557 } else if (!strcmp(aArgV[1], "-display")) {
558 // display all the available data
559 res = DisplayDetectors();
560 if (NS_SUCCEEDED(res)) res = DisplayCharsets();
563 mLog.DelTrace(trace);
564 return res;