diff --git a/mozilla/htmlparser/src/CNavDTD.cpp b/mozilla/htmlparser/src/CNavDTD.cpp
index da6f31eae43..7ef008c72d2 100644
--- a/mozilla/htmlparser/src/CNavDTD.cpp
+++ b/mozilla/htmlparser/src/CNavDTD.cpp
@@ -138,8 +138,7 @@ NS_IMPL_RELEASE(CNavDTD)
*/
CNavDTD::CNavDTD() : nsIDTD(),
mMisplacedContent(0),
- mSkippedContent(0),
- mSharedNodes(0) {
+ mSkippedContent(0) {
NS_INIT_REFCNT();
mSink = 0;
mParser=0;
@@ -165,8 +164,6 @@ CNavDTD::CNavDTD() : nsIDTD(),
mHeadContext=new nsDTDContext();
mBodyContext=new nsDTDContext();
- mNodeRecycler=0;
-
#ifdef RICKG_DEBUG
//DebugDumpContainmentRules2(*this,"c:/temp/DTDRules.new","New CNavDTD Containment Rules");
nsHTMLElement::DebugDumpContainment("c:/temp/contain.new","ElementTable Rules");
@@ -189,22 +186,10 @@ void CNavDTD::RecycleNodes(nsEntryStack *aNodeStack) {
PRInt32 theIndex=0;
for(theIndex=0;theIndexNodeAt(theIndex);
- if(theNode) {
-
- theNode->mUseCount=0;
-
- IF_FREE(theNode->mToken);
-
- CToken* theToken=0;
- while((theToken=(CToken*)theNode->PopAttributeToken())){
- IF_FREE(theToken);
- }
-
- mNodeRecycler->RecycleNode(theNode);
- } //if
- } //while
- } //if
+ nsIParserNode* node=aNodeStack->NodeAt(theIndex);
+ NS_IF_RELEASE(node);
+ }
+ }
}
/**
@@ -282,9 +267,6 @@ CNavDTD::~CNavDTD(){
mTempContext=0;
}
- // delete mNodeRecycler;
-
-
if(mSink) {
nsLoggingSink *theLogSink=GetLoggingSink();
if(mSink==theLogSink) {
@@ -498,8 +480,6 @@ nsresult CNavDTD::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsIToke
mTokenAllocator=mTokenizer->GetTokenAllocator();
- result=mBodyContext->GetNodeRecycler(mNodeRecycler); // Get a copy...
-
if(NS_FAILED(result)) return result;
if(mSink) {
@@ -609,14 +589,14 @@ nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParse
while(mBodyContext->GetCount() > 0) {
nsEntryStack *theChildStyles=0;
- nsCParserNode* theNode=(nsCParserNode*)mBodyContext->Pop(theChildStyles);
- theNode->mUseCount=0;
- mNodeRecycler->RecycleNode(theNode);
- if(theChildStyles) {
- delete theChildStyles;
+ nsIParserNode* theNode=mBodyContext->Pop(theChildStyles);
+ if(theNode) {
+ if(theChildStyles) {
+ delete theChildStyles;
+ }
+ NS_IF_RELEASE(theNode);
}
}
-
}
STOP_TIMER();
@@ -891,7 +871,7 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
* @param aChildTag is the tag itself.
* @return status
*/
-nsresult CNavDTD::DidHandleStartTag(nsCParserNode& aNode,eHTMLTags aChildTag){
+nsresult CNavDTD::DidHandleStartTag(nsIParserNode& aNode,eHTMLTags aChildTag){
nsresult result=NS_OK;
#if 0
@@ -983,10 +963,11 @@ nsresult CNavDTD::DidHandleStartTag(nsCParserNode& aNode,eHTMLTags aChildTag){
break;
}//switch
- //handle tags by generating a close tag...
- //added this to fix bug 48351, which contains XHTML and uses empty tags.
- if(nsHTMLElement::IsContainer(aChildTag) && aNode.mToken) { //nullptr test fixes bug 56085
- CStartToken *theToken=NS_STATIC_CAST(CStartToken*,aNode.mToken);
+ //handle tags by generating a close tag...
+ //added this to fix bug 48351, which contains XHTML and uses empty tags.
+ nsCParserNode* theNode=NS_STATIC_CAST(nsCParserNode*,&aNode);
+ if(nsHTMLElement::IsContainer(aChildTag) && theNode && theNode->mToken) { //nullptr test fixes bug 56085
+ CStartToken *theToken=NS_STATIC_CAST(CStartToken*,theNode->mToken);
if(theToken->IsEmpty()){
CToken *theEndToken=mTokenAllocator->CreateTokenOfType(eToken_end,aChildTag);
@@ -1295,7 +1276,7 @@ void WriteTokenToLog(CToken* aToken) {
* @param aNode is the node (tag) with associated attributes.
* @return TRUE if tag processing should continue; FALSE if the tag has been handled.
*/
-nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsCParserNode& aNode){
+nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsIParserNode& aNode) {
nsresult result=NS_OK;
PRInt32 theAttrCount = aNode.GetAttributeCount();
@@ -1580,8 +1561,7 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
//Begin by gathering up attributes...
- nsCParserNode* theNode=mNodeRecycler->CreateNode();
- theNode->Init(aToken,mLineNumber,mTokenAllocator);
+ nsIParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,mTokenAllocator);
eHTMLTags theChildTag=(eHTMLTags)aToken->GetTypeID();
PRInt16 attrCount=aToken->GetAttributeCount();
@@ -1697,7 +1677,7 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
result=NS_OK;
}
- mNodeRecycler->RecycleNode(theNode);
+ NS_IF_RELEASE(theNode);
return result;
}
@@ -2006,7 +1986,9 @@ nsresult CNavDTD::HandleSavedTokens(PRInt32 anIndex) {
nsEntryStack* theChildStyleStack=0;
for(i=0; i<(theTagCount - theTopIndex); i++) {
- mTempContext->Push((nsCParserNode*)mBodyContext->Pop(theChildStyleStack));
+ nsIParserNode* node=mBodyContext->Pop(theChildStyleStack);
+ mTempContext->Push(node);
+ NS_IF_RELEASE(node); //release the popped node since push will addref for us.
}
// Now flush out all the bad contents.
@@ -2047,7 +2029,9 @@ nsresult CNavDTD::HandleSavedTokens(PRInt32 anIndex) {
// Bad-contents were successfully processed. Now, itz time to get
// back to the original body context state.
for(PRInt32 k=0; k<(theTagCount - theTopIndex); k++) {
- mBodyContext->Push((nsCParserNode*)mTempContext->Pop(theChildStyleStack));
+ nsIParserNode* node=mTempContext->Pop(theChildStyleStack);
+ mBodyContext->Push(node);
+ NS_IF_RELEASE(node);
}
STOP_TIMER()
@@ -2098,23 +2082,20 @@ nsresult CNavDTD::HandleEntityToken(CToken* aToken) {
eHTMLTags theParentTag=mBodyContext->Last();
- nsCParserNode* theNode=mNodeRecycler->CreateNode();
+ nsIParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,0);
if(theNode) {
- theNode->Init(aToken,mLineNumber,0);
PRBool theParentContains=-1; //set to -1 to force CanOmit to recompute...
if(CanOmit(theParentTag,eHTMLTag_entity,theParentContains)) {
eHTMLTags theCurrTag=(eHTMLTags)aToken->GetTypeID();
result=HandleOmittedTag(aToken,theCurrTag,theParentTag,theNode);
- mNodeRecycler->RecycleNode(theNode);
- return result;
}
-
- #ifdef RICKG_DEBUG
- WriteTokenToLog(aToken);
- #endif
-
- result=AddLeaf(theNode);
- mNodeRecycler->RecycleNode(theNode);
+ else {
+#ifdef RICKG_DEBUG
+ WriteTokenToLog(aToken);
+#endif
+ result=AddLeaf(theNode);
+ }
+ NS_IF_RELEASE(theNode);
}
return result;
}
@@ -2138,9 +2119,8 @@ nsresult CNavDTD::HandleCommentToken(CToken* aToken) {
const nsAReadableString& theComment = theToken->GetStringValue();
mLineNumber += CountCharInReadable(theComment, PRUnichar(kNewLine));
- nsCParserNode* theNode=mNodeRecycler->CreateNode();
+ nsIParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,0);
if(theNode) {
- theNode->Init(aToken,mLineNumber,0);
#ifdef RICKG_DEBUG
WriteTokenToLog(aToken);
@@ -2151,7 +2131,7 @@ nsresult CNavDTD::HandleCommentToken(CToken* aToken) {
result=(mSink) ? mSink->AddComment(*theNode) : NS_OK;
- mNodeRecycler->RecycleNode(theNode);
+ NS_IF_RELEASE(theNode);
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleCommentToken(), this=%p\n", this));
START_TIMER();
@@ -2215,9 +2195,8 @@ nsresult CNavDTD::HandleProcessingInstructionToken(CToken* aToken){
nsresult result=NS_OK;
- nsCParserNode* theNode=mNodeRecycler->CreateNode();
+ nsIParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,0);
if(theNode) {
- theNode->Init(aToken,mLineNumber,0);
#ifdef RICKG_DEBUG
WriteTokenToLog(aToken);
@@ -2228,7 +2207,7 @@ nsresult CNavDTD::HandleProcessingInstructionToken(CToken* aToken){
result=(mSink) ? mSink->AddProcessingInstruction(*theNode) : NS_OK;
- mNodeRecycler->RecycleNode(theNode);
+ NS_IF_RELEASE(theNode);
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleProcessingInstructionToken(), this=%p\n", this));
START_TIMER();
@@ -2266,9 +2245,8 @@ nsresult CNavDTD::HandleDocTypeDeclToken(CToken* aToken){
docTypeStr.Cut(0,2); // Now remove "SetStringValue(docTypeStr);
- nsCParserNode* theNode=mNodeRecycler->CreateNode();
+ nsIParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,0);
if(theNode) {
- theNode->Init(aToken,mLineNumber,0);
STOP_TIMER();
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::HandleDocTypeDeclToken(), this=%p\n", this));
@@ -2290,7 +2268,7 @@ nsresult CNavDTD::HandleDocTypeDeclToken(CToken* aToken){
result = (mSink)? mSink->AddDocTypeDecl(*theNode,theMode):NS_OK;
- mNodeRecycler->RecycleNode(theNode);
+ NS_IF_RELEASE(theNode);
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleDocTypeDeclToken(), this=%p\n", this));
START_TIMER();
@@ -2308,7 +2286,7 @@ nsresult CNavDTD::HandleDocTypeDeclToken(CToken* aToken){
* @param aCount is the # of attributes you're expecting
* @return error code (should be 0)
*/
-nsresult CNavDTD::CollectAttributes(nsCParserNode& aNode,eHTMLTags aTag,PRInt32 aCount){
+nsresult CNavDTD::CollectAttributes(nsIParserNode& aNode,eHTMLTags aTag,PRInt32 aCount){
int attr=0;
nsresult result=NS_OK;
@@ -2319,7 +2297,8 @@ nsresult CNavDTD::CollectAttributes(nsCParserNode& aNode,eHTMLTags aTag,PRInt32
for(attr=0;attrPopToken();
+ else
+ theToken=mTokenizer->PopToken();
if(theToken) {
eHTMLTokenTypes theType=eHTMLTokenTypes(theToken->GetTokenType());
if(theType!=eToken_attribute) {
@@ -2359,7 +2338,7 @@ nsresult CNavDTD::CollectAttributes(nsCParserNode& aNode,eHTMLTags aTag,PRInt32
* @param holds the number of skipped content elements encountered
* @return Error condition.
*/
-nsresult CNavDTD::CollectSkippedContent(nsCParserNode& aNode,PRInt32 &aCount) {
+nsresult CNavDTD::CollectSkippedContent(nsIParserNode& aNode,PRInt32 &aCount) {
eHTMLTags theNodeTag=(eHTMLTags)aNode.GetNodeType();
@@ -2371,54 +2350,58 @@ nsresult CNavDTD::CollectSkippedContent(nsCParserNode& aNode,PRInt32 &aCount) {
PRBool aMustConvertLinebreaks = PR_FALSE;
mScratch.Truncate();
- aNode.SetSkippedContent(mScratch); //this guarantees us some skipped content storage.
+
+ nsCParserNode* theNode=NS_STATIC_CAST(nsCParserNode*,&aNode);
+ if(theNode) {
+ theNode->SetSkippedContent(mScratch); //this guarantees us some skipped content storage.
- for(aIndex=0;aIndexGetTokenType();
+ eHTMLTokenTypes theTokenType=(eHTMLTokenTypes)theNextToken->GetTokenType();
- // Dont worry about attributes here because it's already stored in
- // the start token as mTrailing content and will get appended in
- // start token's GetSource();
- if(eToken_attribute!=theTokenType) {
- if ((eToken_entity==theTokenType) &&
- ((eHTMLTag_textarea==theNodeTag) || (eHTMLTag_title==theNodeTag))) {
- mScratch.Truncate();
- ((CEntityToken*)theNextToken)->TranslateToUnicodeStr(mScratch);
- // 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.
- if(mScratch.Length()>0){
- aMustConvertLinebreaks |= (mScratch[0] == kCR);
- aNode.mSkippedContent->Append(mScratch);
+ // Dont worry about attributes here because it's already stored in
+ // the start token as mTrailing content and will get appended in
+ // start token's GetSource();
+ if(eToken_attribute!=theTokenType) {
+ if ((eToken_entity==theTokenType) &&
+ ((eHTMLTag_textarea==theNodeTag) || (eHTMLTag_title==theNodeTag))) {
+ mScratch.Truncate();
+ ((CEntityToken*)theNextToken)->TranslateToUnicodeStr(mScratch);
+ // 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.
+ if(mScratch.Length()>0){
+ aMustConvertLinebreaks |= (mScratch[0] == kCR);
+ theNode->mSkippedContent->Append(mScratch);
+ }
}
- }
- else theNextToken->AppendSource(*aNode.mSkippedContent);
+ else theNextToken->AppendSource(*theNode->mSkippedContent);
+ }
+ IF_FREE(theNextToken);
}
- IF_FREE(theNextToken);
+
+ // if the string contained CRs (hence is either CR, or CRLF terminated)
+ // we need to convert line breaks
+ if (aMustConvertLinebreaks)
+ {
+ /*
+ PRInt32 offset;
+ while ((offset = aNode.mSkippedContent.Find("\r\n")) != kNotFound)
+ aNode.mSkippedContent.Cut(offset, 1); // remove the CR
+
+ // now replace remaining CRs with LFs
+ aNode.mSkippedContent.ReplaceChar("\r", kNewLine);
+ */
+ #if 1
+ nsLinebreakConverter::ConvertStringLineBreaks(*theNode->mSkippedContent,
+ nsLinebreakConverter::eLinebreakAny, nsLinebreakConverter::eLinebreakContent);
+ #endif
+ }
+
+ // Let's hope that this does not hamper the PERFORMANCE!!
+ mLineNumber += theNode->mSkippedContent->CountChar(kNewLine);
}
-
- // if the string contained CRs (hence is either CR, or CRLF terminated)
- // we need to convert line breaks
- if (aMustConvertLinebreaks)
- {
- /*
- PRInt32 offset;
- while ((offset = aNode.mSkippedContent.Find("\r\n")) != kNotFound)
- aNode.mSkippedContent.Cut(offset, 1); // remove the CR
-
- // now replace remaining CRs with LFs
- aNode.mSkippedContent.ReplaceChar("\r", kNewLine);
- */
-#if 1
- nsLinebreakConverter::ConvertStringLineBreaks(*aNode.mSkippedContent,
- nsLinebreakConverter::eLinebreakAny, nsLinebreakConverter::eLinebreakContent);
-#endif
- }
-
- // Let's hope that this does not hamper the PERFORMANCE!!
- mLineNumber += aNode.mSkippedContent->CountChar(kNewLine);
return NS_OK;
}
@@ -2862,10 +2845,8 @@ nsresult CNavDTD::OpenTransientStyles(eHTMLTags aChildTag){
}
else {
//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);
- }
+ nsIParserNode* node=theStack->Remove(sindex,theNodeTag);
+ NS_IF_RELEASE(node);
theEntry--; //back up by one
}
} //if
@@ -2932,10 +2913,8 @@ nsresult CNavDTD::PopStyle(eHTMLTags aTag){
if(mStyleHandlingEnabled) {
#ifdef ENABLE_RESIDUALSTYLE
if(nsHTMLElement::IsResidualStyleTag(aTag)) {
- nsCParserNode* theNode=(nsCParserNode*)mBodyContext->PopStyle(aTag);
- if(theNode) {
- mNodeRecycler->RecycleNode(theNode);
- }
+ nsIParserNode* node=mBodyContext->PopStyle(aTag);
+ NS_IF_RELEASE(node);
}
#endif
} //if
@@ -3547,8 +3526,7 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
nsEntryStack *theChildStyleStack=0;
eHTMLTags theTag=mBodyContext->Last();
- nsCParserNode *theNode=(nsCParserNode*)mBodyContext->Pop(theChildStyleStack);
-// eHTMLTags theParent=mBodyContext->Last();
+ nsCParserNode *theNode=NS_STATIC_CAST(nsCParserNode*,mBodyContext->Pop(theChildStyleStack));
if(theNode) {
result=CloseContainer(theNode,aTarget,aClosedByStartTag);
@@ -3561,15 +3539,12 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
if(!theStyleDoesntLeakOut) {
theStyleDoesntLeakOut = gHTMLElements[aTarget].HasSpecialProperty(kNoStyleLeaksOut);
}
- // (aClosedByStartTag) ? gHTMLElements[aTarget].HasSpecialProperty(kNoStyleLeaksOut)
- // : gHTMLElements[theParent].HasSpecialProperty(kNoStyleLeaksOut);
-
-
- /*************************************************************
- I've added a check (mhasOpenNoXXX) below to prevent residual
- style handling from getting invoked in these cases.
- This fixes bug 25214.
- *************************************************************/
+
+ /*************************************************************
+ I've added a check (mhasOpenNoXXX) below to prevent residual
+ style handling from getting invoked in these cases.
+ This fixes bug 25214.
+ *************************************************************/
if(theTagIsStyle && (0==mHasOpenNoXXX)) {
@@ -3598,7 +3573,8 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
//here's a case we missed:
//The pushes the 1st
onto the rs-stack, then the 2nd
//pops the 1st from the rs-stack altogether.
- mBodyContext->PopStyle(theTag);
+ nsIParserNode* node=mBodyContext->PopStyle(theTag);
+ NS_IF_RELEASE(node);
}
@@ -3643,7 +3619,8 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
// This fixes bug 30885 and 29626
// Make sure that the node, which is about to
// get released does not stay on the style stack...
- mBodyContext->PopStyle(theTag);
+ nsIParserNode* node=mBodyContext->PopStyle(theTag);
+ NS_IF_RELEASE(node);
}
mBodyContext->PushStyles(theChildStyleStack);
}
@@ -3667,7 +3644,8 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
//style tag that got onto that tag stack from a stylestack somewhere.
//Pop it from the stylestack if the target is also a style tag.
if(theTargetTagIsStyle) {
- theNode=(nsCParserNode*)mBodyContext->PopStyle(theTag);
+ nsIParserNode* node=mBodyContext->PopStyle(theTag);
+ NS_IF_RELEASE(node);
}
}
}
@@ -3684,8 +3662,8 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
}
}
#endif
- }//if anode
- mNodeRecycler->RecycleNode(theNode);
+ NS_IF_RELEASE(theNode);
+ }//if theNode
}
} //if
@@ -3769,7 +3747,7 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode *aNode){
while(!done && NS_SUCCEEDED(result)) {
CToken* theToken=mTokenizer->PeekToken();
if(theToken) {
- nsCParserNode* theNode=mNodeRecycler->CreateNode();
+ nsIParserNode* theNode=mNodeAllocator.CreateNode(theToken,mLineNumber,0);
if(theNode) {
theTag=(eHTMLTags)theToken->GetTypeID();
switch(theTag) {
@@ -3778,7 +3756,6 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode *aNode){
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));
@@ -3798,7 +3775,6 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode *aNode){
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();
@@ -3819,7 +3795,7 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode *aNode){
default:
done=PR_TRUE;
} //switch
- mNodeRecycler->RecycleNode(theNode);
+ NS_IF_RELEASE(theNode);
} //if
}//if
else done=PR_TRUE;
diff --git a/mozilla/htmlparser/src/CNavDTD.h b/mozilla/htmlparser/src/CNavDTD.h
index e9cfd65f7c6..3915b6b4e6a 100644
--- a/mozilla/htmlparser/src/CNavDTD.h
+++ b/mozilla/htmlparser/src/CNavDTD.h
@@ -91,6 +91,7 @@
#include "nsDeque.h"
#include "nsParserCIID.h"
#include "nsTime.h"
+#include "nsDTDUtils.h"
#define NS_INAVHTML_DTD_IID \
{0x5c5cce40, 0xcfd6, 0x11d1, \
@@ -106,7 +107,6 @@ class nsEntryStack;
class nsITokenizer;
class nsCParserNode;
class nsTokenAllocator;
-class CNodeRecycler;
/***************************************************************
Now the main event: CNavDTD.
@@ -484,10 +484,10 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
protected:
- nsresult CollectAttributes(nsCParserNode& aNode,eHTMLTags aTag,PRInt32 aCount);
- nsresult CollectSkippedContent(nsCParserNode& aNode,PRInt32& aCount);
- nsresult WillHandleStartTag(CToken* aToken,eHTMLTags aChildTag,nsCParserNode& aNode);
- nsresult DidHandleStartTag(nsCParserNode& aNode,eHTMLTags aChildTag);
+ nsresult CollectAttributes(nsIParserNode& aNode,eHTMLTags aTag,PRInt32 aCount);
+ nsresult CollectSkippedContent(nsIParserNode& aNode,PRInt32& aCount);
+ nsresult WillHandleStartTag(CToken* aToken,eHTMLTags aChildTag,nsIParserNode& aNode);
+ nsresult DidHandleStartTag(nsIParserNode& aNode,eHTMLTags aChildTag);
nsresult HandleOmittedTag(CToken* aToken,eHTMLTags aChildTag,eHTMLTags aParent,nsIParserNode *aNode);
nsresult HandleSavedTokens(PRInt32 anIndex);
nsresult HandleKeyGen(nsIParserNode *aNode);
@@ -513,13 +513,12 @@ protected:
nsParser* mParser;
nsITokenizer* mTokenizer;
nsTokenAllocator* mTokenAllocator;
- CNodeRecycler* mNodeRecycler;
+ nsNodeAllocator mNodeAllocator;
nsDeque mMisplacedContent;
nsDeque mSkippedContent;
PRBool mHasOpenScript;
PRBool mSaveBadTokens;
eHTMLTags mSkipTarget;
- nsDeque mSharedNodes;
nsresult mDTDState;
nsDTDMode mDTDMode;
eParserCommands mParserCommand; //tells us to viewcontent/viewsource/viewerrors...
diff --git a/mozilla/htmlparser/src/COtherDTD.cpp b/mozilla/htmlparser/src/COtherDTD.cpp
index 9b2f7bcd696..716ae924aa8 100644
--- a/mozilla/htmlparser/src/COtherDTD.cpp
+++ b/mozilla/htmlparser/src/COtherDTD.cpp
@@ -129,7 +129,7 @@ NS_IMPL_RELEASE(COtherDTD)
* @param
* @return
*/
-COtherDTD::COtherDTD() : nsIDTD(), mSharedNodes(0) {
+COtherDTD::COtherDTD() : nsIDTD() {
NS_INIT_REFCNT();
mSink = 0;
mParser=0;
@@ -149,6 +149,7 @@ COtherDTD::COtherDTD() : nsIDTD(), mSharedNodes(0) {
mHadBody=PR_FALSE;
mHasOpenScript=PR_FALSE;
mParserCommand=eViewNormal;
+ mNodeAllocator=new nsNodeAllocator();
mBodyContext=new nsDTDContext();
#if 1 //set this to 1 if you want strictDTD to be based on the environment setting.
@@ -169,36 +170,8 @@ COtherDTD::COtherDTD() : nsIDTD(), mSharedNodes(0) {
nsHTMLElement::DebugDumpContainType("c:/temp/ctnrules.out");
#endif
-#ifdef NS_DEBUG
- gNodeCount=0;
-#endif
}
-/**
- * This method creates a new parser node. It tries to get one from
- * the recycle list before allocating a new one.
- * @update gess1/8/99
- * @param
- * @return valid node*
- */
-nsCParserNode* COtherDTD::CreateNode(void) {
-
- nsCParserNode* result=0;
- if(0GetTokenAllocator();
mBodyContext->SetTokenAllocator(mTokenAllocator);
+ mBodyContext->SetNodeAllocator(mNodeAllocator);
if(mSink) {
@@ -529,10 +486,10 @@ nsresult COtherDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIPar
nsCParserNode* theNode=(nsCParserNode*)mBodyContext->Pop(theChildStyles);
if(theNode) {
theNode->mUseCount=0;
- mBodyContext->RecycleNode(theNode);
if(theChildStyles) {
delete theChildStyles;
}
+ NS_IF_RELEASE(theNode);
}
}
}
@@ -606,7 +563,7 @@ nsresult COtherDTD::HandleToken(CToken* aToken,nsIParser* aParser){
* @param aChildTag is the tag itself.
* @return status
*/
-nsresult COtherDTD::DidHandleStartTag(nsCParserNode& aNode,eHTMLTags aChildTag){
+nsresult COtherDTD::DidHandleStartTag(nsIParserNode& aNode,eHTMLTags aChildTag){
nsresult result=NS_OK;
switch(aChildTag){
@@ -683,7 +640,7 @@ void WriteTokenToLog(CToken* aToken) {
* @param aNode is the node (tag) with associated attributes.
* @return TRUE if tag processing should continue; FALSE if the tag has been handled.
*/
-nsresult COtherDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsCParserNode& aNode){
+nsresult COtherDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsIParserNode& aNode){
nsresult result=NS_OK;
//first let's see if there's some skipped content to deal with...
@@ -743,9 +700,8 @@ nsresult COtherDTD::HandleStartToken(CToken* aToken) {
//Begin by gathering up attributes...
nsresult result=NS_OK;
- nsCParserNode* theNode=CreateNode();
+ nsIParserNode* theNode=mNodeAllocator->CreateNode(aToken,mLineNumber,mTokenAllocator);
if(theNode) {
- theNode->Init(aToken,mLineNumber,mTokenAllocator);
eHTMLTags theChildTag=(eHTMLTags)aToken->GetTypeID();
PRInt16 attrCount=aToken->GetAttributeCount();
@@ -786,7 +742,7 @@ nsresult COtherDTD::HandleStartToken(CToken* aToken) {
} //if
}//if
- mBodyContext->RecycleNode(theNode);
+ NS_IF_RELEASE(theNode);
}
else result=NS_ERROR_OUT_OF_MEMORY;
@@ -831,11 +787,10 @@ nsresult COtherDTD::HandleEndToken(CToken* aToken) {
}
CElement* theElement=gElementTable->mElements[theParent];
if(theElement) {
- nsCParserNode* theNode=CreateNode();
+ nsIParserNode* theNode=mNodeAllocator->CreateNode(aToken,mLineNumber,mTokenAllocator);
if(theNode) {
- theNode->Init(aToken,mLineNumber,mTokenAllocator);
result=theElement->HandleEndToken(theNode,theChildTag,mBodyContext,mSink);
- mBodyContext->RecycleNode((nsCParserNode*)theNode);
+ NS_IF_RELEASE(theNode);
}
}
break;
@@ -853,7 +808,7 @@ nsresult COtherDTD::HandleEndToken(CToken* aToken) {
* @param aCount is the # of attributes you're expecting
* @return error code (should be 0)
*/
-nsresult COtherDTD::CollectAttributes(nsCParserNode& aNode,eHTMLTags aTag,PRInt32 aCount){
+nsresult COtherDTD::CollectAttributes(nsIParserNode& aNode,eHTMLTags aTag,PRInt32 aCount){
int attr=0;
nsresult result=NS_OK;
diff --git a/mozilla/htmlparser/src/COtherDTD.h b/mozilla/htmlparser/src/COtherDTD.h
index d2fd78f245e..1f2af7ba893 100644
--- a/mozilla/htmlparser/src/COtherDTD.h
+++ b/mozilla/htmlparser/src/COtherDTD.h
@@ -91,7 +91,6 @@
#include "nsDeque.h"
#include "nsParserCIID.h"
-
#define NS_IOTHERHTML_DTD_IID \
{0x8a5e89c0, 0xd16d, 0x11d1, \
{0x80, 0x22, 0x00, 0x60, 0x8, 0x14, 0x98, 0x89}}
@@ -103,8 +102,9 @@ class nsParser;
class nsDTDContext;
class nsEntryStack;
class nsITokenizer;
-class nsCParserNode;
+class nsIParserNode;
class nsTokenAllocator;
+class nsNodeAllocator;
/***************************************************************
Now the main event: COtherDTD.
@@ -313,10 +313,10 @@ CLASS_EXPORT_HTMLPARS COtherDTD : public nsIDTD {
protected:
- nsresult CollectAttributes(nsCParserNode& aNode,eHTMLTags aTag,PRInt32 aCount);
- nsresult WillHandleStartTag(CToken* aToken,eHTMLTags aChildTag,nsCParserNode& aNode);
- nsresult DidHandleStartTag(nsCParserNode& aNode,eHTMLTags aChildTag);
- nsCParserNode* CreateNode(void);
+ nsresult CollectAttributes(nsIParserNode& aNode,eHTMLTags aTag,PRInt32 aCount);
+ nsresult WillHandleStartTag(CToken* aToken,eHTMLTags aChildTag,nsIParserNode& aNode);
+ nsresult DidHandleStartTag(nsIParserNode& aNode,eHTMLTags aChildTag);
+ nsIParserNode* CreateNode(CToken* aToken=nsnull,PRInt32 aLineNumber=1,nsTokenAllocator* aTokenAllocator=0);
nsIHTMLContentSink* mSink;
@@ -332,10 +332,10 @@ protected:
PRInt32 mLineNumber;
nsParser* mParser;
nsITokenizer* mTokenizer;
- nsTokenAllocator* mTokenAllocator;
+ nsTokenAllocator* mTokenAllocator;
+ nsNodeAllocator* mNodeAllocator;
PRBool mHasOpenScript;
eHTMLTags mSkipTarget;
- nsDeque mSharedNodes;
nsresult mDTDState;
nsDTDMode mDTDMode;
eParserCommands mParserCommand; //tells us to viewcontent/viewsource/viewerrors...
@@ -346,10 +346,6 @@ protected:
eParserDocType mDocType;
PRBool mEnableStrict;
-#ifdef NS_DEBUG
- PRInt32 gNodeCount;
-#endif
-
};
extern NS_HTMLPARS nsresult NS_NewOtherHTMLDTD(nsIDTD** aInstancePtrResult);
diff --git a/mozilla/htmlparser/src/COtherElements.h b/mozilla/htmlparser/src/COtherElements.h
index 6f261ba8817..2e5410f7094 100644
--- a/mozilla/htmlparser/src/COtherElements.h
+++ b/mozilla/htmlparser/src/COtherElements.h
@@ -323,8 +323,7 @@ public:
CElement *theElement=(aTag==mTag) ? this : GetElement(aTag);
result=theElement->NotifyClose(theNode,aTag,aContext,aSink);
- aContext->RecycleNode((nsCParserNode*)theNode);
-
+ NS_IF_RELEASE(aNode);
return result;
}
@@ -808,9 +807,8 @@ public:
if(aContext->mTableStates) {
if(aContext->mTableStates->CanOpenTBody()) {
- nsCParserNode* theNode=aContext->gNodeRecycler->CreateNode();
CToken* theToken=(CStartToken*)aContext->mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_tbody);
- theNode->Init(theToken,0,0); //this will likely leak...
+ nsIParserNode* theNode=aContext->mNodeAllocator->CreateNode(theToken,0,0);
result=HandleStartToken(theNode,eHTMLTag_tbody,aContext,aSink);
}
@@ -1797,8 +1795,7 @@ public:
//let's auto open the body
CToken* theToken=(CStartToken*)aContext->mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_body);
- nsCParserNode* theNode=aContext->gNodeRecycler->CreateNode();
- theNode->Init(theToken,0,0);
+ nsIParserNode* theNode=aContext->mNodeAllocator->CreateNode(theToken,0,0);
result=theBody->HandleStartToken(theNode,eHTMLTag_body,aContext,aSink);
diff --git a/mozilla/htmlparser/src/nsDTDUtils.cpp b/mozilla/htmlparser/src/nsDTDUtils.cpp
index 3033f757597..5ca27e7bbcf 100644
--- a/mozilla/htmlparser/src/nsDTDUtils.cpp
+++ b/mozilla/htmlparser/src/nsDTDUtils.cpp
@@ -132,6 +132,9 @@ void nsEntryStack::Push(const nsIParserNode* aNode,nsEntryStack* aStyleStack) {
mEntries[mCount].mTag=(eHTMLTags)aNode->GetNodeType();
mEntries[mCount].mNode=(nsIParserNode*)aNode;
+
+ NS_ADDREF(mEntries[mCount].mNode);
+
mEntries[mCount].mParent=aStyleStack;
mEntries[mCount++].mStyles=0;
}
@@ -159,6 +162,9 @@ void nsEntryStack::PushFront(const nsIParserNode* aNode,nsEntryStack* aStyleStac
mEntries[0].mTag=(eHTMLTags)aNode->GetNodeType();
mEntries[0].mNode=(nsIParserNode*)aNode;
+
+ NS_ADDREF(mEntries[0].mNode);
+
mEntries[0].mParent=aStyleStack;
mEntries[0].mStyles=0;
mCount++;
@@ -210,6 +216,7 @@ nsIParserNode* nsEntryStack::Remove(PRInt32 anIndex,eHTMLTags aTag) {
for(theIndex=anIndex;theIndexRecycleNode((nsCParserNode*)aStyles->Pop());
+ nsIParserNode* theNode=aStyles->Pop();
+ NS_IF_RELEASE(theNode);
delete aStyles;
aStyles=0;
}
@@ -1118,51 +1125,12 @@ nsIParserNode* nsDTDContext::RemoveStyle(eHTMLTags aTag){
return result;
}
-/**
- *
- * @update harishd 04/10/00
- */
-nsresult nsDTDContext::GetNodeRecycler(CNodeRecycler*& aNodeRecycler){
- nsresult result=NS_OK;
- if(!gNodeRecycler) {
- gNodeRecycler=new CNodeRecycler();
- if(gNodeRecycler==0) result=NS_ERROR_OUT_OF_MEMORY;
- }
- aNodeRecycler=gNodeRecycler;
- return result;
-}
-
-/**
- *
- * @update rickg 16June2000
- */
-void nsDTDContext::RecycleNode(nsCParserNode* aNode) {
- nsresult result=NS_OK;
-
- if(aNode) {
- if(!gNodeRecycler)
- result=nsDTDContext::GetNodeRecycler(gNodeRecycler);
-
- if(NS_SUCCEEDED(result)) {
- gNodeRecycler->RecycleNode(aNode);
- }
- else {
- delete aNode;
- }
- }
-}
-
-
/**
* This gets called when the parser module is getting unloaded
*
* @return nada
*/
void nsDTDContext::ReleaseGlobalObjects(){
- if(gNodeRecycler) {
- delete gNodeRecycler;
- gNodeRecycler=0;
- }
}
@@ -1170,9 +1138,9 @@ void nsDTDContext::ReleaseGlobalObjects(){
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;
+static const size_t kTokenBuckets[] ={sizeof(CStartToken),sizeof(CAttributeToken),sizeof(CCommentToken),sizeof(CEndToken)};
+static const PRInt32 kNumTokenBuckets = sizeof(kTokenBuckets) / sizeof(size_t);
+static const PRInt32 kInitialTokenPoolSize = NS_SIZE_IN_HEAP(sizeof(CToken)) * 200;
/**
*
@@ -1183,7 +1151,7 @@ nsTokenAllocator::nsTokenAllocator() {
MOZ_COUNT_CTOR(nsTokenAllocator);
- mArenaPool.Init("TheTokenPool", kBucketSizes, kNumBuckets, kInitialPoolSize);
+ mArenaPool.Init("TokenPool", kTokenBuckets, kNumTokenBuckets, kInitialTokenPoolSize);
#ifdef NS_DEBUG
int i=0;
@@ -1295,7 +1263,6 @@ CToken* nsTokenAllocator::CreateTokenOfType(eHTMLTokenTypes aType,eHTMLTags aTag
return result;
}
-#define DEBUG_TRACK_NODES
#ifdef DEBUG_TRACK_NODES
static nsCParserNode* gAllNodes[100];
@@ -1329,69 +1296,72 @@ void RemoveNode(nsCParserNode *aNode) {
#endif
-CNodeRecycler::CNodeRecycler(): mSharedNodes(0) {
-
- MOZ_COUNT_CTOR(CNodeRecycler);
+#ifdef HEAP_ALLOCATED_NODES
+nsNodeAllocator::nsNodeAllocator():mSharedNodes(0){
+#ifdef DEBUG_TRACK_NODES
+ mCount=0;
+#endif
+#else
+ static const size_t kNodeBuckets[] ={sizeof(nsCParserNode)};
+ static const PRInt32 kNumNodeBuckets = sizeof(kNodeBuckets) / sizeof(size_t);
+ static const PRInt32 kInitialNodePoolSize = NS_SIZE_IN_HEAP(sizeof(nsCParserNode)) * 50;
+nsNodeAllocator::nsNodeAllocator() {
+ mNodePool.Init("NodePool", kNodeBuckets, kNumNodeBuckets, kInitialNodePoolSize);
+#endif
+ MOZ_COUNT_CTOR(nsNodeAllocator);
}
+
+nsNodeAllocator::~nsNodeAllocator() {
+ MOZ_COUNT_DTOR(nsNodeAllocator);
-CNodeRecycler::~CNodeRecycler() {
-
- MOZ_COUNT_DTOR(CNodeRecycler);
-
+#ifdef HEAP_ALLOCATED_NODES
nsCParserNode* theNode=0;
while((theNode=(nsCParserNode*)mSharedNodes.Pop())){
-#ifdef DEBUG_TRACK_NODES
+#ifdef DEBUG_TRACK_NODES
RemoveNode(theNode);
#endif
- delete theNode;
+ ::operator delete(theNode);
+ theNode=nsnull;
}
-
#ifdef DEBUG_TRACK_NODES
- if(0mUseCount)) {
-
- IF_FREE(aNode->mToken);
+nsIParserNode* nsNodeAllocator::CreateNode(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator) {
+ nsCParserNode* result=0;
- CToken* theToken=0;
- while((theToken=(CToken*)aNode->PopAttributeToken())){
- IF_FREE(theToken);
- }
- mSharedNodes.Push(aNode);
- }
-}
-
-nsCParserNode* CNodeRecycler::CreateNode(void) {
-
-#ifdef DEBUG_TRACK_NODES
+#ifdef HEAP_ALLOCATED_NODES
#if 0
if(gAllNodeCount!=mSharedNodes.GetSize()) {
int x=10; //this is very BAD!
}
-#endif
#endif
- nsCParserNode* result=0;
- if(0Init(aToken,aLineNumber,aTokenAllocator,this);
}
else{
- result=new nsCParserNode();
+ result=new nsCParserNode(aToken,aLineNumber,aTokenAllocator,this);
#ifdef DEBUG_TRACK_NODES
- AddNode(result);
+ mCount++;
+ AddNode(NS_STATIC_CAST(nsCParserNode*,result));
#endif
-
+ NS_IF_ADDREF(result);
}
- return result;
+#else
+ result=new(mNodePool) nsCParserNode(aToken,aLineNumber,aTokenAllocator);
+ NS_IF_ADDREF(result);
+#endif
+ return NS_STATIC_CAST(nsIParserNode*,result);
}
void DebugDumpContainmentRules(nsIDTD& theDTD,const char* aFilename,const char* aTitle) {
diff --git a/mozilla/htmlparser/src/nsDTDUtils.h b/mozilla/htmlparser/src/nsDTDUtils.h
index 603c9456850..7338250cd5d 100644
--- a/mozilla/htmlparser/src/nsDTDUtils.h
+++ b/mozilla/htmlparser/src/nsDTDUtils.h
@@ -46,11 +46,11 @@
#include "nsVoidArray.h"
#define IF_HOLD(_ptr) if(_ptr) { _ptr->AddRef(); }
-#define IF_FREE(_ptr) if(_ptr) { _ptr->Release(); _ptr=0; } // recycles _ptr
+#define IF_FREE(_ptr) if(_ptr) { _ptr->Release(); _ptr=0; } // recycles _ptr
class nsIParserNode;
class nsCParserNode;
-class CNodeRecycler;
+class nsNodeAllocator;
void DebugDumpContainmentRules(nsIDTD& theDTD,const char* aFilename,const char* aTitle);
@@ -238,7 +238,6 @@ protected:
#endif
};
-
/************************************************************************
CNodeRecycler class implementation.
This class is used to recycle nodes.
@@ -246,23 +245,25 @@ protected:
that get created during the run of the system.
************************************************************************/
-class CNodeRecycler {
+class nsNodeAllocator {
public:
- CNodeRecycler();
- virtual ~CNodeRecycler();
- virtual nsCParserNode* CreateNode(void);
- virtual void RecycleNode(nsCParserNode* aNode);
-
+ nsNodeAllocator();
+ virtual ~nsNodeAllocator();
+ virtual nsIParserNode* CreateNode(CToken* aToken=nsnull,PRInt32 aLineNumber=1,nsTokenAllocator* aTokenAllocator=0);
+#ifdef HEAP_ALLOCATED_NODES
+ void Recycle(nsIParserNode* aNode) { mSharedNodes.Push(NS_STATIC_CAST(void*,aNode)); }
protected:
- nsDeque mSharedNodes;
-
-#ifdef NS_DEBUG
- PRInt32 gNodeCount;
+ nsDeque mSharedNodes;
+#ifdef DEBUG_TRACK_NODES
+ PRInt32 mCount;
+#endif
+#else
+protected:
+ nsFixedSizeAllocator mNodePool;
#endif
};
-
/************************************************************************
The dtdcontext class defines an ordered list of tags (a context).
************************************************************************/
@@ -295,8 +296,6 @@ public:
nsIParserNode* PopStyle(eHTMLTags aTag);
nsIParserNode* RemoveStyle(eHTMLTags aTag);
- nsresult GetNodeRecycler(CNodeRecycler*& aNodeRecycler);
- void RecycleNode(nsCParserNode *aNode);
static void ReleaseGlobalObjects(void);
CNamedEntity* RegisterEntity(const nsString& aName,const nsString& aValue);
@@ -304,9 +303,10 @@ public:
void ResetCounters(void);
void AllocateCounters(void);
- PRInt32 IncrementCounter(eHTMLTags aTag,nsCParserNode& aNode,nsString& aResult);
+ PRInt32 IncrementCounter(eHTMLTags aTag,nsIParserNode& aNode,nsString& aResult);
void SetTokenAllocator(nsTokenAllocator* aTokenAllocator) { mTokenAllocator=aTokenAllocator; }
+ void SetNodeAllocator(nsNodeAllocator* aNodeAllocator) { mNodeAllocator=aNodeAllocator; }
nsEntryStack mStack; //this will hold a list of tagentries...
PRInt32 mResidualStyleCount;
@@ -324,12 +324,10 @@ public:
union {
PRUint32 mAllBits;
CFlags mFlags;
- };
-
-
- static CNodeRecycler *gNodeRecycler;
+ };
nsTokenAllocator *mTokenAllocator;
+ nsNodeAllocator *mNodeAllocator;
CTableState *mTableStates;
PRInt32 *mCounters;
nsDeque mEntities;
diff --git a/mozilla/htmlparser/src/nsIParserNode.h b/mozilla/htmlparser/src/nsIParserNode.h
index 8fe06fe980b..470695e16f1 100644
--- a/mozilla/htmlparser/src/nsIParserNode.h
+++ b/mozilla/htmlparser/src/nsIParserNode.h
@@ -46,7 +46,11 @@
#include "nsString.h"
#include "nsDebug.h"
-// class CToken;
+//#define HEAP_ALLOCATED_NODES
+//#define DEBUG_TRACK_NODES
+
+
+class CToken;
// 6e59f160-2717-11d2-9246-00805f8a7ab6
#define NS_IPARSER_NODE_IID \
@@ -133,6 +137,9 @@ class nsIParserNode : public nsISupports {
*/
virtual PRInt32 TranslateToUnicodeStr(nsString& aString) const = 0;
+
+ virtual void AddAttribute(CToken* aToken)=0;
+
/**
* This getter retrieves the line number from the input source where
* the token occured. Lines are interpreted as occuring between \n characters.
diff --git a/mozilla/htmlparser/src/nsLoggingSink.cpp b/mozilla/htmlparser/src/nsLoggingSink.cpp
index 69eb8653029..7ea1600cc03 100644
--- a/mozilla/htmlparser/src/nsLoggingSink.cpp
+++ b/mozilla/htmlparser/src/nsLoggingSink.cpp
@@ -147,7 +147,7 @@ nsLoggingSink::WillBuildModel() {
NS_IMETHODIMP
nsLoggingSink::DidBuildModel(PRInt32 aQualityLevel) {
- WriteTabs(mOutput,mLevel--);
+ WriteTabs(mOutput,--mLevel);
PR_fprintf(mOutput, "\n");
//proxy the call to the real sink if you have one.
@@ -342,11 +342,14 @@ nsLoggingSink::AddComment(const nsIParserNode& aNode){
NS_IMETHODIMP
nsLoggingSink::SetTitle(const nsString& aValue) {
- nsAutoString tmp;
- QuoteText(aValue, tmp);
- WriteTabs(mOutput,++mLevel);
- PR_fprintf(mOutput, "\n", tmp.GetBuffer());
- --mLevel;
+ char* tmp;
+ GetNewCString(aValue, &tmp);
+ WriteTabs(mOutput,++mLevel);
+ if(tmp) {
+ PR_fprintf(mOutput, "\n", tmp);
+ nsMemory::Free(tmp);
+ }
+ --mLevel;
nsresult theResult=NS_OK;
@@ -544,9 +547,12 @@ nsLoggingSink::OpenNode(const char* aKind, const nsIParserNode& aNode) {
PR_fprintf(mOutput, "\"%s\"", tag);
}
else {
- const nsAReadableString& theText = aNode.GetText();
- PR_fprintf(mOutput, "\"%s\"", theText);
-
+ char* text;
+ GetNewCString(aNode.GetText(), &text);
+ if(text) {
+ PR_fprintf(mOutput, "\"%s\"", text);
+ nsMemory::Free(text);
+ }
}
if (WillWriteAttributes(aNode)) {
@@ -571,18 +577,25 @@ nsLoggingSink::CloseNode(const char* aKind) {
nsresult
nsLoggingSink::WriteAttributes(const nsIParserNode& aNode) {
- nsAutoString tmp, tmp2;
+
+ WriteTabs(mOutput,1+mLevel);
+ nsAutoString tmp;
PRInt32 ac = aNode.GetAttributeCount();
for (PRInt32 i = 0; i < ac; i++) {
+ char* key=nsnull;
+ char* value=nsnull;
const nsAReadableString& k = aNode.GetKeyAt(i);
const nsString& v = aNode.GetValueAt(i);
- PR_fprintf(mOutput, " 0) {
PRUnichar first = tmp.First();
if ((first == '"') || (first == '\'')) {
if (tmp.Last() == first) {
@@ -595,20 +608,26 @@ nsLoggingSink::WriteAttributes(const nsIParserNode& aNode) {
// Mismatched quotes - leave them in
}
}
- }
- QuoteText(tmp, tmp2);
- PR_fprintf(mOutput, "%s\"/>\n", tmp2.GetBuffer());
- }
+ GetNewCString(tmp, &value);
- if (0 != strchr(gSkippedContentTags, aNode.GetNodeType())) {
- const nsString& content = aNode.GetSkippedContent();
- if (content.Length() > 0) {
- QuoteText(content, tmp);
- PR_fprintf(mOutput, " \n", tmp.GetBuffer()) ;
+ if(value) {
+ PR_fprintf(mOutput, "%s\"/>\n", value);
+ WriteTabs(mOutput,1+mLevel);
+ nsMemory::Free(value);
+ }
}
}
+ if (0 != strchr(gSkippedContentTags, aNode.GetNodeType())) {
+ char* content;
+ GetNewCString(aNode.GetSkippedContent(), &content);
+ if(content) {
+ PR_fprintf(mOutput, " \n", content) ;
+ nsMemory::Free(content);
+ }
+ }
+ WriteTabs(mOutput,1+mLevel);
return NS_OK;
}
@@ -654,11 +673,15 @@ nsLoggingSink::LeafNode(const nsIParserNode& aNode)
else {
PRInt32 pos;
nsAutoString tmp;
+ char* str;
switch (nodeType) {
case eHTMLTag_whitespace:
case eHTMLTag_text:
- QuoteText(aNode.GetText(), tmp);
- PR_fprintf(mOutput, "\n", tmp.GetBuffer());
+ GetNewCString(aNode.GetText(), &str);
+ if(str) {
+ PR_fprintf(mOutput, "\n", str);
+ nsMemory::Free(str);
+ }
break;
case eHTMLTag_newline:
@@ -707,6 +730,28 @@ nsLoggingSink::QuoteText(const nsAReadableString& aValue, nsString& aResult) {
return NS_OK;
}
+/**
+ * Use this method to convert nsString to char*.
+ * REMEMBER: Match this call with nsMemory::Free(aResult);
+ *
+ * @update 04/04/99 harishd
+ * @param aValue - The string value
+ * @param aResult - String coverted to char*.
+ */
+nsresult
+nsLoggingSink::GetNewCString(const nsAReadableString& aValue, char** aResult)
+{
+ nsresult result=NS_OK;
+ nsAutoString temp;
+ result=QuoteText(aValue,temp);
+ if(NS_SUCCEEDED(result)) {
+ if(temp.Length()>0) {
+ *aResult=temp.ToNewCString();
+ }
+ }
+ return result;
+}
+
NS_IMETHODIMP
nsLoggingSink::DoFragment(PRBool aFlag)
{
diff --git a/mozilla/htmlparser/src/nsLoggingSink.h b/mozilla/htmlparser/src/nsLoggingSink.h
index 602f22e5891..d3931bf4a28 100644
--- a/mozilla/htmlparser/src/nsLoggingSink.h
+++ b/mozilla/htmlparser/src/nsLoggingSink.h
@@ -86,6 +86,7 @@ public:
nsresult LeafNode(const nsIParserNode& aNode);
nsresult WriteAttributes(const nsIParserNode& aNode);
nsresult QuoteText(const nsAReadableString& aValue, nsString& aResult);
+ nsresult GetNewCString(const nsAReadableString& aValue, char** aResult);
PRBool WillWriteAttributes(const nsIParserNode& aNode);
protected:
diff --git a/mozilla/htmlparser/src/nsParserModule.cpp b/mozilla/htmlparser/src/nsParserModule.cpp
index 9a2939a40f1..b290cf1d5d7 100644
--- a/mozilla/htmlparser/src/nsParserModule.cpp
+++ b/mozilla/htmlparser/src/nsParserModule.cpp
@@ -136,7 +136,6 @@ nsParserService::IsBlock(PRInt32 aId, PRBool& aIsBlock) const
//----------------------------------------------------------------------
static NS_DEFINE_CID(kParserCID, NS_PARSER_IID);
-static NS_DEFINE_CID(kParserNodeCID, NS_PARSER_NODE_IID);
static NS_DEFINE_CID(kLoggingSinkCID, NS_LOGGING_SINK_CID);
static NS_DEFINE_CID(kWellFormedDTDCID, NS_WELLFORMEDDTD_CID);
static NS_DEFINE_CID(kNavDTDCID, NS_CNAVDTD_CID);
@@ -154,7 +153,6 @@ struct Components {
static Components gComponents[] = {
{ "Parser", &kParserCID },
- { "ParserNode", &kParserNodeCID },
{ "Logging sink", &kLoggingSinkCID },
{ "Well formed DTD", &kWellFormedDTDCID },
{ "Navigator HTML DTD", &kNavDTDCID },
@@ -169,7 +167,6 @@ static Components gComponents[] = {
#define NUM_COMPONENTS (sizeof(gComponents) / sizeof(gComponents[0]));
NS_GENERIC_FACTORY_CONSTRUCTOR(nsParser)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsCParserNode)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsLoggingSink)
NS_GENERIC_FACTORY_CONSTRUCTOR(CWellFormedDTD)
NS_GENERIC_FACTORY_CONSTRUCTOR(CNavDTD)
@@ -277,13 +274,6 @@ nsParserModule::GetClassObject(nsIComponentManager *aCompMgr,
}
fact = mParserFactory;
}
- else if (aClass.Equals(kParserNodeCID)) {
- if (!mParserNodeFactory) {
- rv = NS_NewGenericFactory(getter_AddRefs(mParserNodeFactory),
- &nsCParserNodeConstructor);
- }
- fact = mParserNodeFactory;
- }
else if (aClass.Equals(kLoggingSinkCID)) {
if (!mLoggingSinkFactory) {
rv = NS_NewGenericFactory(getter_AddRefs(mLoggingSinkFactory),
diff --git a/mozilla/htmlparser/src/nsParserNode.cpp b/mozilla/htmlparser/src/nsParserNode.cpp
index b098fa8e8c4..42deac4f10f 100644
--- a/mozilla/htmlparser/src/nsParserNode.cpp
+++ b/mozilla/htmlparser/src/nsParserNode.cpp
@@ -28,7 +28,6 @@
#include "nsITokenizer.h"
#include "nsDTDUtils.h"
-
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kClassIID, NS_PARSER_NODE_IID);
static NS_DEFINE_IID(kIParserNodeIID, NS_IPARSER_NODE_IID);
@@ -39,6 +38,7 @@ const nsString& GetEmptyString() {
return gEmptyStr;
}
+
/**
* Default constructor
*
@@ -46,7 +46,7 @@ const nsString& GetEmptyString() {
* @param aToken -- token to init internal token
* @return
*/
-nsCParserNode::nsCParserNode(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator):
+nsCParserNode::nsCParserNode(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator,nsNodeAllocator* aNodeAllocator):
nsIParserNode() {
NS_INIT_REFCNT();
MOZ_COUNT_CTOR(nsCParserNode);
@@ -61,15 +61,9 @@ nsCParserNode::nsCParserNode(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator
mUseCount=0;
mSkippedContent=0;
mGenericState=PR_FALSE;
-}
-
-static void RecycleTokens(nsTokenAllocator* aTokenAllocator,nsDeque& aDeque) {
- CToken* theToken=0;
- if(aTokenAllocator) {
- while((theToken=(CToken*)aDeque.Pop())){
- IF_FREE(theToken);
- }
- }
+#ifdef HEAP_ALLOCATED_NODES
+ mNodeAllocator=aNodeAllocator;
+#endif
}
/**
@@ -83,6 +77,14 @@ static void RecycleTokens(nsTokenAllocator* aTokenAllocator,nsDeque& aDeque) {
nsCParserNode::~nsCParserNode() {
MOZ_COUNT_DTOR(nsCParserNode);
ReleaseAll();
+#ifdef HEAP_ALLOCATED_NODES
+ if(mNodeAllocator) {
+ mNodeAllocator->Recycle(this);
+ }
+ mNodeAllocator=nsnull;
+#endif
+ mTokenAllocator=0;
+ mLineNumber=0;
}
@@ -97,11 +99,15 @@ NS_IMPL_RELEASE(nsCParserNode)
* @return
*/
-nsresult nsCParserNode::Init(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator) {
+nsresult nsCParserNode::Init(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator,nsNodeAllocator* aNodeAllocator) {
mLineNumber=aLineNumber;
mTokenAllocator=aTokenAllocator;
- if(mAttributes && (mAttributes->GetSize()))
- RecycleTokens(mTokenAllocator,*mAttributes);
+ if(mAttributes && (mAttributes->GetSize())) {
+ CToken* theAttrToken=0;
+ while((theAttrToken=NS_STATIC_CAST(CToken*,mAttributes->Pop()))) {
+ IF_FREE(theAttrToken);
+ }
+ }
mToken=aToken;
IF_HOLD(mToken);
mGenericState=PR_FALSE;
@@ -109,6 +115,9 @@ nsresult nsCParserNode::Init(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator
if(mSkippedContent) {
mSkippedContent->Truncate();
}
+#ifdef HEAP_ALLOCATED_NODES
+ mNodeAllocator=aNodeAllocator;
+#endif
return NS_OK;
}
@@ -369,30 +378,18 @@ void nsCParserNode::GetSource(nsString& aString) {
*/
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!
- // Umm...why is this a useful comment in the source?
-
- if(mTokenAllocator) {
- RecycleTokens(mTokenAllocator,*mAttributes);
- }
- else {
- CToken* theToken=(CToken*)mAttributes->Pop();
- while(theToken){
- IF_FREE(theToken);
- theToken=(CToken*)mAttributes->Pop();
- }
+ CToken* theAttrToken=0;
+ while((theAttrToken=NS_STATIC_CAST(CToken*,mAttributes->Pop()))) {
+ IF_FREE(theAttrToken);
}
delete mAttributes;
mAttributes=0;
}
if(mSkippedContent) {
delete mSkippedContent;
+ mSkippedContent=0;
}
IF_FREE(mToken);
- mSkippedContent=0;
return NS_OK;
}
diff --git a/mozilla/htmlparser/src/nsParserNode.h b/mozilla/htmlparser/src/nsParserNode.h
index 540da833188..c8898cf560a 100644
--- a/mozilla/htmlparser/src/nsParserNode.h
+++ b/mozilla/htmlparser/src/nsParserNode.h
@@ -45,6 +45,7 @@
#include "nsString.h"
#include "nsParserCIID.h"
#include "nsDeque.h"
+#include "nsDTDUtils.h"
class nsTokenAllocator;
@@ -54,12 +55,44 @@ class nsCParserNode : public nsIParserNode {
NS_DECL_ISUPPORTS
+
+#ifdef HEAP_ALLOCATED_NODES
+ void* operator new(size_t aSize) {
+ return ::operator new(aSize);
+ }
+#else
+ /**
+ *
+ * @update harishd 01/01/01
+ * @param aSize -
+ * @param aArena - Allocate memory from this pool.
+ */
+ static void * operator new (size_t aSize, nsFixedSizeAllocator& anArena)
+ {
+ return anArena.Alloc(aSize);
+ }
+#endif
+ /**
+ *
+ *
+ * @update harishd 01/01/01
+ * @param aPtr - The memory that should be recycled/freed.
+ * @param aSize - The size of memory that needs to be freed.
+ */
+ static void operator delete (void* aPtr,size_t aSize)
+ {
+ // NodeAllocator would take care of heap allocated nodes..
+#ifndef HEAP_ALLOCATED_NODES
+ nsFixedSizeAllocator::Free(aPtr,aSize);
+#endif
+ }
+
/**
* Default constructor
* @update gess5/11/98
* @param aToken is the token this node "refers" to
*/
- nsCParserNode(CToken* aToken=nsnull,PRInt32 aLineNumber=1,nsTokenAllocator* aTokenAllocator=0);
+ nsCParserNode(CToken* aToken=nsnull,PRInt32 aLineNumber=1,nsTokenAllocator* aTokenAllocator=0,nsNodeAllocator* aNodeAllocator=0);
/**
* Destructor
@@ -71,7 +104,7 @@ class nsCParserNode : public nsIParserNode {
* Init
* @update gess5/11/98
*/
- virtual nsresult Init(CToken* aToken=nsnull,PRInt32 aLineNumber=1,nsTokenAllocator* aTokenAllocator=0);
+ virtual nsresult Init(CToken* aToken=nsnull,PRInt32 aLineNumber=1,nsTokenAllocator* aTokenAllocator=0,nsNodeAllocator* aNodeAllocator=0);
/**
* Retrieve the name of the node
@@ -212,6 +245,10 @@ class nsCParserNode : public nsIParserNode {
nsCOMPtr mIDAttributeAtom;
nsTokenAllocator* mTokenAllocator;
+#ifdef HEAP_ALLOCATED_NODES
+ nsNodeAllocator* mNodeAllocator; // weak
+#endif
+
};
#endif
diff --git a/mozilla/htmlparser/src/nsViewSourceHTML.cpp b/mozilla/htmlparser/src/nsViewSourceHTML.cpp
index e2d4cdaed49..3e7d89dbef6 100644
--- a/mozilla/htmlparser/src/nsViewSourceHTML.cpp
+++ b/mozilla/htmlparser/src/nsViewSourceHTML.cpp
@@ -1092,11 +1092,9 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser) {
if((ePlainText!=mDocType) && mParser && (NS_OK==result)) {
CObserverService* theService=mParser->GetObserverService();
if(theService) {
- CParserContext* pc=mParser->PeekContext();
- void* theDocID=(pc)? pc->mKey:0;
- eHTMLTags theTag=(eHTMLTags)theToken->GetTypeID();
-
- result=theService->Notify(theTag,theContext.mTokenNode,theDocID, NS_ConvertToString(kViewSourceCommand), mParser);
+ eHTMLTags theTag=(eHTMLTags)theToken->GetTypeID();
+ const nsISupportsParserBundle* bundle=mParser->GetParserBundle();
+ result=theService->Notify(theTag,theContext.mTokenNode,(void*)bundle, mMimeType, mParser);
}
}
}
diff --git a/mozilla/htmlparser/src/nsXIFDTD.cpp b/mozilla/htmlparser/src/nsXIFDTD.cpp
index 539c81f95d8..16df385081d 100644
--- a/mozilla/htmlparser/src/nsXIFDTD.cpp
+++ b/mozilla/htmlparser/src/nsXIFDTD.cpp
@@ -652,7 +652,7 @@ nsresult nsXIFDTD::HandleStartToken(CToken* aToken) {
}
}
- mNodeRecycler->RecycleNode(node);
+ NS_IF_RELEASE(node);
return result;
}
@@ -1066,7 +1066,7 @@ nsresult nsXIFDTD::CloseContainer(const nsIParserNode& aNode)
if(IsHTMLContainer(theTag) && theTag!=eHTMLTag_unknown) {
result=mSink->CloseContainer(aNode);
}
- mNodeRecycler->RecycleNode(theNode);
+ NS_IF_RELEASE(aNode);
}
return result;
}
@@ -1398,7 +1398,8 @@ nsresult nsXIFDTD::EndCSSStyleSheet(const nsIParserNode& aNode)
((nsCParserNode&)aNode).SetSkippedContent(mBuffer);
result=mSink->AddLeaf(aNode);
- mNodeRecycler->RecycleNode((nsCParserNode*)mXIFContext->Pop());
+ nsIParserNode* node=mXIFContext->Pop();
+ NS_IF_RELEASE(node);
return result;
}
diff --git a/mozilla/htmlparser/tests/outsinks/Convert.cpp b/mozilla/htmlparser/tests/outsinks/Convert.cpp
index 288a9e968e9..b5430f51b59 100644
--- a/mozilla/htmlparser/tests/outsinks/Convert.cpp
+++ b/mozilla/htmlparser/tests/outsinks/Convert.cpp
@@ -22,7 +22,6 @@
#include // for isdigit()
-#include "CNavDTD.h"
#include "nsParserCIID.h"
#include "nsIParser.h"
#include "nsIHTMLContentSink.h"
@@ -160,9 +159,11 @@ HTML2text(nsString& inString, nsString& inType, nsString& outType,
#endif /* USE_SERIALIZER */
parser->SetContentSink(sink);
- nsIDTD* dtd = nsnull;
- if (inType.EqualsWithConversion("text/html"))
- rv = NS_NewNavHTMLDTD(&dtd);
+ nsCOMPtr dtd;
+ if (inType.EqualsWithConversion("text/html")) {
+ static NS_DEFINE_CID(kNavDTDCID, NS_CNAVDTD_CID);
+ rv=nsComponentManager::CreateInstance(kNavDTDCID,nsnull,NS_GET_IID(nsIDTD),getter_AddRefs(dtd));
+ }
else
{
printf("Don't know how to deal with non-html input!\n");
@@ -184,8 +185,6 @@ HTML2text(nsString& inString, nsString& inType, nsString& outType,
printf("Parse() failed! 0x%x\n", rv);
return rv;
}
-
- NS_IF_RELEASE(dtd);
NS_RELEASE(parser);
if (compareAgainst.Length() > 0)
diff --git a/mozilla/parser/htmlparser/src/CNavDTD.cpp b/mozilla/parser/htmlparser/src/CNavDTD.cpp
index da6f31eae43..7ef008c72d2 100644
--- a/mozilla/parser/htmlparser/src/CNavDTD.cpp
+++ b/mozilla/parser/htmlparser/src/CNavDTD.cpp
@@ -138,8 +138,7 @@ NS_IMPL_RELEASE(CNavDTD)
*/
CNavDTD::CNavDTD() : nsIDTD(),
mMisplacedContent(0),
- mSkippedContent(0),
- mSharedNodes(0) {
+ mSkippedContent(0) {
NS_INIT_REFCNT();
mSink = 0;
mParser=0;
@@ -165,8 +164,6 @@ CNavDTD::CNavDTD() : nsIDTD(),
mHeadContext=new nsDTDContext();
mBodyContext=new nsDTDContext();
- mNodeRecycler=0;
-
#ifdef RICKG_DEBUG
//DebugDumpContainmentRules2(*this,"c:/temp/DTDRules.new","New CNavDTD Containment Rules");
nsHTMLElement::DebugDumpContainment("c:/temp/contain.new","ElementTable Rules");
@@ -189,22 +186,10 @@ void CNavDTD::RecycleNodes(nsEntryStack *aNodeStack) {
PRInt32 theIndex=0;
for(theIndex=0;theIndexNodeAt(theIndex);
- if(theNode) {
-
- theNode->mUseCount=0;
-
- IF_FREE(theNode->mToken);
-
- CToken* theToken=0;
- while((theToken=(CToken*)theNode->PopAttributeToken())){
- IF_FREE(theToken);
- }
-
- mNodeRecycler->RecycleNode(theNode);
- } //if
- } //while
- } //if
+ nsIParserNode* node=aNodeStack->NodeAt(theIndex);
+ NS_IF_RELEASE(node);
+ }
+ }
}
/**
@@ -282,9 +267,6 @@ CNavDTD::~CNavDTD(){
mTempContext=0;
}
- // delete mNodeRecycler;
-
-
if(mSink) {
nsLoggingSink *theLogSink=GetLoggingSink();
if(mSink==theLogSink) {
@@ -498,8 +480,6 @@ nsresult CNavDTD::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsIToke
mTokenAllocator=mTokenizer->GetTokenAllocator();
- result=mBodyContext->GetNodeRecycler(mNodeRecycler); // Get a copy...
-
if(NS_FAILED(result)) return result;
if(mSink) {
@@ -609,14 +589,14 @@ nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParse
while(mBodyContext->GetCount() > 0) {
nsEntryStack *theChildStyles=0;
- nsCParserNode* theNode=(nsCParserNode*)mBodyContext->Pop(theChildStyles);
- theNode->mUseCount=0;
- mNodeRecycler->RecycleNode(theNode);
- if(theChildStyles) {
- delete theChildStyles;
+ nsIParserNode* theNode=mBodyContext->Pop(theChildStyles);
+ if(theNode) {
+ if(theChildStyles) {
+ delete theChildStyles;
+ }
+ NS_IF_RELEASE(theNode);
}
}
-
}
STOP_TIMER();
@@ -891,7 +871,7 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
* @param aChildTag is the tag itself.
* @return status
*/
-nsresult CNavDTD::DidHandleStartTag(nsCParserNode& aNode,eHTMLTags aChildTag){
+nsresult CNavDTD::DidHandleStartTag(nsIParserNode& aNode,eHTMLTags aChildTag){
nsresult result=NS_OK;
#if 0
@@ -983,10 +963,11 @@ nsresult CNavDTD::DidHandleStartTag(nsCParserNode& aNode,eHTMLTags aChildTag){
break;
}//switch
- //handle tags by generating a close tag...
- //added this to fix bug 48351, which contains XHTML and uses empty tags.
- if(nsHTMLElement::IsContainer(aChildTag) && aNode.mToken) { //nullptr test fixes bug 56085
- CStartToken *theToken=NS_STATIC_CAST(CStartToken*,aNode.mToken);
+ //handle tags by generating a close tag...
+ //added this to fix bug 48351, which contains XHTML and uses empty tags.
+ nsCParserNode* theNode=NS_STATIC_CAST(nsCParserNode*,&aNode);
+ if(nsHTMLElement::IsContainer(aChildTag) && theNode && theNode->mToken) { //nullptr test fixes bug 56085
+ CStartToken *theToken=NS_STATIC_CAST(CStartToken*,theNode->mToken);
if(theToken->IsEmpty()){
CToken *theEndToken=mTokenAllocator->CreateTokenOfType(eToken_end,aChildTag);
@@ -1295,7 +1276,7 @@ void WriteTokenToLog(CToken* aToken) {
* @param aNode is the node (tag) with associated attributes.
* @return TRUE if tag processing should continue; FALSE if the tag has been handled.
*/
-nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsCParserNode& aNode){
+nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsIParserNode& aNode) {
nsresult result=NS_OK;
PRInt32 theAttrCount = aNode.GetAttributeCount();
@@ -1580,8 +1561,7 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
//Begin by gathering up attributes...
- nsCParserNode* theNode=mNodeRecycler->CreateNode();
- theNode->Init(aToken,mLineNumber,mTokenAllocator);
+ nsIParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,mTokenAllocator);
eHTMLTags theChildTag=(eHTMLTags)aToken->GetTypeID();
PRInt16 attrCount=aToken->GetAttributeCount();
@@ -1697,7 +1677,7 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
result=NS_OK;
}
- mNodeRecycler->RecycleNode(theNode);
+ NS_IF_RELEASE(theNode);
return result;
}
@@ -2006,7 +1986,9 @@ nsresult CNavDTD::HandleSavedTokens(PRInt32 anIndex) {
nsEntryStack* theChildStyleStack=0;
for(i=0; i<(theTagCount - theTopIndex); i++) {
- mTempContext->Push((nsCParserNode*)mBodyContext->Pop(theChildStyleStack));
+ nsIParserNode* node=mBodyContext->Pop(theChildStyleStack);
+ mTempContext->Push(node);
+ NS_IF_RELEASE(node); //release the popped node since push will addref for us.
}
// Now flush out all the bad contents.
@@ -2047,7 +2029,9 @@ nsresult CNavDTD::HandleSavedTokens(PRInt32 anIndex) {
// Bad-contents were successfully processed. Now, itz time to get
// back to the original body context state.
for(PRInt32 k=0; k<(theTagCount - theTopIndex); k++) {
- mBodyContext->Push((nsCParserNode*)mTempContext->Pop(theChildStyleStack));
+ nsIParserNode* node=mTempContext->Pop(theChildStyleStack);
+ mBodyContext->Push(node);
+ NS_IF_RELEASE(node);
}
STOP_TIMER()
@@ -2098,23 +2082,20 @@ nsresult CNavDTD::HandleEntityToken(CToken* aToken) {
eHTMLTags theParentTag=mBodyContext->Last();
- nsCParserNode* theNode=mNodeRecycler->CreateNode();
+ nsIParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,0);
if(theNode) {
- theNode->Init(aToken,mLineNumber,0);
PRBool theParentContains=-1; //set to -1 to force CanOmit to recompute...
if(CanOmit(theParentTag,eHTMLTag_entity,theParentContains)) {
eHTMLTags theCurrTag=(eHTMLTags)aToken->GetTypeID();
result=HandleOmittedTag(aToken,theCurrTag,theParentTag,theNode);
- mNodeRecycler->RecycleNode(theNode);
- return result;
}
-
- #ifdef RICKG_DEBUG
- WriteTokenToLog(aToken);
- #endif
-
- result=AddLeaf(theNode);
- mNodeRecycler->RecycleNode(theNode);
+ else {
+#ifdef RICKG_DEBUG
+ WriteTokenToLog(aToken);
+#endif
+ result=AddLeaf(theNode);
+ }
+ NS_IF_RELEASE(theNode);
}
return result;
}
@@ -2138,9 +2119,8 @@ nsresult CNavDTD::HandleCommentToken(CToken* aToken) {
const nsAReadableString& theComment = theToken->GetStringValue();
mLineNumber += CountCharInReadable(theComment, PRUnichar(kNewLine));
- nsCParserNode* theNode=mNodeRecycler->CreateNode();
+ nsIParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,0);
if(theNode) {
- theNode->Init(aToken,mLineNumber,0);
#ifdef RICKG_DEBUG
WriteTokenToLog(aToken);
@@ -2151,7 +2131,7 @@ nsresult CNavDTD::HandleCommentToken(CToken* aToken) {
result=(mSink) ? mSink->AddComment(*theNode) : NS_OK;
- mNodeRecycler->RecycleNode(theNode);
+ NS_IF_RELEASE(theNode);
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleCommentToken(), this=%p\n", this));
START_TIMER();
@@ -2215,9 +2195,8 @@ nsresult CNavDTD::HandleProcessingInstructionToken(CToken* aToken){
nsresult result=NS_OK;
- nsCParserNode* theNode=mNodeRecycler->CreateNode();
+ nsIParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,0);
if(theNode) {
- theNode->Init(aToken,mLineNumber,0);
#ifdef RICKG_DEBUG
WriteTokenToLog(aToken);
@@ -2228,7 +2207,7 @@ nsresult CNavDTD::HandleProcessingInstructionToken(CToken* aToken){
result=(mSink) ? mSink->AddProcessingInstruction(*theNode) : NS_OK;
- mNodeRecycler->RecycleNode(theNode);
+ NS_IF_RELEASE(theNode);
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleProcessingInstructionToken(), this=%p\n", this));
START_TIMER();
@@ -2266,9 +2245,8 @@ nsresult CNavDTD::HandleDocTypeDeclToken(CToken* aToken){
docTypeStr.Cut(0,2); // Now remove "SetStringValue(docTypeStr);
- nsCParserNode* theNode=mNodeRecycler->CreateNode();
+ nsIParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,0);
if(theNode) {
- theNode->Init(aToken,mLineNumber,0);
STOP_TIMER();
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::HandleDocTypeDeclToken(), this=%p\n", this));
@@ -2290,7 +2268,7 @@ nsresult CNavDTD::HandleDocTypeDeclToken(CToken* aToken){
result = (mSink)? mSink->AddDocTypeDecl(*theNode,theMode):NS_OK;
- mNodeRecycler->RecycleNode(theNode);
+ NS_IF_RELEASE(theNode);
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleDocTypeDeclToken(), this=%p\n", this));
START_TIMER();
@@ -2308,7 +2286,7 @@ nsresult CNavDTD::HandleDocTypeDeclToken(CToken* aToken){
* @param aCount is the # of attributes you're expecting
* @return error code (should be 0)
*/
-nsresult CNavDTD::CollectAttributes(nsCParserNode& aNode,eHTMLTags aTag,PRInt32 aCount){
+nsresult CNavDTD::CollectAttributes(nsIParserNode& aNode,eHTMLTags aTag,PRInt32 aCount){
int attr=0;
nsresult result=NS_OK;
@@ -2319,7 +2297,8 @@ nsresult CNavDTD::CollectAttributes(nsCParserNode& aNode,eHTMLTags aTag,PRInt32
for(attr=0;attrPopToken();
+ else
+ theToken=mTokenizer->PopToken();
if(theToken) {
eHTMLTokenTypes theType=eHTMLTokenTypes(theToken->GetTokenType());
if(theType!=eToken_attribute) {
@@ -2359,7 +2338,7 @@ nsresult CNavDTD::CollectAttributes(nsCParserNode& aNode,eHTMLTags aTag,PRInt32
* @param holds the number of skipped content elements encountered
* @return Error condition.
*/
-nsresult CNavDTD::CollectSkippedContent(nsCParserNode& aNode,PRInt32 &aCount) {
+nsresult CNavDTD::CollectSkippedContent(nsIParserNode& aNode,PRInt32 &aCount) {
eHTMLTags theNodeTag=(eHTMLTags)aNode.GetNodeType();
@@ -2371,54 +2350,58 @@ nsresult CNavDTD::CollectSkippedContent(nsCParserNode& aNode,PRInt32 &aCount) {
PRBool aMustConvertLinebreaks = PR_FALSE;
mScratch.Truncate();
- aNode.SetSkippedContent(mScratch); //this guarantees us some skipped content storage.
+
+ nsCParserNode* theNode=NS_STATIC_CAST(nsCParserNode*,&aNode);
+ if(theNode) {
+ theNode->SetSkippedContent(mScratch); //this guarantees us some skipped content storage.
- for(aIndex=0;aIndexGetTokenType();
+ eHTMLTokenTypes theTokenType=(eHTMLTokenTypes)theNextToken->GetTokenType();
- // Dont worry about attributes here because it's already stored in
- // the start token as mTrailing content and will get appended in
- // start token's GetSource();
- if(eToken_attribute!=theTokenType) {
- if ((eToken_entity==theTokenType) &&
- ((eHTMLTag_textarea==theNodeTag) || (eHTMLTag_title==theNodeTag))) {
- mScratch.Truncate();
- ((CEntityToken*)theNextToken)->TranslateToUnicodeStr(mScratch);
- // 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.
- if(mScratch.Length()>0){
- aMustConvertLinebreaks |= (mScratch[0] == kCR);
- aNode.mSkippedContent->Append(mScratch);
+ // Dont worry about attributes here because it's already stored in
+ // the start token as mTrailing content and will get appended in
+ // start token's GetSource();
+ if(eToken_attribute!=theTokenType) {
+ if ((eToken_entity==theTokenType) &&
+ ((eHTMLTag_textarea==theNodeTag) || (eHTMLTag_title==theNodeTag))) {
+ mScratch.Truncate();
+ ((CEntityToken*)theNextToken)->TranslateToUnicodeStr(mScratch);
+ // 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.
+ if(mScratch.Length()>0){
+ aMustConvertLinebreaks |= (mScratch[0] == kCR);
+ theNode->mSkippedContent->Append(mScratch);
+ }
}
- }
- else theNextToken->AppendSource(*aNode.mSkippedContent);
+ else theNextToken->AppendSource(*theNode->mSkippedContent);
+ }
+ IF_FREE(theNextToken);
}
- IF_FREE(theNextToken);
+
+ // if the string contained CRs (hence is either CR, or CRLF terminated)
+ // we need to convert line breaks
+ if (aMustConvertLinebreaks)
+ {
+ /*
+ PRInt32 offset;
+ while ((offset = aNode.mSkippedContent.Find("\r\n")) != kNotFound)
+ aNode.mSkippedContent.Cut(offset, 1); // remove the CR
+
+ // now replace remaining CRs with LFs
+ aNode.mSkippedContent.ReplaceChar("\r", kNewLine);
+ */
+ #if 1
+ nsLinebreakConverter::ConvertStringLineBreaks(*theNode->mSkippedContent,
+ nsLinebreakConverter::eLinebreakAny, nsLinebreakConverter::eLinebreakContent);
+ #endif
+ }
+
+ // Let's hope that this does not hamper the PERFORMANCE!!
+ mLineNumber += theNode->mSkippedContent->CountChar(kNewLine);
}
-
- // if the string contained CRs (hence is either CR, or CRLF terminated)
- // we need to convert line breaks
- if (aMustConvertLinebreaks)
- {
- /*
- PRInt32 offset;
- while ((offset = aNode.mSkippedContent.Find("\r\n")) != kNotFound)
- aNode.mSkippedContent.Cut(offset, 1); // remove the CR
-
- // now replace remaining CRs with LFs
- aNode.mSkippedContent.ReplaceChar("\r", kNewLine);
- */
-#if 1
- nsLinebreakConverter::ConvertStringLineBreaks(*aNode.mSkippedContent,
- nsLinebreakConverter::eLinebreakAny, nsLinebreakConverter::eLinebreakContent);
-#endif
- }
-
- // Let's hope that this does not hamper the PERFORMANCE!!
- mLineNumber += aNode.mSkippedContent->CountChar(kNewLine);
return NS_OK;
}
@@ -2862,10 +2845,8 @@ nsresult CNavDTD::OpenTransientStyles(eHTMLTags aChildTag){
}
else {
//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);
- }
+ nsIParserNode* node=theStack->Remove(sindex,theNodeTag);
+ NS_IF_RELEASE(node);
theEntry--; //back up by one
}
} //if
@@ -2932,10 +2913,8 @@ nsresult CNavDTD::PopStyle(eHTMLTags aTag){
if(mStyleHandlingEnabled) {
#ifdef ENABLE_RESIDUALSTYLE
if(nsHTMLElement::IsResidualStyleTag(aTag)) {
- nsCParserNode* theNode=(nsCParserNode*)mBodyContext->PopStyle(aTag);
- if(theNode) {
- mNodeRecycler->RecycleNode(theNode);
- }
+ nsIParserNode* node=mBodyContext->PopStyle(aTag);
+ NS_IF_RELEASE(node);
}
#endif
} //if
@@ -3547,8 +3526,7 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
nsEntryStack *theChildStyleStack=0;
eHTMLTags theTag=mBodyContext->Last();
- nsCParserNode *theNode=(nsCParserNode*)mBodyContext->Pop(theChildStyleStack);
-// eHTMLTags theParent=mBodyContext->Last();
+ nsCParserNode *theNode=NS_STATIC_CAST(nsCParserNode*,mBodyContext->Pop(theChildStyleStack));
if(theNode) {
result=CloseContainer(theNode,aTarget,aClosedByStartTag);
@@ -3561,15 +3539,12 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
if(!theStyleDoesntLeakOut) {
theStyleDoesntLeakOut = gHTMLElements[aTarget].HasSpecialProperty(kNoStyleLeaksOut);
}
- // (aClosedByStartTag) ? gHTMLElements[aTarget].HasSpecialProperty(kNoStyleLeaksOut)
- // : gHTMLElements[theParent].HasSpecialProperty(kNoStyleLeaksOut);
-
-
- /*************************************************************
- I've added a check (mhasOpenNoXXX) below to prevent residual
- style handling from getting invoked in these cases.
- This fixes bug 25214.
- *************************************************************/
+
+ /*************************************************************
+ I've added a check (mhasOpenNoXXX) below to prevent residual
+ style handling from getting invoked in these cases.
+ This fixes bug 25214.
+ *************************************************************/
if(theTagIsStyle && (0==mHasOpenNoXXX)) {
@@ -3598,7 +3573,8 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
//here's a case we missed:
//The pushes the 1st
onto the rs-stack, then the 2nd
//pops the 1st from the rs-stack altogether.
- mBodyContext->PopStyle(theTag);
+ nsIParserNode* node=mBodyContext->PopStyle(theTag);
+ NS_IF_RELEASE(node);
}
@@ -3643,7 +3619,8 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
// This fixes bug 30885 and 29626
// Make sure that the node, which is about to
// get released does not stay on the style stack...
- mBodyContext->PopStyle(theTag);
+ nsIParserNode* node=mBodyContext->PopStyle(theTag);
+ NS_IF_RELEASE(node);
}
mBodyContext->PushStyles(theChildStyleStack);
}
@@ -3667,7 +3644,8 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
//style tag that got onto that tag stack from a stylestack somewhere.
//Pop it from the stylestack if the target is also a style tag.
if(theTargetTagIsStyle) {
- theNode=(nsCParserNode*)mBodyContext->PopStyle(theTag);
+ nsIParserNode* node=mBodyContext->PopStyle(theTag);
+ NS_IF_RELEASE(node);
}
}
}
@@ -3684,8 +3662,8 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
}
}
#endif
- }//if anode
- mNodeRecycler->RecycleNode(theNode);
+ NS_IF_RELEASE(theNode);
+ }//if theNode
}
} //if
@@ -3769,7 +3747,7 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode *aNode){
while(!done && NS_SUCCEEDED(result)) {
CToken* theToken=mTokenizer->PeekToken();
if(theToken) {
- nsCParserNode* theNode=mNodeRecycler->CreateNode();
+ nsIParserNode* theNode=mNodeAllocator.CreateNode(theToken,mLineNumber,0);
if(theNode) {
theTag=(eHTMLTags)theToken->GetTypeID();
switch(theTag) {
@@ -3778,7 +3756,6 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode *aNode){
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));
@@ -3798,7 +3775,6 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode *aNode){
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();
@@ -3819,7 +3795,7 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode *aNode){
default:
done=PR_TRUE;
} //switch
- mNodeRecycler->RecycleNode(theNode);
+ NS_IF_RELEASE(theNode);
} //if
}//if
else done=PR_TRUE;
diff --git a/mozilla/parser/htmlparser/src/CNavDTD.h b/mozilla/parser/htmlparser/src/CNavDTD.h
index e9cfd65f7c6..3915b6b4e6a 100644
--- a/mozilla/parser/htmlparser/src/CNavDTD.h
+++ b/mozilla/parser/htmlparser/src/CNavDTD.h
@@ -91,6 +91,7 @@
#include "nsDeque.h"
#include "nsParserCIID.h"
#include "nsTime.h"
+#include "nsDTDUtils.h"
#define NS_INAVHTML_DTD_IID \
{0x5c5cce40, 0xcfd6, 0x11d1, \
@@ -106,7 +107,6 @@ class nsEntryStack;
class nsITokenizer;
class nsCParserNode;
class nsTokenAllocator;
-class CNodeRecycler;
/***************************************************************
Now the main event: CNavDTD.
@@ -484,10 +484,10 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
protected:
- nsresult CollectAttributes(nsCParserNode& aNode,eHTMLTags aTag,PRInt32 aCount);
- nsresult CollectSkippedContent(nsCParserNode& aNode,PRInt32& aCount);
- nsresult WillHandleStartTag(CToken* aToken,eHTMLTags aChildTag,nsCParserNode& aNode);
- nsresult DidHandleStartTag(nsCParserNode& aNode,eHTMLTags aChildTag);
+ nsresult CollectAttributes(nsIParserNode& aNode,eHTMLTags aTag,PRInt32 aCount);
+ nsresult CollectSkippedContent(nsIParserNode& aNode,PRInt32& aCount);
+ nsresult WillHandleStartTag(CToken* aToken,eHTMLTags aChildTag,nsIParserNode& aNode);
+ nsresult DidHandleStartTag(nsIParserNode& aNode,eHTMLTags aChildTag);
nsresult HandleOmittedTag(CToken* aToken,eHTMLTags aChildTag,eHTMLTags aParent,nsIParserNode *aNode);
nsresult HandleSavedTokens(PRInt32 anIndex);
nsresult HandleKeyGen(nsIParserNode *aNode);
@@ -513,13 +513,12 @@ protected:
nsParser* mParser;
nsITokenizer* mTokenizer;
nsTokenAllocator* mTokenAllocator;
- CNodeRecycler* mNodeRecycler;
+ nsNodeAllocator mNodeAllocator;
nsDeque mMisplacedContent;
nsDeque mSkippedContent;
PRBool mHasOpenScript;
PRBool mSaveBadTokens;
eHTMLTags mSkipTarget;
- nsDeque mSharedNodes;
nsresult mDTDState;
nsDTDMode mDTDMode;
eParserCommands mParserCommand; //tells us to viewcontent/viewsource/viewerrors...
diff --git a/mozilla/parser/htmlparser/src/COtherDTD.cpp b/mozilla/parser/htmlparser/src/COtherDTD.cpp
index 9b2f7bcd696..716ae924aa8 100644
--- a/mozilla/parser/htmlparser/src/COtherDTD.cpp
+++ b/mozilla/parser/htmlparser/src/COtherDTD.cpp
@@ -129,7 +129,7 @@ NS_IMPL_RELEASE(COtherDTD)
* @param
* @return
*/
-COtherDTD::COtherDTD() : nsIDTD(), mSharedNodes(0) {
+COtherDTD::COtherDTD() : nsIDTD() {
NS_INIT_REFCNT();
mSink = 0;
mParser=0;
@@ -149,6 +149,7 @@ COtherDTD::COtherDTD() : nsIDTD(), mSharedNodes(0) {
mHadBody=PR_FALSE;
mHasOpenScript=PR_FALSE;
mParserCommand=eViewNormal;
+ mNodeAllocator=new nsNodeAllocator();
mBodyContext=new nsDTDContext();
#if 1 //set this to 1 if you want strictDTD to be based on the environment setting.
@@ -169,36 +170,8 @@ COtherDTD::COtherDTD() : nsIDTD(), mSharedNodes(0) {
nsHTMLElement::DebugDumpContainType("c:/temp/ctnrules.out");
#endif
-#ifdef NS_DEBUG
- gNodeCount=0;
-#endif
}
-/**
- * This method creates a new parser node. It tries to get one from
- * the recycle list before allocating a new one.
- * @update gess1/8/99
- * @param
- * @return valid node*
- */
-nsCParserNode* COtherDTD::CreateNode(void) {
-
- nsCParserNode* result=0;
- if(0GetTokenAllocator();
mBodyContext->SetTokenAllocator(mTokenAllocator);
+ mBodyContext->SetNodeAllocator(mNodeAllocator);
if(mSink) {
@@ -529,10 +486,10 @@ nsresult COtherDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIPar
nsCParserNode* theNode=(nsCParserNode*)mBodyContext->Pop(theChildStyles);
if(theNode) {
theNode->mUseCount=0;
- mBodyContext->RecycleNode(theNode);
if(theChildStyles) {
delete theChildStyles;
}
+ NS_IF_RELEASE(theNode);
}
}
}
@@ -606,7 +563,7 @@ nsresult COtherDTD::HandleToken(CToken* aToken,nsIParser* aParser){
* @param aChildTag is the tag itself.
* @return status
*/
-nsresult COtherDTD::DidHandleStartTag(nsCParserNode& aNode,eHTMLTags aChildTag){
+nsresult COtherDTD::DidHandleStartTag(nsIParserNode& aNode,eHTMLTags aChildTag){
nsresult result=NS_OK;
switch(aChildTag){
@@ -683,7 +640,7 @@ void WriteTokenToLog(CToken* aToken) {
* @param aNode is the node (tag) with associated attributes.
* @return TRUE if tag processing should continue; FALSE if the tag has been handled.
*/
-nsresult COtherDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsCParserNode& aNode){
+nsresult COtherDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsIParserNode& aNode){
nsresult result=NS_OK;
//first let's see if there's some skipped content to deal with...
@@ -743,9 +700,8 @@ nsresult COtherDTD::HandleStartToken(CToken* aToken) {
//Begin by gathering up attributes...
nsresult result=NS_OK;
- nsCParserNode* theNode=CreateNode();
+ nsIParserNode* theNode=mNodeAllocator->CreateNode(aToken,mLineNumber,mTokenAllocator);
if(theNode) {
- theNode->Init(aToken,mLineNumber,mTokenAllocator);
eHTMLTags theChildTag=(eHTMLTags)aToken->GetTypeID();
PRInt16 attrCount=aToken->GetAttributeCount();
@@ -786,7 +742,7 @@ nsresult COtherDTD::HandleStartToken(CToken* aToken) {
} //if
}//if
- mBodyContext->RecycleNode(theNode);
+ NS_IF_RELEASE(theNode);
}
else result=NS_ERROR_OUT_OF_MEMORY;
@@ -831,11 +787,10 @@ nsresult COtherDTD::HandleEndToken(CToken* aToken) {
}
CElement* theElement=gElementTable->mElements[theParent];
if(theElement) {
- nsCParserNode* theNode=CreateNode();
+ nsIParserNode* theNode=mNodeAllocator->CreateNode(aToken,mLineNumber,mTokenAllocator);
if(theNode) {
- theNode->Init(aToken,mLineNumber,mTokenAllocator);
result=theElement->HandleEndToken(theNode,theChildTag,mBodyContext,mSink);
- mBodyContext->RecycleNode((nsCParserNode*)theNode);
+ NS_IF_RELEASE(theNode);
}
}
break;
@@ -853,7 +808,7 @@ nsresult COtherDTD::HandleEndToken(CToken* aToken) {
* @param aCount is the # of attributes you're expecting
* @return error code (should be 0)
*/
-nsresult COtherDTD::CollectAttributes(nsCParserNode& aNode,eHTMLTags aTag,PRInt32 aCount){
+nsresult COtherDTD::CollectAttributes(nsIParserNode& aNode,eHTMLTags aTag,PRInt32 aCount){
int attr=0;
nsresult result=NS_OK;
diff --git a/mozilla/parser/htmlparser/src/COtherDTD.h b/mozilla/parser/htmlparser/src/COtherDTD.h
index d2fd78f245e..1f2af7ba893 100644
--- a/mozilla/parser/htmlparser/src/COtherDTD.h
+++ b/mozilla/parser/htmlparser/src/COtherDTD.h
@@ -91,7 +91,6 @@
#include "nsDeque.h"
#include "nsParserCIID.h"
-
#define NS_IOTHERHTML_DTD_IID \
{0x8a5e89c0, 0xd16d, 0x11d1, \
{0x80, 0x22, 0x00, 0x60, 0x8, 0x14, 0x98, 0x89}}
@@ -103,8 +102,9 @@ class nsParser;
class nsDTDContext;
class nsEntryStack;
class nsITokenizer;
-class nsCParserNode;
+class nsIParserNode;
class nsTokenAllocator;
+class nsNodeAllocator;
/***************************************************************
Now the main event: COtherDTD.
@@ -313,10 +313,10 @@ CLASS_EXPORT_HTMLPARS COtherDTD : public nsIDTD {
protected:
- nsresult CollectAttributes(nsCParserNode& aNode,eHTMLTags aTag,PRInt32 aCount);
- nsresult WillHandleStartTag(CToken* aToken,eHTMLTags aChildTag,nsCParserNode& aNode);
- nsresult DidHandleStartTag(nsCParserNode& aNode,eHTMLTags aChildTag);
- nsCParserNode* CreateNode(void);
+ nsresult CollectAttributes(nsIParserNode& aNode,eHTMLTags aTag,PRInt32 aCount);
+ nsresult WillHandleStartTag(CToken* aToken,eHTMLTags aChildTag,nsIParserNode& aNode);
+ nsresult DidHandleStartTag(nsIParserNode& aNode,eHTMLTags aChildTag);
+ nsIParserNode* CreateNode(CToken* aToken=nsnull,PRInt32 aLineNumber=1,nsTokenAllocator* aTokenAllocator=0);
nsIHTMLContentSink* mSink;
@@ -332,10 +332,10 @@ protected:
PRInt32 mLineNumber;
nsParser* mParser;
nsITokenizer* mTokenizer;
- nsTokenAllocator* mTokenAllocator;
+ nsTokenAllocator* mTokenAllocator;
+ nsNodeAllocator* mNodeAllocator;
PRBool mHasOpenScript;
eHTMLTags mSkipTarget;
- nsDeque mSharedNodes;
nsresult mDTDState;
nsDTDMode mDTDMode;
eParserCommands mParserCommand; //tells us to viewcontent/viewsource/viewerrors...
@@ -346,10 +346,6 @@ protected:
eParserDocType mDocType;
PRBool mEnableStrict;
-#ifdef NS_DEBUG
- PRInt32 gNodeCount;
-#endif
-
};
extern NS_HTMLPARS nsresult NS_NewOtherHTMLDTD(nsIDTD** aInstancePtrResult);
diff --git a/mozilla/parser/htmlparser/src/COtherElements.h b/mozilla/parser/htmlparser/src/COtherElements.h
index 6f261ba8817..2e5410f7094 100644
--- a/mozilla/parser/htmlparser/src/COtherElements.h
+++ b/mozilla/parser/htmlparser/src/COtherElements.h
@@ -323,8 +323,7 @@ public:
CElement *theElement=(aTag==mTag) ? this : GetElement(aTag);
result=theElement->NotifyClose(theNode,aTag,aContext,aSink);
- aContext->RecycleNode((nsCParserNode*)theNode);
-
+ NS_IF_RELEASE(aNode);
return result;
}
@@ -808,9 +807,8 @@ public:
if(aContext->mTableStates) {
if(aContext->mTableStates->CanOpenTBody()) {
- nsCParserNode* theNode=aContext->gNodeRecycler->CreateNode();
CToken* theToken=(CStartToken*)aContext->mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_tbody);
- theNode->Init(theToken,0,0); //this will likely leak...
+ nsIParserNode* theNode=aContext->mNodeAllocator->CreateNode(theToken,0,0);
result=HandleStartToken(theNode,eHTMLTag_tbody,aContext,aSink);
}
@@ -1797,8 +1795,7 @@ public:
//let's auto open the body
CToken* theToken=(CStartToken*)aContext->mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_body);
- nsCParserNode* theNode=aContext->gNodeRecycler->CreateNode();
- theNode->Init(theToken,0,0);
+ nsIParserNode* theNode=aContext->mNodeAllocator->CreateNode(theToken,0,0);
result=theBody->HandleStartToken(theNode,eHTMLTag_body,aContext,aSink);
diff --git a/mozilla/parser/htmlparser/src/nsDTDUtils.cpp b/mozilla/parser/htmlparser/src/nsDTDUtils.cpp
index 3033f757597..5ca27e7bbcf 100644
--- a/mozilla/parser/htmlparser/src/nsDTDUtils.cpp
+++ b/mozilla/parser/htmlparser/src/nsDTDUtils.cpp
@@ -132,6 +132,9 @@ void nsEntryStack::Push(const nsIParserNode* aNode,nsEntryStack* aStyleStack) {
mEntries[mCount].mTag=(eHTMLTags)aNode->GetNodeType();
mEntries[mCount].mNode=(nsIParserNode*)aNode;
+
+ NS_ADDREF(mEntries[mCount].mNode);
+
mEntries[mCount].mParent=aStyleStack;
mEntries[mCount++].mStyles=0;
}
@@ -159,6 +162,9 @@ void nsEntryStack::PushFront(const nsIParserNode* aNode,nsEntryStack* aStyleStac
mEntries[0].mTag=(eHTMLTags)aNode->GetNodeType();
mEntries[0].mNode=(nsIParserNode*)aNode;
+
+ NS_ADDREF(mEntries[0].mNode);
+
mEntries[0].mParent=aStyleStack;
mEntries[0].mStyles=0;
mCount++;
@@ -210,6 +216,7 @@ nsIParserNode* nsEntryStack::Remove(PRInt32 anIndex,eHTMLTags aTag) {
for(theIndex=anIndex;theIndexRecycleNode((nsCParserNode*)aStyles->Pop());
+ nsIParserNode* theNode=aStyles->Pop();
+ NS_IF_RELEASE(theNode);
delete aStyles;
aStyles=0;
}
@@ -1118,51 +1125,12 @@ nsIParserNode* nsDTDContext::RemoveStyle(eHTMLTags aTag){
return result;
}
-/**
- *
- * @update harishd 04/10/00
- */
-nsresult nsDTDContext::GetNodeRecycler(CNodeRecycler*& aNodeRecycler){
- nsresult result=NS_OK;
- if(!gNodeRecycler) {
- gNodeRecycler=new CNodeRecycler();
- if(gNodeRecycler==0) result=NS_ERROR_OUT_OF_MEMORY;
- }
- aNodeRecycler=gNodeRecycler;
- return result;
-}
-
-/**
- *
- * @update rickg 16June2000
- */
-void nsDTDContext::RecycleNode(nsCParserNode* aNode) {
- nsresult result=NS_OK;
-
- if(aNode) {
- if(!gNodeRecycler)
- result=nsDTDContext::GetNodeRecycler(gNodeRecycler);
-
- if(NS_SUCCEEDED(result)) {
- gNodeRecycler->RecycleNode(aNode);
- }
- else {
- delete aNode;
- }
- }
-}
-
-
/**
* This gets called when the parser module is getting unloaded
*
* @return nada
*/
void nsDTDContext::ReleaseGlobalObjects(){
- if(gNodeRecycler) {
- delete gNodeRecycler;
- gNodeRecycler=0;
- }
}
@@ -1170,9 +1138,9 @@ void nsDTDContext::ReleaseGlobalObjects(){
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;
+static const size_t kTokenBuckets[] ={sizeof(CStartToken),sizeof(CAttributeToken),sizeof(CCommentToken),sizeof(CEndToken)};
+static const PRInt32 kNumTokenBuckets = sizeof(kTokenBuckets) / sizeof(size_t);
+static const PRInt32 kInitialTokenPoolSize = NS_SIZE_IN_HEAP(sizeof(CToken)) * 200;
/**
*
@@ -1183,7 +1151,7 @@ nsTokenAllocator::nsTokenAllocator() {
MOZ_COUNT_CTOR(nsTokenAllocator);
- mArenaPool.Init("TheTokenPool", kBucketSizes, kNumBuckets, kInitialPoolSize);
+ mArenaPool.Init("TokenPool", kTokenBuckets, kNumTokenBuckets, kInitialTokenPoolSize);
#ifdef NS_DEBUG
int i=0;
@@ -1295,7 +1263,6 @@ CToken* nsTokenAllocator::CreateTokenOfType(eHTMLTokenTypes aType,eHTMLTags aTag
return result;
}
-#define DEBUG_TRACK_NODES
#ifdef DEBUG_TRACK_NODES
static nsCParserNode* gAllNodes[100];
@@ -1329,69 +1296,72 @@ void RemoveNode(nsCParserNode *aNode) {
#endif
-CNodeRecycler::CNodeRecycler(): mSharedNodes(0) {
-
- MOZ_COUNT_CTOR(CNodeRecycler);
+#ifdef HEAP_ALLOCATED_NODES
+nsNodeAllocator::nsNodeAllocator():mSharedNodes(0){
+#ifdef DEBUG_TRACK_NODES
+ mCount=0;
+#endif
+#else
+ static const size_t kNodeBuckets[] ={sizeof(nsCParserNode)};
+ static const PRInt32 kNumNodeBuckets = sizeof(kNodeBuckets) / sizeof(size_t);
+ static const PRInt32 kInitialNodePoolSize = NS_SIZE_IN_HEAP(sizeof(nsCParserNode)) * 50;
+nsNodeAllocator::nsNodeAllocator() {
+ mNodePool.Init("NodePool", kNodeBuckets, kNumNodeBuckets, kInitialNodePoolSize);
+#endif
+ MOZ_COUNT_CTOR(nsNodeAllocator);
}
+
+nsNodeAllocator::~nsNodeAllocator() {
+ MOZ_COUNT_DTOR(nsNodeAllocator);
-CNodeRecycler::~CNodeRecycler() {
-
- MOZ_COUNT_DTOR(CNodeRecycler);
-
+#ifdef HEAP_ALLOCATED_NODES
nsCParserNode* theNode=0;
while((theNode=(nsCParserNode*)mSharedNodes.Pop())){
-#ifdef DEBUG_TRACK_NODES
+#ifdef DEBUG_TRACK_NODES
RemoveNode(theNode);
#endif
- delete theNode;
+ ::operator delete(theNode);
+ theNode=nsnull;
}
-
#ifdef DEBUG_TRACK_NODES
- if(0mUseCount)) {
-
- IF_FREE(aNode->mToken);
+nsIParserNode* nsNodeAllocator::CreateNode(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator) {
+ nsCParserNode* result=0;
- CToken* theToken=0;
- while((theToken=(CToken*)aNode->PopAttributeToken())){
- IF_FREE(theToken);
- }
- mSharedNodes.Push(aNode);
- }
-}
-
-nsCParserNode* CNodeRecycler::CreateNode(void) {
-
-#ifdef DEBUG_TRACK_NODES
+#ifdef HEAP_ALLOCATED_NODES
#if 0
if(gAllNodeCount!=mSharedNodes.GetSize()) {
int x=10; //this is very BAD!
}
-#endif
#endif
- nsCParserNode* result=0;
- if(0Init(aToken,aLineNumber,aTokenAllocator,this);
}
else{
- result=new nsCParserNode();
+ result=new nsCParserNode(aToken,aLineNumber,aTokenAllocator,this);
#ifdef DEBUG_TRACK_NODES
- AddNode(result);
+ mCount++;
+ AddNode(NS_STATIC_CAST(nsCParserNode*,result));
#endif
-
+ NS_IF_ADDREF(result);
}
- return result;
+#else
+ result=new(mNodePool) nsCParserNode(aToken,aLineNumber,aTokenAllocator);
+ NS_IF_ADDREF(result);
+#endif
+ return NS_STATIC_CAST(nsIParserNode*,result);
}
void DebugDumpContainmentRules(nsIDTD& theDTD,const char* aFilename,const char* aTitle) {
diff --git a/mozilla/parser/htmlparser/src/nsDTDUtils.h b/mozilla/parser/htmlparser/src/nsDTDUtils.h
index 603c9456850..7338250cd5d 100644
--- a/mozilla/parser/htmlparser/src/nsDTDUtils.h
+++ b/mozilla/parser/htmlparser/src/nsDTDUtils.h
@@ -46,11 +46,11 @@
#include "nsVoidArray.h"
#define IF_HOLD(_ptr) if(_ptr) { _ptr->AddRef(); }
-#define IF_FREE(_ptr) if(_ptr) { _ptr->Release(); _ptr=0; } // recycles _ptr
+#define IF_FREE(_ptr) if(_ptr) { _ptr->Release(); _ptr=0; } // recycles _ptr
class nsIParserNode;
class nsCParserNode;
-class CNodeRecycler;
+class nsNodeAllocator;
void DebugDumpContainmentRules(nsIDTD& theDTD,const char* aFilename,const char* aTitle);
@@ -238,7 +238,6 @@ protected:
#endif
};
-
/************************************************************************
CNodeRecycler class implementation.
This class is used to recycle nodes.
@@ -246,23 +245,25 @@ protected:
that get created during the run of the system.
************************************************************************/
-class CNodeRecycler {
+class nsNodeAllocator {
public:
- CNodeRecycler();
- virtual ~CNodeRecycler();
- virtual nsCParserNode* CreateNode(void);
- virtual void RecycleNode(nsCParserNode* aNode);
-
+ nsNodeAllocator();
+ virtual ~nsNodeAllocator();
+ virtual nsIParserNode* CreateNode(CToken* aToken=nsnull,PRInt32 aLineNumber=1,nsTokenAllocator* aTokenAllocator=0);
+#ifdef HEAP_ALLOCATED_NODES
+ void Recycle(nsIParserNode* aNode) { mSharedNodes.Push(NS_STATIC_CAST(void*,aNode)); }
protected:
- nsDeque mSharedNodes;
-
-#ifdef NS_DEBUG
- PRInt32 gNodeCount;
+ nsDeque mSharedNodes;
+#ifdef DEBUG_TRACK_NODES
+ PRInt32 mCount;
+#endif
+#else
+protected:
+ nsFixedSizeAllocator mNodePool;
#endif
};
-
/************************************************************************
The dtdcontext class defines an ordered list of tags (a context).
************************************************************************/
@@ -295,8 +296,6 @@ public:
nsIParserNode* PopStyle(eHTMLTags aTag);
nsIParserNode* RemoveStyle(eHTMLTags aTag);
- nsresult GetNodeRecycler(CNodeRecycler*& aNodeRecycler);
- void RecycleNode(nsCParserNode *aNode);
static void ReleaseGlobalObjects(void);
CNamedEntity* RegisterEntity(const nsString& aName,const nsString& aValue);
@@ -304,9 +303,10 @@ public:
void ResetCounters(void);
void AllocateCounters(void);
- PRInt32 IncrementCounter(eHTMLTags aTag,nsCParserNode& aNode,nsString& aResult);
+ PRInt32 IncrementCounter(eHTMLTags aTag,nsIParserNode& aNode,nsString& aResult);
void SetTokenAllocator(nsTokenAllocator* aTokenAllocator) { mTokenAllocator=aTokenAllocator; }
+ void SetNodeAllocator(nsNodeAllocator* aNodeAllocator) { mNodeAllocator=aNodeAllocator; }
nsEntryStack mStack; //this will hold a list of tagentries...
PRInt32 mResidualStyleCount;
@@ -324,12 +324,10 @@ public:
union {
PRUint32 mAllBits;
CFlags mFlags;
- };
-
-
- static CNodeRecycler *gNodeRecycler;
+ };
nsTokenAllocator *mTokenAllocator;
+ nsNodeAllocator *mNodeAllocator;
CTableState *mTableStates;
PRInt32 *mCounters;
nsDeque mEntities;
diff --git a/mozilla/parser/htmlparser/src/nsIParserNode.h b/mozilla/parser/htmlparser/src/nsIParserNode.h
index 8fe06fe980b..470695e16f1 100644
--- a/mozilla/parser/htmlparser/src/nsIParserNode.h
+++ b/mozilla/parser/htmlparser/src/nsIParserNode.h
@@ -46,7 +46,11 @@
#include "nsString.h"
#include "nsDebug.h"
-// class CToken;
+//#define HEAP_ALLOCATED_NODES
+//#define DEBUG_TRACK_NODES
+
+
+class CToken;
// 6e59f160-2717-11d2-9246-00805f8a7ab6
#define NS_IPARSER_NODE_IID \
@@ -133,6 +137,9 @@ class nsIParserNode : public nsISupports {
*/
virtual PRInt32 TranslateToUnicodeStr(nsString& aString) const = 0;
+
+ virtual void AddAttribute(CToken* aToken)=0;
+
/**
* This getter retrieves the line number from the input source where
* the token occured. Lines are interpreted as occuring between \n characters.
diff --git a/mozilla/parser/htmlparser/src/nsLoggingSink.cpp b/mozilla/parser/htmlparser/src/nsLoggingSink.cpp
index 69eb8653029..7ea1600cc03 100644
--- a/mozilla/parser/htmlparser/src/nsLoggingSink.cpp
+++ b/mozilla/parser/htmlparser/src/nsLoggingSink.cpp
@@ -147,7 +147,7 @@ nsLoggingSink::WillBuildModel() {
NS_IMETHODIMP
nsLoggingSink::DidBuildModel(PRInt32 aQualityLevel) {
- WriteTabs(mOutput,mLevel--);
+ WriteTabs(mOutput,--mLevel);
PR_fprintf(mOutput, "\n");
//proxy the call to the real sink if you have one.
@@ -342,11 +342,14 @@ nsLoggingSink::AddComment(const nsIParserNode& aNode){
NS_IMETHODIMP
nsLoggingSink::SetTitle(const nsString& aValue) {
- nsAutoString tmp;
- QuoteText(aValue, tmp);
- WriteTabs(mOutput,++mLevel);
- PR_fprintf(mOutput, "\n", tmp.GetBuffer());
- --mLevel;
+ char* tmp;
+ GetNewCString(aValue, &tmp);
+ WriteTabs(mOutput,++mLevel);
+ if(tmp) {
+ PR_fprintf(mOutput, "\n", tmp);
+ nsMemory::Free(tmp);
+ }
+ --mLevel;
nsresult theResult=NS_OK;
@@ -544,9 +547,12 @@ nsLoggingSink::OpenNode(const char* aKind, const nsIParserNode& aNode) {
PR_fprintf(mOutput, "\"%s\"", tag);
}
else {
- const nsAReadableString& theText = aNode.GetText();
- PR_fprintf(mOutput, "\"%s\"", theText);
-
+ char* text;
+ GetNewCString(aNode.GetText(), &text);
+ if(text) {
+ PR_fprintf(mOutput, "\"%s\"", text);
+ nsMemory::Free(text);
+ }
}
if (WillWriteAttributes(aNode)) {
@@ -571,18 +577,25 @@ nsLoggingSink::CloseNode(const char* aKind) {
nsresult
nsLoggingSink::WriteAttributes(const nsIParserNode& aNode) {
- nsAutoString tmp, tmp2;
+
+ WriteTabs(mOutput,1+mLevel);
+ nsAutoString tmp;
PRInt32 ac = aNode.GetAttributeCount();
for (PRInt32 i = 0; i < ac; i++) {
+ char* key=nsnull;
+ char* value=nsnull;
const nsAReadableString& k = aNode.GetKeyAt(i);
const nsString& v = aNode.GetValueAt(i);
- PR_fprintf(mOutput, " 0) {
PRUnichar first = tmp.First();
if ((first == '"') || (first == '\'')) {
if (tmp.Last() == first) {
@@ -595,20 +608,26 @@ nsLoggingSink::WriteAttributes(const nsIParserNode& aNode) {
// Mismatched quotes - leave them in
}
}
- }
- QuoteText(tmp, tmp2);
- PR_fprintf(mOutput, "%s\"/>\n", tmp2.GetBuffer());
- }
+ GetNewCString(tmp, &value);
- if (0 != strchr(gSkippedContentTags, aNode.GetNodeType())) {
- const nsString& content = aNode.GetSkippedContent();
- if (content.Length() > 0) {
- QuoteText(content, tmp);
- PR_fprintf(mOutput, " \n", tmp.GetBuffer()) ;
+ if(value) {
+ PR_fprintf(mOutput, "%s\"/>\n", value);
+ WriteTabs(mOutput,1+mLevel);
+ nsMemory::Free(value);
+ }
}
}
+ if (0 != strchr(gSkippedContentTags, aNode.GetNodeType())) {
+ char* content;
+ GetNewCString(aNode.GetSkippedContent(), &content);
+ if(content) {
+ PR_fprintf(mOutput, " \n", content) ;
+ nsMemory::Free(content);
+ }
+ }
+ WriteTabs(mOutput,1+mLevel);
return NS_OK;
}
@@ -654,11 +673,15 @@ nsLoggingSink::LeafNode(const nsIParserNode& aNode)
else {
PRInt32 pos;
nsAutoString tmp;
+ char* str;
switch (nodeType) {
case eHTMLTag_whitespace:
case eHTMLTag_text:
- QuoteText(aNode.GetText(), tmp);
- PR_fprintf(mOutput, "\n", tmp.GetBuffer());
+ GetNewCString(aNode.GetText(), &str);
+ if(str) {
+ PR_fprintf(mOutput, "\n", str);
+ nsMemory::Free(str);
+ }
break;
case eHTMLTag_newline:
@@ -707,6 +730,28 @@ nsLoggingSink::QuoteText(const nsAReadableString& aValue, nsString& aResult) {
return NS_OK;
}
+/**
+ * Use this method to convert nsString to char*.
+ * REMEMBER: Match this call with nsMemory::Free(aResult);
+ *
+ * @update 04/04/99 harishd
+ * @param aValue - The string value
+ * @param aResult - String coverted to char*.
+ */
+nsresult
+nsLoggingSink::GetNewCString(const nsAReadableString& aValue, char** aResult)
+{
+ nsresult result=NS_OK;
+ nsAutoString temp;
+ result=QuoteText(aValue,temp);
+ if(NS_SUCCEEDED(result)) {
+ if(temp.Length()>0) {
+ *aResult=temp.ToNewCString();
+ }
+ }
+ return result;
+}
+
NS_IMETHODIMP
nsLoggingSink::DoFragment(PRBool aFlag)
{
diff --git a/mozilla/parser/htmlparser/src/nsLoggingSink.h b/mozilla/parser/htmlparser/src/nsLoggingSink.h
index 602f22e5891..d3931bf4a28 100644
--- a/mozilla/parser/htmlparser/src/nsLoggingSink.h
+++ b/mozilla/parser/htmlparser/src/nsLoggingSink.h
@@ -86,6 +86,7 @@ public:
nsresult LeafNode(const nsIParserNode& aNode);
nsresult WriteAttributes(const nsIParserNode& aNode);
nsresult QuoteText(const nsAReadableString& aValue, nsString& aResult);
+ nsresult GetNewCString(const nsAReadableString& aValue, char** aResult);
PRBool WillWriteAttributes(const nsIParserNode& aNode);
protected:
diff --git a/mozilla/parser/htmlparser/src/nsParserModule.cpp b/mozilla/parser/htmlparser/src/nsParserModule.cpp
index 9a2939a40f1..b290cf1d5d7 100644
--- a/mozilla/parser/htmlparser/src/nsParserModule.cpp
+++ b/mozilla/parser/htmlparser/src/nsParserModule.cpp
@@ -136,7 +136,6 @@ nsParserService::IsBlock(PRInt32 aId, PRBool& aIsBlock) const
//----------------------------------------------------------------------
static NS_DEFINE_CID(kParserCID, NS_PARSER_IID);
-static NS_DEFINE_CID(kParserNodeCID, NS_PARSER_NODE_IID);
static NS_DEFINE_CID(kLoggingSinkCID, NS_LOGGING_SINK_CID);
static NS_DEFINE_CID(kWellFormedDTDCID, NS_WELLFORMEDDTD_CID);
static NS_DEFINE_CID(kNavDTDCID, NS_CNAVDTD_CID);
@@ -154,7 +153,6 @@ struct Components {
static Components gComponents[] = {
{ "Parser", &kParserCID },
- { "ParserNode", &kParserNodeCID },
{ "Logging sink", &kLoggingSinkCID },
{ "Well formed DTD", &kWellFormedDTDCID },
{ "Navigator HTML DTD", &kNavDTDCID },
@@ -169,7 +167,6 @@ static Components gComponents[] = {
#define NUM_COMPONENTS (sizeof(gComponents) / sizeof(gComponents[0]));
NS_GENERIC_FACTORY_CONSTRUCTOR(nsParser)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsCParserNode)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsLoggingSink)
NS_GENERIC_FACTORY_CONSTRUCTOR(CWellFormedDTD)
NS_GENERIC_FACTORY_CONSTRUCTOR(CNavDTD)
@@ -277,13 +274,6 @@ nsParserModule::GetClassObject(nsIComponentManager *aCompMgr,
}
fact = mParserFactory;
}
- else if (aClass.Equals(kParserNodeCID)) {
- if (!mParserNodeFactory) {
- rv = NS_NewGenericFactory(getter_AddRefs(mParserNodeFactory),
- &nsCParserNodeConstructor);
- }
- fact = mParserNodeFactory;
- }
else if (aClass.Equals(kLoggingSinkCID)) {
if (!mLoggingSinkFactory) {
rv = NS_NewGenericFactory(getter_AddRefs(mLoggingSinkFactory),
diff --git a/mozilla/parser/htmlparser/src/nsParserNode.cpp b/mozilla/parser/htmlparser/src/nsParserNode.cpp
index b098fa8e8c4..42deac4f10f 100644
--- a/mozilla/parser/htmlparser/src/nsParserNode.cpp
+++ b/mozilla/parser/htmlparser/src/nsParserNode.cpp
@@ -28,7 +28,6 @@
#include "nsITokenizer.h"
#include "nsDTDUtils.h"
-
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kClassIID, NS_PARSER_NODE_IID);
static NS_DEFINE_IID(kIParserNodeIID, NS_IPARSER_NODE_IID);
@@ -39,6 +38,7 @@ const nsString& GetEmptyString() {
return gEmptyStr;
}
+
/**
* Default constructor
*
@@ -46,7 +46,7 @@ const nsString& GetEmptyString() {
* @param aToken -- token to init internal token
* @return
*/
-nsCParserNode::nsCParserNode(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator):
+nsCParserNode::nsCParserNode(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator,nsNodeAllocator* aNodeAllocator):
nsIParserNode() {
NS_INIT_REFCNT();
MOZ_COUNT_CTOR(nsCParserNode);
@@ -61,15 +61,9 @@ nsCParserNode::nsCParserNode(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator
mUseCount=0;
mSkippedContent=0;
mGenericState=PR_FALSE;
-}
-
-static void RecycleTokens(nsTokenAllocator* aTokenAllocator,nsDeque& aDeque) {
- CToken* theToken=0;
- if(aTokenAllocator) {
- while((theToken=(CToken*)aDeque.Pop())){
- IF_FREE(theToken);
- }
- }
+#ifdef HEAP_ALLOCATED_NODES
+ mNodeAllocator=aNodeAllocator;
+#endif
}
/**
@@ -83,6 +77,14 @@ static void RecycleTokens(nsTokenAllocator* aTokenAllocator,nsDeque& aDeque) {
nsCParserNode::~nsCParserNode() {
MOZ_COUNT_DTOR(nsCParserNode);
ReleaseAll();
+#ifdef HEAP_ALLOCATED_NODES
+ if(mNodeAllocator) {
+ mNodeAllocator->Recycle(this);
+ }
+ mNodeAllocator=nsnull;
+#endif
+ mTokenAllocator=0;
+ mLineNumber=0;
}
@@ -97,11 +99,15 @@ NS_IMPL_RELEASE(nsCParserNode)
* @return
*/
-nsresult nsCParserNode::Init(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator) {
+nsresult nsCParserNode::Init(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator,nsNodeAllocator* aNodeAllocator) {
mLineNumber=aLineNumber;
mTokenAllocator=aTokenAllocator;
- if(mAttributes && (mAttributes->GetSize()))
- RecycleTokens(mTokenAllocator,*mAttributes);
+ if(mAttributes && (mAttributes->GetSize())) {
+ CToken* theAttrToken=0;
+ while((theAttrToken=NS_STATIC_CAST(CToken*,mAttributes->Pop()))) {
+ IF_FREE(theAttrToken);
+ }
+ }
mToken=aToken;
IF_HOLD(mToken);
mGenericState=PR_FALSE;
@@ -109,6 +115,9 @@ nsresult nsCParserNode::Init(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator
if(mSkippedContent) {
mSkippedContent->Truncate();
}
+#ifdef HEAP_ALLOCATED_NODES
+ mNodeAllocator=aNodeAllocator;
+#endif
return NS_OK;
}
@@ -369,30 +378,18 @@ void nsCParserNode::GetSource(nsString& aString) {
*/
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!
- // Umm...why is this a useful comment in the source?
-
- if(mTokenAllocator) {
- RecycleTokens(mTokenAllocator,*mAttributes);
- }
- else {
- CToken* theToken=(CToken*)mAttributes->Pop();
- while(theToken){
- IF_FREE(theToken);
- theToken=(CToken*)mAttributes->Pop();
- }
+ CToken* theAttrToken=0;
+ while((theAttrToken=NS_STATIC_CAST(CToken*,mAttributes->Pop()))) {
+ IF_FREE(theAttrToken);
}
delete mAttributes;
mAttributes=0;
}
if(mSkippedContent) {
delete mSkippedContent;
+ mSkippedContent=0;
}
IF_FREE(mToken);
- mSkippedContent=0;
return NS_OK;
}
diff --git a/mozilla/parser/htmlparser/src/nsParserNode.h b/mozilla/parser/htmlparser/src/nsParserNode.h
index 540da833188..c8898cf560a 100644
--- a/mozilla/parser/htmlparser/src/nsParserNode.h
+++ b/mozilla/parser/htmlparser/src/nsParserNode.h
@@ -45,6 +45,7 @@
#include "nsString.h"
#include "nsParserCIID.h"
#include "nsDeque.h"
+#include "nsDTDUtils.h"
class nsTokenAllocator;
@@ -54,12 +55,44 @@ class nsCParserNode : public nsIParserNode {
NS_DECL_ISUPPORTS
+
+#ifdef HEAP_ALLOCATED_NODES
+ void* operator new(size_t aSize) {
+ return ::operator new(aSize);
+ }
+#else
+ /**
+ *
+ * @update harishd 01/01/01
+ * @param aSize -
+ * @param aArena - Allocate memory from this pool.
+ */
+ static void * operator new (size_t aSize, nsFixedSizeAllocator& anArena)
+ {
+ return anArena.Alloc(aSize);
+ }
+#endif
+ /**
+ *
+ *
+ * @update harishd 01/01/01
+ * @param aPtr - The memory that should be recycled/freed.
+ * @param aSize - The size of memory that needs to be freed.
+ */
+ static void operator delete (void* aPtr,size_t aSize)
+ {
+ // NodeAllocator would take care of heap allocated nodes..
+#ifndef HEAP_ALLOCATED_NODES
+ nsFixedSizeAllocator::Free(aPtr,aSize);
+#endif
+ }
+
/**
* Default constructor
* @update gess5/11/98
* @param aToken is the token this node "refers" to
*/
- nsCParserNode(CToken* aToken=nsnull,PRInt32 aLineNumber=1,nsTokenAllocator* aTokenAllocator=0);
+ nsCParserNode(CToken* aToken=nsnull,PRInt32 aLineNumber=1,nsTokenAllocator* aTokenAllocator=0,nsNodeAllocator* aNodeAllocator=0);
/**
* Destructor
@@ -71,7 +104,7 @@ class nsCParserNode : public nsIParserNode {
* Init
* @update gess5/11/98
*/
- virtual nsresult Init(CToken* aToken=nsnull,PRInt32 aLineNumber=1,nsTokenAllocator* aTokenAllocator=0);
+ virtual nsresult Init(CToken* aToken=nsnull,PRInt32 aLineNumber=1,nsTokenAllocator* aTokenAllocator=0,nsNodeAllocator* aNodeAllocator=0);
/**
* Retrieve the name of the node
@@ -212,6 +245,10 @@ class nsCParserNode : public nsIParserNode {
nsCOMPtr mIDAttributeAtom;
nsTokenAllocator* mTokenAllocator;
+#ifdef HEAP_ALLOCATED_NODES
+ nsNodeAllocator* mNodeAllocator; // weak
+#endif
+
};
#endif
diff --git a/mozilla/parser/htmlparser/src/nsViewSourceHTML.cpp b/mozilla/parser/htmlparser/src/nsViewSourceHTML.cpp
index e2d4cdaed49..3e7d89dbef6 100644
--- a/mozilla/parser/htmlparser/src/nsViewSourceHTML.cpp
+++ b/mozilla/parser/htmlparser/src/nsViewSourceHTML.cpp
@@ -1092,11 +1092,9 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser) {
if((ePlainText!=mDocType) && mParser && (NS_OK==result)) {
CObserverService* theService=mParser->GetObserverService();
if(theService) {
- CParserContext* pc=mParser->PeekContext();
- void* theDocID=(pc)? pc->mKey:0;
- eHTMLTags theTag=(eHTMLTags)theToken->GetTypeID();
-
- result=theService->Notify(theTag,theContext.mTokenNode,theDocID, NS_ConvertToString(kViewSourceCommand), mParser);
+ eHTMLTags theTag=(eHTMLTags)theToken->GetTypeID();
+ const nsISupportsParserBundle* bundle=mParser->GetParserBundle();
+ result=theService->Notify(theTag,theContext.mTokenNode,(void*)bundle, mMimeType, mParser);
}
}
}
diff --git a/mozilla/parser/htmlparser/src/nsXIFDTD.cpp b/mozilla/parser/htmlparser/src/nsXIFDTD.cpp
index 539c81f95d8..16df385081d 100644
--- a/mozilla/parser/htmlparser/src/nsXIFDTD.cpp
+++ b/mozilla/parser/htmlparser/src/nsXIFDTD.cpp
@@ -652,7 +652,7 @@ nsresult nsXIFDTD::HandleStartToken(CToken* aToken) {
}
}
- mNodeRecycler->RecycleNode(node);
+ NS_IF_RELEASE(node);
return result;
}
@@ -1066,7 +1066,7 @@ nsresult nsXIFDTD::CloseContainer(const nsIParserNode& aNode)
if(IsHTMLContainer(theTag) && theTag!=eHTMLTag_unknown) {
result=mSink->CloseContainer(aNode);
}
- mNodeRecycler->RecycleNode(theNode);
+ NS_IF_RELEASE(aNode);
}
return result;
}
@@ -1398,7 +1398,8 @@ nsresult nsXIFDTD::EndCSSStyleSheet(const nsIParserNode& aNode)
((nsCParserNode&)aNode).SetSkippedContent(mBuffer);
result=mSink->AddLeaf(aNode);
- mNodeRecycler->RecycleNode((nsCParserNode*)mXIFContext->Pop());
+ nsIParserNode* node=mXIFContext->Pop();
+ NS_IF_RELEASE(node);
return result;
}
diff --git a/mozilla/parser/htmlparser/tests/outsinks/Convert.cpp b/mozilla/parser/htmlparser/tests/outsinks/Convert.cpp
index 288a9e968e9..b5430f51b59 100644
--- a/mozilla/parser/htmlparser/tests/outsinks/Convert.cpp
+++ b/mozilla/parser/htmlparser/tests/outsinks/Convert.cpp
@@ -22,7 +22,6 @@
#include // for isdigit()
-#include "CNavDTD.h"
#include "nsParserCIID.h"
#include "nsIParser.h"
#include "nsIHTMLContentSink.h"
@@ -160,9 +159,11 @@ HTML2text(nsString& inString, nsString& inType, nsString& outType,
#endif /* USE_SERIALIZER */
parser->SetContentSink(sink);
- nsIDTD* dtd = nsnull;
- if (inType.EqualsWithConversion("text/html"))
- rv = NS_NewNavHTMLDTD(&dtd);
+ nsCOMPtr dtd;
+ if (inType.EqualsWithConversion("text/html")) {
+ static NS_DEFINE_CID(kNavDTDCID, NS_CNAVDTD_CID);
+ rv=nsComponentManager::CreateInstance(kNavDTDCID,nsnull,NS_GET_IID(nsIDTD),getter_AddRefs(dtd));
+ }
else
{
printf("Don't know how to deal with non-html input!\n");
@@ -184,8 +185,6 @@ HTML2text(nsString& inString, nsString& inType, nsString& outType,
printf("Parse() failed! 0x%x\n", rv);
return rv;
}
-
- NS_IF_RELEASE(dtd);
NS_RELEASE(parser);
if (compareAgainst.Length() > 0)