const PRUnichar *charsetName; res = charsetAtom->GetUnicode(&charsetName);
const char *charsetName; res = charsetAtom->GetUTF8String(&charsetName);
nsresult nsMsgI18NSaveAsCharset(const char* contentType, const char *charset,                                 const PRUnichar* inString, char** outString,                                 char **fallbackCharset, PRBool *isAsciiOnly){  NS_ENSURE_ARG_POINTER(contentType);  NS_ENSURE_ARG_POINTER(charset);  NS_ENSURE_ARG_POINTER(inString);  NS_ENSURE_ARG_POINTER(outString);  *outString = nsnull;  if (nsCRT::IsAscii(inString)) {    if (isAsciiOnly)      *isAsciiOnly = PR_TRUE;    *outString = nsCRT::strdup(NS_LossyConvertUCS2toASCII(inString).get());    return (nsnull != *outString) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;  }  if (isAsciiOnly)    *isAsciiOnly = PR_FALSE;  PRBool bTEXT_HTML = PR_FALSE;  nsresult res;  if (!nsCRT::strcasecmp(contentType, TEXT_HTML)) {    bTEXT_HTML = PR_TRUE;  }  else if (nsCRT::strcasecmp(contentType, TEXT_PLAIN)) {    return NS_ERROR_ILLEGAL_VALUE;  // not supported type  }  nsCOMPtr <nsICharsetConverterManager2> ccm2 = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &res);  NS_ENSURE_SUCCESS(res, res);  nsCOMPtr <nsIAtom> charsetAtom;  res = ccm2->GetCharsetAtom(NS_ConvertASCIItoUCS2(charset).get(), getter_AddRefs(charsetAtom));  NS_ENSURE_SUCCESS(res, res);  const PRUnichar *charsetName;  res = charsetAtom->GetUnicode(&charsetName);  NS_ENSURE_SUCCESS(res, res);  // charset converter plus entity, NCR generation  nsCOMPtr <nsISaveAsCharset> conv = do_CreateInstance(NS_SAVEASCHARSET_CONTRACTID, &res);  NS_ENSURE_SUCCESS(res, res);  // attribute:   // html text - charset conv then fallback to entity or NCR  // plain text - charset conv then fallback to '?'  if (bTEXT_HTML)    // For ISO-8859-1 only, convert to entity first (always generate entites like &nbsp;).    res = conv->Init(NS_ConvertUCS2toUTF8(charsetName).get(),                      !nsCRT::strcmp(charsetName, NS_LITERAL_STRING("ISO-8859-1").get()) ?                     nsISaveAsCharset::attr_htmlTextDefault :                     nsISaveAsCharset::attr_EntityAfterCharsetConv + nsISaveAsCharset::attr_FallbackDecimalNCR,                      nsIEntityConverter::html32);  else    // fallback for text/plain: first try transliterate then '?'    res = conv->Init(NS_ConvertUCS2toUTF8(charsetName).get(),                      nsISaveAsCharset::attr_FallbackQuestionMark + nsISaveAsCharset::attr_EntityAfterCharsetConv,                      nsIEntityConverter::transliterate);  NS_ENSURE_SUCCESS(res, res);  const PRUnichar *input = inString;  // Mapping characters in a certain range (required for Japanese only)  nsAutoString mapped;  if (!nsCRT::strcmp(charsetName, NS_LITERAL_STRING("ISO-2022-JP").get())) {    static PRInt32 sSendHankakuKana = -1;    if (sSendHankakuKana < 0) {      nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID, &res));      NS_ENSURE_SUCCESS(res, res);      PRBool sendHankaku;      // Get a hidden 4.x pref with no UI, get it only once.      if (NS_FAILED(prefBranch->GetBoolPref("mailnews.send_hankaku_kana", &sendHankaku)))        sSendHankakuKana = 0;  // no pref means need the mapping      else        sSendHankakuKana = sendHankaku ? 1 : 0;    }    if (!sSendHankakuKana) {      nsCOMPtr <nsITextTransform> textTransform = do_CreateInstance(NS_HANKAKUTOZENKAKU_CONTRACTID, &res);              if (NS_SUCCEEDED(res)) {        res = textTransform->Change(inString, nsCRT::strlen(inString), mapped);        if (NS_SUCCEEDED(res))          input = mapped.get();      }    }  }  // Convert to charset  res = conv->Convert(input, outString);  // If the converer cannot encode to the charset,  // then fallback to pref sepcified charsets.  if (NS_ERROR_UENC_NOMAPPING == res && !bTEXT_HTML && fallbackCharset) {    nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID, &res));    NS_ENSURE_SUCCESS(res, res);    nsCAutoString prefString("intl.fallbackCharsetList.");    prefString.Append(charset);    nsXPIDLCString fallbackList;    res = prefBranch->GetCharPref(prefString.get(), getter_Copies(fallbackList));    // do the fallback only if there is a pref for the charset    if (NS_FAILED(res) || fallbackList.IsEmpty())      return NS_ERROR_UENC_NOMAPPING;    res = conv->Init(fallbackList.get(),                      nsISaveAsCharset::attr_FallbackQuestionMark +                      nsISaveAsCharset::attr_EntityAfterCharsetConv +                     nsISaveAsCharset::attr_CharsetFallback,                      nsIEntityConverter::transliterate);    NS_ENSURE_SUCCESS(res, res);    // free whatever we have now    PR_FREEIF(*outString);      res = conv->Convert(input, outString);    NS_ENSURE_SUCCESS(res, res);    // get the actual charset used for the conversion    if (NS_FAILED(conv->GetCharset(fallbackCharset)))      *fallbackCharset = nsnull;  }  // In case of HTML, non ASCII may be encoded as CER, NCR.  // Exclude stateful charset which is 7 bit but not ASCII only.  else if (isAsciiOnly && bTEXT_HTML && *outString &&           !nsMsgI18Nstateful_charset(NS_LossyConvertUCS2toASCII(charsetName).get()))    *isAsciiOnly = nsCRT::IsAscii(*outString);  return res;}