Back to index

lightning-sunbird  0.9+nobinonly
TestUConv.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla Communicator client code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "nsIServiceManager.h"
00039 #include "nsICharsetConverterManager.h"
00040 #include "nsUCSupport.h"
00041 #include "nsString.h"
00042 #include "nsIStringEnumerator.h"
00043 #include "nsVoidArray.h"
00044 
00045 //----------------------------------------------------------------------------
00046 // Global functions and data [declaration]
00047 
00048 #define ARRAY_SIZE(_array)  (sizeof(_array) / sizeof(_array[0]))
00049 #define SMALL_BUFFER_SIZE   512
00050 #define MED_BUFFER_SIZE     1024
00051 #define BIG_BUFFER_SIZE     2048
00052 
00053 static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
00054 
00055 //----------------------------------------------------------------------------
00056 // Class nsTestLog [declaration]
00057 
00069 class nsTestLog
00070 {
00071 private:
00072 
00073   static const char * kTraceDelimiter;
00074 
00075   nsCAutoString mTrace;
00076 
00077 public:
00078 
00079   void AddTrace(char * aTrace);
00080   void DelTrace(char * aTrace);
00081   void PrintError(char * aCall, int aError);
00082   void PrintError(char * aCall, char * aMessage);
00083 };
00084   
00085 //----------------------------------------------------------------------------
00086 // Class nsTestUConv [declaration]
00087 
00098 class nsTestUConv
00099 {
00100 private:
00101 
00102   nsTestLog mLog;
00103 
00107   nsresult TestEncoders();
00108 
00112   nsresult TestDecoders();
00113 
00117   nsresult TestCharsetManager();
00118 
00122   nsresult DisplayDetectors();
00123 
00127   nsresult DisplayCharsets();
00128 
00133   nsresult TestTempBug();
00134 
00135   nsresult Encode(PRUnichar ** aSrc, PRUnichar * aSrcEnd, char ** aDest, 
00136     char * aDestEnd, const nsAFlatCString& aCharset);
00137 
00145   nsresult ConvertEncode(PRUnichar ** aSrc, PRUnichar * aSrcEnd, char ** aDest, 
00146     char * aDestEnd, nsIUnicodeEncoder * aEncoder);
00147 
00151   nsresult FinishEncode(char ** aDest, char * aDestEnd, 
00152     nsIUnicodeEncoder * aEncoder);
00153 
00154   void PrintSpaces(int aCount);
00155 
00156 public:
00157 
00161   nsresult Main(int aArgC, char ** aArgV);
00162 };
00163   
00164 //----------------------------------------------------------------------------
00165 // Global functions and data [implementation]
00166 
00167 int main(int argc, char ** argv)
00168 {
00169   nsTestUConv testObj;
00170   nsresult res;
00171  
00172   res = testObj.Main(argc, argv);
00173   return (NS_FAILED(res));
00174 }
00175 
00176 //----------------------------------------------------------------------------
00177 // Class nsTestLog [implementation]
00178 
00179 const char * nsTestLog::kTraceDelimiter = ".";
00180 
00181 void nsTestLog::AddTrace(char * aTrace)
00182 {
00183   mTrace.Append(aTrace);
00184   mTrace.Append(kTraceDelimiter);
00185 }
00186 
00187 void nsTestLog::DelTrace(char * aTrace)
00188 {
00189   mTrace.Truncate(mTrace.Length() - strlen(aTrace) - strlen(kTraceDelimiter));
00190 }
00191 
00192 void nsTestLog::PrintError(char * aCall, int aError)
00193 {
00194   const char * trace = mTrace.get();
00195   printf("ERROR at %s%s code=0x%x.\n", trace, aCall, aError);
00196 }
00197 
00198 void nsTestLog::PrintError(char * aCall, char * aMessage)
00199 {
00200   const char * trace = mTrace.get();
00201   printf("ERROR at %s%s reason: %s.\n", trace, aCall, aMessage);
00202 }
00203 
00204 //----------------------------------------------------------------------------
00205 // Class nsTestUConv [implementation]
00206 
00207 nsresult nsTestUConv::TestEncoders()
00208 {
00209   char * trace = "TestEncoders";
00210   mLog.AddTrace(trace);
00211   nsresult res = NS_OK;
00212 
00213   nsCOMPtr<nsICharsetConverterManager> ccMan = 
00214            do_GetService(kCharsetConverterManagerCID, &res);
00215   if (NS_FAILED(res)) return res;
00216   
00217   nsCOMPtr<nsIUTF8StringEnumerator> encoders;
00218   res = ccMan->GetEncoderList(getter_AddRefs(encoders));
00219   if (NS_FAILED(res)) return res;
00220 
00221   PRUint32 encoderCount=0;
00222 
00223   PRBool hasMore;
00224   encoders->HasMore(&hasMore);
00225   
00226   nsCAutoString charset;
00227   while (hasMore) {
00228     encoders->GetNext(charset);
00229 
00230     encoders->HasMore(&hasMore);
00231   }
00232   
00233   mLog.DelTrace(trace);
00234   return res;
00235 }
00236 
00237 nsresult nsTestUConv::TestDecoders()
00238 {
00239   char * trace = "TestDecoders";
00240   mLog.AddTrace(trace);
00241   nsresult res = NS_OK;
00242 
00243   // XXX write me
00244 
00245   mLog.DelTrace(trace);
00246   return res;
00247 }
00248 
00249 nsresult nsTestUConv::TestCharsetManager()
00250 {
00251   char * trace = "TestCharsetManager";
00252   mLog.AddTrace(trace);
00253   nsresult res = NS_OK;
00254   nsAutoString name;
00255   nsCOMPtr<nsIAtom> csAtom;
00256 
00257   nsCOMPtr<nsICharsetConverterManager> ccMan = 
00258            do_GetService(kCharsetConverterManagerCID, &res);
00259   if (NS_FAILED(res)) {
00260     mLog.PrintError("NS_WITH_SERVICE", res);
00261     return res;
00262   }
00263 
00264   mLog.DelTrace(trace);
00265   return res;
00266 }
00267 
00268 nsresult nsTestUConv::DisplayDetectors()
00269 {
00270   char * trace = "DisplayDetectors";
00271   mLog.AddTrace(trace);
00272   nsresult res = NS_OK;
00273 
00274   nsCOMPtr<nsICharsetConverterManager> ccMan = 
00275            do_GetService(kCharsetConverterManagerCID, &res);
00276   if (NS_FAILED(res)) {
00277     mLog.PrintError("NS_WITH_SERVICE", res);
00278     return res;
00279   }
00280 
00281   // charset detectors
00282   nsCOMPtr<nsIUTF8StringEnumerator> detectors;
00283 
00284   res = ccMan->GetCharsetDetectorList(getter_AddRefs(detectors));
00285   if (NS_FAILED(res)) {
00286     mLog.PrintError("GetCharsetDetectorList()", res);
00287     return res;
00288   }
00289 
00290   printf("***** Character Set Detectors *****\n");
00291 
00292   PRBool hasMore;
00293   detectors->HasMore(&hasMore);
00294   while (hasMore) {
00295     nsCAutoString detectorName;
00296     res = detectors->GetNext(detectorName);
00297     if (NS_FAILED(res)) {
00298       mLog.PrintError("GetNext()", res);
00299       return res;
00300     }
00301 
00302     printf("%s", detectorName.get());
00303     PrintSpaces(36 - detectorName.Length()); // align to hard coded column number
00304 
00305     nsAutoString title;
00306     res = ccMan->GetCharsetTitle(detectorName.get(), title);
00307     if (NS_FAILED(res)) title.SetLength(0);
00308     printf("\"%s\"\n", NS_LossyConvertUCS2toASCII(title).get());
00309   }
00310   
00311   mLog.DelTrace(trace);
00312   return NS_OK;
00313 }
00314 
00315 nsresult nsTestUConv::DisplayCharsets()
00316 {
00317   char * trace = "DisplayCharsets";
00318   mLog.AddTrace(trace);
00319   nsresult res = NS_OK;
00320 
00321   nsCOMPtr<nsICharsetConverterManager> ccMan = 
00322            do_GetService(kCharsetConverterManagerCID, &res);
00323   if (NS_FAILED(res)) {
00324     mLog.PrintError("NS_WITH_SERVICE", res);
00325     return res;
00326   }
00327 
00328   nsCOMPtr<nsIUTF8StringEnumerator> decoders;
00329   nsCOMPtr<nsIUTF8StringEnumerator> encoders;
00330 
00331   res = ccMan->GetDecoderList(getter_AddRefs(decoders));
00332   if (NS_FAILED(res)) {
00333     mLog.PrintError("GetDecoderList()", res);
00334     return res;
00335   }
00336 
00337   res = ccMan->GetEncoderList(getter_AddRefs(encoders));
00338   if (NS_FAILED(res)) {
00339     mLog.PrintError("GetEncoderList()", res);
00340     return res;
00341   }
00342 
00343 
00344   printf("***** Character Sets *****\n");
00345 
00346   PRUint32 encCount = 0, decCount = 0;
00347   PRUint32 basicEncCount = 0, basicDecCount = 0;
00348 
00349   nsCStringArray allCharsets;
00350   
00351   nsCAutoString charset;
00352   PRBool hasMore;
00353   encoders->HasMore(&hasMore);
00354   while (hasMore) {
00355     res = encoders->GetNext(charset);
00356     if (NS_SUCCEEDED(res))
00357       allCharsets.AppendCString(charset);
00358 
00359     encoders->HasMore(&hasMore);
00360   }
00361 
00362   nsAutoString prop, str;
00363   PRUint32 count = allCharsets.Count();
00364   for (PRUint32 i = 0; i < count; i++) {
00365 
00366     const nsCString* charset = allCharsets[i];
00367     printf("%s", charset->get());
00368     PrintSpaces(24 - charset->Length());  // align to hard coded column number
00369 
00370 
00371     nsCOMPtr<nsIUnicodeDecoder> dec = NULL;
00372     res = ccMan->GetUnicodeDecoder(charset->get(), getter_AddRefs(dec));
00373     if (NS_FAILED(res)) printf (" "); 
00374     else {
00375       printf("D");
00376       decCount++;
00377     }
00378 #ifdef NS_DEBUG
00379     // show the "basic" decoder classes
00380     if (dec) {
00381       nsCOMPtr<nsIBasicDecoder> isBasic = do_QueryInterface(dec);
00382       if (isBasic) {
00383         basicDecCount++;
00384         printf("b");
00385       }
00386       else printf(" ");
00387     }
00388     else printf(" ");
00389 #endif
00390 
00391     nsCOMPtr<nsIUnicodeEncoder> enc = NULL;
00392     res = ccMan->GetUnicodeEncoder(charset->get(), getter_AddRefs(enc));
00393     if (NS_FAILED(res)) printf (" "); 
00394     else {
00395       printf("E");
00396       encCount++;
00397     }
00398 
00399 #ifdef NS_DEBUG
00400     if (enc) {
00401       nsCOMPtr<nsIBasicEncoder> isBasic = do_QueryInterface(enc);
00402       if (isBasic) {
00403         basicEncCount++;
00404         printf("b");
00405       }
00406       else printf(" ");
00407     }
00408     else printf(" ");
00409 #endif
00410     
00411     printf(" ");
00412 
00413     prop.AssignLiteral(".notForBrowser");
00414     res = ccMan->GetCharsetData(charset->get(), prop.get(), str);
00415     if ((dec != NULL) && (NS_FAILED(res))) printf ("B"); 
00416     else printf("X");
00417 
00418     prop.AssignLiteral(".notForComposer");
00419     res = ccMan->GetCharsetData(charset->get(), prop.get(), str);
00420     if ((enc != NULL) && (NS_FAILED(res))) printf ("C"); 
00421     else printf("X");
00422 
00423     prop.AssignLiteral(".notForMailView");
00424     res = ccMan->GetCharsetData(charset->get(), prop.get(), str);
00425     if ((dec != NULL) && (NS_FAILED(res))) printf ("V"); 
00426     else printf("X");
00427 
00428     prop.AssignLiteral(".notForMailEdit");
00429     res = ccMan->GetCharsetData(charset->get(), prop.get(), str);
00430     if ((enc != NULL) && (NS_FAILED(res))) printf ("E"); 
00431     else printf("X");
00432 
00433     printf("(%3d, %3d) ", encCount, decCount);
00434     res = ccMan->GetCharsetTitle(charset->get(), str);
00435     if (NS_FAILED(res)) str.SetLength(0);
00436     NS_LossyConvertUCS2toASCII buff2(str);
00437     printf(" \"%s\"\n", buff2.get());
00438   }
00439 
00440   printf("%u of %u decoders are basic (%d%%)\n",
00441          basicDecCount, decCount, (basicDecCount * 100) / decCount);
00442 
00443   printf("%u of %u encoders are basic (%d%%)\n",
00444          basicEncCount, encCount, (basicEncCount * 100) / encCount);
00445   mLog.DelTrace(trace);
00446   return NS_OK;
00447 }
00448 
00449 nsresult nsTestUConv::TestTempBug()
00450 {
00451   char * trace = "TestTempBug";
00452   mLog.AddTrace(trace);
00453   nsresult res = NS_OK;
00454 
00455   NS_NAMED_LITERAL_CSTRING(charset, "ISO-2022-JP");
00456   PRUnichar src[] = {0x0043, 0x004e, 0x0045, 0x0054, 0x0020, 0x004A, 0x0061, 
00457     0x0070, 0x0061, 0x006E, 0x0020, 0x7DE8, 0x96C6, 0x5C40};
00458   PRUnichar * srcEnd = src + ARRAY_SIZE(src);
00459   char dest[BIG_BUFFER_SIZE];
00460   char * destEnd = dest + BIG_BUFFER_SIZE;
00461 
00462   PRUnichar * p = src;
00463   char * q = dest;
00464   res = Encode(&p, srcEnd, &q, destEnd, charset);
00465 
00466   mLog.DelTrace(trace);
00467   return res;
00468 }
00469 
00470 nsresult nsTestUConv::Encode(PRUnichar ** aSrc, PRUnichar * aSrcEnd, 
00471                              char ** aDest, char * aDestEnd, 
00472                              const nsAFlatCString& aCharset)
00473 {
00474   char * trace = "Encode";
00475   mLog.AddTrace(trace);
00476   nsresult res = NS_OK;
00477 
00478   nsCOMPtr<nsICharsetConverterManager> ccMan = 
00479            do_GetService(kCharsetConverterManagerCID, &res);
00480   if (NS_FAILED(res)) {
00481     mLog.PrintError("NS_WITH_SERVICE", res);
00482     return res;
00483   }
00484 
00485   nsCOMPtr<nsIUnicodeEncoder> enc;
00486   res = ccMan->GetUnicodeEncoder(aCharset.get(), getter_AddRefs(enc));
00487   if (NS_FAILED(res)) {
00488     mLog.PrintError("GetUnicodeEncoder()", res);
00489     return res;
00490   }
00491 
00492   res = ConvertEncode(aSrc, aSrcEnd, aDest, aDestEnd, enc);
00493   if (NS_FAILED(res)) {
00494     mLog.PrintError("Convert()", res);
00495     return res;
00496   }
00497 
00498   res = FinishEncode(aDest, aDestEnd, enc);
00499   if (NS_FAILED(res)) {
00500     mLog.PrintError("Finish()", res);
00501     return res;
00502   }
00503 
00504   mLog.DelTrace(trace);
00505   return res;
00506 }
00507 
00508 nsresult nsTestUConv::ConvertEncode(PRUnichar ** aSrc, PRUnichar * aSrcEnd, 
00509                                     char ** aDest, char * aDestEnd, 
00510                                     nsIUnicodeEncoder * aEncoder)
00511 {
00512   PRUnichar * src = (*aSrc);
00513   char * dest = (*aDest);
00514   PRInt32 srcLen = aSrcEnd - src;
00515   PRInt32 destLen = aDestEnd - dest;
00516 
00517   nsresult res = aEncoder->Convert(src, &srcLen, dest, &destLen);
00518 
00519   (*aSrc) = src + srcLen;
00520   (*aDest) = dest + destLen;
00521   return res;
00522 }
00523 
00524 nsresult nsTestUConv::FinishEncode(char ** aDest, char * aDestEnd, 
00525                                    nsIUnicodeEncoder * aEncoder)
00526 {
00527   char * dest = (*aDest);
00528   PRInt32 destLen = aDestEnd - dest;
00529 
00530   nsresult res = aEncoder->Finish(dest, &destLen);
00531 
00532   (*aDest) = dest + destLen;
00533   return res;
00534 }
00535 
00536 void nsTestUConv::PrintSpaces(int aCount)
00537 {
00538   for (int i = 0; i < aCount; i++) printf(" ");
00539 }
00540 
00541 nsresult nsTestUConv::Main(int aArgC, char ** aArgV)
00542 {
00543   char * trace = "Main";
00544   mLog.AddTrace(trace);
00545   nsresult res = NS_OK;
00546 
00547   if (aArgC < 2) {
00548     // no arguments were passed to the program, so we just run the self tests
00549     res = TestCharsetManager();
00550     if (NS_SUCCEEDED(res)) res = TestEncoders();
00551     if (NS_SUCCEEDED(res)) res = TestDecoders();
00552   } else if (!strcmp(aArgV[1], "-tempbug")) {
00553     // we are testing a temporary bug
00554     res = TestTempBug();
00555   } else if (!strcmp(aArgV[1], "-display")) {
00556     // display all the available data
00557     res = DisplayDetectors();
00558     if (NS_SUCCEEDED(res)) res = DisplayCharsets();
00559   }
00560 
00561   mLog.DelTrace(trace);
00562   return res;
00563 }