46702 ( nsbeta3+ ) Partial - Made token cache to be arena based.

r=vidur
This commit is contained in:
harishd%netscape.com 2000-08-30 18:22:03 +00:00
parent f2714e75a8
commit c387ac81a1
74 changed files with 1366 additions and 1274 deletions

View File

@ -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;
}
/**

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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 &#000.
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;
}

View File

@ -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,

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -411,6 +411,7 @@ protected:
nsString mCommandStr;
nsParserBundle* mBundle;
nsTokenAllocator mTokenAllocator;
public:
MOZ_TIMER_DECLARE(mParseTime)

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}
/**

View File

@ -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;
};

View File

@ -352,7 +352,7 @@ NS_IMETHODIMP CValidDTD::HandleToken(CToken* aToken,nsIParser* aParser) {
* @param
* @return
*/
nsITokenRecycler* CValidDTD::GetTokenRecycler(void){
nsTokenAllocator* CValidDTD::GetTokenAllocator(void){
return 0;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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:

View File

@ -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;
}
/**

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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 &#000.
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;
}

View File

@ -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,

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -411,6 +411,7 @@ protected:
nsString mCommandStr;
nsParserBundle* mBundle;
nsTokenAllocator mTokenAllocator;
public:
MOZ_TIMER_DECLARE(mParseTime)

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}
/**

View File

@ -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;
};

View File

@ -352,7 +352,7 @@ NS_IMETHODIMP CValidDTD::HandleToken(CToken* aToken,nsIParser* aParser) {
* @param
* @return
*/
nsITokenRecycler* CValidDTD::GetTokenRecycler(void){
nsTokenAllocator* CValidDTD::GetTokenAllocator(void){
return 0;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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: