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
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.
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"
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]
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
66 * @created 28/Mar/2000
67 * @author Catalin Rotaru [CATA]
73 static const char * kTraceDelimiter
;
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]
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]
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
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
);
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
)
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;
224 encoders
->HasMore(&hasMore
);
226 nsCAutoString charset
;
228 encoders
->GetNext(charset
);
230 encoders
->HasMore(&hasMore
);
233 mLog
.DelTrace(trace
);
237 nsresult
nsTestUConv::TestDecoders()
239 char * trace
= "TestDecoders";
240 mLog
.AddTrace(trace
);
241 nsresult res
= NS_OK
;
245 mLog
.DelTrace(trace
);
249 nsresult
nsTestUConv::TestCharsetManager()
251 char * trace
= "TestCharsetManager";
252 mLog
.AddTrace(trace
);
253 nsresult res
= NS_OK
;
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
);
264 mLog
.DelTrace(trace
);
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
);
282 nsCOMPtr
<nsIUTF8StringEnumerator
> detectors
;
284 res
= ccMan
->GetCharsetDetectorList(getter_AddRefs(detectors
));
285 if (NS_FAILED(res
)) {
286 mLog
.PrintError("GetCharsetDetectorList()", res
);
290 printf("***** Character Set Detectors *****\n");
293 detectors
->HasMore(&hasMore
);
295 nsCAutoString detectorName
;
296 res
= detectors
->GetNext(detectorName
);
297 if (NS_FAILED(res
)) {
298 mLog
.PrintError("GetNext()", res
);
302 printf("%s", detectorName
.get());
303 PrintSpaces(36 - detectorName
.Length()); // align to hard coded column number
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
);
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
);
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
);
339 res
= ccMan
->GetEncoderList(getter_AddRefs(encoders
));
340 if (NS_FAILED(res
)) {
341 mLog
.PrintError("GetEncoderList()", res
);
346 printf("***** Character Sets *****\n");
348 PRUint32 encCount
= 0, decCount
= 0;
349 PRUint32 basicEncCount
= 0, basicDecCount
= 0;
351 nsCStringArray allCharsets
;
353 nsCAutoString charset
;
355 encoders
->HasMore(&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 (" ");
381 // show the "basic" decoder classes
383 nsCOMPtr
<nsIBasicDecoder
> isBasic
= do_QueryInterface(dec
);
393 nsCOMPtr
<nsIUnicodeEncoder
> enc
= NULL
;
394 res
= ccMan
->GetUnicodeEncoder(charset
->get(), getter_AddRefs(enc
));
395 if (NS_FAILED(res
)) printf (" ");
403 nsCOMPtr
<nsIBasicEncoder
> isBasic
= do_QueryInterface(enc
);
415 prop
.AssignLiteral(".notForBrowser");
416 res
= ccMan
->GetCharsetData(charset
->get(), prop
.get(), str
);
417 if ((dec
!= NULL
) && (NS_FAILED(res
))) printf ("B");
420 prop
.AssignLiteral(".notForComposer");
421 res
= ccMan
->GetCharsetData(charset
->get(), prop
.get(), str
);
422 if ((enc
!= NULL
) && (NS_FAILED(res
))) printf ("C");
425 prop
.AssignLiteral(".notForMailView");
426 res
= ccMan
->GetCharsetData(charset
->get(), prop
.get(), str
);
427 if ((dec
!= NULL
) && (NS_FAILED(res
))) printf ("V");
430 prop
.AssignLiteral(".notForMailEdit");
431 res
= ccMan
->GetCharsetData(charset
->get(), prop
.get(), str
);
432 if ((enc
!= NULL
) && (NS_FAILED(res
))) printf ("E");
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
);
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
;
466 res
= Encode(&p
, srcEnd
, &q
, destEnd
, charset
);
468 mLog
.DelTrace(trace
);
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
);
487 nsCOMPtr
<nsIUnicodeEncoder
> enc
;
488 res
= ccMan
->GetUnicodeEncoder(aCharset
.get(), getter_AddRefs(enc
));
489 if (NS_FAILED(res
)) {
490 mLog
.PrintError("GetUnicodeEncoder()", res
);
494 res
= ConvertEncode(aSrc
, aSrcEnd
, aDest
, aDestEnd
, enc
);
495 if (NS_FAILED(res
)) {
496 mLog
.PrintError("Convert()", res
);
500 res
= FinishEncode(aDest
, aDestEnd
, enc
);
501 if (NS_FAILED(res
)) {
502 mLog
.PrintError("Finish()", res
);
506 mLog
.DelTrace(trace
);
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
;
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
;
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
;
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
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
);