diff --git a/htmlparser/src/CParserContext.cpp b/htmlparser/src/CParserContext.cpp
index 8b58ff42934f..a52566816794 100644
--- a/htmlparser/src/CParserContext.cpp
+++ b/htmlparser/src/CParserContext.cpp
@@ -25,6 +25,7 @@
#include "nsToken.h"
MOZ_DECL_CTOR_COUNTER(CParserContext);
+
/**
* Your friendly little constructor. Ok, it's not the friendly, but the only guy
* using it is the parser.
@@ -33,27 +34,68 @@ MOZ_DECL_CTOR_COUNTER(CParserContext);
* @param aKey
* @param aListener
*/
-CParserContext::CParserContext(nsScanner* aScanner,void* aKey,nsIStreamObserver* aListener,PRBool aCopyUnused) :
- mSourceType()
+CParserContext::CParserContext(nsScanner* aScanner,
+ void *aKey,
+ nsIStreamObserver* aListener,
+ nsIDTD *aDTD,
+ eAutoDetectResult aStatus,
+ PRBool aCopyUnused) :
+ mSourceType()
+ //,mTokenDeque(gTokenDeallocator)
+{
+ MOZ_COUNT_CTOR(CParserContext);
+
+ mScanner=aScanner;
+ mKey=aKey;
+ mPrevContext=0;
+ mListener=aListener;
+ NS_IF_ADDREF(mListener);
+ mParseMode=eParseMode_unknown;
+ mAutoDetectStatus=aStatus;
+ mTransferBuffer=0;
+ mDTD=aDTD;
+ NS_IF_ADDREF(mDTD);
+ mTransferBufferSize=eTransferBufferSize;
+ mParserEnabled=PR_TRUE;
+ mStreamListenerState=eNone;
+ mMultipart=PR_TRUE;
+ mContextType=eCTNone;
+ mCopyUnused=aCopyUnused;
+}
+
+/**
+ * Your friendly little constructor. Ok, it's not the friendly, but the only guy
+ * using it is the parser.
+ * @update gess7/23/98
+ * @param aScanner
+ * @param aKey
+ * @param aListener
+ */
+CParserContext::CParserContext(const CParserContext &aContext) :
+ mSourceType(aContext.mSourceType)
//,mTokenDeque(gTokenDeallocator)
{
MOZ_COUNT_CTOR(CParserContext);
- mScanner=aScanner;
- mKey=aKey;
+ mScanner=aContext.mScanner;
+ mKey=aContext.mKey;
mPrevContext=0;
- mListener=aListener;
+ mListener=aContext.mListener;
NS_IF_ADDREF(mListener);
- mParseMode=eParseMode_unknown;
- mAutoDetectStatus=eUnknownDetect;
- mTransferBuffer=0;
- mDTD=0;
+
+ mParseMode=aContext.mParseMode;
+ mAutoDetectStatus=aContext.mAutoDetectStatus;
+ mTransferBuffer=aContext.mTransferBuffer;
+ mDTD=aContext.mDTD;
+ NS_IF_ADDREF(mDTD);
+
mTransferBufferSize=eTransferBufferSize;
- mParserEnabled=PR_TRUE;
- mStreamListenerState=eNone;
- mMultipart=PR_TRUE;
- mContextType=eCTNone;
- mCopyUnused=aCopyUnused;
+ mParserEnabled=aContext.mParserEnabled;
+ mStreamListenerState=aContext.mStreamListenerState;
+ mMultipart=aContext.mMultipart;
+ mContextType=aContext.mContextType;
+ mCopyUnused;
+ mRefCount=2;
}
@@ -66,11 +108,14 @@ CParserContext::~CParserContext(){
MOZ_COUNT_DTOR(CParserContext);
- if(mScanner)
- delete mScanner;
+ mRefCount--;
+ if(0==mRefCount) {
+ if(mScanner)
+ delete mScanner;
- if(mTransferBuffer)
- delete [] mTransferBuffer;
+ if(mTransferBuffer)
+ delete [] mTransferBuffer;
+ }
NS_IF_RELEASE(mDTD);
diff --git a/htmlparser/src/CParserContext.h b/htmlparser/src/CParserContext.h
index a54f68f9a6ad..45fc701b4894 100644
--- a/htmlparser/src/CParserContext.h
+++ b/htmlparser/src/CParserContext.h
@@ -49,10 +49,14 @@ public:
enum {eTransferBufferSize=4096};
enum eContextType {eCTNone,eCTURL,eCTString,eCTStream};
- CParserContext( nsScanner* aScanner,
- void* aKey=0,
- nsIStreamObserver* aListener=0,
- PRBool aCopyUnused=PR_FALSE);
+ CParserContext( nsScanner* aScanner,
+ void* aKey=0,
+ nsIStreamObserver* aListener=0,
+ nsIDTD *aDTD=0,
+ eAutoDetectResult aStatus=eUnknownDetect,
+ PRBool aCopyUnused=PR_FALSE);
+
+ CParserContext( const CParserContext& aContext);
~CParserContext();
@@ -64,6 +68,7 @@ public:
PRBool mMultipart;
eContextType mContextType;
eAutoDetectResult mAutoDetectStatus;
+ PRInt32 mRefCount;
nsString mSourceType;
diff --git a/htmlparser/src/nsParser.cpp b/htmlparser/src/nsParser.cpp
index c14a1e1aa151..4987bff547d0 100644
--- a/htmlparser/src/nsParser.cpp
+++ b/htmlparser/src/nsParser.cpp
@@ -810,6 +810,9 @@ nsresult nsParser::EnableParser(PRBool aState){
if(mParserContext) {
mParserContext->mParserEnabled=aState;
if(aState) {
+
+ //printf(" Re-enable parser\n");
+
result=ResumeParse();
if(result!=NS_OK)
result=mInternalState;
@@ -926,61 +929,75 @@ nsresult nsParser::Parse(nsIInputStream& aStream,PRBool aVerifyEnabled, void* aK
* @param aContentType tells us what type of content to expect in the given string
* @return error code -- 0 if ok, non-zero if error.
*/
-nsresult nsParser::Parse(const nsString& aSourceBuffer,void* aKey,const nsString& aContentType,PRBool aVerifyEnabled,PRBool aLastCall,eParseMode aMode){
-
+nsresult nsParser::Parse(const nsString& aSourceBuffer,void* aKey,const nsString&
+aContentType,PRBool aVerifyEnabled,PRBool aLastCall,eParseMode aMode){
+
//NOTE: Make sure that updates to this method don't cause
- // bug #2361 to break again!
+ // bug #2361 to break again!
-#if 0
- //this is only for debug purposes
- aSourceBuffer.DebugDump();
+#if 0
+ //this is only for debug purposes
+ aSourceBuffer.DebugDump();
#endif
- nsresult result=NS_OK;
- nsParser* me = this;
- // Maintain a reference to ourselves so we don't go away
- // till we're completely done.
- NS_ADDREF(me);
- if(aSourceBuffer.Length() || mUnusedInput.Length()) {
- mDTDVerification=aVerifyEnabled;
+ nsresult result=NS_OK;
+ nsParser* me = this;
+ // Maintain a reference to ourselves so we don't go away
+ // till we're completely done.
+ NS_ADDREF(me);
+
+ if(aSourceBuffer.Length() || mUnusedInput.Length()) {
+ mDTDVerification=aVerifyEnabled;
CParserContext* pc=0;
- if((!mParserContext) || (mParserContext->mKey!=aKey)) {
- //only make a new context if we dont have one, OR if we do, but has a different context key...
-
- nsScanner* theScanner=new nsScanner(mUnusedInput,mCharset,mCharsetSource);
- pc=new CParserContext(theScanner,aKey, 0, aLastCall);
- if(pc && theScanner) {
- PushContext(*pc);
+ if((!mParserContext) || (mParserContext->mKey!=aKey)) {
+ //only make a new context if we dont have one, OR if we do, but has a different context key...
+
+ nsScanner* theScanner=new nsScanner(mUnusedInput,mCharset,mCharsetSource);
+ nsIDTD *theDTD=0;
+ eAutoDetectResult theStatus=eUnknownDetect;
- pc->mMultipart=!aLastCall; //by default
- if (pc->mPrevContext) {
- pc->mMultipart |= pc->mPrevContext->mMultipart; //if available
- }
+ if(mParserContext && (mParserContext->mSourceType==aContentType)) {
+ theDTD=mParserContext->mDTD;
+ theStatus=mParserContext->mAutoDetectStatus;
- pc->mStreamListenerState = (pc->mMultipart) ? eOnDataAvail : eOnStop;
- pc->mContextType=CParserContext::eCTString;
- pc->mSourceType=aContentType;
- mUnusedInput.Truncate(0);
+ //added this to fix bug 32022.
}
- else {
- NS_RELEASE(me);
- return NS_ERROR_OUT_OF_MEMORY;
- }
- }
- else {
- pc=mParserContext;
- pc->mScanner->Append(mUnusedInput);
- }
- pc->mScanner->Append(aSourceBuffer);
+ pc=new CParserContext(theScanner,aKey, 0,theDTD,theStatus,aLastCall);
+
- result=ResumeParse(PR_FALSE);
+ if(pc && theScanner) {
+ PushContext(*pc);
- }//if
- NS_RELEASE(me);
- return result;
-}
+ pc->mMultipart=!aLastCall; //by default
+ if (pc->mPrevContext) {
+ pc->mMultipart |= pc->mPrevContext->mMultipart; //if available
+ }
+
+ pc->mStreamListenerState = (pc->mMultipart) ? eOnDataAvail : eOnStop;
+ pc->mContextType=CParserContext::eCTString;
+ pc->mSourceType=aContentType;
+ mUnusedInput.Truncate(0);
+
+ //printf("Parse(string) iterate: %i",PR_FALSE);
+ pc->mScanner->Append(aSourceBuffer);
+ result=ResumeParse(PR_FALSE);
+
+ }
+ else {
+ NS_RELEASE(me);
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ }
+ else {
+ mParserContext->mScanner->Append(aSourceBuffer);
+ }
+ }//if
+ NS_RELEASE(me);
+ return result;
+}
/**
@@ -1118,7 +1135,10 @@ nsresult nsParser::ParseFragment(const nsString& aSourceBuffer,void* aKey,nsITag
* @return error code -- 0 if ok, non-zero if error.
*/
nsresult nsParser::ResumeParse(PRBool allowIteration, PRBool aIsFinalChunk) {
+
+ //printf(" Resume %i, prev-context: %p\n",allowIteration,mParserContext->mPrevContext);
+
nsresult result=NS_OK;
if(mParserContext->mParserEnabled && mInternalState!=NS_ERROR_HTMLPARSER_STOPPARSING) {
@@ -1131,10 +1151,11 @@ nsresult nsParser::ResumeParse(PRBool allowIteration, PRBool aIsFinalChunk) {
if(mParserContext->mDTD) {
mParserContext->mDTD->WillResumeParse();
- PRBool theIterationIsOk=(allowIteration||(!mParserContext->mPrevContext));
+ PRBool theFirstTime=PR_TRUE;
+ PRBool theIterationIsOk=(allowIteration || (!mParserContext->mPrevContext));
- while((result==NS_OK) && (theIterationIsOk)) {
-
+ while((result==NS_OK) && (theFirstTime || theIterationIsOk)) {
+ theFirstTime=PR_FALSE;
if(mUnusedInput.Length()>0) {
if(mParserContext->mScanner) {
// -- Ref: Bug# 22485 --
diff --git a/parser/htmlparser/src/CParserContext.cpp b/parser/htmlparser/src/CParserContext.cpp
index 8b58ff42934f..a52566816794 100644
--- a/parser/htmlparser/src/CParserContext.cpp
+++ b/parser/htmlparser/src/CParserContext.cpp
@@ -25,6 +25,7 @@
#include "nsToken.h"
MOZ_DECL_CTOR_COUNTER(CParserContext);
+
/**
* Your friendly little constructor. Ok, it's not the friendly, but the only guy
* using it is the parser.
@@ -33,27 +34,68 @@ MOZ_DECL_CTOR_COUNTER(CParserContext);
* @param aKey
* @param aListener
*/
-CParserContext::CParserContext(nsScanner* aScanner,void* aKey,nsIStreamObserver* aListener,PRBool aCopyUnused) :
- mSourceType()
+CParserContext::CParserContext(nsScanner* aScanner,
+ void *aKey,
+ nsIStreamObserver* aListener,
+ nsIDTD *aDTD,
+ eAutoDetectResult aStatus,
+ PRBool aCopyUnused) :
+ mSourceType()
+ //,mTokenDeque(gTokenDeallocator)
+{
+ MOZ_COUNT_CTOR(CParserContext);
+
+ mScanner=aScanner;
+ mKey=aKey;
+ mPrevContext=0;
+ mListener=aListener;
+ NS_IF_ADDREF(mListener);
+ mParseMode=eParseMode_unknown;
+ mAutoDetectStatus=aStatus;
+ mTransferBuffer=0;
+ mDTD=aDTD;
+ NS_IF_ADDREF(mDTD);
+ mTransferBufferSize=eTransferBufferSize;
+ mParserEnabled=PR_TRUE;
+ mStreamListenerState=eNone;
+ mMultipart=PR_TRUE;
+ mContextType=eCTNone;
+ mCopyUnused=aCopyUnused;
+}
+
+/**
+ * Your friendly little constructor. Ok, it's not the friendly, but the only guy
+ * using it is the parser.
+ * @update gess7/23/98
+ * @param aScanner
+ * @param aKey
+ * @param aListener
+ */
+CParserContext::CParserContext(const CParserContext &aContext) :
+ mSourceType(aContext.mSourceType)
//,mTokenDeque(gTokenDeallocator)
{
MOZ_COUNT_CTOR(CParserContext);
- mScanner=aScanner;
- mKey=aKey;
+ mScanner=aContext.mScanner;
+ mKey=aContext.mKey;
mPrevContext=0;
- mListener=aListener;
+ mListener=aContext.mListener;
NS_IF_ADDREF(mListener);
- mParseMode=eParseMode_unknown;
- mAutoDetectStatus=eUnknownDetect;
- mTransferBuffer=0;
- mDTD=0;
+
+ mParseMode=aContext.mParseMode;
+ mAutoDetectStatus=aContext.mAutoDetectStatus;
+ mTransferBuffer=aContext.mTransferBuffer;
+ mDTD=aContext.mDTD;
+ NS_IF_ADDREF(mDTD);
+
mTransferBufferSize=eTransferBufferSize;
- mParserEnabled=PR_TRUE;
- mStreamListenerState=eNone;
- mMultipart=PR_TRUE;
- mContextType=eCTNone;
- mCopyUnused=aCopyUnused;
+ mParserEnabled=aContext.mParserEnabled;
+ mStreamListenerState=aContext.mStreamListenerState;
+ mMultipart=aContext.mMultipart;
+ mContextType=aContext.mContextType;
+ mCopyUnused;
+ mRefCount=2;
}
@@ -66,11 +108,14 @@ CParserContext::~CParserContext(){
MOZ_COUNT_DTOR(CParserContext);
- if(mScanner)
- delete mScanner;
+ mRefCount--;
+ if(0==mRefCount) {
+ if(mScanner)
+ delete mScanner;
- if(mTransferBuffer)
- delete [] mTransferBuffer;
+ if(mTransferBuffer)
+ delete [] mTransferBuffer;
+ }
NS_IF_RELEASE(mDTD);
diff --git a/parser/htmlparser/src/CParserContext.h b/parser/htmlparser/src/CParserContext.h
index a54f68f9a6ad..45fc701b4894 100644
--- a/parser/htmlparser/src/CParserContext.h
+++ b/parser/htmlparser/src/CParserContext.h
@@ -49,10 +49,14 @@ public:
enum {eTransferBufferSize=4096};
enum eContextType {eCTNone,eCTURL,eCTString,eCTStream};
- CParserContext( nsScanner* aScanner,
- void* aKey=0,
- nsIStreamObserver* aListener=0,
- PRBool aCopyUnused=PR_FALSE);
+ CParserContext( nsScanner* aScanner,
+ void* aKey=0,
+ nsIStreamObserver* aListener=0,
+ nsIDTD *aDTD=0,
+ eAutoDetectResult aStatus=eUnknownDetect,
+ PRBool aCopyUnused=PR_FALSE);
+
+ CParserContext( const CParserContext& aContext);
~CParserContext();
@@ -64,6 +68,7 @@ public:
PRBool mMultipart;
eContextType mContextType;
eAutoDetectResult mAutoDetectStatus;
+ PRInt32 mRefCount;
nsString mSourceType;
diff --git a/parser/htmlparser/src/nsParser.cpp b/parser/htmlparser/src/nsParser.cpp
index c14a1e1aa151..4987bff547d0 100644
--- a/parser/htmlparser/src/nsParser.cpp
+++ b/parser/htmlparser/src/nsParser.cpp
@@ -810,6 +810,9 @@ nsresult nsParser::EnableParser(PRBool aState){
if(mParserContext) {
mParserContext->mParserEnabled=aState;
if(aState) {
+
+ //printf(" Re-enable parser\n");
+
result=ResumeParse();
if(result!=NS_OK)
result=mInternalState;
@@ -926,61 +929,75 @@ nsresult nsParser::Parse(nsIInputStream& aStream,PRBool aVerifyEnabled, void* aK
* @param aContentType tells us what type of content to expect in the given string
* @return error code -- 0 if ok, non-zero if error.
*/
-nsresult nsParser::Parse(const nsString& aSourceBuffer,void* aKey,const nsString& aContentType,PRBool aVerifyEnabled,PRBool aLastCall,eParseMode aMode){
-
+nsresult nsParser::Parse(const nsString& aSourceBuffer,void* aKey,const nsString&
+aContentType,PRBool aVerifyEnabled,PRBool aLastCall,eParseMode aMode){
+
//NOTE: Make sure that updates to this method don't cause
- // bug #2361 to break again!
+ // bug #2361 to break again!
-#if 0
- //this is only for debug purposes
- aSourceBuffer.DebugDump();
+#if 0
+ //this is only for debug purposes
+ aSourceBuffer.DebugDump();
#endif
- nsresult result=NS_OK;
- nsParser* me = this;
- // Maintain a reference to ourselves so we don't go away
- // till we're completely done.
- NS_ADDREF(me);
- if(aSourceBuffer.Length() || mUnusedInput.Length()) {
- mDTDVerification=aVerifyEnabled;
+ nsresult result=NS_OK;
+ nsParser* me = this;
+ // Maintain a reference to ourselves so we don't go away
+ // till we're completely done.
+ NS_ADDREF(me);
+
+ if(aSourceBuffer.Length() || mUnusedInput.Length()) {
+ mDTDVerification=aVerifyEnabled;
CParserContext* pc=0;
- if((!mParserContext) || (mParserContext->mKey!=aKey)) {
- //only make a new context if we dont have one, OR if we do, but has a different context key...
-
- nsScanner* theScanner=new nsScanner(mUnusedInput,mCharset,mCharsetSource);
- pc=new CParserContext(theScanner,aKey, 0, aLastCall);
- if(pc && theScanner) {
- PushContext(*pc);
+ if((!mParserContext) || (mParserContext->mKey!=aKey)) {
+ //only make a new context if we dont have one, OR if we do, but has a different context key...
+
+ nsScanner* theScanner=new nsScanner(mUnusedInput,mCharset,mCharsetSource);
+ nsIDTD *theDTD=0;
+ eAutoDetectResult theStatus=eUnknownDetect;
- pc->mMultipart=!aLastCall; //by default
- if (pc->mPrevContext) {
- pc->mMultipart |= pc->mPrevContext->mMultipart; //if available
- }
+ if(mParserContext && (mParserContext->mSourceType==aContentType)) {
+ theDTD=mParserContext->mDTD;
+ theStatus=mParserContext->mAutoDetectStatus;
- pc->mStreamListenerState = (pc->mMultipart) ? eOnDataAvail : eOnStop;
- pc->mContextType=CParserContext::eCTString;
- pc->mSourceType=aContentType;
- mUnusedInput.Truncate(0);
+ //added this to fix bug 32022.
}
- else {
- NS_RELEASE(me);
- return NS_ERROR_OUT_OF_MEMORY;
- }
- }
- else {
- pc=mParserContext;
- pc->mScanner->Append(mUnusedInput);
- }
- pc->mScanner->Append(aSourceBuffer);
+ pc=new CParserContext(theScanner,aKey, 0,theDTD,theStatus,aLastCall);
+
- result=ResumeParse(PR_FALSE);
+ if(pc && theScanner) {
+ PushContext(*pc);
- }//if
- NS_RELEASE(me);
- return result;
-}
+ pc->mMultipart=!aLastCall; //by default
+ if (pc->mPrevContext) {
+ pc->mMultipart |= pc->mPrevContext->mMultipart; //if available
+ }
+
+ pc->mStreamListenerState = (pc->mMultipart) ? eOnDataAvail : eOnStop;
+ pc->mContextType=CParserContext::eCTString;
+ pc->mSourceType=aContentType;
+ mUnusedInput.Truncate(0);
+
+ //printf("Parse(string) iterate: %i",PR_FALSE);
+ pc->mScanner->Append(aSourceBuffer);
+ result=ResumeParse(PR_FALSE);
+
+ }
+ else {
+ NS_RELEASE(me);
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ }
+ else {
+ mParserContext->mScanner->Append(aSourceBuffer);
+ }
+ }//if
+ NS_RELEASE(me);
+ return result;
+}
/**
@@ -1118,7 +1135,10 @@ nsresult nsParser::ParseFragment(const nsString& aSourceBuffer,void* aKey,nsITag
* @return error code -- 0 if ok, non-zero if error.
*/
nsresult nsParser::ResumeParse(PRBool allowIteration, PRBool aIsFinalChunk) {
+
+ //printf(" Resume %i, prev-context: %p\n",allowIteration,mParserContext->mPrevContext);
+
nsresult result=NS_OK;
if(mParserContext->mParserEnabled && mInternalState!=NS_ERROR_HTMLPARSER_STOPPARSING) {
@@ -1131,10 +1151,11 @@ nsresult nsParser::ResumeParse(PRBool allowIteration, PRBool aIsFinalChunk) {
if(mParserContext->mDTD) {
mParserContext->mDTD->WillResumeParse();
- PRBool theIterationIsOk=(allowIteration||(!mParserContext->mPrevContext));
+ PRBool theFirstTime=PR_TRUE;
+ PRBool theIterationIsOk=(allowIteration || (!mParserContext->mPrevContext));
- while((result==NS_OK) && (theIterationIsOk)) {
-
+ while((result==NS_OK) && (theFirstTime || theIterationIsOk)) {
+ theFirstTime=PR_FALSE;
if(mUnusedInput.Length()>0) {
if(mParserContext->mScanner) {
// -- Ref: Bug# 22485 --