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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user