bug 324738: Remove some unnecessary complexity from the parser and hardcode DTDs. r=sicking sr=jst

git-svn-id: svn://10.0.0.236/trunk@188251 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
mrbkap%gmail.com
2006-01-26 19:07:41 +00:00
parent f35c210acb
commit 8b6ba84a47
18 changed files with 38 additions and 465 deletions

View File

@@ -85,97 +85,6 @@ static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
nsCOMArray<nsIUnicharStreamListener> *nsParser::sParserDataListeners;
class CDTDDeallocator: public nsDequeFunctor
{
public:
virtual void* operator()(void* anObject)
{
nsIDTD* aDTD = (nsIDTD*)anObject;
NS_RELEASE(aDTD);
return 0;
}
};
//-------------------------------------------------------------------
class CDTDFinder: public nsDequeFunctor
{
public:
CDTDFinder(nsIDTD* aDTD)
: mTargetDTD(aDTD)
{
}
virtual ~CDTDFinder()
{
}
virtual void* operator()(void* anObject)
{
nsIDTD* theDTD = (nsIDTD*)anObject;
if (theDTD->GetMostDerivedIID().Equals(mTargetDTD->GetMostDerivedIID())) {
return anObject;
}
return 0;
}
nsIDTD* mTargetDTD;
};
//-------------------------------------------------------------------
class CSharedParserObjects
{
public:
CSharedParserObjects()
: mDTDDeque(0),
mHasViewSourceDTD(PR_FALSE),
mHasXMLDTD(PR_FALSE)
{
}
~CSharedParserObjects()
{
CDTDDeallocator theDeallocator;
mDTDDeque.ForEach(theDeallocator); // Release all the DTDs
}
nsresult Init()
{
// Note: To cut down on startup time/overhead, we defer the construction
// of non-html DTD's.
nsIDTD* theDTD = nsnull;
nsresult rv = NS_NewNavHTMLDTD(&theDTD);
NS_ASSERTION(theDTD, "Failed to create DTD");
NS_ENSURE_SUCCESS(rv, rv);
mDTDDeque.Push(theDTD);
mHasViewSourceDTD = PR_FALSE;
mHasXMLDTD = PR_FALSE;
return NS_OK;
}
nsresult RegisterDTD(nsIDTD* aDTD)
{
NS_ENSURE_ARG_POINTER(aDTD);
nsCOMPtr<nsIDTD> dtd(aDTD);
CDTDFinder theFinder(dtd);
if (!mDTDDeque.FirstThat(theFinder)) {
nsIDTD* theDTD;
nsresult rv = dtd->CreateNewInstance(&theDTD);
NS_ENSURE_SUCCESS(rv, rv);
mDTDDeque.Push(theDTD);
}
return NS_OK;
}
nsDeque mDTDDeque;
PRBool mHasViewSourceDTD; //this allows us to defer construction of this object.
PRBool mHasXMLDTD; //also defer XML dtd construction
};
//-------------- Begin ParseContinue Event Definition ------------------------
/*
The parser can be explicitly interrupted by passing a return value of
@@ -261,35 +170,6 @@ struct nsParserContinueEvent : public PLEvent
//-------------- End ParseContinue Event Definition ------------------------
static CSharedParserObjects* gSharedParserObjects = nsnull;
//-------------------------------------------------------------------------
static nsresult
GetSharedObjects(CSharedParserObjects** aSharedParserObjects)
{
if (!gSharedParserObjects) {
gSharedParserObjects = new CSharedParserObjects();
NS_ENSURE_TRUE(gSharedParserObjects, NS_ERROR_OUT_OF_MEMORY);
nsresult rv = gSharedParserObjects->Init();
NS_ENSURE_SUCCESS(rv, rv);
}
*aSharedParserObjects = gSharedParserObjects;
return NS_OK;
}
static void
FreeSharedObjects()
{
if (gSharedParserObjects) {
delete gSharedParserObjects;
gSharedParserObjects = nsnull;
}
}
/**
* This gets called when the htmlparser module is initialized.
*/
@@ -350,8 +230,6 @@ nsParser::Init()
// static
void nsParser::Shutdown()
{
FreeSharedObjects();
delete sParserDataListeners;
sParserDataListeners = nsnull;
}
@@ -557,21 +435,6 @@ nsParser::GetContentSink()
return mSink;
}
/**
* Call this method when you want to
* register your dynamic DTD's with the parser.
*
* @param aDTD is the object to be registered.
*/
NS_IMETHODIMP
nsParser::RegisterDTD(nsIDTD* aDTD)
{
CSharedParserObjects* sharedObjects;
nsresult rv = GetSharedObjects(&sharedObjects);
NS_ENSURE_SUCCESS(rv, rv);
return sharedObjects->RegisterDTD(aDTD);
}
/**
* Retrieve parsemode from topmost parser context
*
@@ -1007,76 +870,32 @@ DetermineParseMode(const nsString& aBuffer, nsDTDMode& aParseMode,
}
static nsresult
FindSuitableDTD(CParserContext& aParserContext, PRBool* aReturn)
FindSuitableDTD(CParserContext& aParserContext)
{
*aReturn = PR_FALSE;
// Let's start by trying the defaultDTD, if one exists...
if (aParserContext.mDTD) {
eAutoDetectResult canParse = aParserContext.mDTD->CanParse(aParserContext);
if (canParse != eUnknownDetect && canParse != eInvalidDetect) {
*aReturn = PR_TRUE;
NS_ASSERTION(!aParserContext.mDTD, "Already found a DTD");
return NS_OK;
}
}
// We always find a DTD.
aParserContext.mAutoDetectStatus = ePrimaryDetect;
CSharedParserObjects* sharedObjects;
nsresult rv = GetSharedObjects(&sharedObjects);
NS_ENSURE_SUCCESS(rv, rv);
aParserContext.mAutoDetectStatus = eUnknownDetect;
PRInt32 theDTDIndex = 0;
nsIDTD* theBestDTD = 0;
nsIDTD* theDTD = 0;
PRBool thePrimaryFound = PR_FALSE;
while ((theDTDIndex <= sharedObjects->mDTDDeque.GetSize()) &&
(aParserContext.mAutoDetectStatus != ePrimaryDetect)){
theDTD = NS_STATIC_CAST(nsIDTD*, sharedObjects->mDTDDeque.ObjectAt(theDTDIndex++));
if (theDTD) {
// Store detect status in temp ( theResult ) to avoid bugs such as
// 36233, 36754, 36491, 36323. Basically, we should avoid calling DTD's
// WillBuildModel() multiple times, i.e., we shouldn't leave auto-detect-status
// unknown.
eAutoDetectResult theResult = theDTD->CanParse(aParserContext);
if (eValidDetect == theResult){
aParserContext.mAutoDetectStatus = eValidDetect;
theBestDTD = theDTD;
} else if (ePrimaryDetect == theResult) {
theBestDTD = theDTD;
thePrimaryFound = PR_TRUE;
aParserContext.mAutoDetectStatus = ePrimaryDetect;
}
}
if (theDTDIndex == sharedObjects->mDTDDeque.GetSize() && !thePrimaryFound) {
if (!sharedObjects->mHasXMLDTD) {
rv = NS_NewExpatDriver(&theDTD); // Do this to view XML files...
NS_ENSURE_SUCCESS(rv, rv);
sharedObjects->mDTDDeque.Push(theDTD);
sharedObjects->mHasXMLDTD = PR_TRUE;
}
#ifdef MOZ_VIEW_SOURCE
else if (!sharedObjects->mHasViewSourceDTD) {
rv = NS_NewViewSourceHTML(&theDTD);
NS_ENSURE_SUCCESS(rv, rv);
sharedObjects->mDTDDeque.Push(theDTD);
sharedObjects->mHasViewSourceDTD = PR_TRUE;
}
// Quick check for view source.
if (aParserContext.mParserCommand == eViewSource) {
aParserContext.mDTD = new CViewSourceHTML();
return aParserContext.mDTD ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
#endif
}
// Now see if we're parsing HTML (which, as far as we're concerned, simply
// means "not XML").
if (aParserContext.mDocType != eXML) {
aParserContext.mDTD = new CNavDTD();
return aParserContext.mDTD ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
if (theBestDTD) {
rv = theBestDTD->CreateNewInstance(getter_AddRefs(aParserContext.mDTD));
NS_ENSURE_SUCCESS(rv, rv);
*aReturn = PR_TRUE;
}
return rv;
// If we're here, then we'd better be parsing XML.
NS_ASSERTION(aParserContext.mDocType == eXML, "What are you trying to send me, here?");
aParserContext.mDTD = new nsExpatDriver();
return aParserContext.mDTD ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
NS_IMETHODIMP
@@ -1125,13 +944,9 @@ nsParser::WillBuildModel(nsString& aFilename)
mParserContext->mDocType, mParserContext->mMimeType);
}
PRBool found;
nsresult rv = FindSuitableDTD(*mParserContext, &found);
nsresult rv = FindSuitableDTD(*mParserContext);
NS_ENSURE_SUCCESS(rv, rv);
if (!found)
return rv;
nsITokenizer* tokenizer;
rv = mParserContext->GetTokenizer(mParserContext->mDTD->GetType(), mSink, tokenizer);
NS_ENSURE_SUCCESS(rv, rv);