mCurrentPos->GetCurrent();
-
- /**************************************************************************
- The point of this code to serve as a testbed for parser reentrancy.
- If you set recurse=1, we go reentrant, passing a text string of HTML onto
- the parser for inline processing, just like javascript/DOM would do it.
- And guess what? It worked the first time!
- Uncomment the following code to enable the test:
-
- int recurse=0;
- if(recurse){
- nsString theString(" this is just a great big empty string ");
-// nsString theString("doc.write");
-// nsString theString("
");
- Parse(theString,PR_TRUE);
- }
- */
-
theMarkPos=*mParserContext->mCurrentPos;
++(*mParserContext->mCurrentPos);
result=theRootDTD->HandleToken(theToken);
@@ -578,9 +575,25 @@ PRInt32 nsParser::BuildModel() {
theRootDTD->Verify(kEmptyString);
}
- if(kInterrupted==result)
+ if(kInterrupted==result) {
*mParserContext->mCurrentPos=theMarkPos;
+ //Now it's time to recycle our used tokens.
+ //The current context has a deque full of them,
+ //and the ones that preceed currentpos are no
+ //longer needed. Let's recycle them.
+ nsITokenRecycler* theRecycler=theRootDTD->GetTokenRecycler();
+ if(theRecycler) {
+ nsDeque& theDeque=mParserContext->mTokenDeque;
+ CToken* theCurrentToken=(CToken*)mParserContext->mCurrentPos->GetCurrent();
+ CToken* theToken=(CToken*)theDeque.Peek();
+ while(theToken && (theToken!=theCurrentToken)) {
+ theDeque.Pop();
+ theRecycler->RecycleToken(theToken);
+ }
+ }
+ }
+
return result;
}
diff --git a/mozilla/htmlparser/src/nsToken.cpp b/mozilla/htmlparser/src/nsToken.cpp
index 3533df8f053..32bc47a8a7f 100644
--- a/mozilla/htmlparser/src/nsToken.cpp
+++ b/mozilla/htmlparser/src/nsToken.cpp
@@ -19,6 +19,13 @@
#include "nsToken.h"
#include "nsScanner.h"
+static int TokenCount=0;
+
+
+/**************************************************************
+ And now for the CToken...
+ **************************************************************/
+
/**
* Default constructor
*
@@ -27,6 +34,7 @@
CToken::CToken(PRInt32 aTag) : mTextValue() {
mTypeID=aTag;
mAttrCount=0;
+ TokenCount++;
}
/**
@@ -38,6 +46,7 @@ CToken::CToken(PRInt32 aTag) : mTextValue() {
CToken::CToken(const nsString& aName) : mTextValue(aName) {
mTypeID=0;
mAttrCount=0;
+ TokenCount++;
}
/**
@@ -49,6 +58,7 @@ CToken::CToken(const nsString& aName) : mTextValue(aName) {
CToken::CToken(const char* aName) : mTextValue(aName) {
mTypeID=0;
mAttrCount=0;
+ TokenCount++;
}
/**
@@ -69,7 +79,11 @@ CToken::~CToken() {
* @param aString
*/
void CToken::Reinitialize(PRInt32 aTag, const nsString& aString){
- mTypeID=0;
+ if(0==aString.Length())
+ mTextValue.Truncate(0);
+ else mTextValue.SetString(aString);
+ mAttrCount=0;
+ mTypeID=aTag;
mAttrCount=0;
}
@@ -211,6 +225,7 @@ const char* CToken::GetClassName(void) {
return "token";
}
+
/**
*
* @update gess 3/25/98
diff --git a/mozilla/htmlparser/src/nsToken.h b/mozilla/htmlparser/src/nsToken.h
index 69e7bde16b7..7313100fcc7 100644
--- a/mozilla/htmlparser/src/nsToken.h
+++ b/mozilla/htmlparser/src/nsToken.h
@@ -41,6 +41,7 @@
class CScanner;
+
/**
* Token objects represent sequences of characters as they
* are consumed from the input stream (URL). While they're
diff --git a/mozilla/htmlparser/src/nsValidDTD.cpp b/mozilla/htmlparser/src/nsValidDTD.cpp
index c4a1c713562..a1159c2eadd 100644
--- a/mozilla/htmlparser/src/nsValidDTD.cpp
+++ b/mozilla/htmlparser/src/nsValidDTD.cpp
@@ -356,3 +356,13 @@ NS_IMETHODIMP CValidDTD::HandleToken(CToken* aToken) {
return result;
}
+/**
+ *
+ * @update gess8/4/98
+ * @param
+ * @return
+ */
+nsITokenRecycler* CValidDTD::GetTokenRecycler(void){
+ return 0;
+}
+
diff --git a/mozilla/htmlparser/src/nsValidDTD.h b/mozilla/htmlparser/src/nsValidDTD.h
index f27d81c31c3..628623ffd01 100644
--- a/mozilla/htmlparser/src/nsValidDTD.h
+++ b/mozilla/htmlparser/src/nsValidDTD.h
@@ -210,7 +210,14 @@ class CValidDTD : public nsIDTD {
* @return PR_TRUE if parent can contain child
*/
virtual PRBool CanContain(PRInt32 aParent,PRInt32 aChild);
-
+
+ /**
+ * Retrieve a ptr to the global token recycler...
+ * @update gess8/4/98
+ * @return ptr to recycler (or null)
+ */
+ virtual nsITokenRecycler* GetTokenRecycler(void);
+
protected:
diff --git a/mozilla/htmlparser/src/nsWellFormedDTD.cpp b/mozilla/htmlparser/src/nsWellFormedDTD.cpp
index f780c29f2f1..d7ef16c87a1 100644
--- a/mozilla/htmlparser/src/nsWellFormedDTD.cpp
+++ b/mozilla/htmlparser/src/nsWellFormedDTD.cpp
@@ -343,3 +343,13 @@ NS_IMETHODIMP CWellFormedDTD::HandleToken(CToken* aToken) {
return result;
}
+
+/**
+ *
+ * @update gess8/4/98
+ * @param
+ * @return
+ */
+nsITokenRecycler* CWellFormedDTD::GetTokenRecycler(void){
+ return 0;
+}
diff --git a/mozilla/htmlparser/src/nsWellFormedDTD.h b/mozilla/htmlparser/src/nsWellFormedDTD.h
index 5f05b4b124f..8f99911f38d 100644
--- a/mozilla/htmlparser/src/nsWellFormedDTD.h
+++ b/mozilla/htmlparser/src/nsWellFormedDTD.h
@@ -200,7 +200,14 @@ class CWellFormedDTD : public nsIDTD {
* @return PR_TRUE if parent can contain child
*/
virtual PRBool CanContain(PRInt32 aParent,PRInt32 aChild);
-
+
+ /**
+ * Retrieve a ptr to the global token recycler...
+ * @update gess8/4/98
+ * @return ptr to recycler (or null)
+ */
+ virtual nsITokenRecycler* GetTokenRecycler(void);
+
protected:
diff --git a/mozilla/htmlparser/src/nsXIFDTD.cpp b/mozilla/htmlparser/src/nsXIFDTD.cpp
index d7bea124dfc..1fe36f55269 100644
--- a/mozilla/htmlparser/src/nsXIFDTD.cpp
+++ b/mozilla/htmlparser/src/nsXIFDTD.cpp
@@ -160,7 +160,7 @@ eXIFTags DetermineXIFTagType(const nsString& aString)
while(low<=high){
middle=(PRInt32)(low+high)/2;
- result=aString.Compare(gXIFTagTable[middle].mName, PR_TRUE);
+ result=aString.Compare(gXIFTagTable[middle].mName, PR_TRUE);
if (result==0)
return gXIFTagTable[middle].fTagID;
if (result<0)
@@ -1736,16 +1736,6 @@ PRInt32 nsXIFDTD::CollectSkippedContent(nsCParserNode& aNode,PRInt32& aCount) {
return result;
}
-/**
- *
- * @update gpk 06/18/98
- * @param
- * @return
- */
-CToken* nsXIFDTD::CreateTokenOfType(eHTMLTokenTypes aType) {
- return 0;
-}
-
/**
*
@@ -1989,3 +1979,13 @@ void nsXIFDTD::AddCSSDeclaration(const nsIParserNode& aNode)
}
+/**
+ *
+ * @update gess8/4/98
+ * @param
+ * @return
+ */
+nsITokenRecycler* nsXIFDTD::GetTokenRecycler(void){
+ return 0;
+}
+
diff --git a/mozilla/htmlparser/src/nsXIFDTD.h b/mozilla/htmlparser/src/nsXIFDTD.h
index 5cc31782b38..6d9cda7c28a 100644
--- a/mozilla/htmlparser/src/nsXIFDTD.h
+++ b/mozilla/htmlparser/src/nsXIFDTD.h
@@ -499,14 +499,6 @@ private:
****************************************************/
- /**
- * Called to cause delegate to create a token of given type.
- * @update gpk 06/18/98
- * @param aType represents the kind of token you want to create.
- * @return new token or NULL
- */
- CToken* CreateTokenOfType(eHTMLTokenTypes aType);
-
/**
* Retrieve the next TAG from the given scanner.
* @update gpk 06/18/98
@@ -627,6 +619,12 @@ private:
void PopAndDelete();
+ /**
+ * Retrieve a ptr to the global token recycler...
+ * @update gess8/4/98
+ * @return ptr to recycler (or null)
+ */
+ virtual nsITokenRecycler* GetTokenRecycler(void);
protected:
diff --git a/mozilla/parser/htmlparser/src/CNavDTD.cpp b/mozilla/parser/htmlparser/src/CNavDTD.cpp
index 26610765f4c..60e023c157b 100644
--- a/mozilla/parser/htmlparser/src/CNavDTD.cpp
+++ b/mozilla/parser/htmlparser/src/CNavDTD.cpp
@@ -208,25 +208,28 @@ eHTMLTags CTagStack::Last() const {
return eHTMLTag_unknown;
}
-
+/**************************************************************
+ Now define the tokenrecycler class...
+ **************************************************************/
/************************************************************************
- CTokenFactory class implementation.
- This class is used to create and destroy our tokens.
+ CTokenRecycler class implementation.
+ This class is used to recycle tokens.
By using this simple class, we cut WAY down on the number of tokens
that get created during the run of the system.
************************************************************************/
-class CTokenFactory {
+class nsCTokenRecycler : public nsITokenRecycler {
public:
- enum {eCacheSize=50};
+ enum {eCacheMaxSize=50};
+
+ nsCTokenRecycler();
+ virtual ~nsCTokenRecycler();
+ virtual void RecycleToken(CToken* aToken);
+ virtual CToken* CreateTokenOfType(eHTMLTokenTypes aType,eHTMLTags aTag, const nsString& aString);
- CTokenFactory();
- ~CTokenFactory();
- CToken* CreateToken(eHTMLTokenTypes aType, eHTMLTags aTag, const nsString& aString);
- void RecycleToken(CToken* aToken);
protected:
- CToken* mTokenCache[eToken_last-1][eCacheSize];
+ CToken* mTokenCache[eToken_last-1][eCacheMaxSize];
PRInt32 mCount[eToken_last-1];
};
@@ -236,7 +239,7 @@ protected:
* @update gess7/25/98
* @param
*/
-CTokenFactory::CTokenFactory() {
+nsCTokenRecycler::nsCTokenRecycler() : nsITokenRecycler() {
nsCRT::zero(mTokenCache,sizeof(mTokenCache));
nsCRT::zero(mCount,sizeof(mCount));
}
@@ -245,29 +248,49 @@ CTokenFactory::CTokenFactory() {
* Destructor for the token factory
* @update gess7/25/98
*/
-CTokenFactory::~CTokenFactory() {
+nsCTokenRecycler::~nsCTokenRecycler() {
}
+
/**
- * This method is used as the factory for all HTML tokens.
- * There will be a corresponding recycler method, so that we can
- * cut down on the number of tokens we create.
+ * This method gets called when someone wants to recycle a token
* @update gess7/24/98
- * @param aType
- * @param aTag
- * @param aString
- * @return newly created token or null
+ * @param aToken -- token to be recycled.
+ * @return nada
*/
-CToken* CTokenFactory::CreateToken(eHTMLTokenTypes aType, eHTMLTags aTag, const nsString& aString) {
+void nsCTokenRecycler::RecycleToken(CToken* aToken) {
+ if(aToken) {
+ PRInt32 theType=aToken->GetTokenType();
+ if(mCount[theType-1]0){
- result=mTokenCache[aType-1][--mCount[aType-1]];
- mTokenCache[aType-1][mCount[aType-1]]=0;
+ if(0Reinitialize(aTag,aString);
+ mTokenCache[aType-1][mCount[aType-1]-1]=0;
+ mCount[aType-1]--;
}
- else
- {
+ else {
switch(aType){
case eToken_start: result=new CStartToken(aTag); break;
case eToken_end: result=new CEndToken(aTag); break;
@@ -287,29 +310,9 @@ CToken* CTokenFactory::CreateToken(eHTMLTokenTypes aType, eHTMLTags aTag, const
return result;
}
-/**
- * This method gets called when the DTD wants to recycle a token
- * it has finished using.
- * @update gess7/24/98
- * @param aToken -- token to be recycled.
- * @return nada
- */
-void CTokenFactory::RecycleToken(CToken* aToken) {
- if(aToken) {
- eHTMLTokenTypes aType=(eHTMLTokenTypes)aToken->GetTokenType();
- if(mCount[aType-1])
@@ -2730,7 +2745,7 @@ nsresult CNavDTD::CreateContextStackFor(eHTMLTags aChildTag){
int i=0;
for(i=pos;iConsume(aChar,aScanner); //tell new token to finish consuming text...
@@ -2957,7 +2972,7 @@ CNavDTD::ConsumeContentToEndTag(const nsString& aString,
nsAutoString endTag("");
endTag.Append(aString);
endTag.Append(">");
- aToken=gTokenFactory.CreateToken(eToken_skippedcontent,aChildTag,endTag);
+ aToken=gTokenRecycler.CreateTokenOfType(eToken_skippedcontent,aChildTag,endTag);
return aToken->Consume(aChar,aScanner); //tell new token to finish consuming text...
}
@@ -2979,7 +2994,7 @@ CNavDTD::ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,CToken*& aToken) {
PRInt32 theDequeSize=mTokenDeque.GetSize();
nsresult result=NS_OK;
- aToken=gTokenFactory.CreateToken(eToken_start,eHTMLTag_unknown,gEmpty);
+ aToken=gTokenRecycler.CreateTokenOfType(eToken_start,eHTMLTag_unknown,gEmpty);
if(aToken) {
result= aToken->Consume(aChar,aScanner); //tell new token to finish consuming text...
@@ -3012,7 +3027,7 @@ CNavDTD::ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,CToken*& aToken) {
//In the case that we just read a given tag, we should go and
//consume all the tag content itself (and throw it all away).
- CToken* endtoken=gTokenFactory.CreateToken(eToken_end,theTag,gEmpty);
+ CToken* endtoken=gTokenRecycler.CreateTokenOfType(eToken_end,theTag,gEmpty);
mTokenDeque.Push(endtoken);
} //if
} //if
@@ -3053,11 +3068,11 @@ CNavDTD::ConsumeEntity(PRUnichar aChar,CScanner& aScanner,CToken*& aToken) {
if(NS_OK==result) {
if(nsString::IsAlpha(ch)) { //handle common enity references &xxx; or .
- aToken = gTokenFactory.CreateToken(eToken_entity,eHTMLTag_unknown,gEmpty);
+ aToken = gTokenRecycler.CreateTokenOfType(eToken_entity,eHTMLTag_unknown,gEmpty);
result = aToken->Consume(ch,aScanner); //tell new token to finish consuming text...
}
else if(kHashsign==ch) {
- aToken = gTokenFactory.CreateToken(eToken_entity,eHTMLTag_unknown,gEmpty);
+ aToken = gTokenRecycler.CreateTokenOfType(eToken_entity,eHTMLTag_unknown,gEmpty);
result=aToken->Consume(0,aScanner);
}
else {
@@ -3084,7 +3099,7 @@ nsresult
CNavDTD::ConsumeWhitespace(PRUnichar aChar,
CScanner& aScanner,
CToken*& aToken) {
- aToken = gTokenFactory.CreateToken(eToken_whitespace,eHTMLTag_unknown,gEmpty);
+ aToken = gTokenRecycler.CreateTokenOfType(eToken_whitespace,eHTMLTag_unknown,gEmpty);
nsresult result=kNoError;
if(aToken) {
result=aToken->Consume(aChar,aScanner);
@@ -3103,7 +3118,7 @@ CNavDTD::ConsumeWhitespace(PRUnichar aChar,
* @return new token or null
*/
nsresult CNavDTD::ConsumeComment(PRUnichar aChar,CScanner& aScanner,CToken*& aToken){
- aToken = gTokenFactory.CreateToken(eToken_comment,eHTMLTag_unknown,gEmpty);
+ aToken = gTokenRecycler.CreateTokenOfType(eToken_comment,eHTMLTag_unknown,gEmpty);
nsresult result=NS_OK;
if(aToken) {
result=aToken->Consume(aChar,aScanner);
@@ -3123,7 +3138,7 @@ nsresult CNavDTD::ConsumeComment(PRUnichar aChar,CScanner& aScanner,CToken*& aTo
*/
nsresult CNavDTD::ConsumeText(const nsString& aString,CScanner& aScanner,CToken*& aToken){
nsresult result=NS_OK;
- aToken=gTokenFactory.CreateToken(eToken_text,eHTMLTag_text,aString);
+ aToken=gTokenRecycler.CreateTokenOfType(eToken_text,eHTMLTag_text,aString);
if(aToken) {
PRUnichar ch=0;
result=aToken->Consume(ch,aScanner);
@@ -3148,7 +3163,7 @@ nsresult CNavDTD::ConsumeText(const nsString& aString,CScanner& aScanner,CToken*
* @return error code
*/
nsresult CNavDTD::ConsumeNewline(PRUnichar aChar,CScanner& aScanner,CToken*& aToken){
- aToken=gTokenFactory.CreateToken(eToken_newline,eHTMLTag_newline,gEmpty);
+ aToken=gTokenRecycler.CreateTokenOfType(eToken_newline,eHTMLTag_newline,gEmpty);
nsresult result=NS_OK;
if(aToken) {
result=aToken->Consume(aChar,aScanner);
@@ -3228,16 +3243,6 @@ nsresult CNavDTD::ConsumeToken(CToken*& aToken){
return result;
}
-/**
- *
- * @update gess4/11/98
- * @param
- * @return
- */
-CToken* CNavDTD::CreateTokenOfType(eHTMLTokenTypes aType) {
- return 0;
-}
-
/**
*
@@ -3254,10 +3259,10 @@ nsresult CNavDTD::WillResumeParse(void){
}
/**
- *
+ * This method gets called when the parsing process is interrupted
+ * due to lack of data (waiting for netlib).
* @update gess5/18/98
- * @param
- * @return
+ * @return error code
*/
nsresult CNavDTD::WillInterruptParse(void){
nsresult result = NS_OK;
diff --git a/mozilla/parser/htmlparser/src/CNavDTD.h b/mozilla/parser/htmlparser/src/CNavDTD.h
index ef6087ffb28..872d186f95d 100644
--- a/mozilla/parser/htmlparser/src/CNavDTD.h
+++ b/mozilla/parser/htmlparser/src/CNavDTD.h
@@ -443,6 +443,8 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
nsresult HandleScriptToken(CToken* aToken, nsCParserNode& aNode);
nsresult HandleStyleToken(CToken* aToken);
+ virtual nsITokenRecycler* GetTokenRecycler(void);
+
protected:
@@ -551,14 +553,6 @@ protected:
****************************************************/
- /**
- * Called to cause delegate to create a token of given type.
- * @update gess 5/11/98
- * @param aType represents the kind of token you want to create.
- * @return new token or NULL
- */
- CToken* CreateTokenOfType(eHTMLTokenTypes aType);
-
/**
* The following methods consume a particular type
* of HTML token.
diff --git a/mozilla/parser/htmlparser/src/COtherDTD.cpp b/mozilla/parser/htmlparser/src/COtherDTD.cpp
index 29c37577c34..78d27bc053e 100644
--- a/mozilla/parser/htmlparser/src/COtherDTD.cpp
+++ b/mozilla/parser/htmlparser/src/COtherDTD.cpp
@@ -938,16 +938,6 @@ nsresult COtherDTD::ConsumeToken(CToken*& aToken){
return CNavDTD::ConsumeToken(aToken);
}
-/**
- *
- * @update gess4/11/98
- * @param
- * @return
- */
-CToken* COtherDTD::CreateTokenOfType(eHTMLTokenTypes aType) {
- return CNavDTD::CreateTokenOfType(aType);
-}
-
/**
*
diff --git a/mozilla/parser/htmlparser/src/COtherDTD.h b/mozilla/parser/htmlparser/src/COtherDTD.h
index 20b76275f5a..7b7cc6131fd 100644
--- a/mozilla/parser/htmlparser/src/COtherDTD.h
+++ b/mozilla/parser/htmlparser/src/COtherDTD.h
@@ -504,14 +504,6 @@ private:
****************************************************/
- /**
- * Called to cause delegate to create a token of given type.
- * @update gess 5/11/98
- * @param aType represents the kind of token you want to create.
- * @return new token or NULL
- */
- CToken* CreateTokenOfType(eHTMLTokenTypes aType);
-
/**
* Retrieve the next TAG from the given scanner.
* @update gess 5/11/98
diff --git a/mozilla/parser/htmlparser/src/CRtfDTD.cpp b/mozilla/parser/htmlparser/src/CRtfDTD.cpp
index 808e607b281..6f90c69a580 100644
--- a/mozilla/parser/htmlparser/src/CRtfDTD.cpp
+++ b/mozilla/parser/htmlparser/src/CRtfDTD.cpp
@@ -542,6 +542,16 @@ nsresult CRtfDTD::HandleToken(CToken* aToken) {
+/**
+ *
+ * @update gess8/4/98
+ * @param
+ * @return
+ */
+nsITokenRecycler* CRtfDTD::GetTokenRecycler(void){
+ return 0;
+}
+
/***************************************************************
Heres's the RTFControlWord subclass...
***************************************************************/
diff --git a/mozilla/parser/htmlparser/src/CRtfDTD.h b/mozilla/parser/htmlparser/src/CRtfDTD.h
index 67429ee5296..971831a6045 100644
--- a/mozilla/parser/htmlparser/src/CRtfDTD.h
+++ b/mozilla/parser/htmlparser/src/CRtfDTD.h
@@ -346,7 +346,14 @@ class CRtfDTD : public nsIDTD {
* @return PR_TRUE if parent can contain child
*/
virtual PRBool CanContain(PRInt32 aParent,PRInt32 aChild);
-
+
+ /**
+ * Retrieve a ptr to the global token recycler...
+ * @update gess8/4/98
+ * @return ptr to recycler (or null)
+ */
+ virtual nsITokenRecycler* GetTokenRecycler(void);
+
protected:
nsParser* mParser;
diff --git a/mozilla/parser/htmlparser/src/nsHTMLTokens.cpp b/mozilla/parser/htmlparser/src/nsHTMLTokens.cpp
index 3427adcb103..3ae28998d4f 100644
--- a/mozilla/parser/htmlparser/src/nsHTMLTokens.cpp
+++ b/mozilla/parser/htmlparser/src/nsHTMLTokens.cpp
@@ -26,6 +26,7 @@
#include "prtypes.h"
#include "nsDebug.h"
#include "nsHTMLTags.h"
+#include "nsCRT.h"
//#define GESS_MACHINE
#ifdef GESS_MACHINE
@@ -94,6 +95,11 @@ static StrToUnicodeStruct gStrToUnicodeTable[] =
{"yuml", 0x00ff}
};
+
+/**************************************************************
+ And now for the token classes...
+ **************************************************************/
+
/*
* default constructor
*
@@ -128,6 +134,7 @@ void CHTMLToken::SetStringValue(const char* name){
}
}
+
/*
* constructor from tag id
*
@@ -153,6 +160,18 @@ CStartToken::CStartToken(nsString& aString) : CHTMLToken(aString) {
}
+/**
+ *
+ * @update gess8/4/98
+ * @param
+ * @return
+ */
+void CStartToken::Reinitialize(PRInt32 aTag, const nsString& aString){
+ CToken::Reinitialize(aTag,aString);
+ mAttributed=PR_FALSE;
+ mEmpty=PR_FALSE;
+}
+
/*
* This method returns the typeid (the tag type) for this token.
*
@@ -682,6 +701,18 @@ CAttributeToken::CAttributeToken(const nsString& aKey, const nsString& aName) :
mLastAttribute=PR_FALSE;
}
+/**
+ *
+ * @update gess8/4/98
+ * @param
+ * @return
+ */
+void CAttributeToken::Reinitialize(PRInt32 aTag, const nsString& aString){
+ CHTMLToken::Reinitialize(aTag,aString);
+ mTextKey.Truncate();
+ mLastAttribute=PR_FALSE;
+}
+
/*
*
*
@@ -949,6 +980,7 @@ CEntityToken::CEntityToken(const nsString& aName) : CHTMLToken(aName) {
#endif
}
+
/*
* Consume the rest of the entity. We've already eaten the "&".
*
@@ -1329,6 +1361,7 @@ nsresult CSkippedContentToken::Consume(PRUnichar,CScanner& aScanner) {
return result;
}
+
#if 0
/*
* This method iterates the tagtable to ensure that is
diff --git a/mozilla/parser/htmlparser/src/nsHTMLTokens.h b/mozilla/parser/htmlparser/src/nsHTMLTokens.h
index 96bdfe023a5..e92338685f3 100644
--- a/mozilla/parser/htmlparser/src/nsHTMLTokens.h
+++ b/mozilla/parser/htmlparser/src/nsHTMLTokens.h
@@ -71,6 +71,7 @@ const char* GetTagName(PRInt32 aTag);
*/
class CHTMLToken : public CToken {
public:
+
CHTMLToken(eHTMLTags aTag);
CHTMLToken(const nsString& aString);
virtual void SetStringValue(const char* name);
@@ -99,6 +100,7 @@ class CStartToken: public CHTMLToken {
PRBool IsEmpty(void);
void SetEmpty(PRBool aValue);
virtual void DebugDumpSource(ostream& out);
+ virtual void Reinitialize(PRInt32 aTag, const nsString& aString);
protected:
PRBool mAttributed;
@@ -225,6 +227,7 @@ class CAttributeToken: public CHTMLToken {
virtual void DebugDumpToken(ostream& out);
virtual void DebugDumpSource(ostream& out);
PRBool mLastAttribute;
+ virtual void Reinitialize(PRInt32 aTag, const nsString& aString);
protected:
nsString mTextKey;
diff --git a/mozilla/parser/htmlparser/src/nsIDTD.h b/mozilla/parser/htmlparser/src/nsIDTD.h
index d4932ed1bf5..8b74354cba6 100644
--- a/mozilla/parser/htmlparser/src/nsIDTD.h
+++ b/mozilla/parser/htmlparser/src/nsIDTD.h
@@ -44,8 +44,16 @@ class nsIDTDDebug;
class nsIURL;
class nsString;
+
enum eAutoDetectResult {eUnknownDetect, eValidDetect, eInvalidDetect};
+
+class nsITokenRecycler {
+public:
+ virtual void RecycleToken(CToken* aToken)=0;
+};
+
+
class nsIDTD : public nsISupports {
public:
@@ -177,7 +185,17 @@ class nsIDTD : public nsISupports {
*/
virtual PRBool Verify(nsString& aURLRef)=0;
+ /**
+ * Retrieve a ptr to the global token recycler...
+ * @update gess8/4/98
+ * @return ptr to recycler (or null)
+ */
+ virtual nsITokenRecycler* GetTokenRecycler(void)=0;
+
+
};
+
+
#endif /* nsIDTD_h___ */
diff --git a/mozilla/parser/htmlparser/src/nsParser.cpp b/mozilla/parser/htmlparser/src/nsParser.cpp
index ea650d22cc9..409c54ff206 100644
--- a/mozilla/parser/htmlparser/src/nsParser.cpp
+++ b/mozilla/parser/htmlparser/src/nsParser.cpp
@@ -93,7 +93,7 @@ public:
void RegisterDTD(nsIDTD* aDTD){
CDTDFinder theFinder(aDTD);
- if(!mDTDDeque.ForEach(theFinder))
+ if(!mDTDDeque.FirstThat(theFinder))
mDTDDeque.Push(aDTD);
}
@@ -383,6 +383,20 @@ PRInt32 nsParser::DidBuildModel(PRInt32 anErrorCode) {
result=mParserContext->mDTD->DidBuildModel(anErrorCode,PRBool(0==mParserContext->mPrevContext));
}
+ //Now it's time to recycle our used tokens.
+ //The current context has a deque full of them,
+ //and the ones that preceed currentpos are no
+ //longer needed. Let's recycle them.
+ nsDeque& theDeque=mParserContext->mTokenDeque;
+ nsITokenRecycler* theRecycler=mParserContext->mDTD->GetTokenRecycler();
+ if(theRecycler) {
+ CToken* theToken=(CToken*)theDeque.Pop();
+ while(theToken) {
+ theRecycler->RecycleToken(theToken);
+ theToken=(CToken*)theDeque.Pop();
+ }
+ }
+
return result;
}
@@ -554,23 +568,6 @@ PRInt32 nsParser::BuildModel() {
while((kNoError==result) && ((*mParserContext->mCurrentPosmCurrentPos->GetCurrent();
-
- /**************************************************************************
- The point of this code to serve as a testbed for parser reentrancy.
- If you set recurse=1, we go reentrant, passing a text string of HTML onto
- the parser for inline processing, just like javascript/DOM would do it.
- And guess what? It worked the first time!
- Uncomment the following code to enable the test:
-
- int recurse=0;
- if(recurse){
- nsString theString(" this is just a great big empty string ");
-// nsString theString("doc.write");
-// nsString theString("
");
- Parse(theString,PR_TRUE);
- }
- */
-
theMarkPos=*mParserContext->mCurrentPos;
++(*mParserContext->mCurrentPos);
result=theRootDTD->HandleToken(theToken);
@@ -578,9 +575,25 @@ PRInt32 nsParser::BuildModel() {
theRootDTD->Verify(kEmptyString);
}
- if(kInterrupted==result)
+ if(kInterrupted==result) {
*mParserContext->mCurrentPos=theMarkPos;
+ //Now it's time to recycle our used tokens.
+ //The current context has a deque full of them,
+ //and the ones that preceed currentpos are no
+ //longer needed. Let's recycle them.
+ nsITokenRecycler* theRecycler=theRootDTD->GetTokenRecycler();
+ if(theRecycler) {
+ nsDeque& theDeque=mParserContext->mTokenDeque;
+ CToken* theCurrentToken=(CToken*)mParserContext->mCurrentPos->GetCurrent();
+ CToken* theToken=(CToken*)theDeque.Peek();
+ while(theToken && (theToken!=theCurrentToken)) {
+ theDeque.Pop();
+ theRecycler->RecycleToken(theToken);
+ }
+ }
+ }
+
return result;
}
diff --git a/mozilla/parser/htmlparser/src/nsToken.cpp b/mozilla/parser/htmlparser/src/nsToken.cpp
index 3533df8f053..32bc47a8a7f 100644
--- a/mozilla/parser/htmlparser/src/nsToken.cpp
+++ b/mozilla/parser/htmlparser/src/nsToken.cpp
@@ -19,6 +19,13 @@
#include "nsToken.h"
#include "nsScanner.h"
+static int TokenCount=0;
+
+
+/**************************************************************
+ And now for the CToken...
+ **************************************************************/
+
/**
* Default constructor
*
@@ -27,6 +34,7 @@
CToken::CToken(PRInt32 aTag) : mTextValue() {
mTypeID=aTag;
mAttrCount=0;
+ TokenCount++;
}
/**
@@ -38,6 +46,7 @@ CToken::CToken(PRInt32 aTag) : mTextValue() {
CToken::CToken(const nsString& aName) : mTextValue(aName) {
mTypeID=0;
mAttrCount=0;
+ TokenCount++;
}
/**
@@ -49,6 +58,7 @@ CToken::CToken(const nsString& aName) : mTextValue(aName) {
CToken::CToken(const char* aName) : mTextValue(aName) {
mTypeID=0;
mAttrCount=0;
+ TokenCount++;
}
/**
@@ -69,7 +79,11 @@ CToken::~CToken() {
* @param aString
*/
void CToken::Reinitialize(PRInt32 aTag, const nsString& aString){
- mTypeID=0;
+ if(0==aString.Length())
+ mTextValue.Truncate(0);
+ else mTextValue.SetString(aString);
+ mAttrCount=0;
+ mTypeID=aTag;
mAttrCount=0;
}
@@ -211,6 +225,7 @@ const char* CToken::GetClassName(void) {
return "token";
}
+
/**
*
* @update gess 3/25/98
diff --git a/mozilla/parser/htmlparser/src/nsToken.h b/mozilla/parser/htmlparser/src/nsToken.h
index 69e7bde16b7..7313100fcc7 100644
--- a/mozilla/parser/htmlparser/src/nsToken.h
+++ b/mozilla/parser/htmlparser/src/nsToken.h
@@ -41,6 +41,7 @@
class CScanner;
+
/**
* Token objects represent sequences of characters as they
* are consumed from the input stream (URL). While they're
diff --git a/mozilla/parser/htmlparser/src/nsValidDTD.cpp b/mozilla/parser/htmlparser/src/nsValidDTD.cpp
index c4a1c713562..a1159c2eadd 100644
--- a/mozilla/parser/htmlparser/src/nsValidDTD.cpp
+++ b/mozilla/parser/htmlparser/src/nsValidDTD.cpp
@@ -356,3 +356,13 @@ NS_IMETHODIMP CValidDTD::HandleToken(CToken* aToken) {
return result;
}
+/**
+ *
+ * @update gess8/4/98
+ * @param
+ * @return
+ */
+nsITokenRecycler* CValidDTD::GetTokenRecycler(void){
+ return 0;
+}
+
diff --git a/mozilla/parser/htmlparser/src/nsValidDTD.h b/mozilla/parser/htmlparser/src/nsValidDTD.h
index f27d81c31c3..628623ffd01 100644
--- a/mozilla/parser/htmlparser/src/nsValidDTD.h
+++ b/mozilla/parser/htmlparser/src/nsValidDTD.h
@@ -210,7 +210,14 @@ class CValidDTD : public nsIDTD {
* @return PR_TRUE if parent can contain child
*/
virtual PRBool CanContain(PRInt32 aParent,PRInt32 aChild);
-
+
+ /**
+ * Retrieve a ptr to the global token recycler...
+ * @update gess8/4/98
+ * @return ptr to recycler (or null)
+ */
+ virtual nsITokenRecycler* GetTokenRecycler(void);
+
protected:
diff --git a/mozilla/parser/htmlparser/src/nsWellFormedDTD.cpp b/mozilla/parser/htmlparser/src/nsWellFormedDTD.cpp
index f780c29f2f1..d7ef16c87a1 100644
--- a/mozilla/parser/htmlparser/src/nsWellFormedDTD.cpp
+++ b/mozilla/parser/htmlparser/src/nsWellFormedDTD.cpp
@@ -343,3 +343,13 @@ NS_IMETHODIMP CWellFormedDTD::HandleToken(CToken* aToken) {
return result;
}
+
+/**
+ *
+ * @update gess8/4/98
+ * @param
+ * @return
+ */
+nsITokenRecycler* CWellFormedDTD::GetTokenRecycler(void){
+ return 0;
+}
diff --git a/mozilla/parser/htmlparser/src/nsWellFormedDTD.h b/mozilla/parser/htmlparser/src/nsWellFormedDTD.h
index 5f05b4b124f..8f99911f38d 100644
--- a/mozilla/parser/htmlparser/src/nsWellFormedDTD.h
+++ b/mozilla/parser/htmlparser/src/nsWellFormedDTD.h
@@ -200,7 +200,14 @@ class CWellFormedDTD : public nsIDTD {
* @return PR_TRUE if parent can contain child
*/
virtual PRBool CanContain(PRInt32 aParent,PRInt32 aChild);
-
+
+ /**
+ * Retrieve a ptr to the global token recycler...
+ * @update gess8/4/98
+ * @return ptr to recycler (or null)
+ */
+ virtual nsITokenRecycler* GetTokenRecycler(void);
+
protected:
diff --git a/mozilla/parser/htmlparser/src/nsXIFDTD.cpp b/mozilla/parser/htmlparser/src/nsXIFDTD.cpp
index d7bea124dfc..1fe36f55269 100644
--- a/mozilla/parser/htmlparser/src/nsXIFDTD.cpp
+++ b/mozilla/parser/htmlparser/src/nsXIFDTD.cpp
@@ -160,7 +160,7 @@ eXIFTags DetermineXIFTagType(const nsString& aString)
while(low<=high){
middle=(PRInt32)(low+high)/2;
- result=aString.Compare(gXIFTagTable[middle].mName, PR_TRUE);
+ result=aString.Compare(gXIFTagTable[middle].mName, PR_TRUE);
if (result==0)
return gXIFTagTable[middle].fTagID;
if (result<0)
@@ -1736,16 +1736,6 @@ PRInt32 nsXIFDTD::CollectSkippedContent(nsCParserNode& aNode,PRInt32& aCount) {
return result;
}
-/**
- *
- * @update gpk 06/18/98
- * @param
- * @return
- */
-CToken* nsXIFDTD::CreateTokenOfType(eHTMLTokenTypes aType) {
- return 0;
-}
-
/**
*
@@ -1989,3 +1979,13 @@ void nsXIFDTD::AddCSSDeclaration(const nsIParserNode& aNode)
}
+/**
+ *
+ * @update gess8/4/98
+ * @param
+ * @return
+ */
+nsITokenRecycler* nsXIFDTD::GetTokenRecycler(void){
+ return 0;
+}
+
diff --git a/mozilla/parser/htmlparser/src/nsXIFDTD.h b/mozilla/parser/htmlparser/src/nsXIFDTD.h
index 5cc31782b38..6d9cda7c28a 100644
--- a/mozilla/parser/htmlparser/src/nsXIFDTD.h
+++ b/mozilla/parser/htmlparser/src/nsXIFDTD.h
@@ -499,14 +499,6 @@ private:
****************************************************/
- /**
- * Called to cause delegate to create a token of given type.
- * @update gpk 06/18/98
- * @param aType represents the kind of token you want to create.
- * @return new token or NULL
- */
- CToken* CreateTokenOfType(eHTMLTokenTypes aType);
-
/**
* Retrieve the next TAG from the given scanner.
* @update gpk 06/18/98
@@ -627,6 +619,12 @@ private:
void PopAndDelete();
+ /**
+ * Retrieve a ptr to the global token recycler...
+ * @update gess8/4/98
+ * @return ptr to recycler (or null)
+ */
+ virtual nsITokenRecycler* GetTokenRecycler(void);
protected: