Back to index

lightning-sunbird  0.9+nobinonly
nsOS2Uni.cpp
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is an API for accessing OS/2 Unicode support.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * IBM Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 2002
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 #include "nsOS2Uni.h"
00038 #include "nsIServiceManager.h"
00039 #include "nsIPlatformCharset.h"
00040 #include <stdlib.h>
00041 
00042 
00043 /**********************************************************
00044     OS2Uni
00045  **********************************************************/
00046 nsICharsetConverterManager* OS2Uni::gCharsetManager = nsnull;
00047 
00048 struct ConverterInfo
00049 {
00050   PRUint16            mCodePage;
00051   char*               mConvName;
00052   nsIUnicodeEncoder*  mEncoder;
00053   nsIUnicodeDecoder*  mDecoder;
00054 };
00055 
00056 #define eCONVERTER_COUNT  17
00057 ConverterInfo gConverterInfo[eCONVERTER_COUNT] =
00058 {
00059   { 0,    "",              nsnull,  nsnull },
00060   { 1252, "windows-1252",  nsnull,  nsnull },
00061   { 1208, "UTF-8",         nsnull,  nsnull },
00062   { 1250, "windows-1250",  nsnull,  nsnull },
00063   { 1251, "windows-1251",  nsnull,  nsnull },
00064   { 813,  "ISO-8859-7",    nsnull,  nsnull },
00065   { 1254, "windows-1254",  nsnull,  nsnull },
00066   { 864,  "IBM864",        nsnull,  nsnull },
00067   { 1257, "windows-1257",  nsnull,  nsnull },
00068   { 874,  "windows-874",   nsnull,  nsnull },
00069   { 932,  "Shift_JIS",     nsnull,  nsnull },
00070   { 943,  "Shift_JIS",     nsnull,  nsnull },
00071   { 1381, "GB2312",        nsnull,  nsnull },
00072   { 1386, "GB2312",        nsnull,  nsnull },
00073   { 949,  "x-windows-949", nsnull,  nsnull },
00074   { 950,  "Big5",          nsnull,  nsnull },
00075   { 1361, "x-johab",       nsnull,  nsnull }
00076 };
00077 
00078 static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
00079 
00080 nsISupports*
00081 OS2Uni::GetUconvObject(int aCodePage, ConverterRequest aReq)
00082 {
00083   if (gCharsetManager == nsnull) {
00084     CallGetService(kCharsetConverterManagerCID, &gCharsetManager);
00085   }
00086 
00087   nsresult rv;
00088   nsISupports* uco = nsnull;
00089   for (int i = 0; i < eCONVERTER_COUNT; i++) {
00090     if (aCodePage == gConverterInfo[i].mCodePage) {
00091       if (gConverterInfo[i].mEncoder == nsnull) {
00092         const char* convname;
00093         nsCAutoString charset;
00094         if (aCodePage == 0) {
00095           nsCOMPtr<nsIPlatformCharset>
00096                       plat(do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv));
00097           if (NS_SUCCEEDED(rv)) {
00098             plat->GetCharset(kPlatformCharsetSel_FileName, charset);
00099           } else {
00100             // default to IBM850 if this should fail
00101             charset = "IBM850";
00102           }
00103           convname = charset.get();
00104         } else {
00105           convname = gConverterInfo[i].mConvName;
00106         }
00107         rv = gCharsetManager->GetUnicodeEncoderRaw(convname,
00108                                                    &gConverterInfo[i].mEncoder);
00109         gConverterInfo[i].mEncoder->
00110                     SetOutputErrorBehavior(nsIUnicodeEncoder::kOnError_Replace,
00111                                            nsnull, '?');
00112         gCharsetManager->GetUnicodeDecoderRaw(convname,
00113                                               &gConverterInfo[i].mDecoder);
00114         NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to get converter");
00115       }
00116       if (aReq == eConv_Encoder) {
00117         uco = gConverterInfo[i].mEncoder;
00118       } else {
00119         uco = gConverterInfo[i].mDecoder;
00120       }
00121       break;
00122     }
00123   }
00124 
00125   return uco;
00126 }
00127 
00128 void OS2Uni::FreeUconvObjects()
00129 {
00130   for (int i = 0; i < eCONVERTER_COUNT; i++) {
00131     NS_IF_RELEASE(gConverterInfo[i].mEncoder);
00132     NS_IF_RELEASE(gConverterInfo[i].mDecoder);
00133   }
00134   NS_IF_RELEASE(gCharsetManager);
00135 }
00136 
00137 /**********************************************************
00138     WideCharToMultiByte
00139  **********************************************************/
00140 nsresult
00141 WideCharToMultiByte(int aCodePage, const PRUnichar* aSrc,
00142                     PRInt32 aSrcLength, nsAutoCharBuffer& aResult,
00143                     PRInt32& aResultLength)
00144 {
00145   nsresult rv;
00146   nsISupports* sup = OS2Uni::GetUconvObject(aCodePage, eConv_Encoder);
00147   nsCOMPtr<nsIUnicodeEncoder> uco = do_QueryInterface(sup);
00148 
00149   if (NS_FAILED(uco->GetMaxLength(aSrc, aSrcLength, &aResultLength))) {
00150     return NS_ERROR_UNEXPECTED;
00151   }
00152   if (!aResult.EnsureElemCapacity(aResultLength + 1))
00153     return NS_ERROR_OUT_OF_MEMORY;
00154   char* str = aResult.get();
00155 
00156   rv = uco->Convert(aSrc, &aSrcLength, str, &aResultLength);
00157   aResult.get()[aResultLength] = '\0';
00158   return rv;
00159 }
00160 
00161 /**********************************************************
00162     MultiByteToWideChar
00163  **********************************************************/
00164 nsresult
00165 MultiByteToWideChar(int aCodePage, const char* aSrc,
00166                     PRInt32 aSrcLength, nsAutoChar16Buffer& aResult,
00167                     PRInt32& aResultLength)
00168 {
00169   nsresult rv;
00170   nsISupports* sup = OS2Uni::GetUconvObject(aCodePage, eConv_Decoder);
00171   nsCOMPtr<nsIUnicodeDecoder> uco = do_QueryInterface(sup);
00172 
00173   if (NS_FAILED(uco->GetMaxLength(aSrc, aSrcLength, &aResultLength))) {
00174     return NS_ERROR_UNEXPECTED;
00175   }
00176   if (!aResult.EnsureElemCapacity(aResultLength + 1))
00177     return NS_ERROR_OUT_OF_MEMORY;
00178   PRUnichar* str = aResult.get();
00179 
00180   rv = uco->Convert(aSrc, &aSrcLength, str, &aResultLength);
00181   aResult.get()[aResultLength] = '\0';
00182   return rv;
00183 }