Optimize nsSegmentEncoder to not get an mEncoder unless it actually has

encoding to do (has a non-ascii spec segment).  Bug 212475, r=darin, sr=dbaron
This commit is contained in:
bzbarsky%mit.edu 2003-07-12 23:06:13 +00:00
parent 9a8abe477b
commit 401365f06a
4 changed files with 63 additions and 28 deletions

View File

@ -170,27 +170,8 @@ nsPrefObserver::Observe(nsISupports *subject,
nsStandardURL::
nsSegmentEncoder::nsSegmentEncoder(const char *charset)
: mCharset(charset)
{
if (!charset || !*charset)
return;
// get unicode encoder (XXX cache this someplace)
nsresult rv;
if (!gCharsetMgr) {
nsCOMPtr<nsICharsetConverterManager> convMgr(
do_GetService("@mozilla.org/charset-converter-manager;1", &rv));
if (NS_FAILED(rv)) {
NS_ERROR("failed to get charset-converter-manager");
return;
}
NS_ADDREF(gCharsetMgr = convMgr);
}
rv = gCharsetMgr->GetUnicodeEncoder(charset, getter_AddRefs(mEncoder));
if (NS_FAILED(rv)) {
NS_ERROR("failed to get unicode encoder");
mEncoder = 0; // just in case
}
}
PRInt32 nsStandardURL::
@ -207,16 +188,21 @@ nsSegmentEncoder::EncodeSegmentCount(const char *str,
len = seg.mLen;
// first honor the origin charset if appropriate. as an optimization,
// only do this if |str| is non-ASCII.
// only do this if the segment is non-ASCII. Further, if mCharset is
// null or the empty string then the origin charset is UTF-8 and there
// is nothing to do.
nsCAutoString encBuf;
if (mEncoder && !nsCRT::IsAscii(str)) {
NS_ConvertUTF8toUCS2 ucsBuf(Substring(str + pos, str + pos + len));
if (NS_SUCCEEDED(EncodeString(mEncoder, ucsBuf, encBuf))) {
str = encBuf.get();
pos = 0;
len = encBuf.Length();
if (!nsCRT::IsAscii(str + pos, len) && mCharset && *mCharset) {
// we have to encode this segment
if (mEncoder || InitUnicodeEncoder()) {
NS_ConvertUTF8toUCS2 ucsBuf(Substring(str + pos, str + pos + len));
if (NS_SUCCEEDED(EncodeString(mEncoder, ucsBuf, encBuf))) {
str = encBuf.get();
pos = 0;
len = encBuf.Length();
}
// else some failure occured... assume UTF-8 is ok.
}
// else some failure occured... assume UTF-8 is ok.
}
// escape per RFC2396 unless UTF-8 and allowed by preferences
@ -250,6 +236,30 @@ nsSegmentEncoder::EncodeSegment(const nsASingleFragmentCString &str,
return str;
}
PRBool nsStandardURL::
nsSegmentEncoder::InitUnicodeEncoder()
{
NS_ASSERTION(!mEncoder, "Don't call this if we have an encoder already!");
nsresult rv;
if (!gCharsetMgr) {
rv = CallGetService("@mozilla.org/charset-converter-manager;1",
&gCharsetMgr);
if (NS_FAILED(rv)) {
NS_ERROR("failed to get charset-converter-manager");
return PR_FALSE;
}
}
rv = gCharsetMgr->GetUnicodeEncoder(mCharset, getter_AddRefs(mEncoder));
if (NS_FAILED(rv)) {
NS_ERROR("failed to get unicode encoder");
mEncoder = 0; // just in case
return PR_FALSE;
}
return PR_TRUE;
}
#define GET_SEGMENT_ENCODER(name) \
nsSegmentEncoder name(mOriginCharset.get())

View File

@ -131,6 +131,10 @@ public: /* internal -- HPUX compiler can't handle this being private */
PRInt16 mask,
nsAFlatCString &buf);
private:
PRBool InitUnicodeEncoder();
const char* mCharset; // Caller should keep this alive for
// the life of the segment encoder
nsCOMPtr<nsIUnicodeEncoder> mEncoder;
};
friend class nsSegmentEncoder;

View File

@ -469,6 +469,26 @@ PRBool nsCRT::IsAscii(const char *aString) {
}
return PR_TRUE;
}
/**
* Determine whether the given string consists of valid ascii chars
*
* @param aString is null terminated
* @param aLength is the number of chars to test. This must be at most
* the number of chars in aString before the null terminator
* @return PR_TRUE if all chars are valid ASCII chars, PR_FALSE otherwise
*/
PRBool nsCRT::IsAscii(const char* aString, PRUnichar aLength)
{
const char* end = aString + aLength;
while (aString < end) {
NS_ASSERTION(*aString, "Null byte before end of data!");
if (0x80 & *aString)
return PR_FALSE;
++aString;
}
return PR_TRUE;
}
/**
* Determine if given char in valid alpha range
*

View File

@ -262,6 +262,7 @@ public:
static PRBool IsAsciiDigit(PRUnichar aChar);
static PRBool IsAsciiSpace(PRUnichar aChar);
static PRBool IsAscii(const char* aString);
static PRBool IsAscii(const char* aString, PRUnichar aLength);
};
#define FF '\014'