mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
46702 ( nsbeta3+ ) Partial - Made token cache to be arena based.
r=vidur
This commit is contained in:
parent
f2714e75a8
commit
c387ac81a1
@ -152,8 +152,6 @@ CNavDTD::CNavDTD() : nsIDTD(),
|
||||
mHasOpenForm=PR_FALSE;
|
||||
mHasOpenMap=PR_FALSE;
|
||||
mHasOpenNoXXX=0;
|
||||
mHeadContext=new nsDTDContext();
|
||||
mBodyContext=new nsDTDContext();
|
||||
mFormContext=0;
|
||||
mMapContext=0;
|
||||
mTempContext=0;
|
||||
@ -166,6 +164,9 @@ CNavDTD::CNavDTD() : nsIDTD(),
|
||||
mRequestedHead=PR_FALSE;
|
||||
mIsFormContainer=PR_FALSE;
|
||||
|
||||
mHeadContext=new nsDTDContext();
|
||||
mBodyContext=new nsDTDContext();
|
||||
|
||||
if(!gHTMLElements) {
|
||||
InitializeElementTable();
|
||||
}
|
||||
@ -205,15 +206,12 @@ void CNavDTD::RecycleNodes(nsEntryStack *aNodeStack) {
|
||||
if(theNode) {
|
||||
|
||||
theNode->mUseCount=0;
|
||||
if(theNode->mToken) {
|
||||
theNode->mToken->mUseCount=0;
|
||||
mTokenRecycler->RecycleToken(theNode->mToken);
|
||||
}
|
||||
|
||||
IF_FREE(theNode->mToken);
|
||||
|
||||
CToken* theToken=0;
|
||||
while((theToken=(CToken*)theNode->PopAttributeToken())){
|
||||
theNode->mToken->mUseCount=0;
|
||||
mTokenRecycler->RecycleToken(theToken);
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
|
||||
mSharedNodes.Push(theNode);
|
||||
@ -413,7 +411,6 @@ nsresult CNavDTD::WillBuildModel( const CParserContext& aParserContext,nsIConte
|
||||
mBodyContext->ResetCounters();
|
||||
mDocType=aParserContext.mDocType;
|
||||
|
||||
mTokenRecycler=0;
|
||||
mStyleHandlingEnabled=PR_TRUE;
|
||||
|
||||
if(aSink && (!mSink)) {
|
||||
@ -456,9 +453,9 @@ nsresult CNavDTD::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsIToke
|
||||
mParser=(nsParser*)aParser;
|
||||
|
||||
if(mTokenizer) {
|
||||
|
||||
mTokenRecycler=(CTokenRecycler*)mTokenizer->GetTokenRecycler();
|
||||
|
||||
mTokenAllocator=mTokenizer->GetTokenAllocator();
|
||||
|
||||
result=mBodyContext->GetNodeRecycler(mNodeRecycler); // Get a copy...
|
||||
|
||||
if(NS_FAILED(result)) return result;
|
||||
@ -469,13 +466,13 @@ nsresult CNavDTD::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsIToke
|
||||
CStartToken* theToken=nsnull;
|
||||
if(ePlainText==mDocType) {
|
||||
//we do this little trick for text files, in both normal and viewsource mode...
|
||||
theToken=(CStartToken*)mTokenRecycler->CreateTokenOfType(eToken_start,eHTMLTag_pre);
|
||||
theToken=(CStartToken*)mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_pre);
|
||||
if(theToken) {
|
||||
mTokenizer->PushTokenFront(theToken);
|
||||
}
|
||||
}
|
||||
//if the content model is empty, then begin by opening <html>...
|
||||
theToken=(CStartToken*)mTokenRecycler->CreateTokenOfType(eToken_start,eHTMLTag_html,NS_ConvertToString("html"));
|
||||
theToken=(CStartToken*)mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_html,NS_ConvertToString("html"));
|
||||
if(theToken) {
|
||||
mTokenizer->PushTokenFront(theToken); //this token should get pushed on the context stack.
|
||||
}
|
||||
@ -528,7 +525,7 @@ nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParse
|
||||
|
||||
mSkipTarget=eHTMLTag_unknown; //clear this in case we were searching earlier.
|
||||
|
||||
CStartToken *theToken=(CStartToken*)mTokenRecycler->CreateTokenOfType(eToken_start,eHTMLTag_body,NS_ConvertToString("body"));
|
||||
CStartToken *theToken=(CStartToken*)mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_body,NS_ConvertToString("body"));
|
||||
mTokenizer->PushTokenFront(theToken); //this token should get pushed on the context stack, don't recycle it
|
||||
result=BuildModel(aParser,mTokenizer,0,aSink);
|
||||
}
|
||||
@ -538,13 +535,13 @@ nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParse
|
||||
if((NS_OK==anErrorCode) && (mBodyContext->GetCount()>0)) {
|
||||
if(mSkipTarget) {
|
||||
CHTMLToken* theEndToken=nsnull;
|
||||
theEndToken=(CHTMLToken*)mTokenRecycler->CreateTokenOfType(eToken_end,mSkipTarget);
|
||||
theEndToken=(CHTMLToken*)mTokenAllocator->CreateTokenOfType(eToken_end,mSkipTarget);
|
||||
if(theEndToken) {
|
||||
result=HandleToken(theEndToken,mParser);
|
||||
}
|
||||
}
|
||||
if(!mBodyContext->mHadDocTypeDecl) {
|
||||
CToken* theDocTypeToken=mTokenRecycler->CreateTokenOfType(eToken_doctypeDecl,eHTMLTag_markupDecl);
|
||||
CToken* theDocTypeToken=mTokenAllocator->CreateTokenOfType(eToken_doctypeDecl,eHTMLTag_markupDecl);
|
||||
if(theDocTypeToken) {
|
||||
nsAutoString theDocTypeStr;
|
||||
theDocTypeStr.AssignWithConversion("<!DOCTYPE \"-//W3C//DTD HTML 3.2 Final//EN\">");
|
||||
@ -574,7 +571,7 @@ nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParse
|
||||
nsEntryStack *theChildStyles=0;
|
||||
nsCParserNode* theNode=(nsCParserNode*)mBodyContext->Pop(theChildStyles);
|
||||
theNode->mUseCount=0;
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
mNodeRecycler->RecycleNode(theNode);
|
||||
if(theChildStyles) {
|
||||
delete theChildStyles;
|
||||
}
|
||||
@ -622,7 +619,7 @@ nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParse
|
||||
|
||||
CToken* theToken=0;
|
||||
while((theToken=(CToken*)mMisplacedContent.Pop())) {
|
||||
mTokenRecycler->RecycleToken(theToken);
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
|
||||
if(mDTDDebug) {
|
||||
@ -657,8 +654,6 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
||||
eHTMLTags theTag=(eHTMLTags)theToken->GetTypeID();
|
||||
PRBool execSkipContent=PR_FALSE;
|
||||
|
||||
theToken->mUseCount=0; //assume every token coming into this system needs recycling.
|
||||
|
||||
/* ---------------------------------------------------------------------------------
|
||||
To understand this little piece of code, you need to look below too.
|
||||
In essence, this code caches "skipped content" until we find a given skiptarget.
|
||||
@ -674,7 +669,7 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
||||
mSkipTarget=eHTMLTag_unknown; //stop skipping.
|
||||
//mTokenizer->PushTokenFront(aToken); //push the end token...
|
||||
execSkipContent=PR_TRUE;
|
||||
mTokenRecycler->RecycleToken(aToken);
|
||||
IF_FREE(aToken);
|
||||
theToken=(CHTMLToken*)mSkippedContent.PopFront();
|
||||
theType=eToken_start;
|
||||
}
|
||||
@ -721,9 +716,8 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
||||
//We're going to move it to the body by storing it temporarily on the misplaced stack.
|
||||
//However, in quirks mode, a few tags request, ambiguosly, for a BODY. - Bugs 18928, 24204.-
|
||||
mMisplacedContent.Push(aToken);
|
||||
aToken->mUseCount++;
|
||||
if(mDTDMode==eDTDMode_quirks && (gHTMLElements[theTag].HasSpecialProperty(kRequiresBody))) {
|
||||
CToken* theBodyToken=(CToken*)mTokenRecycler->CreateTokenOfType(eToken_start,eHTMLTag_body,NS_ConvertToString("body"));
|
||||
CToken* theBodyToken=(CToken*)mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_body,NS_ConvertToString("body"));
|
||||
result=HandleToken(theBodyToken,aParser);
|
||||
}
|
||||
return result;
|
||||
@ -794,22 +788,15 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
||||
|
||||
|
||||
if(NS_SUCCEEDED(result) || (NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
if(0>=theToken->mUseCount)
|
||||
mTokenRecycler->RecycleToken(theToken);
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
else if(result==NS_ERROR_HTMLPARSER_STOPPARSING)
|
||||
else if(result==NS_ERROR_HTMLPARSER_STOPPARSING) {
|
||||
mDTDState=result;
|
||||
else return NS_OK;
|
||||
}
|
||||
else {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
// CAUTION: Here we are forgetting to push the ATTRIBUTE Tokens.
|
||||
// So, before you uncomment this part please make sure
|
||||
// that the attribute tokens are also accounted for.
|
||||
|
||||
//else if(NS_ERROR_HTMLPARSER_MISPLACED!=result)
|
||||
// mTokenizer->PushTokenFront(theToken);
|
||||
//else result=NS_OK;
|
||||
/***************************************************************/
|
||||
#if 0
|
||||
if (mDTDDebug) {
|
||||
mDTDDebug->Verify(this, mParser, mBodyContext->GetCount(), mBodyContext->mStack, mFilename);
|
||||
@ -849,7 +836,7 @@ nsresult CNavDTD::DidHandleStartTag(nsCParserNode& aNode,eHTMLTags aChildTag){
|
||||
if(eToken_newline==theType){
|
||||
mLineNumber++;
|
||||
theNextToken=mTokenizer->PopToken(); //skip 1st newline inside PRE and LISTING
|
||||
if(theNextToken) mTokenRecycler->RecycleToken(theNextToken); // fix for Bug 29379
|
||||
IF_FREE(theNextToken); // fix for Bug 29379
|
||||
}//if
|
||||
}//if
|
||||
}
|
||||
@ -1176,7 +1163,7 @@ nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsCParserNode
|
||||
//(during editing) to display a special icon for unknown tags.
|
||||
|
||||
if(eHTMLTag_userdefined==aTag) {
|
||||
CAttributeToken* theToken= (CAttributeToken*)mTokenRecycler->CreateTokenOfType(eToken_attribute,aTag);
|
||||
CAttributeToken* theToken= (CAttributeToken*)mTokenAllocator->CreateTokenOfType(eToken_attribute,aTag);
|
||||
if(theToken) {
|
||||
theToken->mTextKey.AssignWithConversion("_moz-userdefined");
|
||||
aNode.AddAttribute(theToken);
|
||||
@ -1263,7 +1250,6 @@ static void PushMisplacedAttributes(nsIParserNode& aNode,nsDeque& aDeque,PRInt32
|
||||
theAttrToken=theAttrNode->PopAttributeToken();
|
||||
if(theAttrToken) {
|
||||
aDeque.Push(theAttrToken);
|
||||
theAttrToken->mUseCount=0;
|
||||
}
|
||||
aCount--;
|
||||
}//while
|
||||
@ -1319,7 +1305,6 @@ nsresult CNavDTD::HandleOmittedTag(CToken* aToken,eHTMLTags aChildTag,eHTMLTags
|
||||
static eHTMLTags gLegalElements[]={eHTMLTag_td,eHTMLTag_th};
|
||||
while(!done){
|
||||
mMisplacedContent.Push(theToken);
|
||||
theToken->mUseCount++;
|
||||
|
||||
// If the token is attributed then save those attributes too.
|
||||
if(attrCount > 0) PushMisplacedAttributes(*aNode,mMisplacedContent,attrCount);
|
||||
@ -1327,7 +1312,6 @@ nsresult CNavDTD::HandleOmittedTag(CToken* aToken,eHTMLTags aChildTag,eHTMLTags
|
||||
theToken=mTokenizer->PeekToken();
|
||||
|
||||
if(theToken) {
|
||||
theToken->mUseCount=0;
|
||||
theTag=(eHTMLTags)theToken->GetTypeID();
|
||||
if(!nsHTMLElement::IsWhitespaceTag(theTag) && theTag!=eHTMLTag_unknown) {
|
||||
if((gHTMLElements[theTag].mSkipTarget && theToken->GetTokenType() != eToken_end) ||
|
||||
@ -1350,7 +1334,6 @@ nsresult CNavDTD::HandleOmittedTag(CToken* aToken,eHTMLTags aChildTag,eHTMLTags
|
||||
|
||||
if((aChildTag!=aParent) && (gHTMLElements[aParent].HasSpecialProperty(kSaveMisplaced))) {
|
||||
mMisplacedContent.Push(aToken);
|
||||
aToken->mUseCount++;
|
||||
// If the token is attributed then save those attributes too.
|
||||
if(attrCount > 0) PushMisplacedAttributes(*aNode,mMisplacedContent,attrCount);
|
||||
}
|
||||
@ -1387,24 +1370,24 @@ nsresult CNavDTD::HandleKeyGen(nsIParserNode* aNode) {
|
||||
nsString* theTextValue=nsnull;
|
||||
PRInt32 theIndex=nsnull;
|
||||
|
||||
if(mTokenizer && mTokenRecycler) {
|
||||
if(mTokenizer && mTokenAllocator) {
|
||||
// Populate the tokenizer with the fabricated elements in the reverse order
|
||||
// such that <SELECT> is on the top fo the tokenizer followed by <OPTION>s
|
||||
// and </SELECT>
|
||||
theToken=mTokenRecycler->CreateTokenOfType(eToken_end,eHTMLTag_select);
|
||||
theToken=mTokenAllocator->CreateTokenOfType(eToken_end,eHTMLTag_select);
|
||||
mTokenizer->PushTokenFront(theToken);
|
||||
|
||||
for(theIndex=theContent.Count()-1;theIndex>-1;theIndex--) {
|
||||
theTextValue=(nsString*)theContent[theIndex];
|
||||
theToken=mTokenRecycler->CreateTokenOfType(eToken_text,eHTMLTag_text,*theTextValue);
|
||||
theToken=mTokenAllocator->CreateTokenOfType(eToken_text,eHTMLTag_text,*theTextValue);
|
||||
mTokenizer->PushTokenFront(theToken);
|
||||
theToken=mTokenRecycler->CreateTokenOfType(eToken_start,eHTMLTag_option);
|
||||
theToken=mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_option);
|
||||
mTokenizer->PushTokenFront(theToken);
|
||||
}
|
||||
|
||||
// The attribute ( provided by the form processor ) should be a part of the SELECT.
|
||||
// Placing the attribute token on the tokenizer to get picked up by the SELECT.
|
||||
theToken=mTokenRecycler->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown,theAttribute);
|
||||
theToken=mTokenAllocator->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown,theAttribute);
|
||||
|
||||
nsString& theKey=((CAttributeToken*)theToken)->GetKey();
|
||||
theKey.AssignWithConversion("_moz-type");
|
||||
@ -1417,11 +1400,11 @@ nsresult CNavDTD::HandleKeyGen(nsIParserNode* aNode) {
|
||||
mTokenizer->PushTokenFront(((nsCParserNode*)aNode)->PopAttributeToken());
|
||||
}
|
||||
|
||||
theToken=mTokenRecycler->CreateTokenOfType(eToken_start,eHTMLTag_select);
|
||||
theToken=mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_select);
|
||||
// Increament the count because of the additional attribute from the form processor.
|
||||
theToken->SetAttributeCount(theAttrCount+1);
|
||||
mTokenizer->PushTokenFront(theToken);
|
||||
}//if(mTokenizer && mTokenRecycler)
|
||||
}//if(mTokenizer && mTokenAllocator)
|
||||
}//if(NS_SUCCEEDED(result))
|
||||
}// if(NS_SUCCEEDED(result))
|
||||
} //if(aNode)
|
||||
@ -1453,7 +1436,7 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
|
||||
//Begin by gathering up attributes...
|
||||
|
||||
nsCParserNode* theNode=mNodeRecycler->CreateNode();
|
||||
theNode->Init(aToken,mLineNumber,mTokenRecycler);
|
||||
theNode->Init(aToken,mLineNumber,mTokenAllocator);
|
||||
|
||||
eHTMLTags theChildTag=(eHTMLTags)aToken->GetTypeID();
|
||||
PRInt16 attrCount=aToken->GetAttributeCount();
|
||||
@ -1568,7 +1551,7 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
|
||||
}//if
|
||||
} //if
|
||||
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
mNodeRecycler->RecycleNode(theNode);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1680,16 +1663,17 @@ eHTMLTags FindAutoCloseTargetForEndTag(eHTMLTags aCurrentTag,nsDTDContext& aCont
|
||||
* @update gess 10/11/99
|
||||
* @return nada
|
||||
*/
|
||||
static void StripWSFollowingTag(eHTMLTags aChildTag,nsITokenizer* aTokenizer,nsITokenRecycler* aRecycler, PRInt32& aNewlineCount){
|
||||
static void StripWSFollowingTag(eHTMLTags aChildTag,nsITokenizer* aTokenizer,nsTokenAllocator* aTokenAllocator, PRInt32& aNewlineCount){
|
||||
CToken* theToken= (aTokenizer)? aTokenizer->PeekToken():nsnull;
|
||||
|
||||
if(aRecycler) {
|
||||
if(aTokenAllocator) {
|
||||
while(theToken) {
|
||||
eHTMLTokenTypes theType=eHTMLTokenTypes(theToken->GetTokenType());
|
||||
switch(theType) {
|
||||
case eToken_newline: aNewlineCount++;
|
||||
case eToken_whitespace:
|
||||
aRecycler->RecycleToken(aTokenizer->PopToken());
|
||||
theToken=aTokenizer->PopToken();
|
||||
IF_FREE(theToken);
|
||||
theToken=aTokenizer->PeekToken();
|
||||
break;
|
||||
default:
|
||||
@ -1735,7 +1719,7 @@ nsresult CNavDTD::HandleEndToken(CToken* aToken) {
|
||||
break;
|
||||
|
||||
case eHTMLTag_head:
|
||||
StripWSFollowingTag(theChildTag,mTokenizer,mTokenRecycler,mLineNumber);
|
||||
StripWSFollowingTag(theChildTag,mTokenizer,mTokenAllocator,mLineNumber);
|
||||
mRequestedHead=PR_FALSE;
|
||||
//ok to fall through...
|
||||
|
||||
@ -1753,7 +1737,7 @@ nsresult CNavDTD::HandleEndToken(CToken* aToken) {
|
||||
//to use </BR>, even though that isn't a legitimate tag.
|
||||
if(eDTDMode_quirks==mDTDMode) {
|
||||
// Use recycler and pass the token thro' HandleToken() to fix bugs like 32782.
|
||||
CHTMLToken* theToken = (CHTMLToken*)mTokenRecycler->CreateTokenOfType(eToken_start,theChildTag);
|
||||
CHTMLToken* theToken = (CHTMLToken*)mTokenAllocator->CreateTokenOfType(eToken_start,theChildTag);
|
||||
result=HandleToken(theToken,mParser);
|
||||
}
|
||||
}
|
||||
@ -1761,7 +1745,7 @@ nsresult CNavDTD::HandleEndToken(CToken* aToken) {
|
||||
|
||||
case eHTMLTag_body:
|
||||
case eHTMLTag_html:
|
||||
StripWSFollowingTag(theChildTag,mTokenizer,mTokenRecycler,mLineNumber);
|
||||
StripWSFollowingTag(theChildTag,mTokenizer,mTokenAllocator,mLineNumber);
|
||||
break;
|
||||
|
||||
case eHTMLTag_noframes:
|
||||
@ -1802,8 +1786,9 @@ nsresult CNavDTD::HandleEndToken(CToken* aToken) {
|
||||
// Ex. <html><body>Hello</P>There</body></html>
|
||||
PRBool theParentContains=-1; //set to -1 to force canomit to recompute.
|
||||
if(!CanOmit(theParentTag,theChildTag,theParentContains)) {
|
||||
IF_HOLD(aToken);
|
||||
mTokenizer->PushTokenFront(aToken); //put this end token back...
|
||||
CHTMLToken* theToken = (CHTMLToken*)mTokenRecycler->CreateTokenOfType(eToken_start,theChildTag);
|
||||
CHTMLToken* theToken = (CHTMLToken*)mTokenAllocator->CreateTokenOfType(eToken_start,theChildTag);
|
||||
mTokenizer->PushTokenFront(theToken); //put this new token onto stack...
|
||||
}
|
||||
}
|
||||
@ -1895,7 +1880,7 @@ nsresult CNavDTD::HandleSavedTokens(PRInt32 anIndex) {
|
||||
|
||||
if(!(theIndex!=kNotFound && theIndex<=mBodyContext->mContextTopIndex))
|
||||
result=HandleToken(theToken,mParser);
|
||||
else mTokenRecycler->RecycleToken(theToken);
|
||||
else IF_FREE(theToken);
|
||||
}
|
||||
theBadTokenCount--;
|
||||
}//while
|
||||
@ -1942,16 +1927,14 @@ nsresult CNavDTD::HandleEntityToken(CToken* aToken) {
|
||||
CNamedEntity *theEntity=mBodyContext->GetEntity(theStr);
|
||||
CToken *theToken=0;
|
||||
if(theEntity) {
|
||||
theToken=new CTextToken(theEntity->mValue);
|
||||
theToken=(CTextToken*)mTokenAllocator->CreateTokenOfType(eToken_text,eHTMLTag_text,theEntity->mValue);
|
||||
}
|
||||
else {
|
||||
//if you're here we have a bogus entity.
|
||||
//convert it into a text token.
|
||||
nsAutoString temp; temp.AssignWithConversion("&");
|
||||
temp.Append(theStr);
|
||||
theToken=new CTextToken(temp);
|
||||
theToken=(CTextToken*)mTokenAllocator->CreateTokenOfType(eToken_text,eHTMLTag_text,NS_ConvertToString("&"));
|
||||
}
|
||||
return HandleStartToken(theToken);
|
||||
return HandleToken(theToken,mParser);
|
||||
}
|
||||
|
||||
eHTMLTags theParentTag=mBodyContext->Last();
|
||||
@ -1971,7 +1954,7 @@ nsresult CNavDTD::HandleEntityToken(CToken* aToken) {
|
||||
#endif
|
||||
|
||||
result=AddLeaf(theNode);
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
mNodeRecycler->RecycleNode(theNode);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -2007,7 +1990,7 @@ nsresult CNavDTD::HandleCommentToken(CToken* aToken) {
|
||||
|
||||
result=(mSink) ? mSink->AddComment(*theNode) : NS_OK;
|
||||
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
mNodeRecycler->RecycleNode(theNode);
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleCommentToken(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
@ -2084,7 +2067,7 @@ nsresult CNavDTD::HandleProcessingInstructionToken(CToken* aToken){
|
||||
|
||||
result=(mSink) ? mSink->AddProcessingInstruction(*theNode) : NS_OK;
|
||||
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
mNodeRecycler->RecycleNode(theNode);
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleProcessingInstructionToken(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
@ -2148,7 +2131,7 @@ nsresult CNavDTD::HandleDocTypeDeclToken(CToken* aToken){
|
||||
|
||||
result = (mSink)? mSink->AddDocTypeDecl(*theNode,theMode):NS_OK;
|
||||
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
mNodeRecycler->RecycleNode(theNode);
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleDocTypeDeclToken(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
@ -2238,15 +2221,17 @@ nsresult CNavDTD::CollectSkippedContent(nsCParserNode& aNode,PRInt32 &aCount) {
|
||||
// since this is an entity, we know that it's only one character.
|
||||
// check to see if it's a CR, in which case we'll need to do line
|
||||
// termination conversion at the end.
|
||||
aMustConvertLinebreaks |= (mScratch[0] == kCR);
|
||||
aNode.mSkippedContent->Append(mScratch);
|
||||
if(mScratch.Length()>0){
|
||||
aMustConvertLinebreaks |= (mScratch[0] == kCR);
|
||||
aNode.mSkippedContent->Append(mScratch);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
theNextToken->AppendSource(*aNode.mSkippedContent);
|
||||
}
|
||||
}
|
||||
mTokenRecycler->RecycleToken(theNextToken);
|
||||
IF_FREE(theNextToken);
|
||||
}
|
||||
|
||||
// if the string contained CRs (hence is either CR, or CRLF terminated)
|
||||
@ -2695,7 +2680,7 @@ nsresult CNavDTD::OpenTransientStyles(eHTMLTags aChildTag){
|
||||
//if the node tag can't contain the child tag, then remove the child tag from the style stack
|
||||
nsCParserNode* theRemovedNode=(nsCParserNode*)theStack->Remove(sindex,theNodeTag);
|
||||
if(theRemovedNode) {
|
||||
mNodeRecycler->RecycleNode(theRemovedNode,mTokenRecycler);
|
||||
mNodeRecycler->RecycleNode(theRemovedNode);
|
||||
}
|
||||
theEntry--; //back up by one
|
||||
}
|
||||
@ -2765,7 +2750,7 @@ nsresult CNavDTD::PopStyle(eHTMLTags aTag){
|
||||
if(nsHTMLElement::IsResidualStyleTag(aTag)) {
|
||||
nsCParserNode* theNode=(nsCParserNode*)mBodyContext->PopStyle(aTag);
|
||||
if(theNode) {
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
mNodeRecycler->RecycleNode(theNode);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -3296,7 +3281,8 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
|
||||
|
||||
if((anIndex<mBodyContext->GetCount()) && (anIndex>=0)) {
|
||||
|
||||
while(mBodyContext->GetCount()>anIndex) {
|
||||
PRInt32 count=0;
|
||||
while((count=mBodyContext->GetCount())>anIndex) {
|
||||
|
||||
nsEntryStack *theChildStyleStack=0;
|
||||
eHTMLTags theTag=mBodyContext->Last();
|
||||
@ -3438,7 +3424,7 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
|
||||
}
|
||||
#endif
|
||||
}//if anode
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
mNodeRecycler->RecycleNode(theNode);
|
||||
}
|
||||
|
||||
} //if
|
||||
@ -3517,65 +3503,63 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode *aNode){
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
PRBool done=PR_FALSE;
|
||||
eHTMLTags thePrevTag=theTag;
|
||||
nsCParserNode theNode;
|
||||
//nsCParserNode theNode;
|
||||
|
||||
while(!done && NS_SUCCEEDED(result)) {
|
||||
CToken* theToken=mTokenizer->PeekToken();
|
||||
if(theToken) {
|
||||
theTag=(eHTMLTags)theToken->GetTypeID();
|
||||
switch(theTag) {
|
||||
case eHTMLTag_newline:
|
||||
mLineNumber++;
|
||||
case eHTMLTag_whitespace:
|
||||
{
|
||||
theToken=mTokenizer->PopToken();
|
||||
theNode.Init(theToken,mLineNumber,0);
|
||||
nsCParserNode* theNode=mNodeRecycler->CreateNode();
|
||||
if(theNode) {
|
||||
theTag=(eHTMLTags)theToken->GetTypeID();
|
||||
switch(theTag) {
|
||||
case eHTMLTag_newline:
|
||||
mLineNumber++;
|
||||
case eHTMLTag_whitespace:
|
||||
{
|
||||
theToken=mTokenizer->PopToken();
|
||||
theNode->Init(theToken,mLineNumber,0);
|
||||
|
||||
STOP_TIMER();
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
|
||||
STOP_TIMER();
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
|
||||
|
||||
result=mSink->AddLeaf(theNode);
|
||||
result=mSink->AddLeaf(*theNode);
|
||||
|
||||
if((NS_SUCCEEDED(result))||(NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
if(mTokenRecycler) {
|
||||
mTokenRecycler->RecycleToken(theToken);
|
||||
if((NS_SUCCEEDED(result))||(NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
else delete theToken;
|
||||
}
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
thePrevTag=theTag;
|
||||
}
|
||||
break;
|
||||
case eHTMLTag_text:
|
||||
if((mHasOpenBody) && (!mHasOpenHead) &&
|
||||
!(nsHTMLElement::IsWhitespaceTag(thePrevTag))) {
|
||||
theToken=mTokenizer->PopToken();
|
||||
theNode.Init(theToken,mLineNumber);
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
|
||||
STOP_TIMER();
|
||||
|
||||
mLineNumber += theToken->mNewlineCount;
|
||||
result=mSink->AddLeaf(theNode);
|
||||
|
||||
if((NS_SUCCEEDED(result))||(NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
if(mTokenRecycler) {
|
||||
mTokenRecycler->RecycleToken(theToken);
|
||||
}
|
||||
else delete theToken;
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
thePrevTag=theTag;
|
||||
}
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
}
|
||||
else done=PR_TRUE;
|
||||
break;
|
||||
break;
|
||||
case eHTMLTag_text:
|
||||
if((mHasOpenBody) && (!mHasOpenHead) &&
|
||||
!(nsHTMLElement::IsWhitespaceTag(thePrevTag))) {
|
||||
theToken=mTokenizer->PopToken();
|
||||
theNode->Init(theToken,mLineNumber);
|
||||
|
||||
default:
|
||||
done=PR_TRUE;
|
||||
} //switch
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
|
||||
STOP_TIMER();
|
||||
|
||||
mLineNumber += theToken->mNewlineCount;
|
||||
result=mSink->AddLeaf(*theNode);
|
||||
|
||||
if((NS_SUCCEEDED(result))||(NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
}
|
||||
else done=PR_TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
done=PR_TRUE;
|
||||
} //switch
|
||||
mNodeRecycler->RecycleNode(theNode);
|
||||
} //if
|
||||
}//if
|
||||
else done=PR_TRUE;
|
||||
} //while
|
||||
@ -3702,8 +3686,8 @@ nsresult CNavDTD::CreateContextStackFor(eHTMLTags aChildTag){
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
CStartToken *theToken=(CStartToken*)mTokenRecycler->CreateTokenOfType(eToken_start,theTag);
|
||||
HandleStartToken(theToken); //these should all wind up on contextstack, so don't recycle.
|
||||
CStartToken *theToken=(CStartToken*)mTokenAllocator->CreateTokenOfType(eToken_start,theTag);
|
||||
HandleToken(theToken,mParser); //these should all wind up on contextstack, so don't recycle.
|
||||
}
|
||||
result=NS_OK;
|
||||
}
|
||||
@ -3732,14 +3716,14 @@ nsresult CNavDTD::GetTokenizer(nsITokenizer*& aTokenizer) {
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsITokenRecycler* CNavDTD::GetTokenRecycler(void){
|
||||
if(!mTokenRecycler) {
|
||||
nsTokenAllocator* CNavDTD::GetTokenAllocator(void){
|
||||
if(!mTokenAllocator) {
|
||||
nsresult result=GetTokenizer(mTokenizer);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
mTokenRecycler=(CTokenRecycler*)mTokenizer->GetTokenRecycler();
|
||||
mTokenAllocator=mTokenizer->GetTokenAllocator();
|
||||
}
|
||||
}
|
||||
return mTokenRecycler;
|
||||
return mTokenAllocator;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -105,7 +105,7 @@ class nsDTDContext;
|
||||
class nsEntryStack;
|
||||
class nsITokenizer;
|
||||
class nsCParserNode;
|
||||
class CTokenRecycler;
|
||||
class nsTokenAllocator;
|
||||
class CNodeRecycler;
|
||||
|
||||
/***************************************************************
|
||||
@ -232,7 +232,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
virtual nsITokenRecycler* GetTokenRecycler(void);
|
||||
virtual nsTokenAllocator* GetTokenAllocator(void);
|
||||
|
||||
/**
|
||||
* If the parse process gets interrupted, this method gets called
|
||||
@ -511,7 +511,7 @@ protected:
|
||||
PRInt32 mLineNumber;
|
||||
nsParser* mParser;
|
||||
nsITokenizer* mTokenizer;
|
||||
CTokenRecycler* mTokenRecycler;
|
||||
nsTokenAllocator* mTokenAllocator;
|
||||
CNodeRecycler* mNodeRecycler;
|
||||
nsDeque mMisplacedContent;
|
||||
nsDeque mSkippedContent;
|
||||
|
@ -139,8 +139,8 @@ COtherDTD::COtherDTD() : nsIDTD(), mSharedNodes(0) {
|
||||
mHasOpenHead=0;
|
||||
mHasOpenForm=PR_FALSE;
|
||||
mHasOpenMap=PR_FALSE;
|
||||
mBodyContext=new nsDTDContext();
|
||||
mTokenizer=0;
|
||||
mTokenAllocator=0;
|
||||
mComputedCRC32=0;
|
||||
mExpectedCRC32=0;
|
||||
mDTDState=NS_OK;
|
||||
@ -149,6 +149,7 @@ COtherDTD::COtherDTD() : nsIDTD(), mSharedNodes(0) {
|
||||
mHadBody=PR_FALSE;
|
||||
mHasOpenScript=PR_FALSE;
|
||||
mParserCommand=eViewNormal;
|
||||
mBodyContext=new nsDTDContext();
|
||||
|
||||
#if 1 //set this to 1 if you want strictDTD to be based on the environment setting.
|
||||
char* theEnvString = PR_GetEnv("MOZ_DISABLE_STRICT");
|
||||
@ -416,7 +417,6 @@ nsresult COtherDTD::WillBuildModel( const CParserContext& aParserContext,nsICon
|
||||
|
||||
mDocType=aParserContext.mDocType;
|
||||
mBodyContext->mTransitional=PRBool(aParserContext.mDTDMode==eDTDMode_transitional);
|
||||
mBodyContext->GetTokenRecycler();
|
||||
|
||||
if(aSink && (!mSink)) {
|
||||
result=aSink->QueryInterface(kIHTMLContentSinkIID, (void **)&mSink);
|
||||
@ -459,11 +459,15 @@ nsresult COtherDTD::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsITo
|
||||
|
||||
if(mTokenizer) {
|
||||
|
||||
mTokenAllocator=mTokenizer->GetTokenAllocator();
|
||||
|
||||
mBodyContext->SetTokenAllocator(mTokenAllocator);
|
||||
|
||||
if(mSink) {
|
||||
|
||||
if(!mBodyContext->GetCount()) {
|
||||
//if the content model is empty, then begin by opening <html>...
|
||||
CStartToken *theToken=(CStartToken*)mBodyContext->gTokenRecycler->CreateTokenOfType(eToken_start,eHTMLTag_html,NS_ConvertToString("html"));
|
||||
CStartToken *theToken=(CStartToken*)mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_html,NS_ConvertToString("html"));
|
||||
HandleStartToken(theToken); //this token should get pushed on the context stack, don't recycle it.
|
||||
}
|
||||
|
||||
@ -567,7 +571,7 @@ nsresult COtherDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
||||
CHTMLToken* theToken= (CHTMLToken*)(aToken);
|
||||
eHTMLTokenTypes theType=eHTMLTokenTypes(theToken->GetTokenType());
|
||||
|
||||
theToken->mUseCount=0; //assume every token coming into this system needs recycling.
|
||||
// theToken->mUseCount=0; //assume every token coming into this system needs recycling.
|
||||
|
||||
mParser=(nsParser*)aParser;
|
||||
|
||||
@ -591,8 +595,7 @@ nsresult COtherDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
||||
|
||||
|
||||
if(NS_SUCCEEDED(result) || (NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
if(0>=theToken->mUseCount)
|
||||
mBodyContext->gTokenRecycler->RecycleToken(theToken);
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
else if(result==NS_ERROR_HTMLPARSER_STOPPARSING)
|
||||
mDTDState=result;
|
||||
@ -749,7 +752,7 @@ nsresult COtherDTD::HandleStartToken(CToken* aToken) {
|
||||
nsresult result=NS_OK;
|
||||
nsCParserNode* theNode=CreateNode();
|
||||
if(theNode) {
|
||||
theNode->Init(aToken,mLineNumber,mBodyContext->gTokenRecycler);
|
||||
theNode->Init(aToken,mLineNumber,mTokenAllocator);
|
||||
|
||||
eHTMLTags theChildTag=(eHTMLTags)aToken->GetTypeID();
|
||||
PRInt16 attrCount=aToken->GetAttributeCount();
|
||||
@ -835,8 +838,12 @@ nsresult COtherDTD::HandleEndToken(CToken* aToken) {
|
||||
}
|
||||
CElement* theElement=gElementTable->mElements[theParent];
|
||||
if(theElement) {
|
||||
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber);
|
||||
result=theElement->HandleEndToken(&theNode,theChildTag,mBodyContext,mSink);
|
||||
nsCParserNode* theNode=CreateNode();
|
||||
if(theNode) {
|
||||
theNode->Init(aToken,mLineNumber,mTokenAllocator);
|
||||
result=theElement->HandleEndToken(theNode,theChildTag,mBodyContext,mSink);
|
||||
mBodyContext->RecycleNode((nsCParserNode*)theNode);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -904,14 +911,13 @@ nsresult COtherDTD::HandleEntityToken(CToken* aToken) {
|
||||
//before we just toss this away as a bogus entity, let's check...
|
||||
CNamedEntity *theEntity=mBodyContext->GetEntity(theStr);
|
||||
if(theEntity) {
|
||||
theToken=new CTextToken(theEntity->mValue);
|
||||
theToken=(CTextToken*)mTokenAllocator->CreateTokenOfType(eToken_text,eHTMLTag_text,theEntity->mValue);
|
||||
}
|
||||
else {
|
||||
//if you're here we have a bogus entity.
|
||||
//convert it into a text token.
|
||||
nsAutoString temp; temp.AssignWithConversion("&");
|
||||
temp.Append(theStr);
|
||||
theToken=new CTextToken(temp);
|
||||
theToken=(CTextToken*)mTokenAllocator->CreateTokenOfType(eToken_text,eHTMLTag_text,NS_ConvertToString("&"));
|
||||
|
||||
}
|
||||
result=HandleStartToken(theToken);
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ class nsDTDContext;
|
||||
class nsEntryStack;
|
||||
class nsITokenizer;
|
||||
class nsCParserNode;
|
||||
class CTokenRecycler;
|
||||
class nsTokenAllocator;
|
||||
|
||||
/***************************************************************
|
||||
Now the main event: COtherDTD.
|
||||
@ -231,7 +231,7 @@ CLASS_EXPORT_HTMLPARS COtherDTD : public nsIDTD {
|
||||
* @update rickg 16June2000
|
||||
* @return always 0
|
||||
*/
|
||||
virtual nsITokenRecycler* GetTokenRecycler(void) {return 0;}
|
||||
virtual nsTokenAllocator* GetTokenAllocator(void) {return 0;}
|
||||
|
||||
/**
|
||||
* If the parse process gets interrupted, this method gets called
|
||||
@ -334,6 +334,7 @@ protected:
|
||||
PRInt32 mLineNumber;
|
||||
nsParser* mParser;
|
||||
nsITokenizer* mTokenizer;
|
||||
nsTokenAllocator* mTokenAllocator;
|
||||
PRBool mHasOpenScript;
|
||||
eHTMLTags mSkipTarget;
|
||||
nsDeque mSharedNodes;
|
||||
|
@ -815,8 +815,8 @@ public:
|
||||
|
||||
if(aContext->mTableStates) {
|
||||
if(aContext->mTableStates->CanOpenTBody()) {
|
||||
nsCParserNode* theNode=new nsCParserNode();
|
||||
CToken* theToken=new CStartToken(eHTMLTag_tbody);
|
||||
nsCParserNode* theNode=aContext->gNodeRecycler->CreateNode();
|
||||
CToken* theToken=(CStartToken*)aContext->mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_tbody);
|
||||
theNode->Init(theToken,0,0); //this will likely leak...
|
||||
|
||||
result=HandleStartToken(theNode,eHTMLTag_tbody,aContext,aSink);
|
||||
@ -1859,8 +1859,9 @@ public:
|
||||
if(theBody->CanContain(theChildElement,aContext)) {
|
||||
//let's auto open the body
|
||||
|
||||
CToken* theToken=new CStartToken(eHTMLTag_body);
|
||||
nsCParserNode* theNode=new nsCParserNode(theToken,0,0);
|
||||
CToken* theToken=(CStartToken*)aContext->mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_body);
|
||||
nsCParserNode* theNode=aContext->gNodeRecycler->CreateNode();
|
||||
theNode->Init(theToken,0,0);
|
||||
|
||||
result=theBody->HandleStartToken(theNode,eHTMLTag_body,aContext,aSink);
|
||||
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "nsITokenizer.h"
|
||||
#include "nsIHTMLContentSink.h"
|
||||
#include "nsHTMLEntities.h"
|
||||
#include "nsDTDUtils.h"
|
||||
|
||||
#include "prenv.h" //this is here for debug reasons...
|
||||
#include "prtypes.h" //this is here for debug reasons...
|
||||
@ -65,10 +66,10 @@ public:
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual nsresult WillTokenize(PRBool aIsFinalChunk);
|
||||
virtual nsresult WillTokenize(PRBool aIsFinalChunk,nsTokenAllocator* aTokenAllocator);
|
||||
virtual nsresult ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens);
|
||||
virtual nsresult DidTokenize(PRBool aIsFinalChunk);
|
||||
virtual nsITokenRecycler* GetTokenRecycler(void);
|
||||
virtual nsTokenAllocator* GetTokenAllocator(void);
|
||||
|
||||
virtual CToken* PushTokenFront(CToken* theToken);
|
||||
virtual CToken* PushToken(CToken* theToken);
|
||||
@ -78,10 +79,10 @@ public:
|
||||
virtual PRInt32 GetCount(void);
|
||||
|
||||
virtual void PrependTokens(nsDeque& aDeque);
|
||||
static void FreeTokenRecycler(void);
|
||||
protected:
|
||||
|
||||
nsDeque mTokenDeque;
|
||||
nsDeque mTokenDeque;
|
||||
nsTokenAllocator* mTokenAllocator;
|
||||
};
|
||||
|
||||
|
||||
@ -443,6 +444,8 @@ NS_IMETHODIMP CRtfDTD::DidBuildModel(nsresult anErrorCode,PRInt32 aLevel,nsIPars
|
||||
CloseContainer(eHTMLTag_body);
|
||||
CloseContainer(eHTMLTag_html);
|
||||
|
||||
if(mSink) mSink->DidBuildModel(0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -814,6 +817,7 @@ nsresult CRtfDTD::HandleToken(CToken* aToken,nsIParser* aParser) {
|
||||
case eRTFToken_controlword:
|
||||
result=HandleControlWord(aToken); break;
|
||||
|
||||
case eRTFToken_content:
|
||||
case eToken_newline:
|
||||
case eHTMLTag_text:
|
||||
result=HandleContent(aToken); break;
|
||||
@ -835,7 +839,7 @@ nsresult CRtfDTD::HandleToken(CToken* aToken,nsIParser* aParser) {
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsITokenRecycler* CRtfDTD::GetTokenRecycler(void){
|
||||
nsTokenAllocator* CRtfDTD::GetTokenAllocator(void){
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -946,7 +950,7 @@ CRTFContent::CRTFContent(PRUnichar* aKey) : CToken(nsAutoString(aKey)) {
|
||||
* @return nsresult
|
||||
*/
|
||||
PRInt32 CRTFContent::GetTokenType() {
|
||||
return eHTMLTag_text;
|
||||
return eRTFToken_content;
|
||||
}
|
||||
|
||||
|
||||
@ -1026,38 +1030,22 @@ nsRTFTokenizer::~nsRTFTokenizer() {
|
||||
* @param
|
||||
* @return nsresult
|
||||
*/
|
||||
nsresult nsRTFTokenizer::WillTokenize(PRBool aIsFinalChunk) {
|
||||
nsresult nsRTFTokenizer::WillTokenize(PRBool aIsFinalChunk,nsTokenAllocator* aTokenAllocator) {
|
||||
nsresult result=NS_OK;
|
||||
mTokenAllocator=aTokenAllocator;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static CTokenRecycler* gTokenRecycler=0;
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess 1/31/00
|
||||
* @param
|
||||
* @return nsresult
|
||||
*/
|
||||
nsITokenRecycler* nsRTFTokenizer::GetTokenRecycler(void) {
|
||||
nsTokenAllocator* nsRTFTokenizer::GetTokenAllocator(void) {
|
||||
//let's move to this once we eliminate the leaking of tokens...
|
||||
if(!gTokenRecycler)
|
||||
gTokenRecycler=new CTokenRecycler();
|
||||
return gTokenRecycler;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess 1/31/00
|
||||
* @param
|
||||
* @return nsresult
|
||||
*/
|
||||
void nsRTFTokenizer::FreeTokenRecycler(void) {
|
||||
if(gTokenRecycler) {
|
||||
delete gTokenRecycler;
|
||||
gTokenRecycler=0;
|
||||
}
|
||||
return mTokenAllocator;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1077,7 +1065,8 @@ nsresult nsRTFTokenizer::ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens)
|
||||
case '{':
|
||||
{
|
||||
eRTFTags theTag= ('{'==theChar) ? eRTFCtrl_startgroup : eRTFCtrl_endgroup;
|
||||
CRTFControlWord* theToken=new CRTFControlWord(theTag);
|
||||
CRTFControlWord* theToken=(CRTFControlWord*)mTokenAllocator->CreateRTFTokenOfType(eRTFToken_controlword,theTag);
|
||||
|
||||
if(theToken) {
|
||||
mTokenDeque.Push(theToken);
|
||||
}
|
||||
@ -1086,7 +1075,7 @@ nsresult nsRTFTokenizer::ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens)
|
||||
break;
|
||||
case '\\':
|
||||
{
|
||||
CRTFControlWord* theWord = new CRTFControlWord(eRTFCtrl_unknown);
|
||||
CRTFControlWord* theWord =(CRTFControlWord*)mTokenAllocator->CreateRTFTokenOfType(eRTFToken_controlword,eRTFCtrl_unknown);
|
||||
if(theWord) {
|
||||
result=theWord->Consume(theChar,aScanner,0);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
@ -1098,7 +1087,7 @@ nsresult nsRTFTokenizer::ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens)
|
||||
case '\n':
|
||||
case '\r':
|
||||
{
|
||||
CNewlineToken* theContent= new CNewlineToken();
|
||||
CNewlineToken* theContent=(CNewlineToken*)mTokenAllocator->CreateTokenOfType(eToken_newline,eHTMLTag_newline);
|
||||
if(theContent) {
|
||||
result=theContent->Consume(theChar,aScanner,0);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
@ -1108,7 +1097,7 @@ nsresult nsRTFTokenizer::ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens)
|
||||
}
|
||||
break;
|
||||
default:
|
||||
CRTFContent* theContent= new CRTFContent();
|
||||
CRTFContent* theContent=(CRTFContent*)mTokenAllocator->CreateRTFTokenOfType(eRTFToken_content,(eRTFTags)0);
|
||||
if(theContent) {
|
||||
result=theContent->Consume(theChar,aScanner,0);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
@ -1154,7 +1143,6 @@ CToken* nsRTFTokenizer::PeekToken() {
|
||||
CToken* nsRTFTokenizer::PopToken() {
|
||||
CToken* result=nsnull;
|
||||
result=(CToken*)mTokenDeque.PopFront();
|
||||
if(result) result->mUseCount=0;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1167,7 +1155,6 @@ CToken* nsRTFTokenizer::PopToken() {
|
||||
*/
|
||||
CToken* nsRTFTokenizer::PushTokenFront(CToken* theToken) {
|
||||
mTokenDeque.PushFront(theToken);
|
||||
theToken->mUseCount=1;
|
||||
return theToken;
|
||||
}
|
||||
|
||||
@ -1179,7 +1166,6 @@ CToken* nsRTFTokenizer::PushTokenFront(CToken* theToken) {
|
||||
*/
|
||||
CToken* nsRTFTokenizer::PushToken(CToken* theToken) {
|
||||
mTokenDeque.Push(theToken);
|
||||
theToken->mUseCount=1;
|
||||
return theToken;
|
||||
}
|
||||
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "nsDeque.h"
|
||||
#include "nsToken.h"
|
||||
|
||||
|
||||
#define NS_RTF_DTD_IID \
|
||||
{0xa39c6bfc, 0x15f0, 0x11d2, \
|
||||
{0x80, 0x41, 0x00, 0x10, 0x4b, 0x98, 0x3f, 0xd4}}
|
||||
@ -303,7 +304,7 @@ class CRtfDTD : public nsIDTD {
|
||||
* @update gess8/4/98
|
||||
* @return ptr to recycler (or null)
|
||||
*/
|
||||
virtual nsITokenRecycler* GetTokenRecycler(void);
|
||||
virtual nsTokenAllocator* GetTokenAllocator(void);
|
||||
|
||||
/**
|
||||
* Use this id you want to stop the building content model
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
MOZ_DECL_CTOR_COUNTER(nsEntryStack);
|
||||
MOZ_DECL_CTOR_COUNTER(nsDTDContext);
|
||||
MOZ_DECL_CTOR_COUNTER(CTokenRecycler);
|
||||
MOZ_DECL_CTOR_COUNTER(nsTokenAllocator);
|
||||
MOZ_DECL_CTOR_COUNTER(CNodeRecycler);
|
||||
MOZ_DECL_CTOR_COUNTER(CObserverService);
|
||||
|
||||
@ -129,7 +129,6 @@ void nsEntryStack::Push(const nsIParserNode* aNode,nsEntryStack* aStyleStack) {
|
||||
EnsureCapacityFor(mCount+1);
|
||||
|
||||
((nsCParserNode*)aNode)->mUseCount++;
|
||||
((nsCParserNode*)aNode)->mToken->mUseCount++;
|
||||
|
||||
mEntries[mCount].mTag=(eHTMLTags)aNode->GetNodeType();
|
||||
mEntries[mCount].mNode=(nsIParserNode*)aNode;
|
||||
@ -157,7 +156,6 @@ void nsEntryStack::PushFront(const nsIParserNode* aNode,nsEntryStack* aStyleStac
|
||||
|
||||
|
||||
((nsCParserNode*)aNode)->mUseCount++;
|
||||
((nsCParserNode*)aNode)->mToken->mUseCount++;
|
||||
|
||||
mEntries[0].mTag=(eHTMLTags)aNode->GetNodeType();
|
||||
mEntries[0].mNode=(nsIParserNode*)aNode;
|
||||
@ -206,7 +204,6 @@ nsIParserNode* nsEntryStack::Remove(PRInt32 anIndex,eHTMLTags aTag) {
|
||||
result=mEntries[anIndex].mNode;
|
||||
|
||||
((nsCParserNode*)result)->mUseCount--;
|
||||
((nsCParserNode*)result)->mToken->mUseCount--;
|
||||
|
||||
PRInt32 theIndex=0;
|
||||
mCount-=1;
|
||||
@ -250,7 +247,7 @@ nsIParserNode* nsEntryStack::Pop(void) {
|
||||
result=mEntries[--mCount].mNode;
|
||||
|
||||
((nsCParserNode*)result)->mUseCount--;
|
||||
((nsCParserNode*)result)->mToken->mUseCount--;
|
||||
|
||||
mEntries[mCount].mNode=0;
|
||||
mEntries[mCount].mStyles=0;
|
||||
|
||||
@ -359,7 +356,6 @@ eHTMLTags nsEntryStack::Last() const {
|
||||
***************************************************************/
|
||||
|
||||
CNodeRecycler *nsDTDContext::gNodeRecycler=0;
|
||||
CTokenRecycler *nsDTDContext::gTokenRecycler=0;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -377,6 +373,7 @@ nsDTDContext::nsDTDContext() : mStack(), mEntities(0){
|
||||
ResetCounters();
|
||||
mHadDocTypeDecl=PR_FALSE;
|
||||
mHasOpenHead=PR_FALSE;
|
||||
mTokenAllocator=0;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
memset(mXTags,0,sizeof(mXTags));
|
||||
@ -1017,6 +1014,7 @@ void nsDTDContext::PushStyles(nsEntryStack *aStyles){
|
||||
// If you're here it means that we have hit the rock bottom
|
||||
// ,of the stack, and there's no need to handle anymore styles.
|
||||
// Fix for bug 29048
|
||||
gNodeRecycler->RecycleNode((nsCParserNode*)aStyles->Pop());
|
||||
delete aStyles;
|
||||
aStyles=0;
|
||||
}
|
||||
@ -1108,23 +1106,6 @@ nsresult nsDTDContext::GetNodeRecycler(CNodeRecycler*& aNodeRecycler){
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets called someone wants to create a token of the given type.
|
||||
*
|
||||
* @update rickg 16June2000
|
||||
* @param aType
|
||||
* @param aTag
|
||||
* @param aString
|
||||
* @return new CToken* or 0.
|
||||
*/
|
||||
CTokenRecycler* nsDTDContext::GetTokenRecycler(void) {
|
||||
if(!gTokenRecycler) {
|
||||
gTokenRecycler = new CTokenRecycler();
|
||||
}
|
||||
return gTokenRecycler;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update rickg 16June2000
|
||||
@ -1137,9 +1118,7 @@ void nsDTDContext::RecycleNode(nsCParserNode* aNode) {
|
||||
result=nsDTDContext::GetNodeRecycler(gNodeRecycler);
|
||||
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
if(!gTokenRecycler)
|
||||
GetTokenRecycler();
|
||||
gNodeRecycler->RecycleNode(aNode,gTokenRecycler);
|
||||
gNodeRecycler->RecycleNode(aNode);
|
||||
}
|
||||
else {
|
||||
delete aNode;
|
||||
@ -1158,29 +1137,31 @@ void nsDTDContext::ReleaseGlobalObjects(){
|
||||
delete gNodeRecycler;
|
||||
gNodeRecycler=0;
|
||||
}
|
||||
if(gTokenRecycler) {
|
||||
delete gTokenRecycler;
|
||||
gTokenRecycler=0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************
|
||||
Now define the tokenrecycler class...
|
||||
Now define the nsTokenAllocator class...
|
||||
**************************************************************/
|
||||
|
||||
static const size_t kBucketSizes[] ={sizeof(CStartToken),sizeof(CAttributeToken),sizeof(CCommentToken),sizeof(CEndToken)};
|
||||
static const PRInt32 kNumBuckets = sizeof(kBucketSizes) / sizeof(size_t);
|
||||
static const PRInt32 kInitialPoolSize = NS_SIZE_IN_HEAP(sizeof(CToken)) * 1536;
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess7/25/98
|
||||
* @param
|
||||
*/
|
||||
CTokenRecycler::CTokenRecycler() : nsITokenRecycler() {
|
||||
nsTokenAllocator::nsTokenAllocator() {
|
||||
|
||||
MOZ_COUNT_CTOR(CTokenRecycler);
|
||||
MOZ_COUNT_CTOR(nsTokenAllocator);
|
||||
|
||||
mArenaPool.Init("TheTokenPool", kBucketSizes, kNumBuckets, kInitialPoolSize);
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
int i=0;
|
||||
for(i=0;i<eToken_last-1;i++) {
|
||||
mTokenCache[i]=new nsDeque(0);
|
||||
#ifdef NS_DEBUG
|
||||
mTotals[i]=0;
|
||||
#endif
|
||||
}
|
||||
@ -1190,22 +1171,10 @@ CTokenRecycler::CTokenRecycler() : nsITokenRecycler() {
|
||||
* Destructor for the token factory
|
||||
* @update gess7/25/98
|
||||
*/
|
||||
CTokenRecycler::~CTokenRecycler() {
|
||||
nsTokenAllocator::~nsTokenAllocator() {
|
||||
|
||||
MOZ_COUNT_DTOR(CTokenRecycler);
|
||||
MOZ_COUNT_DTOR(nsTokenAllocator);
|
||||
|
||||
//begin by deleting all the known (recycled) tokens...
|
||||
//We're also deleting the cache-deques themselves.
|
||||
int i;
|
||||
|
||||
CTokenDeallocator theDeallocator;
|
||||
for(i=0;i<eToken_last-1;i++) {
|
||||
if(0!=mTokenCache[i]) {
|
||||
mTokenCache[i]->ForEach(theDeallocator);
|
||||
delete mTokenCache[i];
|
||||
mTokenCache[i]=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CTokenFinder: public nsDequeFunctor{
|
||||
@ -1220,31 +1189,6 @@ public:
|
||||
CToken* mToken;
|
||||
};
|
||||
|
||||
/**
|
||||
* This method gets called when someone wants to recycle a token
|
||||
* @update gess7/24/98
|
||||
* @param aToken -- token to be recycled.
|
||||
* @return nada
|
||||
*/
|
||||
void CTokenRecycler::RecycleToken(CToken* aToken) {
|
||||
if(aToken) {
|
||||
PRInt32 theType=aToken->GetTokenType();
|
||||
|
||||
#if 0
|
||||
//This should be disabled since it's only debug code.
|
||||
CTokenFinder finder(aToken);
|
||||
CToken* theMatch;
|
||||
theMatch=(CToken*)mTokenCache[theType-1]->FirstThat(finder);
|
||||
if(theMatch) {
|
||||
printf("dup token: %p\n",theMatch);
|
||||
}
|
||||
#endif
|
||||
aToken->mUseCount=1;
|
||||
mTokenCache[theType-1]->Push(aToken);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Let's get this code ready to be reused by all the contexts.
|
||||
*
|
||||
@ -1255,37 +1199,33 @@ void CTokenRecycler::RecycleToken(CToken* aToken) {
|
||||
*
|
||||
* @return ptr to new token (or 0).
|
||||
*/
|
||||
CToken* CTokenRecycler::CreateTokenOfType(eHTMLTokenTypes aType,eHTMLTags aTag, const nsString& aString) {
|
||||
CToken* nsTokenAllocator::CreateTokenOfType(eHTMLTokenTypes aType,eHTMLTags aTag, const nsString& aString) {
|
||||
|
||||
CToken* result=(CToken*)mTokenCache[aType-1]->Pop();
|
||||
CToken* result=0;
|
||||
|
||||
if(result) {
|
||||
result->Reinitialize(aTag,aString);
|
||||
}
|
||||
else {
|
||||
#ifdef NS_DEBUG
|
||||
mTotals[aType-1]++;
|
||||
#endif
|
||||
switch(aType){
|
||||
case eToken_start: result=new CStartToken(aTag); break;
|
||||
case eToken_end: result=new CEndToken(aTag); break;
|
||||
case eToken_comment: result=new CCommentToken(); break;
|
||||
case eToken_entity: result=new CEntityToken(aString); break;
|
||||
case eToken_whitespace: result=new CWhitespaceToken(); break;
|
||||
case eToken_newline: result=new CNewlineToken(); break;
|
||||
case eToken_text: result=new CTextToken(aString); break;
|
||||
case eToken_attribute: result=new CAttributeToken(); break;
|
||||
case eToken_script: result=new CScriptToken(); break;
|
||||
case eToken_style: result=new CStyleToken(); break;
|
||||
case eToken_skippedcontent: result=new CSkippedContentToken(aString); break;
|
||||
case eToken_instruction: result=new CInstructionToken(); break;
|
||||
case eToken_cdatasection: result=new CCDATASectionToken(); break;
|
||||
case eToken_error: result=new CErrorToken(); break;
|
||||
case eToken_doctypeDecl: result=new CDoctypeDeclToken(); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch(aType){
|
||||
case eToken_start: result=new(mArenaPool) CStartToken(aTag); break;
|
||||
case eToken_end: result=new(mArenaPool) CEndToken(aTag); break;
|
||||
case eToken_comment: result=new(mArenaPool) CCommentToken(); break;
|
||||
case eToken_entity: result=new(mArenaPool) CEntityToken(aString); break;
|
||||
case eToken_whitespace: result=new(mArenaPool) CWhitespaceToken(); break;
|
||||
case eToken_newline: result=new(mArenaPool) CNewlineToken(); break;
|
||||
case eToken_text: result=new(mArenaPool) CTextToken(aString); break;
|
||||
case eToken_attribute: result=new(mArenaPool) CAttributeToken(aString); break;
|
||||
case eToken_script: result=new(mArenaPool) CScriptToken(); break;
|
||||
case eToken_style: result=new(mArenaPool) CStyleToken(); break;
|
||||
case eToken_skippedcontent: result=new(mArenaPool) CSkippedContentToken(aString); break;
|
||||
case eToken_instruction: result=new(mArenaPool) CInstructionToken(); break;
|
||||
case eToken_cdatasection: result=new(mArenaPool) CCDATASectionToken(); break;
|
||||
case eToken_error: result=new(mArenaPool) CErrorToken(); break;
|
||||
case eToken_doctypeDecl: result=new(mArenaPool) CDoctypeDeclToken(); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1298,40 +1238,60 @@ CToken* CTokenRecycler::CreateTokenOfType(eHTMLTokenTypes aType,eHTMLTags aTag,
|
||||
*
|
||||
* @return ptr to new token (or 0).
|
||||
*/
|
||||
CToken* CTokenRecycler::CreateTokenOfType(eHTMLTokenTypes aType,eHTMLTags aTag) {
|
||||
CToken* nsTokenAllocator::CreateTokenOfType(eHTMLTokenTypes aType,eHTMLTags aTag) {
|
||||
|
||||
CToken* result=(CToken*)mTokenCache[aType-1]->Pop();
|
||||
CToken* result=0;
|
||||
|
||||
if(result) {
|
||||
result->Reinitialize(aTag,mEmpty);
|
||||
}
|
||||
else {
|
||||
#ifdef NS_DEBUG
|
||||
mTotals[aType-1]++;
|
||||
#endif
|
||||
switch(aType){
|
||||
case eToken_start: result=new CStartToken(aTag); break;
|
||||
case eToken_end: result=new CEndToken(aTag); break;
|
||||
case eToken_comment: result=new CCommentToken(); break;
|
||||
case eToken_attribute: result=new CAttributeToken(); break;
|
||||
case eToken_entity: result=new CEntityToken(); break;
|
||||
case eToken_whitespace: result=new CWhitespaceToken(); break;
|
||||
case eToken_newline: result=new CNewlineToken(); break;
|
||||
case eToken_text: result=new CTextToken(mEmpty); break;
|
||||
case eToken_script: result=new CScriptToken(); break;
|
||||
case eToken_style: result=new CStyleToken(); break;
|
||||
case eToken_skippedcontent: result=new CSkippedContentToken(mEmpty); break;
|
||||
case eToken_instruction: result=new CInstructionToken(); break;
|
||||
case eToken_cdatasection: result=new CCDATASectionToken(); break;
|
||||
case eToken_error: result=new CErrorToken(); break;
|
||||
case eToken_doctypeDecl: result=new CDoctypeDeclToken(aTag); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch(aType){
|
||||
case eToken_start: result=new(mArenaPool) CStartToken(aTag); break;
|
||||
case eToken_end: result=new(mArenaPool) CEndToken(aTag); break;
|
||||
case eToken_comment: result=new(mArenaPool) CCommentToken(); break;
|
||||
case eToken_attribute: result=new(mArenaPool) CAttributeToken(); break;
|
||||
case eToken_entity: result=new(mArenaPool) CEntityToken(); break;
|
||||
case eToken_whitespace: result=new(mArenaPool) CWhitespaceToken(); break;
|
||||
case eToken_newline: result=new(mArenaPool) CNewlineToken(); break;
|
||||
case eToken_text: result=new(mArenaPool) CTextToken(NS_ConvertToString("")); break;
|
||||
case eToken_script: result=new(mArenaPool) CScriptToken(); break;
|
||||
case eToken_style: result=new(mArenaPool) CStyleToken(); break;
|
||||
case eToken_skippedcontent: result=new(mArenaPool) CSkippedContentToken(NS_ConvertToString("")); break;
|
||||
case eToken_instruction: result=new(mArenaPool) CInstructionToken(); break;
|
||||
case eToken_cdatasection: result=new(mArenaPool) CCDATASectionToken(); break;
|
||||
case eToken_error: result=new(mArenaPool) CErrorToken(); break;
|
||||
case eToken_doctypeDecl: result=new(mArenaPool) CDoctypeDeclToken(aTag); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Let's get this code ready to be reused by all the contexts.
|
||||
*
|
||||
* @update harishd 08/04/00
|
||||
* @param aType -- tells you the type of token to create
|
||||
* @param aTag -- tells you the type of tag to init with this token
|
||||
*
|
||||
* @return ptr to new token (or 0).
|
||||
*/
|
||||
CToken* nsTokenAllocator::CreateRTFTokenOfType(eRTFTokenTypes aType,eRTFTags aTag) {
|
||||
|
||||
CToken* result=0;
|
||||
|
||||
switch(aType){
|
||||
case eRTFToken_controlword: result=new(mArenaPool) CRTFControlWord(aTag); break;
|
||||
case eRTFToken_content: result=new(mArenaPool) CRTFContent(); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
CNodeRecycler::CNodeRecycler(): mSharedNodes(0) {
|
||||
|
||||
MOZ_COUNT_CTOR(CNodeRecycler);
|
||||
@ -1361,24 +1321,15 @@ CNodeRecycler::~CNodeRecycler() {
|
||||
}
|
||||
}
|
||||
|
||||
void CNodeRecycler::RecycleNode(nsCParserNode* aNode,nsITokenRecycler* aTokenRecycler) {
|
||||
void CNodeRecycler::RecycleNode(nsCParserNode* aNode) {
|
||||
|
||||
if(aNode && (!aNode->mUseCount)) {
|
||||
|
||||
IF_FREE(aNode->mToken);
|
||||
|
||||
// If the node contains tokens there better me a token recycler..
|
||||
if(aTokenRecycler) {
|
||||
if(aNode->mToken) {
|
||||
if(!aNode->mToken->mUseCount) {
|
||||
aTokenRecycler->RecycleToken(aNode->mToken);
|
||||
}
|
||||
}
|
||||
|
||||
CToken* theToken=0;
|
||||
while((theToken=(CToken*)aNode->PopAttributeToken())){
|
||||
if(!theToken->mUseCount) {
|
||||
aTokenRecycler->RecycleToken(theToken);
|
||||
}
|
||||
}
|
||||
CToken* theToken=0;
|
||||
while((theToken=(CToken*)aNode->PopAttributeToken())){
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
mSharedNodes.Push(aNode);
|
||||
}
|
||||
|
@ -42,6 +42,11 @@
|
||||
#include "nsString.h"
|
||||
#include "nsIElementObserver.h"
|
||||
#include "nsIParserNode.h"
|
||||
#include "nsFixedSizeAllocator.h"
|
||||
#include "CRtfDTD.h"
|
||||
|
||||
#define IF_HOLD(_ptr) if(_ptr) { _ptr->AddRef(); }
|
||||
#define IF_FREE(_ptr) if(_ptr) { _ptr->Release(); _ptr=0; } // recycles _ptr
|
||||
|
||||
class nsIParserNode;
|
||||
class nsCParserNode;
|
||||
@ -207,25 +212,27 @@ public:
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
CTokenRecycler class implementation.
|
||||
nsTokenAllocator class implementation.
|
||||
This class is used to recycle tokens.
|
||||
By using this simple class, we cut WAY down on the number of tokens
|
||||
that get created during the run of the system.
|
||||
************************************************************************/
|
||||
class CTokenRecycler : public nsITokenRecycler {
|
||||
public:
|
||||
|
||||
// enum {eCacheMaxSize=100};
|
||||
|
||||
CTokenRecycler();
|
||||
virtual ~CTokenRecycler();
|
||||
virtual void RecycleToken(CToken* aToken);
|
||||
Note: The allocator is created per document. It's been shared
|
||||
( but not ref. counted ) by objects, tokenizer,dtd,and dtd context,
|
||||
that cease to exist when the document is destroyed.
|
||||
************************************************************************/
|
||||
class nsTokenAllocator {
|
||||
public:
|
||||
|
||||
nsTokenAllocator();
|
||||
virtual ~nsTokenAllocator();
|
||||
virtual CToken* CreateTokenOfType(eHTMLTokenTypes aType,eHTMLTags aTag, const nsString& aString);
|
||||
virtual CToken* CreateTokenOfType(eHTMLTokenTypes aType,eHTMLTags aTag);
|
||||
virtual CToken* CreateRTFTokenOfType(eRTFTokenTypes aType,eRTFTags aTag);
|
||||
|
||||
protected:
|
||||
nsDeque* mTokenCache[eToken_last-1];
|
||||
nsString mEmpty;
|
||||
nsFixedSizeAllocator mArenaPool;
|
||||
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
int mTotals[eToken_last-1];
|
||||
@ -246,7 +253,7 @@ public:
|
||||
CNodeRecycler();
|
||||
virtual ~CNodeRecycler();
|
||||
virtual nsCParserNode* CreateNode(void);
|
||||
virtual void RecycleNode(nsCParserNode* aNode,nsITokenRecycler* aTokenRecycler=0);
|
||||
virtual void RecycleNode(nsCParserNode* aNode);
|
||||
|
||||
protected:
|
||||
nsDeque mSharedNodes;
|
||||
@ -291,7 +298,6 @@ public:
|
||||
|
||||
nsresult GetNodeRecycler(CNodeRecycler*& aNodeRecycler);
|
||||
void RecycleNode(nsCParserNode *aNode);
|
||||
CTokenRecycler* GetTokenRecycler(void);
|
||||
static void ReleaseGlobalObjects(void);
|
||||
|
||||
CNamedEntity* RegisterEntity(const nsString& aName,const nsString& aValue);
|
||||
@ -300,6 +306,8 @@ public:
|
||||
void ResetCounters(void);
|
||||
PRInt32 IncrementCounter(eHTMLTags aTag,nsCParserNode& aNode,nsString& aResult);
|
||||
|
||||
void SetTokenAllocator(nsTokenAllocator* aTokenAllocator) { mTokenAllocator=aTokenAllocator; }
|
||||
|
||||
nsEntryStack mStack; //this will hold a list of tagentries...
|
||||
PRInt32 mResidualStyleCount;
|
||||
PRInt32 mContextTopIndex;
|
||||
@ -310,8 +318,8 @@ public:
|
||||
PRBool mHadDocTypeDecl;
|
||||
|
||||
static CNodeRecycler *gNodeRecycler;
|
||||
static CTokenRecycler *gTokenRecycler;
|
||||
|
||||
|
||||
nsTokenAllocator *mTokenAllocator;
|
||||
CTableState *mTableStates;
|
||||
PRInt32 mCounters[NS_HTML_TAG_MAX];
|
||||
nsString mDefaultEntity;
|
||||
|
@ -227,14 +227,14 @@ NS_IMETHODIMP nsExpatDTD::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer
|
||||
if(aTokenizer) {
|
||||
nsITokenizer* oldTokenizer=mTokenizer;
|
||||
mTokenizer=aTokenizer;
|
||||
nsITokenRecycler* theRecycler=aTokenizer->GetTokenRecycler();
|
||||
nsTokenAllocator* theAllocator=aTokenizer->GetTokenAllocator();
|
||||
|
||||
while(NS_OK==result){
|
||||
CToken* theToken=mTokenizer->PopToken();
|
||||
if(theToken) {
|
||||
result=HandleToken(theToken,aParser);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
theRecycler->RecycleToken(theToken);
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
else if(NS_ERROR_HTMLPARSER_BLOCK!=result){
|
||||
mTokenizer->PushTokenFront(theToken);
|
||||
@ -277,12 +277,12 @@ NS_IMETHODIMP nsExpatDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsITokenRecycler* nsExpatDTD::GetTokenRecycler(void){
|
||||
nsTokenAllocator* nsExpatDTD::GetTokenAllocator(void){
|
||||
nsITokenizer* theTokenizer=0;
|
||||
nsresult result=GetTokenizer(theTokenizer);
|
||||
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
return theTokenizer->GetTokenRecycler();
|
||||
return theTokenizer->GetTokenAllocator();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -237,7 +237,7 @@ class nsExpatDTD : public nsIDTD {
|
||||
* @update gess8/4/98
|
||||
* @return ptr to recycler (or null)
|
||||
*/
|
||||
virtual nsITokenRecycler* GetTokenRecycler(void);
|
||||
virtual nsTokenAllocator* GetTokenAllocator(void);
|
||||
|
||||
/**
|
||||
* Parse an XML buffer using expat
|
||||
|
@ -45,7 +45,7 @@
|
||||
typedef struct _XMLParserState {
|
||||
XML_Parser parser;
|
||||
nsDeque* tokenDeque;
|
||||
CTokenRecycler* tokenRecycler;
|
||||
nsTokenAllocator* tokenAllocator;
|
||||
CToken* doctypeToken;
|
||||
CToken* cdataToken; // Used by the begin and end handlers of the cdata section
|
||||
} XMLParserState;
|
||||
@ -115,11 +115,6 @@ nsresult nsExpatTokenizer::QueryInterface(const nsIID& aIID, void** aInstancePtr
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsExpatTokenizer::FreeTokenRecycler(void) {
|
||||
nsHTMLTokenizer::FreeTokenRecycler();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is defined in nsIParser. It is used to
|
||||
* cause the COM-like construction of an nsParser.
|
||||
@ -180,7 +175,7 @@ nsExpatTokenizer::nsExpatTokenizer(nsString* aURL) : nsHTMLTokenizer() {
|
||||
NS_INIT_REFCNT();
|
||||
mBytesParsed = 0;
|
||||
mState = new XMLParserState;
|
||||
mState->tokenRecycler = (CTokenRecycler*)GetTokenRecycler();
|
||||
mState->tokenAllocator = nsnull;
|
||||
mState->cdataToken = nsnull;
|
||||
mState->parser = nsnull;
|
||||
mState->tokenDeque = nsnull;
|
||||
@ -224,6 +219,12 @@ nsExpatTokenizer::~nsExpatTokenizer(){
|
||||
Here begins the real working methods for the tokenizer.
|
||||
*******************************************************************/
|
||||
|
||||
nsresult nsExpatTokenizer::WillTokenize(PRBool aIsFinalChunk,nsTokenAllocator* aTokenAllocator)
|
||||
{
|
||||
mState->tokenAllocator=aTokenAllocator;
|
||||
return nsHTMLTokenizer::WillTokenize(aIsFinalChunk,aTokenAllocator);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parameters:
|
||||
*
|
||||
@ -336,38 +337,38 @@ nsresult
|
||||
nsExpatTokenizer::AddErrorMessageTokens(nsParserError* aError)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
CToken* newToken = mState->tokenRecycler->CreateTokenOfType(eToken_start, eHTMLTag_parsererror);
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
|
||||
CToken* newToken = mState->tokenAllocator->CreateTokenOfType(eToken_start, eHTMLTag_parsererror);
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenAllocator);
|
||||
|
||||
CAttributeToken* attrToken = (CAttributeToken*)
|
||||
mState->tokenRecycler->CreateTokenOfType(eToken_attribute, eHTMLTag_unknown);
|
||||
mState->tokenAllocator->CreateTokenOfType(eToken_attribute, eHTMLTag_unknown);
|
||||
nsString& key = attrToken->GetKey();
|
||||
key.AssignWithConversion("xmlns");
|
||||
attrToken->SetCStringValue(kHTMLNameSpaceURI);
|
||||
newToken->SetAttributeCount(1);
|
||||
newToken = (CToken*) attrToken;
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenAllocator);
|
||||
|
||||
nsAutoString textStr;
|
||||
CreateErrorText(aError, textStr);
|
||||
newToken = mState->tokenRecycler->CreateTokenOfType(eToken_text, eHTMLTag_unknown);
|
||||
newToken = mState->tokenAllocator->CreateTokenOfType(eToken_text, eHTMLTag_unknown);
|
||||
newToken->SetStringValue(textStr);
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenAllocator);
|
||||
|
||||
newToken = mState->tokenRecycler->CreateTokenOfType(eToken_start, eHTMLTag_sourcetext);
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
|
||||
newToken = mState->tokenAllocator->CreateTokenOfType(eToken_start, eHTMLTag_sourcetext);
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenAllocator);
|
||||
|
||||
textStr.Truncate();
|
||||
CreateSourceText(aError, textStr);
|
||||
newToken = mState->tokenRecycler->CreateTokenOfType(eToken_text, eHTMLTag_unknown);
|
||||
newToken = mState->tokenAllocator->CreateTokenOfType(eToken_text, eHTMLTag_unknown);
|
||||
newToken->SetStringValue(textStr);
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenAllocator);
|
||||
|
||||
newToken = mState->tokenRecycler->CreateTokenOfType(eToken_end, eHTMLTag_sourcetext);
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
|
||||
newToken = mState->tokenAllocator->CreateTokenOfType(eToken_end, eHTMLTag_sourcetext);
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenAllocator);
|
||||
|
||||
newToken = mState->tokenRecycler->CreateTokenOfType(eToken_end, eHTMLTag_parsererror);
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
|
||||
newToken = mState->tokenAllocator->CreateTokenOfType(eToken_end, eHTMLTag_parsererror);
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenAllocator);
|
||||
|
||||
return rv;
|
||||
}
|
||||
@ -392,7 +393,7 @@ nsExpatTokenizer::AddErrorMessageTokens(nsParserError* aError)
|
||||
nsresult
|
||||
nsExpatTokenizer::PushXMLErrorTokens(const char *aBuffer, PRUint32 aLength, PRBool aIsFinal)
|
||||
{
|
||||
CErrorToken* errorToken= (CErrorToken *) mState->tokenRecycler->CreateTokenOfType(eToken_error, eHTMLTag_unknown);
|
||||
CErrorToken* errorToken= (CErrorToken *) mState->tokenAllocator->CreateTokenOfType(eToken_error, eHTMLTag_unknown);
|
||||
nsParserError *error = new nsParserError;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
@ -416,7 +417,7 @@ nsExpatTokenizer::PushXMLErrorTokens(const char *aBuffer, PRUint32 aLength, PRBo
|
||||
|
||||
/* Add the error token */
|
||||
CToken* newToken = (CToken*) errorToken;
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenAllocator);
|
||||
|
||||
/* Add the error message tokens */
|
||||
AddErrorMessageTokens(error);
|
||||
@ -505,7 +506,7 @@ void nsExpatTokenizer::FrontloadMisplacedContent(nsDeque& aDeque){
|
||||
|
||||
void nsExpatTokenizer::HandleStartElement(void *userData, const XML_Char *name, const XML_Char **atts) {
|
||||
XMLParserState* state = (XMLParserState*) userData;
|
||||
CToken* theToken = state->tokenRecycler->CreateTokenOfType(eToken_start,eHTMLTag_unknown);
|
||||
CToken* theToken = state->tokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_unknown);
|
||||
if(theToken) {
|
||||
// If an ID attribute exists for this element, set it on the start token
|
||||
PRInt32 index = XML_GetIdAttributeIndex(state->parser);
|
||||
@ -518,14 +519,14 @@ void nsExpatTokenizer::HandleStartElement(void *userData, const XML_Char *name,
|
||||
// Set the element name on the start token and add the token to the token queue
|
||||
nsString& theString=theToken->GetStringValueXXX();
|
||||
theString.Assign((PRUnichar *) name);
|
||||
AddToken(theToken, NS_OK, state->tokenDeque, state->tokenRecycler);
|
||||
AddToken(theToken, NS_OK, state->tokenDeque, state->tokenAllocator);
|
||||
|
||||
// For each attribute on this element, create and add attribute tokens to the token queue
|
||||
int theAttrCount=0;
|
||||
while(*atts){
|
||||
theAttrCount++;
|
||||
CAttributeToken* theAttrToken = (CAttributeToken*)
|
||||
state->tokenRecycler->CreateTokenOfType(eToken_attribute, eHTMLTag_unknown);
|
||||
state->tokenAllocator->CreateTokenOfType(eToken_attribute, eHTMLTag_unknown);
|
||||
if(theAttrToken){
|
||||
nsString& theKey=theAttrToken->GetKey();
|
||||
theKey.Assign((PRUnichar *) (*atts++));
|
||||
@ -533,7 +534,7 @@ void nsExpatTokenizer::HandleStartElement(void *userData, const XML_Char *name,
|
||||
theValue.Assign((PRUnichar *) (*atts++));
|
||||
}
|
||||
CToken* theTok=(CToken*)theAttrToken;
|
||||
AddToken(theTok, NS_OK, state->tokenDeque, state->tokenRecycler);
|
||||
AddToken(theTok, NS_OK, state->tokenDeque, state->tokenAllocator);
|
||||
}
|
||||
theToken->SetAttributeCount(theAttrCount);
|
||||
}
|
||||
@ -544,11 +545,11 @@ void nsExpatTokenizer::HandleStartElement(void *userData, const XML_Char *name,
|
||||
|
||||
void nsExpatTokenizer::HandleEndElement(void *userData, const XML_Char *name) {
|
||||
XMLParserState* state = (XMLParserState*) userData;
|
||||
CToken* theToken = state->tokenRecycler->CreateTokenOfType(eToken_end,eHTMLTag_unknown);
|
||||
CToken* theToken = state->tokenAllocator->CreateTokenOfType(eToken_end,eHTMLTag_unknown);
|
||||
if(theToken) {
|
||||
nsString& theString=theToken->GetStringValueXXX();
|
||||
theString.Assign((PRUnichar *) name);
|
||||
AddToken(theToken, NS_OK, state->tokenDeque, state->tokenRecycler);
|
||||
AddToken(theToken, NS_OK, state->tokenDeque, state->tokenAllocator);
|
||||
}
|
||||
else{
|
||||
//THROW A HUGE ERROR IF WE CANT CREATE A TOKEN!
|
||||
@ -570,14 +571,14 @@ void nsExpatTokenizer::HandleCharacterData(void *userData, const XML_Char *s, in
|
||||
switch(((PRUnichar*)s)[0]){
|
||||
case kNewLine:
|
||||
case CR:
|
||||
newToken = state->tokenRecycler->CreateTokenOfType(eToken_newline,eHTMLTag_unknown);
|
||||
newToken = state->tokenAllocator->CreateTokenOfType(eToken_newline,eHTMLTag_unknown);
|
||||
break;
|
||||
case kSpace:
|
||||
case kTab:
|
||||
newToken = state->tokenRecycler->CreateTokenOfType(eToken_whitespace,eHTMLTag_unknown);
|
||||
newToken = state->tokenAllocator->CreateTokenOfType(eToken_whitespace,eHTMLTag_unknown);
|
||||
break;
|
||||
default:
|
||||
newToken = state->tokenRecycler->CreateTokenOfType(eToken_text,eHTMLTag_unknown);
|
||||
newToken = state->tokenAllocator->CreateTokenOfType(eToken_text,eHTMLTag_unknown);
|
||||
}
|
||||
|
||||
if(newToken) {
|
||||
@ -585,7 +586,7 @@ void nsExpatTokenizer::HandleCharacterData(void *userData, const XML_Char *s, in
|
||||
nsString& theString=newToken->GetStringValueXXX();
|
||||
theString.Append((PRUnichar *) s,len);
|
||||
}
|
||||
AddToken(newToken, NS_OK, state->tokenDeque, state->tokenRecycler);
|
||||
AddToken(newToken, NS_OK, state->tokenDeque, state->tokenAllocator);
|
||||
}
|
||||
else {
|
||||
//THROW A HUGE ERROR IF WE CANT CREATE A TOKEN!
|
||||
@ -595,11 +596,11 @@ void nsExpatTokenizer::HandleCharacterData(void *userData, const XML_Char *s, in
|
||||
|
||||
void nsExpatTokenizer::HandleComment(void *userData, const XML_Char *name) {
|
||||
XMLParserState* state = (XMLParserState*) userData;
|
||||
CToken* theToken = state->tokenRecycler->CreateTokenOfType(eToken_comment, eHTMLTag_unknown);
|
||||
CToken* theToken = state->tokenAllocator->CreateTokenOfType(eToken_comment, eHTMLTag_unknown);
|
||||
if(theToken) {
|
||||
nsString& theString=theToken->GetStringValueXXX();
|
||||
theString.Assign((PRUnichar *) name);
|
||||
AddToken(theToken, NS_OK, state->tokenDeque, state->tokenRecycler);
|
||||
AddToken(theToken, NS_OK, state->tokenDeque, state->tokenAllocator);
|
||||
}
|
||||
else{
|
||||
//THROW A HUGE ERROR IF WE CANT CREATE A TOKEN!
|
||||
@ -608,7 +609,7 @@ void nsExpatTokenizer::HandleComment(void *userData, const XML_Char *name) {
|
||||
|
||||
void nsExpatTokenizer::HandleStartCdataSection(void *userData) {
|
||||
XMLParserState* state = (XMLParserState*) userData;
|
||||
CToken* cdataToken = state->tokenRecycler->CreateTokenOfType(eToken_cdatasection,
|
||||
CToken* cdataToken = state->tokenAllocator->CreateTokenOfType(eToken_cdatasection,
|
||||
eHTMLTag_unknown);
|
||||
|
||||
state->cdataToken = cdataToken;
|
||||
@ -620,7 +621,7 @@ void nsExpatTokenizer::HandleEndCdataSection(void *userData) {
|
||||
|
||||
// We've reached the end of the current CDATA section. Push the current
|
||||
// CDATA token onto the token queue
|
||||
AddToken(currentCDataToken, NS_OK, state->tokenDeque, state->tokenRecycler);
|
||||
AddToken(currentCDataToken, NS_OK, state->tokenDeque, state->tokenAllocator);
|
||||
|
||||
state->cdataToken = nsnull;
|
||||
}
|
||||
@ -630,7 +631,7 @@ void nsExpatTokenizer::HandleProcessingInstruction(void *userData,
|
||||
const XML_Char *data)
|
||||
{
|
||||
XMLParserState* state = (XMLParserState*) userData;
|
||||
CToken* theToken = state->tokenRecycler->CreateTokenOfType(eToken_instruction,eHTMLTag_unknown);
|
||||
CToken* theToken = state->tokenAllocator->CreateTokenOfType(eToken_instruction,eHTMLTag_unknown);
|
||||
if(theToken) {
|
||||
nsString& theString=theToken->GetStringValueXXX();
|
||||
theString. AppendWithConversion("<?");
|
||||
@ -640,7 +641,7 @@ void nsExpatTokenizer::HandleProcessingInstruction(void *userData,
|
||||
theString.Append((PRUnichar *) data);
|
||||
}
|
||||
theString.AppendWithConversion("?>");
|
||||
AddToken(theToken, NS_OK, state->tokenDeque, state->tokenRecycler);
|
||||
AddToken(theToken, NS_OK, state->tokenDeque, state->tokenAllocator);
|
||||
}
|
||||
else{
|
||||
//THROW A HUGE ERROR IF WE CANT CREATE A TOKEN!
|
||||
@ -659,8 +660,8 @@ void nsExpatTokenizer::HandleDefault(void *userData, const XML_Char *s, int len)
|
||||
CToken* newLine = 0;
|
||||
|
||||
while ((offset = str.FindChar('\n', PR_FALSE, offset + 1)) != -1) {
|
||||
newLine = state->tokenRecycler->CreateTokenOfType(eToken_newline, eHTMLTag_unknown);
|
||||
AddToken(newLine, NS_OK, state->tokenDeque, state->tokenRecycler);
|
||||
newLine = state->tokenAllocator->CreateTokenOfType(eToken_newline, eHTMLTag_unknown);
|
||||
AddToken(newLine, NS_OK, state->tokenDeque, state->tokenAllocator);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -873,7 +874,7 @@ void nsExpatTokenizer::HandleStartDoctypeDecl(void *userData,
|
||||
const XML_Char *doctypeName)
|
||||
{
|
||||
XMLParserState* state = (XMLParserState*) userData;
|
||||
CToken* token = state->tokenRecycler->CreateTokenOfType(eToken_doctypeDecl, eHTMLTag_unknown);
|
||||
CToken* token = state->tokenAllocator->CreateTokenOfType(eToken_doctypeDecl, eHTMLTag_unknown);
|
||||
if (token) {
|
||||
nsString& str = token->GetStringValueXXX();
|
||||
str.AppendWithConversion(kDocTypeDeclPrefix);
|
||||
@ -888,7 +889,7 @@ void nsExpatTokenizer::HandleEndDoctypeDecl(void *userData)
|
||||
if (token) {
|
||||
nsString& str = token->GetStringValueXXX();
|
||||
str.AppendWithConversion(">");
|
||||
AddToken(token, NS_OK, state->tokenDeque, state->tokenRecycler);
|
||||
AddToken(token, NS_OK, state->tokenDeque, state->tokenAllocator);
|
||||
state->doctypeToken = nsnull;
|
||||
}
|
||||
// Do nothing
|
||||
|
@ -74,13 +74,12 @@ public:
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
/* nsITokenizer methods */
|
||||
/* nsITokenizer methods */
|
||||
virtual nsresult WillTokenize(PRBool aIsFinalChunk,nsTokenAllocator* aTokenAllocator);
|
||||
virtual nsresult ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens);
|
||||
virtual nsresult DidTokenize(PRBool aIsFinalChunk);
|
||||
|
||||
virtual void FrontloadMisplacedContent(nsDeque& aDeque);
|
||||
static void FreeTokenRecycler(void);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -75,16 +75,6 @@ nsresult nsHTMLTokenizer::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static CTokenRecycler* gTokenRecycler=0;
|
||||
|
||||
void
|
||||
nsHTMLTokenizer::FreeTokenRecycler(void) {
|
||||
if(gTokenRecycler) {
|
||||
delete gTokenRecycler;
|
||||
gTokenRecycler=0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is defined in nsHTMLTokenizer.h. It is used to
|
||||
* cause the COM-like construction of an HTMLTokenizer.
|
||||
@ -128,6 +118,7 @@ NS_IMPL_RELEASE(nsHTMLTokenizer)
|
||||
mDocType=aDocType;
|
||||
mRecordTrailingContent=PR_FALSE;
|
||||
mParserCommand=aCommand;
|
||||
mTokenAllocator=nsnull;
|
||||
}
|
||||
|
||||
|
||||
@ -150,17 +141,13 @@ nsHTMLTokenizer::~nsHTMLTokenizer(){
|
||||
Here begins the real working methods for the tokenizer.
|
||||
*******************************************************************/
|
||||
|
||||
void nsHTMLTokenizer::AddToken(CToken*& aToken,nsresult aResult,nsDeque* aDeque,CTokenRecycler* aRecycler) {
|
||||
void nsHTMLTokenizer::AddToken(CToken*& aToken,nsresult aResult,nsDeque* aDeque,nsTokenAllocator* aTokenAllocator) {
|
||||
if(aToken && aDeque) {
|
||||
if(NS_SUCCEEDED(aResult)) {
|
||||
aDeque->Push(aToken);
|
||||
}
|
||||
else {
|
||||
if(aRecycler) {
|
||||
aRecycler->RecycleToken(aToken);
|
||||
}
|
||||
else delete aToken;
|
||||
aToken=0;
|
||||
IF_FREE(aToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -170,11 +157,8 @@ void nsHTMLTokenizer::AddToken(CToken*& aToken,nsresult aResult,nsDeque* aDeque,
|
||||
* @update gess8/4/98
|
||||
* @return ptr to recycler (or null)
|
||||
*/
|
||||
nsITokenRecycler* nsHTMLTokenizer::GetTokenRecycler(void) {
|
||||
//let's move to this once we eliminate the leaking of tokens...
|
||||
if(!gTokenRecycler)
|
||||
gTokenRecycler=new CTokenRecycler();
|
||||
return gTokenRecycler;
|
||||
nsTokenAllocator* nsHTMLTokenizer::GetTokenAllocator(void) {
|
||||
return mTokenAllocator;
|
||||
}
|
||||
|
||||
|
||||
@ -198,7 +182,6 @@ CToken* nsHTMLTokenizer::PeekToken() {
|
||||
CToken* nsHTMLTokenizer::PopToken() {
|
||||
CToken* result=nsnull;
|
||||
result=(CToken*)mTokenDeque.PopFront();
|
||||
if(result) result->mUseCount=0;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -211,7 +194,6 @@ CToken* nsHTMLTokenizer::PopToken() {
|
||||
*/
|
||||
CToken* nsHTMLTokenizer::PushTokenFront(CToken* theToken) {
|
||||
mTokenDeque.PushFront(theToken);
|
||||
theToken->mUseCount=1;
|
||||
return theToken;
|
||||
}
|
||||
|
||||
@ -223,7 +205,6 @@ CToken* nsHTMLTokenizer::PushTokenFront(CToken* theToken) {
|
||||
*/
|
||||
CToken* nsHTMLTokenizer::PushToken(CToken* theToken) {
|
||||
mTokenDeque.Push(theToken);
|
||||
theToken->mUseCount=1;
|
||||
return theToken;
|
||||
}
|
||||
|
||||
@ -247,8 +228,15 @@ CToken* nsHTMLTokenizer::GetTokenAt(PRInt32 anIndex){
|
||||
return (CToken*)mTokenDeque.ObjectAt(anIndex);
|
||||
}
|
||||
|
||||
nsresult nsHTMLTokenizer::WillTokenize(PRBool aIsFinalChunk)
|
||||
/**
|
||||
* @update gess 12/29/98
|
||||
* @update harishd 08/04/00
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsresult nsHTMLTokenizer::WillTokenize(PRBool aIsFinalChunk,nsTokenAllocator* aTokenAllocator)
|
||||
{
|
||||
mTokenAllocator=aTokenAllocator;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -410,10 +398,10 @@ nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,CStartToken* aToken,
|
||||
nsresult result=NS_OK;
|
||||
PRInt16 theAttrCount=0;
|
||||
|
||||
CTokenRecycler* theRecycler=(CTokenRecycler*)GetTokenRecycler();
|
||||
nsTokenAllocator* theAllocator=this->GetTokenAllocator();
|
||||
|
||||
while((!done) && (result==NS_OK)) {
|
||||
CToken* theToken= (CAttributeToken*)theRecycler->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown);
|
||||
CToken* theToken= (CAttributeToken*)theAllocator->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown);
|
||||
if(theToken){
|
||||
if(aLeadingWS.Length()) {
|
||||
nsString& theKey=((CAttributeToken*)theToken)->GetKey();
|
||||
@ -433,16 +421,16 @@ nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,CStartToken* aToken,
|
||||
if((mDoXMLEmptyTags) && (kForwardSlash==key.CharAt(0)) && (0==text.Length())){
|
||||
//tada! our special case! Treat it like an empty start tag...
|
||||
aToken->SetEmpty(PR_TRUE);
|
||||
theRecycler->RecycleToken(theToken);
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
else {
|
||||
theAttrCount++;
|
||||
AddToken(theToken,result,&mTokenDeque,theRecycler);
|
||||
AddToken(theToken,result,&mTokenDeque,theAllocator);
|
||||
}
|
||||
}
|
||||
else { //if(NS_ERROR_HTMLPARSER_BADATTRIBUTE==result){
|
||||
aToken->SetEmpty(PR_TRUE);
|
||||
theRecycler->RecycleToken(theToken);
|
||||
IF_FREE(theToken);
|
||||
if(NS_ERROR_HTMLPARSER_BADATTRIBUTE==result)
|
||||
result=NS_OK;
|
||||
}
|
||||
@ -460,8 +448,8 @@ nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,CStartToken* aToken,
|
||||
else if(aChar==kLessThan) {
|
||||
eHTMLTags theEndTag = (eHTMLTags)aToken->GetTypeID();
|
||||
if(result==NS_OK&&(gHTMLElements[theEndTag].mSkipTarget)){
|
||||
CToken* theEndToken=theRecycler->CreateTokenOfType(eToken_end,theEndTag);
|
||||
AddToken(theEndToken,NS_OK,&mTokenDeque,theRecycler);
|
||||
CToken* theEndToken=theAllocator->CreateTokenOfType(eToken_end,theEndTag);
|
||||
AddToken(theEndToken,NS_OK,&mTokenDeque,theAllocator);
|
||||
}
|
||||
done=PR_TRUE;
|
||||
}
|
||||
@ -497,8 +485,8 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
|
||||
PRInt32 theDequeSize=mTokenDeque.GetSize(); //remember this for later in case you have to unwind...
|
||||
nsresult result=NS_OK;
|
||||
|
||||
CTokenRecycler* theRecycler=(CTokenRecycler*)GetTokenRecycler();
|
||||
aToken=theRecycler->CreateTokenOfType(eToken_start,eHTMLTag_unknown);
|
||||
nsTokenAllocator* theAllocator=this->GetTokenAllocator();
|
||||
aToken=theAllocator->CreateTokenOfType(eToken_start,eHTMLTag_unknown);
|
||||
|
||||
if(aToken) {
|
||||
((CStartToken*)aToken)->mOrigin=aScanner.GetOffset()-1; // Save the position after '<' for use in recording traling contents. Ref: Bug. 15204.
|
||||
@ -507,7 +495,7 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
|
||||
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
|
||||
AddToken(aToken,result,&mTokenDeque,theRecycler);
|
||||
AddToken(aToken,result,&mTokenDeque,theAllocator);
|
||||
eHTMLTags theTag=(eHTMLTags)aToken->GetTypeID();
|
||||
|
||||
//Good. Now, let's see if the next char is ">".
|
||||
@ -551,12 +539,12 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
|
||||
if(gHTMLElements[theTag].CanContainType(kCDATA)) {
|
||||
nsAutoString endTag; endTag.AssignWithConversion(nsHTMLTags::GetStringValue(theTag));
|
||||
endTag.InsertWithConversion("</",0,2);
|
||||
CToken* textToken=theRecycler->CreateTokenOfType(eToken_text,eHTMLTag_text);
|
||||
CToken* textToken=theAllocator->CreateTokenOfType(eToken_text,eHTMLTag_text);
|
||||
result=((CTextToken*)textToken)->ConsumeUntil(0,PRBool(theTag!=eHTMLTag_script),aScanner,endTag,mParseMode,aFlushTokens); //tell new token to finish consuming text...
|
||||
//endTag.Append(">");
|
||||
CToken* endToken=theRecycler->CreateTokenOfType(eToken_end,theTag,endTag);
|
||||
AddToken(textToken,result,&mTokenDeque,theRecycler);
|
||||
AddToken(endToken,result,&mTokenDeque,theRecycler);
|
||||
CToken* endToken=theAllocator->CreateTokenOfType(eToken_end,theTag,endTag);
|
||||
AddToken(textToken,result,&mTokenDeque,theAllocator);
|
||||
AddToken(endToken,result,&mTokenDeque,theAllocator);
|
||||
}
|
||||
}
|
||||
|
||||
@ -568,11 +556,12 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
|
||||
//any new tokens we've cued this round. Later we can get smarter about this.
|
||||
if(!NS_SUCCEEDED(result)) {
|
||||
while(mTokenDeque.GetSize()>theDequeSize) {
|
||||
theRecycler->RecycleToken((CToken*)mTokenDeque.Pop());
|
||||
CToken* theToken=(CToken*)mTokenDeque.Pop();
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
}
|
||||
} //if
|
||||
else theRecycler->RecycleToken(aToken);
|
||||
else IF_FREE(aToken);
|
||||
} //if
|
||||
return result;
|
||||
}
|
||||
@ -585,8 +574,8 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
|
||||
*/
|
||||
nsresult nsHTMLTokenizer::ConsumeEndTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner) {
|
||||
|
||||
CTokenRecycler* theRecycler=(CTokenRecycler*)GetTokenRecycler();
|
||||
aToken=theRecycler->CreateTokenOfType(eToken_end,eHTMLTag_unknown);
|
||||
nsTokenAllocator* theAllocator=this->GetTokenAllocator();
|
||||
aToken=theAllocator->CreateTokenOfType(eToken_end,eHTMLTag_unknown);
|
||||
nsresult result=NS_OK;
|
||||
|
||||
if(aToken) {
|
||||
@ -595,7 +584,7 @@ nsresult nsHTMLTokenizer::ConsumeEndTag(PRUnichar aChar,CToken*& aToken,nsScanne
|
||||
mRecordTrailingContent=PR_FALSE;
|
||||
}
|
||||
result= aToken->Consume(aChar,aScanner,mParseMode); //tell new token to finish consuming text...
|
||||
AddToken(aToken,result,&mTokenDeque,theRecycler);
|
||||
AddToken(aToken,result,&mTokenDeque,theAllocator);
|
||||
} //if
|
||||
return result;
|
||||
}
|
||||
@ -614,14 +603,14 @@ nsresult nsHTMLTokenizer::ConsumeEntity(PRUnichar aChar,CToken*& aToken,nsScanne
|
||||
PRUnichar theChar;
|
||||
nsresult result=aScanner.GetChar(theChar);
|
||||
|
||||
CTokenRecycler* theRecycler=(CTokenRecycler*)GetTokenRecycler();
|
||||
nsTokenAllocator* theAllocator=this->GetTokenAllocator();
|
||||
if(NS_OK==result) {
|
||||
if(nsCRT::IsAsciiAlpha(theChar)) { //handle common enity references &xxx; or �.
|
||||
aToken = theRecycler->CreateTokenOfType(eToken_entity,eHTMLTag_entity);
|
||||
aToken = theAllocator->CreateTokenOfType(eToken_entity,eHTMLTag_entity);
|
||||
result = aToken->Consume(theChar,aScanner,mParseMode); //tell new token to finish consuming text...
|
||||
}
|
||||
else if(kHashsign==theChar) {
|
||||
aToken = theRecycler->CreateTokenOfType(eToken_entity,eHTMLTag_entity);
|
||||
aToken = theAllocator->CreateTokenOfType(eToken_entity,eHTMLTag_entity);
|
||||
result=aToken->Consume(theChar,aScanner,mParseMode);
|
||||
}
|
||||
else {
|
||||
@ -639,12 +628,12 @@ nsresult nsHTMLTokenizer::ConsumeEntity(PRUnichar aChar,CToken*& aToken,nsScanne
|
||||
//convert it into a text token.
|
||||
nsAutoString temp; temp.AssignWithConversion("&");
|
||||
temp.Append(theStr);
|
||||
CToken* theToken=theRecycler->CreateTokenOfType(eToken_text,eHTMLTag_text,temp);
|
||||
theRecycler->RecycleToken(aToken);
|
||||
CToken* theToken=theAllocator->CreateTokenOfType(eToken_text,eHTMLTag_text,temp);
|
||||
IF_FREE(aToken);
|
||||
aToken=theToken;
|
||||
}
|
||||
#endif
|
||||
AddToken(aToken,result,&mTokenDeque,theRecycler);
|
||||
AddToken(aToken,result,&mTokenDeque,theAllocator);
|
||||
}
|
||||
}//if
|
||||
return result;
|
||||
@ -662,12 +651,12 @@ nsresult nsHTMLTokenizer::ConsumeEntity(PRUnichar aChar,CToken*& aToken,nsScanne
|
||||
* @return new token or null
|
||||
*/
|
||||
nsresult nsHTMLTokenizer::ConsumeWhitespace(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner) {
|
||||
CTokenRecycler* theRecycler=(CTokenRecycler*)GetTokenRecycler();
|
||||
aToken = theRecycler->CreateTokenOfType(eToken_whitespace,eHTMLTag_whitespace);
|
||||
nsTokenAllocator* theAllocator=this->GetTokenAllocator();
|
||||
aToken = theAllocator->CreateTokenOfType(eToken_whitespace,eHTMLTag_whitespace);
|
||||
nsresult result=NS_OK;
|
||||
if(aToken) {
|
||||
result=aToken->Consume(aChar,aScanner,mParseMode);
|
||||
AddToken(aToken,result,&mTokenDeque,theRecycler);
|
||||
AddToken(aToken,result,&mTokenDeque,theAllocator);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -683,12 +672,12 @@ nsresult nsHTMLTokenizer::ConsumeWhitespace(PRUnichar aChar,CToken*& aToken,nsSc
|
||||
* @return new token or null
|
||||
*/
|
||||
nsresult nsHTMLTokenizer::ConsumeComment(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner){
|
||||
CTokenRecycler* theRecycler=(CTokenRecycler*)GetTokenRecycler();
|
||||
aToken = theRecycler->CreateTokenOfType(eToken_comment,eHTMLTag_comment);
|
||||
nsTokenAllocator* theAllocator=this->GetTokenAllocator();
|
||||
aToken = theAllocator->CreateTokenOfType(eToken_comment,eHTMLTag_comment);
|
||||
nsresult result=NS_OK;
|
||||
if(aToken) {
|
||||
result=aToken->Consume(aChar,aScanner,mParseMode);
|
||||
AddToken(aToken,result,&mTokenDeque,theRecycler);
|
||||
AddToken(aToken,result,&mTokenDeque,theAllocator);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -705,20 +694,20 @@ nsresult nsHTMLTokenizer::ConsumeComment(PRUnichar aChar,CToken*& aToken,nsScann
|
||||
*/
|
||||
nsresult nsHTMLTokenizer::ConsumeText(const nsString& aString,CToken*& aToken,nsScanner& aScanner){
|
||||
nsresult result=NS_OK;
|
||||
CTokenRecycler* theRecycler=(CTokenRecycler*)GetTokenRecycler();
|
||||
aToken=theRecycler->CreateTokenOfType(eToken_text,eHTMLTag_text,aString);
|
||||
nsTokenAllocator* theAllocator=this->GetTokenAllocator();
|
||||
aToken=theAllocator->CreateTokenOfType(eToken_text,eHTMLTag_text,aString);
|
||||
if(aToken) {
|
||||
PRUnichar ch=0;
|
||||
result=aToken->Consume(ch,aScanner,mParseMode);
|
||||
if(!NS_SUCCEEDED(result)) {
|
||||
nsString& temp=aToken->GetStringValueXXX();
|
||||
if(0==temp.Length()){
|
||||
theRecycler->RecycleToken(aToken);
|
||||
IF_FREE(aToken);
|
||||
aToken = nsnull;
|
||||
}
|
||||
else result=NS_OK;
|
||||
}
|
||||
AddToken(aToken,result,&mTokenDeque,theRecycler);
|
||||
AddToken(aToken,result,&mTokenDeque,theAllocator);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -741,19 +730,19 @@ nsresult nsHTMLTokenizer::ConsumeSpecialMarkup(PRUnichar aChar,CToken*& aToken,n
|
||||
theBuffer.Mid(theBufCopy,aScanner.GetOffset(),20);
|
||||
theBufCopy.ToUpperCase();
|
||||
PRInt32 theIndex=theBufCopy.Find("DOCTYPE");
|
||||
CTokenRecycler* theRecycler=(CTokenRecycler*)GetTokenRecycler();
|
||||
nsTokenAllocator* theAllocator=this->GetTokenAllocator();
|
||||
|
||||
if(theIndex==kNotFound) {
|
||||
if('['==theBufCopy.CharAt(0))
|
||||
aToken = theRecycler->CreateTokenOfType(eToken_cdatasection,eHTMLTag_comment);
|
||||
else aToken = theRecycler->CreateTokenOfType(eToken_comment,eHTMLTag_comment);
|
||||
aToken = theAllocator->CreateTokenOfType(eToken_cdatasection,eHTMLTag_comment);
|
||||
else aToken = theAllocator->CreateTokenOfType(eToken_comment,eHTMLTag_comment);
|
||||
}
|
||||
else
|
||||
aToken = theRecycler->CreateTokenOfType(eToken_doctypeDecl,eHTMLTag_markupDecl);
|
||||
aToken = theAllocator->CreateTokenOfType(eToken_doctypeDecl,eHTMLTag_markupDecl);
|
||||
|
||||
if(aToken) {
|
||||
result=aToken->Consume(aChar,aScanner,mParseMode);
|
||||
AddToken(aToken,result,&mTokenDeque,theRecycler);
|
||||
AddToken(aToken,result,&mTokenDeque,theAllocator);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -768,12 +757,12 @@ nsresult nsHTMLTokenizer::ConsumeSpecialMarkup(PRUnichar aChar,CToken*& aToken,n
|
||||
* @return error code
|
||||
*/
|
||||
nsresult nsHTMLTokenizer::ConsumeNewline(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner){
|
||||
CTokenRecycler* theRecycler=(CTokenRecycler*)GetTokenRecycler();
|
||||
aToken=theRecycler->CreateTokenOfType(eToken_newline,eHTMLTag_newline);
|
||||
nsTokenAllocator* theAllocator=this->GetTokenAllocator();
|
||||
aToken=theAllocator->CreateTokenOfType(eToken_newline,eHTMLTag_newline);
|
||||
nsresult result=NS_OK;
|
||||
if(aToken) {
|
||||
result=aToken->Consume(aChar,aScanner,mParseMode);
|
||||
AddToken(aToken,result,&mTokenDeque,theRecycler);
|
||||
AddToken(aToken,result,&mTokenDeque,theAllocator);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -789,12 +778,12 @@ nsresult nsHTMLTokenizer::ConsumeNewline(PRUnichar aChar,CToken*& aToken,nsScann
|
||||
* @return error code
|
||||
*/
|
||||
nsresult nsHTMLTokenizer::ConsumeProcessingInstruction(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner){
|
||||
CTokenRecycler* theRecycler=(CTokenRecycler*)GetTokenRecycler();
|
||||
aToken=theRecycler->CreateTokenOfType(eToken_instruction,eHTMLTag_unknown);
|
||||
nsTokenAllocator* theAllocator=this->GetTokenAllocator();
|
||||
aToken=theAllocator->CreateTokenOfType(eToken_instruction,eHTMLTag_unknown);
|
||||
nsresult result=NS_OK;
|
||||
if(aToken) {
|
||||
result=aToken->Consume(aChar,aScanner,mParseMode);
|
||||
AddToken(aToken,result,&mTokenDeque,theRecycler);
|
||||
AddToken(aToken,result,&mTokenDeque,theAllocator);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -61,10 +61,10 @@ public:
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual nsresult WillTokenize(PRBool aIsFinalChunk);
|
||||
virtual nsresult WillTokenize(PRBool aIsFinalChunk,nsTokenAllocator* aTokenAllocator);
|
||||
virtual nsresult ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens);
|
||||
virtual nsresult DidTokenize(PRBool aIsFinalChunk);
|
||||
virtual nsITokenRecycler* GetTokenRecycler(void);
|
||||
virtual nsTokenAllocator* GetTokenAllocator(void);
|
||||
|
||||
virtual CToken* PushTokenFront(CToken* theToken);
|
||||
virtual CToken* PushToken(CToken* theToken);
|
||||
@ -74,7 +74,6 @@ public:
|
||||
virtual PRInt32 GetCount(void);
|
||||
|
||||
virtual void PrependTokens(nsDeque& aDeque);
|
||||
static void FreeTokenRecycler(void);
|
||||
|
||||
protected:
|
||||
|
||||
@ -93,15 +92,16 @@ protected:
|
||||
|
||||
virtual void RecordTrailingContent(CStartToken* aStartToken,nsScanner& aScanner);
|
||||
|
||||
static void AddToken(CToken*& aToken,nsresult aResult,nsDeque* aDeque,CTokenRecycler* aRecycler);
|
||||
static void AddToken(CToken*& aToken,nsresult aResult,nsDeque* aDeque,nsTokenAllocator* aTokenAllocator);
|
||||
|
||||
nsDeque mTokenDeque;
|
||||
PRBool mDoXMLEmptyTags;
|
||||
PRInt32 mParseMode;
|
||||
eParserDocType mDocType;
|
||||
PRBool mRecordTrailingContent;
|
||||
eParserCommands mParserCommand; //tells us to viewcontent/viewsource/viewerrors...
|
||||
nsAutoString mScratch;
|
||||
nsDeque mTokenDeque;
|
||||
PRBool mDoXMLEmptyTags;
|
||||
PRInt32 mParseMode;
|
||||
eParserDocType mDocType;
|
||||
PRBool mRecordTrailingContent;
|
||||
eParserCommands mParserCommand; //tells us to viewcontent/viewsource/viewerrors...
|
||||
nsAutoString mScratch;
|
||||
nsTokenAllocator* mTokenAllocator;
|
||||
};
|
||||
|
||||
extern NS_HTMLPARS nsresult NS_NewHTMLTokenizer( nsITokenizer** aInstancePtrResult,
|
||||
|
@ -134,7 +134,7 @@ CStartToken::CStartToken(const nsString& aName,eHTMLTags aTag) : CHTMLToken(aNam
|
||||
void CStartToken::Reinitialize(PRInt32 aTag, const nsString& aString){
|
||||
CToken::Reinitialize(aTag,aString);
|
||||
mAttributed=PR_FALSE;
|
||||
mUseCount=0; //assume recycling is needed by default.
|
||||
mUseCount=1;
|
||||
mEmpty=PR_FALSE;
|
||||
mOrigin=-1;
|
||||
mTrailingContent.Truncate();
|
||||
@ -1134,6 +1134,7 @@ nsresult CNewlineToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMo
|
||||
* @return
|
||||
*/
|
||||
CAttributeToken::CAttributeToken() : CHTMLToken(eHTMLTag_unknown) {
|
||||
mLastAttribute=PR_FALSE;
|
||||
mHasEqualWithoutValue=PR_FALSE;
|
||||
}
|
||||
|
||||
@ -1401,8 +1402,14 @@ nsresult CAttributeToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 a
|
||||
if(result==kBadStringLiteral) {
|
||||
result=ConsumeAttributeValueText(aChar,mTextValue,aScanner);
|
||||
}
|
||||
if(!aRetainWhitespace)
|
||||
// According to spec. we ( who? ) should ignore linefeeds. But look,
|
||||
// even the carriage return was getting stripped ( wonder why! ) -
|
||||
// Ref. to bug 15204. Okay, so the spec. told us to ignore linefeeds,
|
||||
// bug then what about bug 47535 ? Should we preserve everything then?
|
||||
// Well, let's make it so! Commenting out the next two lines..
|
||||
/*if(!aRetainWhitespace)
|
||||
mTextValue.StripChars("\r\n"); //per the HTML spec, ignore linefeeds...
|
||||
*/
|
||||
}
|
||||
else if(kGreaterThan==aChar){
|
||||
mHasEqualWithoutValue=PR_TRUE;
|
||||
|
@ -279,6 +279,7 @@ class CAttributeToken: public CHTMLToken {
|
||||
CAttributeToken();
|
||||
CAttributeToken(const nsString& aString);
|
||||
CAttributeToken(const nsString& aKey, const nsString& aString);
|
||||
~CAttributeToken() { mTextKey.SetCapacity(0);}
|
||||
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
|
||||
virtual const char* GetClassName(void);
|
||||
virtual PRInt32 GetTokenType(void);
|
||||
|
@ -143,7 +143,7 @@ class nsIDTD : public nsISupports {
|
||||
NS_IMETHOD GetTokenizer(nsITokenizer*& aTokenizer)=0;
|
||||
|
||||
|
||||
virtual nsITokenRecycler* GetTokenRecycler(void)=0;
|
||||
virtual nsTokenAllocator* GetTokenAllocator(void)=0;
|
||||
|
||||
/**
|
||||
* If the parse process gets interrupted midway, this method is called by the
|
||||
|
@ -155,6 +155,12 @@ class nsIParserNode : public nsISupports {
|
||||
*/
|
||||
virtual void GetSource(nsString& aString)=0;
|
||||
|
||||
/** Release all the objects you're holding
|
||||
* @update harishd 08/02/00
|
||||
* @return void
|
||||
*/
|
||||
virtual nsresult ReleaseAll()=0;
|
||||
|
||||
/*
|
||||
* Get and set the ID attribute atom for this node.
|
||||
* See http://www.w3.org/TR/1998/REC-xml-19980210#sec-attribute-types
|
||||
|
@ -37,20 +37,11 @@
|
||||
class CToken;
|
||||
class nsScanner;
|
||||
class nsDeque;
|
||||
class nsTokenAllocator;
|
||||
|
||||
#define NS_ITOKENIZER_IID \
|
||||
{0xe4238ddc, 0x9eb6, 0x11d2, {0xba, 0xa5, 0x0, 0x10, 0x4b, 0x98, 0x3f, 0xd4 }}
|
||||
|
||||
|
||||
/***************************************************************
|
||||
Notes:
|
||||
***************************************************************/
|
||||
|
||||
class nsITokenRecycler {
|
||||
public:
|
||||
virtual void RecycleToken(CToken* aToken)=0;
|
||||
};
|
||||
|
||||
/**
|
||||
* This interface is used as a callback to objects interested
|
||||
* in observing the token stream created from the parse process.
|
||||
@ -67,10 +58,10 @@ public:
|
||||
class nsITokenizer : public nsISupports {
|
||||
public:
|
||||
|
||||
virtual nsresult WillTokenize(PRBool aIsFinalChunk)=0;
|
||||
virtual nsresult WillTokenize(PRBool aIsFinalChunk,nsTokenAllocator* aTokenAllocator)=0;
|
||||
virtual nsresult ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens)=0;
|
||||
virtual nsresult DidTokenize(PRBool aIsFinalChunk)=0;
|
||||
virtual nsITokenRecycler* GetTokenRecycler(void)=0;
|
||||
virtual nsTokenAllocator* GetTokenAllocator(void)=0;
|
||||
|
||||
virtual CToken* PushTokenFront(CToken* aToken)=0;
|
||||
virtual CToken* PushToken(CToken* aToken)=0;
|
||||
|
@ -2387,7 +2387,7 @@ PRBool nsParser::WillTokenize(PRBool aIsFinalChunk){
|
||||
nsITokenizer* theTokenizer=0;
|
||||
nsresult result=mParserContext->mDTD->GetTokenizer(theTokenizer);
|
||||
if (theTokenizer) {
|
||||
result = theTokenizer->WillTokenize(aIsFinalChunk);
|
||||
result = theTokenizer->WillTokenize(aIsFinalChunk,&mTokenAllocator);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -411,6 +411,7 @@ protected:
|
||||
nsString mCommandStr;
|
||||
|
||||
nsParserBundle* mBundle;
|
||||
nsTokenAllocator mTokenAllocator;
|
||||
|
||||
public:
|
||||
MOZ_TIMER_DECLARE(mParseTime)
|
||||
|
@ -208,9 +208,6 @@ nsParserModule::Shutdown()
|
||||
if (mInitialized) {
|
||||
nsHTMLTags::ReleaseTable();
|
||||
nsHTMLEntities::ReleaseTable();
|
||||
nsHTMLTokenizer::FreeTokenRecycler();
|
||||
nsXMLTokenizer::FreeTokenRecycler();
|
||||
nsExpatTokenizer::FreeTokenRecycler();
|
||||
nsDTDContext::ReleaseGlobalObjects();
|
||||
nsParser::FreeSharedObjects();
|
||||
mInitialized = PR_FALSE;
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "nshtmlpars.h"
|
||||
#include "nsITokenizer.h"
|
||||
#include "nsDTDUtils.h"
|
||||
|
||||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
@ -45,7 +46,7 @@ const nsString& GetEmptyString() {
|
||||
* @param aToken -- token to init internal token
|
||||
* @return
|
||||
*/
|
||||
nsCParserNode::nsCParserNode(CToken* aToken,PRInt32 aLineNumber,nsITokenRecycler* aRecycler):
|
||||
nsCParserNode::nsCParserNode(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator):
|
||||
nsIParserNode() {
|
||||
NS_INIT_REFCNT();
|
||||
MOZ_COUNT_CTOR(nsCParserNode);
|
||||
@ -55,17 +56,18 @@ nsCParserNode::nsCParserNode(CToken* aToken,PRInt32 aLineNumber,nsITokenRecycler
|
||||
mAttributes=0;
|
||||
mLineNumber=aLineNumber;
|
||||
mToken=aToken;
|
||||
mRecycler=aRecycler;
|
||||
IF_HOLD(mToken);
|
||||
mTokenAllocator=aTokenAllocator;
|
||||
mUseCount=0;
|
||||
mSkippedContent=0;
|
||||
mGenericState=PR_FALSE;
|
||||
}
|
||||
|
||||
static void RecycleTokens(nsITokenRecycler* aRecycler,nsDeque& aDeque) {
|
||||
static void RecycleTokens(nsTokenAllocator* aTokenAllocator,nsDeque& aDeque) {
|
||||
CToken* theToken=0;
|
||||
if(aRecycler) {
|
||||
if(aTokenAllocator) {
|
||||
while((theToken=(CToken*)aDeque.Pop())){
|
||||
aRecycler->RecycleToken(theToken);
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -79,31 +81,8 @@ static void RecycleTokens(nsITokenRecycler* aRecycler,nsDeque& aDeque) {
|
||||
* @return
|
||||
*/
|
||||
nsCParserNode::~nsCParserNode() {
|
||||
if(mAttributes) {
|
||||
|
||||
//fixed a bug that patrick found, where the attributes deque existed
|
||||
//but was empty. In that case, the attributes deque itself was leaked.
|
||||
//THANKS PATRICK!
|
||||
|
||||
if(mRecycler) {
|
||||
RecycleTokens(mRecycler,*mAttributes);
|
||||
}
|
||||
else {
|
||||
CToken* theToken=(CToken*)mAttributes->Pop();
|
||||
while(theToken){
|
||||
delete theToken;
|
||||
theToken=(CToken*)mAttributes->Pop();
|
||||
}
|
||||
}
|
||||
delete mAttributes;
|
||||
mAttributes=0;
|
||||
}
|
||||
if(mSkippedContent) {
|
||||
delete mSkippedContent;
|
||||
}
|
||||
mSkippedContent=0;
|
||||
|
||||
MOZ_COUNT_DTOR(nsCParserNode);
|
||||
ReleaseAll();
|
||||
}
|
||||
|
||||
|
||||
@ -118,12 +97,13 @@ NS_IMPL_RELEASE(nsCParserNode)
|
||||
* @return
|
||||
*/
|
||||
|
||||
nsresult nsCParserNode::Init(CToken* aToken,PRInt32 aLineNumber,nsITokenRecycler* aRecycler) {
|
||||
nsresult nsCParserNode::Init(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator) {
|
||||
mLineNumber=aLineNumber;
|
||||
mRecycler=aRecycler;
|
||||
mTokenAllocator=aTokenAllocator;
|
||||
if(mAttributes && (mAttributes->GetSize()))
|
||||
RecycleTokens(mRecycler,*mAttributes);
|
||||
RecycleTokens(mTokenAllocator,*mAttributes);
|
||||
mToken=aToken;
|
||||
IF_HOLD(mToken);
|
||||
mGenericState=PR_FALSE;
|
||||
mUseCount=0;
|
||||
if(mSkippedContent) {
|
||||
@ -383,6 +363,38 @@ void nsCParserNode::GetSource(nsString& aString) {
|
||||
aString.AppendWithConversion(">");
|
||||
}
|
||||
|
||||
/** Release all the objects you're holding to.
|
||||
* @update harishd 08/02/00
|
||||
* @return void
|
||||
*/
|
||||
nsresult nsCParserNode::ReleaseAll() {
|
||||
if(mAttributes) {
|
||||
|
||||
//fixed a bug that patrick found, where the attributes deque existed
|
||||
//but was empty. In that case, the attributes deque itself was leaked.
|
||||
//THANKS PATRICK!
|
||||
|
||||
if(mTokenAllocator) {
|
||||
RecycleTokens(mTokenAllocator,*mAttributes);
|
||||
}
|
||||
else {
|
||||
CToken* theToken=(CToken*)mAttributes->Pop();
|
||||
while(theToken){
|
||||
IF_FREE(theToken);
|
||||
theToken=(CToken*)mAttributes->Pop();
|
||||
}
|
||||
}
|
||||
delete mAttributes;
|
||||
mAttributes=0;
|
||||
}
|
||||
if(mSkippedContent) {
|
||||
delete mSkippedContent;
|
||||
}
|
||||
IF_FREE(mToken);
|
||||
mSkippedContent=0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCParserNode::GetIDAttributeAtom(nsIAtom** aResult) const
|
||||
{
|
||||
@ -400,3 +412,4 @@ nsCParserNode::SetIDAttributeAtom(nsIAtom* aID)
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@
|
||||
#include "nsParserCIID.h"
|
||||
#include "nsDeque.h"
|
||||
|
||||
class nsITokenRecycler;
|
||||
class nsTokenAllocator;
|
||||
|
||||
class nsCParserNode : public nsIParserNode {
|
||||
|
||||
@ -59,7 +59,7 @@ class nsCParserNode : public nsIParserNode {
|
||||
* @update gess5/11/98
|
||||
* @param aToken is the token this node "refers" to
|
||||
*/
|
||||
nsCParserNode(CToken* aToken=nsnull,PRInt32 aLineNumber=1,nsITokenRecycler* aRecycler=0);
|
||||
nsCParserNode(CToken* aToken=nsnull,PRInt32 aLineNumber=1,nsTokenAllocator* aTokenAllocator=0);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
@ -71,7 +71,7 @@ class nsCParserNode : public nsIParserNode {
|
||||
* Init
|
||||
* @update gess5/11/98
|
||||
*/
|
||||
virtual nsresult Init(CToken* aToken=nsnull,PRInt32 aLineNumber=1,nsITokenRecycler* aRecycler=0);
|
||||
virtual nsresult Init(CToken* aToken=nsnull,PRInt32 aLineNumber=1,nsTokenAllocator* aTokenAllocator=0);
|
||||
|
||||
/**
|
||||
* Retrieve the name of the node
|
||||
@ -196,6 +196,12 @@ class nsCParserNode : public nsIParserNode {
|
||||
*/
|
||||
virtual PRBool GetGenericState(void) const {return mGenericState;}
|
||||
virtual void SetGenericState(PRBool aState) {mGenericState=aState;}
|
||||
|
||||
/** Release all the objects you're holding
|
||||
* @update harishd 08/02/00
|
||||
* @return void
|
||||
*/
|
||||
virtual nsresult ReleaseAll();
|
||||
|
||||
PRInt32 mLineNumber;
|
||||
CToken* mToken;
|
||||
@ -205,7 +211,7 @@ class nsCParserNode : public nsIParserNode {
|
||||
PRBool mGenericState;
|
||||
nsCOMPtr<nsIAtom> mIDAttributeAtom;
|
||||
|
||||
nsITokenRecycler* mRecycler;
|
||||
nsTokenAllocator* mTokenAllocator;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -23,7 +23,10 @@
|
||||
#include "nsToken.h"
|
||||
#include "nsScanner.h"
|
||||
|
||||
|
||||
#ifdef MATCH_CTOR_DTOR
|
||||
MOZ_DECL_CTOR_COUNTER(CToken);
|
||||
#endif
|
||||
|
||||
static int TokenCount=0;
|
||||
static int DelTokenCount=0;
|
||||
@ -41,13 +44,25 @@ int CToken::GetTokenCount(){return TokenCount-DelTokenCount;}
|
||||
* @update gess 7/21/98
|
||||
*/
|
||||
CToken::CToken(PRInt32 aTag) : mTextValue() {
|
||||
// Tokens are allocated through the arena ( not heap allocated..yay ).
|
||||
// We, therefore, don't need this macro anymore..
|
||||
#ifdef MATCH_CTOR_DTOR
|
||||
MOZ_COUNT_CTOR(CToken);
|
||||
mTypeID=aTag;
|
||||
#endif
|
||||
mAttrCount=0;
|
||||
TokenCount++;
|
||||
mOrigin=eSource;
|
||||
mUseCount=0;
|
||||
mNewlineCount=0;
|
||||
mTypeID=aTag;
|
||||
mOrigin=eSource;
|
||||
// Note that the use count starts with 1 instead of 0. This
|
||||
// is because of the assumption that any token created is in
|
||||
// use and therefore does not require an explicit addref, or
|
||||
// rather IF_HOLD. This, also, will make sure that tokens created
|
||||
// on the stack do not accidently hit the arena recycler.
|
||||
mUseCount=1;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
TokenCount++;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@ -57,13 +72,26 @@ CToken::CToken(PRInt32 aTag) : mTextValue() {
|
||||
* @param nsString--name of token
|
||||
*/
|
||||
CToken::CToken(const nsString& aName) : mTextValue(aName) {
|
||||
// Tokens are allocated through the arena ( not heap allocated..yay ).
|
||||
// We, therefore, don't need this macro anymore..
|
||||
#ifdef MATCH_CTOR_DTOR
|
||||
MOZ_COUNT_CTOR(CToken);
|
||||
#endif
|
||||
|
||||
mTypeID=0;
|
||||
mAttrCount=0;
|
||||
TokenCount++;
|
||||
mOrigin=eSource;
|
||||
mUseCount=0;
|
||||
mNewlineCount=0;
|
||||
mOrigin=eSource;
|
||||
// Note that the use count starts with 1 instead of 0. This
|
||||
// is because of the assumption that any token created is in
|
||||
// use and therefore does not require an explicit addref, or
|
||||
// rather IF_HOLD. This, also, will make sure that tokens created
|
||||
// on the stack do not accidently hit the arena recycler.
|
||||
mUseCount=1;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
TokenCount++;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@ -73,14 +101,27 @@ CToken::CToken(const nsString& aName) : mTextValue(aName) {
|
||||
* @param aName--char* containing name of token
|
||||
*/
|
||||
CToken::CToken(const char* aName) {
|
||||
// Tokens are allocated through the arena ( not heap allocated..yay ).
|
||||
// We, therefore, don't need this macro anymore..
|
||||
#ifdef MATCH_CTOR_DTOR
|
||||
MOZ_COUNT_CTOR(CToken);
|
||||
mTextValue.AssignWithConversion(aName);
|
||||
#endif
|
||||
|
||||
mTypeID=0;
|
||||
mAttrCount=0;
|
||||
TokenCount++;
|
||||
mOrigin=eSource;
|
||||
mUseCount=0;
|
||||
mNewlineCount=0;
|
||||
mOrigin=eSource;
|
||||
mTextValue.AssignWithConversion(aName);
|
||||
// Note that the use count starts with 1 instead of 0. This
|
||||
// is because of the assumption that any token created is in
|
||||
// use and therefore does not require an explicit addref, or
|
||||
// rather IF_HOLD. This, also, will make sure that tokens created
|
||||
// on the stack do not accidently hit the arena recycler.
|
||||
mUseCount=1;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
TokenCount++;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@ -89,10 +130,39 @@ CToken::CToken(const char* aName) {
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
CToken::~CToken() {
|
||||
// Tokens are allocated through the arena ( not heap allocated..yay ).
|
||||
// We, therefore, don't need this macro anymore..
|
||||
#ifdef MATCH_CTOR_DTOR
|
||||
MOZ_COUNT_DTOR(CToken);
|
||||
#endif
|
||||
DelTokenCount++;
|
||||
mUseCount=0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update harishd 08/01/00
|
||||
* @param aSize -
|
||||
* @param aArena - Allocate memory from this pool.
|
||||
*/
|
||||
void *
|
||||
CToken::operator new (size_t aSize, nsFixedSizeAllocator& anArena)
|
||||
{
|
||||
return (CToken*)anArena.Alloc(aSize);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @update harishd 08/01/00
|
||||
* @param aPtr - The memory that should be recycled/freed.
|
||||
* @param aSize - The size of memory that needs to be freed.
|
||||
*/
|
||||
void
|
||||
CToken::operator delete (void* aPtr,size_t aSize)
|
||||
{
|
||||
nsFixedSizeAllocator::Free(aPtr,aSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets called when a token is about to be reused
|
||||
@ -107,11 +177,16 @@ void CToken::Reinitialize(PRInt32 aTag, const nsString& aString){
|
||||
mTextValue.Truncate(0);
|
||||
else mTextValue=aString;
|
||||
mAttrCount=0;
|
||||
mTypeID=aTag;
|
||||
mAttrCount=0;
|
||||
mOrigin=eSource;
|
||||
mUseCount=0;
|
||||
mNewlineCount=0;
|
||||
mTypeID=aTag;
|
||||
mOrigin=eSource;
|
||||
// Note that the use count starts with 1 instead of 0. This
|
||||
// is because of the assumption that any token created is in
|
||||
// use and therefore does not require an explicit addref, or
|
||||
// rather IF_HOLD. This, also, will make sure that tokens created
|
||||
// on the stack do not accidently hit the arena recycler.
|
||||
mUseCount=1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -44,11 +44,11 @@
|
||||
#include <iostream.h>
|
||||
#include "nsError.h"
|
||||
#include "nsFileSpec.h"
|
||||
#include "nsFixedSizeAllocator.h"
|
||||
|
||||
|
||||
class nsScanner;
|
||||
|
||||
|
||||
/**
|
||||
* Token objects represent sequences of characters as they
|
||||
* are consumed from the input stream (URL). While they're
|
||||
@ -63,6 +63,35 @@ class CToken {
|
||||
|
||||
enum eTokenOrigin {eSource,eResidualStyle};
|
||||
|
||||
/**
|
||||
* Use the arena to allocate memory
|
||||
* @update harishd 08/02/00
|
||||
* @param aSize - Allocation size.
|
||||
* @param anArena - Used for allocating memory.
|
||||
*/
|
||||
void* operator new(size_t aSize,nsFixedSizeAllocator& anArena);
|
||||
|
||||
/**
|
||||
* Free up the memory in the arena.
|
||||
* @update harishd 08/02/00
|
||||
* @param aPtr - Memory that's to be freed.
|
||||
*/
|
||||
void operator delete(void* aPtr,size_t aSize);
|
||||
|
||||
/**
|
||||
* Make a note on number of times you have been referenced
|
||||
* @update harishd 08/02/00
|
||||
*/
|
||||
void AddRef() { mUseCount++; }
|
||||
|
||||
/**
|
||||
* Free yourself if no one is holding you.
|
||||
* @update harishd 08/02/00
|
||||
*/
|
||||
void Release() {
|
||||
if(--mUseCount==0)
|
||||
delete this;
|
||||
}
|
||||
/**
|
||||
* Default constructor
|
||||
* @update gess7/21/98
|
||||
@ -214,13 +243,14 @@ class CToken {
|
||||
static int GetTokenCount();
|
||||
|
||||
eTokenOrigin mOrigin;
|
||||
PRInt32 mUseCount;
|
||||
PRInt32 mNewlineCount;
|
||||
|
||||
protected:
|
||||
|
||||
PRInt32 mTypeID;
|
||||
PRInt16 mAttrCount;
|
||||
nsString mTextValue;
|
||||
PRInt32 mUseCount;
|
||||
};
|
||||
|
||||
|
||||
|
@ -352,7 +352,7 @@ NS_IMETHODIMP CValidDTD::HandleToken(CToken* aToken,nsIParser* aParser) {
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsITokenRecycler* CValidDTD::GetTokenRecycler(void){
|
||||
nsTokenAllocator* CValidDTD::GetTokenAllocator(void){
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -216,7 +216,7 @@ class CValidDTD : public nsIDTD {
|
||||
* @update gess8/4/98
|
||||
* @return ptr to recycler (or null)
|
||||
*/
|
||||
virtual nsITokenRecycler* GetTokenRecycler(void);
|
||||
virtual nsTokenAllocator* GetTokenAllocator(void);
|
||||
|
||||
/**
|
||||
* Use this id you want to stop the building content model
|
||||
|
@ -75,8 +75,6 @@ static NS_DEFINE_IID(kIDTDIID, NS_IDTD_IID);
|
||||
static NS_DEFINE_IID(kClassIID, NS_VIEWSOURCE_HTML_IID);
|
||||
static int gErrorThreshold = 10;
|
||||
|
||||
static CTokenRecycler* gTokenRecycler=0;
|
||||
|
||||
//#define rickgdebug
|
||||
#ifdef rickgdebug
|
||||
#include <fstream.h>
|
||||
@ -228,6 +226,7 @@ CViewSourceHTML::CViewSourceHTML() : mTags(), mErrors() {
|
||||
mTokenizer=0;
|
||||
mDocType=eHTML3Text;
|
||||
mValidator=0;
|
||||
mHasOpenRoot=PR_FALSE;
|
||||
|
||||
//set this to 1 if you want to see errors in your HTML markup.
|
||||
char* theEnvString = PR_GetEnv("MOZ_VALIDATE_HTML");
|
||||
@ -348,14 +347,6 @@ nsresult CViewSourceHTML::WillBuildModel( const CParserContext& aParserContext,
|
||||
(*gDumpFile) << "<viewsource xmlns=\"viewsource\">" << endl;
|
||||
#endif
|
||||
|
||||
//now let's automatically open the root container...
|
||||
CToken theToken("viewsource");
|
||||
nsCParserNode theNode(&theToken,0);
|
||||
|
||||
CAttributeToken *theAttr=new CAttributeToken(NS_ConvertToString("xmlns"), NS_ConvertToString("http://www.mozilla.org/viewsource"));
|
||||
if(theAttr)
|
||||
theNode.AddAttribute(theAttr);
|
||||
mSink->OpenContainer(theNode);
|
||||
}
|
||||
|
||||
|
||||
@ -385,25 +376,40 @@ NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aToke
|
||||
|
||||
nsITokenizer* oldTokenizer=mTokenizer;
|
||||
mTokenizer=aTokenizer;
|
||||
gTokenRecycler=(CTokenRecycler*)mTokenizer->GetTokenRecycler();
|
||||
|
||||
if(gTokenRecycler) {
|
||||
|
||||
while(NS_SUCCEEDED(result)){
|
||||
CToken* theToken=mTokenizer->PopToken();
|
||||
if(theToken) {
|
||||
result=HandleToken(theToken,aParser);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
gTokenRecycler->RecycleToken(theToken);
|
||||
}
|
||||
else if(NS_ERROR_HTMLPARSER_BLOCK!=result){
|
||||
mTokenizer->PushTokenFront(theToken);
|
||||
}
|
||||
// theRootDTD->Verify(kEmptyString,aParser);
|
||||
}
|
||||
else break;
|
||||
}//while
|
||||
if(!mHasOpenRoot) {
|
||||
//now let's automatically open the root container...
|
||||
CToken theToken("viewsource");
|
||||
nsCParserNode theNode(&theToken,0);
|
||||
|
||||
CAttributeToken *theAttr=nsnull;
|
||||
nsTokenAllocator* theAllocator=mTokenizer->GetTokenAllocator();
|
||||
if(theAllocator) {
|
||||
theAttr=(CAttributeToken*)theAllocator->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown,NS_ConvertToString("http://www.mozilla.org/viewsource"));
|
||||
nsString& theKey=theAttr->GetKey();
|
||||
theKey=NS_ConvertToString("xmlns");
|
||||
}
|
||||
if(theAttr)
|
||||
theNode.AddAttribute(theAttr);
|
||||
result=mSink->OpenContainer(theNode);
|
||||
if(NS_SUCCEEDED(result)) mHasOpenRoot=PR_TRUE;
|
||||
}
|
||||
|
||||
while(NS_SUCCEEDED(result)){
|
||||
CToken* theToken=mTokenizer->PopToken();
|
||||
if(theToken) {
|
||||
result=HandleToken(theToken,aParser);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
else if(NS_ERROR_HTMLPARSER_BLOCK!=result){
|
||||
mTokenizer->PushTokenFront(theToken);
|
||||
}
|
||||
// theRootDTD->Verify(kEmptyString,aParser);
|
||||
}
|
||||
else break;
|
||||
}//while
|
||||
|
||||
mTokenizer=oldTokenizer;
|
||||
}
|
||||
else result=NS_ERROR_HTMLPARSER_BADTOKENIZER;
|
||||
@ -493,12 +499,12 @@ NS_IMETHODIMP CViewSourceHTML::DidBuildModel(nsresult anErrorCode,PRBool aNotify
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsITokenRecycler* CViewSourceHTML::GetTokenRecycler(void){
|
||||
nsTokenAllocator* CViewSourceHTML::GetTokenAllocator(void){
|
||||
nsITokenizer* theTokenizer=0;
|
||||
nsresult result=GetTokenizer(theTokenizer);
|
||||
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
return theTokenizer->GetTokenRecycler();
|
||||
return theTokenizer->GetTokenAllocator();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -989,7 +995,6 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser) {
|
||||
result=theService->Notify(theTag,theContext.mTokenNode,theDocID, NS_ConvertToString(kViewSourceCommand), mParser);
|
||||
}
|
||||
}
|
||||
theContext.mTokenNode.Init(0,0,gTokenRecycler); //now recycle.
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1067,9 +1072,7 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser) {
|
||||
result=NS_OK;
|
||||
}//switch
|
||||
|
||||
while(theContext.mTokenNode.PopAttributeToken()){
|
||||
//dump the attributes since they're on the stack...
|
||||
}
|
||||
theContext.mTokenNode.ReleaseAll();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ class CViewSourceHTML: public nsIDTD {
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
virtual nsITokenRecycler* GetTokenRecycler(void);
|
||||
virtual nsTokenAllocator* GetTokenAllocator(void);
|
||||
|
||||
/**
|
||||
*
|
||||
@ -279,6 +279,7 @@ protected:
|
||||
nsString mTags;
|
||||
nsString mErrors;
|
||||
PRBool mShowErrors;
|
||||
PRBool mHasOpenRoot;
|
||||
};
|
||||
|
||||
extern NS_HTMLPARS nsresult NS_NewViewSourceHTML(nsIDTD** aInstancePtrResult);
|
||||
|
@ -249,7 +249,7 @@ NS_IMETHODIMP CWellFormedDTD::BuildModel(nsIParser* aParser,nsITokenizer* aToken
|
||||
if(aTokenizer) {
|
||||
nsHTMLTokenizer* oldTokenizer=mTokenizer;
|
||||
mTokenizer=(nsHTMLTokenizer*)aTokenizer;
|
||||
nsITokenRecycler* theRecycler=aTokenizer->GetTokenRecycler();
|
||||
nsTokenAllocator* theAllocator=aTokenizer->GetTokenAllocator();
|
||||
|
||||
while(NS_SUCCEEDED(result)){
|
||||
if(mDTDState!=NS_ERROR_HTMLPARSER_STOPPARSING) {
|
||||
@ -257,7 +257,7 @@ NS_IMETHODIMP CWellFormedDTD::BuildModel(nsIParser* aParser,nsITokenizer* aToken
|
||||
if(theToken) {
|
||||
result=HandleToken(theToken,aParser);
|
||||
if(NS_SUCCEEDED(result) || (NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
theRecycler->RecycleToken(theToken);
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
else {
|
||||
// if(NS_ERROR_HTMLPARSER_BLOCK!=result){
|
||||
@ -321,13 +321,13 @@ NS_IMETHODIMP CWellFormedDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifyS
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsITokenRecycler* CWellFormedDTD::GetTokenRecycler(void){
|
||||
nsTokenAllocator* CWellFormedDTD::GetTokenAllocator(void){
|
||||
nsITokenizer* theTokenizer=0;
|
||||
|
||||
nsresult result=GetTokenizer(theTokenizer);
|
||||
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
return theTokenizer->GetTokenRecycler();
|
||||
return theTokenizer->GetTokenAllocator();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -348,8 +348,8 @@ nsresult CWellFormedDTD::Terminate(nsIParser* aParser)
|
||||
nsresult result=NS_OK;
|
||||
|
||||
if(mTokenizer) {
|
||||
nsITokenRecycler* theRecycler=mTokenizer->GetTokenRecycler();
|
||||
if(theRecycler) {
|
||||
nsTokenAllocator* theAllocator=mTokenizer->GetTokenAllocator();
|
||||
if(theAllocator) {
|
||||
eHTMLTokenTypes theType=eToken_unknown;
|
||||
|
||||
mDTDState=NS_ERROR_HTMLPARSER_STOPPARSING;
|
||||
@ -361,7 +361,7 @@ nsresult CWellFormedDTD::Terminate(nsIParser* aParser)
|
||||
if(theType==eToken_error) {
|
||||
result=HandleToken(theToken,aParser);
|
||||
}
|
||||
theRecycler->RecycleToken(theToken);
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
else break;
|
||||
}//while
|
||||
@ -552,7 +552,7 @@ nsresult CWellFormedDTD::HandleLeafToken(CToken* aToken) {
|
||||
|
||||
nsresult result=NS_OK;
|
||||
|
||||
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenRecycler());
|
||||
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenAllocator());
|
||||
result= (mSink)? mSink->AddLeaf(theNode):NS_OK;
|
||||
return result;
|
||||
}
|
||||
@ -575,7 +575,7 @@ nsresult CWellFormedDTD::HandleCommentToken(CToken* aToken) {
|
||||
|
||||
mLineNumber += (aToken->GetStringValueXXX()).CountChar(kNewLine);
|
||||
|
||||
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenRecycler());
|
||||
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenAllocator());
|
||||
result=(mSink)? mSink->AddComment(theNode):NS_OK;
|
||||
|
||||
return result;
|
||||
@ -596,7 +596,7 @@ nsresult CWellFormedDTD::HandleProcessingInstructionToken(CToken* aToken) {
|
||||
|
||||
nsresult result=NS_OK;
|
||||
|
||||
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenRecycler());
|
||||
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenAllocator());
|
||||
result=(mSink)? mSink->AddProcessingInstruction(theNode):NS_OK;
|
||||
return result;
|
||||
}
|
||||
@ -616,7 +616,7 @@ nsresult CWellFormedDTD::HandleStartToken(CToken* aToken) {
|
||||
|
||||
nsresult result=NS_OK;
|
||||
|
||||
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenRecycler());
|
||||
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenAllocator());
|
||||
PRInt16 attrCount=aToken->GetAttributeCount();
|
||||
|
||||
if(0<attrCount){ //go collect the attributes...
|
||||
@ -667,7 +667,7 @@ nsresult CWellFormedDTD::HandleEndToken(CToken* aToken) {
|
||||
|
||||
nsresult result=NS_OK;
|
||||
|
||||
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenRecycler());
|
||||
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenAllocator());
|
||||
result=(mSink)? mSink->CloseContainer(theNode):NS_OK;
|
||||
return result;
|
||||
}
|
||||
@ -689,7 +689,7 @@ nsresult CWellFormedDTD::HandleErrorToken(CToken* aToken) {
|
||||
nsresult result=NS_OK;
|
||||
|
||||
if(mTokenizer) {
|
||||
nsITokenRecycler* theRecycler=mTokenizer->GetTokenRecycler();
|
||||
nsTokenAllocator* theAllocator=mTokenizer->GetTokenAllocator();
|
||||
|
||||
// Cycle through the remaining tokens in the token stream and handle them
|
||||
// These tokens were added so that content objects for the error message
|
||||
@ -715,7 +715,7 @@ nsresult CWellFormedDTD::HandleErrorToken(CToken* aToken) {
|
||||
// Do nothing
|
||||
break;
|
||||
}
|
||||
if(theRecycler) theRecycler->RecycleToken(token);
|
||||
IF_FREE(token);
|
||||
}
|
||||
else
|
||||
break;
|
||||
@ -758,7 +758,7 @@ nsresult CWellFormedDTD::HandleDocTypeDeclToken(CToken* aToken) {
|
||||
|
||||
nsresult result=NS_OK;
|
||||
|
||||
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenRecycler());
|
||||
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenAllocator());
|
||||
result = (mSink)? mSink->AddDocTypeDecl(theNode, 0):NS_OK;
|
||||
return result;
|
||||
}
|
||||
|
@ -201,7 +201,7 @@ class CWellFormedDTD : public nsIDTD {
|
||||
* @update gess8/4/98
|
||||
* @return ptr to recycler (or null)
|
||||
*/
|
||||
virtual nsITokenRecycler* GetTokenRecycler(void);
|
||||
virtual nsTokenAllocator* GetTokenAllocator(void);
|
||||
|
||||
/**
|
||||
* Use this id you want to stop the building content model
|
||||
|
@ -398,7 +398,7 @@ nsresult nsXIFDTD::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsITok
|
||||
|
||||
if(mTokenizer) {
|
||||
|
||||
mTokenRecycler=(CTokenRecycler*)mTokenizer->GetTokenRecycler();
|
||||
mTokenAllocator=mTokenizer->GetTokenAllocator();
|
||||
result=mXIFContext->GetNodeRecycler(mNodeRecycler);
|
||||
|
||||
if(NS_FAILED(result)) return result;
|
||||
@ -490,8 +490,6 @@ nsresult nsXIFDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
||||
result=WillHandleToken(aToken,theType);
|
||||
|
||||
if(result==NS_OK) {
|
||||
|
||||
aToken->mUseCount=0; //assume every token coming into this system needs recycling.
|
||||
|
||||
switch(theType) {
|
||||
case eToken_text:
|
||||
@ -520,13 +518,10 @@ nsresult nsXIFDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
||||
*/
|
||||
|
||||
nsresult nsXIFDTD::DidHandleToken(CToken* aToken, nsresult aResult) {
|
||||
NS_ASSERTION(mTokenRecycler!=nsnull,"We need a recycler");
|
||||
NS_ASSERTION(mTokenAllocator!=nsnull,"We need a allocator");
|
||||
nsresult result=aResult;
|
||||
if(NS_SUCCEEDED(result) || (NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
if(aToken) {
|
||||
if(0>=aToken->mUseCount)
|
||||
if(mTokenRecycler) mTokenRecycler->RecycleToken(aToken);
|
||||
}
|
||||
IF_FREE(aToken);
|
||||
}
|
||||
else if(result==NS_ERROR_HTMLPARSER_STOPPARSING)
|
||||
mDTDState=result;
|
||||
@ -614,7 +609,7 @@ nsresult nsXIFDTD::HandleStartToken(CToken* aToken) {
|
||||
|
||||
//Begin by gathering up attributes...
|
||||
nsCParserNode* node=mNodeRecycler->CreateNode();
|
||||
node->Init(aToken,mLineNumber,mTokenRecycler);
|
||||
node->Init(aToken,mLineNumber,mTokenAllocator);
|
||||
|
||||
PRInt16 attrCount=aToken->GetAttributeCount();
|
||||
nsresult result=(0==attrCount) ? NS_OK : CollectAttributes(*node,attrCount);
|
||||
@ -655,7 +650,7 @@ nsresult nsXIFDTD::HandleStartToken(CToken* aToken) {
|
||||
}
|
||||
}
|
||||
|
||||
mNodeRecycler->RecycleNode(node,mTokenRecycler);
|
||||
mNodeRecycler->RecycleNode(node);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -720,7 +715,7 @@ nsresult nsXIFDTD::HandleContainer(nsIParserNode& aNode) {
|
||||
theTagID=nsHTMLTags::LookupTag(theTagName);
|
||||
|
||||
theNode->mToken->Reinitialize(theTagID,theTagName);
|
||||
theNode->Init(theNode->mToken,0,mTokenRecycler);
|
||||
theNode->Init(theNode->mToken,0,mTokenAllocator);
|
||||
}
|
||||
mXIFContext->Push(&aNode);
|
||||
}
|
||||
@ -810,8 +805,8 @@ nsresult nsXIFDTD::HandleCommentToken(CToken* aToken, nsIParserNode& aNode) {
|
||||
eHTMLTokenTypes type=(eHTMLTokenTypes)aToken->GetTokenType();
|
||||
|
||||
if(type==eToken_start) {
|
||||
nsITokenRecycler* recycler=(mTokenizer)? mTokenizer->GetTokenRecycler():nsnull;
|
||||
if(recycler) {
|
||||
nsTokenAllocator* allocator=(mTokenizer)? mTokenizer->GetTokenAllocator():nsnull;
|
||||
if(allocator) {
|
||||
nsAutoString fragment;
|
||||
PRBool done=PR_FALSE;
|
||||
PRBool inContent=PR_FALSE;
|
||||
@ -838,7 +833,7 @@ nsresult nsXIFDTD::HandleCommentToken(CToken* aToken, nsIParserNode& aNode) {
|
||||
else {
|
||||
if(inContent) comment.Append(fragment);
|
||||
}
|
||||
recycler->RecycleToken(token);
|
||||
IF_FREE(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -866,7 +861,7 @@ nsresult nsXIFDTD::HandleAttributeToken(CToken* aToken,nsIParserNode& aNode) {
|
||||
PRBool hasValue=GetAttributePair(aNode,theKey,theValue);
|
||||
|
||||
if(hasValue) {
|
||||
CToken* attribute = mTokenRecycler->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown,theValue);
|
||||
CToken* attribute = mTokenAllocator->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown,theValue);
|
||||
nsString& key=((CAttributeToken*)attribute)->GetKey();
|
||||
key=theKey; // set the new key on the attribute..
|
||||
thePeekNode->AddAttribute(attribute);
|
||||
@ -1067,7 +1062,7 @@ nsresult nsXIFDTD::CloseContainer(const nsIParserNode& aNode)
|
||||
if(IsHTMLContainer(theTag) && theTag!=eHTMLTag_unknown) {
|
||||
result=mSink->CloseContainer(aNode);
|
||||
}
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
mNodeRecycler->RecycleNode(theNode);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -1140,13 +1135,13 @@ nsresult nsXIFDTD::GetTokenizer(nsITokenizer*& aTokenizer) {
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsITokenRecycler* nsXIFDTD::GetTokenRecycler(void){
|
||||
nsTokenAllocator* nsXIFDTD::GetTokenAllocator(void){
|
||||
nsITokenizer* theTokenizer=0;
|
||||
|
||||
nsresult result=GetTokenizer(theTokenizer);
|
||||
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
return theTokenizer->GetTokenRecycler();
|
||||
return theTokenizer->GetTokenAllocator();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -1349,7 +1344,7 @@ nsresult nsXIFDTD::ProcessEntityTag(const nsIParserNode& aNode)
|
||||
entity->Reinitialize(eHTMLTag_text,scratch); // Covert type to text and set the translated value.
|
||||
}
|
||||
}
|
||||
((nsCParserNode&)aNode).Init(entity,mLineNumber,mTokenRecycler);
|
||||
((nsCParserNode&)aNode).Init(entity,mLineNumber,mTokenAllocator);
|
||||
}
|
||||
result=mSink->AddLeaf(aNode);
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ class nsITokenizer;
|
||||
class nsDTDContext;
|
||||
class nsEntryStack;
|
||||
class nsCParserNode;
|
||||
class CTokenRecycler;
|
||||
class nsTokenAllocator;
|
||||
class CNodeRecycler;
|
||||
|
||||
//*** This enum is used to define the known universe of XIF tags.
|
||||
@ -395,7 +395,7 @@ private:
|
||||
* @update gess8/4/98
|
||||
* @return ptr to recycler (or null)
|
||||
*/
|
||||
virtual nsITokenRecycler* GetTokenRecycler(void);
|
||||
virtual nsTokenAllocator* GetTokenAllocator(void);
|
||||
|
||||
private:
|
||||
|
||||
@ -443,7 +443,7 @@ protected:
|
||||
nsString mCharset;
|
||||
|
||||
nsDTDContext* mXIFContext;
|
||||
CTokenRecycler* mTokenRecycler;
|
||||
nsTokenAllocator* mTokenAllocator;
|
||||
CNodeRecycler* mNodeRecycler;
|
||||
nsresult mDTDState;
|
||||
|
||||
|
@ -78,11 +78,6 @@ nsresult nsXMLTokenizer::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsXMLTokenizer::FreeTokenRecycler(void) {
|
||||
nsHTMLTokenizer::FreeTokenRecycler();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is defined in nsIParser. It is used to
|
||||
* cause the COM-like construction of an nsParser.
|
||||
@ -151,8 +146,8 @@ nsresult nsXMLTokenizer::ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens)
|
||||
}
|
||||
|
||||
|
||||
nsITokenRecycler* nsXMLTokenizer::GetTokenRecycler(void) {
|
||||
return nsHTMLTokenizer::GetTokenRecycler();
|
||||
nsTokenAllocator* nsXMLTokenizer::GetTokenAllocator(void) {
|
||||
return nsHTMLTokenizer::GetTokenAllocator();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -202,14 +197,14 @@ nsresult ConsumeConditional(nsScanner& aScanner,const nsString& aMatchString,PRB
|
||||
*/
|
||||
nsresult nsXMLTokenizer::ConsumeComment(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner){
|
||||
nsresult result=NS_OK;
|
||||
CTokenRecycler* theRecycler=(CTokenRecycler*)GetTokenRecycler();
|
||||
nsTokenAllocator* theAllocator=this->GetTokenAllocator();
|
||||
|
||||
if(theRecycler) {
|
||||
if(theAllocator) {
|
||||
nsAutoString theEmpty;
|
||||
aToken=theRecycler->CreateTokenOfType(eToken_comment,eHTMLTag_comment,theEmpty);
|
||||
aToken=theAllocator->CreateTokenOfType(eToken_comment,eHTMLTag_comment,theEmpty);
|
||||
if(aToken) {
|
||||
result=aToken->Consume(aChar,aScanner,eDTDMode_strict);
|
||||
AddToken(aToken,result,&mTokenDeque,theRecycler);
|
||||
AddToken(aToken,result,&mTokenDeque,theAllocator);
|
||||
}
|
||||
}
|
||||
|
||||
@ -229,9 +224,9 @@ nsresult nsXMLTokenizer::ConsumeComment(PRUnichar aChar,CToken*& aToken,nsScanne
|
||||
*/
|
||||
nsresult nsXMLTokenizer::ConsumeSpecialMarkup(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner){
|
||||
nsresult result=NS_OK;
|
||||
CTokenRecycler* theRecycler=(CTokenRecycler*)GetTokenRecycler();
|
||||
nsTokenAllocator* theAllocator=this->GetTokenAllocator();
|
||||
|
||||
if(theRecycler) {
|
||||
if(theAllocator) {
|
||||
PRUnichar theChar;
|
||||
aScanner.Peek(theChar);
|
||||
PRBool isComment=PR_TRUE;
|
||||
@ -242,17 +237,17 @@ nsresult nsXMLTokenizer::ConsumeSpecialMarkup(PRUnichar aChar,CToken*& aToken,ns
|
||||
result = ConsumeConditional(aScanner, CDATAString, isCDATA);
|
||||
if (NS_OK == result) {
|
||||
if (isCDATA) {
|
||||
aToken=theRecycler->CreateTokenOfType(eToken_cdatasection,eHTMLTag_unknown,theEmpty);
|
||||
aToken=theAllocator->CreateTokenOfType(eToken_cdatasection,eHTMLTag_unknown,theEmpty);
|
||||
isComment=PR_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(isComment) aToken = theRecycler->CreateTokenOfType(eToken_comment,eHTMLTag_comment,theEmpty);
|
||||
if(isComment) aToken = theAllocator->CreateTokenOfType(eToken_comment,eHTMLTag_comment,theEmpty);
|
||||
|
||||
if(aToken) {
|
||||
result=aToken->Consume(aChar,aScanner,eDTDMode_strict);
|
||||
AddToken(aToken,result,&mTokenDeque,theRecycler);
|
||||
AddToken(aToken,result,&mTokenDeque,theAllocator);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -60,9 +60,7 @@ public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual nsresult ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens);
|
||||
virtual nsITokenRecycler* GetTokenRecycler(void);
|
||||
|
||||
static void FreeTokenRecycler(void);
|
||||
virtual nsTokenAllocator* GetTokenAllocator(void);
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -152,8 +152,6 @@ CNavDTD::CNavDTD() : nsIDTD(),
|
||||
mHasOpenForm=PR_FALSE;
|
||||
mHasOpenMap=PR_FALSE;
|
||||
mHasOpenNoXXX=0;
|
||||
mHeadContext=new nsDTDContext();
|
||||
mBodyContext=new nsDTDContext();
|
||||
mFormContext=0;
|
||||
mMapContext=0;
|
||||
mTempContext=0;
|
||||
@ -166,6 +164,9 @@ CNavDTD::CNavDTD() : nsIDTD(),
|
||||
mRequestedHead=PR_FALSE;
|
||||
mIsFormContainer=PR_FALSE;
|
||||
|
||||
mHeadContext=new nsDTDContext();
|
||||
mBodyContext=new nsDTDContext();
|
||||
|
||||
if(!gHTMLElements) {
|
||||
InitializeElementTable();
|
||||
}
|
||||
@ -205,15 +206,12 @@ void CNavDTD::RecycleNodes(nsEntryStack *aNodeStack) {
|
||||
if(theNode) {
|
||||
|
||||
theNode->mUseCount=0;
|
||||
if(theNode->mToken) {
|
||||
theNode->mToken->mUseCount=0;
|
||||
mTokenRecycler->RecycleToken(theNode->mToken);
|
||||
}
|
||||
|
||||
IF_FREE(theNode->mToken);
|
||||
|
||||
CToken* theToken=0;
|
||||
while((theToken=(CToken*)theNode->PopAttributeToken())){
|
||||
theNode->mToken->mUseCount=0;
|
||||
mTokenRecycler->RecycleToken(theToken);
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
|
||||
mSharedNodes.Push(theNode);
|
||||
@ -413,7 +411,6 @@ nsresult CNavDTD::WillBuildModel( const CParserContext& aParserContext,nsIConte
|
||||
mBodyContext->ResetCounters();
|
||||
mDocType=aParserContext.mDocType;
|
||||
|
||||
mTokenRecycler=0;
|
||||
mStyleHandlingEnabled=PR_TRUE;
|
||||
|
||||
if(aSink && (!mSink)) {
|
||||
@ -456,9 +453,9 @@ nsresult CNavDTD::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsIToke
|
||||
mParser=(nsParser*)aParser;
|
||||
|
||||
if(mTokenizer) {
|
||||
|
||||
mTokenRecycler=(CTokenRecycler*)mTokenizer->GetTokenRecycler();
|
||||
|
||||
mTokenAllocator=mTokenizer->GetTokenAllocator();
|
||||
|
||||
result=mBodyContext->GetNodeRecycler(mNodeRecycler); // Get a copy...
|
||||
|
||||
if(NS_FAILED(result)) return result;
|
||||
@ -469,13 +466,13 @@ nsresult CNavDTD::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsIToke
|
||||
CStartToken* theToken=nsnull;
|
||||
if(ePlainText==mDocType) {
|
||||
//we do this little trick for text files, in both normal and viewsource mode...
|
||||
theToken=(CStartToken*)mTokenRecycler->CreateTokenOfType(eToken_start,eHTMLTag_pre);
|
||||
theToken=(CStartToken*)mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_pre);
|
||||
if(theToken) {
|
||||
mTokenizer->PushTokenFront(theToken);
|
||||
}
|
||||
}
|
||||
//if the content model is empty, then begin by opening <html>...
|
||||
theToken=(CStartToken*)mTokenRecycler->CreateTokenOfType(eToken_start,eHTMLTag_html,NS_ConvertToString("html"));
|
||||
theToken=(CStartToken*)mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_html,NS_ConvertToString("html"));
|
||||
if(theToken) {
|
||||
mTokenizer->PushTokenFront(theToken); //this token should get pushed on the context stack.
|
||||
}
|
||||
@ -528,7 +525,7 @@ nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParse
|
||||
|
||||
mSkipTarget=eHTMLTag_unknown; //clear this in case we were searching earlier.
|
||||
|
||||
CStartToken *theToken=(CStartToken*)mTokenRecycler->CreateTokenOfType(eToken_start,eHTMLTag_body,NS_ConvertToString("body"));
|
||||
CStartToken *theToken=(CStartToken*)mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_body,NS_ConvertToString("body"));
|
||||
mTokenizer->PushTokenFront(theToken); //this token should get pushed on the context stack, don't recycle it
|
||||
result=BuildModel(aParser,mTokenizer,0,aSink);
|
||||
}
|
||||
@ -538,13 +535,13 @@ nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParse
|
||||
if((NS_OK==anErrorCode) && (mBodyContext->GetCount()>0)) {
|
||||
if(mSkipTarget) {
|
||||
CHTMLToken* theEndToken=nsnull;
|
||||
theEndToken=(CHTMLToken*)mTokenRecycler->CreateTokenOfType(eToken_end,mSkipTarget);
|
||||
theEndToken=(CHTMLToken*)mTokenAllocator->CreateTokenOfType(eToken_end,mSkipTarget);
|
||||
if(theEndToken) {
|
||||
result=HandleToken(theEndToken,mParser);
|
||||
}
|
||||
}
|
||||
if(!mBodyContext->mHadDocTypeDecl) {
|
||||
CToken* theDocTypeToken=mTokenRecycler->CreateTokenOfType(eToken_doctypeDecl,eHTMLTag_markupDecl);
|
||||
CToken* theDocTypeToken=mTokenAllocator->CreateTokenOfType(eToken_doctypeDecl,eHTMLTag_markupDecl);
|
||||
if(theDocTypeToken) {
|
||||
nsAutoString theDocTypeStr;
|
||||
theDocTypeStr.AssignWithConversion("<!DOCTYPE \"-//W3C//DTD HTML 3.2 Final//EN\">");
|
||||
@ -574,7 +571,7 @@ nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParse
|
||||
nsEntryStack *theChildStyles=0;
|
||||
nsCParserNode* theNode=(nsCParserNode*)mBodyContext->Pop(theChildStyles);
|
||||
theNode->mUseCount=0;
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
mNodeRecycler->RecycleNode(theNode);
|
||||
if(theChildStyles) {
|
||||
delete theChildStyles;
|
||||
}
|
||||
@ -622,7 +619,7 @@ nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParse
|
||||
|
||||
CToken* theToken=0;
|
||||
while((theToken=(CToken*)mMisplacedContent.Pop())) {
|
||||
mTokenRecycler->RecycleToken(theToken);
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
|
||||
if(mDTDDebug) {
|
||||
@ -657,8 +654,6 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
||||
eHTMLTags theTag=(eHTMLTags)theToken->GetTypeID();
|
||||
PRBool execSkipContent=PR_FALSE;
|
||||
|
||||
theToken->mUseCount=0; //assume every token coming into this system needs recycling.
|
||||
|
||||
/* ---------------------------------------------------------------------------------
|
||||
To understand this little piece of code, you need to look below too.
|
||||
In essence, this code caches "skipped content" until we find a given skiptarget.
|
||||
@ -674,7 +669,7 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
||||
mSkipTarget=eHTMLTag_unknown; //stop skipping.
|
||||
//mTokenizer->PushTokenFront(aToken); //push the end token...
|
||||
execSkipContent=PR_TRUE;
|
||||
mTokenRecycler->RecycleToken(aToken);
|
||||
IF_FREE(aToken);
|
||||
theToken=(CHTMLToken*)mSkippedContent.PopFront();
|
||||
theType=eToken_start;
|
||||
}
|
||||
@ -721,9 +716,8 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
||||
//We're going to move it to the body by storing it temporarily on the misplaced stack.
|
||||
//However, in quirks mode, a few tags request, ambiguosly, for a BODY. - Bugs 18928, 24204.-
|
||||
mMisplacedContent.Push(aToken);
|
||||
aToken->mUseCount++;
|
||||
if(mDTDMode==eDTDMode_quirks && (gHTMLElements[theTag].HasSpecialProperty(kRequiresBody))) {
|
||||
CToken* theBodyToken=(CToken*)mTokenRecycler->CreateTokenOfType(eToken_start,eHTMLTag_body,NS_ConvertToString("body"));
|
||||
CToken* theBodyToken=(CToken*)mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_body,NS_ConvertToString("body"));
|
||||
result=HandleToken(theBodyToken,aParser);
|
||||
}
|
||||
return result;
|
||||
@ -794,22 +788,15 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
||||
|
||||
|
||||
if(NS_SUCCEEDED(result) || (NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
if(0>=theToken->mUseCount)
|
||||
mTokenRecycler->RecycleToken(theToken);
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
else if(result==NS_ERROR_HTMLPARSER_STOPPARSING)
|
||||
else if(result==NS_ERROR_HTMLPARSER_STOPPARSING) {
|
||||
mDTDState=result;
|
||||
else return NS_OK;
|
||||
}
|
||||
else {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
// CAUTION: Here we are forgetting to push the ATTRIBUTE Tokens.
|
||||
// So, before you uncomment this part please make sure
|
||||
// that the attribute tokens are also accounted for.
|
||||
|
||||
//else if(NS_ERROR_HTMLPARSER_MISPLACED!=result)
|
||||
// mTokenizer->PushTokenFront(theToken);
|
||||
//else result=NS_OK;
|
||||
/***************************************************************/
|
||||
#if 0
|
||||
if (mDTDDebug) {
|
||||
mDTDDebug->Verify(this, mParser, mBodyContext->GetCount(), mBodyContext->mStack, mFilename);
|
||||
@ -849,7 +836,7 @@ nsresult CNavDTD::DidHandleStartTag(nsCParserNode& aNode,eHTMLTags aChildTag){
|
||||
if(eToken_newline==theType){
|
||||
mLineNumber++;
|
||||
theNextToken=mTokenizer->PopToken(); //skip 1st newline inside PRE and LISTING
|
||||
if(theNextToken) mTokenRecycler->RecycleToken(theNextToken); // fix for Bug 29379
|
||||
IF_FREE(theNextToken); // fix for Bug 29379
|
||||
}//if
|
||||
}//if
|
||||
}
|
||||
@ -1176,7 +1163,7 @@ nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsCParserNode
|
||||
//(during editing) to display a special icon for unknown tags.
|
||||
|
||||
if(eHTMLTag_userdefined==aTag) {
|
||||
CAttributeToken* theToken= (CAttributeToken*)mTokenRecycler->CreateTokenOfType(eToken_attribute,aTag);
|
||||
CAttributeToken* theToken= (CAttributeToken*)mTokenAllocator->CreateTokenOfType(eToken_attribute,aTag);
|
||||
if(theToken) {
|
||||
theToken->mTextKey.AssignWithConversion("_moz-userdefined");
|
||||
aNode.AddAttribute(theToken);
|
||||
@ -1263,7 +1250,6 @@ static void PushMisplacedAttributes(nsIParserNode& aNode,nsDeque& aDeque,PRInt32
|
||||
theAttrToken=theAttrNode->PopAttributeToken();
|
||||
if(theAttrToken) {
|
||||
aDeque.Push(theAttrToken);
|
||||
theAttrToken->mUseCount=0;
|
||||
}
|
||||
aCount--;
|
||||
}//while
|
||||
@ -1319,7 +1305,6 @@ nsresult CNavDTD::HandleOmittedTag(CToken* aToken,eHTMLTags aChildTag,eHTMLTags
|
||||
static eHTMLTags gLegalElements[]={eHTMLTag_td,eHTMLTag_th};
|
||||
while(!done){
|
||||
mMisplacedContent.Push(theToken);
|
||||
theToken->mUseCount++;
|
||||
|
||||
// If the token is attributed then save those attributes too.
|
||||
if(attrCount > 0) PushMisplacedAttributes(*aNode,mMisplacedContent,attrCount);
|
||||
@ -1327,7 +1312,6 @@ nsresult CNavDTD::HandleOmittedTag(CToken* aToken,eHTMLTags aChildTag,eHTMLTags
|
||||
theToken=mTokenizer->PeekToken();
|
||||
|
||||
if(theToken) {
|
||||
theToken->mUseCount=0;
|
||||
theTag=(eHTMLTags)theToken->GetTypeID();
|
||||
if(!nsHTMLElement::IsWhitespaceTag(theTag) && theTag!=eHTMLTag_unknown) {
|
||||
if((gHTMLElements[theTag].mSkipTarget && theToken->GetTokenType() != eToken_end) ||
|
||||
@ -1350,7 +1334,6 @@ nsresult CNavDTD::HandleOmittedTag(CToken* aToken,eHTMLTags aChildTag,eHTMLTags
|
||||
|
||||
if((aChildTag!=aParent) && (gHTMLElements[aParent].HasSpecialProperty(kSaveMisplaced))) {
|
||||
mMisplacedContent.Push(aToken);
|
||||
aToken->mUseCount++;
|
||||
// If the token is attributed then save those attributes too.
|
||||
if(attrCount > 0) PushMisplacedAttributes(*aNode,mMisplacedContent,attrCount);
|
||||
}
|
||||
@ -1387,24 +1370,24 @@ nsresult CNavDTD::HandleKeyGen(nsIParserNode* aNode) {
|
||||
nsString* theTextValue=nsnull;
|
||||
PRInt32 theIndex=nsnull;
|
||||
|
||||
if(mTokenizer && mTokenRecycler) {
|
||||
if(mTokenizer && mTokenAllocator) {
|
||||
// Populate the tokenizer with the fabricated elements in the reverse order
|
||||
// such that <SELECT> is on the top fo the tokenizer followed by <OPTION>s
|
||||
// and </SELECT>
|
||||
theToken=mTokenRecycler->CreateTokenOfType(eToken_end,eHTMLTag_select);
|
||||
theToken=mTokenAllocator->CreateTokenOfType(eToken_end,eHTMLTag_select);
|
||||
mTokenizer->PushTokenFront(theToken);
|
||||
|
||||
for(theIndex=theContent.Count()-1;theIndex>-1;theIndex--) {
|
||||
theTextValue=(nsString*)theContent[theIndex];
|
||||
theToken=mTokenRecycler->CreateTokenOfType(eToken_text,eHTMLTag_text,*theTextValue);
|
||||
theToken=mTokenAllocator->CreateTokenOfType(eToken_text,eHTMLTag_text,*theTextValue);
|
||||
mTokenizer->PushTokenFront(theToken);
|
||||
theToken=mTokenRecycler->CreateTokenOfType(eToken_start,eHTMLTag_option);
|
||||
theToken=mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_option);
|
||||
mTokenizer->PushTokenFront(theToken);
|
||||
}
|
||||
|
||||
// The attribute ( provided by the form processor ) should be a part of the SELECT.
|
||||
// Placing the attribute token on the tokenizer to get picked up by the SELECT.
|
||||
theToken=mTokenRecycler->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown,theAttribute);
|
||||
theToken=mTokenAllocator->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown,theAttribute);
|
||||
|
||||
nsString& theKey=((CAttributeToken*)theToken)->GetKey();
|
||||
theKey.AssignWithConversion("_moz-type");
|
||||
@ -1417,11 +1400,11 @@ nsresult CNavDTD::HandleKeyGen(nsIParserNode* aNode) {
|
||||
mTokenizer->PushTokenFront(((nsCParserNode*)aNode)->PopAttributeToken());
|
||||
}
|
||||
|
||||
theToken=mTokenRecycler->CreateTokenOfType(eToken_start,eHTMLTag_select);
|
||||
theToken=mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_select);
|
||||
// Increament the count because of the additional attribute from the form processor.
|
||||
theToken->SetAttributeCount(theAttrCount+1);
|
||||
mTokenizer->PushTokenFront(theToken);
|
||||
}//if(mTokenizer && mTokenRecycler)
|
||||
}//if(mTokenizer && mTokenAllocator)
|
||||
}//if(NS_SUCCEEDED(result))
|
||||
}// if(NS_SUCCEEDED(result))
|
||||
} //if(aNode)
|
||||
@ -1453,7 +1436,7 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
|
||||
//Begin by gathering up attributes...
|
||||
|
||||
nsCParserNode* theNode=mNodeRecycler->CreateNode();
|
||||
theNode->Init(aToken,mLineNumber,mTokenRecycler);
|
||||
theNode->Init(aToken,mLineNumber,mTokenAllocator);
|
||||
|
||||
eHTMLTags theChildTag=(eHTMLTags)aToken->GetTypeID();
|
||||
PRInt16 attrCount=aToken->GetAttributeCount();
|
||||
@ -1568,7 +1551,7 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
|
||||
}//if
|
||||
} //if
|
||||
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
mNodeRecycler->RecycleNode(theNode);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1680,16 +1663,17 @@ eHTMLTags FindAutoCloseTargetForEndTag(eHTMLTags aCurrentTag,nsDTDContext& aCont
|
||||
* @update gess 10/11/99
|
||||
* @return nada
|
||||
*/
|
||||
static void StripWSFollowingTag(eHTMLTags aChildTag,nsITokenizer* aTokenizer,nsITokenRecycler* aRecycler, PRInt32& aNewlineCount){
|
||||
static void StripWSFollowingTag(eHTMLTags aChildTag,nsITokenizer* aTokenizer,nsTokenAllocator* aTokenAllocator, PRInt32& aNewlineCount){
|
||||
CToken* theToken= (aTokenizer)? aTokenizer->PeekToken():nsnull;
|
||||
|
||||
if(aRecycler) {
|
||||
if(aTokenAllocator) {
|
||||
while(theToken) {
|
||||
eHTMLTokenTypes theType=eHTMLTokenTypes(theToken->GetTokenType());
|
||||
switch(theType) {
|
||||
case eToken_newline: aNewlineCount++;
|
||||
case eToken_whitespace:
|
||||
aRecycler->RecycleToken(aTokenizer->PopToken());
|
||||
theToken=aTokenizer->PopToken();
|
||||
IF_FREE(theToken);
|
||||
theToken=aTokenizer->PeekToken();
|
||||
break;
|
||||
default:
|
||||
@ -1735,7 +1719,7 @@ nsresult CNavDTD::HandleEndToken(CToken* aToken) {
|
||||
break;
|
||||
|
||||
case eHTMLTag_head:
|
||||
StripWSFollowingTag(theChildTag,mTokenizer,mTokenRecycler,mLineNumber);
|
||||
StripWSFollowingTag(theChildTag,mTokenizer,mTokenAllocator,mLineNumber);
|
||||
mRequestedHead=PR_FALSE;
|
||||
//ok to fall through...
|
||||
|
||||
@ -1753,7 +1737,7 @@ nsresult CNavDTD::HandleEndToken(CToken* aToken) {
|
||||
//to use </BR>, even though that isn't a legitimate tag.
|
||||
if(eDTDMode_quirks==mDTDMode) {
|
||||
// Use recycler and pass the token thro' HandleToken() to fix bugs like 32782.
|
||||
CHTMLToken* theToken = (CHTMLToken*)mTokenRecycler->CreateTokenOfType(eToken_start,theChildTag);
|
||||
CHTMLToken* theToken = (CHTMLToken*)mTokenAllocator->CreateTokenOfType(eToken_start,theChildTag);
|
||||
result=HandleToken(theToken,mParser);
|
||||
}
|
||||
}
|
||||
@ -1761,7 +1745,7 @@ nsresult CNavDTD::HandleEndToken(CToken* aToken) {
|
||||
|
||||
case eHTMLTag_body:
|
||||
case eHTMLTag_html:
|
||||
StripWSFollowingTag(theChildTag,mTokenizer,mTokenRecycler,mLineNumber);
|
||||
StripWSFollowingTag(theChildTag,mTokenizer,mTokenAllocator,mLineNumber);
|
||||
break;
|
||||
|
||||
case eHTMLTag_noframes:
|
||||
@ -1802,8 +1786,9 @@ nsresult CNavDTD::HandleEndToken(CToken* aToken) {
|
||||
// Ex. <html><body>Hello</P>There</body></html>
|
||||
PRBool theParentContains=-1; //set to -1 to force canomit to recompute.
|
||||
if(!CanOmit(theParentTag,theChildTag,theParentContains)) {
|
||||
IF_HOLD(aToken);
|
||||
mTokenizer->PushTokenFront(aToken); //put this end token back...
|
||||
CHTMLToken* theToken = (CHTMLToken*)mTokenRecycler->CreateTokenOfType(eToken_start,theChildTag);
|
||||
CHTMLToken* theToken = (CHTMLToken*)mTokenAllocator->CreateTokenOfType(eToken_start,theChildTag);
|
||||
mTokenizer->PushTokenFront(theToken); //put this new token onto stack...
|
||||
}
|
||||
}
|
||||
@ -1895,7 +1880,7 @@ nsresult CNavDTD::HandleSavedTokens(PRInt32 anIndex) {
|
||||
|
||||
if(!(theIndex!=kNotFound && theIndex<=mBodyContext->mContextTopIndex))
|
||||
result=HandleToken(theToken,mParser);
|
||||
else mTokenRecycler->RecycleToken(theToken);
|
||||
else IF_FREE(theToken);
|
||||
}
|
||||
theBadTokenCount--;
|
||||
}//while
|
||||
@ -1942,16 +1927,14 @@ nsresult CNavDTD::HandleEntityToken(CToken* aToken) {
|
||||
CNamedEntity *theEntity=mBodyContext->GetEntity(theStr);
|
||||
CToken *theToken=0;
|
||||
if(theEntity) {
|
||||
theToken=new CTextToken(theEntity->mValue);
|
||||
theToken=(CTextToken*)mTokenAllocator->CreateTokenOfType(eToken_text,eHTMLTag_text,theEntity->mValue);
|
||||
}
|
||||
else {
|
||||
//if you're here we have a bogus entity.
|
||||
//convert it into a text token.
|
||||
nsAutoString temp; temp.AssignWithConversion("&");
|
||||
temp.Append(theStr);
|
||||
theToken=new CTextToken(temp);
|
||||
theToken=(CTextToken*)mTokenAllocator->CreateTokenOfType(eToken_text,eHTMLTag_text,NS_ConvertToString("&"));
|
||||
}
|
||||
return HandleStartToken(theToken);
|
||||
return HandleToken(theToken,mParser);
|
||||
}
|
||||
|
||||
eHTMLTags theParentTag=mBodyContext->Last();
|
||||
@ -1971,7 +1954,7 @@ nsresult CNavDTD::HandleEntityToken(CToken* aToken) {
|
||||
#endif
|
||||
|
||||
result=AddLeaf(theNode);
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
mNodeRecycler->RecycleNode(theNode);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -2007,7 +1990,7 @@ nsresult CNavDTD::HandleCommentToken(CToken* aToken) {
|
||||
|
||||
result=(mSink) ? mSink->AddComment(*theNode) : NS_OK;
|
||||
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
mNodeRecycler->RecycleNode(theNode);
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleCommentToken(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
@ -2084,7 +2067,7 @@ nsresult CNavDTD::HandleProcessingInstructionToken(CToken* aToken){
|
||||
|
||||
result=(mSink) ? mSink->AddProcessingInstruction(*theNode) : NS_OK;
|
||||
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
mNodeRecycler->RecycleNode(theNode);
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleProcessingInstructionToken(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
@ -2148,7 +2131,7 @@ nsresult CNavDTD::HandleDocTypeDeclToken(CToken* aToken){
|
||||
|
||||
result = (mSink)? mSink->AddDocTypeDecl(*theNode,theMode):NS_OK;
|
||||
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
mNodeRecycler->RecycleNode(theNode);
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleDocTypeDeclToken(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
@ -2238,15 +2221,17 @@ nsresult CNavDTD::CollectSkippedContent(nsCParserNode& aNode,PRInt32 &aCount) {
|
||||
// since this is an entity, we know that it's only one character.
|
||||
// check to see if it's a CR, in which case we'll need to do line
|
||||
// termination conversion at the end.
|
||||
aMustConvertLinebreaks |= (mScratch[0] == kCR);
|
||||
aNode.mSkippedContent->Append(mScratch);
|
||||
if(mScratch.Length()>0){
|
||||
aMustConvertLinebreaks |= (mScratch[0] == kCR);
|
||||
aNode.mSkippedContent->Append(mScratch);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
theNextToken->AppendSource(*aNode.mSkippedContent);
|
||||
}
|
||||
}
|
||||
mTokenRecycler->RecycleToken(theNextToken);
|
||||
IF_FREE(theNextToken);
|
||||
}
|
||||
|
||||
// if the string contained CRs (hence is either CR, or CRLF terminated)
|
||||
@ -2695,7 +2680,7 @@ nsresult CNavDTD::OpenTransientStyles(eHTMLTags aChildTag){
|
||||
//if the node tag can't contain the child tag, then remove the child tag from the style stack
|
||||
nsCParserNode* theRemovedNode=(nsCParserNode*)theStack->Remove(sindex,theNodeTag);
|
||||
if(theRemovedNode) {
|
||||
mNodeRecycler->RecycleNode(theRemovedNode,mTokenRecycler);
|
||||
mNodeRecycler->RecycleNode(theRemovedNode);
|
||||
}
|
||||
theEntry--; //back up by one
|
||||
}
|
||||
@ -2765,7 +2750,7 @@ nsresult CNavDTD::PopStyle(eHTMLTags aTag){
|
||||
if(nsHTMLElement::IsResidualStyleTag(aTag)) {
|
||||
nsCParserNode* theNode=(nsCParserNode*)mBodyContext->PopStyle(aTag);
|
||||
if(theNode) {
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
mNodeRecycler->RecycleNode(theNode);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -3296,7 +3281,8 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
|
||||
|
||||
if((anIndex<mBodyContext->GetCount()) && (anIndex>=0)) {
|
||||
|
||||
while(mBodyContext->GetCount()>anIndex) {
|
||||
PRInt32 count=0;
|
||||
while((count=mBodyContext->GetCount())>anIndex) {
|
||||
|
||||
nsEntryStack *theChildStyleStack=0;
|
||||
eHTMLTags theTag=mBodyContext->Last();
|
||||
@ -3438,7 +3424,7 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
|
||||
}
|
||||
#endif
|
||||
}//if anode
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
mNodeRecycler->RecycleNode(theNode);
|
||||
}
|
||||
|
||||
} //if
|
||||
@ -3517,65 +3503,63 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode *aNode){
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
PRBool done=PR_FALSE;
|
||||
eHTMLTags thePrevTag=theTag;
|
||||
nsCParserNode theNode;
|
||||
//nsCParserNode theNode;
|
||||
|
||||
while(!done && NS_SUCCEEDED(result)) {
|
||||
CToken* theToken=mTokenizer->PeekToken();
|
||||
if(theToken) {
|
||||
theTag=(eHTMLTags)theToken->GetTypeID();
|
||||
switch(theTag) {
|
||||
case eHTMLTag_newline:
|
||||
mLineNumber++;
|
||||
case eHTMLTag_whitespace:
|
||||
{
|
||||
theToken=mTokenizer->PopToken();
|
||||
theNode.Init(theToken,mLineNumber,0);
|
||||
nsCParserNode* theNode=mNodeRecycler->CreateNode();
|
||||
if(theNode) {
|
||||
theTag=(eHTMLTags)theToken->GetTypeID();
|
||||
switch(theTag) {
|
||||
case eHTMLTag_newline:
|
||||
mLineNumber++;
|
||||
case eHTMLTag_whitespace:
|
||||
{
|
||||
theToken=mTokenizer->PopToken();
|
||||
theNode->Init(theToken,mLineNumber,0);
|
||||
|
||||
STOP_TIMER();
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
|
||||
STOP_TIMER();
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
|
||||
|
||||
result=mSink->AddLeaf(theNode);
|
||||
result=mSink->AddLeaf(*theNode);
|
||||
|
||||
if((NS_SUCCEEDED(result))||(NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
if(mTokenRecycler) {
|
||||
mTokenRecycler->RecycleToken(theToken);
|
||||
if((NS_SUCCEEDED(result))||(NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
else delete theToken;
|
||||
}
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
thePrevTag=theTag;
|
||||
}
|
||||
break;
|
||||
case eHTMLTag_text:
|
||||
if((mHasOpenBody) && (!mHasOpenHead) &&
|
||||
!(nsHTMLElement::IsWhitespaceTag(thePrevTag))) {
|
||||
theToken=mTokenizer->PopToken();
|
||||
theNode.Init(theToken,mLineNumber);
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
|
||||
STOP_TIMER();
|
||||
|
||||
mLineNumber += theToken->mNewlineCount;
|
||||
result=mSink->AddLeaf(theNode);
|
||||
|
||||
if((NS_SUCCEEDED(result))||(NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
if(mTokenRecycler) {
|
||||
mTokenRecycler->RecycleToken(theToken);
|
||||
}
|
||||
else delete theToken;
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
thePrevTag=theTag;
|
||||
}
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
}
|
||||
else done=PR_TRUE;
|
||||
break;
|
||||
break;
|
||||
case eHTMLTag_text:
|
||||
if((mHasOpenBody) && (!mHasOpenHead) &&
|
||||
!(nsHTMLElement::IsWhitespaceTag(thePrevTag))) {
|
||||
theToken=mTokenizer->PopToken();
|
||||
theNode->Init(theToken,mLineNumber);
|
||||
|
||||
default:
|
||||
done=PR_TRUE;
|
||||
} //switch
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
|
||||
STOP_TIMER();
|
||||
|
||||
mLineNumber += theToken->mNewlineCount;
|
||||
result=mSink->AddLeaf(*theNode);
|
||||
|
||||
if((NS_SUCCEEDED(result))||(NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
}
|
||||
else done=PR_TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
done=PR_TRUE;
|
||||
} //switch
|
||||
mNodeRecycler->RecycleNode(theNode);
|
||||
} //if
|
||||
}//if
|
||||
else done=PR_TRUE;
|
||||
} //while
|
||||
@ -3702,8 +3686,8 @@ nsresult CNavDTD::CreateContextStackFor(eHTMLTags aChildTag){
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
CStartToken *theToken=(CStartToken*)mTokenRecycler->CreateTokenOfType(eToken_start,theTag);
|
||||
HandleStartToken(theToken); //these should all wind up on contextstack, so don't recycle.
|
||||
CStartToken *theToken=(CStartToken*)mTokenAllocator->CreateTokenOfType(eToken_start,theTag);
|
||||
HandleToken(theToken,mParser); //these should all wind up on contextstack, so don't recycle.
|
||||
}
|
||||
result=NS_OK;
|
||||
}
|
||||
@ -3732,14 +3716,14 @@ nsresult CNavDTD::GetTokenizer(nsITokenizer*& aTokenizer) {
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsITokenRecycler* CNavDTD::GetTokenRecycler(void){
|
||||
if(!mTokenRecycler) {
|
||||
nsTokenAllocator* CNavDTD::GetTokenAllocator(void){
|
||||
if(!mTokenAllocator) {
|
||||
nsresult result=GetTokenizer(mTokenizer);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
mTokenRecycler=(CTokenRecycler*)mTokenizer->GetTokenRecycler();
|
||||
mTokenAllocator=mTokenizer->GetTokenAllocator();
|
||||
}
|
||||
}
|
||||
return mTokenRecycler;
|
||||
return mTokenAllocator;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -105,7 +105,7 @@ class nsDTDContext;
|
||||
class nsEntryStack;
|
||||
class nsITokenizer;
|
||||
class nsCParserNode;
|
||||
class CTokenRecycler;
|
||||
class nsTokenAllocator;
|
||||
class CNodeRecycler;
|
||||
|
||||
/***************************************************************
|
||||
@ -232,7 +232,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
virtual nsITokenRecycler* GetTokenRecycler(void);
|
||||
virtual nsTokenAllocator* GetTokenAllocator(void);
|
||||
|
||||
/**
|
||||
* If the parse process gets interrupted, this method gets called
|
||||
@ -511,7 +511,7 @@ protected:
|
||||
PRInt32 mLineNumber;
|
||||
nsParser* mParser;
|
||||
nsITokenizer* mTokenizer;
|
||||
CTokenRecycler* mTokenRecycler;
|
||||
nsTokenAllocator* mTokenAllocator;
|
||||
CNodeRecycler* mNodeRecycler;
|
||||
nsDeque mMisplacedContent;
|
||||
nsDeque mSkippedContent;
|
||||
|
@ -139,8 +139,8 @@ COtherDTD::COtherDTD() : nsIDTD(), mSharedNodes(0) {
|
||||
mHasOpenHead=0;
|
||||
mHasOpenForm=PR_FALSE;
|
||||
mHasOpenMap=PR_FALSE;
|
||||
mBodyContext=new nsDTDContext();
|
||||
mTokenizer=0;
|
||||
mTokenAllocator=0;
|
||||
mComputedCRC32=0;
|
||||
mExpectedCRC32=0;
|
||||
mDTDState=NS_OK;
|
||||
@ -149,6 +149,7 @@ COtherDTD::COtherDTD() : nsIDTD(), mSharedNodes(0) {
|
||||
mHadBody=PR_FALSE;
|
||||
mHasOpenScript=PR_FALSE;
|
||||
mParserCommand=eViewNormal;
|
||||
mBodyContext=new nsDTDContext();
|
||||
|
||||
#if 1 //set this to 1 if you want strictDTD to be based on the environment setting.
|
||||
char* theEnvString = PR_GetEnv("MOZ_DISABLE_STRICT");
|
||||
@ -416,7 +417,6 @@ nsresult COtherDTD::WillBuildModel( const CParserContext& aParserContext,nsICon
|
||||
|
||||
mDocType=aParserContext.mDocType;
|
||||
mBodyContext->mTransitional=PRBool(aParserContext.mDTDMode==eDTDMode_transitional);
|
||||
mBodyContext->GetTokenRecycler();
|
||||
|
||||
if(aSink && (!mSink)) {
|
||||
result=aSink->QueryInterface(kIHTMLContentSinkIID, (void **)&mSink);
|
||||
@ -459,11 +459,15 @@ nsresult COtherDTD::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsITo
|
||||
|
||||
if(mTokenizer) {
|
||||
|
||||
mTokenAllocator=mTokenizer->GetTokenAllocator();
|
||||
|
||||
mBodyContext->SetTokenAllocator(mTokenAllocator);
|
||||
|
||||
if(mSink) {
|
||||
|
||||
if(!mBodyContext->GetCount()) {
|
||||
//if the content model is empty, then begin by opening <html>...
|
||||
CStartToken *theToken=(CStartToken*)mBodyContext->gTokenRecycler->CreateTokenOfType(eToken_start,eHTMLTag_html,NS_ConvertToString("html"));
|
||||
CStartToken *theToken=(CStartToken*)mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_html,NS_ConvertToString("html"));
|
||||
HandleStartToken(theToken); //this token should get pushed on the context stack, don't recycle it.
|
||||
}
|
||||
|
||||
@ -567,7 +571,7 @@ nsresult COtherDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
||||
CHTMLToken* theToken= (CHTMLToken*)(aToken);
|
||||
eHTMLTokenTypes theType=eHTMLTokenTypes(theToken->GetTokenType());
|
||||
|
||||
theToken->mUseCount=0; //assume every token coming into this system needs recycling.
|
||||
// theToken->mUseCount=0; //assume every token coming into this system needs recycling.
|
||||
|
||||
mParser=(nsParser*)aParser;
|
||||
|
||||
@ -591,8 +595,7 @@ nsresult COtherDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
||||
|
||||
|
||||
if(NS_SUCCEEDED(result) || (NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
if(0>=theToken->mUseCount)
|
||||
mBodyContext->gTokenRecycler->RecycleToken(theToken);
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
else if(result==NS_ERROR_HTMLPARSER_STOPPARSING)
|
||||
mDTDState=result;
|
||||
@ -749,7 +752,7 @@ nsresult COtherDTD::HandleStartToken(CToken* aToken) {
|
||||
nsresult result=NS_OK;
|
||||
nsCParserNode* theNode=CreateNode();
|
||||
if(theNode) {
|
||||
theNode->Init(aToken,mLineNumber,mBodyContext->gTokenRecycler);
|
||||
theNode->Init(aToken,mLineNumber,mTokenAllocator);
|
||||
|
||||
eHTMLTags theChildTag=(eHTMLTags)aToken->GetTypeID();
|
||||
PRInt16 attrCount=aToken->GetAttributeCount();
|
||||
@ -835,8 +838,12 @@ nsresult COtherDTD::HandleEndToken(CToken* aToken) {
|
||||
}
|
||||
CElement* theElement=gElementTable->mElements[theParent];
|
||||
if(theElement) {
|
||||
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber);
|
||||
result=theElement->HandleEndToken(&theNode,theChildTag,mBodyContext,mSink);
|
||||
nsCParserNode* theNode=CreateNode();
|
||||
if(theNode) {
|
||||
theNode->Init(aToken,mLineNumber,mTokenAllocator);
|
||||
result=theElement->HandleEndToken(theNode,theChildTag,mBodyContext,mSink);
|
||||
mBodyContext->RecycleNode((nsCParserNode*)theNode);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -904,14 +911,13 @@ nsresult COtherDTD::HandleEntityToken(CToken* aToken) {
|
||||
//before we just toss this away as a bogus entity, let's check...
|
||||
CNamedEntity *theEntity=mBodyContext->GetEntity(theStr);
|
||||
if(theEntity) {
|
||||
theToken=new CTextToken(theEntity->mValue);
|
||||
theToken=(CTextToken*)mTokenAllocator->CreateTokenOfType(eToken_text,eHTMLTag_text,theEntity->mValue);
|
||||
}
|
||||
else {
|
||||
//if you're here we have a bogus entity.
|
||||
//convert it into a text token.
|
||||
nsAutoString temp; temp.AssignWithConversion("&");
|
||||
temp.Append(theStr);
|
||||
theToken=new CTextToken(temp);
|
||||
theToken=(CTextToken*)mTokenAllocator->CreateTokenOfType(eToken_text,eHTMLTag_text,NS_ConvertToString("&"));
|
||||
|
||||
}
|
||||
result=HandleStartToken(theToken);
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ class nsDTDContext;
|
||||
class nsEntryStack;
|
||||
class nsITokenizer;
|
||||
class nsCParserNode;
|
||||
class CTokenRecycler;
|
||||
class nsTokenAllocator;
|
||||
|
||||
/***************************************************************
|
||||
Now the main event: COtherDTD.
|
||||
@ -231,7 +231,7 @@ CLASS_EXPORT_HTMLPARS COtherDTD : public nsIDTD {
|
||||
* @update rickg 16June2000
|
||||
* @return always 0
|
||||
*/
|
||||
virtual nsITokenRecycler* GetTokenRecycler(void) {return 0;}
|
||||
virtual nsTokenAllocator* GetTokenAllocator(void) {return 0;}
|
||||
|
||||
/**
|
||||
* If the parse process gets interrupted, this method gets called
|
||||
@ -334,6 +334,7 @@ protected:
|
||||
PRInt32 mLineNumber;
|
||||
nsParser* mParser;
|
||||
nsITokenizer* mTokenizer;
|
||||
nsTokenAllocator* mTokenAllocator;
|
||||
PRBool mHasOpenScript;
|
||||
eHTMLTags mSkipTarget;
|
||||
nsDeque mSharedNodes;
|
||||
|
@ -815,8 +815,8 @@ public:
|
||||
|
||||
if(aContext->mTableStates) {
|
||||
if(aContext->mTableStates->CanOpenTBody()) {
|
||||
nsCParserNode* theNode=new nsCParserNode();
|
||||
CToken* theToken=new CStartToken(eHTMLTag_tbody);
|
||||
nsCParserNode* theNode=aContext->gNodeRecycler->CreateNode();
|
||||
CToken* theToken=(CStartToken*)aContext->mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_tbody);
|
||||
theNode->Init(theToken,0,0); //this will likely leak...
|
||||
|
||||
result=HandleStartToken(theNode,eHTMLTag_tbody,aContext,aSink);
|
||||
@ -1859,8 +1859,9 @@ public:
|
||||
if(theBody->CanContain(theChildElement,aContext)) {
|
||||
//let's auto open the body
|
||||
|
||||
CToken* theToken=new CStartToken(eHTMLTag_body);
|
||||
nsCParserNode* theNode=new nsCParserNode(theToken,0,0);
|
||||
CToken* theToken=(CStartToken*)aContext->mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_body);
|
||||
nsCParserNode* theNode=aContext->gNodeRecycler->CreateNode();
|
||||
theNode->Init(theToken,0,0);
|
||||
|
||||
result=theBody->HandleStartToken(theNode,eHTMLTag_body,aContext,aSink);
|
||||
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "nsITokenizer.h"
|
||||
#include "nsIHTMLContentSink.h"
|
||||
#include "nsHTMLEntities.h"
|
||||
#include "nsDTDUtils.h"
|
||||
|
||||
#include "prenv.h" //this is here for debug reasons...
|
||||
#include "prtypes.h" //this is here for debug reasons...
|
||||
@ -65,10 +66,10 @@ public:
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual nsresult WillTokenize(PRBool aIsFinalChunk);
|
||||
virtual nsresult WillTokenize(PRBool aIsFinalChunk,nsTokenAllocator* aTokenAllocator);
|
||||
virtual nsresult ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens);
|
||||
virtual nsresult DidTokenize(PRBool aIsFinalChunk);
|
||||
virtual nsITokenRecycler* GetTokenRecycler(void);
|
||||
virtual nsTokenAllocator* GetTokenAllocator(void);
|
||||
|
||||
virtual CToken* PushTokenFront(CToken* theToken);
|
||||
virtual CToken* PushToken(CToken* theToken);
|
||||
@ -78,10 +79,10 @@ public:
|
||||
virtual PRInt32 GetCount(void);
|
||||
|
||||
virtual void PrependTokens(nsDeque& aDeque);
|
||||
static void FreeTokenRecycler(void);
|
||||
protected:
|
||||
|
||||
nsDeque mTokenDeque;
|
||||
nsDeque mTokenDeque;
|
||||
nsTokenAllocator* mTokenAllocator;
|
||||
};
|
||||
|
||||
|
||||
@ -443,6 +444,8 @@ NS_IMETHODIMP CRtfDTD::DidBuildModel(nsresult anErrorCode,PRInt32 aLevel,nsIPars
|
||||
CloseContainer(eHTMLTag_body);
|
||||
CloseContainer(eHTMLTag_html);
|
||||
|
||||
if(mSink) mSink->DidBuildModel(0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -814,6 +817,7 @@ nsresult CRtfDTD::HandleToken(CToken* aToken,nsIParser* aParser) {
|
||||
case eRTFToken_controlword:
|
||||
result=HandleControlWord(aToken); break;
|
||||
|
||||
case eRTFToken_content:
|
||||
case eToken_newline:
|
||||
case eHTMLTag_text:
|
||||
result=HandleContent(aToken); break;
|
||||
@ -835,7 +839,7 @@ nsresult CRtfDTD::HandleToken(CToken* aToken,nsIParser* aParser) {
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsITokenRecycler* CRtfDTD::GetTokenRecycler(void){
|
||||
nsTokenAllocator* CRtfDTD::GetTokenAllocator(void){
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -946,7 +950,7 @@ CRTFContent::CRTFContent(PRUnichar* aKey) : CToken(nsAutoString(aKey)) {
|
||||
* @return nsresult
|
||||
*/
|
||||
PRInt32 CRTFContent::GetTokenType() {
|
||||
return eHTMLTag_text;
|
||||
return eRTFToken_content;
|
||||
}
|
||||
|
||||
|
||||
@ -1026,38 +1030,22 @@ nsRTFTokenizer::~nsRTFTokenizer() {
|
||||
* @param
|
||||
* @return nsresult
|
||||
*/
|
||||
nsresult nsRTFTokenizer::WillTokenize(PRBool aIsFinalChunk) {
|
||||
nsresult nsRTFTokenizer::WillTokenize(PRBool aIsFinalChunk,nsTokenAllocator* aTokenAllocator) {
|
||||
nsresult result=NS_OK;
|
||||
mTokenAllocator=aTokenAllocator;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static CTokenRecycler* gTokenRecycler=0;
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess 1/31/00
|
||||
* @param
|
||||
* @return nsresult
|
||||
*/
|
||||
nsITokenRecycler* nsRTFTokenizer::GetTokenRecycler(void) {
|
||||
nsTokenAllocator* nsRTFTokenizer::GetTokenAllocator(void) {
|
||||
//let's move to this once we eliminate the leaking of tokens...
|
||||
if(!gTokenRecycler)
|
||||
gTokenRecycler=new CTokenRecycler();
|
||||
return gTokenRecycler;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess 1/31/00
|
||||
* @param
|
||||
* @return nsresult
|
||||
*/
|
||||
void nsRTFTokenizer::FreeTokenRecycler(void) {
|
||||
if(gTokenRecycler) {
|
||||
delete gTokenRecycler;
|
||||
gTokenRecycler=0;
|
||||
}
|
||||
return mTokenAllocator;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1077,7 +1065,8 @@ nsresult nsRTFTokenizer::ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens)
|
||||
case '{':
|
||||
{
|
||||
eRTFTags theTag= ('{'==theChar) ? eRTFCtrl_startgroup : eRTFCtrl_endgroup;
|
||||
CRTFControlWord* theToken=new CRTFControlWord(theTag);
|
||||
CRTFControlWord* theToken=(CRTFControlWord*)mTokenAllocator->CreateRTFTokenOfType(eRTFToken_controlword,theTag);
|
||||
|
||||
if(theToken) {
|
||||
mTokenDeque.Push(theToken);
|
||||
}
|
||||
@ -1086,7 +1075,7 @@ nsresult nsRTFTokenizer::ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens)
|
||||
break;
|
||||
case '\\':
|
||||
{
|
||||
CRTFControlWord* theWord = new CRTFControlWord(eRTFCtrl_unknown);
|
||||
CRTFControlWord* theWord =(CRTFControlWord*)mTokenAllocator->CreateRTFTokenOfType(eRTFToken_controlword,eRTFCtrl_unknown);
|
||||
if(theWord) {
|
||||
result=theWord->Consume(theChar,aScanner,0);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
@ -1098,7 +1087,7 @@ nsresult nsRTFTokenizer::ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens)
|
||||
case '\n':
|
||||
case '\r':
|
||||
{
|
||||
CNewlineToken* theContent= new CNewlineToken();
|
||||
CNewlineToken* theContent=(CNewlineToken*)mTokenAllocator->CreateTokenOfType(eToken_newline,eHTMLTag_newline);
|
||||
if(theContent) {
|
||||
result=theContent->Consume(theChar,aScanner,0);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
@ -1108,7 +1097,7 @@ nsresult nsRTFTokenizer::ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens)
|
||||
}
|
||||
break;
|
||||
default:
|
||||
CRTFContent* theContent= new CRTFContent();
|
||||
CRTFContent* theContent=(CRTFContent*)mTokenAllocator->CreateRTFTokenOfType(eRTFToken_content,(eRTFTags)0);
|
||||
if(theContent) {
|
||||
result=theContent->Consume(theChar,aScanner,0);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
@ -1154,7 +1143,6 @@ CToken* nsRTFTokenizer::PeekToken() {
|
||||
CToken* nsRTFTokenizer::PopToken() {
|
||||
CToken* result=nsnull;
|
||||
result=(CToken*)mTokenDeque.PopFront();
|
||||
if(result) result->mUseCount=0;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1167,7 +1155,6 @@ CToken* nsRTFTokenizer::PopToken() {
|
||||
*/
|
||||
CToken* nsRTFTokenizer::PushTokenFront(CToken* theToken) {
|
||||
mTokenDeque.PushFront(theToken);
|
||||
theToken->mUseCount=1;
|
||||
return theToken;
|
||||
}
|
||||
|
||||
@ -1179,7 +1166,6 @@ CToken* nsRTFTokenizer::PushTokenFront(CToken* theToken) {
|
||||
*/
|
||||
CToken* nsRTFTokenizer::PushToken(CToken* theToken) {
|
||||
mTokenDeque.Push(theToken);
|
||||
theToken->mUseCount=1;
|
||||
return theToken;
|
||||
}
|
||||
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "nsDeque.h"
|
||||
#include "nsToken.h"
|
||||
|
||||
|
||||
#define NS_RTF_DTD_IID \
|
||||
{0xa39c6bfc, 0x15f0, 0x11d2, \
|
||||
{0x80, 0x41, 0x00, 0x10, 0x4b, 0x98, 0x3f, 0xd4}}
|
||||
@ -303,7 +304,7 @@ class CRtfDTD : public nsIDTD {
|
||||
* @update gess8/4/98
|
||||
* @return ptr to recycler (or null)
|
||||
*/
|
||||
virtual nsITokenRecycler* GetTokenRecycler(void);
|
||||
virtual nsTokenAllocator* GetTokenAllocator(void);
|
||||
|
||||
/**
|
||||
* Use this id you want to stop the building content model
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
MOZ_DECL_CTOR_COUNTER(nsEntryStack);
|
||||
MOZ_DECL_CTOR_COUNTER(nsDTDContext);
|
||||
MOZ_DECL_CTOR_COUNTER(CTokenRecycler);
|
||||
MOZ_DECL_CTOR_COUNTER(nsTokenAllocator);
|
||||
MOZ_DECL_CTOR_COUNTER(CNodeRecycler);
|
||||
MOZ_DECL_CTOR_COUNTER(CObserverService);
|
||||
|
||||
@ -129,7 +129,6 @@ void nsEntryStack::Push(const nsIParserNode* aNode,nsEntryStack* aStyleStack) {
|
||||
EnsureCapacityFor(mCount+1);
|
||||
|
||||
((nsCParserNode*)aNode)->mUseCount++;
|
||||
((nsCParserNode*)aNode)->mToken->mUseCount++;
|
||||
|
||||
mEntries[mCount].mTag=(eHTMLTags)aNode->GetNodeType();
|
||||
mEntries[mCount].mNode=(nsIParserNode*)aNode;
|
||||
@ -157,7 +156,6 @@ void nsEntryStack::PushFront(const nsIParserNode* aNode,nsEntryStack* aStyleStac
|
||||
|
||||
|
||||
((nsCParserNode*)aNode)->mUseCount++;
|
||||
((nsCParserNode*)aNode)->mToken->mUseCount++;
|
||||
|
||||
mEntries[0].mTag=(eHTMLTags)aNode->GetNodeType();
|
||||
mEntries[0].mNode=(nsIParserNode*)aNode;
|
||||
@ -206,7 +204,6 @@ nsIParserNode* nsEntryStack::Remove(PRInt32 anIndex,eHTMLTags aTag) {
|
||||
result=mEntries[anIndex].mNode;
|
||||
|
||||
((nsCParserNode*)result)->mUseCount--;
|
||||
((nsCParserNode*)result)->mToken->mUseCount--;
|
||||
|
||||
PRInt32 theIndex=0;
|
||||
mCount-=1;
|
||||
@ -250,7 +247,7 @@ nsIParserNode* nsEntryStack::Pop(void) {
|
||||
result=mEntries[--mCount].mNode;
|
||||
|
||||
((nsCParserNode*)result)->mUseCount--;
|
||||
((nsCParserNode*)result)->mToken->mUseCount--;
|
||||
|
||||
mEntries[mCount].mNode=0;
|
||||
mEntries[mCount].mStyles=0;
|
||||
|
||||
@ -359,7 +356,6 @@ eHTMLTags nsEntryStack::Last() const {
|
||||
***************************************************************/
|
||||
|
||||
CNodeRecycler *nsDTDContext::gNodeRecycler=0;
|
||||
CTokenRecycler *nsDTDContext::gTokenRecycler=0;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -377,6 +373,7 @@ nsDTDContext::nsDTDContext() : mStack(), mEntities(0){
|
||||
ResetCounters();
|
||||
mHadDocTypeDecl=PR_FALSE;
|
||||
mHasOpenHead=PR_FALSE;
|
||||
mTokenAllocator=0;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
memset(mXTags,0,sizeof(mXTags));
|
||||
@ -1017,6 +1014,7 @@ void nsDTDContext::PushStyles(nsEntryStack *aStyles){
|
||||
// If you're here it means that we have hit the rock bottom
|
||||
// ,of the stack, and there's no need to handle anymore styles.
|
||||
// Fix for bug 29048
|
||||
gNodeRecycler->RecycleNode((nsCParserNode*)aStyles->Pop());
|
||||
delete aStyles;
|
||||
aStyles=0;
|
||||
}
|
||||
@ -1108,23 +1106,6 @@ nsresult nsDTDContext::GetNodeRecycler(CNodeRecycler*& aNodeRecycler){
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets called someone wants to create a token of the given type.
|
||||
*
|
||||
* @update rickg 16June2000
|
||||
* @param aType
|
||||
* @param aTag
|
||||
* @param aString
|
||||
* @return new CToken* or 0.
|
||||
*/
|
||||
CTokenRecycler* nsDTDContext::GetTokenRecycler(void) {
|
||||
if(!gTokenRecycler) {
|
||||
gTokenRecycler = new CTokenRecycler();
|
||||
}
|
||||
return gTokenRecycler;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update rickg 16June2000
|
||||
@ -1137,9 +1118,7 @@ void nsDTDContext::RecycleNode(nsCParserNode* aNode) {
|
||||
result=nsDTDContext::GetNodeRecycler(gNodeRecycler);
|
||||
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
if(!gTokenRecycler)
|
||||
GetTokenRecycler();
|
||||
gNodeRecycler->RecycleNode(aNode,gTokenRecycler);
|
||||
gNodeRecycler->RecycleNode(aNode);
|
||||
}
|
||||
else {
|
||||
delete aNode;
|
||||
@ -1158,29 +1137,31 @@ void nsDTDContext::ReleaseGlobalObjects(){
|
||||
delete gNodeRecycler;
|
||||
gNodeRecycler=0;
|
||||
}
|
||||
if(gTokenRecycler) {
|
||||
delete gTokenRecycler;
|
||||
gTokenRecycler=0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************
|
||||
Now define the tokenrecycler class...
|
||||
Now define the nsTokenAllocator class...
|
||||
**************************************************************/
|
||||
|
||||
static const size_t kBucketSizes[] ={sizeof(CStartToken),sizeof(CAttributeToken),sizeof(CCommentToken),sizeof(CEndToken)};
|
||||
static const PRInt32 kNumBuckets = sizeof(kBucketSizes) / sizeof(size_t);
|
||||
static const PRInt32 kInitialPoolSize = NS_SIZE_IN_HEAP(sizeof(CToken)) * 1536;
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess7/25/98
|
||||
* @param
|
||||
*/
|
||||
CTokenRecycler::CTokenRecycler() : nsITokenRecycler() {
|
||||
nsTokenAllocator::nsTokenAllocator() {
|
||||
|
||||
MOZ_COUNT_CTOR(CTokenRecycler);
|
||||
MOZ_COUNT_CTOR(nsTokenAllocator);
|
||||
|
||||
mArenaPool.Init("TheTokenPool", kBucketSizes, kNumBuckets, kInitialPoolSize);
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
int i=0;
|
||||
for(i=0;i<eToken_last-1;i++) {
|
||||
mTokenCache[i]=new nsDeque(0);
|
||||
#ifdef NS_DEBUG
|
||||
mTotals[i]=0;
|
||||
#endif
|
||||
}
|
||||
@ -1190,22 +1171,10 @@ CTokenRecycler::CTokenRecycler() : nsITokenRecycler() {
|
||||
* Destructor for the token factory
|
||||
* @update gess7/25/98
|
||||
*/
|
||||
CTokenRecycler::~CTokenRecycler() {
|
||||
nsTokenAllocator::~nsTokenAllocator() {
|
||||
|
||||
MOZ_COUNT_DTOR(CTokenRecycler);
|
||||
MOZ_COUNT_DTOR(nsTokenAllocator);
|
||||
|
||||
//begin by deleting all the known (recycled) tokens...
|
||||
//We're also deleting the cache-deques themselves.
|
||||
int i;
|
||||
|
||||
CTokenDeallocator theDeallocator;
|
||||
for(i=0;i<eToken_last-1;i++) {
|
||||
if(0!=mTokenCache[i]) {
|
||||
mTokenCache[i]->ForEach(theDeallocator);
|
||||
delete mTokenCache[i];
|
||||
mTokenCache[i]=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CTokenFinder: public nsDequeFunctor{
|
||||
@ -1220,31 +1189,6 @@ public:
|
||||
CToken* mToken;
|
||||
};
|
||||
|
||||
/**
|
||||
* This method gets called when someone wants to recycle a token
|
||||
* @update gess7/24/98
|
||||
* @param aToken -- token to be recycled.
|
||||
* @return nada
|
||||
*/
|
||||
void CTokenRecycler::RecycleToken(CToken* aToken) {
|
||||
if(aToken) {
|
||||
PRInt32 theType=aToken->GetTokenType();
|
||||
|
||||
#if 0
|
||||
//This should be disabled since it's only debug code.
|
||||
CTokenFinder finder(aToken);
|
||||
CToken* theMatch;
|
||||
theMatch=(CToken*)mTokenCache[theType-1]->FirstThat(finder);
|
||||
if(theMatch) {
|
||||
printf("dup token: %p\n",theMatch);
|
||||
}
|
||||
#endif
|
||||
aToken->mUseCount=1;
|
||||
mTokenCache[theType-1]->Push(aToken);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Let's get this code ready to be reused by all the contexts.
|
||||
*
|
||||
@ -1255,37 +1199,33 @@ void CTokenRecycler::RecycleToken(CToken* aToken) {
|
||||
*
|
||||
* @return ptr to new token (or 0).
|
||||
*/
|
||||
CToken* CTokenRecycler::CreateTokenOfType(eHTMLTokenTypes aType,eHTMLTags aTag, const nsString& aString) {
|
||||
CToken* nsTokenAllocator::CreateTokenOfType(eHTMLTokenTypes aType,eHTMLTags aTag, const nsString& aString) {
|
||||
|
||||
CToken* result=(CToken*)mTokenCache[aType-1]->Pop();
|
||||
CToken* result=0;
|
||||
|
||||
if(result) {
|
||||
result->Reinitialize(aTag,aString);
|
||||
}
|
||||
else {
|
||||
#ifdef NS_DEBUG
|
||||
mTotals[aType-1]++;
|
||||
#endif
|
||||
switch(aType){
|
||||
case eToken_start: result=new CStartToken(aTag); break;
|
||||
case eToken_end: result=new CEndToken(aTag); break;
|
||||
case eToken_comment: result=new CCommentToken(); break;
|
||||
case eToken_entity: result=new CEntityToken(aString); break;
|
||||
case eToken_whitespace: result=new CWhitespaceToken(); break;
|
||||
case eToken_newline: result=new CNewlineToken(); break;
|
||||
case eToken_text: result=new CTextToken(aString); break;
|
||||
case eToken_attribute: result=new CAttributeToken(); break;
|
||||
case eToken_script: result=new CScriptToken(); break;
|
||||
case eToken_style: result=new CStyleToken(); break;
|
||||
case eToken_skippedcontent: result=new CSkippedContentToken(aString); break;
|
||||
case eToken_instruction: result=new CInstructionToken(); break;
|
||||
case eToken_cdatasection: result=new CCDATASectionToken(); break;
|
||||
case eToken_error: result=new CErrorToken(); break;
|
||||
case eToken_doctypeDecl: result=new CDoctypeDeclToken(); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch(aType){
|
||||
case eToken_start: result=new(mArenaPool) CStartToken(aTag); break;
|
||||
case eToken_end: result=new(mArenaPool) CEndToken(aTag); break;
|
||||
case eToken_comment: result=new(mArenaPool) CCommentToken(); break;
|
||||
case eToken_entity: result=new(mArenaPool) CEntityToken(aString); break;
|
||||
case eToken_whitespace: result=new(mArenaPool) CWhitespaceToken(); break;
|
||||
case eToken_newline: result=new(mArenaPool) CNewlineToken(); break;
|
||||
case eToken_text: result=new(mArenaPool) CTextToken(aString); break;
|
||||
case eToken_attribute: result=new(mArenaPool) CAttributeToken(aString); break;
|
||||
case eToken_script: result=new(mArenaPool) CScriptToken(); break;
|
||||
case eToken_style: result=new(mArenaPool) CStyleToken(); break;
|
||||
case eToken_skippedcontent: result=new(mArenaPool) CSkippedContentToken(aString); break;
|
||||
case eToken_instruction: result=new(mArenaPool) CInstructionToken(); break;
|
||||
case eToken_cdatasection: result=new(mArenaPool) CCDATASectionToken(); break;
|
||||
case eToken_error: result=new(mArenaPool) CErrorToken(); break;
|
||||
case eToken_doctypeDecl: result=new(mArenaPool) CDoctypeDeclToken(); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1298,40 +1238,60 @@ CToken* CTokenRecycler::CreateTokenOfType(eHTMLTokenTypes aType,eHTMLTags aTag,
|
||||
*
|
||||
* @return ptr to new token (or 0).
|
||||
*/
|
||||
CToken* CTokenRecycler::CreateTokenOfType(eHTMLTokenTypes aType,eHTMLTags aTag) {
|
||||
CToken* nsTokenAllocator::CreateTokenOfType(eHTMLTokenTypes aType,eHTMLTags aTag) {
|
||||
|
||||
CToken* result=(CToken*)mTokenCache[aType-1]->Pop();
|
||||
CToken* result=0;
|
||||
|
||||
if(result) {
|
||||
result->Reinitialize(aTag,mEmpty);
|
||||
}
|
||||
else {
|
||||
#ifdef NS_DEBUG
|
||||
mTotals[aType-1]++;
|
||||
#endif
|
||||
switch(aType){
|
||||
case eToken_start: result=new CStartToken(aTag); break;
|
||||
case eToken_end: result=new CEndToken(aTag); break;
|
||||
case eToken_comment: result=new CCommentToken(); break;
|
||||
case eToken_attribute: result=new CAttributeToken(); break;
|
||||
case eToken_entity: result=new CEntityToken(); break;
|
||||
case eToken_whitespace: result=new CWhitespaceToken(); break;
|
||||
case eToken_newline: result=new CNewlineToken(); break;
|
||||
case eToken_text: result=new CTextToken(mEmpty); break;
|
||||
case eToken_script: result=new CScriptToken(); break;
|
||||
case eToken_style: result=new CStyleToken(); break;
|
||||
case eToken_skippedcontent: result=new CSkippedContentToken(mEmpty); break;
|
||||
case eToken_instruction: result=new CInstructionToken(); break;
|
||||
case eToken_cdatasection: result=new CCDATASectionToken(); break;
|
||||
case eToken_error: result=new CErrorToken(); break;
|
||||
case eToken_doctypeDecl: result=new CDoctypeDeclToken(aTag); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch(aType){
|
||||
case eToken_start: result=new(mArenaPool) CStartToken(aTag); break;
|
||||
case eToken_end: result=new(mArenaPool) CEndToken(aTag); break;
|
||||
case eToken_comment: result=new(mArenaPool) CCommentToken(); break;
|
||||
case eToken_attribute: result=new(mArenaPool) CAttributeToken(); break;
|
||||
case eToken_entity: result=new(mArenaPool) CEntityToken(); break;
|
||||
case eToken_whitespace: result=new(mArenaPool) CWhitespaceToken(); break;
|
||||
case eToken_newline: result=new(mArenaPool) CNewlineToken(); break;
|
||||
case eToken_text: result=new(mArenaPool) CTextToken(NS_ConvertToString("")); break;
|
||||
case eToken_script: result=new(mArenaPool) CScriptToken(); break;
|
||||
case eToken_style: result=new(mArenaPool) CStyleToken(); break;
|
||||
case eToken_skippedcontent: result=new(mArenaPool) CSkippedContentToken(NS_ConvertToString("")); break;
|
||||
case eToken_instruction: result=new(mArenaPool) CInstructionToken(); break;
|
||||
case eToken_cdatasection: result=new(mArenaPool) CCDATASectionToken(); break;
|
||||
case eToken_error: result=new(mArenaPool) CErrorToken(); break;
|
||||
case eToken_doctypeDecl: result=new(mArenaPool) CDoctypeDeclToken(aTag); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Let's get this code ready to be reused by all the contexts.
|
||||
*
|
||||
* @update harishd 08/04/00
|
||||
* @param aType -- tells you the type of token to create
|
||||
* @param aTag -- tells you the type of tag to init with this token
|
||||
*
|
||||
* @return ptr to new token (or 0).
|
||||
*/
|
||||
CToken* nsTokenAllocator::CreateRTFTokenOfType(eRTFTokenTypes aType,eRTFTags aTag) {
|
||||
|
||||
CToken* result=0;
|
||||
|
||||
switch(aType){
|
||||
case eRTFToken_controlword: result=new(mArenaPool) CRTFControlWord(aTag); break;
|
||||
case eRTFToken_content: result=new(mArenaPool) CRTFContent(); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
CNodeRecycler::CNodeRecycler(): mSharedNodes(0) {
|
||||
|
||||
MOZ_COUNT_CTOR(CNodeRecycler);
|
||||
@ -1361,24 +1321,15 @@ CNodeRecycler::~CNodeRecycler() {
|
||||
}
|
||||
}
|
||||
|
||||
void CNodeRecycler::RecycleNode(nsCParserNode* aNode,nsITokenRecycler* aTokenRecycler) {
|
||||
void CNodeRecycler::RecycleNode(nsCParserNode* aNode) {
|
||||
|
||||
if(aNode && (!aNode->mUseCount)) {
|
||||
|
||||
IF_FREE(aNode->mToken);
|
||||
|
||||
// If the node contains tokens there better me a token recycler..
|
||||
if(aTokenRecycler) {
|
||||
if(aNode->mToken) {
|
||||
if(!aNode->mToken->mUseCount) {
|
||||
aTokenRecycler->RecycleToken(aNode->mToken);
|
||||
}
|
||||
}
|
||||
|
||||
CToken* theToken=0;
|
||||
while((theToken=(CToken*)aNode->PopAttributeToken())){
|
||||
if(!theToken->mUseCount) {
|
||||
aTokenRecycler->RecycleToken(theToken);
|
||||
}
|
||||
}
|
||||
CToken* theToken=0;
|
||||
while((theToken=(CToken*)aNode->PopAttributeToken())){
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
mSharedNodes.Push(aNode);
|
||||
}
|
||||
|
@ -42,6 +42,11 @@
|
||||
#include "nsString.h"
|
||||
#include "nsIElementObserver.h"
|
||||
#include "nsIParserNode.h"
|
||||
#include "nsFixedSizeAllocator.h"
|
||||
#include "CRtfDTD.h"
|
||||
|
||||
#define IF_HOLD(_ptr) if(_ptr) { _ptr->AddRef(); }
|
||||
#define IF_FREE(_ptr) if(_ptr) { _ptr->Release(); _ptr=0; } // recycles _ptr
|
||||
|
||||
class nsIParserNode;
|
||||
class nsCParserNode;
|
||||
@ -207,25 +212,27 @@ public:
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
CTokenRecycler class implementation.
|
||||
nsTokenAllocator class implementation.
|
||||
This class is used to recycle tokens.
|
||||
By using this simple class, we cut WAY down on the number of tokens
|
||||
that get created during the run of the system.
|
||||
************************************************************************/
|
||||
class CTokenRecycler : public nsITokenRecycler {
|
||||
public:
|
||||
|
||||
// enum {eCacheMaxSize=100};
|
||||
|
||||
CTokenRecycler();
|
||||
virtual ~CTokenRecycler();
|
||||
virtual void RecycleToken(CToken* aToken);
|
||||
Note: The allocator is created per document. It's been shared
|
||||
( but not ref. counted ) by objects, tokenizer,dtd,and dtd context,
|
||||
that cease to exist when the document is destroyed.
|
||||
************************************************************************/
|
||||
class nsTokenAllocator {
|
||||
public:
|
||||
|
||||
nsTokenAllocator();
|
||||
virtual ~nsTokenAllocator();
|
||||
virtual CToken* CreateTokenOfType(eHTMLTokenTypes aType,eHTMLTags aTag, const nsString& aString);
|
||||
virtual CToken* CreateTokenOfType(eHTMLTokenTypes aType,eHTMLTags aTag);
|
||||
virtual CToken* CreateRTFTokenOfType(eRTFTokenTypes aType,eRTFTags aTag);
|
||||
|
||||
protected:
|
||||
nsDeque* mTokenCache[eToken_last-1];
|
||||
nsString mEmpty;
|
||||
nsFixedSizeAllocator mArenaPool;
|
||||
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
int mTotals[eToken_last-1];
|
||||
@ -246,7 +253,7 @@ public:
|
||||
CNodeRecycler();
|
||||
virtual ~CNodeRecycler();
|
||||
virtual nsCParserNode* CreateNode(void);
|
||||
virtual void RecycleNode(nsCParserNode* aNode,nsITokenRecycler* aTokenRecycler=0);
|
||||
virtual void RecycleNode(nsCParserNode* aNode);
|
||||
|
||||
protected:
|
||||
nsDeque mSharedNodes;
|
||||
@ -291,7 +298,6 @@ public:
|
||||
|
||||
nsresult GetNodeRecycler(CNodeRecycler*& aNodeRecycler);
|
||||
void RecycleNode(nsCParserNode *aNode);
|
||||
CTokenRecycler* GetTokenRecycler(void);
|
||||
static void ReleaseGlobalObjects(void);
|
||||
|
||||
CNamedEntity* RegisterEntity(const nsString& aName,const nsString& aValue);
|
||||
@ -300,6 +306,8 @@ public:
|
||||
void ResetCounters(void);
|
||||
PRInt32 IncrementCounter(eHTMLTags aTag,nsCParserNode& aNode,nsString& aResult);
|
||||
|
||||
void SetTokenAllocator(nsTokenAllocator* aTokenAllocator) { mTokenAllocator=aTokenAllocator; }
|
||||
|
||||
nsEntryStack mStack; //this will hold a list of tagentries...
|
||||
PRInt32 mResidualStyleCount;
|
||||
PRInt32 mContextTopIndex;
|
||||
@ -310,8 +318,8 @@ public:
|
||||
PRBool mHadDocTypeDecl;
|
||||
|
||||
static CNodeRecycler *gNodeRecycler;
|
||||
static CTokenRecycler *gTokenRecycler;
|
||||
|
||||
|
||||
nsTokenAllocator *mTokenAllocator;
|
||||
CTableState *mTableStates;
|
||||
PRInt32 mCounters[NS_HTML_TAG_MAX];
|
||||
nsString mDefaultEntity;
|
||||
|
@ -227,14 +227,14 @@ NS_IMETHODIMP nsExpatDTD::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer
|
||||
if(aTokenizer) {
|
||||
nsITokenizer* oldTokenizer=mTokenizer;
|
||||
mTokenizer=aTokenizer;
|
||||
nsITokenRecycler* theRecycler=aTokenizer->GetTokenRecycler();
|
||||
nsTokenAllocator* theAllocator=aTokenizer->GetTokenAllocator();
|
||||
|
||||
while(NS_OK==result){
|
||||
CToken* theToken=mTokenizer->PopToken();
|
||||
if(theToken) {
|
||||
result=HandleToken(theToken,aParser);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
theRecycler->RecycleToken(theToken);
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
else if(NS_ERROR_HTMLPARSER_BLOCK!=result){
|
||||
mTokenizer->PushTokenFront(theToken);
|
||||
@ -277,12 +277,12 @@ NS_IMETHODIMP nsExpatDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsITokenRecycler* nsExpatDTD::GetTokenRecycler(void){
|
||||
nsTokenAllocator* nsExpatDTD::GetTokenAllocator(void){
|
||||
nsITokenizer* theTokenizer=0;
|
||||
nsresult result=GetTokenizer(theTokenizer);
|
||||
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
return theTokenizer->GetTokenRecycler();
|
||||
return theTokenizer->GetTokenAllocator();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -237,7 +237,7 @@ class nsExpatDTD : public nsIDTD {
|
||||
* @update gess8/4/98
|
||||
* @return ptr to recycler (or null)
|
||||
*/
|
||||
virtual nsITokenRecycler* GetTokenRecycler(void);
|
||||
virtual nsTokenAllocator* GetTokenAllocator(void);
|
||||
|
||||
/**
|
||||
* Parse an XML buffer using expat
|
||||
|
@ -45,7 +45,7 @@
|
||||
typedef struct _XMLParserState {
|
||||
XML_Parser parser;
|
||||
nsDeque* tokenDeque;
|
||||
CTokenRecycler* tokenRecycler;
|
||||
nsTokenAllocator* tokenAllocator;
|
||||
CToken* doctypeToken;
|
||||
CToken* cdataToken; // Used by the begin and end handlers of the cdata section
|
||||
} XMLParserState;
|
||||
@ -115,11 +115,6 @@ nsresult nsExpatTokenizer::QueryInterface(const nsIID& aIID, void** aInstancePtr
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsExpatTokenizer::FreeTokenRecycler(void) {
|
||||
nsHTMLTokenizer::FreeTokenRecycler();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is defined in nsIParser. It is used to
|
||||
* cause the COM-like construction of an nsParser.
|
||||
@ -180,7 +175,7 @@ nsExpatTokenizer::nsExpatTokenizer(nsString* aURL) : nsHTMLTokenizer() {
|
||||
NS_INIT_REFCNT();
|
||||
mBytesParsed = 0;
|
||||
mState = new XMLParserState;
|
||||
mState->tokenRecycler = (CTokenRecycler*)GetTokenRecycler();
|
||||
mState->tokenAllocator = nsnull;
|
||||
mState->cdataToken = nsnull;
|
||||
mState->parser = nsnull;
|
||||
mState->tokenDeque = nsnull;
|
||||
@ -224,6 +219,12 @@ nsExpatTokenizer::~nsExpatTokenizer(){
|
||||
Here begins the real working methods for the tokenizer.
|
||||
*******************************************************************/
|
||||
|
||||
nsresult nsExpatTokenizer::WillTokenize(PRBool aIsFinalChunk,nsTokenAllocator* aTokenAllocator)
|
||||
{
|
||||
mState->tokenAllocator=aTokenAllocator;
|
||||
return nsHTMLTokenizer::WillTokenize(aIsFinalChunk,aTokenAllocator);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parameters:
|
||||
*
|
||||
@ -336,38 +337,38 @@ nsresult
|
||||
nsExpatTokenizer::AddErrorMessageTokens(nsParserError* aError)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
CToken* newToken = mState->tokenRecycler->CreateTokenOfType(eToken_start, eHTMLTag_parsererror);
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
|
||||
CToken* newToken = mState->tokenAllocator->CreateTokenOfType(eToken_start, eHTMLTag_parsererror);
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenAllocator);
|
||||
|
||||
CAttributeToken* attrToken = (CAttributeToken*)
|
||||
mState->tokenRecycler->CreateTokenOfType(eToken_attribute, eHTMLTag_unknown);
|
||||
mState->tokenAllocator->CreateTokenOfType(eToken_attribute, eHTMLTag_unknown);
|
||||
nsString& key = attrToken->GetKey();
|
||||
key.AssignWithConversion("xmlns");
|
||||
attrToken->SetCStringValue(kHTMLNameSpaceURI);
|
||||
newToken->SetAttributeCount(1);
|
||||
newToken = (CToken*) attrToken;
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenAllocator);
|
||||
|
||||
nsAutoString textStr;
|
||||
CreateErrorText(aError, textStr);
|
||||
newToken = mState->tokenRecycler->CreateTokenOfType(eToken_text, eHTMLTag_unknown);
|
||||
newToken = mState->tokenAllocator->CreateTokenOfType(eToken_text, eHTMLTag_unknown);
|
||||
newToken->SetStringValue(textStr);
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenAllocator);
|
||||
|
||||
newToken = mState->tokenRecycler->CreateTokenOfType(eToken_start, eHTMLTag_sourcetext);
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
|
||||
newToken = mState->tokenAllocator->CreateTokenOfType(eToken_start, eHTMLTag_sourcetext);
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenAllocator);
|
||||
|
||||
textStr.Truncate();
|
||||
CreateSourceText(aError, textStr);
|
||||
newToken = mState->tokenRecycler->CreateTokenOfType(eToken_text, eHTMLTag_unknown);
|
||||
newToken = mState->tokenAllocator->CreateTokenOfType(eToken_text, eHTMLTag_unknown);
|
||||
newToken->SetStringValue(textStr);
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenAllocator);
|
||||
|
||||
newToken = mState->tokenRecycler->CreateTokenOfType(eToken_end, eHTMLTag_sourcetext);
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
|
||||
newToken = mState->tokenAllocator->CreateTokenOfType(eToken_end, eHTMLTag_sourcetext);
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenAllocator);
|
||||
|
||||
newToken = mState->tokenRecycler->CreateTokenOfType(eToken_end, eHTMLTag_parsererror);
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
|
||||
newToken = mState->tokenAllocator->CreateTokenOfType(eToken_end, eHTMLTag_parsererror);
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenAllocator);
|
||||
|
||||
return rv;
|
||||
}
|
||||
@ -392,7 +393,7 @@ nsExpatTokenizer::AddErrorMessageTokens(nsParserError* aError)
|
||||
nsresult
|
||||
nsExpatTokenizer::PushXMLErrorTokens(const char *aBuffer, PRUint32 aLength, PRBool aIsFinal)
|
||||
{
|
||||
CErrorToken* errorToken= (CErrorToken *) mState->tokenRecycler->CreateTokenOfType(eToken_error, eHTMLTag_unknown);
|
||||
CErrorToken* errorToken= (CErrorToken *) mState->tokenAllocator->CreateTokenOfType(eToken_error, eHTMLTag_unknown);
|
||||
nsParserError *error = new nsParserError;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
@ -416,7 +417,7 @@ nsExpatTokenizer::PushXMLErrorTokens(const char *aBuffer, PRUint32 aLength, PRBo
|
||||
|
||||
/* Add the error token */
|
||||
CToken* newToken = (CToken*) errorToken;
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
|
||||
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenAllocator);
|
||||
|
||||
/* Add the error message tokens */
|
||||
AddErrorMessageTokens(error);
|
||||
@ -505,7 +506,7 @@ void nsExpatTokenizer::FrontloadMisplacedContent(nsDeque& aDeque){
|
||||
|
||||
void nsExpatTokenizer::HandleStartElement(void *userData, const XML_Char *name, const XML_Char **atts) {
|
||||
XMLParserState* state = (XMLParserState*) userData;
|
||||
CToken* theToken = state->tokenRecycler->CreateTokenOfType(eToken_start,eHTMLTag_unknown);
|
||||
CToken* theToken = state->tokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_unknown);
|
||||
if(theToken) {
|
||||
// If an ID attribute exists for this element, set it on the start token
|
||||
PRInt32 index = XML_GetIdAttributeIndex(state->parser);
|
||||
@ -518,14 +519,14 @@ void nsExpatTokenizer::HandleStartElement(void *userData, const XML_Char *name,
|
||||
// Set the element name on the start token and add the token to the token queue
|
||||
nsString& theString=theToken->GetStringValueXXX();
|
||||
theString.Assign((PRUnichar *) name);
|
||||
AddToken(theToken, NS_OK, state->tokenDeque, state->tokenRecycler);
|
||||
AddToken(theToken, NS_OK, state->tokenDeque, state->tokenAllocator);
|
||||
|
||||
// For each attribute on this element, create and add attribute tokens to the token queue
|
||||
int theAttrCount=0;
|
||||
while(*atts){
|
||||
theAttrCount++;
|
||||
CAttributeToken* theAttrToken = (CAttributeToken*)
|
||||
state->tokenRecycler->CreateTokenOfType(eToken_attribute, eHTMLTag_unknown);
|
||||
state->tokenAllocator->CreateTokenOfType(eToken_attribute, eHTMLTag_unknown);
|
||||
if(theAttrToken){
|
||||
nsString& theKey=theAttrToken->GetKey();
|
||||
theKey.Assign((PRUnichar *) (*atts++));
|
||||
@ -533,7 +534,7 @@ void nsExpatTokenizer::HandleStartElement(void *userData, const XML_Char *name,
|
||||
theValue.Assign((PRUnichar *) (*atts++));
|
||||
}
|
||||
CToken* theTok=(CToken*)theAttrToken;
|
||||
AddToken(theTok, NS_OK, state->tokenDeque, state->tokenRecycler);
|
||||
AddToken(theTok, NS_OK, state->tokenDeque, state->tokenAllocator);
|
||||
}
|
||||
theToken->SetAttributeCount(theAttrCount);
|
||||
}
|
||||
@ -544,11 +545,11 @@ void nsExpatTokenizer::HandleStartElement(void *userData, const XML_Char *name,
|
||||
|
||||
void nsExpatTokenizer::HandleEndElement(void *userData, const XML_Char *name) {
|
||||
XMLParserState* state = (XMLParserState*) userData;
|
||||
CToken* theToken = state->tokenRecycler->CreateTokenOfType(eToken_end,eHTMLTag_unknown);
|
||||
CToken* theToken = state->tokenAllocator->CreateTokenOfType(eToken_end,eHTMLTag_unknown);
|
||||
if(theToken) {
|
||||
nsString& theString=theToken->GetStringValueXXX();
|
||||
theString.Assign((PRUnichar *) name);
|
||||
AddToken(theToken, NS_OK, state->tokenDeque, state->tokenRecycler);
|
||||
AddToken(theToken, NS_OK, state->tokenDeque, state->tokenAllocator);
|
||||
}
|
||||
else{
|
||||
//THROW A HUGE ERROR IF WE CANT CREATE A TOKEN!
|
||||
@ -570,14 +571,14 @@ void nsExpatTokenizer::HandleCharacterData(void *userData, const XML_Char *s, in
|
||||
switch(((PRUnichar*)s)[0]){
|
||||
case kNewLine:
|
||||
case CR:
|
||||
newToken = state->tokenRecycler->CreateTokenOfType(eToken_newline,eHTMLTag_unknown);
|
||||
newToken = state->tokenAllocator->CreateTokenOfType(eToken_newline,eHTMLTag_unknown);
|
||||
break;
|
||||
case kSpace:
|
||||
case kTab:
|
||||
newToken = state->tokenRecycler->CreateTokenOfType(eToken_whitespace,eHTMLTag_unknown);
|
||||
newToken = state->tokenAllocator->CreateTokenOfType(eToken_whitespace,eHTMLTag_unknown);
|
||||
break;
|
||||
default:
|
||||
newToken = state->tokenRecycler->CreateTokenOfType(eToken_text,eHTMLTag_unknown);
|
||||
newToken = state->tokenAllocator->CreateTokenOfType(eToken_text,eHTMLTag_unknown);
|
||||
}
|
||||
|
||||
if(newToken) {
|
||||
@ -585,7 +586,7 @@ void nsExpatTokenizer::HandleCharacterData(void *userData, const XML_Char *s, in
|
||||
nsString& theString=newToken->GetStringValueXXX();
|
||||
theString.Append((PRUnichar *) s,len);
|
||||
}
|
||||
AddToken(newToken, NS_OK, state->tokenDeque, state->tokenRecycler);
|
||||
AddToken(newToken, NS_OK, state->tokenDeque, state->tokenAllocator);
|
||||
}
|
||||
else {
|
||||
//THROW A HUGE ERROR IF WE CANT CREATE A TOKEN!
|
||||
@ -595,11 +596,11 @@ void nsExpatTokenizer::HandleCharacterData(void *userData, const XML_Char *s, in
|
||||
|
||||
void nsExpatTokenizer::HandleComment(void *userData, const XML_Char *name) {
|
||||
XMLParserState* state = (XMLParserState*) userData;
|
||||
CToken* theToken = state->tokenRecycler->CreateTokenOfType(eToken_comment, eHTMLTag_unknown);
|
||||
CToken* theToken = state->tokenAllocator->CreateTokenOfType(eToken_comment, eHTMLTag_unknown);
|
||||
if(theToken) {
|
||||
nsString& theString=theToken->GetStringValueXXX();
|
||||
theString.Assign((PRUnichar *) name);
|
||||
AddToken(theToken, NS_OK, state->tokenDeque, state->tokenRecycler);
|
||||
AddToken(theToken, NS_OK, state->tokenDeque, state->tokenAllocator);
|
||||
}
|
||||
else{
|
||||
//THROW A HUGE ERROR IF WE CANT CREATE A TOKEN!
|
||||
@ -608,7 +609,7 @@ void nsExpatTokenizer::HandleComment(void *userData, const XML_Char *name) {
|
||||
|
||||
void nsExpatTokenizer::HandleStartCdataSection(void *userData) {
|
||||
XMLParserState* state = (XMLParserState*) userData;
|
||||
CToken* cdataToken = state->tokenRecycler->CreateTokenOfType(eToken_cdatasection,
|
||||
CToken* cdataToken = state->tokenAllocator->CreateTokenOfType(eToken_cdatasection,
|
||||
eHTMLTag_unknown);
|
||||
|
||||
state->cdataToken = cdataToken;
|
||||
@ -620,7 +621,7 @@ void nsExpatTokenizer::HandleEndCdataSection(void *userData) {
|
||||
|
||||
// We've reached the end of the current CDATA section. Push the current
|
||||
// CDATA token onto the token queue
|
||||
AddToken(currentCDataToken, NS_OK, state->tokenDeque, state->tokenRecycler);
|
||||
AddToken(currentCDataToken, NS_OK, state->tokenDeque, state->tokenAllocator);
|
||||
|
||||
state->cdataToken = nsnull;
|
||||
}
|
||||
@ -630,7 +631,7 @@ void nsExpatTokenizer::HandleProcessingInstruction(void *userData,
|
||||
const XML_Char *data)
|
||||
{
|
||||
XMLParserState* state = (XMLParserState*) userData;
|
||||
CToken* theToken = state->tokenRecycler->CreateTokenOfType(eToken_instruction,eHTMLTag_unknown);
|
||||
CToken* theToken = state->tokenAllocator->CreateTokenOfType(eToken_instruction,eHTMLTag_unknown);
|
||||
if(theToken) {
|
||||
nsString& theString=theToken->GetStringValueXXX();
|
||||
theString. AppendWithConversion("<?");
|
||||
@ -640,7 +641,7 @@ void nsExpatTokenizer::HandleProcessingInstruction(void *userData,
|
||||
theString.Append((PRUnichar *) data);
|
||||
}
|
||||
theString.AppendWithConversion("?>");
|
||||
AddToken(theToken, NS_OK, state->tokenDeque, state->tokenRecycler);
|
||||
AddToken(theToken, NS_OK, state->tokenDeque, state->tokenAllocator);
|
||||
}
|
||||
else{
|
||||
//THROW A HUGE ERROR IF WE CANT CREATE A TOKEN!
|
||||
@ -659,8 +660,8 @@ void nsExpatTokenizer::HandleDefault(void *userData, const XML_Char *s, int len)
|
||||
CToken* newLine = 0;
|
||||
|
||||
while ((offset = str.FindChar('\n', PR_FALSE, offset + 1)) != -1) {
|
||||
newLine = state->tokenRecycler->CreateTokenOfType(eToken_newline, eHTMLTag_unknown);
|
||||
AddToken(newLine, NS_OK, state->tokenDeque, state->tokenRecycler);
|
||||
newLine = state->tokenAllocator->CreateTokenOfType(eToken_newline, eHTMLTag_unknown);
|
||||
AddToken(newLine, NS_OK, state->tokenDeque, state->tokenAllocator);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -873,7 +874,7 @@ void nsExpatTokenizer::HandleStartDoctypeDecl(void *userData,
|
||||
const XML_Char *doctypeName)
|
||||
{
|
||||
XMLParserState* state = (XMLParserState*) userData;
|
||||
CToken* token = state->tokenRecycler->CreateTokenOfType(eToken_doctypeDecl, eHTMLTag_unknown);
|
||||
CToken* token = state->tokenAllocator->CreateTokenOfType(eToken_doctypeDecl, eHTMLTag_unknown);
|
||||
if (token) {
|
||||
nsString& str = token->GetStringValueXXX();
|
||||
str.AppendWithConversion(kDocTypeDeclPrefix);
|
||||
@ -888,7 +889,7 @@ void nsExpatTokenizer::HandleEndDoctypeDecl(void *userData)
|
||||
if (token) {
|
||||
nsString& str = token->GetStringValueXXX();
|
||||
str.AppendWithConversion(">");
|
||||
AddToken(token, NS_OK, state->tokenDeque, state->tokenRecycler);
|
||||
AddToken(token, NS_OK, state->tokenDeque, state->tokenAllocator);
|
||||
state->doctypeToken = nsnull;
|
||||
}
|
||||
// Do nothing
|
||||
|
@ -74,13 +74,12 @@ public:
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
/* nsITokenizer methods */
|
||||
/* nsITokenizer methods */
|
||||
virtual nsresult WillTokenize(PRBool aIsFinalChunk,nsTokenAllocator* aTokenAllocator);
|
||||
virtual nsresult ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens);
|
||||
virtual nsresult DidTokenize(PRBool aIsFinalChunk);
|
||||
|
||||
virtual void FrontloadMisplacedContent(nsDeque& aDeque);
|
||||
static void FreeTokenRecycler(void);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -75,16 +75,6 @@ nsresult nsHTMLTokenizer::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static CTokenRecycler* gTokenRecycler=0;
|
||||
|
||||
void
|
||||
nsHTMLTokenizer::FreeTokenRecycler(void) {
|
||||
if(gTokenRecycler) {
|
||||
delete gTokenRecycler;
|
||||
gTokenRecycler=0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is defined in nsHTMLTokenizer.h. It is used to
|
||||
* cause the COM-like construction of an HTMLTokenizer.
|
||||
@ -128,6 +118,7 @@ NS_IMPL_RELEASE(nsHTMLTokenizer)
|
||||
mDocType=aDocType;
|
||||
mRecordTrailingContent=PR_FALSE;
|
||||
mParserCommand=aCommand;
|
||||
mTokenAllocator=nsnull;
|
||||
}
|
||||
|
||||
|
||||
@ -150,17 +141,13 @@ nsHTMLTokenizer::~nsHTMLTokenizer(){
|
||||
Here begins the real working methods for the tokenizer.
|
||||
*******************************************************************/
|
||||
|
||||
void nsHTMLTokenizer::AddToken(CToken*& aToken,nsresult aResult,nsDeque* aDeque,CTokenRecycler* aRecycler) {
|
||||
void nsHTMLTokenizer::AddToken(CToken*& aToken,nsresult aResult,nsDeque* aDeque,nsTokenAllocator* aTokenAllocator) {
|
||||
if(aToken && aDeque) {
|
||||
if(NS_SUCCEEDED(aResult)) {
|
||||
aDeque->Push(aToken);
|
||||
}
|
||||
else {
|
||||
if(aRecycler) {
|
||||
aRecycler->RecycleToken(aToken);
|
||||
}
|
||||
else delete aToken;
|
||||
aToken=0;
|
||||
IF_FREE(aToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -170,11 +157,8 @@ void nsHTMLTokenizer::AddToken(CToken*& aToken,nsresult aResult,nsDeque* aDeque,
|
||||
* @update gess8/4/98
|
||||
* @return ptr to recycler (or null)
|
||||
*/
|
||||
nsITokenRecycler* nsHTMLTokenizer::GetTokenRecycler(void) {
|
||||
//let's move to this once we eliminate the leaking of tokens...
|
||||
if(!gTokenRecycler)
|
||||
gTokenRecycler=new CTokenRecycler();
|
||||
return gTokenRecycler;
|
||||
nsTokenAllocator* nsHTMLTokenizer::GetTokenAllocator(void) {
|
||||
return mTokenAllocator;
|
||||
}
|
||||
|
||||
|
||||
@ -198,7 +182,6 @@ CToken* nsHTMLTokenizer::PeekToken() {
|
||||
CToken* nsHTMLTokenizer::PopToken() {
|
||||
CToken* result=nsnull;
|
||||
result=(CToken*)mTokenDeque.PopFront();
|
||||
if(result) result->mUseCount=0;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -211,7 +194,6 @@ CToken* nsHTMLTokenizer::PopToken() {
|
||||
*/
|
||||
CToken* nsHTMLTokenizer::PushTokenFront(CToken* theToken) {
|
||||
mTokenDeque.PushFront(theToken);
|
||||
theToken->mUseCount=1;
|
||||
return theToken;
|
||||
}
|
||||
|
||||
@ -223,7 +205,6 @@ CToken* nsHTMLTokenizer::PushTokenFront(CToken* theToken) {
|
||||
*/
|
||||
CToken* nsHTMLTokenizer::PushToken(CToken* theToken) {
|
||||
mTokenDeque.Push(theToken);
|
||||
theToken->mUseCount=1;
|
||||
return theToken;
|
||||
}
|
||||
|
||||
@ -247,8 +228,15 @@ CToken* nsHTMLTokenizer::GetTokenAt(PRInt32 anIndex){
|
||||
return (CToken*)mTokenDeque.ObjectAt(anIndex);
|
||||
}
|
||||
|
||||
nsresult nsHTMLTokenizer::WillTokenize(PRBool aIsFinalChunk)
|
||||
/**
|
||||
* @update gess 12/29/98
|
||||
* @update harishd 08/04/00
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsresult nsHTMLTokenizer::WillTokenize(PRBool aIsFinalChunk,nsTokenAllocator* aTokenAllocator)
|
||||
{
|
||||
mTokenAllocator=aTokenAllocator;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -410,10 +398,10 @@ nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,CStartToken* aToken,
|
||||
nsresult result=NS_OK;
|
||||
PRInt16 theAttrCount=0;
|
||||
|
||||
CTokenRecycler* theRecycler=(CTokenRecycler*)GetTokenRecycler();
|
||||
nsTokenAllocator* theAllocator=this->GetTokenAllocator();
|
||||
|
||||
while((!done) && (result==NS_OK)) {
|
||||
CToken* theToken= (CAttributeToken*)theRecycler->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown);
|
||||
CToken* theToken= (CAttributeToken*)theAllocator->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown);
|
||||
if(theToken){
|
||||
if(aLeadingWS.Length()) {
|
||||
nsString& theKey=((CAttributeToken*)theToken)->GetKey();
|
||||
@ -433,16 +421,16 @@ nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,CStartToken* aToken,
|
||||
if((mDoXMLEmptyTags) && (kForwardSlash==key.CharAt(0)) && (0==text.Length())){
|
||||
//tada! our special case! Treat it like an empty start tag...
|
||||
aToken->SetEmpty(PR_TRUE);
|
||||
theRecycler->RecycleToken(theToken);
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
else {
|
||||
theAttrCount++;
|
||||
AddToken(theToken,result,&mTokenDeque,theRecycler);
|
||||
AddToken(theToken,result,&mTokenDeque,theAllocator);
|
||||
}
|
||||
}
|
||||
else { //if(NS_ERROR_HTMLPARSER_BADATTRIBUTE==result){
|
||||
aToken->SetEmpty(PR_TRUE);
|
||||
theRecycler->RecycleToken(theToken);
|
||||
IF_FREE(theToken);
|
||||
if(NS_ERROR_HTMLPARSER_BADATTRIBUTE==result)
|
||||
result=NS_OK;
|
||||
}
|
||||
@ -460,8 +448,8 @@ nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,CStartToken* aToken,
|
||||
else if(aChar==kLessThan) {
|
||||
eHTMLTags theEndTag = (eHTMLTags)aToken->GetTypeID();
|
||||
if(result==NS_OK&&(gHTMLElements[theEndTag].mSkipTarget)){
|
||||
CToken* theEndToken=theRecycler->CreateTokenOfType(eToken_end,theEndTag);
|
||||
AddToken(theEndToken,NS_OK,&mTokenDeque,theRecycler);
|
||||
CToken* theEndToken=theAllocator->CreateTokenOfType(eToken_end,theEndTag);
|
||||
AddToken(theEndToken,NS_OK,&mTokenDeque,theAllocator);
|
||||
}
|
||||
done=PR_TRUE;
|
||||
}
|
||||
@ -497,8 +485,8 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
|
||||
PRInt32 theDequeSize=mTokenDeque.GetSize(); //remember this for later in case you have to unwind...
|
||||
nsresult result=NS_OK;
|
||||
|
||||
CTokenRecycler* theRecycler=(CTokenRecycler*)GetTokenRecycler();
|
||||
aToken=theRecycler->CreateTokenOfType(eToken_start,eHTMLTag_unknown);
|
||||
nsTokenAllocator* theAllocator=this->GetTokenAllocator();
|
||||
aToken=theAllocator->CreateTokenOfType(eToken_start,eHTMLTag_unknown);
|
||||
|
||||
if(aToken) {
|
||||
((CStartToken*)aToken)->mOrigin=aScanner.GetOffset()-1; // Save the position after '<' for use in recording traling contents. Ref: Bug. 15204.
|
||||
@ -507,7 +495,7 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
|
||||
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
|
||||
AddToken(aToken,result,&mTokenDeque,theRecycler);
|
||||
AddToken(aToken,result,&mTokenDeque,theAllocator);
|
||||
eHTMLTags theTag=(eHTMLTags)aToken->GetTypeID();
|
||||
|
||||
//Good. Now, let's see if the next char is ">".
|
||||
@ -551,12 +539,12 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
|
||||
if(gHTMLElements[theTag].CanContainType(kCDATA)) {
|
||||
nsAutoString endTag; endTag.AssignWithConversion(nsHTMLTags::GetStringValue(theTag));
|
||||
endTag.InsertWithConversion("</",0,2);
|
||||
CToken* textToken=theRecycler->CreateTokenOfType(eToken_text,eHTMLTag_text);
|
||||
CToken* textToken=theAllocator->CreateTokenOfType(eToken_text,eHTMLTag_text);
|
||||
result=((CTextToken*)textToken)->ConsumeUntil(0,PRBool(theTag!=eHTMLTag_script),aScanner,endTag,mParseMode,aFlushTokens); //tell new token to finish consuming text...
|
||||
//endTag.Append(">");
|
||||
CToken* endToken=theRecycler->CreateTokenOfType(eToken_end,theTag,endTag);
|
||||
AddToken(textToken,result,&mTokenDeque,theRecycler);
|
||||
AddToken(endToken,result,&mTokenDeque,theRecycler);
|
||||
CToken* endToken=theAllocator->CreateTokenOfType(eToken_end,theTag,endTag);
|
||||
AddToken(textToken,result,&mTokenDeque,theAllocator);
|
||||
AddToken(endToken,result,&mTokenDeque,theAllocator);
|
||||
}
|
||||
}
|
||||
|
||||
@ -568,11 +556,12 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
|
||||
//any new tokens we've cued this round. Later we can get smarter about this.
|
||||
if(!NS_SUCCEEDED(result)) {
|
||||
while(mTokenDeque.GetSize()>theDequeSize) {
|
||||
theRecycler->RecycleToken((CToken*)mTokenDeque.Pop());
|
||||
CToken* theToken=(CToken*)mTokenDeque.Pop();
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
}
|
||||
} //if
|
||||
else theRecycler->RecycleToken(aToken);
|
||||
else IF_FREE(aToken);
|
||||
} //if
|
||||
return result;
|
||||
}
|
||||
@ -585,8 +574,8 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
|
||||
*/
|
||||
nsresult nsHTMLTokenizer::ConsumeEndTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner) {
|
||||
|
||||
CTokenRecycler* theRecycler=(CTokenRecycler*)GetTokenRecycler();
|
||||
aToken=theRecycler->CreateTokenOfType(eToken_end,eHTMLTag_unknown);
|
||||
nsTokenAllocator* theAllocator=this->GetTokenAllocator();
|
||||
aToken=theAllocator->CreateTokenOfType(eToken_end,eHTMLTag_unknown);
|
||||
nsresult result=NS_OK;
|
||||
|
||||
if(aToken) {
|
||||
@ -595,7 +584,7 @@ nsresult nsHTMLTokenizer::ConsumeEndTag(PRUnichar aChar,CToken*& aToken,nsScanne
|
||||
mRecordTrailingContent=PR_FALSE;
|
||||
}
|
||||
result= aToken->Consume(aChar,aScanner,mParseMode); //tell new token to finish consuming text...
|
||||
AddToken(aToken,result,&mTokenDeque,theRecycler);
|
||||
AddToken(aToken,result,&mTokenDeque,theAllocator);
|
||||
} //if
|
||||
return result;
|
||||
}
|
||||
@ -614,14 +603,14 @@ nsresult nsHTMLTokenizer::ConsumeEntity(PRUnichar aChar,CToken*& aToken,nsScanne
|
||||
PRUnichar theChar;
|
||||
nsresult result=aScanner.GetChar(theChar);
|
||||
|
||||
CTokenRecycler* theRecycler=(CTokenRecycler*)GetTokenRecycler();
|
||||
nsTokenAllocator* theAllocator=this->GetTokenAllocator();
|
||||
if(NS_OK==result) {
|
||||
if(nsCRT::IsAsciiAlpha(theChar)) { //handle common enity references &xxx; or �.
|
||||
aToken = theRecycler->CreateTokenOfType(eToken_entity,eHTMLTag_entity);
|
||||
aToken = theAllocator->CreateTokenOfType(eToken_entity,eHTMLTag_entity);
|
||||
result = aToken->Consume(theChar,aScanner,mParseMode); //tell new token to finish consuming text...
|
||||
}
|
||||
else if(kHashsign==theChar) {
|
||||
aToken = theRecycler->CreateTokenOfType(eToken_entity,eHTMLTag_entity);
|
||||
aToken = theAllocator->CreateTokenOfType(eToken_entity,eHTMLTag_entity);
|
||||
result=aToken->Consume(theChar,aScanner,mParseMode);
|
||||
}
|
||||
else {
|
||||
@ -639,12 +628,12 @@ nsresult nsHTMLTokenizer::ConsumeEntity(PRUnichar aChar,CToken*& aToken,nsScanne
|
||||
//convert it into a text token.
|
||||
nsAutoString temp; temp.AssignWithConversion("&");
|
||||
temp.Append(theStr);
|
||||
CToken* theToken=theRecycler->CreateTokenOfType(eToken_text,eHTMLTag_text,temp);
|
||||
theRecycler->RecycleToken(aToken);
|
||||
CToken* theToken=theAllocator->CreateTokenOfType(eToken_text,eHTMLTag_text,temp);
|
||||
IF_FREE(aToken);
|
||||
aToken=theToken;
|
||||
}
|
||||
#endif
|
||||
AddToken(aToken,result,&mTokenDeque,theRecycler);
|
||||
AddToken(aToken,result,&mTokenDeque,theAllocator);
|
||||
}
|
||||
}//if
|
||||
return result;
|
||||
@ -662,12 +651,12 @@ nsresult nsHTMLTokenizer::ConsumeEntity(PRUnichar aChar,CToken*& aToken,nsScanne
|
||||
* @return new token or null
|
||||
*/
|
||||
nsresult nsHTMLTokenizer::ConsumeWhitespace(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner) {
|
||||
CTokenRecycler* theRecycler=(CTokenRecycler*)GetTokenRecycler();
|
||||
aToken = theRecycler->CreateTokenOfType(eToken_whitespace,eHTMLTag_whitespace);
|
||||
nsTokenAllocator* theAllocator=this->GetTokenAllocator();
|
||||
aToken = theAllocator->CreateTokenOfType(eToken_whitespace,eHTMLTag_whitespace);
|
||||
nsresult result=NS_OK;
|
||||
if(aToken) {
|
||||
result=aToken->Consume(aChar,aScanner,mParseMode);
|
||||
AddToken(aToken,result,&mTokenDeque,theRecycler);
|
||||
AddToken(aToken,result,&mTokenDeque,theAllocator);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -683,12 +672,12 @@ nsresult nsHTMLTokenizer::ConsumeWhitespace(PRUnichar aChar,CToken*& aToken,nsSc
|
||||
* @return new token or null
|
||||
*/
|
||||
nsresult nsHTMLTokenizer::ConsumeComment(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner){
|
||||
CTokenRecycler* theRecycler=(CTokenRecycler*)GetTokenRecycler();
|
||||
aToken = theRecycler->CreateTokenOfType(eToken_comment,eHTMLTag_comment);
|
||||
nsTokenAllocator* theAllocator=this->GetTokenAllocator();
|
||||
aToken = theAllocator->CreateTokenOfType(eToken_comment,eHTMLTag_comment);
|
||||
nsresult result=NS_OK;
|
||||
if(aToken) {
|
||||
result=aToken->Consume(aChar,aScanner,mParseMode);
|
||||
AddToken(aToken,result,&mTokenDeque,theRecycler);
|
||||
AddToken(aToken,result,&mTokenDeque,theAllocator);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -705,20 +694,20 @@ nsresult nsHTMLTokenizer::ConsumeComment(PRUnichar aChar,CToken*& aToken,nsScann
|
||||
*/
|
||||
nsresult nsHTMLTokenizer::ConsumeText(const nsString& aString,CToken*& aToken,nsScanner& aScanner){
|
||||
nsresult result=NS_OK;
|
||||
CTokenRecycler* theRecycler=(CTokenRecycler*)GetTokenRecycler();
|
||||
aToken=theRecycler->CreateTokenOfType(eToken_text,eHTMLTag_text,aString);
|
||||
nsTokenAllocator* theAllocator=this->GetTokenAllocator();
|
||||
aToken=theAllocator->CreateTokenOfType(eToken_text,eHTMLTag_text,aString);
|
||||
if(aToken) {
|
||||
PRUnichar ch=0;
|
||||
result=aToken->Consume(ch,aScanner,mParseMode);
|
||||
if(!NS_SUCCEEDED(result)) {
|
||||
nsString& temp=aToken->GetStringValueXXX();
|
||||
if(0==temp.Length()){
|
||||
theRecycler->RecycleToken(aToken);
|
||||
IF_FREE(aToken);
|
||||
aToken = nsnull;
|
||||
}
|
||||
else result=NS_OK;
|
||||
}
|
||||
AddToken(aToken,result,&mTokenDeque,theRecycler);
|
||||
AddToken(aToken,result,&mTokenDeque,theAllocator);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -741,19 +730,19 @@ nsresult nsHTMLTokenizer::ConsumeSpecialMarkup(PRUnichar aChar,CToken*& aToken,n
|
||||
theBuffer.Mid(theBufCopy,aScanner.GetOffset(),20);
|
||||
theBufCopy.ToUpperCase();
|
||||
PRInt32 theIndex=theBufCopy.Find("DOCTYPE");
|
||||
CTokenRecycler* theRecycler=(CTokenRecycler*)GetTokenRecycler();
|
||||
nsTokenAllocator* theAllocator=this->GetTokenAllocator();
|
||||
|
||||
if(theIndex==kNotFound) {
|
||||
if('['==theBufCopy.CharAt(0))
|
||||
aToken = theRecycler->CreateTokenOfType(eToken_cdatasection,eHTMLTag_comment);
|
||||
else aToken = theRecycler->CreateTokenOfType(eToken_comment,eHTMLTag_comment);
|
||||
aToken = theAllocator->CreateTokenOfType(eToken_cdatasection,eHTMLTag_comment);
|
||||
else aToken = theAllocator->CreateTokenOfType(eToken_comment,eHTMLTag_comment);
|
||||
}
|
||||
else
|
||||
aToken = theRecycler->CreateTokenOfType(eToken_doctypeDecl,eHTMLTag_markupDecl);
|
||||
aToken = theAllocator->CreateTokenOfType(eToken_doctypeDecl,eHTMLTag_markupDecl);
|
||||
|
||||
if(aToken) {
|
||||
result=aToken->Consume(aChar,aScanner,mParseMode);
|
||||
AddToken(aToken,result,&mTokenDeque,theRecycler);
|
||||
AddToken(aToken,result,&mTokenDeque,theAllocator);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -768,12 +757,12 @@ nsresult nsHTMLTokenizer::ConsumeSpecialMarkup(PRUnichar aChar,CToken*& aToken,n
|
||||
* @return error code
|
||||
*/
|
||||
nsresult nsHTMLTokenizer::ConsumeNewline(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner){
|
||||
CTokenRecycler* theRecycler=(CTokenRecycler*)GetTokenRecycler();
|
||||
aToken=theRecycler->CreateTokenOfType(eToken_newline,eHTMLTag_newline);
|
||||
nsTokenAllocator* theAllocator=this->GetTokenAllocator();
|
||||
aToken=theAllocator->CreateTokenOfType(eToken_newline,eHTMLTag_newline);
|
||||
nsresult result=NS_OK;
|
||||
if(aToken) {
|
||||
result=aToken->Consume(aChar,aScanner,mParseMode);
|
||||
AddToken(aToken,result,&mTokenDeque,theRecycler);
|
||||
AddToken(aToken,result,&mTokenDeque,theAllocator);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -789,12 +778,12 @@ nsresult nsHTMLTokenizer::ConsumeNewline(PRUnichar aChar,CToken*& aToken,nsScann
|
||||
* @return error code
|
||||
*/
|
||||
nsresult nsHTMLTokenizer::ConsumeProcessingInstruction(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner){
|
||||
CTokenRecycler* theRecycler=(CTokenRecycler*)GetTokenRecycler();
|
||||
aToken=theRecycler->CreateTokenOfType(eToken_instruction,eHTMLTag_unknown);
|
||||
nsTokenAllocator* theAllocator=this->GetTokenAllocator();
|
||||
aToken=theAllocator->CreateTokenOfType(eToken_instruction,eHTMLTag_unknown);
|
||||
nsresult result=NS_OK;
|
||||
if(aToken) {
|
||||
result=aToken->Consume(aChar,aScanner,mParseMode);
|
||||
AddToken(aToken,result,&mTokenDeque,theRecycler);
|
||||
AddToken(aToken,result,&mTokenDeque,theAllocator);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -61,10 +61,10 @@ public:
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual nsresult WillTokenize(PRBool aIsFinalChunk);
|
||||
virtual nsresult WillTokenize(PRBool aIsFinalChunk,nsTokenAllocator* aTokenAllocator);
|
||||
virtual nsresult ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens);
|
||||
virtual nsresult DidTokenize(PRBool aIsFinalChunk);
|
||||
virtual nsITokenRecycler* GetTokenRecycler(void);
|
||||
virtual nsTokenAllocator* GetTokenAllocator(void);
|
||||
|
||||
virtual CToken* PushTokenFront(CToken* theToken);
|
||||
virtual CToken* PushToken(CToken* theToken);
|
||||
@ -74,7 +74,6 @@ public:
|
||||
virtual PRInt32 GetCount(void);
|
||||
|
||||
virtual void PrependTokens(nsDeque& aDeque);
|
||||
static void FreeTokenRecycler(void);
|
||||
|
||||
protected:
|
||||
|
||||
@ -93,15 +92,16 @@ protected:
|
||||
|
||||
virtual void RecordTrailingContent(CStartToken* aStartToken,nsScanner& aScanner);
|
||||
|
||||
static void AddToken(CToken*& aToken,nsresult aResult,nsDeque* aDeque,CTokenRecycler* aRecycler);
|
||||
static void AddToken(CToken*& aToken,nsresult aResult,nsDeque* aDeque,nsTokenAllocator* aTokenAllocator);
|
||||
|
||||
nsDeque mTokenDeque;
|
||||
PRBool mDoXMLEmptyTags;
|
||||
PRInt32 mParseMode;
|
||||
eParserDocType mDocType;
|
||||
PRBool mRecordTrailingContent;
|
||||
eParserCommands mParserCommand; //tells us to viewcontent/viewsource/viewerrors...
|
||||
nsAutoString mScratch;
|
||||
nsDeque mTokenDeque;
|
||||
PRBool mDoXMLEmptyTags;
|
||||
PRInt32 mParseMode;
|
||||
eParserDocType mDocType;
|
||||
PRBool mRecordTrailingContent;
|
||||
eParserCommands mParserCommand; //tells us to viewcontent/viewsource/viewerrors...
|
||||
nsAutoString mScratch;
|
||||
nsTokenAllocator* mTokenAllocator;
|
||||
};
|
||||
|
||||
extern NS_HTMLPARS nsresult NS_NewHTMLTokenizer( nsITokenizer** aInstancePtrResult,
|
||||
|
@ -134,7 +134,7 @@ CStartToken::CStartToken(const nsString& aName,eHTMLTags aTag) : CHTMLToken(aNam
|
||||
void CStartToken::Reinitialize(PRInt32 aTag, const nsString& aString){
|
||||
CToken::Reinitialize(aTag,aString);
|
||||
mAttributed=PR_FALSE;
|
||||
mUseCount=0; //assume recycling is needed by default.
|
||||
mUseCount=1;
|
||||
mEmpty=PR_FALSE;
|
||||
mOrigin=-1;
|
||||
mTrailingContent.Truncate();
|
||||
@ -1134,6 +1134,7 @@ nsresult CNewlineToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMo
|
||||
* @return
|
||||
*/
|
||||
CAttributeToken::CAttributeToken() : CHTMLToken(eHTMLTag_unknown) {
|
||||
mLastAttribute=PR_FALSE;
|
||||
mHasEqualWithoutValue=PR_FALSE;
|
||||
}
|
||||
|
||||
@ -1401,8 +1402,14 @@ nsresult CAttributeToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 a
|
||||
if(result==kBadStringLiteral) {
|
||||
result=ConsumeAttributeValueText(aChar,mTextValue,aScanner);
|
||||
}
|
||||
if(!aRetainWhitespace)
|
||||
// According to spec. we ( who? ) should ignore linefeeds. But look,
|
||||
// even the carriage return was getting stripped ( wonder why! ) -
|
||||
// Ref. to bug 15204. Okay, so the spec. told us to ignore linefeeds,
|
||||
// bug then what about bug 47535 ? Should we preserve everything then?
|
||||
// Well, let's make it so! Commenting out the next two lines..
|
||||
/*if(!aRetainWhitespace)
|
||||
mTextValue.StripChars("\r\n"); //per the HTML spec, ignore linefeeds...
|
||||
*/
|
||||
}
|
||||
else if(kGreaterThan==aChar){
|
||||
mHasEqualWithoutValue=PR_TRUE;
|
||||
|
@ -279,6 +279,7 @@ class CAttributeToken: public CHTMLToken {
|
||||
CAttributeToken();
|
||||
CAttributeToken(const nsString& aString);
|
||||
CAttributeToken(const nsString& aKey, const nsString& aString);
|
||||
~CAttributeToken() { mTextKey.SetCapacity(0);}
|
||||
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
|
||||
virtual const char* GetClassName(void);
|
||||
virtual PRInt32 GetTokenType(void);
|
||||
|
@ -143,7 +143,7 @@ class nsIDTD : public nsISupports {
|
||||
NS_IMETHOD GetTokenizer(nsITokenizer*& aTokenizer)=0;
|
||||
|
||||
|
||||
virtual nsITokenRecycler* GetTokenRecycler(void)=0;
|
||||
virtual nsTokenAllocator* GetTokenAllocator(void)=0;
|
||||
|
||||
/**
|
||||
* If the parse process gets interrupted midway, this method is called by the
|
||||
|
@ -155,6 +155,12 @@ class nsIParserNode : public nsISupports {
|
||||
*/
|
||||
virtual void GetSource(nsString& aString)=0;
|
||||
|
||||
/** Release all the objects you're holding
|
||||
* @update harishd 08/02/00
|
||||
* @return void
|
||||
*/
|
||||
virtual nsresult ReleaseAll()=0;
|
||||
|
||||
/*
|
||||
* Get and set the ID attribute atom for this node.
|
||||
* See http://www.w3.org/TR/1998/REC-xml-19980210#sec-attribute-types
|
||||
|
@ -37,20 +37,11 @@
|
||||
class CToken;
|
||||
class nsScanner;
|
||||
class nsDeque;
|
||||
class nsTokenAllocator;
|
||||
|
||||
#define NS_ITOKENIZER_IID \
|
||||
{0xe4238ddc, 0x9eb6, 0x11d2, {0xba, 0xa5, 0x0, 0x10, 0x4b, 0x98, 0x3f, 0xd4 }}
|
||||
|
||||
|
||||
/***************************************************************
|
||||
Notes:
|
||||
***************************************************************/
|
||||
|
||||
class nsITokenRecycler {
|
||||
public:
|
||||
virtual void RecycleToken(CToken* aToken)=0;
|
||||
};
|
||||
|
||||
/**
|
||||
* This interface is used as a callback to objects interested
|
||||
* in observing the token stream created from the parse process.
|
||||
@ -67,10 +58,10 @@ public:
|
||||
class nsITokenizer : public nsISupports {
|
||||
public:
|
||||
|
||||
virtual nsresult WillTokenize(PRBool aIsFinalChunk)=0;
|
||||
virtual nsresult WillTokenize(PRBool aIsFinalChunk,nsTokenAllocator* aTokenAllocator)=0;
|
||||
virtual nsresult ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens)=0;
|
||||
virtual nsresult DidTokenize(PRBool aIsFinalChunk)=0;
|
||||
virtual nsITokenRecycler* GetTokenRecycler(void)=0;
|
||||
virtual nsTokenAllocator* GetTokenAllocator(void)=0;
|
||||
|
||||
virtual CToken* PushTokenFront(CToken* aToken)=0;
|
||||
virtual CToken* PushToken(CToken* aToken)=0;
|
||||
|
@ -2387,7 +2387,7 @@ PRBool nsParser::WillTokenize(PRBool aIsFinalChunk){
|
||||
nsITokenizer* theTokenizer=0;
|
||||
nsresult result=mParserContext->mDTD->GetTokenizer(theTokenizer);
|
||||
if (theTokenizer) {
|
||||
result = theTokenizer->WillTokenize(aIsFinalChunk);
|
||||
result = theTokenizer->WillTokenize(aIsFinalChunk,&mTokenAllocator);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -411,6 +411,7 @@ protected:
|
||||
nsString mCommandStr;
|
||||
|
||||
nsParserBundle* mBundle;
|
||||
nsTokenAllocator mTokenAllocator;
|
||||
|
||||
public:
|
||||
MOZ_TIMER_DECLARE(mParseTime)
|
||||
|
@ -208,9 +208,6 @@ nsParserModule::Shutdown()
|
||||
if (mInitialized) {
|
||||
nsHTMLTags::ReleaseTable();
|
||||
nsHTMLEntities::ReleaseTable();
|
||||
nsHTMLTokenizer::FreeTokenRecycler();
|
||||
nsXMLTokenizer::FreeTokenRecycler();
|
||||
nsExpatTokenizer::FreeTokenRecycler();
|
||||
nsDTDContext::ReleaseGlobalObjects();
|
||||
nsParser::FreeSharedObjects();
|
||||
mInitialized = PR_FALSE;
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "nshtmlpars.h"
|
||||
#include "nsITokenizer.h"
|
||||
#include "nsDTDUtils.h"
|
||||
|
||||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
@ -45,7 +46,7 @@ const nsString& GetEmptyString() {
|
||||
* @param aToken -- token to init internal token
|
||||
* @return
|
||||
*/
|
||||
nsCParserNode::nsCParserNode(CToken* aToken,PRInt32 aLineNumber,nsITokenRecycler* aRecycler):
|
||||
nsCParserNode::nsCParserNode(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator):
|
||||
nsIParserNode() {
|
||||
NS_INIT_REFCNT();
|
||||
MOZ_COUNT_CTOR(nsCParserNode);
|
||||
@ -55,17 +56,18 @@ nsCParserNode::nsCParserNode(CToken* aToken,PRInt32 aLineNumber,nsITokenRecycler
|
||||
mAttributes=0;
|
||||
mLineNumber=aLineNumber;
|
||||
mToken=aToken;
|
||||
mRecycler=aRecycler;
|
||||
IF_HOLD(mToken);
|
||||
mTokenAllocator=aTokenAllocator;
|
||||
mUseCount=0;
|
||||
mSkippedContent=0;
|
||||
mGenericState=PR_FALSE;
|
||||
}
|
||||
|
||||
static void RecycleTokens(nsITokenRecycler* aRecycler,nsDeque& aDeque) {
|
||||
static void RecycleTokens(nsTokenAllocator* aTokenAllocator,nsDeque& aDeque) {
|
||||
CToken* theToken=0;
|
||||
if(aRecycler) {
|
||||
if(aTokenAllocator) {
|
||||
while((theToken=(CToken*)aDeque.Pop())){
|
||||
aRecycler->RecycleToken(theToken);
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -79,31 +81,8 @@ static void RecycleTokens(nsITokenRecycler* aRecycler,nsDeque& aDeque) {
|
||||
* @return
|
||||
*/
|
||||
nsCParserNode::~nsCParserNode() {
|
||||
if(mAttributes) {
|
||||
|
||||
//fixed a bug that patrick found, where the attributes deque existed
|
||||
//but was empty. In that case, the attributes deque itself was leaked.
|
||||
//THANKS PATRICK!
|
||||
|
||||
if(mRecycler) {
|
||||
RecycleTokens(mRecycler,*mAttributes);
|
||||
}
|
||||
else {
|
||||
CToken* theToken=(CToken*)mAttributes->Pop();
|
||||
while(theToken){
|
||||
delete theToken;
|
||||
theToken=(CToken*)mAttributes->Pop();
|
||||
}
|
||||
}
|
||||
delete mAttributes;
|
||||
mAttributes=0;
|
||||
}
|
||||
if(mSkippedContent) {
|
||||
delete mSkippedContent;
|
||||
}
|
||||
mSkippedContent=0;
|
||||
|
||||
MOZ_COUNT_DTOR(nsCParserNode);
|
||||
ReleaseAll();
|
||||
}
|
||||
|
||||
|
||||
@ -118,12 +97,13 @@ NS_IMPL_RELEASE(nsCParserNode)
|
||||
* @return
|
||||
*/
|
||||
|
||||
nsresult nsCParserNode::Init(CToken* aToken,PRInt32 aLineNumber,nsITokenRecycler* aRecycler) {
|
||||
nsresult nsCParserNode::Init(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator) {
|
||||
mLineNumber=aLineNumber;
|
||||
mRecycler=aRecycler;
|
||||
mTokenAllocator=aTokenAllocator;
|
||||
if(mAttributes && (mAttributes->GetSize()))
|
||||
RecycleTokens(mRecycler,*mAttributes);
|
||||
RecycleTokens(mTokenAllocator,*mAttributes);
|
||||
mToken=aToken;
|
||||
IF_HOLD(mToken);
|
||||
mGenericState=PR_FALSE;
|
||||
mUseCount=0;
|
||||
if(mSkippedContent) {
|
||||
@ -383,6 +363,38 @@ void nsCParserNode::GetSource(nsString& aString) {
|
||||
aString.AppendWithConversion(">");
|
||||
}
|
||||
|
||||
/** Release all the objects you're holding to.
|
||||
* @update harishd 08/02/00
|
||||
* @return void
|
||||
*/
|
||||
nsresult nsCParserNode::ReleaseAll() {
|
||||
if(mAttributes) {
|
||||
|
||||
//fixed a bug that patrick found, where the attributes deque existed
|
||||
//but was empty. In that case, the attributes deque itself was leaked.
|
||||
//THANKS PATRICK!
|
||||
|
||||
if(mTokenAllocator) {
|
||||
RecycleTokens(mTokenAllocator,*mAttributes);
|
||||
}
|
||||
else {
|
||||
CToken* theToken=(CToken*)mAttributes->Pop();
|
||||
while(theToken){
|
||||
IF_FREE(theToken);
|
||||
theToken=(CToken*)mAttributes->Pop();
|
||||
}
|
||||
}
|
||||
delete mAttributes;
|
||||
mAttributes=0;
|
||||
}
|
||||
if(mSkippedContent) {
|
||||
delete mSkippedContent;
|
||||
}
|
||||
IF_FREE(mToken);
|
||||
mSkippedContent=0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCParserNode::GetIDAttributeAtom(nsIAtom** aResult) const
|
||||
{
|
||||
@ -400,3 +412,4 @@ nsCParserNode::SetIDAttributeAtom(nsIAtom* aID)
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@
|
||||
#include "nsParserCIID.h"
|
||||
#include "nsDeque.h"
|
||||
|
||||
class nsITokenRecycler;
|
||||
class nsTokenAllocator;
|
||||
|
||||
class nsCParserNode : public nsIParserNode {
|
||||
|
||||
@ -59,7 +59,7 @@ class nsCParserNode : public nsIParserNode {
|
||||
* @update gess5/11/98
|
||||
* @param aToken is the token this node "refers" to
|
||||
*/
|
||||
nsCParserNode(CToken* aToken=nsnull,PRInt32 aLineNumber=1,nsITokenRecycler* aRecycler=0);
|
||||
nsCParserNode(CToken* aToken=nsnull,PRInt32 aLineNumber=1,nsTokenAllocator* aTokenAllocator=0);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
@ -71,7 +71,7 @@ class nsCParserNode : public nsIParserNode {
|
||||
* Init
|
||||
* @update gess5/11/98
|
||||
*/
|
||||
virtual nsresult Init(CToken* aToken=nsnull,PRInt32 aLineNumber=1,nsITokenRecycler* aRecycler=0);
|
||||
virtual nsresult Init(CToken* aToken=nsnull,PRInt32 aLineNumber=1,nsTokenAllocator* aTokenAllocator=0);
|
||||
|
||||
/**
|
||||
* Retrieve the name of the node
|
||||
@ -196,6 +196,12 @@ class nsCParserNode : public nsIParserNode {
|
||||
*/
|
||||
virtual PRBool GetGenericState(void) const {return mGenericState;}
|
||||
virtual void SetGenericState(PRBool aState) {mGenericState=aState;}
|
||||
|
||||
/** Release all the objects you're holding
|
||||
* @update harishd 08/02/00
|
||||
* @return void
|
||||
*/
|
||||
virtual nsresult ReleaseAll();
|
||||
|
||||
PRInt32 mLineNumber;
|
||||
CToken* mToken;
|
||||
@ -205,7 +211,7 @@ class nsCParserNode : public nsIParserNode {
|
||||
PRBool mGenericState;
|
||||
nsCOMPtr<nsIAtom> mIDAttributeAtom;
|
||||
|
||||
nsITokenRecycler* mRecycler;
|
||||
nsTokenAllocator* mTokenAllocator;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -23,7 +23,10 @@
|
||||
#include "nsToken.h"
|
||||
#include "nsScanner.h"
|
||||
|
||||
|
||||
#ifdef MATCH_CTOR_DTOR
|
||||
MOZ_DECL_CTOR_COUNTER(CToken);
|
||||
#endif
|
||||
|
||||
static int TokenCount=0;
|
||||
static int DelTokenCount=0;
|
||||
@ -41,13 +44,25 @@ int CToken::GetTokenCount(){return TokenCount-DelTokenCount;}
|
||||
* @update gess 7/21/98
|
||||
*/
|
||||
CToken::CToken(PRInt32 aTag) : mTextValue() {
|
||||
// Tokens are allocated through the arena ( not heap allocated..yay ).
|
||||
// We, therefore, don't need this macro anymore..
|
||||
#ifdef MATCH_CTOR_DTOR
|
||||
MOZ_COUNT_CTOR(CToken);
|
||||
mTypeID=aTag;
|
||||
#endif
|
||||
mAttrCount=0;
|
||||
TokenCount++;
|
||||
mOrigin=eSource;
|
||||
mUseCount=0;
|
||||
mNewlineCount=0;
|
||||
mTypeID=aTag;
|
||||
mOrigin=eSource;
|
||||
// Note that the use count starts with 1 instead of 0. This
|
||||
// is because of the assumption that any token created is in
|
||||
// use and therefore does not require an explicit addref, or
|
||||
// rather IF_HOLD. This, also, will make sure that tokens created
|
||||
// on the stack do not accidently hit the arena recycler.
|
||||
mUseCount=1;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
TokenCount++;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@ -57,13 +72,26 @@ CToken::CToken(PRInt32 aTag) : mTextValue() {
|
||||
* @param nsString--name of token
|
||||
*/
|
||||
CToken::CToken(const nsString& aName) : mTextValue(aName) {
|
||||
// Tokens are allocated through the arena ( not heap allocated..yay ).
|
||||
// We, therefore, don't need this macro anymore..
|
||||
#ifdef MATCH_CTOR_DTOR
|
||||
MOZ_COUNT_CTOR(CToken);
|
||||
#endif
|
||||
|
||||
mTypeID=0;
|
||||
mAttrCount=0;
|
||||
TokenCount++;
|
||||
mOrigin=eSource;
|
||||
mUseCount=0;
|
||||
mNewlineCount=0;
|
||||
mOrigin=eSource;
|
||||
// Note that the use count starts with 1 instead of 0. This
|
||||
// is because of the assumption that any token created is in
|
||||
// use and therefore does not require an explicit addref, or
|
||||
// rather IF_HOLD. This, also, will make sure that tokens created
|
||||
// on the stack do not accidently hit the arena recycler.
|
||||
mUseCount=1;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
TokenCount++;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@ -73,14 +101,27 @@ CToken::CToken(const nsString& aName) : mTextValue(aName) {
|
||||
* @param aName--char* containing name of token
|
||||
*/
|
||||
CToken::CToken(const char* aName) {
|
||||
// Tokens are allocated through the arena ( not heap allocated..yay ).
|
||||
// We, therefore, don't need this macro anymore..
|
||||
#ifdef MATCH_CTOR_DTOR
|
||||
MOZ_COUNT_CTOR(CToken);
|
||||
mTextValue.AssignWithConversion(aName);
|
||||
#endif
|
||||
|
||||
mTypeID=0;
|
||||
mAttrCount=0;
|
||||
TokenCount++;
|
||||
mOrigin=eSource;
|
||||
mUseCount=0;
|
||||
mNewlineCount=0;
|
||||
mOrigin=eSource;
|
||||
mTextValue.AssignWithConversion(aName);
|
||||
// Note that the use count starts with 1 instead of 0. This
|
||||
// is because of the assumption that any token created is in
|
||||
// use and therefore does not require an explicit addref, or
|
||||
// rather IF_HOLD. This, also, will make sure that tokens created
|
||||
// on the stack do not accidently hit the arena recycler.
|
||||
mUseCount=1;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
TokenCount++;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@ -89,10 +130,39 @@ CToken::CToken(const char* aName) {
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
CToken::~CToken() {
|
||||
// Tokens are allocated through the arena ( not heap allocated..yay ).
|
||||
// We, therefore, don't need this macro anymore..
|
||||
#ifdef MATCH_CTOR_DTOR
|
||||
MOZ_COUNT_DTOR(CToken);
|
||||
#endif
|
||||
DelTokenCount++;
|
||||
mUseCount=0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update harishd 08/01/00
|
||||
* @param aSize -
|
||||
* @param aArena - Allocate memory from this pool.
|
||||
*/
|
||||
void *
|
||||
CToken::operator new (size_t aSize, nsFixedSizeAllocator& anArena)
|
||||
{
|
||||
return (CToken*)anArena.Alloc(aSize);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @update harishd 08/01/00
|
||||
* @param aPtr - The memory that should be recycled/freed.
|
||||
* @param aSize - The size of memory that needs to be freed.
|
||||
*/
|
||||
void
|
||||
CToken::operator delete (void* aPtr,size_t aSize)
|
||||
{
|
||||
nsFixedSizeAllocator::Free(aPtr,aSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets called when a token is about to be reused
|
||||
@ -107,11 +177,16 @@ void CToken::Reinitialize(PRInt32 aTag, const nsString& aString){
|
||||
mTextValue.Truncate(0);
|
||||
else mTextValue=aString;
|
||||
mAttrCount=0;
|
||||
mTypeID=aTag;
|
||||
mAttrCount=0;
|
||||
mOrigin=eSource;
|
||||
mUseCount=0;
|
||||
mNewlineCount=0;
|
||||
mTypeID=aTag;
|
||||
mOrigin=eSource;
|
||||
// Note that the use count starts with 1 instead of 0. This
|
||||
// is because of the assumption that any token created is in
|
||||
// use and therefore does not require an explicit addref, or
|
||||
// rather IF_HOLD. This, also, will make sure that tokens created
|
||||
// on the stack do not accidently hit the arena recycler.
|
||||
mUseCount=1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -44,11 +44,11 @@
|
||||
#include <iostream.h>
|
||||
#include "nsError.h"
|
||||
#include "nsFileSpec.h"
|
||||
#include "nsFixedSizeAllocator.h"
|
||||
|
||||
|
||||
class nsScanner;
|
||||
|
||||
|
||||
/**
|
||||
* Token objects represent sequences of characters as they
|
||||
* are consumed from the input stream (URL). While they're
|
||||
@ -63,6 +63,35 @@ class CToken {
|
||||
|
||||
enum eTokenOrigin {eSource,eResidualStyle};
|
||||
|
||||
/**
|
||||
* Use the arena to allocate memory
|
||||
* @update harishd 08/02/00
|
||||
* @param aSize - Allocation size.
|
||||
* @param anArena - Used for allocating memory.
|
||||
*/
|
||||
void* operator new(size_t aSize,nsFixedSizeAllocator& anArena);
|
||||
|
||||
/**
|
||||
* Free up the memory in the arena.
|
||||
* @update harishd 08/02/00
|
||||
* @param aPtr - Memory that's to be freed.
|
||||
*/
|
||||
void operator delete(void* aPtr,size_t aSize);
|
||||
|
||||
/**
|
||||
* Make a note on number of times you have been referenced
|
||||
* @update harishd 08/02/00
|
||||
*/
|
||||
void AddRef() { mUseCount++; }
|
||||
|
||||
/**
|
||||
* Free yourself if no one is holding you.
|
||||
* @update harishd 08/02/00
|
||||
*/
|
||||
void Release() {
|
||||
if(--mUseCount==0)
|
||||
delete this;
|
||||
}
|
||||
/**
|
||||
* Default constructor
|
||||
* @update gess7/21/98
|
||||
@ -214,13 +243,14 @@ class CToken {
|
||||
static int GetTokenCount();
|
||||
|
||||
eTokenOrigin mOrigin;
|
||||
PRInt32 mUseCount;
|
||||
PRInt32 mNewlineCount;
|
||||
|
||||
protected:
|
||||
|
||||
PRInt32 mTypeID;
|
||||
PRInt16 mAttrCount;
|
||||
nsString mTextValue;
|
||||
PRInt32 mUseCount;
|
||||
};
|
||||
|
||||
|
||||
|
@ -352,7 +352,7 @@ NS_IMETHODIMP CValidDTD::HandleToken(CToken* aToken,nsIParser* aParser) {
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsITokenRecycler* CValidDTD::GetTokenRecycler(void){
|
||||
nsTokenAllocator* CValidDTD::GetTokenAllocator(void){
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -216,7 +216,7 @@ class CValidDTD : public nsIDTD {
|
||||
* @update gess8/4/98
|
||||
* @return ptr to recycler (or null)
|
||||
*/
|
||||
virtual nsITokenRecycler* GetTokenRecycler(void);
|
||||
virtual nsTokenAllocator* GetTokenAllocator(void);
|
||||
|
||||
/**
|
||||
* Use this id you want to stop the building content model
|
||||
|
@ -75,8 +75,6 @@ static NS_DEFINE_IID(kIDTDIID, NS_IDTD_IID);
|
||||
static NS_DEFINE_IID(kClassIID, NS_VIEWSOURCE_HTML_IID);
|
||||
static int gErrorThreshold = 10;
|
||||
|
||||
static CTokenRecycler* gTokenRecycler=0;
|
||||
|
||||
//#define rickgdebug
|
||||
#ifdef rickgdebug
|
||||
#include <fstream.h>
|
||||
@ -228,6 +226,7 @@ CViewSourceHTML::CViewSourceHTML() : mTags(), mErrors() {
|
||||
mTokenizer=0;
|
||||
mDocType=eHTML3Text;
|
||||
mValidator=0;
|
||||
mHasOpenRoot=PR_FALSE;
|
||||
|
||||
//set this to 1 if you want to see errors in your HTML markup.
|
||||
char* theEnvString = PR_GetEnv("MOZ_VALIDATE_HTML");
|
||||
@ -348,14 +347,6 @@ nsresult CViewSourceHTML::WillBuildModel( const CParserContext& aParserContext,
|
||||
(*gDumpFile) << "<viewsource xmlns=\"viewsource\">" << endl;
|
||||
#endif
|
||||
|
||||
//now let's automatically open the root container...
|
||||
CToken theToken("viewsource");
|
||||
nsCParserNode theNode(&theToken,0);
|
||||
|
||||
CAttributeToken *theAttr=new CAttributeToken(NS_ConvertToString("xmlns"), NS_ConvertToString("http://www.mozilla.org/viewsource"));
|
||||
if(theAttr)
|
||||
theNode.AddAttribute(theAttr);
|
||||
mSink->OpenContainer(theNode);
|
||||
}
|
||||
|
||||
|
||||
@ -385,25 +376,40 @@ NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aToke
|
||||
|
||||
nsITokenizer* oldTokenizer=mTokenizer;
|
||||
mTokenizer=aTokenizer;
|
||||
gTokenRecycler=(CTokenRecycler*)mTokenizer->GetTokenRecycler();
|
||||
|
||||
if(gTokenRecycler) {
|
||||
|
||||
while(NS_SUCCEEDED(result)){
|
||||
CToken* theToken=mTokenizer->PopToken();
|
||||
if(theToken) {
|
||||
result=HandleToken(theToken,aParser);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
gTokenRecycler->RecycleToken(theToken);
|
||||
}
|
||||
else if(NS_ERROR_HTMLPARSER_BLOCK!=result){
|
||||
mTokenizer->PushTokenFront(theToken);
|
||||
}
|
||||
// theRootDTD->Verify(kEmptyString,aParser);
|
||||
}
|
||||
else break;
|
||||
}//while
|
||||
if(!mHasOpenRoot) {
|
||||
//now let's automatically open the root container...
|
||||
CToken theToken("viewsource");
|
||||
nsCParserNode theNode(&theToken,0);
|
||||
|
||||
CAttributeToken *theAttr=nsnull;
|
||||
nsTokenAllocator* theAllocator=mTokenizer->GetTokenAllocator();
|
||||
if(theAllocator) {
|
||||
theAttr=(CAttributeToken*)theAllocator->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown,NS_ConvertToString("http://www.mozilla.org/viewsource"));
|
||||
nsString& theKey=theAttr->GetKey();
|
||||
theKey=NS_ConvertToString("xmlns");
|
||||
}
|
||||
if(theAttr)
|
||||
theNode.AddAttribute(theAttr);
|
||||
result=mSink->OpenContainer(theNode);
|
||||
if(NS_SUCCEEDED(result)) mHasOpenRoot=PR_TRUE;
|
||||
}
|
||||
|
||||
while(NS_SUCCEEDED(result)){
|
||||
CToken* theToken=mTokenizer->PopToken();
|
||||
if(theToken) {
|
||||
result=HandleToken(theToken,aParser);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
else if(NS_ERROR_HTMLPARSER_BLOCK!=result){
|
||||
mTokenizer->PushTokenFront(theToken);
|
||||
}
|
||||
// theRootDTD->Verify(kEmptyString,aParser);
|
||||
}
|
||||
else break;
|
||||
}//while
|
||||
|
||||
mTokenizer=oldTokenizer;
|
||||
}
|
||||
else result=NS_ERROR_HTMLPARSER_BADTOKENIZER;
|
||||
@ -493,12 +499,12 @@ NS_IMETHODIMP CViewSourceHTML::DidBuildModel(nsresult anErrorCode,PRBool aNotify
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsITokenRecycler* CViewSourceHTML::GetTokenRecycler(void){
|
||||
nsTokenAllocator* CViewSourceHTML::GetTokenAllocator(void){
|
||||
nsITokenizer* theTokenizer=0;
|
||||
nsresult result=GetTokenizer(theTokenizer);
|
||||
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
return theTokenizer->GetTokenRecycler();
|
||||
return theTokenizer->GetTokenAllocator();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -989,7 +995,6 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser) {
|
||||
result=theService->Notify(theTag,theContext.mTokenNode,theDocID, NS_ConvertToString(kViewSourceCommand), mParser);
|
||||
}
|
||||
}
|
||||
theContext.mTokenNode.Init(0,0,gTokenRecycler); //now recycle.
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1067,9 +1072,7 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser) {
|
||||
result=NS_OK;
|
||||
}//switch
|
||||
|
||||
while(theContext.mTokenNode.PopAttributeToken()){
|
||||
//dump the attributes since they're on the stack...
|
||||
}
|
||||
theContext.mTokenNode.ReleaseAll();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ class CViewSourceHTML: public nsIDTD {
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
virtual nsITokenRecycler* GetTokenRecycler(void);
|
||||
virtual nsTokenAllocator* GetTokenAllocator(void);
|
||||
|
||||
/**
|
||||
*
|
||||
@ -279,6 +279,7 @@ protected:
|
||||
nsString mTags;
|
||||
nsString mErrors;
|
||||
PRBool mShowErrors;
|
||||
PRBool mHasOpenRoot;
|
||||
};
|
||||
|
||||
extern NS_HTMLPARS nsresult NS_NewViewSourceHTML(nsIDTD** aInstancePtrResult);
|
||||
|
@ -249,7 +249,7 @@ NS_IMETHODIMP CWellFormedDTD::BuildModel(nsIParser* aParser,nsITokenizer* aToken
|
||||
if(aTokenizer) {
|
||||
nsHTMLTokenizer* oldTokenizer=mTokenizer;
|
||||
mTokenizer=(nsHTMLTokenizer*)aTokenizer;
|
||||
nsITokenRecycler* theRecycler=aTokenizer->GetTokenRecycler();
|
||||
nsTokenAllocator* theAllocator=aTokenizer->GetTokenAllocator();
|
||||
|
||||
while(NS_SUCCEEDED(result)){
|
||||
if(mDTDState!=NS_ERROR_HTMLPARSER_STOPPARSING) {
|
||||
@ -257,7 +257,7 @@ NS_IMETHODIMP CWellFormedDTD::BuildModel(nsIParser* aParser,nsITokenizer* aToken
|
||||
if(theToken) {
|
||||
result=HandleToken(theToken,aParser);
|
||||
if(NS_SUCCEEDED(result) || (NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
theRecycler->RecycleToken(theToken);
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
else {
|
||||
// if(NS_ERROR_HTMLPARSER_BLOCK!=result){
|
||||
@ -321,13 +321,13 @@ NS_IMETHODIMP CWellFormedDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifyS
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsITokenRecycler* CWellFormedDTD::GetTokenRecycler(void){
|
||||
nsTokenAllocator* CWellFormedDTD::GetTokenAllocator(void){
|
||||
nsITokenizer* theTokenizer=0;
|
||||
|
||||
nsresult result=GetTokenizer(theTokenizer);
|
||||
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
return theTokenizer->GetTokenRecycler();
|
||||
return theTokenizer->GetTokenAllocator();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -348,8 +348,8 @@ nsresult CWellFormedDTD::Terminate(nsIParser* aParser)
|
||||
nsresult result=NS_OK;
|
||||
|
||||
if(mTokenizer) {
|
||||
nsITokenRecycler* theRecycler=mTokenizer->GetTokenRecycler();
|
||||
if(theRecycler) {
|
||||
nsTokenAllocator* theAllocator=mTokenizer->GetTokenAllocator();
|
||||
if(theAllocator) {
|
||||
eHTMLTokenTypes theType=eToken_unknown;
|
||||
|
||||
mDTDState=NS_ERROR_HTMLPARSER_STOPPARSING;
|
||||
@ -361,7 +361,7 @@ nsresult CWellFormedDTD::Terminate(nsIParser* aParser)
|
||||
if(theType==eToken_error) {
|
||||
result=HandleToken(theToken,aParser);
|
||||
}
|
||||
theRecycler->RecycleToken(theToken);
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
else break;
|
||||
}//while
|
||||
@ -552,7 +552,7 @@ nsresult CWellFormedDTD::HandleLeafToken(CToken* aToken) {
|
||||
|
||||
nsresult result=NS_OK;
|
||||
|
||||
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenRecycler());
|
||||
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenAllocator());
|
||||
result= (mSink)? mSink->AddLeaf(theNode):NS_OK;
|
||||
return result;
|
||||
}
|
||||
@ -575,7 +575,7 @@ nsresult CWellFormedDTD::HandleCommentToken(CToken* aToken) {
|
||||
|
||||
mLineNumber += (aToken->GetStringValueXXX()).CountChar(kNewLine);
|
||||
|
||||
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenRecycler());
|
||||
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenAllocator());
|
||||
result=(mSink)? mSink->AddComment(theNode):NS_OK;
|
||||
|
||||
return result;
|
||||
@ -596,7 +596,7 @@ nsresult CWellFormedDTD::HandleProcessingInstructionToken(CToken* aToken) {
|
||||
|
||||
nsresult result=NS_OK;
|
||||
|
||||
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenRecycler());
|
||||
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenAllocator());
|
||||
result=(mSink)? mSink->AddProcessingInstruction(theNode):NS_OK;
|
||||
return result;
|
||||
}
|
||||
@ -616,7 +616,7 @@ nsresult CWellFormedDTD::HandleStartToken(CToken* aToken) {
|
||||
|
||||
nsresult result=NS_OK;
|
||||
|
||||
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenRecycler());
|
||||
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenAllocator());
|
||||
PRInt16 attrCount=aToken->GetAttributeCount();
|
||||
|
||||
if(0<attrCount){ //go collect the attributes...
|
||||
@ -667,7 +667,7 @@ nsresult CWellFormedDTD::HandleEndToken(CToken* aToken) {
|
||||
|
||||
nsresult result=NS_OK;
|
||||
|
||||
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenRecycler());
|
||||
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenAllocator());
|
||||
result=(mSink)? mSink->CloseContainer(theNode):NS_OK;
|
||||
return result;
|
||||
}
|
||||
@ -689,7 +689,7 @@ nsresult CWellFormedDTD::HandleErrorToken(CToken* aToken) {
|
||||
nsresult result=NS_OK;
|
||||
|
||||
if(mTokenizer) {
|
||||
nsITokenRecycler* theRecycler=mTokenizer->GetTokenRecycler();
|
||||
nsTokenAllocator* theAllocator=mTokenizer->GetTokenAllocator();
|
||||
|
||||
// Cycle through the remaining tokens in the token stream and handle them
|
||||
// These tokens were added so that content objects for the error message
|
||||
@ -715,7 +715,7 @@ nsresult CWellFormedDTD::HandleErrorToken(CToken* aToken) {
|
||||
// Do nothing
|
||||
break;
|
||||
}
|
||||
if(theRecycler) theRecycler->RecycleToken(token);
|
||||
IF_FREE(token);
|
||||
}
|
||||
else
|
||||
break;
|
||||
@ -758,7 +758,7 @@ nsresult CWellFormedDTD::HandleDocTypeDeclToken(CToken* aToken) {
|
||||
|
||||
nsresult result=NS_OK;
|
||||
|
||||
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenRecycler());
|
||||
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenAllocator());
|
||||
result = (mSink)? mSink->AddDocTypeDecl(theNode, 0):NS_OK;
|
||||
return result;
|
||||
}
|
||||
|
@ -201,7 +201,7 @@ class CWellFormedDTD : public nsIDTD {
|
||||
* @update gess8/4/98
|
||||
* @return ptr to recycler (or null)
|
||||
*/
|
||||
virtual nsITokenRecycler* GetTokenRecycler(void);
|
||||
virtual nsTokenAllocator* GetTokenAllocator(void);
|
||||
|
||||
/**
|
||||
* Use this id you want to stop the building content model
|
||||
|
@ -398,7 +398,7 @@ nsresult nsXIFDTD::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsITok
|
||||
|
||||
if(mTokenizer) {
|
||||
|
||||
mTokenRecycler=(CTokenRecycler*)mTokenizer->GetTokenRecycler();
|
||||
mTokenAllocator=mTokenizer->GetTokenAllocator();
|
||||
result=mXIFContext->GetNodeRecycler(mNodeRecycler);
|
||||
|
||||
if(NS_FAILED(result)) return result;
|
||||
@ -490,8 +490,6 @@ nsresult nsXIFDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
||||
result=WillHandleToken(aToken,theType);
|
||||
|
||||
if(result==NS_OK) {
|
||||
|
||||
aToken->mUseCount=0; //assume every token coming into this system needs recycling.
|
||||
|
||||
switch(theType) {
|
||||
case eToken_text:
|
||||
@ -520,13 +518,10 @@ nsresult nsXIFDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
||||
*/
|
||||
|
||||
nsresult nsXIFDTD::DidHandleToken(CToken* aToken, nsresult aResult) {
|
||||
NS_ASSERTION(mTokenRecycler!=nsnull,"We need a recycler");
|
||||
NS_ASSERTION(mTokenAllocator!=nsnull,"We need a allocator");
|
||||
nsresult result=aResult;
|
||||
if(NS_SUCCEEDED(result) || (NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
if(aToken) {
|
||||
if(0>=aToken->mUseCount)
|
||||
if(mTokenRecycler) mTokenRecycler->RecycleToken(aToken);
|
||||
}
|
||||
IF_FREE(aToken);
|
||||
}
|
||||
else if(result==NS_ERROR_HTMLPARSER_STOPPARSING)
|
||||
mDTDState=result;
|
||||
@ -614,7 +609,7 @@ nsresult nsXIFDTD::HandleStartToken(CToken* aToken) {
|
||||
|
||||
//Begin by gathering up attributes...
|
||||
nsCParserNode* node=mNodeRecycler->CreateNode();
|
||||
node->Init(aToken,mLineNumber,mTokenRecycler);
|
||||
node->Init(aToken,mLineNumber,mTokenAllocator);
|
||||
|
||||
PRInt16 attrCount=aToken->GetAttributeCount();
|
||||
nsresult result=(0==attrCount) ? NS_OK : CollectAttributes(*node,attrCount);
|
||||
@ -655,7 +650,7 @@ nsresult nsXIFDTD::HandleStartToken(CToken* aToken) {
|
||||
}
|
||||
}
|
||||
|
||||
mNodeRecycler->RecycleNode(node,mTokenRecycler);
|
||||
mNodeRecycler->RecycleNode(node);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -720,7 +715,7 @@ nsresult nsXIFDTD::HandleContainer(nsIParserNode& aNode) {
|
||||
theTagID=nsHTMLTags::LookupTag(theTagName);
|
||||
|
||||
theNode->mToken->Reinitialize(theTagID,theTagName);
|
||||
theNode->Init(theNode->mToken,0,mTokenRecycler);
|
||||
theNode->Init(theNode->mToken,0,mTokenAllocator);
|
||||
}
|
||||
mXIFContext->Push(&aNode);
|
||||
}
|
||||
@ -810,8 +805,8 @@ nsresult nsXIFDTD::HandleCommentToken(CToken* aToken, nsIParserNode& aNode) {
|
||||
eHTMLTokenTypes type=(eHTMLTokenTypes)aToken->GetTokenType();
|
||||
|
||||
if(type==eToken_start) {
|
||||
nsITokenRecycler* recycler=(mTokenizer)? mTokenizer->GetTokenRecycler():nsnull;
|
||||
if(recycler) {
|
||||
nsTokenAllocator* allocator=(mTokenizer)? mTokenizer->GetTokenAllocator():nsnull;
|
||||
if(allocator) {
|
||||
nsAutoString fragment;
|
||||
PRBool done=PR_FALSE;
|
||||
PRBool inContent=PR_FALSE;
|
||||
@ -838,7 +833,7 @@ nsresult nsXIFDTD::HandleCommentToken(CToken* aToken, nsIParserNode& aNode) {
|
||||
else {
|
||||
if(inContent) comment.Append(fragment);
|
||||
}
|
||||
recycler->RecycleToken(token);
|
||||
IF_FREE(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -866,7 +861,7 @@ nsresult nsXIFDTD::HandleAttributeToken(CToken* aToken,nsIParserNode& aNode) {
|
||||
PRBool hasValue=GetAttributePair(aNode,theKey,theValue);
|
||||
|
||||
if(hasValue) {
|
||||
CToken* attribute = mTokenRecycler->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown,theValue);
|
||||
CToken* attribute = mTokenAllocator->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown,theValue);
|
||||
nsString& key=((CAttributeToken*)attribute)->GetKey();
|
||||
key=theKey; // set the new key on the attribute..
|
||||
thePeekNode->AddAttribute(attribute);
|
||||
@ -1067,7 +1062,7 @@ nsresult nsXIFDTD::CloseContainer(const nsIParserNode& aNode)
|
||||
if(IsHTMLContainer(theTag) && theTag!=eHTMLTag_unknown) {
|
||||
result=mSink->CloseContainer(aNode);
|
||||
}
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
mNodeRecycler->RecycleNode(theNode);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -1140,13 +1135,13 @@ nsresult nsXIFDTD::GetTokenizer(nsITokenizer*& aTokenizer) {
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsITokenRecycler* nsXIFDTD::GetTokenRecycler(void){
|
||||
nsTokenAllocator* nsXIFDTD::GetTokenAllocator(void){
|
||||
nsITokenizer* theTokenizer=0;
|
||||
|
||||
nsresult result=GetTokenizer(theTokenizer);
|
||||
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
return theTokenizer->GetTokenRecycler();
|
||||
return theTokenizer->GetTokenAllocator();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -1349,7 +1344,7 @@ nsresult nsXIFDTD::ProcessEntityTag(const nsIParserNode& aNode)
|
||||
entity->Reinitialize(eHTMLTag_text,scratch); // Covert type to text and set the translated value.
|
||||
}
|
||||
}
|
||||
((nsCParserNode&)aNode).Init(entity,mLineNumber,mTokenRecycler);
|
||||
((nsCParserNode&)aNode).Init(entity,mLineNumber,mTokenAllocator);
|
||||
}
|
||||
result=mSink->AddLeaf(aNode);
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ class nsITokenizer;
|
||||
class nsDTDContext;
|
||||
class nsEntryStack;
|
||||
class nsCParserNode;
|
||||
class CTokenRecycler;
|
||||
class nsTokenAllocator;
|
||||
class CNodeRecycler;
|
||||
|
||||
//*** This enum is used to define the known universe of XIF tags.
|
||||
@ -395,7 +395,7 @@ private:
|
||||
* @update gess8/4/98
|
||||
* @return ptr to recycler (or null)
|
||||
*/
|
||||
virtual nsITokenRecycler* GetTokenRecycler(void);
|
||||
virtual nsTokenAllocator* GetTokenAllocator(void);
|
||||
|
||||
private:
|
||||
|
||||
@ -443,7 +443,7 @@ protected:
|
||||
nsString mCharset;
|
||||
|
||||
nsDTDContext* mXIFContext;
|
||||
CTokenRecycler* mTokenRecycler;
|
||||
nsTokenAllocator* mTokenAllocator;
|
||||
CNodeRecycler* mNodeRecycler;
|
||||
nsresult mDTDState;
|
||||
|
||||
|
@ -78,11 +78,6 @@ nsresult nsXMLTokenizer::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsXMLTokenizer::FreeTokenRecycler(void) {
|
||||
nsHTMLTokenizer::FreeTokenRecycler();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is defined in nsIParser. It is used to
|
||||
* cause the COM-like construction of an nsParser.
|
||||
@ -151,8 +146,8 @@ nsresult nsXMLTokenizer::ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens)
|
||||
}
|
||||
|
||||
|
||||
nsITokenRecycler* nsXMLTokenizer::GetTokenRecycler(void) {
|
||||
return nsHTMLTokenizer::GetTokenRecycler();
|
||||
nsTokenAllocator* nsXMLTokenizer::GetTokenAllocator(void) {
|
||||
return nsHTMLTokenizer::GetTokenAllocator();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -202,14 +197,14 @@ nsresult ConsumeConditional(nsScanner& aScanner,const nsString& aMatchString,PRB
|
||||
*/
|
||||
nsresult nsXMLTokenizer::ConsumeComment(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner){
|
||||
nsresult result=NS_OK;
|
||||
CTokenRecycler* theRecycler=(CTokenRecycler*)GetTokenRecycler();
|
||||
nsTokenAllocator* theAllocator=this->GetTokenAllocator();
|
||||
|
||||
if(theRecycler) {
|
||||
if(theAllocator) {
|
||||
nsAutoString theEmpty;
|
||||
aToken=theRecycler->CreateTokenOfType(eToken_comment,eHTMLTag_comment,theEmpty);
|
||||
aToken=theAllocator->CreateTokenOfType(eToken_comment,eHTMLTag_comment,theEmpty);
|
||||
if(aToken) {
|
||||
result=aToken->Consume(aChar,aScanner,eDTDMode_strict);
|
||||
AddToken(aToken,result,&mTokenDeque,theRecycler);
|
||||
AddToken(aToken,result,&mTokenDeque,theAllocator);
|
||||
}
|
||||
}
|
||||
|
||||
@ -229,9 +224,9 @@ nsresult nsXMLTokenizer::ConsumeComment(PRUnichar aChar,CToken*& aToken,nsScanne
|
||||
*/
|
||||
nsresult nsXMLTokenizer::ConsumeSpecialMarkup(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner){
|
||||
nsresult result=NS_OK;
|
||||
CTokenRecycler* theRecycler=(CTokenRecycler*)GetTokenRecycler();
|
||||
nsTokenAllocator* theAllocator=this->GetTokenAllocator();
|
||||
|
||||
if(theRecycler) {
|
||||
if(theAllocator) {
|
||||
PRUnichar theChar;
|
||||
aScanner.Peek(theChar);
|
||||
PRBool isComment=PR_TRUE;
|
||||
@ -242,17 +237,17 @@ nsresult nsXMLTokenizer::ConsumeSpecialMarkup(PRUnichar aChar,CToken*& aToken,ns
|
||||
result = ConsumeConditional(aScanner, CDATAString, isCDATA);
|
||||
if (NS_OK == result) {
|
||||
if (isCDATA) {
|
||||
aToken=theRecycler->CreateTokenOfType(eToken_cdatasection,eHTMLTag_unknown,theEmpty);
|
||||
aToken=theAllocator->CreateTokenOfType(eToken_cdatasection,eHTMLTag_unknown,theEmpty);
|
||||
isComment=PR_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(isComment) aToken = theRecycler->CreateTokenOfType(eToken_comment,eHTMLTag_comment,theEmpty);
|
||||
if(isComment) aToken = theAllocator->CreateTokenOfType(eToken_comment,eHTMLTag_comment,theEmpty);
|
||||
|
||||
if(aToken) {
|
||||
result=aToken->Consume(aChar,aScanner,eDTDMode_strict);
|
||||
AddToken(aToken,result,&mTokenDeque,theRecycler);
|
||||
AddToken(aToken,result,&mTokenDeque,theAllocator);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -60,9 +60,7 @@ public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual nsresult ConsumeToken(nsScanner& aScanner,PRBool& aFlushTokens);
|
||||
virtual nsITokenRecycler* GetTokenRecycler(void);
|
||||
|
||||
static void FreeTokenRecycler(void);
|
||||
virtual nsTokenAllocator* GetTokenAllocator(void);
|
||||
|
||||
protected:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user