Changed to resolve charset alias before unicode conversion, made charset name to case sensitive, consolidated conversion wrapper functions, bug 18264,

r=ftang.
This commit is contained in:
nhotta%netscape.com 1999-11-11 22:05:10 +00:00
Родитель 594c1f0c93
Коммит a079345422
7 изменённых файлов: 183 добавлений и 259 удалений

Просмотреть файл

@ -265,6 +265,13 @@ void DIR_SetFileName(char** filename, const char* leafName);
static PRInt32 PR_CALLBACK dir_ServerPrefCallback(const char *pref, void *inst_data);
// This can now use nsTextFormater.
// e.g.
// #include "nsTextFormater.h"
// nsString aString("");
// nsAutoString fmt("%s");
// PRUnichar *uniBuffer = nsTextFormater::smprintf(fmt.GetUnicode(), aBuffer); // this converts UTF-8 to UCS-2
// Do not use void* that was inherited from old libmime when it could not include C++, use PRUnichar* instead.
PRInt32 INTL_ConvertToUnicode(const char* aBuffer, const PRInt32 aLength,
void** uniBuffer, PRInt32* uniLength)
{
@ -308,6 +315,11 @@ PRInt32 INTL_ConvertToUnicode(const char* aBuffer, const PRInt32 aLength,
return NS_SUCCEEDED(res) ? 0 : -1;
}
// This can now use ToNewUTF8String (or this function itself can be substitued by that).
// e.g.
// nsAutoString aStr(uniBuffer);
// *aBuffer = aStr.ToNewUTF8String();
// Do not use void* that was inherited from old libmime when it could not include C++, use PRUnichar* instead.
PRInt32 INTL_ConvertFromUnicode(const void* uniBuffer, const PRInt32 uniLength, char** aBuffer)
{
nsresult res;

Просмотреть файл

@ -22,8 +22,10 @@
// as does this
#define NS_IMPL_IDS
#include "nsIServiceManager.h"
#include "nsICharsetConverterManager.h"
#include "nsICharsetAlias.h"
#undef NS_IMPL_IDS
#include "nsIServiceManager.h"
#include "nsISupports.h"
#include "nsIPref.h"
@ -53,21 +55,44 @@ nsresult ConvertFromUnicode(const nsString& aCharset,
const nsString& inString,
char** outCString)
{
*outCString = NULL;
if (inString.IsEmpty()) {
*outCString = nsCRT::strdup("");
return (NULL == *outCString) ? NS_ERROR_OUT_OF_MEMORY : NS_OK;
}
// Note: this will hide a possible error when the unicode text may contain more than one charset.
// (e.g. Latin1 + Japanese). Use nsMsgI18NSaveAsCharset instead to avoid that problem.
else if (aCharset.IsEmpty() ||
aCharset.EqualsIgnoreCase("us-ascii") ||
aCharset.EqualsIgnoreCase("ISO-8859-1")) {
*outCString = inString.ToNewCString();
return (NULL == *outCString) ? NS_ERROR_OUT_OF_MEMORY : NS_OK;
}
else if (aCharset.EqualsIgnoreCase("UTF-8")) {
*outCString = inString.ToNewUTF8String();
return (NULL == *outCString) ? NS_ERROR_OUT_OF_MEMORY : NS_OK;
}
nsAutoString convCharset;
nsresult res;
// Resolve charset alias
NS_WITH_SERVICE(nsICharsetAlias, calias, kCharsetAliasCID, &res);
if (NS_SUCCEEDED(res)) {
nsAutoString aAlias(aCharset);
if (aAlias.Length()) {
res = calias->GetPreferred(aAlias, convCharset);
}
}
if (NS_FAILED(res)) {
return res;
}
NS_WITH_SERVICE(nsICharsetConverterManager, ccm, kCharsetConverterManagerCID, &res);
if(NS_SUCCEEDED(res) && (nsnull != ccm)) {
if(NS_SUCCEEDED(res)) {
nsIUnicodeEncoder* encoder = nsnull;
nsString convCharset;
// map to converter charset
if (aCharset.EqualsIgnoreCase("us-ascii")) {
convCharset.SetString("iso-8859-1");
}
else {
convCharset = aCharset;
}
// get an unicode converter
res = ccm->GetUnicodeEncoder(&convCharset, &encoder);
@ -118,22 +143,42 @@ nsresult ConvertToUnicode(const nsString& aCharset,
const char* inCString,
nsString& outString)
{
if (NULL == inCString) {
return NS_ERROR_NULL_POINTER;
}
else if ('\0' == *inCString) {
outString.SetString("");
return NS_OK;
}
else if (aCharset.IsEmpty() ||
aCharset.EqualsIgnoreCase("us-ascii") ||
aCharset.EqualsIgnoreCase("ISO-8859-1")) {
outString.SetString(inCString);
return NS_OK;
}
nsAutoString convCharset;
nsresult res;
// Resolve charset alias
NS_WITH_SERVICE(nsICharsetAlias, calias, kCharsetAliasCID, &res);
if (NS_SUCCEEDED(res)) {
nsAutoString aAlias(aCharset);
if (aAlias.Length()) {
res = calias->GetPreferred(aAlias, convCharset);
}
}
if (NS_FAILED(res)) {
return res;
}
NS_WITH_SERVICE(nsICharsetConverterManager, ccm, kCharsetConverterManagerCID, &res);
if(NS_SUCCEEDED(res) && (nsnull != ccm)) {
nsIUnicodeDecoder* decoder = nsnull;
PRUnichar *unichars;
PRInt32 unicharLength;
nsString convCharset;
// map to converter charset
if (aCharset.EqualsIgnoreCase("us-ascii")) {
convCharset.SetString("iso-8859-1");
}
else {
convCharset = aCharset;
}
// get an unicode converter
res = ccm->GetUnicodeDecoder(&convCharset, &decoder);
if(NS_SUCCEEDED(res) && (nsnull != decoder)) {
@ -213,17 +258,17 @@ char * nsMsgI18NGetDefaultMailCharset()
retVal = prefValue;
}
else
retVal = PL_strdup("iso-8859-1");
retVal = nsCRT::strdup("ISO-8859-1");
}
return (nsnull != retVal) ? retVal : PL_strdup("iso-8859-1");
return (nsnull != retVal) ? retVal : nsCRT::strdup("ISO-8859-1");
}
// Return True if a charset is stateful (e.g. JIS).
PRBool nsMsgI18Nstateful_charset(const char *charset)
{
//TODO: use charset manager's service
return (PL_strcasecmp(charset, "iso-2022-jp") == 0);
return (nsCRT::strcasecmp(charset, "ISO-2022-JP") == 0);
}
// Check 7bit in a given buffer.
@ -259,7 +304,7 @@ PRBool nsMsgI18N7bit_data_part(const char *charset, const char *inString, const
const char *
nsMsgI18NParseMetaCharset(nsFileSpec* fileSpec)
{
static char charset[65];
static char charset[kMAX_CSNAME+1];
char buffer[512];
nsInputFileStream fileStream(*fileSpec);
@ -338,6 +383,19 @@ nsresult nsMsgI18NSaveAsCharset(const char* contentType, const char *charset, co
return NS_ERROR_ILLEGAL_VALUE; // not supported type
}
// Resolve charset alias
nsAutoString aCharset(charset);
NS_WITH_SERVICE(nsICharsetAlias, calias, kCharsetAliasCID, &res);
if (NS_SUCCEEDED(res)) {
nsAutoString aAlias(aCharset);
if (aAlias.Length()) {
res = calias->GetPreferred(aAlias, aCharset);
}
}
if (NS_FAILED(res)) {
return res;
}
nsCOMPtr <nsISaveAsCharset> aConv; // charset converter plus entity, NCR generation
res = nsComponentManager::CreateInstance(kSaveAsCharsetCID, NULL,
nsISaveAsCharset::GetIID(), getter_AddRefs(aConv));
@ -345,7 +403,8 @@ nsresult nsMsgI18NSaveAsCharset(const char* contentType, const char *charset, co
// attribute:
// html text - charset conv then fallback to entity or NCR
// plain text - charset conv then fallback to '?'
res = aConv->Init(charset,
char charset_buf[kMAX_CSNAME+1];
res = aConv->Init(aCharset.ToCString(charset_buf, kMAX_CSNAME+1),
bTEXT_HTML ?
nsISaveAsCharset::attr_EntityAfterCharsetConv + nsISaveAsCharset::attr_FallbackDecimalNCR :
nsISaveAsCharset::attr_plainTextDefault + nsISaveAsCharset::attr_FallbackQuestionMark,

Просмотреть файл

@ -27,6 +27,10 @@
#include "msgCore.h"
#ifndef kMAX_CSNAME
#define kMAX_CSNAME 64
#endif
NS_MSG_BASE char *nsMsgI18NEncodeMimePartIIStr(const char *header, const char *charset, PRBool bUseMime);
NS_MSG_BASE PRBool nsMsgI18Nstateful_charset(const char *charset);
NS_MSG_BASE PRBool nsMsgI18N7bit_data_part(const char *charset, const char *string, const PRUint32 size);

Просмотреть файл

@ -38,6 +38,7 @@
#include "mimevcrd.h"
#include "nsEscape.h"
#include "nsIURI.h"
#include "nsMsgI18N.h"
#include "nsIEventQueueService.h"
#include "nsIStringBundle.h"
@ -50,8 +51,6 @@
// String bundles...
nsCOMPtr<nsIStringBundle> stringBundle = nsnull;
static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
static int MimeInlineTextVCard_parse_line (char *, PRInt32, MimeObject *);
static int MimeInlineTextVCard_parse_eof (MimeObject *, PRBool);
static int MimeInlineTextVCard_parse_begin (MimeObject *obj);
@ -215,60 +214,20 @@ static PRInt32 INTL_ConvertCharset(const char* from_charset, const char* to_char
return -1;
// us-ascii is a subset of utf-8
if ((!nsCRT::strcasecmp(from_charset, "us-ascii") && !nsCRT::strcasecmp(to_charset, "utf-8")) ||
(!nsCRT::strcasecmp(from_charset, "utf-8") && !nsCRT::strcasecmp(to_charset, "us-ascii")))
if ((!nsCRT::strcasecmp(from_charset, "us-ascii") && !nsCRT::strcasecmp(to_charset, "UTF-8")) ||
(!nsCRT::strcasecmp(from_charset, "UTF-8") && !nsCRT::strcasecmp(to_charset, "us-ascii")))
return -1;
NS_WITH_SERVICE(nsICharsetConverterManager, ccm, kCharsetConverterManagerCID, &res);
if(NS_SUCCEEDED(res) && (nsnull != ccm)) {
nsString aCharset(from_charset);
nsIUnicodeDecoder* decoder = nsnull;
PRUnichar *unichars;
PRInt32 unicharLength;
// convert to unicode
res = ccm->GetUnicodeDecoder(&aCharset, &decoder);
if(NS_SUCCEEDED(res) && (nsnull != decoder)) {
PRInt32 srcLen = inLength;
res = decoder->GetMaxLength(inBuffer, srcLen, &unicharLength);
// temporary buffer to hold unicode string
unichars = new PRUnichar[unicharLength];
if (unichars == nsnull) {
res = NS_ERROR_OUT_OF_MEMORY;
}
else {
res = decoder->Convert(inBuffer, &srcLen, unichars, &unicharLength);
// convert from unicode
nsIUnicodeEncoder* encoder = nsnull;
aCharset.SetString(to_charset);
res = ccm->GetUnicodeEncoder(&aCharset, &encoder);
if(NS_SUCCEEDED(res) && (nsnull != encoder)) {
res = encoder->GetMaxLength(unichars, unicharLength, &dstLength);
// allocale an output buffer
dstPtr = (char *) PR_Malloc(dstLength + 1);
if (dstPtr == nsnull) {
res = NS_ERROR_OUT_OF_MEMORY;
}
else {
res = encoder->Convert(unichars, &unicharLength, dstPtr, &dstLength);
}
NS_IF_RELEASE(encoder);
}
delete [] unichars;
}
NS_IF_RELEASE(decoder);
nsString outString;
res = ConvertToUnicode(nsAutoString(from_charset), inBuffer, outString);
if (NS_SUCCEEDED(res)) {
res = ConvertFromUnicode(nsAutoString(to_charset), outString, outBuffer);
if (NS_SUCCEEDED(res)) {
*outLength = nsCRT::strlen(*outBuffer);
}
}
// set the outputs
if (NS_SUCCEEDED(res) && nsnull != dstPtr) {
dstPtr[dstLength] = '\0';
*outBuffer = dstPtr;
*outLength = dstLength;
}
return NS_SUCCEEDED(res) ? 0 : -1;
}
////////////////////////////////////////////////////////////////////////////////

Просмотреть файл

@ -53,7 +53,7 @@ static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CI
extern "C" char * MIME_StripContinuations(char *original);
/* These are needed by other libmime functions */
extern "C" PRInt16 INTL_DefaultWinCharSetID(char a) { return a; }
extern "C" char *INTL_CsidToCharsetNamePt(PRInt16 id) { return "iso-8859-1"; }
extern "C" char *INTL_CsidToCharsetNamePt(PRInt16 id) { return "ISO-8859-1"; }
extern "C" PRInt16 INTL_CharSetNameToID(char *charset) { return 0; }
@ -276,16 +276,16 @@ const char kMsgHeaderQEncoding[] = "Q";
static const char * intl_message_header_encoding(const char* charset)
{
//TODO: make this overridable.
if (!nsCRT::strcasecmp(charset, "iso-2022-jp") ||
!nsCRT::strcasecmp(charset, "iso-2022-kr") ||
!nsCRT::strcasecmp(charset, "hz-gb-2312") ||
!nsCRT::strcasecmp(charset, "shift_jis") ||
!nsCRT::strcasecmp(charset, "euc-jp") ||
!nsCRT::strcasecmp(charset, "big5") ||
!nsCRT::strcasecmp(charset, "gb2312") ||
!nsCRT::strcasecmp(charset, "euc-kr") ||
!nsCRT::strcasecmp(charset, "utf-7") ||
!nsCRT::strcasecmp(charset, "utf-8")) {
if (!nsCRT::strcasecmp(charset, "ISO-2022-JP") ||
!nsCRT::strcasecmp(charset, "ISO-2022-KR") ||
!nsCRT::strcasecmp(charset, "HZ-GB-2312") ||
!nsCRT::strcasecmp(charset, "Shift_JIS") ||
!nsCRT::strcasecmp(charset, "EUC-JP") ||
!nsCRT::strcasecmp(charset, "Big5") ||
!nsCRT::strcasecmp(charset, "GB2312") ||
!nsCRT::strcasecmp(charset, "EUC-KR") ||
!nsCRT::strcasecmp(charset, "UTF-7") ||
!nsCRT::strcasecmp(charset, "UTF-8")) {
return kMsgHeaderBEncoding;
}
@ -294,7 +294,7 @@ static const char * intl_message_header_encoding(const char* charset)
static PRBool stateful_encoding(const char* charset)
{
if (!nsCRT::strcasecmp(charset, "iso-2022-jp"))
if (!nsCRT::strcasecmp(charset, "ISO-2022-JP"))
return PR_TRUE;
return PR_FALSE;
@ -772,9 +772,9 @@ convert_and_encode:
return NULL; //error
}
nsresult rv = nsMsgI18NSaveAsCharset(TEXT_PLAIN,
!nsCRT::strcasecmp(charset, "us-ascii") ? "iso-8859-1" : charset,
!nsCRT::strcasecmp(charset, "us-ascii") ? "ISO-8859-1" : charset,
u, &buf1);
nsAllocator::Free(u);
nsTextFormater::smprintf_free(u);
if (NS_FAILED(rv) || NULL == buf1) {
PR_FREEIF(srcbuf);
PR_FREEIF(retbuf);
@ -985,13 +985,52 @@ char *utf8_EncodeMimePartIIStr(const char *subject, char *charset, int maxLineLe
/* If we are sending JIS then check the pref setting and
* decide if we should convert hankaku (1byte) to zenkaku (2byte) kana.
*/
if (!nsCRT::strcasecmp(charset, "iso-2022-jp")) {
if (!nsCRT::strcasecmp(charset, "ISO-2022-JP")) {
;
}
/* MIME Part2 encode */
buf = utf8_mime_encode_mail_address(charset, subject, maxLineLen);
#if 0 // fix for 18105, need more testing
/* The input buffer may be too large, try to divide it into chunks. */
if (NULL == buf) {
PRUnichar *ucs2 = NULL;
nsAutoString fmt("%s");
ucs2 = nsTextFormater::smprintf(fmt.GetUnicode(), subject); /* convert from UTF-8 so we can chunk up safely */
if (NULL == ucs2)
return NULL;
int ucs2Len = nsCRT::strlen(ucs2);
int chunkLen = ( maxLineLen - nsCRT::strlen(charset) - 7 ) * 3 / 4; /* how many characters we can convert from the src */
nsAutoString chunk;
for (int index = 0; index < ucs2Len; index += chunkLen) {
/* set string, chunk length or remaining buffer length */
chunk.SetString(&ucs2[index], chunkLen <= (ucs2Len - index) ? chunkLen : (ucs2Len - index));
char *utf8 = chunk.ToNewUTF8String(); /* convert to UTF-8, again */
if (NULL == utf8) {
nsTextFormater::smprintf_free(ucs2);
PR_FREEIF(buf);
return NULL;
}
char * encoded_chunk = utf8_mime_encode_mail_address(charset, utf8, maxLineLen);
nsAllocator::Free(utf8);
if (NULL == encoded_chunk) {
PR_FREEIF(buf);
return NULL;
}
buf = PR_sprintf_append(buf, "%s%s", (0 == index) ? "" : "\r\n\t", encoded_chunk);
PR_Free(encoded_chunk);
}
nsTextFormater::smprintf_free(ucs2);
}
#endif //0
return buf;
}
@ -1159,7 +1198,7 @@ char *intl_decode_mime_part2_str(const char *header, char* charset)
break; /* exit the loop because there are no charset info */
*q++ = '\0';
if (charset)
PL_strcpy(charset, nsCRT::strcasecmp(p, "us-ascii") ? p : "iso-8859-1");
PL_strcpy(charset, nsCRT::strcasecmp(p, "us-ascii") ? p : "ISO-8859-1");
if (*(q+1) == '?' &&
(*q == 'Q' || *q == 'q' || *q == 'B' || *q == 'b'))
@ -1209,79 +1248,6 @@ char *intl_decode_mime_part2_str(const char *header, char* charset)
}
}
////////////////////////////////////////////////////////////////////////////////
static PRInt32 INTL_ConvertToUnicode(const char* from_charset, const char* aBuffer, const PRInt32 aLength,
void** uniBuffer, PRInt32* uniLength)
{
nsresult res;
if (nsnull == from_charset || '\0' == *from_charset|| nsnull == aBuffer) {
return -1;
}
NS_WITH_SERVICE(nsICharsetConverterManager, ccm, kCharsetConverterManagerCID, &res);
if(NS_SUCCEEDED(res) && (nsnull != ccm)) {
nsString aCharset(from_charset);
nsIUnicodeDecoder* decoder = nsnull;
PRUnichar *unichars;
PRInt32 unicharLength;
// convert to unicode
res = ccm->GetUnicodeDecoder(&aCharset, &decoder);
if(NS_SUCCEEDED(res) && (nsnull != decoder)) {
PRInt32 srcLen = aLength;
res = decoder->GetMaxLength(aBuffer, srcLen, &unicharLength);
// allocale an output buffer
unichars = (PRUnichar *) PR_Malloc(unicharLength * sizeof(PRUnichar));
if (unichars != nsnull) {
res = decoder->Convert(aBuffer, &srcLen, unichars, &unicharLength);
*uniBuffer = (void *) unichars;
*uniLength = unicharLength;
}
else {
res = NS_ERROR_OUT_OF_MEMORY;
}
NS_IF_RELEASE(decoder);
}
}
return NS_SUCCEEDED(res) ? 0 : -1;
}
static PRInt32 INTL_ConvertFromUnicode(const char* to_charset, const void* uniBuffer, const PRInt32 uniLength,
char** aBuffer)
{
nsresult res;
if (nsnull == to_charset || '\0' == *to_charset|| nsnull == uniBuffer) {
return -1;
}
NS_WITH_SERVICE(nsICharsetConverterManager, ccm, kCharsetConverterManagerCID, &res);
if(NS_SUCCEEDED(res) && (nsnull != ccm)) {
nsString aCharset(to_charset);
nsIUnicodeEncoder* encoder = nsnull;
// convert from unicode
res = ccm->GetUnicodeEncoder(&aCharset, &encoder);
if(NS_SUCCEEDED(res) && (nsnull != encoder)) {
const PRUnichar *unichars = (const PRUnichar *) uniBuffer;
PRInt32 unicharLength = uniLength;
PRInt32 dstLength;
res = encoder->GetMaxLength(unichars, unicharLength, &dstLength);
// allocale an output buffer
*aBuffer = (char *) PR_Malloc(dstLength + 1);
if (*aBuffer != nsnull) {
res = encoder->Convert(unichars, &unicharLength, *aBuffer, &dstLength);
(*aBuffer)[dstLength] = '\0';
}
else {
res = NS_ERROR_OUT_OF_MEMORY;
}
NS_IF_RELEASE(encoder);
}
}
return NS_SUCCEEDED(res) ? 0 : -1;
}
////////////////////////////////////////////////////////////////////////////////
MimeCharsetConverterClass::MimeCharsetConverterClass()
@ -1311,19 +1277,24 @@ PRInt32 MimeCharsetConverterClass::Initialize(const char* from_charset, const ch
NS_ASSERTION(NULL == mEncoder, "No reinitialization allowed.");
mInputCharset.SetString(from_charset); // remember input charset for a hint
if (mInputCharset.IsEmpty()) {
mInputCharset.SetString("ISO-8859-1");
}
mOutputCharset.SetString(to_charset); // remember output charset
if (mOutputCharset.IsEmpty()) {
mOutputCharset.SetString("UTF-8");
}
mAutoDetect = autoDetect;
mMaxNumCharsDetect = maxNumCharsDetect;
// Resolve charset alias
NS_WITH_SERVICE(nsICharsetAlias, calias, kCharsetAliasCID, &res);
if (NS_SUCCEEDED(res) && (nsnull != calias)) {
nsString aAlias;
aAlias.SetString(from_charset);
if (NS_SUCCEEDED(res)) {
nsString aAlias(mInputCharset);
if (aAlias.Length()) {
res = calias->GetPreferred(aAlias, mInputCharset);
}
aAlias.SetString(to_charset);
aAlias = mOutputCharset;
if (aAlias.Length()) {
res = calias->GetPreferred(aAlias, mOutputCharset);
}
@ -1335,7 +1306,7 @@ PRInt32 MimeCharsetConverterClass::Initialize(const char* from_charset, const ch
PL_strcpy(detector_progid, NS_STRCDETECTOR_PROGID_BASE);
NS_WITH_SERVICE(nsIPref, prefs, kPrefCID, &res);
if (nsnull != prefs && NS_SUCCEEDED(res)) {
if (NS_SUCCEEDED(res)) {
if (NS_SUCCEEDED(prefs->CopyCharPref("mail.charset.detector", &detector_name))) {
PL_strcat(detector_progid, detector_name);
PR_FREEIF(detector_name);
@ -1361,7 +1332,7 @@ PRInt32 MimeCharsetConverterClass::Initialize(const char* from_charset, const ch
// Set up charset converters.
NS_WITH_SERVICE(nsICharsetConverterManager, ccm, kCharsetConverterManagerCID, &res);
if (NS_SUCCEEDED(res) && (nsnull != ccm)) {
if (NS_SUCCEEDED(res)) {
// create a decoder (conv to unicode), ok if failed if we do auto detection
res = ccm->GetUnicodeDecoder(&mInputCharset, &mDecoder);
if (NS_SUCCEEDED(res) || mAutoDetect) {
@ -1420,7 +1391,7 @@ PRInt32 MimeCharsetConverterClass::Convert(const char* inBuffer, const PRInt32 i
}
else {
NS_WITH_SERVICE(nsICharsetConverterManager, ccm, kCharsetConverterManagerCID, &res);
if (NS_SUCCEEDED(res) && (nsnull != ccm)) {
if (NS_SUCCEEDED(res)) {
NS_IF_RELEASE(mDecoderDetected);
mDecoderDetected = nsnull;
res = ccm->GetUnicodeDecoder(&aCharsetDetected, &mDecoderDetected);
@ -1437,20 +1408,6 @@ PRInt32 MimeCharsetConverterClass::Convert(const char* inBuffer, const PRInt32 i
// Decoders are not available, do fallback
if (NULL == mDecoder && NULL == mDecoderDetected) {
// if the input charset is empty and the out charset is utf-8
// then assume latin1 to avoid generating a wrong utf-8
if (!mInputCharset.Length() &&
mOutputCharset.EqualsIgnoreCase("utf-8")) {
nsAutoString tempStr("");
tempStr.Append(inBuffer, inLength);
*outBuffer = tempStr.ToNewUTF8String();
if (NULL != *outBuffer) {
*outLength = nsCRT::strlen(*outBuffer);
return 0;
}
return -1;
}
// otherwise, duplicate the input
*outBuffer = (char *) PR_Malloc(inLength+1);
if (NULL != *outBuffer) {
nsCRT::memcpy(*outBuffer, inBuffer, inLength);
@ -1532,8 +1489,8 @@ PRBool MimeCharsetConverterClass::NeedCharsetConversion(const nsString& from_cha
else if (from_charset.EqualsIgnoreCase(to_charset)) {
return PR_FALSE;
}
else if ((from_charset.EqualsIgnoreCase("us-ascii") && to_charset.EqualsIgnoreCase("utf-8")) ||
(from_charset.EqualsIgnoreCase("utf-8") && to_charset.EqualsIgnoreCase("us-ascii"))) {
else if ((from_charset.EqualsIgnoreCase("us-ascii") && to_charset.EqualsIgnoreCase("UTF-8")) ||
(from_charset.EqualsIgnoreCase("UTF-8") && to_charset.EqualsIgnoreCase("us-ascii"))) {
return PR_FALSE;
}
return PR_TRUE;
@ -1575,16 +1532,9 @@ PRInt32 MIME_ConvertCharset(const PRBool autoDetection, const char* from_charset
const char* inBuffer, const PRInt32 inLength, char** outBuffer, PRInt32* outLength,
PRInt32* numUnConverted)
{
// char srcCharset[kMAX_CSNAME+1], dstCharset[kMAX_CSNAME+1];
MimeCharsetConverterClass aMimeCharsetConverterClass;
PRInt32 res;
// commenting out per Naoki's instructions.
// srcCharset[0] = '\0';
// dstCharset[0] = '\0';
// PL_strcpy(srcCharset, nsCRT::strcasecmp(from_charset, "us-ascii") ? (char *) from_charset : "iso-8859-1");
// PL_strcpy(dstCharset, nsCRT::strcasecmp(from_charset, "us-ascii") ? (char *) to_charset : "iso-8859-1");
res = aMimeCharsetConverterClass.Initialize(from_charset, to_charset, autoDetection, -1);
if (res != -1) {
@ -1594,26 +1544,6 @@ PRInt32 MIME_ConvertCharset(const PRBool autoDetection, const char* from_charset
return res;
}
PRInt32 MIME_ConvertToUnicode(const char* from_charset, const char* inCstring,
void** uniBuffer, PRInt32* uniLength)
{
char charset[kMAX_CSNAME+1];
// Since we don't have a converter for us-ascii and the manager does not map,
// so we do the mapping here.
PL_strcpy(charset, nsCRT::strcasecmp(from_charset, "us-ascii") ? (char *) from_charset : "iso-8859-1");
return INTL_ConvertToUnicode(charset, inCstring, nsCRT::strlen(inCstring), uniBuffer, uniLength);
}
PRInt32 MIME_ConvertFromUnicode(const char* to_charset, const void* uniBuffer, const PRInt32 uniLength,
char** outCstring)
{
char charset[kMAX_CSNAME+1];
// Since we don't have a converter for us-ascii and the manager does not map,
// so we do the mapping here.
PL_strcpy(charset, nsCRT::strcasecmp(to_charset, "us-ascii") ? (char *) to_charset : "iso-8859-1");
return INTL_ConvertFromUnicode(charset, uniBuffer, uniLength, outCstring);
}
extern "C" char *MIME_DecodeMimePartIIStr(const char *header, char *charset)
{
char *result = nsnull;

Просмотреть файл

@ -143,34 +143,6 @@ PRInt32 MIME_ConvertCharset(const PRBool autoDetection, const char* from_charset
const char* inBuffer, const PRInt32 inLength, char** outBuffer, PRInt32* outLength,
PRInt32* numUnConverted);
/**
* Convert an input string with a charset into unicode.
*
* Note the caller cannot call this muliple times for a large buffer (of multi byte text)
* since this will not save a state info (i.e. converter instance will be created/destroyed for every call).
*
* @param from_charset [IN] A charset name in C string.
* @param inCstring [IN] Input buffer (in C string) to convert.
* @param uniBuffer [OUT] Output unicode buffer is set. Allocated buffer should be freed by PR_FREE.
* @param uniLength [OUT] Output unicode buffer character length is set.
* @return 0 is success, otherwise error.
*/
PRInt32 MIME_ConvertToUnicode(const char* from_charset, const char* inCstring,
void** uniBuffer, PRInt32* uniLength);
/**
* Conver an unicode buffer to a given charset.
*
*
* @param to_charset [IN] A charset name in C string.
* @param uniBuffer [IN] Input unicode buffer to convert.
* @param uniLength [IN] Input unicode buffer character length.
* @param outCstring [OUT] Output buffer (in C string) is set. Allocated buffer should be freed by PR_FREE.
* @return 0 is success, otherwise error.
*/
PRInt32 MIME_ConvertFromUnicode(const char* to_charset, const void* uniBuffer, const PRInt32 uniLength,
char** outCstring);
/**
* Get a next character position in an UTF-8 string.

Просмотреть файл

@ -25,6 +25,7 @@
#include "nscore.h"
#include "nsMimeConverter.h"
#include "comi18n.h"
#include "nsMsgI18N.h"
#include "prmem.h"
#include "plstr.h"
@ -53,15 +54,13 @@ nsMimeConverter::DecodeMimePartIIStr(const nsString& header,
nsString& decodedString)
{
char charsetCstr[kMAX_CSNAME+1];
char *encodedCstr;
char *decodedCstr;
char *encodedCstr = nsnull;
char *decodedCstr = nsnull;
nsresult res = NS_OK;
(void) charset.ToCString(charsetCstr, kMAX_CSNAME+1);
encodedCstr = header.ToNewCString();
if (nsnull != encodedCstr) {
PRUnichar *unichars;
PRInt32 unicharLength;
// apply MIME decode.
decodedCstr = MIME_DecodeMimePartIIStr((const char *) encodedCstr, charsetCstr);
if (nsnull == decodedCstr) {
@ -71,24 +70,13 @@ nsMimeConverter::DecodeMimePartIIStr(const nsString& header,
}
else {
// no MIME encoded, convert default charset to unicode
res = MIME_ConvertToUnicode(charsetCstr, (const char *) encodedCstr,
(void **) &unichars, &unicharLength);
if (NS_SUCCEEDED(res)) {
decodedString.SetString(unichars, unicharLength);
PR_Free(unichars);
}
res = ConvertToUnicode(charset, (const char *) encodedCstr, decodedString);
}
}
else {
// convert MIME charset to unicode
res = MIME_ConvertToUnicode(charsetCstr, (const char *) decodedCstr,
(void **) &unichars, &unicharLength);
if (NS_SUCCEEDED(res)) {
charset.SetString(charsetCstr);
decodedString.SetString(unichars, unicharLength);
PR_Free(unichars);
}
PR_Free(decodedCstr);
res = ConvertToUnicode(nsAutoString(charsetCstr), (const char *) decodedCstr, decodedString);
PR_FREEIF(decodedCstr);
}
nsAllocator::Free(encodedCstr);
}