From 07953b40b45bc442c0a7f8e886b796d302229157 Mon Sep 17 00:00:00 2001 From: "shanjian%netscape.com" Date: Tue, 20 Aug 2002 03:32:28 +0000 Subject: [PATCH] #162377 Non-ASCII filename is not shown when saving and downloading from a ftp listing added code to convert string bundle to ncr. r=ftang, sr=jst --- .../streamconv/converters/nsIndexedToHTML.cpp | 127 ++++++++++++++++-- .../streamconv/converters/nsIndexedToHTML.h | 3 + 2 files changed, 116 insertions(+), 14 deletions(-) diff --git a/netwerk/streamconv/converters/nsIndexedToHTML.cpp b/netwerk/streamconv/converters/nsIndexedToHTML.cpp index c2c10daaf6b..75a94bd9524 100644 --- a/netwerk/streamconv/converters/nsIndexedToHTML.cpp +++ b/netwerk/streamconv/converters/nsIndexedToHTML.cpp @@ -54,6 +54,28 @@ NS_IMPL_THREADSAFE_ISUPPORTS4(nsIndexedToHTML, static NS_DEFINE_CID(kDateTimeFormatCID, NS_DATETIMEFORMAT_CID); +static void ConvertNonAsciiToNCR(const nsAString& in, nsAFlatString& out) +{ + nsAString::const_iterator start, end; + + in.BeginReading(start); + in.EndReading(end); + + out.Truncate(); + + while (start != end) { + if (*start < 128) { + out.Append(*start++); + } else { + out.Append(NS_LITERAL_STRING("&#x")); + nsAutoString hex; + hex.AppendInt(*start++, 16); + out.Append(hex); + out.Append((PRUnichar)';'); + } + } +} + NS_METHOD nsIndexedToHTML::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult) { nsresult rv; @@ -201,10 +223,23 @@ nsIndexedToHTML::OnStartRequest(nsIRequest* request, nsISupports *aContext) { } nsString buffer; - buffer.Assign(NS_LITERAL_STRING("\n") + + nsXPIDLCString encoding; + rv = mParser->GetEncoding(getter_Copies(encoding)); + if (NS_FAILED(rv)) return rv; + + buffer.Append(NS_LITERAL_STRING(" encoding=\"") + + NS_ConvertASCIItoUCS2(encoding) + + NS_LITERAL_STRING("\"")); + + buffer.Append(NS_LITERAL_STRING("?>\n") + NS_LITERAL_STRING("\n")); @@ -214,9 +249,6 @@ nsIndexedToHTML::OnStartRequest(nsIRequest* request, nsISupports *aContext) { buffer.Append(NS_LITERAL_STRING("\n")); nsXPIDLString title; - nsXPIDLCString encoding; - rv = mParser->GetEncoding(getter_Copies(encoding)); - if (NS_FAILED(rv)) return rv; if (!mTextToSubURI) { mTextToSubURI = do_GetService(NS_ITEXTTOSUBURI_CONTRACTID, &rv); @@ -241,7 +273,12 @@ nsIndexedToHTML::OnStartRequest(nsIRequest* request, nsISupports *aContext) { sizeof(formatTitle)/sizeof(PRUnichar*), getter_Copies(title)); if (NS_FAILED(rv)) return rv; - buffer.Append(title); + + // we want to convert string bundle to NCR + // to ensure they're shown in any charsets + nsAutoString strNCR; + ConvertNonAsciiToNCR(title, strNCR); + buffer.Append(strNCR); buffer.Append(NS_LITERAL_STRING("\n
") + tableHeading); //buffer.Append(NS_LITERAL_STRING("NameSizeLast modified\n")); @@ -278,10 +316,11 @@ nsIndexedToHTML::OnStartRequest(nsIRequest* request, nsISupports *aContext) { getter_Copies(parentText)); if (NS_FAILED(rv)) return rv; + ConvertNonAsciiToNCR(parentText, strNCR); buffer.Append(NS_LITERAL_STRING("") + - parentText + + strNCR + NS_LITERAL_STRING("\n")); } @@ -318,12 +357,72 @@ nsresult nsIndexedToHTML::FormatInputStream(nsIRequest* aRequest, nsISupports *aContext, const nsAString &aBuffer) { nsresult rv = NS_OK; - NS_ConvertUCS2toUTF8 buffer(aBuffer); + + // set up unicode encoder + if (!mUnicodeEncoder) { + nsXPIDLCString encoding; + rv = mParser->GetEncoding(getter_Copies(encoding)); + if (NS_SUCCEEDED(rv)) { + nsCOMPtr charsetConverterManager; + charsetConverterManager = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv); + nsCOMPtr charsetAtom; + rv = charsetConverterManager->GetCharsetAtom2(encoding.get(), getter_AddRefs(charsetAtom)); + if (NS_SUCCEEDED(rv)) { + rv = charsetConverterManager->GetUnicodeEncoder(charsetAtom, + getter_AddRefs(mUnicodeEncoder)); + if (NS_SUCCEEDED(rv)) + rv = mUnicodeEncoder->SetOutputErrorBehavior(nsIUnicodeEncoder::kOnError_Replace, + nsnull, (PRUnichar)'?'); + } + } + } + + // convert the data with unicode encoder + char *buffer = nsnull; + PRInt32 dstLength; + if (NS_SUCCEEDED(rv)) { + PRInt32 unicharLength = aBuffer.Length(); + rv = mUnicodeEncoder->GetMaxLength(PromiseFlatString(aBuffer).get(), + unicharLength, &dstLength); + if (NS_SUCCEEDED(rv)) { + buffer = (char *) nsMemory::Alloc(dstLength); + NS_ENSURE_TRUE(buffer, NS_ERROR_OUT_OF_MEMORY); + + rv = mUnicodeEncoder->Convert(PromiseFlatString(aBuffer).get(), &unicharLength, + buffer, &dstLength); + if (NS_SUCCEEDED(rv)) { + PRInt32 finLen = 0; + rv = mUnicodeEncoder->Finish(buffer + dstLength, &finLen); + if (NS_SUCCEEDED(rv)) + dstLength += finLen; + } + } + } + + // if conversion error then fallback to UTF-8 + if (NS_FAILED(rv)) { + rv = NS_OK; + if (buffer) { + nsMemory::Free(buffer); + buffer = nsnull; + } + } + nsCOMPtr inputData; - rv = NS_NewCStringInputStream(getter_AddRefs(inputData), buffer); - if (NS_FAILED(rv)) return rv; - rv = mListener->OnDataAvailable(aRequest, aContext, - inputData, 0, buffer.Length()); + if (buffer) { + rv = NS_NewCStringInputStream(getter_AddRefs(inputData), nsDependentCString(buffer, dstLength)); + nsMemory::Free(buffer); + NS_ENSURE_SUCCESS(rv, rv); + rv = mListener->OnDataAvailable(aRequest, aContext, + inputData, 0, dstLength); + } + else { + NS_ConvertUCS2toUTF8 utf8Buffer(aBuffer); + rv = NS_NewCStringInputStream(getter_AddRefs(inputData), utf8Buffer); + NS_ENSURE_SUCCESS(rv, rv); + rv = mListener->OnDataAvailable(aRequest, aContext, + inputData, 0, utf8Buffer.Length()); + } return (rv); } diff --git a/netwerk/streamconv/converters/nsIndexedToHTML.h b/netwerk/streamconv/converters/nsIndexedToHTML.h index 8582905c7d7..b3481309e71 100644 --- a/netwerk/streamconv/converters/nsIndexedToHTML.h +++ b/netwerk/streamconv/converters/nsIndexedToHTML.h @@ -49,6 +49,8 @@ #include "nsIStringBundle.h" #include "nsIStringStream.h" #include "nsITextToSubURI.h" +#include "nsICharsetConverterManager.h" +#include "nsICharsetConverterManager2.h" #define NS_NSINDEXEDTOHTMLCONVERTER_CID \ { 0xcf0f71fd, 0xfafd, 0x4e2b, {0x9f, 0xdc, 0x13, 0x4d, 0x97, 0x2e, 0x16, 0xe2} } @@ -85,6 +87,7 @@ protected: nsCOMPtr mBundle; nsCOMPtr mTextToSubURI; + nsCOMPtr mUnicodeEncoder; private: // Current number of rows