Bug 575043: Remove internal uses of nsICaseConversion. r=smontagu sr=roc

--HG--
extra : rebase_source : f95ad3f21a95e354324e1524c378cad7146f3241
This commit is contained in:
Kyle Huey 2010-07-29 12:22:16 -07:00
parent 42bf6c49ea
commit cc25e38cd5
18 changed files with 287 additions and 479 deletions

View File

@ -111,7 +111,6 @@ class nsIRunnable;
class nsIInterfaceRequestor;
template<class E> class nsCOMArray;
struct JSRuntime;
class nsICaseConversion;
class nsIUGenCategory;
class nsIWidget;
class nsIDragSession;
@ -616,11 +615,6 @@ public:
return sWordBreaker;
}
static nsICaseConversion* GetCaseConv()
{
return sCaseConv;
}
static nsIUGenCategory* GetGenCat()
{
return sGenCat;
@ -1741,7 +1735,6 @@ private:
static nsILineBreaker* sLineBreaker;
static nsIWordBreaker* sWordBreaker;
static nsICaseConversion* sCaseConv;
static nsIUGenCategory* sGenCat;
// Holds pointers to nsISupports* that should be released at shutdown

View File

@ -146,7 +146,6 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
#include "nsIMEStateManager.h"
#include "nsContentErrors.h"
#include "nsUnicharUtilCIID.h"
#include "nsICaseConversion.h"
#include "nsCompressedCharMap.h"
#include "nsINativeKeyBindings.h"
#include "nsIDOMNSUIEvent.h"
@ -241,7 +240,6 @@ nsIContentPolicy *nsContentUtils::sContentPolicyService;
PRBool nsContentUtils::sTriedToGetContentPolicy = PR_FALSE;
nsILineBreaker *nsContentUtils::sLineBreaker;
nsIWordBreaker *nsContentUtils::sWordBreaker;
nsICaseConversion *nsContentUtils::sCaseConv;
nsIUGenCategory *nsContentUtils::sGenCat;
nsTArray<nsISupports**> *nsContentUtils::sPtrsToPtrsToRelease;
nsIScriptRuntime *nsContentUtils::sScriptRuntimes[NS_STID_ARRAY_UBOUND];
@ -404,9 +402,6 @@ nsContentUtils::Init()
rv = CallGetService(NS_WBRK_CONTRACTID, &sWordBreaker);
NS_ENSURE_SUCCESS(rv, rv);
rv = CallGetService(NS_UNICHARUTIL_CONTRACTID, &sCaseConv);
NS_ENSURE_SUCCESS(rv, rv);
rv = CallGetService(NS_UNICHARCATEGORY_CONTRACTID, &sGenCat);
NS_ENSURE_SUCCESS(rv, rv);
@ -1083,7 +1078,6 @@ nsContentUtils::Shutdown()
NS_IF_RELEASE(sIOService);
NS_IF_RELEASE(sLineBreaker);
NS_IF_RELEASE(sWordBreaker);
NS_IF_RELEASE(sCaseConv);
NS_IF_RELEASE(sGenCat);
#ifdef MOZ_XTF
NS_IF_RELEASE(sXTFService);

View File

@ -79,7 +79,6 @@
#include "nsServiceManagerUtils.h"
#include "nsIUnicodeEncoder.h"
#include "nsIUnicodeDecoder.h"
#include "nsICaseConversion.h"
#include "nsICharsetConverterManager.h"
#include "nsUnicharUtilCIID.h"
#include "nsUnicharUtils.h"
@ -5211,7 +5210,6 @@ struct cs_info * get_current_cs(const char * es) {
nsCOMPtr<nsIUnicodeEncoder> encoder;
nsCOMPtr<nsIUnicodeDecoder> decoder;
nsCOMPtr<nsICaseConversion> caseConv;
nsresult rv;
nsCOMPtr<nsICharsetConverterManager> ccm = do_GetService(kCharsetConverterManagerCID, &rv);
@ -5227,10 +5225,6 @@ struct cs_info * get_current_cs(const char * es) {
return nsnull;
decoder->SetInputErrorBehavior(decoder->kOnError_Signal);
caseConv = do_GetService(kUnicharUtilCID, &rv);
if (NS_FAILED(rv))
return nsnull;
ccs = new cs_info[256];
for (unsigned int i = 0; i <= 0xff; ++i) {
@ -5252,18 +5246,14 @@ struct cs_info * get_current_cs(const char * es) {
// NS_OK_UDEC_MOREOUTPUT or NS_OK_UDEC_MOREINPUT.
if (rv != NS_OK || charLength != 1 || uniLength != 1)
break;
rv = caseConv->ToLower(uni, &uniCased);
if (NS_FAILED(rv))
break;
uniCased = ToLowerCase(uni);
rv = encoder->Convert(&uniCased, &uniLength, &lower, &charLength);
// Explicitly check NS_OK because we don't want to allow
// NS_OK_UDEC_MOREOUTPUT or NS_OK_UDEC_MOREINPUT.
if (rv != NS_OK || charLength != 1 || uniLength != 1)
break;
rv = caseConv->ToUpper(uni, &uniCased);
if (NS_FAILED(rv))
break;
uniCased = ToUpperCase(uni);
rv = encoder->Convert(&uniCased, &uniLength, &upper, &charLength);
// Explicitly check NS_OK because we don't want to allow
// NS_OK_UDEC_MOREOUTPUT or NS_OK_UDEC_MOREINPUT.
@ -5392,15 +5382,6 @@ void free_utf_tbl() {
}
}
#ifdef MOZILLA_CLIENT
static nsCOMPtr<nsICaseConversion>& getcaseConv()
{
nsresult rv;
static nsCOMPtr<nsICaseConversion> caseConv = do_GetService(kUnicharUtilCID, &rv);
return caseConv;
}
#endif
unsigned short unicodetoupper(unsigned short c, int langnum)
{
// In Azeri and Turkish, I and i dictinct letters:
@ -5412,9 +5393,7 @@ unsigned short unicodetoupper(unsigned short c, int langnum)
return u_toupper(c);
#else
#ifdef MOZILLA_CLIENT
PRUnichar ch2;
getcaseConv()->ToUpper((PRUnichar) c, &ch2);
return ch2;
return ToUpperCase((PRUnichar) c);
#else
return (utf_tbl) ? utf_tbl[c].cupper : c;
#endif
@ -5432,9 +5411,7 @@ unsigned short unicodetolower(unsigned short c, int langnum)
return u_tolower(c);
#else
#ifdef MOZILLA_CLIENT
PRUnichar ch2;
getcaseConv()->ToLower((PRUnichar) c, &ch2);
return ch2;
return ToLowerCase((PRUnichar) c);
#else
return (utf_tbl) ? utf_tbl[c].clower : c;
#endif

View File

@ -39,6 +39,7 @@
#include "nsICharsetAlias.h"
#include "nsReadableUtils.h"
#include "nsIServiceManager.h"
#include "nsUnicharUtils.h"
#include "nsUnicharUtilCIID.h"
#include "nsCRT.h"
@ -51,8 +52,7 @@ NS_INTERFACE_MAP_BEGIN(mozEnglishWordUtils)
NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(mozEnglishWordUtils)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_3(mozEnglishWordUtils,
mCaseConv,
NS_IMPL_CYCLE_COLLECTION_2(mozEnglishWordUtils,
mCategories,
mURLDetector)
@ -62,7 +62,6 @@ mozEnglishWordUtils::mozEnglishWordUtils()
nsresult rv;
mURLDetector = do_CreateInstance(MOZ_TXTTOHTMLCONV_CONTRACTID, &rv);
mCaseConv = do_GetService(NS_UNICHARUTIL_CONTRACTID);
mCategories = do_GetService(NS_UNICHARCATEGORY_CONTRACTID);
}
@ -118,15 +117,15 @@ NS_IMETHODIMP mozEnglishWordUtils::GetRootForm(const PRUnichar *aWord, PRUint32
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(0, tmpPtr);
return NS_ERROR_OUT_OF_MEMORY;
}
mCaseConv->ToLower(tmpPtr[0], tmpPtr[0], length);
ToLowerCase(tmpPtr[0], tmpPtr[0], length);
tmpPtr[1] = ToNewUnicode(word);
if (!tmpPtr[1]) {
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(1, tmpPtr);
return NS_ERROR_OUT_OF_MEMORY;
}
mCaseConv->ToLower(tmpPtr[1], tmpPtr[1], length);
mCaseConv->ToUpper(tmpPtr[1], tmpPtr[1], 1);
ToLowerCase(tmpPtr[1], tmpPtr[1], length);
ToUpperCase(tmpPtr[1], tmpPtr[1], 1);
tmpPtr[2] = ToNewUnicode(word);
if (!tmpPtr[2]) {
@ -148,7 +147,7 @@ NS_IMETHODIMP mozEnglishWordUtils::GetRootForm(const PRUnichar *aWord, PRUint32
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(0, tmpPtr);
return NS_ERROR_OUT_OF_MEMORY;
}
mCaseConv->ToLower(tmpPtr[0], tmpPtr[0], length);
ToLowerCase(tmpPtr[0], tmpPtr[0], length);
tmpPtr[1] = ToNewUnicode(word);
if (!tmpPtr[1]) {
@ -245,15 +244,14 @@ NS_IMETHODIMP mozEnglishWordUtils::FindNextWord(const PRUnichar *word, PRUint32
mozEnglishWordUtils::myspCapitalization
mozEnglishWordUtils::captype(const nsString &word)
{
if(!mCaseConv) return HuhCap; //punt
PRUnichar* lword=ToNewUnicode(word);
mCaseConv->ToUpper(lword,lword,word.Length());
ToUpperCase(lword,lword,word.Length());
if(word.Equals(lword)){
nsMemory::Free(lword);
return AllCap;
}
mCaseConv->ToLower(lword,lword,word.Length());
ToLowerCase(lword,lword,word.Length());
if(word.Equals(lword)){
nsMemory::Free(lword);
return NoCap;
@ -298,10 +296,12 @@ NS_IMETHODIMP mozEnglishWordUtils::FromRootForm(const PRUnichar *aWord, const PR
case NoCap:
break;
case AllCap:
rv = mCaseConv->ToUpper(tmpPtr[i],tmpPtr[i],length);
ToUpperCase(tmpPtr[i],tmpPtr[i],length);
rv = NS_OK;
break;
case InitCap:
rv = mCaseConv->ToUpper(tmpPtr[i],tmpPtr[i],1);
ToUpperCase(tmpPtr[i],tmpPtr[i],1);
rv = NS_OK;
break;
default:
rv = NS_ERROR_FAILURE; // should never get here;

View File

@ -43,7 +43,6 @@
#include "nsIUnicodeEncoder.h"
#include "nsIUnicodeDecoder.h"
#include "nsString.h"
#include "nsICaseConversion.h"
#include "nsIUGenCategory.h"
#include "mozITXTToHTMLConv.h"
@ -69,7 +68,6 @@ protected:
nsString mLanguage;
nsString mCharset;
nsCOMPtr<nsICaseConversion> mCaseConv;
nsCOMPtr<nsIUGenCategory> mCategories;
nsCOMPtr<mozITXTToHTMLConv> mURLDetector; // used to detect urls so the spell checker can skip them.
};

View File

@ -59,7 +59,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsSemanticUnitScanner)
NS_DEFINE_NAMED_CID(NS_LBRK_CID);
NS_DEFINE_NAMED_CID(NS_WBRK_CID);
NS_DEFINE_NAMED_CID(NS_SEMANTICUNITSCANNER_CID);
NS_DEFINE_NAMED_CID(NS_UNICHARUTIL_CID);
NS_DEFINE_NAMED_CID(NS_UNICHARCATEGORY_CID);
NS_DEFINE_NAMED_CID(NS_ENTITYCONVERTER_CID);
NS_DEFINE_NAMED_CID(NS_SAVEASCHARSET_CID);
@ -95,7 +94,6 @@ static const mozilla::Module::CIDEntry kIntlCIDs[] = {
{ &kNS_LBRK_CID, false, NULL, nsJISx4051LineBreakerConstructor },
{ &kNS_WBRK_CID, false, NULL, nsSampleWordBreakerConstructor },
{ &kNS_SEMANTICUNITSCANNER_CID, false, NULL, nsSemanticUnitScannerConstructor },
{ &kNS_UNICHARUTIL_CID, false, NULL, nsCaseConversionImp2Constructor },
{ &kNS_UNICHARCATEGORY_CID, false, NULL, nsCategoryImpConstructor },
{ &kNS_ENTITYCONVERTER_CID, false, NULL, nsEntityConverterConstructor },
{ &kNS_SAVEASCHARSET_CID, false, NULL, nsSaveAsCharsetConstructor },
@ -133,7 +131,6 @@ static const mozilla::Module::ContractIDEntry kIntlContracts[] = {
{ NS_LBRK_CONTRACTID, &kNS_LBRK_CID },
{ NS_WBRK_CONTRACTID, &kNS_WBRK_CID },
{ NS_SEMANTICUNITSCANNER_CONTRACTID, &kNS_SEMANTICUNITSCANNER_CID },
{ NS_UNICHARUTIL_CONTRACTID, &kNS_UNICHARUTIL_CID },
{ NS_UNICHARCATEGORY_CONTRACTID, &kNS_UNICHARCATEGORY_CID },
{ NS_ENTITYCONVERTER_CONTRACTID, &kNS_ENTITYCONVERTER_CID },
{ NS_SAVEASCHARSET_CONTRACTID, &kNS_SAVEASCHARSET_CID },

View File

@ -41,7 +41,7 @@
#include "nsIComponentManager.h"
#include "nsCollation.h"
#include "nsCollationCID.h"
#include "nsUnicharUtilCIID.h"
#include "nsUnicharUtils.h"
#include "prmem.h"
#include "nsReadableUtils.h"
@ -74,9 +74,6 @@ nsresult nsCollationFactory::CreateCollation(nsILocale* locale, nsICollation** i
nsCollation::nsCollation()
{
MOZ_COUNT_CTOR(nsCollation);
nsresult res;
mCaseConversion = do_GetService(NS_UNICHARUTIL_CONTRACTID, &res);
NS_ASSERTION(NS_SUCCEEDED(res), "CreateInstance failed for kCaseConversionIID");
}
nsCollation::~nsCollation()
@ -86,27 +83,22 @@ nsCollation::~nsCollation()
nsresult nsCollation::NormalizeString(const nsAString& stringIn, nsAString& stringOut)
{
if (!mCaseConversion) {
stringOut = stringIn;
PRInt32 aLength = stringIn.Length();
if (aLength <= 64) {
PRUnichar conversionBuffer[64];
ToLowerCase(PromiseFlatString(stringIn).get(), conversionBuffer, aLength);
stringOut.Assign(conversionBuffer, aLength);
}
else {
PRInt32 aLength = stringIn.Length();
if (aLength <= 64) {
PRUnichar conversionBuffer[64];
mCaseConversion->ToLower(PromiseFlatString(stringIn).get(), conversionBuffer, aLength);
stringOut.Assign(conversionBuffer, aLength);
}
else {
PRUnichar* conversionBuffer;
conversionBuffer = new PRUnichar[aLength];
if (!conversionBuffer) {
return NS_ERROR_OUT_OF_MEMORY;
}
mCaseConversion->ToLower(PromiseFlatString(stringIn).get(), conversionBuffer, aLength);
stringOut.Assign(conversionBuffer, aLength);
delete [] conversionBuffer;
PRUnichar* conversionBuffer;
conversionBuffer = new PRUnichar[aLength];
if (!conversionBuffer) {
return NS_ERROR_OUT_OF_MEMORY;
}
ToLowerCase(PromiseFlatString(stringIn).get(), conversionBuffer, aLength);
stringOut.Assign(conversionBuffer, aLength);
delete [] conversionBuffer;
}
return NS_OK;
}

View File

@ -41,7 +41,6 @@
#include "nsICollation.h"
#include "nsICaseConversion.h"
#include "nsICharsetConverterManager.h"
#include "nsCOMPtr.h"
@ -75,7 +74,6 @@ public:
nsresult UnicodeToChar(const nsAString& aSrc, char** dst);
protected:
nsCOMPtr <nsICaseConversion> mCaseConversion;
nsCOMPtr <nsIUnicodeEncoder> mEncoder;
};

View File

@ -36,137 +36,8 @@
*
* ***** END LICENSE BLOCK ***** */
#include "pratom.h"
#include "nsUUDll.h"
#include "nsCaseConversionImp2.h"
#include "casetable.h"
// For gUpperToTitle
enum {
kUpperIdx =0,
kTitleIdx
};
// For gUpperToTitle
enum {
kLowIdx =0,
kSizeEveryIdx,
kDiffIdx
};
#define IS_ASCII(u) ( 0x0000 == ((u) & 0xFF80))
#define IS_ASCII_UPPER(u) ((0x0041 <= (u)) && ( (u) <= 0x005a))
#define IS_ASCII_LOWER(u) ((0x0061 <= (u)) && ( (u) <= 0x007a))
#define IS_ASCII_ALPHA(u) (IS_ASCII_UPPER(u) || IS_ASCII_LOWER(u))
#define IS_ASCII_SPACE(u) ( 0x0020 == (u) )
#define IS_NOCASE_CHAR(u) (0==(1&(gCaseBlocks[(u)>>13]>>(0x001F&((u)>>8)))))
// Size of Tables
#define CASE_MAP_CACHE_SIZE 0x40
#define CASE_MAP_CACHE_MASK 0x3F
nsCaseConversionImp2* gCaseConv = nsnull;
struct nsCompressedMap {
const PRUnichar *mTable;
PRUint32 mSize;
PRUint32 mCache[CASE_MAP_CACHE_SIZE];
PRUint32 mLastBase;
PRUnichar Map(PRUnichar aChar)
{
// no need to worry about thread safety since cached values are
// not objects but primitive data types which could be
// accessed in atomic operations. We need to access
// the whole 32 bit of cachedData at once in order to make it
// thread safe. Never access bits from mCache directly.
PRUint32 cachedData = mCache[aChar & CASE_MAP_CACHE_MASK];
if(aChar == ((cachedData >> 16) & 0x0000FFFF))
return (cachedData & 0x0000FFFF);
// try the last index first
// store into local variable so we can be thread safe
PRUint32 base = mLastBase;
PRUnichar res = 0;
if (( aChar <= ((mTable[base+kSizeEveryIdx] >> 8) +
mTable[base+kLowIdx])) &&
( mTable[base+kLowIdx] <= aChar ))
{
// Hit the last base
if(((mTable[base+kSizeEveryIdx] & 0x00FF) > 0) &&
(0 != ((aChar - mTable[base+kLowIdx]) %
(mTable[base+kSizeEveryIdx] & 0x00FF))))
{
res = aChar;
} else {
res = aChar + mTable[base+kDiffIdx];
}
} else {
res = this->Lookup(0, (mSize/2), mSize-1, aChar);
}
mCache[aChar & CASE_MAP_CACHE_MASK] =
(((aChar << 16) & 0xFFFF0000) | (0x0000FFFF & res));
return res;
}
PRUnichar Lookup(PRUint32 l,
PRUint32 m,
PRUint32 r,
PRUnichar aChar)
{
PRUint32 base = m*3;
if ( aChar > ((mTable[base+kSizeEveryIdx] >> 8) +
mTable[base+kLowIdx]))
{
if( l > m )
return aChar;
PRUint32 newm = (m+r+1)/2;
if(newm == m)
newm++;
return this->Lookup(m+1, newm , r, aChar);
} else if ( mTable[base+kLowIdx] > aChar ) {
if( r < m )
return aChar;
PRUint32 newm = (l+m-1)/2;
if(newm == m)
newm++;
return this->Lookup(l, newm, m-1, aChar);
} else {
if(((mTable[base+kSizeEveryIdx] & 0x00FF) > 0) &&
(0 != ((aChar - mTable[base+kLowIdx]) %
(mTable[base+kSizeEveryIdx] & 0x00FF))))
{
return aChar;
}
mLastBase = base; // cache the base
return aChar + mTable[base+kDiffIdx];
}
}
};
static nsCompressedMap gUpperMap = {
reinterpret_cast<const PRUnichar*>(&gToUpper[0]),
gToUpperItems
};
static nsCompressedMap gLowerMap = {
reinterpret_cast<const PRUnichar*>(&gToLower[0]),
gToLowerItems
};
nsCaseConversionImp2* nsCaseConversionImp2::GetInstance()
{
if (!gCaseConv)
gCaseConv = new nsCaseConversionImp2();
return gCaseConv;
}
#include "nsUnicharUtils.h"
NS_IMETHODIMP_(nsrefcnt) nsCaseConversionImp2::AddRef(void)
{
@ -180,166 +51,45 @@ NS_IMETHODIMP_(nsrefcnt) nsCaseConversionImp2::Release(void)
NS_IMPL_THREADSAFE_QUERY_INTERFACE1(nsCaseConversionImp2, nsICaseConversion)
nsresult nsCaseConversionImp2::ToUpper(
PRUnichar aChar, PRUnichar* aReturn
)
NS_IMETHODIMP nsCaseConversionImp2::ToUpper(PRUnichar aChar, PRUnichar* aReturn)
{
if( IS_ASCII(aChar)) // optimize for ASCII
{
if(IS_ASCII_LOWER(aChar))
*aReturn = aChar - 0x0020;
else
*aReturn = aChar;
}
else if( IS_NOCASE_CHAR(aChar)) // optimize for block which have no case
{
*aReturn = aChar;
}
else
{
*aReturn = gUpperMap.Map(aChar);
}
*aReturn = ToUpperCase(aChar);
return NS_OK;
}
// a non-virtual version of ToLower
static PRUnichar FastToLower(
PRUnichar aChar
)
NS_IMETHODIMP nsCaseConversionImp2::ToLower(PRUnichar aChar, PRUnichar* aReturn)
{
if( IS_ASCII(aChar)) // optimize for ASCII
{
if(IS_ASCII_UPPER(aChar))
return aChar + 0x0020;
else
return aChar;
}
else if( IS_NOCASE_CHAR(aChar)) // optimize for block which have no case
{
return aChar;
}
return gLowerMap.Map(aChar);
}
nsresult nsCaseConversionImp2::ToLower(
PRUnichar aChar, PRUnichar* aReturn
)
{
*aReturn = FastToLower(aChar);
*aReturn = ToLowerCase(aChar);
return NS_OK;
}
nsresult nsCaseConversionImp2::ToTitle(
PRUnichar aChar, PRUnichar* aReturn
)
NS_IMETHODIMP nsCaseConversionImp2::ToTitle(PRUnichar aChar, PRUnichar* aReturn)
{
if( IS_ASCII(aChar)) // optimize for ASCII
{
return this->ToUpper(aChar, aReturn);
}
else if( IS_NOCASE_CHAR(aChar)) // optimize for block which have no case
{
*aReturn = aChar;
}
else
{
// First check for uppercase characters whose titlecase mapping is
// different, like U+01F1 DZ: they must remain unchanged.
if( 0x01C0 == ( aChar & 0xFFC0)) // 0x01Cx - 0x01Fx
{
for(PRUint32 i = 0 ; i < gUpperToTitleItems; i++) {
if ( aChar == gUpperToTitle[(i*2)+kUpperIdx]) {
*aReturn = aChar;
return NS_OK;
}
}
}
PRUnichar upper = gUpperMap.Map(aChar);
if( 0x01C0 == ( upper & 0xFFC0)) // 0x01Cx - 0x01Fx
{
for(PRUint32 i = 0 ; i < gUpperToTitleItems; i++) {
if ( upper == gUpperToTitle[(i*2)+kUpperIdx]) {
*aReturn = gUpperToTitle[(i*2)+kTitleIdx];
return NS_OK;
}
}
}
*aReturn = upper;
}
*aReturn = ToTitleCase(aChar);
return NS_OK;
}
nsresult nsCaseConversionImp2::ToUpper(
const PRUnichar* anArray, PRUnichar* aReturn, PRUint32 aLen
)
NS_IMETHODIMP nsCaseConversionImp2::ToUpper(const PRUnichar* anArray,
PRUnichar* aReturn,
PRUint32 aLen)
{
PRUint32 i;
for(i=0;i<aLen;i++)
{
PRUnichar aChar = anArray[i];
if( IS_ASCII(aChar)) // optimize for ASCII
{
if(IS_ASCII_LOWER(aChar))
aReturn[i] = aChar - 0x0020;
else
aReturn[i] = aChar;
}
else if( IS_NOCASE_CHAR(aChar)) // optimize for block which have no case
{
aReturn[i] = aChar;
}
else
{
aReturn[i] = gUpperMap.Map(aChar);
}
}
ToUpperCase(anArray, aReturn, aLen);
return NS_OK;
}
nsresult nsCaseConversionImp2::ToLower(
const PRUnichar* anArray, PRUnichar* aReturn, PRUint32 aLen
)
NS_IMETHODIMP nsCaseConversionImp2::ToLower(const PRUnichar* anArray,
PRUnichar* aReturn,
PRUint32 aLen)
{
PRUint32 i;
for(i=0;i<aLen;i++)
aReturn[i] = FastToLower(anArray[i]);
ToLowerCase(anArray, aReturn, aLen);
return NS_OK;
}
// implementation moved from the old nsCRT routine
NS_IMETHODIMP
nsCaseConversionImp2::CaseInsensitiveCompare(const PRUnichar *aLeft,
const PRUnichar *aRight,
PRUint32 aCount, PRInt32* aResult)
{
if (!aLeft || !aRight)
return NS_ERROR_INVALID_POINTER;
// assume equality. We bail early if no equality
*aResult = 0;
if (aCount) {
do {
PRUnichar c1 = *aLeft++;
PRUnichar c2 = *aRight++;
if (c1 != c2) {
c1 = FastToLower(c1);
c2 = FastToLower(c2);
if (c1 != c2) {
if (c1 < c2) {
*aResult = -1;
return NS_OK;
}
*aResult = 1;
return NS_OK;
}
}
} while (--aCount != 0);
}
*aResult = ::CaseInsensitiveCompare(aLeft, aRight, aCount);
return NS_OK;
}

View File

@ -64,6 +64,4 @@ public:
NS_IMETHOD CaseInsensitiveCompare(const PRUnichar* aLeft, const PRUnichar* aRight, PRUint32 aLength, PRInt32 *aResult);
};
extern nsCaseConversionImp2* gCaseConv;
#endif

View File

@ -39,9 +39,9 @@
#define nsUcharUtilConstructors_h__
#include "nsUnicharUtilCIID.h"
#include "nsCaseConversionImp2.h"
#include "nsCategoryImp.h"
#include "nsICaseConversion.h"
#include "nsCaseConversionImp2.h"
#include "nsEntityConverter.h"
#include "nsSaveAsCharset.h"
#include "nsUUDll.h"
@ -76,9 +76,7 @@ CreateNew##_name(nsISupports* aOuter, REFNSIID aIID, void **aResult) \
return rv; \
}
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsCaseConversionImp2,
nsCaseConversionImp2::GetInstance)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsCaseConversionImp2)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsCategoryImp,
nsCategoryImp::GetInstance)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsEntityConverter)

View File

@ -74,6 +74,8 @@ FORCE_STATIC_LIB = 1
FORCE_USE_PIC = 1
USE_STATIC_LIBS = 1
LOCAL_INCLUDES += -I$(srcdir)/../src
include $(topsrcdir)/config/rules.mk
ifdef _MSC_VER

View File

@ -58,6 +58,7 @@ include $(srcdir)/../objs.mk
EXTRA_DEPS += $(srcdir)/../objs.mk
LOCAL_INCLUDES += -I$(srcdir)/.. \
-I$(srcdir)/../../src
CPPSRCS = $(INTL_UNICHARUTIL_UTIL_LCPPSRCS)

View File

@ -45,34 +45,133 @@
#include "nsICaseConversion.h"
#include "nsServiceManagerUtils.h"
#include "nsXPCOMStrings.h"
#include "casetable.h"
#include <ctype.h>
static nsICaseConversion* gCaseConv = nsnull;
// For gUpperToTitle
enum {
kUpperIdx =0,
kTitleIdx
};
nsICaseConversion*
NS_GetCaseConversion()
{
if (!gCaseConv) {
nsresult rv = CallGetService(NS_UNICHARUTIL_CONTRACTID, &gCaseConv);
if (NS_FAILED(rv)) {
NS_ERROR("Failed to get the case conversion service!");
gCaseConv = nsnull;
// For gUpperToTitle
enum {
kLowIdx =0,
kSizeEveryIdx,
kDiffIdx
};
#define IS_ASCII(u) ( 0x0000 == ((u) & 0xFF80))
#define IS_ASCII_UPPER(u) ((0x0041 <= (u)) && ( (u) <= 0x005a))
#define IS_ASCII_LOWER(u) ((0x0061 <= (u)) && ( (u) <= 0x007a))
#define IS_ASCII_ALPHA(u) (IS_ASCII_UPPER(u) || IS_ASCII_LOWER(u))
#define IS_ASCII_SPACE(u) ( 0x0020 == (u) )
#define IS_NOCASE_CHAR(u) (0==(1&(gCaseBlocks[(u)>>13]>>(0x001F&((u)>>8)))))
// Size of Tables
#define CASE_MAP_CACHE_SIZE 0x40
#define CASE_MAP_CACHE_MASK 0x3F
struct nsCompressedMap {
const PRUnichar *mTable;
PRUint32 mSize;
PRUint32 mCache[CASE_MAP_CACHE_SIZE];
PRUint32 mLastBase;
PRUnichar Map(PRUnichar aChar)
{
// no need to worry about thread safety since cached values are
// not objects but primitive data types which could be
// accessed in atomic operations. We need to access
// the whole 32 bit of cachedData at once in order to make it
// thread safe. Never access bits from mCache directly.
PRUint32 cachedData = mCache[aChar & CASE_MAP_CACHE_MASK];
if(aChar == ((cachedData >> 16) & 0x0000FFFF))
return (cachedData & 0x0000FFFF);
// try the last index first
// store into local variable so we can be thread safe
PRUint32 base = mLastBase;
PRUnichar res = 0;
if (( aChar <= ((mTable[base+kSizeEveryIdx] >> 8) +
mTable[base+kLowIdx])) &&
( mTable[base+kLowIdx] <= aChar ))
{
// Hit the last base
if(((mTable[base+kSizeEveryIdx] & 0x00FF) > 0) &&
(0 != ((aChar - mTable[base+kLowIdx]) %
(mTable[base+kSizeEveryIdx] & 0x00FF))))
{
res = aChar;
} else {
res = aChar + mTable[base+kDiffIdx];
}
} else {
res = this->Lookup(0, (mSize/2), mSize-1, aChar);
}
mCache[aChar & CASE_MAP_CACHE_MASK] =
(((aChar << 16) & 0xFFFF0000) | (0x0000FFFF & res));
return res;
}
PRUnichar Lookup(PRUint32 l,
PRUint32 m,
PRUint32 r,
PRUnichar aChar)
{
PRUint32 base = m*3;
if ( aChar > ((mTable[base+kSizeEveryIdx] >> 8) +
mTable[base+kLowIdx]))
{
if( l > m )
return aChar;
PRUint32 newm = (m+r+1)/2;
if(newm == m)
newm++;
return this->Lookup(m+1, newm , r, aChar);
} else if ( mTable[base+kLowIdx] > aChar ) {
if( r < m )
return aChar;
PRUint32 newm = (l+m-1)/2;
if(newm == m)
newm++;
return this->Lookup(l, newm, m-1, aChar);
} else {
if(((mTable[base+kSizeEveryIdx] & 0x00FF) > 0) &&
(0 != ((aChar - mTable[base+kLowIdx]) %
(mTable[base+kSizeEveryIdx] & 0x00FF))))
{
return aChar;
}
mLastBase = base; // cache the base
return aChar + mTable[base+kDiffIdx];
}
}
return gCaseConv;
}
};
static nsCompressedMap gUpperMap = {
reinterpret_cast<const PRUnichar*>(&gToUpper[0]),
gToUpperItems
};
static nsCompressedMap gLowerMap = {
reinterpret_cast<const PRUnichar*>(&gToLower[0]),
gToLowerItems
};
void
ToLowerCase(nsAString& aString)
{
nsICaseConversion* caseConv = NS_GetCaseConversion();
if (caseConv) {
PRUnichar *buf = aString.BeginWriting();
caseConv->ToLower(buf, buf, aString.Length());
}
else
NS_WARNING("No case converter: no conversion done");
PRUnichar *buf = aString.BeginWriting();
ToLowerCase(buf, buf, aString.Length());
}
void
@ -80,30 +179,18 @@ ToLowerCase(const nsAString& aSource,
nsAString& aDest)
{
const PRUnichar *in;
PRUint32 len = NS_StringGetData(aSource, &in);
PRUnichar *out;
PRUint32 len = NS_StringGetData(aSource, &in);
NS_StringGetMutableData(aDest, len, &out);
nsICaseConversion* caseConv = NS_GetCaseConversion();
if (out && caseConv)
caseConv->ToLower(in, out, len);
else {
NS_WARNING("No case converter: only copying");
aDest.Assign(aSource);
}
NS_ASSERTION(out, "Uh...");
ToLowerCase(in, out, len);
}
void
ToUpperCase(nsAString& aString)
{
nsICaseConversion* caseConv = NS_GetCaseConversion();
if (caseConv) {
PRUnichar *buf = aString.BeginWriting();
caseConv->ToUpper(buf, buf, aString.Length());
}
else
NS_WARNING("No case converter: no conversion done");
PRUnichar *buf = aString.BeginWriting();
ToUpperCase(buf, buf, aString.Length());
}
void
@ -111,18 +198,11 @@ ToUpperCase(const nsAString& aSource,
nsAString& aDest)
{
const PRUnichar *in;
PRUint32 len = NS_StringGetData(aSource, &in);
PRUnichar *out;
PRUint32 len = NS_StringGetData(aSource, &in);
NS_StringGetMutableData(aDest, len, &out);
nsICaseConversion* caseConv = NS_GetCaseConversion();
if (out && caseConv)
caseConv->ToUpper(in, out, len);
else {
NS_WARNING("No case converter: only copying");
aDest.Assign(aSource);
}
NS_ASSERTION(out, "Uh...");
ToUpperCase(in, out, len);
}
#ifdef MOZILLA_INTERNAL_API
@ -132,16 +212,7 @@ nsCaseInsensitiveStringComparator::operator()(const PRUnichar* lhs,
const PRUnichar* rhs,
PRUint32 aLength) const
{
PRInt32 result;
nsICaseConversion* caseConv = NS_GetCaseConversion();
if (caseConv)
caseConv->CaseInsensitiveCompare(lhs, rhs, aLength, &result);
else {
NS_WARNING("No case converter: using default");
nsDefaultStringComparator comparator;
result = comparator(lhs, rhs, aLength);
}
return result;
return CaseInsensitiveCompare(lhs, rhs, aLength);
}
PRInt32
@ -152,18 +223,8 @@ nsCaseInsensitiveStringComparator::operator()(PRUnichar lhs,
if (lhs == rhs)
return 0;
nsICaseConversion* caseConv = NS_GetCaseConversion();
if (caseConv) {
caseConv->ToLower(lhs, &lhs);
caseConv->ToLower(rhs, &rhs);
}
else {
if (lhs < 256)
lhs = tolower(char(lhs));
if (rhs < 256)
rhs = tolower(char(rhs));
NS_WARNING("No case converter: no conversion done");
}
lhs = ToLowerCase(lhs);
rhs = ToLowerCase(rhs);
if (lhs == rhs)
return 0;
@ -173,54 +234,109 @@ nsCaseInsensitiveStringComparator::operator()(PRUnichar lhs,
return 1;
}
#else // MOZILLA_INTERNAL_API
#endif // MOZILLA_INTERNAL_API
PRInt32
CaseInsensitiveCompare(const PRUnichar *a,
const PRUnichar *b,
PRUint32 len)
{
nsICaseConversion* caseConv = NS_GetCaseConversion();
if (!caseConv)
return NS_strcmp(a, b);
NS_ASSERTION(a && b, "Do not pass in invalid pointers!");
PRInt32 result;
caseConv->CaseInsensitiveCompare(a, b, len, &result);
return result;
if (len) {
do {
PRUnichar c1 = *a++;
PRUnichar c2 = *b++;
if (c1 != c2) {
c1 = ToLowerCase(c1);
c2 = ToLowerCase(c2);
if (c1 != c2) {
if (c1 < c2) {
return -1;
}
return 1;
}
}
} while (--len != 0);
}
return 0;
}
#endif // MOZILLA_INTERNAL_API
PRUnichar
ToLowerCase(PRUnichar aChar)
{
PRUnichar result;
nsICaseConversion* caseConv = NS_GetCaseConversion();
if (caseConv)
caseConv->ToLower(aChar, &result);
else {
NS_WARNING("No case converter: no conversion done");
if (aChar < 256)
result = tolower(char(aChar));
if (IS_ASCII(aChar)) {
if (IS_ASCII_UPPER(aChar))
return aChar + 0x0020;
else
result = aChar;
return aChar;
} else if (IS_NOCASE_CHAR(aChar)) {
return aChar;
}
return gLowerMap.Map(aChar);
}
void
ToLowerCase(const PRUnichar *aIn, PRUnichar *aOut, PRUint32 aLen)
{
for (PRUint32 i = 0; i < aLen; i++) {
aOut[i] = ToLowerCase(aIn[i]);
}
return result;
}
PRUnichar
ToUpperCase(PRUnichar aChar)
{
PRUnichar result;
nsICaseConversion* caseConv = NS_GetCaseConversion();
if (caseConv)
caseConv->ToUpper(aChar, &result);
else {
NS_WARNING("No case converter: no conversion done");
if (aChar < 256)
result = toupper(char(aChar));
if (IS_ASCII(aChar)) {
if (IS_ASCII_LOWER(aChar))
return aChar - 0x0020;
else
result = aChar;
return aChar;
} else if (IS_NOCASE_CHAR(aChar)) {
return aChar;
}
return result;
return gUpperMap.Map(aChar);
}
void
ToUpperCase(const PRUnichar *aIn, PRUnichar *aOut, PRUint32 aLen)
{
for (PRUint32 i = 0; i < aLen; i++) {
aOut[i] = ToUpperCase(aIn[i]);
}
}
PRUnichar
ToTitleCase(PRUnichar aChar)
{
if (IS_ASCII(aChar)) {
return ToUpperCase(aChar);
} else if (IS_NOCASE_CHAR(aChar)) {
return aChar;
}
// First check for uppercase characters whose titlecase mapping is
// different, like U+01F1 DZ: they must remain unchanged.
if (0x01C0 == (aChar & 0xFFC0)) {
for (PRUint32 i = 0; i < gUpperToTitleItems; i++) {
if (aChar == gUpperToTitle[(i*2)+kUpperIdx]) {
return aChar;
}
}
}
PRUnichar upper = gUpperMap.Map(aChar);
if (0x01C0 == ( upper & 0xFFC0)) {
for (PRUint32 i = 0 ; i < gUpperToTitleItems; i++) {
if (upper == gUpperToTitle[(i*2)+kUpperIdx]) {
return gUpperToTitle[(i*2)+kTitleIdx];
}
}
}
return upper;
}

View File

@ -56,8 +56,12 @@ void ToUpperCase(nsAString&);
void ToLowerCase(const nsAString& aSource, nsAString& aDest);
void ToUpperCase(const nsAString& aSource, nsAString& aDest);
PRUnichar ToUpperCase(PRUnichar);
PRUnichar ToLowerCase(PRUnichar);
PRUnichar ToUpperCase(PRUnichar);
PRUnichar ToTitleCase(PRUnichar);
void ToLowerCase(const PRUnichar*, PRUnichar*, PRUint32);
void ToUpperCase(const PRUnichar*, PRUnichar*, PRUint32);
inline PRBool IsUpperCase(PRUnichar c) {
return ToLowerCase(c) != c;
@ -72,11 +76,11 @@ inline PRBool IsLowerCase(PRUnichar c) {
class nsCaseInsensitiveStringComparator : public nsStringComparator
{
public:
virtual int operator() (const PRUnichar*,
const PRUnichar*,
PRUint32 aLength) const;
virtual int operator() (PRUnichar,
PRUnichar) const;
virtual PRInt32 operator() (const PRUnichar*,
const PRUnichar*,
PRUint32 aLength) const;
virtual PRInt32 operator() (PRUnichar,
PRUnichar) const;
};
class nsCaseInsensitiveStringArrayComparator
@ -107,11 +111,9 @@ CaseInsensitiveFindInReadable(const nsAString& aPattern,
nsCaseInsensitiveStringComparator());
}
#else // MOZILLA_INTERNAL_API
NS_HIDDEN_(PRInt32)
CaseInsensitiveCompare(const PRUnichar *a, const PRUnichar *b, PRUint32 len);
#endif // MOZILLA_INTERNAL_API
PRInt32
CaseInsensitiveCompare(const PRUnichar *a, const PRUnichar *b, PRUint32 len);
#endif /* nsUnicharUtils_h__ */

View File

@ -84,7 +84,6 @@
#include "nsTextFrameTextRunCache.h"
#include "nsExpirationTracker.h"
#include "nsTextFrame.h"
#include "nsICaseConversion.h"
#include "nsIUGenCategory.h"
#include "nsUnicharUtilCIID.h"
@ -6765,14 +6764,14 @@ static PRUnichar TransformChar(const nsStyleText* aStyle, gfxTextRun* aTextRun,
}
switch (aStyle->mTextTransform) {
case NS_STYLE_TEXT_TRANSFORM_LOWERCASE:
nsContentUtils::GetCaseConv()->ToLower(aChar, &aChar);
aChar = ToLowerCase(aChar);
break;
case NS_STYLE_TEXT_TRANSFORM_UPPERCASE:
nsContentUtils::GetCaseConv()->ToUpper(aChar, &aChar);
aChar = ToUpperCase(aChar);
break;
case NS_STYLE_TEXT_TRANSFORM_CAPITALIZE:
if (aTextRun->CanBreakLineBefore(aSkippedOffset)) {
nsContentUtils::GetCaseConv()->ToTitle(aChar, &aChar);
aChar = ToTitleCase(aChar);
}
break;
}

View File

@ -40,11 +40,11 @@
#include "nsTextFrameUtils.h"
#include "gfxSkipChars.h"
#include "nsICaseConversion.h"
#include "nsStyleConsts.h"
#include "nsStyleContext.h"
#include "gfxContext.h"
#include "nsContentUtils.h"
#include "nsUnicharUtils.h"
#define SZLIG 0x00DF
@ -234,10 +234,6 @@ void
nsFontVariantTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
gfxContext* aRefContext)
{
nsICaseConversion* converter = nsContentUtils::GetCaseConv();
if (!converter)
return;
gfxFontGroup* fontGroup = aTextRun->GetFontGroup();
gfxFontStyle fontStyle = *fontGroup->GetStyle();
fontStyle.size *= 0.8;
@ -279,7 +275,7 @@ nsFontVariantTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
if (styles[i]->GetStyleFont()->mFont.variant == NS_STYLE_FONT_VARIANT_SMALL_CAPS) {
PRUnichar ch = str[i];
PRUnichar ch2;
converter->ToUpper(ch, &ch2);
ch2 = ToUpperCase(ch);
isLowercase = ch != ch2 || ch == SZLIG;
} else {
// Don't transform the character! I.e., pretend that it's not lowercase
@ -332,10 +328,6 @@ void
nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
gfxContext* aRefContext)
{
nsICaseConversion* converter = nsContentUtils::GetCaseConv();
if (!converter)
return;
PRUint32 length = aTextRun->GetLength();
const PRUnichar* str = aTextRun->GetTextUnicode();
nsRefPtr<nsStyleContext>* styles = aTextRun->mStyles.Elements();
@ -360,7 +352,7 @@ nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
switch (style) {
case NS_STYLE_TEXT_TRANSFORM_LOWERCASE:
converter->ToLower(ch, &ch);
ch = ToLowerCase(ch);
break;
case NS_STYLE_TEXT_TRANSFORM_UPPERCASE:
if (ch == SZLIG) {
@ -368,7 +360,7 @@ nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
extraChar = PR_TRUE;
ch = 'S';
} else {
converter->ToUpper(ch, &ch);
ch = ToUpperCase(ch);
}
break;
case NS_STYLE_TEXT_TRANSFORM_CAPITALIZE:
@ -378,7 +370,7 @@ nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
extraChar = PR_TRUE;
ch = 'S';
} else {
converter->ToTitle(ch, &ch);
ch = ToTitleCase(ch);
}
}
break;

View File

@ -138,7 +138,8 @@ GARBAGE += \
dlldeps-javaxpcom.cpp \
$(NULL)
LOCAL_INCLUDES += -I$(topsrcdir)/intl/unicharutil/util
LOCAL_INCLUDES += -I$(topsrcdir)/intl/unicharutil/util \
-I$(topsrcdir)/intl/unicharutil/src
ifdef MOZ_RDF
EXTRA_DEPS += \