added WIP support for reentrancy in the parser

This commit is contained in:
rickg 1998-07-13 21:13:09 +00:00
Родитель 129f8dca89
Коммит fe718837d2
48 изменённых файлов: 1432 добавлений и 1772 удалений

Просмотреть файл

@ -91,6 +91,115 @@ static char gWhitespaceTags[]={
0}; 0};
/************************************************************************
CTagStack class implementation.
The reason we use this class is so that we can view the stack state
in the usual way via the debugger.
************************************************************************/
CTagStack::CTagStack(int aDefaultSize) {
#ifdef _dynstack
mSize=aDefaultSize;
mTags =new eHTMLTags[mSize];
mBits =new PRBool[mSize];
#else
mSize=eStackSize;
#endif
mCount=0;
nsCRT::zero(mTags,mSize*sizeof(eHTMLTag_html));
nsCRT::zero(mBits,mSize*sizeof(PRBool));
}
/**
* Default constructor
* @update gess7/9/98
* @param aDefaultsize tells the stack what size to start out.
* however, we'll autosize as needed.
*/
CTagStack::~CTagStack() {
#ifdef _dynstack
delete mTags;
delete mBits;
mTags=0;
mBits=0;
#endif
mSize=mCount=0;
}
/**
*
* @update gess7/9/98
* @param
* @return
*/
void CTagStack::Push(eHTMLTags aTag) {
if(mCount>=mSize) {
#ifdef _dynstack
eHTMLTags* tmp=new eHTMLTags[2*mSize];
nsCRT::zero(tmp,2*mSize*sizeof(eHTMLTag_html));
nsCRT::memcpy(tmp,mTags,mSize*sizeof(eHTMLTag_html));
delete mTags;
mTags=tmp;
PRBool* tmp2=new PRBool[2*mSize];
nsCRT::zero(tmp2,2*mSize*sizeof(PRBool));
nsCRT::memcpy(tmp2,mBits,mSize*sizeof(PRBool));
delete mBits;
mBits=tmp2;
mSize*=2;
#endif
}
mTags[mCount++]=aTag;
}
/**
*
* @update gess7/9/98
* @param
* @return
*/
eHTMLTags CTagStack::Pop() {
eHTMLTags result=eHTMLTag_unknown;
if(mCount>0) {
result=mTags[--mCount];
mTags[mCount]=eHTMLTag_unknown;
mBits[mCount]=PR_FALSE;
}
return result;
}
/**
*
* @update gess7/9/98
* @param
* @return
*/
eHTMLTags CTagStack::First() const {
if(mCount>0)
return mTags[0];
return eHTMLTag_unknown;
}
/**
*
* @update gess7/9/98
* @param
* @return
*/
eHTMLTags CTagStack::Last() const {
if(mCount>0)
return mTags[mCount-1];
return eHTMLTag_unknown;
}
/************************************************************************
And now for the main class -- CNavDTD...
************************************************************************/
/** /**
* This method gets called as part of our COM-like interfaces. * This method gets called as part of our COM-like interfaces.
* Its purpose is to create an interface to parser object * Its purpose is to create an interface to parser object
@ -124,6 +233,7 @@ nsresult CNavDTD::QueryInterface(const nsIID& aIID, void** aInstancePtr)
return NS_OK; return NS_OK;
} }
/** /**
* This method is defined in nsIParser. It is used to * This method is defined in nsIParser. It is used to
* cause the COM-like construction of an nsParser. * cause the COM-like construction of an nsParser.
@ -234,15 +344,13 @@ static CNavTokenDeallocator gTokenKiller;
* @param * @param
* @return * @return
*/ */
CNavDTD::CNavDTD() : nsIDTD(), mTokenDeque(gTokenKiller) { CNavDTD::CNavDTD() : nsIDTD(), mTokenDeque(gTokenKiller),
mContextStack(), mStyleStack() {
NS_INIT_REFCNT(); NS_INIT_REFCNT();
mParser=0; mParser=0;
mFilename=0;
mSink = nsnull; mSink = nsnull;
mDTDDebug=0; mDTDDebug=0;
nsCRT::zero(mTokenHandlers,sizeof(mTokenHandlers)); nsCRT::zero(mTokenHandlers,sizeof(mTokenHandlers));
mContextStackPos=0;
mStyleStackPos=0;
mHasOpenForm=PR_FALSE; mHasOpenForm=PR_FALSE;
mHasOpenMap=PR_FALSE; mHasOpenMap=PR_FALSE;
InitializeDefaultTokenHandlers(); InitializeDefaultTokenHandlers();
@ -257,8 +365,6 @@ CNavDTD::CNavDTD() : nsIDTD(), mTokenDeque(gTokenKiller) {
*/ */
CNavDTD::~CNavDTD(){ CNavDTD::~CNavDTD(){
DeleteTokenHandlers(); DeleteTokenHandlers();
if (mFilename)
PL_strfree(mFilename);
if (mDTDDebug) if (mDTDDebug)
NS_RELEASE(mDTDDebug); NS_RELEASE(mDTDDebug);
@ -281,6 +387,7 @@ void CNavDTD::SetDTDDebug(nsIDTDDebug * aDTDDebug)
NS_ADDREF(mDTDDebug); NS_ADDREF(mDTDDebug);
} }
/** /**
* This method is called to determine if the given DTD can parse * This method is called to determine if the given DTD can parse
* a document in a given source-type. * a document in a given source-type.
@ -308,24 +415,16 @@ eAutoDetectResult CNavDTD::AutoDetectContentType(nsString& aBuffer,nsString& aTy
return result; return result;
} }
/** /**
* *
* @update gess5/18/98 * @update gess5/18/98
* @param * @param
* @return * @return
*/ */
PRInt32 CNavDTD::WillBuildModel(const char* aFilename){ PRInt32 CNavDTD::WillBuildModel(nsString& aFilename){
PRInt32 result=0; PRInt32 result=0;
if (mFilename) { mFilename=aFilename;
PL_strfree(mFilename);
mFilename=0;
}
if(aFilename) {
mFilename = PL_strdup(aFilename);
}
if(mSink) if(mSink)
mSink->WillBuildModel(); mSink->WillBuildModel();
@ -342,7 +441,7 @@ PRInt32 CNavDTD::WillBuildModel(const char* aFilename){
PRInt32 CNavDTD::DidBuildModel(PRInt32 anErrorCode){ PRInt32 CNavDTD::DidBuildModel(PRInt32 anErrorCode){
PRInt32 result=0; PRInt32 result=0;
if((kNoError==anErrorCode) && (mContextStackPos>0)) { if((kNoError==anErrorCode) && (mContextStack.mCount>0)) {
CloseContainersTo(0,eHTMLTag_unknown,PR_FALSE); CloseContainersTo(0,eHTMLTag_unknown,PR_FALSE);
} }
if(mSink) { if(mSink) {
@ -375,7 +474,7 @@ PRInt32 CNavDTD::HandleToken(CToken* aToken){
if(theHandler) { if(theHandler) {
result=(*theHandler)(theToken,this); result=(*theHandler)(theToken,this);
if (mDTDDebug) if (mDTDDebug)
mDTDDebug->Verify(this, mParser, mContextStackPos, mContextStack, mFilename); mDTDDebug->Verify(this, mParser, mContextStack.mCount, mContextStack.mTags, mFilename);
} }
}//if }//if
@ -420,13 +519,13 @@ PRInt32 CNavDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsIP
} }
if(IsContainer(aChildTag)){ if(IsContainer(aChildTag)){
if(PR_TRUE==(PRBool)mLeafBits[mContextStackPos-1]) { if(PR_TRUE==mContextStack.mBits[mContextStack.mCount-1]) {
CloseTransientStyles(aChildTag); CloseTransientStyles(aChildTag);
} }
result=OpenContainer(aNode,PR_TRUE); result=OpenContainer(aNode,PR_TRUE);
} }
else { else {
if(PR_FALSE==(PRBool)mLeafBits[mContextStackPos-1]) { if(PR_FALSE==mContextStack.mBits[mContextStack.mCount-1]) {
OpenTransientStyles(aChildTag); OpenTransientStyles(aChildTag);
} }
result=AddLeaf(aNode); result=AddLeaf(aNode);
@ -576,16 +675,8 @@ PRInt32 CNavDTD::HandleEndToken(CToken* aToken) {
// we have to handle explicit styles the way it does. That means // we have to handle explicit styles the way it does. That means
// that we keep an internal style stack.When an EndToken occurs, // that we keep an internal style stack.When an EndToken occurs,
// we should see if it is an explicit style tag. If so, we can // we should see if it is an explicit style tag. If so, we can
// close AND explicit style tag (goofy, huh?) // close the explicit style tag (goofy, huh?)
/*
if(0!=strchr(gStyleTags,tokenTagType)){
eHTMLTags topTag=GetTopNode();
if(0!=strchr(gStyleTags,topTag)){
tokenTagType=topTag;
}
}
*/
//now check to see if this token should be omitted... //now check to see if this token should be omitted...
if(PR_TRUE==CanOmitEndTag(GetTopNode(),tokenTagType)) { if(PR_TRUE==CanOmitEndTag(GetTopNode(),tokenTagType)) {
@ -622,7 +713,7 @@ PRInt32 CNavDTD::HandleEndToken(CToken* aToken) {
// Empty the transient style stack (we just closed any extra // Empty the transient style stack (we just closed any extra
// ones off so it's safe to do it now) because they don't carry // ones off so it's safe to do it now) because they don't carry
// forward across table cell boundaries. // forward across table cell boundaries.
mStyleStackPos = 0; mStyleStack.mCount=0;
break; break;
default: default:
@ -1148,8 +1239,8 @@ PRBool CNavDTD::CanContain(PRInt32 aParent,PRInt32 aChild) {
break; //singletons can't contain anything... break; //singletons can't contain anything...
case eHTMLTag_li: case eHTMLTag_li:
if ((eHTMLTag_li == aChild) || if ((eHTMLTag_li == aChild) || //XXX this is temporary!!!
(eHTMLTag_ul == aChild) || // XXX this is temporary!!! (eHTMLTag_ul == aChild) ||
(eHTMLTag_ol == aChild) || (eHTMLTag_ol == aChild) ||
(eHTMLTag_menu == aChild) || (eHTMLTag_menu == aChild) ||
(eHTMLTag_dir == aChild)) { (eHTMLTag_dir == aChild)) {
@ -1620,29 +1711,6 @@ PRBool CNavDTD::BackwardPropagate(nsString& aVector,eHTMLTags aParentTag,eHTMLTa
return PRBool(aParentTag==theParentTag); return PRBool(aParentTag==theParentTag);
} }
/**
*
* @update gess6/4/98
* @param aTag is the id of the html container being opened
* @return 0 if all is well.
*/
PRInt32 CNavDTD::DidOpenContainer(eHTMLTags aTag,PRBool /*anExplicitOpen*/){
PRInt32 result=0;
return result;
}
/**
*
* @update gess6/4/98
* @param
* @return
*/
PRInt32 CNavDTD::DidCloseContainer(eHTMLTags aTag,PRBool/*anExplicitClosure*/){
PRInt32 result=0;
return result;
}
/** /**
* This method allows the caller to determine if a form * This method allows the caller to determine if a form
* element is currently open. * element is currently open.
@ -1672,9 +1740,7 @@ PRBool CNavDTD::HasOpenContainer(eHTMLTags aContainer) const {
* @return tag id of topmost node in contextstack * @return tag id of topmost node in contextstack
*/ */
eHTMLTags CNavDTD::GetTopNode() const { eHTMLTags CNavDTD::GetTopNode() const {
if(mContextStackPos) return mContextStack.Last();
return (eHTMLTags)(int)mContextStack[mContextStackPos-1];
return eHTMLTag_unknown;
} }
@ -1688,8 +1754,8 @@ eHTMLTags CNavDTD::GetTopNode() const {
*/ */
PRInt32 CNavDTD::GetTopmostIndexOf(eHTMLTags aTag) const { PRInt32 CNavDTD::GetTopmostIndexOf(eHTMLTags aTag) const {
int i=0; int i=0;
for(i=mContextStackPos-1;i>=0;i--){ for(i=mContextStack.mCount-1;i>=0;i--){
if((eHTMLTags)(int)mContextStack[i]==aTag) if(mContextStack.mTags[i]==aTag)
return i; return i;
} }
return kNotFound; return kNotFound;
@ -1720,8 +1786,8 @@ PRInt32 CNavDTD::OpenTransientStyles(eHTMLTags aTag){
eHTMLTags parentTag=GetTopNode(); eHTMLTags parentTag=GetTopNode();
if(CanContainStyles(parentTag)) { if(CanContainStyles(parentTag)) {
for(pos=0;pos<mStyleStackPos;pos++) { for(pos=0;pos<mStyleStack.mCount;pos++) {
eHTMLTags theTag=(eHTMLTags)(int)mStyleStack[pos]; eHTMLTags theTag=mStyleStack.mTags[pos];
if(PR_FALSE==HasOpenContainer(theTag)) { if(PR_FALSE==HasOpenContainer(theTag)) {
CStartToken token(GetTagName(theTag)); CStartToken token(GetTagName(theTag));
@ -1735,7 +1801,7 @@ PRInt32 CNavDTD::OpenTransientStyles(eHTMLTags aTag){
default: default:
token.SetTypeID(theTag); //open the html container... token.SetTypeID(theTag); //open the html container...
result=OpenContainer(theNode,PR_FALSE); result=OpenContainer(theNode,PR_FALSE);
mLeafBits.ReplaceElementAt((void*)PR_TRUE,mContextStackPos-1); mContextStack.mBits[mContextStack.mCount-1]=PR_TRUE;
} //switch } //switch
} }
if(kNoError!=result) if(kNoError!=result)
@ -1761,11 +1827,11 @@ PRInt32 CNavDTD::OpenTransientStyles(eHTMLTags aTag){
PRInt32 CNavDTD::CloseTransientStyles(eHTMLTags aTag){ PRInt32 CNavDTD::CloseTransientStyles(eHTMLTags aTag){
PRInt32 result=0; PRInt32 result=0;
if((mStyleStackPos>0) && (mLeafBits[mContextStackPos-1])) { if((mStyleStack.mCount>0) && (mContextStack.mBits[mContextStack.mCount-1])) {
if(0==strchr(gWhitespaceTags,aTag)){ if(0==strchr(gWhitespaceTags,aTag)){
result=CloseContainersTo((eHTMLTags)(int)mStyleStack[0],PR_FALSE); result=CloseContainersTo(mStyleStack.mTags[0],PR_FALSE);
mLeafBits.ReplaceElementAt((void*)PR_FALSE,mContextStackPos-1); mContextStack.mBits[mContextStack.mCount-1]=PR_FALSE;
}//if }//if
}//if }//if
@ -1782,10 +1848,10 @@ PRInt32 CNavDTD::CloseTransientStyles(eHTMLTags aTag){
* @return TRUE if ok, FALSE if error * @return TRUE if ok, FALSE if error
*/ */
PRInt32 CNavDTD::OpenHTML(const nsIParserNode& aNode){ PRInt32 CNavDTD::OpenHTML(const nsIParserNode& aNode){
NS_PRECONDITION(mContextStackPos >= 0, kInvalidTagStackPos); NS_PRECONDITION(mContextStack.mCount >= 0, kInvalidTagStackPos);
PRInt32 result=mSink->OpenHTML(aNode); PRInt32 result=mSink->OpenHTML(aNode);
mContextStack.ReplaceElementAt((void*)aNode.GetNodeType(),mContextStackPos++); mContextStack.Push((eHTMLTags)aNode.GetNodeType());
return result; return result;
} }
@ -1799,9 +1865,9 @@ PRInt32 CNavDTD::OpenHTML(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error * @return TRUE if ok, FALSE if error
*/ */
PRInt32 CNavDTD::CloseHTML(const nsIParserNode& aNode){ PRInt32 CNavDTD::CloseHTML(const nsIParserNode& aNode){
NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos); NS_PRECONDITION(mContextStack.mCount > 0, kInvalidTagStackPos);
PRInt32 result=mSink->CloseHTML(aNode); PRInt32 result=mSink->CloseHTML(aNode);
mContextStack.ReplaceElementAt((void*)eHTMLTag_unknown,--mContextStackPos); mContextStack.Pop();
return result; return result;
} }
@ -1815,7 +1881,7 @@ PRInt32 CNavDTD::CloseHTML(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error * @return TRUE if ok, FALSE if error
*/ */
PRInt32 CNavDTD::OpenHead(const nsIParserNode& aNode){ PRInt32 CNavDTD::OpenHead(const nsIParserNode& aNode){
mContextStack.ReplaceElementAt((void*)eHTMLTag_head,++mContextStackPos); mContextStack.Push(eHTMLTag_head);
PRInt32 result=mSink->OpenHead(aNode); PRInt32 result=mSink->OpenHead(aNode);
return result; return result;
} }
@ -1830,7 +1896,7 @@ PRInt32 CNavDTD::OpenHead(const nsIParserNode& aNode){
*/ */
PRInt32 CNavDTD::CloseHead(const nsIParserNode& aNode){ PRInt32 CNavDTD::CloseHead(const nsIParserNode& aNode){
PRInt32 result=mSink->CloseHead(aNode); PRInt32 result=mSink->CloseHead(aNode);
mContextStack.ReplaceElementAt((void*)eHTMLTag_unknown,--mContextStackPos); mContextStack.Pop();
return result; return result;
} }
@ -1843,7 +1909,7 @@ PRInt32 CNavDTD::CloseHead(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error * @return TRUE if ok, FALSE if error
*/ */
PRInt32 CNavDTD::OpenBody(const nsIParserNode& aNode){ PRInt32 CNavDTD::OpenBody(const nsIParserNode& aNode){
NS_PRECONDITION(mContextStackPos >= 0, kInvalidTagStackPos); NS_PRECONDITION(mContextStack.mCount >= 0, kInvalidTagStackPos);
PRInt32 result=kNoError; PRInt32 result=kNoError;
eHTMLTags topTag=GetTopNode(); eHTMLTags topTag=GetTopNode();
@ -1875,7 +1941,7 @@ PRInt32 CNavDTD::OpenBody(const nsIParserNode& aNode){
if(kNoError==result) { if(kNoError==result) {
result=mSink->OpenBody(aNode); result=mSink->OpenBody(aNode);
mContextStack.ReplaceElementAt((void*)aNode.GetNodeType(),mContextStackPos++); mContextStack.Push((eHTMLTags)aNode.GetNodeType());
} }
return result; return result;
} }
@ -1889,9 +1955,9 @@ PRInt32 CNavDTD::OpenBody(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error * @return TRUE if ok, FALSE if error
*/ */
PRInt32 CNavDTD::CloseBody(const nsIParserNode& aNode){ PRInt32 CNavDTD::CloseBody(const nsIParserNode& aNode){
NS_PRECONDITION(mContextStackPos >= 0, kInvalidTagStackPos); NS_PRECONDITION(mContextStack.mCount >= 0, kInvalidTagStackPos);
PRInt32 result=mSink->CloseBody(aNode); PRInt32 result=mSink->CloseBody(aNode);
mContextStack.ReplaceElementAt((void*)eHTMLTag_unknown,--mContextStackPos); mContextStack.Pop();
return result; return result;
} }
@ -1980,9 +2046,9 @@ PRInt32 CNavDTD::CloseMap(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error * @return TRUE if ok, FALSE if error
*/ */
PRInt32 CNavDTD::OpenFrameset(const nsIParserNode& aNode){ PRInt32 CNavDTD::OpenFrameset(const nsIParserNode& aNode){
NS_PRECONDITION(mContextStackPos >= 0, kInvalidTagStackPos); NS_PRECONDITION(mContextStack.mCount >= 0, kInvalidTagStackPos);
PRInt32 result=mSink->OpenFrameset(aNode); PRInt32 result=mSink->OpenFrameset(aNode);
mContextStack.ReplaceElementAt((void*)aNode.GetNodeType(),mContextStackPos++); mContextStack.Push((eHTMLTags)aNode.GetNodeType());
return result; return result;
} }
@ -1995,9 +2061,9 @@ PRInt32 CNavDTD::OpenFrameset(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error * @return TRUE if ok, FALSE if error
*/ */
PRInt32 CNavDTD::CloseFrameset(const nsIParserNode& aNode){ PRInt32 CNavDTD::CloseFrameset(const nsIParserNode& aNode){
NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos); NS_PRECONDITION(mContextStack.mCount > 0, kInvalidTagStackPos);
PRInt32 result=mSink->CloseFrameset(aNode); PRInt32 result=mSink->CloseFrameset(aNode);
mContextStack.ReplaceElementAt((void*)eHTMLTag_unknown,--mContextStackPos); mContextStack.Pop();
return result; return result;
} }
@ -2011,7 +2077,7 @@ PRInt32 CNavDTD::CloseFrameset(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error * @return TRUE if ok, FALSE if error
*/ */
PRInt32 CNavDTD::OpenContainer(const nsIParserNode& aNode,PRBool aUpdateStyleStack){ PRInt32 CNavDTD::OpenContainer(const nsIParserNode& aNode,PRBool aUpdateStyleStack){
NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos); NS_PRECONDITION(mContextStack.mCount > 0, kInvalidTagStackPos);
PRInt32 result=kNoError; PRInt32 result=kNoError;
eHTMLTags nodeType=(eHTMLTags)aNode.GetNodeType(); eHTMLTags nodeType=(eHTMLTags)aNode.GetNodeType();
@ -2037,7 +2103,7 @@ PRInt32 CNavDTD::OpenContainer(const nsIParserNode& aNode,PRBool aUpdateStyleSta
default: default:
result=mSink->OpenContainer(aNode); result=mSink->OpenContainer(aNode);
mContextStack.ReplaceElementAt((void*)nodeType,mContextStackPos++); mContextStack.Push((eHTMLTags)aNode.GetNodeType());
break; break;
} }
@ -2057,7 +2123,7 @@ PRInt32 CNavDTD::OpenContainer(const nsIParserNode& aNode,PRBool aUpdateStyleSta
* @return TRUE if ok, FALSE if error * @return TRUE if ok, FALSE if error
*/ */
PRInt32 CNavDTD::CloseContainer(const nsIParserNode& aNode,eHTMLTags aTag,PRBool aUpdateStyles){ PRInt32 CNavDTD::CloseContainer(const nsIParserNode& aNode,eHTMLTags aTag,PRBool aUpdateStyles){
NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos); NS_PRECONDITION(mContextStack.mCount > 0, kInvalidTagStackPos);
PRInt32 result=kNoError; //was false PRInt32 result=kNoError; //was false
eHTMLTags nodeType=(eHTMLTags)aNode.GetNodeType(); eHTMLTags nodeType=(eHTMLTags)aNode.GetNodeType();
@ -2085,11 +2151,11 @@ PRInt32 CNavDTD::CloseContainer(const nsIParserNode& aNode,eHTMLTags aTag,PRBool
case eHTMLTag_title: case eHTMLTag_title:
default: default:
result=mSink->CloseContainer(aNode); result=mSink->CloseContainer(aNode);
mContextStack.ReplaceElementAt((void*)eHTMLTag_unknown,--mContextStackPos); mContextStack.Pop();
break; break;
} }
mLeafBits.ReplaceElementAt((void*)PR_FALSE, mContextStackPos); mContextStack.mBits[mContextStack.mCount]=PR_FALSE;
if((kNoError==result) && (PR_TRUE==aUpdateStyles)){ if((kNoError==result) && (PR_TRUE==aUpdateStyles)){
UpdateStyleStackForCloseTag(nodeType,aTag); UpdateStyleStackForCloseTag(nodeType,aTag);
} }
@ -2106,15 +2172,15 @@ PRInt32 CNavDTD::CloseContainer(const nsIParserNode& aNode,eHTMLTags aTag,PRBool
* @return TRUE if ok, FALSE if error * @return TRUE if ok, FALSE if error
*/ */
PRInt32 CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTag,PRBool aUpdateStyles){ PRInt32 CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTag,PRBool aUpdateStyles){
NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos); NS_PRECONDITION(mContextStack.mCount > 0, kInvalidTagStackPos);
PRInt32 result=kNoError; PRInt32 result=kNoError;
CEndToken aToken(gEmpty); CEndToken aToken(gEmpty);
nsCParserNode theNode(&aToken); nsCParserNode theNode(&aToken);
if((anIndex<mContextStackPos) && (anIndex>=0)) { if((anIndex<mContextStack.mCount) && (anIndex>=0)) {
while(mContextStackPos>anIndex) { while(mContextStack.mCount>anIndex) {
eHTMLTags theTag=(eHTMLTags)(int)mContextStack[mContextStackPos-1]; eHTMLTags theTag=mContextStack.Last();
aToken.SetTypeID(theTag); aToken.SetTypeID(theTag);
result=CloseContainer(theNode,aTag,aUpdateStyles); result=CloseContainer(theNode,aTag,aUpdateStyles);
} }
@ -2131,7 +2197,7 @@ PRInt32 CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTag,PRBool aUpdate
* @return TRUE if ok, FALSE if error * @return TRUE if ok, FALSE if error
*/ */
PRInt32 CNavDTD::CloseContainersTo(eHTMLTags aTag,PRBool aUpdateStyles){ PRInt32 CNavDTD::CloseContainersTo(eHTMLTags aTag,PRBool aUpdateStyles){
NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos); NS_PRECONDITION(mContextStack.mCount > 0, kInvalidTagStackPos);
PRInt32 pos=GetTopmostIndexOf(aTag); PRInt32 pos=GetTopmostIndexOf(aTag);
@ -2172,10 +2238,10 @@ PRInt32 CNavDTD::CloseContainersTo(eHTMLTags aTag,PRBool aUpdateStyles){
* @return TRUE if ok, FALSE if error * @return TRUE if ok, FALSE if error
*/ */
PRInt32 CNavDTD::CloseTopmostContainer(){ PRInt32 CNavDTD::CloseTopmostContainer(){
NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos); NS_PRECONDITION(mContextStack.mCount > 0, kInvalidTagStackPos);
CEndToken aToken(gEmpty); CEndToken aToken(gEmpty);
eHTMLTags theTag=(eHTMLTags)(int)mContextStack[mContextStackPos-1]; eHTMLTags theTag=mContextStack.Last();
aToken.SetTypeID(theTag); aToken.SetTypeID(theTag);
nsCParserNode theNode(&aToken); nsCParserNode theNode(&aToken);
return CloseContainer(theNode,theTag,PR_TRUE); return CloseContainer(theNode,theTag,PR_TRUE);
@ -2217,7 +2283,7 @@ PRInt32 CNavDTD::CreateContextStackFor(eHTMLTags aChildTag){
//add code here to build up context stack based on forward propagated context vector... //add code here to build up context stack based on forward propagated context vector...
pos=0; pos=0;
cnt=theVector.Length()-1; cnt=theVector.Length()-1;
if(mContextStack[mContextStackPos-1]==(void*)theVector[cnt]) if(mContextStack.Last()==(eHTMLTags)theVector[cnt])
result=kNoError; result=kNoError;
else result=kContextMismatch; else result=kContextMismatch;
} }
@ -2236,8 +2302,8 @@ PRInt32 CNavDTD::CreateContextStackFor(eHTMLTags aChildTag){
pos=0; pos=0;
cnt=theVector.Length(); cnt=theVector.Length();
result=kNoError; result=kNoError;
while(pos<mContextStackPos) { while(pos<mContextStack.mCount) {
if(mContextStack[pos]==(void*)theVector[cnt-1-pos]) { if(mContextStack.mTags[pos]==(eHTMLTags)theVector[cnt-1-pos]) {
pos++; pos++;
} }
else { else {
@ -2321,7 +2387,7 @@ PRInt32 CNavDTD::UpdateStyleStackForOpenTag(eHTMLTags aTag,eHTMLTags anActualTag
case eHTMLTag_tt: case eHTMLTag_tt:
case eHTMLTag_u: case eHTMLTag_u:
case eHTMLTag_var: case eHTMLTag_var:
mStyleStack.ReplaceElementAt((void*)aTag,mStyleStackPos++); mStyleStack.Push(aTag);
break; break;
case eHTMLTag_h1: case eHTMLTag_h2: case eHTMLTag_h1: case eHTMLTag_h2:
@ -2347,7 +2413,7 @@ PRInt32 CNavDTD::UpdateStyleStackForOpenTag(eHTMLTags aTag,eHTMLTags anActualTag
PRInt32 CNavDTD::UpdateStyleStackForCloseTag(eHTMLTags aTag,eHTMLTags anActualTag){ PRInt32 CNavDTD::UpdateStyleStackForCloseTag(eHTMLTags aTag,eHTMLTags anActualTag){
PRInt32 result=0; PRInt32 result=0;
if(mStyleStackPos>0) { if(mStyleStack.mCount>0) {
switch (aTag) { switch (aTag) {
case eHTMLTag_a: case eHTMLTag_a:
@ -2369,7 +2435,7 @@ PRInt32 CNavDTD::UpdateStyleStackForCloseTag(eHTMLTags aTag,eHTMLTags anActualTa
case eHTMLTag_u: case eHTMLTag_u:
case eHTMLTag_var: case eHTMLTag_var:
if(aTag==anActualTag) if(aTag==anActualTag)
mStyleStack.ReplaceElementAt((void*)eHTMLTag_unknown,--mStyleStackPos); mStyleStack.Pop();
break; break;
case eHTMLTag_h1: case eHTMLTag_h2: case eHTMLTag_h1: case eHTMLTag_h2:
@ -2716,8 +2782,8 @@ PRInt32 CNavDTD::ConsumeToken(CToken*& aToken){
CScanner* theScanner=mParser->GetScanner(); CScanner* theScanner=mParser->GetScanner();
if(kNoError==result){ if(kNoError==result){
PRUnichar aChar; PRUnichar theChar;
result=theScanner->GetChar(aChar); result=theScanner->GetChar(theChar);
switch(result) { switch(result) {
case kEOF: case kEOF:
break; break;
@ -2728,25 +2794,25 @@ PRInt32 CNavDTD::ConsumeToken(CToken*& aToken){
case kNoError: case kNoError:
default: default:
switch(aChar) { switch(theChar) {
case kLessThan: case kLessThan:
return ConsumeTag(aChar,*theScanner,aToken); return ConsumeTag(theChar,*theScanner,aToken);
case kAmpersand: case kAmpersand:
return ConsumeEntity(aChar,*theScanner,aToken); return ConsumeEntity(theChar,*theScanner,aToken);
case kCR: case kLF: case kCR: case kLF:
return ConsumeNewline(aChar,*theScanner,aToken); return ConsumeNewline(theChar,*theScanner,aToken);
case kNotFound: case kNotFound:
break; break;
default: default:
if(!nsString::IsSpace(aChar)) { if(!nsString::IsSpace(theChar)) {
nsAutoString temp(aChar); nsAutoString temp(theChar);
return ConsumeText(temp,*theScanner,aToken); return ConsumeText(temp,*theScanner,aToken);
} }
return ConsumeWhitespace(aChar,*theScanner,aToken); return ConsumeWhitespace(theChar,*theScanner,aToken);
} //switch } //switch
break; break;
} //switch } //switch

Просмотреть файл

@ -45,6 +45,54 @@ class nsIParserNode;
class CITokenHandler; class CITokenHandler;
class nsParser; class nsParser;
/***************************************************************
First define a helper class called CTagStack.
Simple, we've built ourselves a little data structure that
serves as a stack for htmltags (and associated bits).
What's special is that if you #define _dynstack 1, the stack
size can grow dynamically (like you'ld want in a release build.)
If you don't #define _dynstack 1, then the stack is a fixed size,
equal to the eStackSize enum. This makes debugging easier, because
you can see the htmltags on the stack if its not dynamic.
***************************************************************/
//#define _dynstack 1
class CTagStack {
enum {eStackSize=200};
public:
CTagStack(int aDefaultSize=50);
~CTagStack();
void Push(eHTMLTags aTag);
eHTMLTags Pop();
eHTMLTags First() const;
eHTMLTags Last() const;
int mSize;
int mCount;
#ifdef _dynstack
eHTMLTags* mTags;
PRBool* mBits;
#else
eHTMLTags mTags[200];
PRBool mBits[200];
#endif
};
/***************************************************************
Now the main event: CNavDTD.
This not so simple class performs all the duties of token
construction and model building. It works in conjunction with
an nsParser.
***************************************************************/
class CNavDTD : public nsIDTD { class CNavDTD : public nsIDTD {
public: public:
@ -103,7 +151,7 @@ class CNavDTD : public nsIDTD {
* @param * @param
* @return * @return
*/ */
virtual PRInt32 WillBuildModel(const char* aFilename=0); virtual PRInt32 WillBuildModel(nsString& aFilename);
/** /**
* *
@ -251,14 +299,6 @@ class CNavDTD : public nsIDTD {
*/ */
virtual PRBool BackwardPropagate(nsString& aVector,eHTMLTags aParentTag,eHTMLTags aChildTag) const; virtual PRBool BackwardPropagate(nsString& aVector,eHTMLTags aParentTag,eHTMLTags aChildTag) const;
/**
*
* @update gess6/4/98
* @param
* @return
*/
virtual PRInt32 DidOpenContainer(eHTMLTags aTag,PRBool anExplicitOpen);
/** /**
* Ask parser if a given container is open ANYWHERE on stack * Ask parser if a given container is open ANYWHERE on stack
* @update gess5/11/98 * @update gess5/11/98
@ -283,129 +323,36 @@ class CNavDTD : public nsIDTD {
*/ */
virtual PRInt32 GetTopmostIndexOf(eHTMLTags aTag) const; virtual PRInt32 GetTopmostIndexOf(eHTMLTags aTag) const;
/**
*
* @update gess6/4/98
* @param
* @return
*/
virtual PRInt32 DidCloseContainer(eHTMLTags aTag,PRBool anExplicitClosure);
/** /**
* This method gets called when a start token has been consumed and needs * The following set of methods are used to partially construct
* to be handled (possibly added to content model via sink). * the content model (via the sink) according to the type of token.
* @update gess5/11/98 * @update gess5/11/98
* @param aToken is the start token to be handled * @param aToken is the start token to be handled
* @return TRUE if the token was handled. * @return TRUE if the token was handled.
*/ */
PRInt32 HandleStartToken(CToken* aToken); PRInt32 HandleStartToken(CToken* aToken);
/**
* This method gets called when a start token has been consumed, and
* we want to use default start token handling behavior.
* This method gets called automatically by handleStartToken.
*
* @update gess5/11/98
* @param aToken is the start token to be handled
* @param aChildTag is the tag-type of given token
* @param aNode is a node be updated with info from given token
* @return TRUE if the token was handled.
*/
PRInt32 HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsIParserNode& aNode); PRInt32 HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsIParserNode& aNode);
/**
* This method gets called when an end token has been consumed and needs
* to be handled (possibly added to content model via sink).
* @update gess5/11/98
* @param aToken is the end token to be handled
* @return TRUE if the token was handled.
*/
PRInt32 HandleEndToken(CToken* aToken); PRInt32 HandleEndToken(CToken* aToken);
/**
* This method gets called when an entity token has been consumed and needs
* to be handled (possibly added to content model via sink).
* @update gess5/11/98
* @param aToken is the entity token to be handled
* @return TRUE if the token was handled.
*/
PRInt32 HandleEntityToken(CToken* aToken); PRInt32 HandleEntityToken(CToken* aToken);
/**
* This method gets called when a comment token has been consumed and needs
* to be handled (possibly added to content model via sink).
* @update gess5/11/98
* @param aToken is the comment token to be handled
* @return TRUE if the token was handled.
*/
PRInt32 HandleCommentToken(CToken* aToken); PRInt32 HandleCommentToken(CToken* aToken);
/**
* This method gets called when a skipped-content token has been consumed and needs
* to be handled (possibly added to content model via sink).
* @update gess5/11/98
* @param aToken is the skipped-content token to be handled
* @return TRUE if the token was handled.
*/
PRInt32 HandleSkippedContentToken(CToken* aToken); PRInt32 HandleSkippedContentToken(CToken* aToken);
/**
* This method gets called when an attribute token has been consumed and needs
* to be handled (possibly added to content model via sink).
* @update gess5/11/98
* @param aToken is the attribute token to be handled
* @return TRUE if the token was handled.
*/
PRInt32 HandleAttributeToken(CToken* aToken); PRInt32 HandleAttributeToken(CToken* aToken);
/**
* This method gets called when a script token has been consumed and needs
* to be handled (possibly added to content model via sink).
* @update gess5/11/98
* @param aToken is the script token to be handled
* @return TRUE if the token was handled.
*/
PRInt32 HandleScriptToken(CToken* aToken); PRInt32 HandleScriptToken(CToken* aToken);
/**
* This method gets called when a style token has been consumed and needs
* to be handled (possibly added to content model via sink).
* @update gess5/11/98
* @param aToken is the style token to be handled
* @return TRUE if the token was handled.
*/
PRInt32 HandleStyleToken(CToken* aToken); PRInt32 HandleStyleToken(CToken* aToken);
protected: protected:
/** /**
* Causes token handlers to be registered for this parser. * The following methods are use to create and manage
* DO NOT CALL THIS! IT'S DEPRECATED! * the dynamic set of token handlers.
* @update gess5/11/98
*/
void InitializeDefaultTokenHandlers();
/**
* DEPRECATED
* @update gess5/11/98 * @update gess5/11/98
*/ */
void InitializeDefaultTokenHandlers();
CITokenHandler* GetTokenHandler(eHTMLTokenTypes aType) const; CITokenHandler* GetTokenHandler(eHTMLTokenTypes aType) const;
/**
* DEPRECATED
* @update gess5/11/98
*/
CITokenHandler* AddTokenHandler(CITokenHandler* aHandler); CITokenHandler* AddTokenHandler(CITokenHandler* aHandler);
void DeleteTokenHandlers(void);
/**
* DEPRECATED
* @update gess5/11/98
*/
void DeleteTokenHandlers(void);
//************************************************* //*************************************************
@ -414,145 +361,43 @@ protected:
//************************************************* //*************************************************
/** /**
* This cover method opens the given node as a HTML item in * The next set of method open given HTML element.
* content sink. *
* @update gess5/11/98 * @update gess5/11/98
* @param HTML (node) to be opened in content sink. * @param HTML (node) to be opened in content sink.
* @return TRUE if all went well. * @return TRUE if all went well.
*/ */
PRInt32 OpenHTML(const nsIParserNode& aNode); PRInt32 OpenHTML(const nsIParserNode& aNode);
/**
*
* @update gess5/11/98
* @param
* @return
*/
PRInt32 CloseHTML(const nsIParserNode& aNode);
/**
* This cover method opens the given node as a head item in
* content sink.
* @update gess5/11/98
* @param HEAD (node) to be opened in content sink.
* @return TRUE if all went well.
*/
PRInt32 OpenHead(const nsIParserNode& aNode); PRInt32 OpenHead(const nsIParserNode& aNode);
/**
* This cover method causes the content-sink head to be closed
* @update gess5/11/98
* @param aNode is the node to be closed in sink (usually ignored)
* @return TRUE if all went well.
*/
PRInt32 CloseHead(const nsIParserNode& aNode);
/**
* This cover method opens the given node as a body item in
* content sink.
* @update gess5/11/98
* @param BODY (node) to be opened in content sink.
* @return TRUE if all went well.
*/
PRInt32 OpenBody(const nsIParserNode& aNode); PRInt32 OpenBody(const nsIParserNode& aNode);
/**
* This cover method causes the content-sink body to be closed
* @update gess5/11/98
* @param aNode is the body node to be closed in sink (usually ignored)
* @return TRUE if all went well.
*/
PRInt32 CloseBody(const nsIParserNode& aNode);
/**
* This cover method opens the given node as a form item in
* content sink.
* @update gess5/11/98
* @param FORM (node) to be opened in content sink.
* @return TRUE if all went well.
*/
PRInt32 OpenForm(const nsIParserNode& aNode); PRInt32 OpenForm(const nsIParserNode& aNode);
/**
* This cover method causes the content-sink form to be closed
* @update gess5/11/98
* @param aNode is the form node to be closed in sink (usually ignored)
* @return TRUE if all went well.
*/
PRInt32 CloseForm(const nsIParserNode& aNode);
/**
* This cover method opens the given node as a form item in
* content sink.
* @update gess5/11/98
* @param FORM (node) to be opened in content sink.
* @return TRUE if all went well.
*/
PRInt32 OpenMap(const nsIParserNode& aNode); PRInt32 OpenMap(const nsIParserNode& aNode);
/**
* This cover method causes the content-sink form to be closed
* @update gess5/11/98
* @param aNode is the form node to be closed in sink (usually ignored)
* @return TRUE if all went well.
*/
PRInt32 CloseMap(const nsIParserNode& aNode);
/**
* This cover method opens the given node as a frameset item in
* content sink.
* @update gess5/11/98
* @param FRAMESET (node) to be opened in content sink.
* @return TRUE if all went well.
*/
PRInt32 OpenFrameset(const nsIParserNode& aNode); PRInt32 OpenFrameset(const nsIParserNode& aNode);
/**
* This cover method causes the content-sink frameset to be closed
* @update gess5/11/98
* @param aNode is the frameeset node to be closed in sink (usually ignored)
* @return TRUE if all went well.
*/
PRInt32 CloseFrameset(const nsIParserNode& aNode);
/**
* This cover method opens the given node as a generic container in
* content sink.
* @update gess5/11/98
* @param generic container (node) to be opened in content sink.
* @return TRUE if all went well.
*/
PRInt32 OpenContainer(const nsIParserNode& aNode,PRBool aUpdateStyleStack); PRInt32 OpenContainer(const nsIParserNode& aNode,PRBool aUpdateStyleStack);
/** /**
* This cover method causes a generic containre in the content-sink to be closed * The next set of methods close the given HTML element.
*
* @update gess5/11/98 * @update gess5/11/98
* @param aNode is the node to be closed in sink (usually ignored) * @param HTML (node) to be opened in content sink.
* @return TRUE if all went well. * @return TRUE if all went well.
*/ */
PRInt32 CloseHTML(const nsIParserNode& aNode);
PRInt32 CloseHead(const nsIParserNode& aNode);
PRInt32 CloseBody(const nsIParserNode& aNode);
PRInt32 CloseForm(const nsIParserNode& aNode);
PRInt32 CloseMap(const nsIParserNode& aNode);
PRInt32 CloseFrameset(const nsIParserNode& aNode);
PRInt32 CloseContainer(const nsIParserNode& aNode,eHTMLTags anActualTag,PRBool aUpdateStyles); PRInt32 CloseContainer(const nsIParserNode& aNode,eHTMLTags anActualTag,PRBool aUpdateStyles);
/** /**
* This cover method causes the topmost container to be closed in sink * The special purpose methods automatically close
* one or more open containers.
* @update gess5/11/98 * @update gess5/11/98
* @return TRUE if all went well. * @return TRUE if all went well.
*/ */
PRInt32 CloseTopmostContainer(); PRInt32 CloseTopmostContainer();
/**
* Cause all containers down to topmost given tag to be closed
* @update gess5/11/98
* @param aTag is the tag at which auto-closure should stop (inclusive)
* @return TRUE if all went well -- otherwise FALSE
*/
PRInt32 CloseContainersTo(eHTMLTags aTag,PRBool aUpdateStyles); PRInt32 CloseContainersTo(eHTMLTags aTag,PRBool aUpdateStyles);
/**
* Cause all containers down to given position to be closed
* @update gess5/11/98
* @param anIndex is the stack pos at which auto-closure should stop (inclusive)
* @return TRUE if all went well -- otherwise FALSE
*/
PRInt32 CloseContainersTo(PRInt32 anIndex,eHTMLTags aTag,PRBool aUpdateStyles); PRInt32 CloseContainersTo(PRInt32 anIndex,eHTMLTags aTag,PRBool aUpdateStyles);
/** /**
@ -603,81 +448,22 @@ protected:
CToken* CreateTokenOfType(eHTMLTokenTypes aType); CToken* CreateTokenOfType(eHTMLTokenTypes aType);
/** /**
* Retrieve the next TAG from the given scanner. * The following methods consume a particular type
* of HTML token.
*
* @update gess 5/11/98 * @update gess 5/11/98
* @param aScanner is the input source * @param aScanner is the input source
* @param aToken is the next token (or null) * @param aToken is the next token (or null)
* @return error code * @return error code
*/ */
PRInt32 ConsumeTag(PRUnichar aChar,CScanner& aScanner,CToken*& aToken); PRInt32 ConsumeTag(PRUnichar aChar,CScanner& aScanner,CToken*& aToken);
/**
* Retrieve next START tag from given scanner.
* @update gess 5/11/98
* @param aScanner is the input source
* @param aToken is the next token (or null)
* @return error code
*/
PRInt32 ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,CToken*& aToken); PRInt32 ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,CToken*& aToken);
/**
* Retrieve collection of HTML/XML attributes from given scanner
* @update gess 5/11/98
* @param aScanner is the input source
* @param aToken is the next token (or null)
* @return error code
*/
PRInt32 ConsumeAttributes(PRUnichar aChar,CScanner& aScanner,CStartToken* aToken); PRInt32 ConsumeAttributes(PRUnichar aChar,CScanner& aScanner,CStartToken* aToken);
/**
* Retrieve a sequence of text from given scanner.
* @update gess 5/11/98
* @param aString will contain retrieved text.
* @param aScanner is the input source
* @param aToken is the next token (or null)
* @return error code
*/
PRInt32 ConsumeText(const nsString& aString,CScanner& aScanner,CToken*& aToken);
/**
* Retrieve an entity from given scanner
* @update gess 5/11/98
* @param aChar last char read from scanner
* @param aScanner is the input source
* @param aToken is the next token (or null)
* @return error code
*/
PRInt32 ConsumeEntity(PRUnichar aChar,CScanner& aScanner,CToken*& aToken); PRInt32 ConsumeEntity(PRUnichar aChar,CScanner& aScanner,CToken*& aToken);
/**
* Retrieve a whitespace sequence from the given scanner
* @update gess 5/11/98
* @param aChar last char read from scanner
* @param aScanner is the input source
* @param aToken is the next token (or null)
* @return error code
*/
PRInt32 ConsumeWhitespace(PRUnichar aChar,CScanner& aScanner,CToken*& aToken); PRInt32 ConsumeWhitespace(PRUnichar aChar,CScanner& aScanner,CToken*& aToken);
/**
* Retrieve a comment from the given scanner
* @update gess 5/11/98
* @param aChar last char read from scanner
* @param aScanner is the input source
* @param aToken is the next token (or null)
* @return error code
*/
PRInt32 ConsumeComment(PRUnichar aChar,CScanner& aScanner,CToken*& aToken); PRInt32 ConsumeComment(PRUnichar aChar,CScanner& aScanner,CToken*& aToken);
/**
* Retrieve newlines from given scanner
* @update gess 5/11/98
* @param aChar last char read from scanner
* @param aScanner is the input source
* @param aToken is the next token (or null)
* @return error code
*/
PRInt32 ConsumeNewline(PRUnichar aChar,CScanner& aScanner,CToken*& aToken); PRInt32 ConsumeNewline(PRUnichar aChar,CScanner& aScanner,CToken*& aToken);
PRInt32 ConsumeText(const nsString& aString,CScanner& aScanner,CToken*& aToken);
/** /**
* Causes content to be skipped up to sequence contained in aString. * Causes content to be skipped up to sequence contained in aString.
@ -700,16 +486,13 @@ protected:
CITokenHandler* mTokenHandlers[eToken_last]; CITokenHandler* mTokenHandlers[eToken_last];
nsVoidArray mLeafBits; CTagStack mContextStack;
nsVoidArray mContextStack; CTagStack mStyleStack;
PRInt32 mContextStackPos;
nsVoidArray mStyleStack;
PRInt32 mStyleStackPos;
PRBool mHasOpenForm; PRBool mHasOpenForm;
PRBool mHasOpenMap; PRBool mHasOpenMap;
nsDeque mTokenDeque; nsDeque mTokenDeque;
char* mFilename; nsString mFilename;
nsIDTDDebug* mDTDDebug; nsIDTDDebug* mDTDDebug;
}; };

Просмотреть файл

@ -178,7 +178,7 @@ eAutoDetectResult COtherDTD::AutoDetectContentType(nsString& aBuffer,nsString& a
* @param * @param
* @return * @return
*/ */
PRInt32 COtherDTD::WillBuildModel(const char* aFilename) { PRInt32 COtherDTD::WillBuildModel(nsString& aFilename) {
return CNavDTD::WillBuildModel(aFilename); return CNavDTD::WillBuildModel(aFilename);
} }
@ -464,25 +464,6 @@ PRBool COtherDTD::BackwardPropagate(nsString& aVector,eHTMLTags aParentTag,eHTML
return CNavDTD::BackwardPropagate(aVector,aParentTag,aChildTag); return CNavDTD::BackwardPropagate(aVector,aParentTag,aChildTag);
} }
/**
*
* @update gess6/4/98
* @param aTag is the id of the html container being opened
* @return 0 if all is well.
*/
PRInt32 COtherDTD::DidOpenContainer(eHTMLTags aTag,PRBool anExplicitOpen){
return CNavDTD::DidOpenContainer(aTag,anExplicitOpen);
}
/**
*
* @update gess6/4/98
* @param
* @return
*/
PRInt32 COtherDTD::DidCloseContainer(eHTMLTags aTag,PRBool anExplicitClosure){
return CNavDTD::DidOpenContainer(aTag,anExplicitClosure);
}
/********************************************* /*********************************************
Here comes code that handles the interface Here comes code that handles the interface

Просмотреть файл

@ -87,7 +87,7 @@ class COtherDTD : public CNavDTD {
* @param * @param
* @return * @return
*/ */
virtual PRInt32 WillBuildModel(const char* aFilename=0); virtual PRInt32 WillBuildModel(nsString& aString);
/** /**
* *
@ -218,22 +218,6 @@ class COtherDTD : public CNavDTD {
*/ */
virtual PRBool BackwardPropagate(nsString& aVector,eHTMLTags aParentTag,eHTMLTags aChildTag) const; virtual PRBool BackwardPropagate(nsString& aVector,eHTMLTags aParentTag,eHTMLTags aChildTag) const;
/**
*
* @update gess6/4/98
* @param
* @return
*/
virtual PRInt32 DidOpenContainer(eHTMLTags aTag,PRBool anExplicitOpen);
/**
*
* @update gess6/4/98
* @param
* @return
*/
virtual PRInt32 DidCloseContainer(eHTMLTags aTag,PRBool anExplicitClosure);
/** /**
* This method gets called when a start token has been consumed and needs * This method gets called when a start token has been consumed and needs
* to be handled (possibly added to content model via sink). * to be handled (possibly added to content model via sink).

Просмотреть файл

@ -0,0 +1,85 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/**
* MODULE NOTES:
* @update gess 4/1/98
*
*/
#include "CParserContext.h"
#include "nsToken.h"
class CTokenDeallocator: public nsDequeFunctor{
public:
virtual void* operator()(void* anObject) {
CToken* aToken = (CToken*)anObject;
delete aToken;
return 0;
}
};
CTokenDeallocator gTokenDeallocator;
CParserContext::CParserContext(CScanner* aScanner,
CParserContext* aPreviousContext,
nsIStreamObserver* aListener) :
mTokenDeque(gTokenDeallocator),
mSourceType()
{
mScanner=aScanner;
mPrevContext=aPreviousContext;
mListener=aListener;
NS_IF_ADDREF(mListener);
mMajorIteration=mMinorIteration=-1;
mParseMode=eParseMode_unknown;
mAutoDetectStatus=eUnknownDetect;
mTransferBuffer=new char[eTransferBufferSize+1];
mCurrentPos=0;
mMarkPos=0;
mDTD=0;
}
/**
* Destructor for parser context
* NOTE: DO NOT destroy the dtd here.
* @update gess7/11/98
*/
CParserContext::~CParserContext(){
if(mCurrentPos)
delete mCurrentPos;
if(mMarkPos)
delete mMarkPos;
if(mScanner)
delete mScanner;
if(mTransferBuffer)
delete [] mTransferBuffer;
//Remember that it's ok to simply
//ignore the DTD and the prevcontext.
}

Просмотреть файл

@ -0,0 +1,80 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/**
* MODULE NOTES:
* @update gess 4/1/98
*
*/
#ifndef __CParserContext
#define __CParserContext
#include "nsIParser.h"
#include "nsDeque.h"
#include "nsParserTypes.h"
#include "nsIURL.h"
#include "nsIDTD.h"
#include "nsScanner.h"
#include "nsIStreamListener.h"
/**
* Note that the parser is given FULL access to all
* data in a parsercontext. Hey, that what it's for!
*/
class CParserContext {
public:
enum {eTransferBufferSize=4096};
CParserContext( CScanner* aScanner,
CParserContext* aPreviousContext=0,
nsIStreamObserver* aListener=0);
~CParserContext();
PRInt32 mMajorIteration;
PRInt32 mMinorIteration;
nsString mSourceType;
eAutoDetectResult mAutoDetectStatus;
nsDequeIterator* mCurrentPos;
nsDequeIterator* mMarkPos;
nsDeque mTokenDeque;
CScanner* mScanner;
nsIDTD* mDTD;
eParseMode mParseMode;
char* mTransferBuffer;
nsIStreamObserver* mListener;
CParserContext* mPrevContext;
};
#endif

Просмотреть файл

@ -251,7 +251,7 @@ eAutoDetectResult CRtfDTD::AutoDetectContentType(nsString& aBuffer,nsString& aTy
* @param * @param
* @return * @return
*/ */
PRInt32 CRtfDTD::WillBuildModel(const char* aFilename){ PRInt32 CRtfDTD::WillBuildModel(nsString& aFilename){
PRInt32 result=0; PRInt32 result=0;
return result; return result;
} }

Просмотреть файл

@ -190,7 +190,7 @@ class CRtfDTD : public nsIDTD {
* @param * @param
* @return * @return
*/ */
virtual PRInt32 WillBuildModel(const char* aFilename=0); virtual PRInt32 WillBuildModel(nsString& aFilename);
/** /**
* *

Просмотреть файл

@ -34,6 +34,7 @@ CPPSRCS = \
nsValidDTD.cpp \ nsValidDTD.cpp \
nsWellFormedDTD.cpp \ nsWellFormedDTD.cpp \
nsParser.cpp \ nsParser.cpp \
CParserContext.cpp \
nsHTMLTokens.cpp \ nsHTMLTokens.cpp \
nsHTMLTags.cpp \ nsHTMLTags.cpp \
prstrm.cpp \ prstrm.cpp \

Просмотреть файл

@ -34,6 +34,7 @@ CPPSRCS= \
nsHTMLTags.obj \ nsHTMLTags.obj \
nsHTMLTokens.obj \ nsHTMLTokens.obj \
nsParser.obj \ nsParser.obj \
CParserContext.obj \
nsParserNode.obj \ nsParserNode.obj \
nsScanner.obj \ nsScanner.obj \
nsToken.obj \ nsToken.obj \
@ -53,6 +54,7 @@ CPP_OBJS= \
.\$(OBJDIR)\nsHTMLTags.obj \ .\$(OBJDIR)\nsHTMLTags.obj \
.\$(OBJDIR)\nsHTMLTokens.obj \ .\$(OBJDIR)\nsHTMLTokens.obj \
.\$(OBJDIR)\nsParser.obj \ .\$(OBJDIR)\nsParser.obj \
.\$(OBJDIR)\CParserContext.obj \
.\$(OBJDIR)\nsParserNode.obj \ .\$(OBJDIR)\nsParserNode.obj \
.\$(OBJDIR)\nsScanner.obj \ .\$(OBJDIR)\nsScanner.obj \
.\$(OBJDIR)\nsToken.obj \ .\$(OBJDIR)\nsToken.obj \

Просмотреть файл

@ -67,7 +67,7 @@ public:
void SetVerificationDirectory(char * verify_dir); void SetVerificationDirectory(char * verify_dir);
void SetRecordStatistics(PRBool bval); void SetRecordStatistics(PRBool bval);
PRBool Verify(nsIDTD * aDTD, nsParser * aParser, int ContextStackPos, nsVoidArray &aContextStack, char * aURLRef); PRBool Verify(nsIDTD * aDTD, nsParser * aParser, int ContextStackPos, eHTMLTags aContextStack[], nsString& aURLRef);
void DumpVectorRecord(void); void DumpVectorRecord(void);
// global table for storing vector statistics and the size // global table for storing vector statistics and the size
@ -78,8 +78,8 @@ private:
char * mVerificationDir; char * mVerificationDir;
PRBool mRecordingStatistics; PRBool mRecordingStatistics;
PRBool DebugRecord(char * path, char * pURLRef, char * filename); PRBool DebugRecord(char * path, nsString& pURLRef, char * filename);
void NoteVector(nsVoidArray & aTags,PRInt32 count, PRBool good_vector); void NoteVector(eHTMLTags aTags[],PRInt32 count, PRBool good_vector);
void MakeVectorString(char * vector_string, VectorInfo * pInfo); void MakeVectorString(char * vector_string, VectorInfo * pInfo);
}; };
@ -188,7 +188,7 @@ void CDTDDebug::SetRecordStatistics(PRBool bval)
* @return TRUE if it is already record (dont rerecord) * @return TRUE if it is already record (dont rerecord)
*/ */
PRBool CDTDDebug::DebugRecord(char * path, char * pURLRef, char * filename) PRBool CDTDDebug::DebugRecord(char * path, nsString& aURLRef, char * filename)
{ {
char recordPath[2048]; char recordPath[2048];
PRIntn oflags = 0; PRIntn oflags = 0;
@ -215,7 +215,9 @@ PRBool CDTDDebug::DebugRecord(char * path, char * pURLRef, char * filename)
// vectors are stored on the format iof "URL vector filename" // vectors are stored on the format iof "URL vector filename"
// where the vector contains the verification path and // where the vector contains the verification path and
// the filename contains the debug source dump // the filename contains the debug source dump
sprintf(string,"%s %s %s\r\n", pURLRef, path, filename); char buffer[513];
aURLRef.ToCString(buffer,sizeof(buffer)-1);
sprintf(string,"%s %s %s\r\n", buffer, path, filename);
// get the file size, read in the file and parse it line at // get the file size, read in the file and parse it line at
// a time to check to see if we have already recorded this // a time to check to see if we have already recorded this
@ -310,7 +312,7 @@ static int compare( const void *arg1, const void *arg2 )
* @return * @return
*/ */
void CDTDDebug::NoteVector(nsVoidArray & aTags,PRInt32 count, PRBool good_vector) void CDTDDebug::NoteVector(eHTMLTags aTags[],PRInt32 count, PRBool good_vector)
{ {
// if the table doesn't exist, create it // if the table doesn't exist, create it
if (!mVectorInfoArray) { if (!mVectorInfoArray) {
@ -327,7 +329,7 @@ void CDTDDebug::NoteVector(nsVoidArray & aTags,PRInt32 count, PRBool good_vector
PRBool match = PR_TRUE; PRBool match = PR_TRUE;
for (PRInt32 j = 0; j < count; j++) for (PRInt32 j = 0; j < count; j++)
if (mVectorInfoArray[i]->vector[j] != (eHTMLTags)(int)aTags[j]) { if (mVectorInfoArray[i]->vector[j] != aTags[j]) {
match = PR_FALSE; match = PR_FALSE;
break; break;
} }
@ -348,7 +350,7 @@ void CDTDDebug::NoteVector(nsVoidArray & aTags,PRInt32 count, PRBool good_vector
pVectorInfo->good_vector = good_vector; pVectorInfo->good_vector = good_vector;
pVectorInfo->vector = (eHTMLTags*)PR_Malloc(count*sizeof(eHTMLTags)); pVectorInfo->vector = (eHTMLTags*)PR_Malloc(count*sizeof(eHTMLTags));
for (PRInt32 i = 0; i < count; i++) for (PRInt32 i = 0; i < count; i++)
pVectorInfo->vector[i] = (eHTMLTags)(int)aTags[i]; pVectorInfo->vector[i] = aTags[i];
mVectorInfoArray[mVectorCount++] = pVectorInfo; mVectorInfoArray[mVectorCount++] = pVectorInfo;
// have we maxed out the table? grow it.. sort it.. love it. // have we maxed out the table? grow it.. sort it.. love it.
@ -467,7 +469,7 @@ void CDTDDebug::DumpVectorRecord(void)
* @return TRUE if we know how to handle it, else false * @return TRUE if we know how to handle it, else false
*/ */
PRBool CDTDDebug::Verify(nsIDTD * aDTD, nsParser * aParser, int aContextStackPos, nsVoidArray &aContextStack, char * aURLRef) PRBool CDTDDebug::Verify(nsIDTD * aDTD, nsParser * aParser, int aContextStackPos, eHTMLTags aContextStack[], nsString& aURLRef)
{ {
PRBool result=PR_TRUE; PRBool result=PR_TRUE;
@ -477,7 +479,7 @@ PRBool CDTDDebug::Verify(nsIDTD * aDTD, nsParser * aParser, int aContextStackPo
if(aDTD && aContextStackPos>1) { if(aDTD && aContextStackPos>1) {
for (int i = 0; i < aContextStackPos-1; i++) for (int i = 0; i < aContextStackPos-1; i++)
if (!aDTD->CanContain((eHTMLTags)(int)aContextStack[i],(eHTMLTags)(int)aContextStack[i+1])) { if (!aDTD->CanContain(aContextStack[i],aContextStack[i+1])) {
result = PR_FALSE; result = PR_FALSE;
break; break;
} }
@ -495,7 +497,7 @@ PRBool CDTDDebug::Verify(nsIDTD * aDTD, nsParser * aParser, int aContextStackPo
int i=0; int i=0;
for(i=0;i<aContextStackPos;i++){ for(i=0;i<aContextStackPos;i++){
strcat(path,"/"); strcat(path,"/");
const char* name=GetTagName((eHTMLTags)(int)aContextStack[i]); const char* name=GetTagName(aContextStack[i]);
strcat(path,name); strcat(path,name);
PR_MkDir(path,0); PR_MkDir(path,0);
} }

Просмотреть файл

@ -30,7 +30,7 @@
#include "nsHTMLContentSinkStream.h" #include "nsHTMLContentSinkStream.h"
#include "nsHTMLTokens.h" #include "nsHTMLTokens.h"
#include <iostream.h> #include <iostream.h>
#include "nsString.h" #include "nsstring.h"
#include "nsParserTypes.h" #include "nsParserTypes.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
@ -89,8 +89,8 @@ NS_IMPL_RELEASE(CHTMLContentSinkStream)
* @param nsIParser** ptr to newly instantiated parser * @param nsIParser** ptr to newly instantiated parser
* @return NS_xxx error result * @return NS_xxx error result
*/ */
NS_HTMLPARS nsresult NS_New_HTML_ContentSinkStream(CHTMLContentSinkStream** aInstancePtrResult) { NS_HTMLPARS nsresult NS_New_HTML_ContentSinkStream(CHTMLContentSinkStream** aInstancePtrResult,ostream* aStream) {
CHTMLContentSinkStream* it = new CHTMLContentSinkStream(); CHTMLContentSinkStream* it = new CHTMLContentSinkStream(aStream);
if (it == 0) { if (it == 0) {
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
@ -99,25 +99,14 @@ NS_HTMLPARS nsresult NS_New_HTML_ContentSinkStream(CHTMLContentSinkStream** aIns
return it->QueryInterface(kClassIID, (void **) aInstancePtrResult); return it->QueryInterface(kClassIID, (void **) aInstancePtrResult);
} }
/** /**
* Construct a content sink stream. * Construct a content sink stream.
* @update gess7/7/98 * @update gess7/7/98
* @param * @param
* @return * @return
*/ */
CHTMLContentSinkStream::CHTMLContentSinkStream() { CHTMLContentSinkStream::CHTMLContentSinkStream(ostream* aStream) {
mOutput=&cout; mOutput=(0==aStream) ? &cout : aStream;
}
/**
* Construct a content sink stream.
* @update gess7/7/98
* @param
* @return
*/
CHTMLContentSinkStream::CHTMLContentSinkStream(ostream& aStream) {
mOutput=&aStream;
} }
@ -132,17 +121,6 @@ CHTMLContentSinkStream::~CHTMLContentSinkStream() {
} }
/**
*
* @update gess7/7/98
* @param
* @return
*/
void CHTMLContentSinkStream::SetOutputStream(ostream& aStream) {
mOutput=&aStream;
}
/** /**
* *
* @update gess7/7/98 * @update gess7/7/98
@ -171,7 +149,7 @@ void WriteAttributes(const nsIParserNode& aNode,ostream& aStream) {
* @param * @param
* @return * @return
*/ */
void OpenTagWithAttributes(const char* theTag,const nsIParserNode& aNode,int tab,ostream& aStream,PRBool aNewline) { void OpenTagWithAttributes(const char* theTag,const nsIParserNode& aNode,int tab,ostream& aStream,bool aNewline) {
int i=0; int i=0;
for(i=0;i<tab*gTabSize;i++) for(i=0;i<tab*gTabSize;i++)
aStream << " "; aStream << " ";
@ -189,7 +167,7 @@ void OpenTagWithAttributes(const char* theTag,const nsIParserNode& aNode,int tab
* @param * @param
* @return * @return
*/ */
void OpenTag(const char* theTag,int tab,ostream& aStream,PRBool aNewline) { void OpenTag(const char* theTag,int tab,ostream& aStream,bool aNewline) {
int i=0; int i=0;
for(i=0;i<tab*gTabSize;i++) for(i=0;i<tab*gTabSize;i++)
aStream << " "; aStream << " ";
@ -221,7 +199,7 @@ void CloseTag(const char* theTag,int tab,ostream& aStream) {
*/ */
void WritePair(eHTMLTags aTag,const nsString& theContent,int tab,ostream& aStream) { void WritePair(eHTMLTags aTag,const nsString& theContent,int tab,ostream& aStream) {
const char* titleStr = GetTagName(aTag); const char* titleStr = GetTagName(aTag);
OpenTag(titleStr,tab,aStream,PR_FALSE); OpenTag(titleStr,tab,aStream,false);
theContent.ToCString(gBuffer,sizeof(gBuffer)-1); theContent.ToCString(gBuffer,sizeof(gBuffer)-1);
aStream << gBuffer; aStream << gBuffer;
CloseTag(titleStr,0,aStream); CloseTag(titleStr,0,aStream);
@ -237,7 +215,7 @@ void WritePair(eHTMLTags aTag,const nsString& theContent,int tab,ostream& aStrea
*/ */
void WriteSingleton(eHTMLTags aTag,const nsString& theContent,int tab,ostream& aStream) { void WriteSingleton(eHTMLTags aTag,const nsString& theContent,int tab,ostream& aStream) {
const char* titleStr = GetTagName(aTag); const char* titleStr = GetTagName(aTag);
OpenTag(titleStr,tab,aStream,PR_FALSE); OpenTag(titleStr,tab,aStream,false);
if(theContent.Length()) { if(theContent.Length()) {
theContent.ToCString(gBuffer,sizeof(gBuffer)-1); theContent.ToCString(gBuffer,sizeof(gBuffer)-1);
aStream << gBuffer; aStream << gBuffer;
@ -275,7 +253,7 @@ PRInt32 CHTMLContentSinkStream::OpenHTML(const nsIParserNode& aNode){
mTabLevel++; mTabLevel++;
if(mOutput) { if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_html); const char* theTag= GetTagName(eHTMLTag_html);
OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,PR_TRUE); OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,true);
} }
return result; return result;
} }
@ -311,7 +289,7 @@ PRInt32 CHTMLContentSinkStream::OpenHead(const nsIParserNode& aNode){
mTabLevel++; mTabLevel++;
if(mOutput) { if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_head); const char* theTag= GetTagName(eHTMLTag_head);
OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,PR_TRUE); OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,true);
} }
return result; return result;
} }
@ -347,7 +325,7 @@ PRInt32 CHTMLContentSinkStream::OpenBody(const nsIParserNode& aNode){
mTabLevel++; mTabLevel++;
if(mOutput) { if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_body); const char* theTag= GetTagName(eHTMLTag_body);
OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,PR_TRUE); OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,true);
} }
return result; return result;
} }
@ -383,7 +361,7 @@ PRInt32 CHTMLContentSinkStream::OpenForm(const nsIParserNode& aNode){
mTabLevel++; mTabLevel++;
if(mOutput) { if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_form); const char* theTag= GetTagName(eHTMLTag_form);
OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,PR_TRUE); OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,true);
} }
return result; return result;
} }
@ -419,7 +397,7 @@ PRInt32 CHTMLContentSinkStream::OpenFrameset(const nsIParserNode& aNode){
mTabLevel++; mTabLevel++;
if(mOutput) { if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_frameset); const char* theTag= GetTagName(eHTMLTag_frameset);
OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,PR_TRUE); OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,true);
} }
return result; return result;
} }
@ -487,7 +465,7 @@ PRInt32 CHTMLContentSinkStream::OpenContainer(const nsIParserNode& aNode){
{ {
const nsString& name=aNode.GetName(); const nsString& name=aNode.GetName();
const char* tagName= GetTagName(nodeType); const char* tagName= GetTagName(nodeType);
OpenTagWithAttributes(tagName,aNode,mTabLevel,*mOutput,PR_TRUE); OpenTagWithAttributes(tagName,aNode,mTabLevel,*mOutput,true);
} }
break; break;
} }

Просмотреть файл

@ -52,15 +52,7 @@ class CHTMLContentSinkStream : public nsIHTMLContentSink {
* @param * @param
* @return * @return
*/ */
CHTMLContentSinkStream(); CHTMLContentSinkStream(ostream* aStream);
/**
*
* @update gess7/7/98
* @param
* @return
*/
CHTMLContentSinkStream(ostream& aStream);
/** /**
* *
@ -71,14 +63,6 @@ class CHTMLContentSinkStream : public nsIHTMLContentSink {
virtual ~CHTMLContentSinkStream(); virtual ~CHTMLContentSinkStream();
/**
*
* @update gess7/7/98
* @param
* @return
*/
void SetOutputStream(ostream& aStream);
/** /**
* This method gets called by the parser when it encounters * This method gets called by the parser when it encounters
* a title tag and wants to set the document title in the sink. * a title tag and wants to set the document title in the sink.
@ -249,7 +233,7 @@ protected:
}; };
extern NS_HTMLPARS nsresult NS_New_HTML_ContentSinkStream(CHTMLContentSinkStream** aInstancePtrResult); extern NS_HTMLPARS nsresult NS_New_HTML_ContentSinkStream(CHTMLContentSinkStream** aInstancePtrResult,ostream* aStream);
#endif #endif

Просмотреть файл

@ -99,7 +99,7 @@ class nsIDTD : public nsISupports {
* @param * @param
* @return * @return
*/ */
virtual PRInt32 WillBuildModel(const char* aFilename=0)=0; virtual PRInt32 WillBuildModel(nsString& aFilename)=0;
/** /**
* *

Просмотреть файл

@ -47,7 +47,7 @@ public:
virtual void SetRecordStatistics(PRBool bval) = 0; virtual void SetRecordStatistics(PRBool bval) = 0;
virtual PRBool Verify(nsIDTD * aDTD, nsParser * aParser, int ContextStackPos, nsVoidArray & aContextStack, char * aURLRef) = 0; virtual PRBool Verify(nsIDTD * aDTD, nsParser * aParser, int ContextStackPos, eHTMLTags aContextStack[], nsString& aURLRef) = 0;
virtual void DumpVectorRecord(void) = 0; virtual void DumpVectorRecord(void) = 0;

Просмотреть файл

@ -23,6 +23,7 @@
#include "nsISupports.h" #include "nsISupports.h"
#include "nsIStreamListener.h" #include "nsIStreamListener.h"
#include "nsIDTD.h" #include "nsIDTD.h"
#include "nsIInputStream.h"
#define NS_IPARSER_IID \ #define NS_IPARSER_IID \
{0x355cbba0, 0xbf7d, 0x11d1, \ {0x355cbba0, 0xbf7d, 0x11d1, \
@ -67,20 +68,18 @@ class nsIParser : public nsISupports {
* until you wind up with HTML in your actual content model. * until you wind up with HTML in your actual content model.
******************************************************************************************/ ******************************************************************************************/
virtual PRInt32 Parse(nsIURL* aURL,nsIStreamObserver* aListener = nsnull,nsIDTDDebug * aDTDDebug = 0) = 0; virtual PRInt32 Parse(nsIURL* aURL,nsIStreamObserver* aListener = nsnull,nsIDTDDebug * aDTDDebug = 0) = 0;
virtual PRInt32 Parse(const char* aFilename)=0; virtual PRInt32 Parse(nsIInputStream* pIStream,nsIStreamObserver* aListener,nsIDTDDebug* aDTDDebug = 0)=0;
virtual PRInt32 Parse(nsString& aFilename)=0;
virtual PRInt32 Parse(fstream& aStream)=0; virtual PRInt32 Parse(fstream& aStream)=0;
virtual PRInt32 Parse(nsString& anHTMLString,PRBool appendTokens)=0; virtual PRInt32 Parse(nsString& anHTMLString,PRBool appendTokens)=0;
virtual PRInt32 ResumeParse(void)=0;
/** /**
* This method gets called when the tokens have been consumed, and it's time * This method gets called when the tokens have been consumed, and it's time
* to build the model via the content sink. * to build the model via the content sink.
* @update gess5/11/98 * @update gess5/11/98
* @return YES if model building went well -- NO otherwise. * @return YES if model building went well -- NO otherwise.
*/ */
virtual PRInt32 IterateTokens(void)=0; virtual PRInt32 BuildModel(void)=0;
}; };

Просмотреть файл

@ -26,7 +26,6 @@
#include "prenv.h" //this is here for debug reasons... #include "prenv.h" //this is here for debug reasons...
#include "plstr.h" #include "plstr.h"
#include <fstream.h> #include <fstream.h>
#include "nsIInputStream.h"
#include "nsIParserFilter.h" #include "nsIParserFilter.h"
#include "nsIDTDDebug.h" #include "nsIDTDDebug.h"
#include "nshtmlpars.h" #include "nshtmlpars.h"
@ -47,13 +46,10 @@ static const char* kNullURL = "Error: Null URL given";
static const char* kNullFilename= "Error: Null filename given"; static const char* kNullFilename= "Error: Null filename given";
static const char* kNullTokenizer = "Error: Unable to construct tokenizer"; static const char* kNullTokenizer = "Error: Unable to construct tokenizer";
static const char* kHTMLTextContentType = "text/html"; static const char* kHTMLTextContentType = "text/html";
static nsString kUnknownFilename("unknown");
static const int gTransferBufferSize=4096; //size of the buffer used in moving data from iistream static const int gTransferBufferSize=4096; //size of the buffer used in moving data from iistream
#define DEBUG_SAVE_SOURCE_DOC 1
#ifdef DEBUG_SAVE_SOURCE_DOC
fstream* gTempStream=0;
#endif
/** /**
@ -84,7 +80,7 @@ public:
} }
}; };
CTokenDeallocator gTokenDeallocator; CTokenDeallocator gTokenDeallocator2;
class CDTDDeallocator: public nsDequeFunctor{ class CDTDDeallocator: public nsDequeFunctor{
public: public:
@ -114,6 +110,7 @@ public:
CSharedParserObjects() : mDeallocator(), mDTDDeque(mDeallocator) { CSharedParserObjects() : mDeallocator(), mDTDDeque(mDeallocator) {
} }
~CSharedParserObjects() { ~CSharedParserObjects() {
} }
@ -141,25 +138,13 @@ CSharedParserObjects gSharedParserObjects;
* @param * @param
* @return * @return
*/ */
nsParser::nsParser() : nsParser::nsParser() {
mTokenDeque(gTokenDeallocator),
mSourceType(),
mTargetType()
{
NS_INIT_REFCNT(); NS_INIT_REFCNT();
mDTDDebug = 0; mDTDDebug = 0;
mParserFilter = 0; mParserFilter = 0;
mObserver = 0; mObserver = 0;
mTransferBuffer=0;
mSink=0; mSink=0;
mCurrentPos=0; mParserContext=0;
mMarkPos=0;
mParseMode=eParseMode_unknown;
mURL=0;
mDTD=0;
mScanner=0;
mTransferBuffer=new char[gTransferBufferSize+1];
mAutoDetectStatus=eUnknownDetect;
} }
@ -172,20 +157,12 @@ nsParser::nsParser() :
*/ */
nsParser::~nsParser() { nsParser::~nsParser() {
NS_IF_RELEASE(mObserver); NS_IF_RELEASE(mObserver);
NS_IF_RELEASE(mDTDDebug); // NS_IF_RELEASE(mDTDDebug);
if(mTransferBuffer)
delete [] mTransferBuffer;
mTransferBuffer=0;
NS_RELEASE(mSink); NS_RELEASE(mSink);
if(mCurrentPos)
delete mCurrentPos;
mCurrentPos=0;
if(mScanner)
delete mScanner;
mScanner=0;
NS_IF_RELEASE(mURL);
//don't forget to add code here to delete
//what may be several contexts...
delete mParserContext;
} }
@ -298,7 +275,9 @@ void nsParser::RegisterDTD(nsIDTD* aDTD){
* @return * @return
*/ */
CScanner* nsParser::GetScanner(void){ CScanner* nsParser::GetScanner(void){
return mScanner; if(mParserContext)
return mParserContext->mScanner;
return 0;
} }
/** /**
@ -311,6 +290,7 @@ CScanner* nsParser::GetScanner(void){
eParseMode DetermineParseMode() { eParseMode DetermineParseMode() {
const char* theModeStr= PR_GetEnv("PARSE_MODE"); const char* theModeStr= PR_GetEnv("PARSE_MODE");
const char* other="other"; const char* other="other";
eParseMode result=eParseMode_navigator; eParseMode result=eParseMode_navigator;
if(theModeStr) if(theModeStr)
@ -326,25 +306,23 @@ eParseMode DetermineParseMode() {
* @param * @param
* @return * @return
*/ */
PRBool FindSuitableDTD( eParseMode aMode, PRBool FindSuitableDTD( CParserContext& aParserContext) {
nsString& aSourceType,
nsString& aTargetType,
nsIDTD*& aDefaultDTD) {
//Let's start by tring the defaultDTD, if one exists... //Let's start by tring the defaultDTD, if one exists...
if(aDefaultDTD && (aDefaultDTD->CanParse(aSourceType,0))) if(aParserContext.mDTD && (aParserContext.mDTD->CanParse(aParserContext.mSourceType,0)))
return PR_TRUE; return PR_TRUE;
PRBool result=PR_FALSE; PRBool result=PR_FALSE;
nsDequeIterator b=gSharedParserObjects.mDTDDeque.Begin(); nsDequeIterator b=gSharedParserObjects.mDTDDeque.Begin();
nsDequeIterator e=gSharedParserObjects.mDTDDeque.End(); nsDequeIterator e=gSharedParserObjects.mDTDDeque.End();
while(b<e){ while(b<e){
nsIDTD* theDTD=(nsIDTD*)b.GetCurrent(); nsIDTD* theDTD=(nsIDTD*)b.GetCurrent();
if(theDTD) { if(theDTD) {
result=theDTD->CanParse(aSourceType,0); result=theDTD->CanParse(aParserContext.mSourceType,0);
if(result){ if(result){
aDefaultDTD=theDTD; aParserContext.mDTD=theDTD;
break; break;
} }
} }
@ -371,22 +349,22 @@ eAutoDetectResult nsParser::AutoDetectContentType(nsString& aBuffer,nsString& aT
// recognize the content in the scanner. // recognize the content in the scanner.
// Somebody should say yes, or we can't continue. // Somebody should say yes, or we can't continue.
//This method may change mSourceType and mDTD. //This method may change mSourceType and mParserContext->mDTD.
//It absolutely changes mAutoDetectStatus //It absolutely changes mParserContext->mAutoDetectStatus
nsDequeIterator b=gSharedParserObjects.mDTDDeque.Begin(); nsDequeIterator b=gSharedParserObjects.mDTDDeque.Begin();
nsDequeIterator e=gSharedParserObjects.mDTDDeque.End(); nsDequeIterator e=gSharedParserObjects.mDTDDeque.End();
mAutoDetectStatus=eUnknownDetect; mParserContext->mAutoDetectStatus=eUnknownDetect;
while((b<e) && (eUnknownDetect==mAutoDetectStatus)){ while((b<e) && (eUnknownDetect==mParserContext->mAutoDetectStatus)){
nsIDTD* theDTD=(nsIDTD*)b.GetCurrent(); nsIDTD* theDTD=(nsIDTD*)b.GetCurrent();
if(theDTD) { if(theDTD) {
mAutoDetectStatus=theDTD->AutoDetectContentType(aBuffer,aType); mParserContext->mAutoDetectStatus=theDTD->AutoDetectContentType(aBuffer,aType);
} }
b++; b++;
} }
return mAutoDetectStatus; return mParserContext->mAutoDetectStatus;
} }
@ -401,27 +379,18 @@ eAutoDetectResult nsParser::AutoDetectContentType(nsString& aBuffer,nsString& aT
* @param * @param
* @return * @return
*/ */
PRInt32 nsParser::WillBuildModel(const char* aFilename){ PRInt32 nsParser::WillBuildModel(nsString& aFilename){
mMajorIteration=-1; mParserContext->mMajorIteration=-1;
mMinorIteration=-1; mParserContext->mMinorIteration=-1;
mParseMode=DetermineParseMode(); mParserContext->mParseMode=DetermineParseMode();
if(PR_TRUE==FindSuitableDTD(mParseMode,mSourceType,mTargetType,mDTD)) { if(PR_TRUE==FindSuitableDTD(*mParserContext)) {
mDTD->SetParser(this); mParserContext->mDTD->SetParser(this);
mDTD->SetContentSink(mSink); mParserContext->mDTD->SetContentSink(mSink);
mDTD->WillBuildModel(aFilename); mParserContext->mDTD->WillBuildModel(aFilename);
} }
#ifdef DEBUG_SAVE_SOURCE_DOC
#if defined(XP_UNIX) && (defined(IRIX) || defined(MKLINUX))
/* XXX: IRIX does not support ios::binary */
gTempStream =new fstream("/tmp/out.html",ios::out);
#else
gTempStream = new fstream("c:/temp/out.html",ios::out|ios::binary);
#endif
#endif
return kNoError; return kNoError;
} }
@ -434,18 +403,10 @@ PRInt32 nsParser::WillBuildModel(const char* aFilename){
PRInt32 nsParser::DidBuildModel(PRInt32 anErrorCode) { PRInt32 nsParser::DidBuildModel(PRInt32 anErrorCode) {
//One last thing...close any open containers. //One last thing...close any open containers.
PRInt32 result=anErrorCode; PRInt32 result=anErrorCode;
if(mDTD) { if(mParserContext->mDTD) {
result=mDTD->DidBuildModel(anErrorCode); result=mParserContext->mDTD->DidBuildModel(anErrorCode);
} }
#ifdef DEBUG_SAVE_SOURCE_DOC
if(gTempStream) {
gTempStream->close();
delete gTempStream;
gTempStream=0;
}
#endif
return result; return result;
} }
@ -460,22 +421,21 @@ PRInt32 nsParser::DidBuildModel(PRInt32 anErrorCode) {
* @param aFilename -- const char* containing file to be parsed. * @param aFilename -- const char* containing file to be parsed.
* @return PR_TRUE if parse succeeded, PR_FALSE otherwise. * @return PR_TRUE if parse succeeded, PR_FALSE otherwise.
*/ */
PRBool nsParser::Parse(const char* aFilename){ PRInt32 nsParser::Parse(nsString& aFilename){
NS_PRECONDITION(0!=aFilename,kNullFilename);
PRInt32 status=kBadFilename; PRInt32 status=kBadFilename;
if(aFilename) { if(aFilename) {
//ok, time to create our tokenizer and begin the process //ok, time to create our tokenizer and begin the process
mTargetType=kHTMLTextContentType;
mScanner=new CScanner(aFilename,mParseMode); mParserContext = new CParserContext(new CScanner(aFilename),mParserContext);
if(mScanner) { mParserContext->mScanner->Eof();
mScanner->Eof(); if(eValidDetect==AutoDetectContentType(mParserContext->mScanner->GetBuffer(),
if(eValidDetect==AutoDetectContentType(mScanner->GetBuffer(),mSourceType)) { mParserContext->mSourceType))
WillBuildModel(aFilename); {
status=ResumeParse(); WillBuildModel(aFilename);
DidBuildModel(status); status=ResumeParse();
} DidBuildModel(status);
} //if } //if
} }
return status; return status;
@ -488,11 +448,35 @@ PRBool nsParser::Parse(const char* aFilename){
* @return TRUE if all went well -- FALSE otherwise * @return TRUE if all went well -- FALSE otherwise
*/ */
PRInt32 nsParser::Parse(fstream& aStream){ PRInt32 nsParser::Parse(fstream& aStream){
PRInt32 result=0;
return result; PRInt32 status=kNoError;
//ok, time to create our tokenizer and begin the process
mParserContext = new CParserContext(new CScanner(kUnknownFilename,aStream,PR_FALSE),mParserContext);
mParserContext->mScanner->Eof();
if(eValidDetect==AutoDetectContentType(mParserContext->mScanner->GetBuffer(),
mParserContext->mSourceType)) {
WillBuildModel(mParserContext->mScanner->GetFilename());
status=ResumeParse();
DidBuildModel(status);
} //if
return status;
} }
/**
*
* @update gess7/13/98
* @param
* @return
*/
PRInt32 nsParser::Parse(nsIInputStream* pIStream,nsIStreamObserver* aListener,nsIDTDDebug* aDTDDebug){
PRInt32 result=kNoError;
return result;
}
/** /**
* This is the main controlling routine in the parsing process. * This is the main controlling routine in the parsing process.
* Note that it may get called multiple times for the same scanner, * Note that it may get called multiple times for the same scanner,
@ -512,19 +496,14 @@ PRInt32 nsParser::Parse(nsIURL* aURL,nsIStreamObserver* aListener, nsIDTDDebug *
PRInt32 status=kBadURL; PRInt32 status=kBadURL;
/* Disable DTD Debug for now...
mDTDDebug = aDTDDebug; mDTDDebug = aDTDDebug;
NS_IF_ADDREF(mDTDDebug); NS_IF_ADDREF(mDTDDebug);
*/
NS_IF_RELEASE(mURL);
mURL = aURL;
NS_IF_ADDREF(mURL);
NS_IF_RELEASE(mObserver);
mObserver = aListener;
NS_IF_ADDREF(mObserver);
if(mURL) { if(aURL) {
mScanner=new CScanner(mParseMode); nsAutoString theName(aURL->GetSpec());
mParserContext=new CParserContext(new CScanner(theName,PR_FALSE),mParserContext,aListener);
status=NS_OK; status=NS_OK;
} }
return status; return status;
@ -533,6 +512,8 @@ PRInt32 nsParser::Parse(nsIURL* aURL,nsIStreamObserver* aListener, nsIDTDDebug *
/** /**
* Call this method if all you want to do is parse 1 string full of HTML text. * Call this method if all you want to do is parse 1 string full of HTML text.
* In particular, this method should be called by the DOM when it has an HTML
* string to feed to the parser in real-time.
* *
* @update gess5/11/98 * @update gess5/11/98
* @param anHTMLString contains a string-full of real HTML * @param anHTMLString contains a string-full of real HTML
@ -542,11 +523,10 @@ PRInt32 nsParser::Parse(nsIURL* aURL,nsIStreamObserver* aListener, nsIDTDDebug *
PRInt32 nsParser::Parse(nsString& aSourceBuffer,PRBool appendTokens){ PRInt32 nsParser::Parse(nsString& aSourceBuffer,PRBool appendTokens){
PRInt32 result=kNoError; PRInt32 result=kNoError;
mTargetType=kHTMLTextContentType; mParserContext = new CParserContext(new CScanner(kUnknownFilename),mParserContext,0);
mScanner=new CScanner(); mParserContext->mScanner->Append(aSourceBuffer);
mScanner->Append(aSourceBuffer); if(eValidDetect==AutoDetectContentType(aSourceBuffer,mParserContext->mSourceType)) {
if(eValidDetect==AutoDetectContentType(aSourceBuffer,mSourceType)) { WillBuildModel(mParserContext->mScanner->GetFilename());
WillBuildModel("");
result=ResumeParse(); result=ResumeParse();
DidBuildModel(result); DidBuildModel(result);
} }
@ -567,12 +547,12 @@ PRInt32 nsParser::Parse(nsString& aSourceBuffer,PRBool appendTokens){
PRInt32 nsParser::ResumeParse() { PRInt32 nsParser::ResumeParse() {
PRInt32 result=kNoError; PRInt32 result=kNoError;
mDTD->WillResumeParse(); mParserContext->mDTD->WillResumeParse();
if(kNoError==result) { if(kNoError==result) {
result=Tokenize(); result=Tokenize();
if(kInterrupted==result) if(kInterrupted==result)
mDTD->WillInterruptParse(); mParserContext->mDTD->WillInterruptParse();
IterateTokens(); BuildModel();
} }
return result; return result;
} }
@ -585,26 +565,28 @@ PRInt32 nsParser::ResumeParse() {
* @param * @param
* @return PR_TRUE if parse succeeded, PR_FALSE otherwise. * @return PR_TRUE if parse succeeded, PR_FALSE otherwise.
*/ */
PRInt32 nsParser::IterateTokens() { PRInt32 nsParser::BuildModel() {
nsDequeIterator e=mTokenDeque.End();
nsDequeIterator e=mParserContext->mTokenDeque.End();
nsDequeIterator theMarkPos(e); nsDequeIterator theMarkPos(e);
mMajorIteration++;
if(!mCurrentPos) // mParserContext->mMajorIteration++;
mCurrentPos=new nsDequeIterator(mTokenDeque.Begin());
if(!mParserContext->mCurrentPos)
mParserContext->mCurrentPos=new nsDequeIterator(mParserContext->mTokenDeque.Begin());
PRInt32 result=kNoError; PRInt32 result=kNoError;
while((kNoError==result) && ((*mCurrentPos<e))){ while((kNoError==result) && ((*mParserContext->mCurrentPos<e))){
mMinorIteration++; mParserContext->mMinorIteration++;
CToken* theToken=(CToken*)mCurrentPos->GetCurrent(); CToken* theToken=(CToken*)mParserContext->mCurrentPos->GetCurrent();
theMarkPos=*mCurrentPos; theMarkPos=*mParserContext->mCurrentPos;
result=mDTD->HandleToken(theToken); result=mParserContext->mDTD->HandleToken(theToken);
++(*mCurrentPos); ++(*mParserContext->mCurrentPos);
} }
if(kInterrupted==result) if(kInterrupted==result)
*mCurrentPos=theMarkPos; *mParserContext->mCurrentPos=theMarkPos;
return result; return result;
} }
@ -619,17 +601,17 @@ PRInt32 nsParser::IterateTokens() {
* @return error code (should be 0) * @return error code (should be 0)
*/ */
PRInt32 nsParser::CollectAttributes(nsCParserNode& aNode,PRInt32 aCount){ PRInt32 nsParser::CollectAttributes(nsCParserNode& aNode,PRInt32 aCount){
nsDequeIterator end=mTokenDeque.End(); nsDequeIterator end=mParserContext->mTokenDeque.End();
int attr=0; int attr=0;
for(attr=0;attr<aCount;attr++) { for(attr=0;attr<aCount;attr++) {
if(*mCurrentPos<end) { if(*mParserContext->mCurrentPos<end) {
CToken* tkn=(CToken*)(++(*mCurrentPos)); CToken* tkn=(CToken*)(++(*mParserContext->mCurrentPos));
if(tkn){ if(tkn){
if(eToken_attribute==eHTMLTokenTypes(tkn->GetTokenType())){ if(eToken_attribute==eHTMLTokenTypes(tkn->GetTokenType())){
aNode.AddAttribute(tkn); aNode.AddAttribute(tkn);
} }
else (*mCurrentPos)--; else (*mParserContext->mCurrentPos)--;
} }
else return kInterrupted; else return kInterrupted;
} }
@ -649,18 +631,18 @@ PRInt32 nsParser::CollectAttributes(nsCParserNode& aNode,PRInt32 aCount){
*/ */
PRInt32 nsParser::CollectSkippedContent(nsCParserNode& aNode,PRInt32& aCount) { PRInt32 nsParser::CollectSkippedContent(nsCParserNode& aNode,PRInt32& aCount) {
eHTMLTokenTypes subtype=eToken_attribute; eHTMLTokenTypes subtype=eToken_attribute;
nsDequeIterator end=mTokenDeque.End(); nsDequeIterator end=mParserContext->mTokenDeque.End();
PRInt32 result=kNoError; PRInt32 result=kNoError;
aCount=0; aCount=0;
while((*mCurrentPos!=end) && (eToken_attribute==subtype)) { while((*mParserContext->mCurrentPos!=end) && (eToken_attribute==subtype)) {
CToken* tkn=(CToken*)(++(*mCurrentPos)); CToken* tkn=(CToken*)(++(*mParserContext->mCurrentPos));
subtype=eHTMLTokenTypes(tkn->GetTokenType()); subtype=eHTMLTokenTypes(tkn->GetTokenType());
if(eToken_skippedcontent==subtype) { if(eToken_skippedcontent==subtype) {
aNode.SetSkippedContent(tkn); aNode.SetSkippedContent(tkn);
aCount++; aCount++;
} }
else (*mCurrentPos)--; else (*mParserContext->mCurrentPos)--;
} }
return result; return result;
} }
@ -710,10 +692,9 @@ nsresult nsParser::OnStartBinding(const char *aSourceType){
if (nsnull != mObserver) { if (nsnull != mObserver) {
mObserver->OnStartBinding(aSourceType); mObserver->OnStartBinding(aSourceType);
} }
mAutoDetectStatus=eUnknownDetect; mParserContext->mAutoDetectStatus=eUnknownDetect;
mDTD=0; mParserContext->mDTD=0;
mParserContext->mSourceType=aSourceType;
mSourceType=aSourceType;
return kNoError; return kNoError;
} }
@ -732,37 +713,33 @@ nsresult nsParser::OnDataAvailable(nsIInputStream *pIStream, PRInt32 length){
mListener->OnDataAvailable(pIStream, length); mListener->OnDataAvailable(pIStream, length);
} }
*/ */
int len=0;
int offset=0;
if(eInvalidDetect==mAutoDetectStatus) { if(eInvalidDetect==mParserContext->mAutoDetectStatus) {
if(mScanner) { if(mParserContext->mScanner) {
mScanner->GetBuffer().Truncate(); mParserContext->mScanner->GetBuffer().Truncate();
} }
} }
do { int len=1; //init to a non-zero value
PRInt32 err; int err;
len = pIStream->Read(&err, mTransferBuffer, 0, gTransferBufferSize); int offset=0;
if(len>0) {
#ifdef DEBUG_SAVE_SOURCE_DOC while (len > 0) {
if(gTempStream) { len = pIStream->Read(&err, mParserContext->mTransferBuffer, 0, mParserContext->eTransferBufferSize);
gTempStream->write(mTransferBuffer,len); if(len>0) {
}
#endif
if (mParserFilter) if(mParserFilter)
mParserFilter->RawBuffer(mTransferBuffer, &len); mParserFilter->RawBuffer(mParserContext->mTransferBuffer, &len);
mScanner->Append(mTransferBuffer,len);
if(eUnknownDetect==mAutoDetectStatus) { mParserContext->mScanner->Append(mParserContext->mTransferBuffer,len);
if(eValidDetect==AutoDetectContentType(mScanner->GetBuffer(),mSourceType)) {
nsresult result=WillBuildModel(mURL->GetSpec()); if(eUnknownDetect==mParserContext->mAutoDetectStatus) {
} //if if(eValidDetect==AutoDetectContentType(mParserContext->mScanner->GetBuffer(),mParserContext->mSourceType)) {
} nsresult result=WillBuildModel(mParserContext->mScanner->GetFilename());
} //if } //if
} while (len > 0); }
} //if
}
nsresult result=ResumeParse(); nsresult result=ResumeParse();
return result; return result;
@ -797,7 +774,7 @@ nsresult nsParser::OnStopBinding(PRInt32 status, const nsString& aMsg){
* @return new token or null * @return new token or null
*/ */
PRInt32 nsParser::ConsumeToken(CToken*& aToken) { PRInt32 nsParser::ConsumeToken(CToken*& aToken) {
PRInt32 result=mDTD->ConsumeToken(aToken); PRInt32 result=mParserContext->mDTD->ConsumeToken(aToken);
return result; return result;
} }
@ -811,39 +788,11 @@ PRInt32 nsParser::ConsumeToken(CToken*& aToken) {
* @param * @param
* @return TRUE if it's ok to proceed * @return TRUE if it's ok to proceed
*/ */
PRBool nsParser::WillTokenize(void){ PRBool nsParser::WillTokenize(){
PRBool result=PR_TRUE; PRBool result=PR_TRUE;
return result; return result;
} }
/**
*
* @update gess 3/25/98
* @return TRUE if it's ok to proceed
*/
PRInt32 nsParser::Tokenize(nsString& aSourceBuffer,PRBool appendTokens){
CToken* theToken=0;
PRInt32 result=kNoError;
PRInt32 debugCounter=0; //this can be removed. It's only for debugging...
WillTokenize();
while(kNoError==result) {
debugCounter++;
result=ConsumeToken(theToken);
if(theToken && (kNoError==result)) {
#ifdef VERBOSE_DEBUG
theToken->DebugDumpToken(cout);
#endif
mTokenDeque.Push(theToken);
}
}
if(kEOF==result)
result=kNoError;
DidTokenize();
return result;
}
/** /**
* This is the primary control routine. It iteratively * This is the primary control routine. It iteratively
@ -853,14 +802,14 @@ PRInt32 nsParser::Tokenize(nsString& aSourceBuffer,PRBool appendTokens){
* @update gess 3/25/98 * @update gess 3/25/98
* @return error code * @return error code
*/ */
PRInt32 nsParser::Tokenize(void) { PRInt32 nsParser::Tokenize(){
CToken* theToken=0; CToken* theToken=0;
PRInt32 result=kNoError; PRInt32 result=kNoError;
PRBool done=(0==mMajorIteration) ? (!WillTokenize()) : PR_FALSE; PRBool done=(0==++mParserContext->mMajorIteration) ? (!WillTokenize()) : PR_FALSE;
while((PR_FALSE==done) && (kNoError==result)) { while((PR_FALSE==done) && (kNoError==result)) {
mScanner->Mark(); mParserContext->mScanner->Mark();
result=ConsumeToken(theToken); result=ConsumeToken(theToken);
if(kNoError==result) { if(kNoError==result) {
if(theToken) { if(theToken) {
@ -868,14 +817,14 @@ PRInt32 nsParser::Tokenize(void) {
#ifdef VERBOSE_DEBUG #ifdef VERBOSE_DEBUG
theToken->DebugDumpToken(cout); theToken->DebugDumpToken(cout);
#endif #endif
mTokenDeque.Push(theToken); mParserContext->mTokenDeque.Push(theToken);
} }
} }
else { else {
if(theToken) if(theToken)
delete theToken; delete theToken;
mScanner->RewindToMark(); mParserContext->mScanner->RewindToMark();
} }
} }
if((PR_TRUE==done) && (kInterrupted!=result)) if((PR_TRUE==done) && (kInterrupted!=result))
@ -892,7 +841,7 @@ PRInt32 nsParser::Tokenize(void) {
* @param * @param
* @return TRUE if all went well * @return TRUE if all went well
*/ */
PRBool nsParser::DidTokenize(void) { PRBool nsParser::DidTokenize(){
PRBool result=PR_TRUE; PRBool result=PR_TRUE;
#ifdef VERBOSE_DEBUG #ifdef VERBOSE_DEBUG
@ -912,8 +861,8 @@ PRBool nsParser::DidTokenize(void) {
* @return * @return
*/ */
void nsParser::DebugDumpTokens(ostream& out) { void nsParser::DebugDumpTokens(ostream& out) {
nsDequeIterator b=mTokenDeque.Begin(); nsDequeIterator b=mParserContext->mTokenDeque.Begin();
nsDequeIterator e=mTokenDeque.End(); nsDequeIterator e=mParserContext->mTokenDeque.End();
CToken* theToken; CToken* theToken;
while(b!=e) { while(b!=e) {
@ -933,8 +882,8 @@ void nsParser::DebugDumpTokens(ostream& out) {
* @return * @return
*/ */
void nsParser::DebugDumpSource(ostream& out) { void nsParser::DebugDumpSource(ostream& out) {
nsDequeIterator b=mTokenDeque.Begin(); nsDequeIterator b=mParserContext->mTokenDeque.Begin();
nsDequeIterator e=mTokenDeque.End(); nsDequeIterator e=mParserContext->mTokenDeque.End();
CToken* theToken; CToken* theToken;
while(b!=e) { while(b!=e) {

Просмотреть файл

@ -60,7 +60,7 @@
#include "nsParserNode.h" #include "nsParserNode.h"
#include "nsParserTypes.h" #include "nsParserTypes.h"
#include "nsIURL.h" #include "nsIURL.h"
#include "CParserContext.h"
#define NS_PARSER_IID \ #define NS_PARSER_IID \
{0x2ce606b0, 0xbee6, 0x11d1, \ {0x2ce606b0, 0xbee6, 0x11d1, \
@ -69,7 +69,6 @@
class IContentSink; class IContentSink;
class nsIHTMLContentSink; class nsIHTMLContentSink;
class nsIURL;
class nsIDTD; class nsIDTD;
class nsIDTDDebug; class nsIDTDDebug;
class CScanner; class CScanner;
@ -119,14 +118,26 @@ friend class CTokenHandler;
virtual CScanner* GetScanner(void); virtual CScanner* GetScanner(void);
/** /**
* Cause parser to parse input from given URL in given mode * Cause parser to parse input from given URL
* @update gess5/11/98 * @update gess5/11/98
* @param aURL is a descriptor for source document * @param aURL is a descriptor for source document
* @param aListener is a listener to forward notifications to * @param aListener is a listener to forward notifications to
* @return TRUE if all went well -- FALSE otherwise * @return TRUE if all went well -- FALSE otherwise
*/ */
virtual PRInt32 Parse(nsIURL* aURL, virtual PRInt32 Parse(nsIURL* aURL,
nsIStreamObserver* aListener, nsIDTDDebug * aDTDDebug = 0); nsIStreamObserver* aListener,
nsIDTDDebug* aDTDDebug = 0);
/**
* Cause parser to parse input from given nsIInputStream
* @update gess5/11/98
* @param pIStream is an nsIInputStream
* @param aListener is a listener to forward notifications to
* @return TRUE if all went well -- FALSE otherwise
*/
virtual PRInt32 Parse(nsIInputStream* pIStream,
nsIStreamObserver* aListener,
nsIDTDDebug* aDTDDebug = 0);
/** /**
* Cause parser to parse input from given file in given mode * Cause parser to parse input from given file in given mode
@ -134,7 +145,7 @@ friend class CTokenHandler;
* @param aFilename is a path for file document * @param aFilename is a path for file document
* @return TRUE if all went well -- FALSE otherwise * @return TRUE if all went well -- FALSE otherwise
*/ */
virtual PRInt32 Parse(const char* aFilename); virtual PRInt32 Parse(nsString& aFilename);
/** /**
* Cause parser to parse input from given stream * Cause parser to parse input from given stream
@ -157,7 +168,7 @@ friend class CTokenHandler;
* @update gess5/11/98 * @update gess5/11/98
* @return TRUE if all went well, otherwise FALSE * @return TRUE if all went well, otherwise FALSE
*/ */
virtual PRInt32 ResumeParse(void); virtual PRInt32 ResumeParse();
/** /**
* Causes the parser to scan foward, collecting nearby (sequential) * Causes the parser to scan foward, collecting nearby (sequential)
@ -208,7 +219,7 @@ protected:
* @param * @param
* @return * @return
*/ */
PRInt32 WillBuildModel(const char* aFilename=0); PRInt32 WillBuildModel(nsString& aFilename);
/** /**
* *
@ -224,7 +235,7 @@ protected:
* @update gess5/11/98 * @update gess5/11/98
* @return YES if model building went well -- NO otherwise. * @return YES if model building went well -- NO otherwise.
*/ */
virtual PRInt32 IterateTokens(void); virtual PRInt32 BuildModel(void);
private: private:
@ -251,15 +262,9 @@ private:
* @param * @param
* @return TRUE if it's ok to proceed * @return TRUE if it's ok to proceed
*/ */
PRBool WillTokenize(void); PRBool WillTokenize();
/**
*
* @update gess 3/25/98
* @return TRUE if it's ok to proceed
*/
PRInt32 Tokenize(nsString& aSourceBuffer,PRBool appendTokens);
/** /**
* This is the primary control routine. It iteratively * This is the primary control routine. It iteratively
* consumes tokens until an error occurs or you run out * consumes tokens until an error occurs or you run out
@ -268,7 +273,7 @@ private:
* @update gess 3/25/98 * @update gess 3/25/98
* @return error code * @return error code
*/ */
PRInt32 Tokenize(void); PRInt32 Tokenize();
/** /**
* This is the tail-end of the code sandwich for the * This is the tail-end of the code sandwich for the
@ -279,7 +284,7 @@ private:
* @param * @param
* @return TRUE if all went well * @return TRUE if all went well
*/ */
PRBool DidTokenize(void); PRBool DidTokenize();
/** /**
* This debug routine is used to cause the tokenizer to * This debug routine is used to cause the tokenizer to
@ -311,27 +316,42 @@ protected:
// And now, some data members... // And now, some data members...
//********************************************* //*********************************************
nsIStreamObserver* mObserver; /*****************************************************
nsIContentSink* mSink; All of these moved into the parse-context object:
nsIParserFilter* mParserFilter;
nsDequeIterator* mCurrentPos;
nsDequeIterator* mMarkPos;
nsIDTD* mDTD;
eParseMode mParseMode;
char* mTransferBuffer;
PRInt32 mMajorIteration; PRInt32 mMajorIteration;
PRInt32 mMinorIteration; PRInt32 mMinorIteration;
nsDeque mTokenDeque;
CScanner* mScanner;
nsIURL* mURL; nsIURL* mURL;
nsIDTDDebug* mDTDDebug;
nsString mSourceType; nsString mSourceType;
nsString mTargetType; nsString mTargetType;
eAutoDetectResult mAutoDetectStatus; eAutoDetectResult mAutoDetectStatus;
nsDequeIterator* mCurrentPos;
nsDequeIterator* mMarkPos;
nsDeque mTokenDeque;
CScanner* mScanner;
nsIDTD* mDTD;
eParseMode mParseMode;
char* mTransferBuffer;
*****************************************************/
CParserContext* mParserContext;
/*****************************************************
The above fields are moving into parse-context
*****************************************************/
nsIStreamObserver* mObserver;
nsIContentSink* mSink;
nsIParserFilter* mParserFilter;
nsIDTDDebug* mDTDDebug;
}; };

Просмотреть файл

@ -19,10 +19,8 @@
//#define __INCREMENTAL 1 //#define __INCREMENTAL 1
#include "nsScanner.h" #include "nsScanner.h"
#include "nsIURL.h"
#include "nsDebug.h" #include "nsDebug.h"
const char* gURLRef=0;
const char* kBadHTMLText="<H3>Oops...</H3>You just tried to read a non-existent document: <BR>"; const char* kBadHTMLText="<H3>Oops...</H3>You just tried to read a non-existent document: <BR>";
#ifdef __INCREMENTAL #ifdef __INCREMENTAL
@ -31,89 +29,55 @@ const int kBufsize=1;
const int kBufsize=64; const int kBufsize=64;
#endif #endif
/** /**
* Use this constructor if you want an incremental (callback) * Use this constructor if you want i/o to be based on an
* based input stream. * incremental netstream. If you pass a null filename, you
* can still provide data to the scanner via append.
* *
* @update gess 5/12/98 * @update gess 5/12/98
* @param aMode represents the parser mode (nav, other) * @param aFilename --
* @return * @return
*/ */
CScanner::CScanner(eParseMode aMode) : mBuffer("") { CScanner::CScanner(nsString& aFilename,PRBool aCreateStream) :
mBuffer(""), mFilename(aFilename)
{
mOffset=0; mOffset=0;
mMarkPos=-1; mMarkPos=-1;
mTotalRead=0; mTotalRead=0;
mParseMode=aMode; mOwnsStream=aCreateStream;
mNetStream=0;
mFileStream=0; mFileStream=0;
mIncremental=PR_TRUE; if(aCreateStream) {
mOwnsStream=PR_TRUE; char buffer[513];
aFilename.ToCString(buffer,sizeof(buffer)-1);
#if defined(XP_UNIX) && (defined(IRIX) || defined(MKLINUX))
/* XXX: IRIX does not support ios::binary */
mFileStream=new fstream(buffer,ios::in);
#else
mFileStream=new fstream(buffer,ios::in|ios::binary);
#endif
} //if
} }
/** /**
* Use this constructor if you want i/o to be file based. * Use this constructor if you want i/o to be stream based.
* *
* @update gess 5/12/98 * @update gess 5/12/98
* @param aMode represents the parser mode (nav, other) * @param aStream --
* @param assumeOwnership --
* @param aFilename --
* @return * @return
*/ */
CScanner::CScanner(const char* aFilename,eParseMode aMode) : mBuffer("") { CScanner::CScanner(nsString& aFilename,fstream& aStream,PRBool assumeOwnership) :
NS_ASSERTION(0!=aFilename,"Error: Null filename!"); mBuffer(""), mFilename(aFilename)
{
mOffset=0; mOffset=0;
mMarkPos=-1; mMarkPos=-1;
mTotalRead=0; mTotalRead=0;
mParseMode=aMode; mOwnsStream=assumeOwnership;
mNetStream=0;
mIncremental=PR_FALSE;
mOwnsStream=PR_TRUE;
#if defined(XP_UNIX) && (defined(IRIX) || defined(MKLINUX))
/* XXX: IRIX does not support ios::binary */
mFileStream=new fstream(aFilename,ios::in);
#else
mFileStream=new fstream(aFilename,ios::in|ios::binary);
#endif
}
/**
* Use this constructor if you want i/o to be file based.
*
* @update gess 5/12/98
* @param aMode represents the parser mode (nav, other)
* @return
*/
CScanner::CScanner(fstream& aStream,eParseMode aMode) : mBuffer("") {
mOffset=0;
mMarkPos=-1;
mTotalRead=0;
mParseMode=aMode;
mNetStream=0;
mIncremental=PR_FALSE;
mOwnsStream=PR_FALSE;
mFileStream=&aStream; mFileStream=&aStream;
} }
/**
* Use this constructor if you want i/o to be based on a
* non-incremental netstream.
*
* @update gess 5/12/98
* @param aMode represents the parser mode (nav, other)
* @return
*/
CScanner::CScanner(nsIURL* aURL,eParseMode aMode) : mBuffer("") {
NS_ASSERTION(0!=aURL,"Error: Null URL!");
mOffset=0;
mMarkPos=-1;
mTotalRead=0;
mParseMode=aMode;
mFileStream=0;
PRInt32 error=0;
mIncremental=PR_FALSE;
mNetStream=aURL->Open(&error);
gURLRef=aURL->GetSpec();
mOwnsStream=PR_FALSE;
}
/** /**
* default destructor * default destructor
@ -128,13 +92,7 @@ CScanner::~CScanner() {
if(mOwnsStream) if(mOwnsStream)
delete mFileStream; delete mFileStream;
} }
else if(mNetStream) {
mNetStream->Close();
mNetStream->Release();
}
mFileStream=0; mFileStream=0;
mNetStream=0;
gURLRef=0;
} }
/** /**
@ -200,34 +158,9 @@ void _PreCompressBuffer(nsString& aBuffer,PRInt32& anOffset,PRInt32& aMarkPos){
} }
/**
* This method should only be called by the parser when
* we're doing incremental i/o over the net.
*
* @update gess 5/12/98
* @param aBuffer contains next blob of i/o data
* @param aSize contains size of buffer
* @return 0 if all went well, otherwise error code.
*/
PRInt32 CScanner::IncrementalAppend(const char* aBuffer,PRInt32 aSize){
NS_ASSERTION(((!mFileStream) && (!mNetStream)),"Error: Should only be called during incremental net i/o!");
PRInt32 result=0;
if((!mFileStream) && (!mNetStream)) {
_PreCompressBuffer(mBuffer,mOffset,mMarkPos);
//now that the buffer is (possibly) shortened, let's append the new data.
if(0<aSize) {
mBuffer.Append(aBuffer,aSize);
mTotalRead+=aSize;
}
}
return result;
}
/** /**
* Grab data from underlying stream. * Append data to our underlying input buffer as
* if it were read from an input stream.
* *
* @update gess4/3/98 * @update gess4/3/98
* @return error code * @return error code
@ -235,6 +168,7 @@ PRInt32 CScanner::IncrementalAppend(const char* aBuffer,PRInt32 aSize){
PRBool CScanner::Append(nsString& aBuffer) { PRBool CScanner::Append(nsString& aBuffer) {
_PreCompressBuffer(mBuffer,mOffset,mMarkPos); _PreCompressBuffer(mBuffer,mOffset,mMarkPos);
mBuffer.Append(aBuffer); mBuffer.Append(aBuffer);
mTotalRead+=aBuffer.Length();
return PR_TRUE; return PR_TRUE;
} }
@ -248,6 +182,7 @@ PRBool CScanner::Append(nsString& aBuffer) {
PRBool CScanner::Append(const char* aBuffer, PRInt32 aLen){ PRBool CScanner::Append(const char* aBuffer, PRInt32 aLen){
_PreCompressBuffer(mBuffer,mOffset,mMarkPos); _PreCompressBuffer(mBuffer,mOffset,mMarkPos);
mBuffer.Append(aBuffer,aLen); mBuffer.Append(aBuffer,aLen);
mTotalRead+=aLen;
return PR_TRUE; return PR_TRUE;
} }
@ -262,18 +197,18 @@ PRInt32 CScanner::FillBuffer(void) {
_PreCompressBuffer(mBuffer,mOffset,mMarkPos); _PreCompressBuffer(mBuffer,mOffset,mMarkPos);
if((!mIncremental) && (!mNetStream) && (!mFileStream)) { if(!mFileStream) {
//This is DEBUG code!!!!!! XXX DEBUG XXX //This is DEBUG code!!!!!! XXX DEBUG XXX
//If you're here, it means someone tried to load a //If you're here, it means someone tried to load a
//non-existent document. So as a favor, we emit a //non-existent document. So as a favor, we emit a
//little bit of HTML explaining the error. //little bit of HTML explaining the error.
if(0==mTotalRead) { if(0==mTotalRead) {
mBuffer.Append((const char*)kBadHTMLText); mBuffer.Append((const char*)kBadHTMLText);
mBuffer.Append((const char*)gURLRef); mBuffer.Append(mFilename);
} }
else return 0; else return kInterrupted;
} }
else if(!mIncremental) { else {
PRInt32 numread=0; PRInt32 numread=0;
char buf[kBufsize+1]; char buf[kBufsize+1];
buf[kBufsize]=0; buf[kBufsize]=0;
@ -282,17 +217,11 @@ PRInt32 CScanner::FillBuffer(void) {
mFileStream->read(buf,kBufsize); mFileStream->read(buf,kBufsize);
numread=mFileStream->gcount(); numread=mFileStream->gcount();
} }
else if(mNetStream) {
numread=mNetStream->Read(&anError,buf,0,kBufsize);
if(1==anError)
anError=kEOF;
}
mOffset=mBuffer.Length(); mOffset=mBuffer.Length();
if((0<numread) && (0==anError)) if((0<numread) && (0==anError))
mBuffer.Append((const char*)buf,numread); mBuffer.Append((const char*)buf,numread);
mTotalRead+=mBuffer.Length(); mTotalRead+=mBuffer.Length();
} }
else anError=kInterrupted;
return anError; return anError;
} }
@ -308,9 +237,7 @@ PRInt32 CScanner::Eof() {
PRInt32 theError=0; PRInt32 theError=0;
if(mOffset>=mBuffer.Length()) { if(mOffset>=mBuffer.Length()) {
if(!mIncremental) theError=FillBuffer();
theError=FillBuffer();
else return kInterrupted;
} }
if(0==theError) if(0==theError)
@ -451,21 +378,21 @@ PRInt32 CScanner::SkipPast(nsString& aValidSet){
* @return error code * @return error code
*/ */
PRInt32 CScanner::ReadWhile(nsString& aString,nsString& aValidSet,PRBool addTerminal){ PRInt32 CScanner::ReadWhile(nsString& aString,nsString& aValidSet,PRBool addTerminal){
PRUnichar ch=0; PRUnichar theChar=0;
PRInt32 result=kNoError; PRInt32 result=kNoError;
PRInt32 wrPos=0; PRInt32 wrPos=0;
while(kNoError==result) { while(kNoError==result) {
result=GetChar(ch); result=GetChar(theChar);
if(kNoError==result) { if(kNoError==result) {
PRInt32 pos=aValidSet.Find(ch); PRInt32 pos=aValidSet.Find(theChar);
if(kNotFound==pos) { if(kNotFound==pos) {
if(addTerminal) if(addTerminal)
aString+=ch; aString+=theChar;
else PutBack(ch); else PutBack(theChar);
break; break;
} }
else aString+=ch; else aString+=theChar;
} }
} }
return result; return result;
@ -535,6 +462,18 @@ nsString& CScanner::GetBuffer(void) {
return mBuffer; return mBuffer;
} }
/**
* Retrieve the name of the file that the scanner is reading from.
* In some cases, it's just a given name, because the scanner isn't
* really reading from a file.
*
* @update gess 5/12/98
* @return
*/
nsString& CScanner::GetFilename(void) {
return mFilename;
}
/** /**
* Conduct self test. Actually, selftesting for this class * Conduct self test. Actually, selftesting for this class
* occurs in the parser selftest. * occurs in the parser selftest.

Просмотреть файл

@ -35,43 +35,21 @@
#include "nsString.h" #include "nsString.h"
#include "nsParserTypes.h" #include "nsParserTypes.h"
#include "prtypes.h" #include "prtypes.h"
#include "nsIInputStream.h"
#include <fstream.h> #include <fstream.h>
class nsIURL;
//class ifstream;
class CScanner { class CScanner {
public: public:
/** /**
* Use this constructor if you want an incremental (callback) * Use this constructor if you want i/o to be based on
* based input stream. * a file (therefore a stream) or just data you provide via Append().
* *
* @update gess 5/12/98 * @update gess 5/12/98
* @param aMode represents the parser mode (nav, other) * @param aMode represents the parser mode (nav, other)
* @return * @return
*/ */
CScanner(eParseMode aMode=eParseMode_navigator); CScanner(nsString& aFilename,PRBool aCreateStream=PR_TRUE);
/**
* Use this constructor if you want i/o to be based on a
* non-incremental netstream.
*
* @update gess 5/12/98
* @param aMode represents the parser mode (nav, other)
* @return
*/
CScanner(nsIURL* aURL,eParseMode aMode=eParseMode_navigator);
/**
* Use this constructor if you want i/o to be file based.
*
* @update gess 5/12/98
* @param aMode represents the parser mode (nav, other)
* @return
*/
CScanner(const char* aFilename,eParseMode aMode=eParseMode_navigator);
/** /**
* Use this constructor if you want i/o to be stream based. * Use this constructor if you want i/o to be stream based.
@ -80,7 +58,7 @@ class CScanner {
* @param aMode represents the parser mode (nav, other) * @param aMode represents the parser mode (nav, other)
* @return * @return
*/ */
CScanner(fstream& aStream,eParseMode aMode=eParseMode_navigator); CScanner(nsString& aFilename,fstream& aStream,PRBool assumeOwnership=PR_TRUE);
~CScanner(); ~CScanner();
@ -241,16 +219,17 @@ class CScanner {
* @param * @param
* @return * @return
*/ */
PRInt32 IncrementalAppend(const char* aBuffer,PRInt32 aSize); nsString& GetBuffer(void);
/** /**
* * Retrieve the name of the file that the scanner is reading from.
* In some cases, it's just a given name, because the scanner isn't
* really reading from a file.
* *
* @update gess 5/12/98 * @update gess 5/12/98
* @param
* @return * @return
*/ */
nsString& GetBuffer(void); nsString& GetFilename(void);
static void SelfTest(); static void SelfTest();
@ -268,13 +247,11 @@ class CScanner {
fstream* mFileStream; fstream* mFileStream;
nsIInputStream* mNetStream;
nsString mBuffer; nsString mBuffer;
nsString mFilename;
PRInt32 mOffset; PRInt32 mOffset;
PRInt32 mMarkPos; PRInt32 mMarkPos;
PRInt32 mTotalRead; PRInt32 mTotalRead;
eParseMode mParseMode;
PRBool mIncremental;
PRBool mOwnsStream; PRBool mOwnsStream;
}; };

Просмотреть файл

@ -190,7 +190,7 @@ eAutoDetectResult CValidDTD::AutoDetectContentType(nsString& aBuffer,nsString& a
* @param * @param
* @return * @return
*/ */
PRInt32 CValidDTD::WillBuildModel(const char* aFilename){ PRInt32 CValidDTD::WillBuildModel(nsString& aFilename){
PRInt32 result=0; PRInt32 result=0;
return result; return result;
} }

Просмотреть файл

@ -108,7 +108,7 @@ class CValidDTD : public nsIDTD {
* @param * @param
* @return * @return
*/ */
virtual PRInt32 WillBuildModel(const char* aFilename=0); virtual PRInt32 WillBuildModel(nsString& aFilename);
/** /**
* *

Просмотреть файл

@ -177,7 +177,7 @@ eAutoDetectResult CWellFormedDTD::AutoDetectContentType(nsString& aBuffer,nsStri
* @param * @param
* @return * @return
*/ */
PRInt32 CWellFormedDTD::WillBuildModel(const char* aFilename){ PRInt32 CWellFormedDTD::WillBuildModel(nsString& aFilename){
PRInt32 result=0; PRInt32 result=0;
return result; return result;
} }

Просмотреть файл

@ -97,7 +97,7 @@ class CWellFormedDTD : public nsIDTD {
* @param * @param
* @return * @return
*/ */
virtual PRInt32 WillBuildModel(const char* aFilename=0); virtual PRInt32 WillBuildModel(nsString& aFilename);
/** /**
* *

Просмотреть файл

@ -91,6 +91,115 @@ static char gWhitespaceTags[]={
0}; 0};
/************************************************************************
CTagStack class implementation.
The reason we use this class is so that we can view the stack state
in the usual way via the debugger.
************************************************************************/
CTagStack::CTagStack(int aDefaultSize) {
#ifdef _dynstack
mSize=aDefaultSize;
mTags =new eHTMLTags[mSize];
mBits =new PRBool[mSize];
#else
mSize=eStackSize;
#endif
mCount=0;
nsCRT::zero(mTags,mSize*sizeof(eHTMLTag_html));
nsCRT::zero(mBits,mSize*sizeof(PRBool));
}
/**
* Default constructor
* @update gess7/9/98
* @param aDefaultsize tells the stack what size to start out.
* however, we'll autosize as needed.
*/
CTagStack::~CTagStack() {
#ifdef _dynstack
delete mTags;
delete mBits;
mTags=0;
mBits=0;
#endif
mSize=mCount=0;
}
/**
*
* @update gess7/9/98
* @param
* @return
*/
void CTagStack::Push(eHTMLTags aTag) {
if(mCount>=mSize) {
#ifdef _dynstack
eHTMLTags* tmp=new eHTMLTags[2*mSize];
nsCRT::zero(tmp,2*mSize*sizeof(eHTMLTag_html));
nsCRT::memcpy(tmp,mTags,mSize*sizeof(eHTMLTag_html));
delete mTags;
mTags=tmp;
PRBool* tmp2=new PRBool[2*mSize];
nsCRT::zero(tmp2,2*mSize*sizeof(PRBool));
nsCRT::memcpy(tmp2,mBits,mSize*sizeof(PRBool));
delete mBits;
mBits=tmp2;
mSize*=2;
#endif
}
mTags[mCount++]=aTag;
}
/**
*
* @update gess7/9/98
* @param
* @return
*/
eHTMLTags CTagStack::Pop() {
eHTMLTags result=eHTMLTag_unknown;
if(mCount>0) {
result=mTags[--mCount];
mTags[mCount]=eHTMLTag_unknown;
mBits[mCount]=PR_FALSE;
}
return result;
}
/**
*
* @update gess7/9/98
* @param
* @return
*/
eHTMLTags CTagStack::First() const {
if(mCount>0)
return mTags[0];
return eHTMLTag_unknown;
}
/**
*
* @update gess7/9/98
* @param
* @return
*/
eHTMLTags CTagStack::Last() const {
if(mCount>0)
return mTags[mCount-1];
return eHTMLTag_unknown;
}
/************************************************************************
And now for the main class -- CNavDTD...
************************************************************************/
/** /**
* This method gets called as part of our COM-like interfaces. * This method gets called as part of our COM-like interfaces.
* Its purpose is to create an interface to parser object * Its purpose is to create an interface to parser object
@ -124,6 +233,7 @@ nsresult CNavDTD::QueryInterface(const nsIID& aIID, void** aInstancePtr)
return NS_OK; return NS_OK;
} }
/** /**
* This method is defined in nsIParser. It is used to * This method is defined in nsIParser. It is used to
* cause the COM-like construction of an nsParser. * cause the COM-like construction of an nsParser.
@ -234,15 +344,13 @@ static CNavTokenDeallocator gTokenKiller;
* @param * @param
* @return * @return
*/ */
CNavDTD::CNavDTD() : nsIDTD(), mTokenDeque(gTokenKiller) { CNavDTD::CNavDTD() : nsIDTD(), mTokenDeque(gTokenKiller),
mContextStack(), mStyleStack() {
NS_INIT_REFCNT(); NS_INIT_REFCNT();
mParser=0; mParser=0;
mFilename=0;
mSink = nsnull; mSink = nsnull;
mDTDDebug=0; mDTDDebug=0;
nsCRT::zero(mTokenHandlers,sizeof(mTokenHandlers)); nsCRT::zero(mTokenHandlers,sizeof(mTokenHandlers));
mContextStackPos=0;
mStyleStackPos=0;
mHasOpenForm=PR_FALSE; mHasOpenForm=PR_FALSE;
mHasOpenMap=PR_FALSE; mHasOpenMap=PR_FALSE;
InitializeDefaultTokenHandlers(); InitializeDefaultTokenHandlers();
@ -257,8 +365,6 @@ CNavDTD::CNavDTD() : nsIDTD(), mTokenDeque(gTokenKiller) {
*/ */
CNavDTD::~CNavDTD(){ CNavDTD::~CNavDTD(){
DeleteTokenHandlers(); DeleteTokenHandlers();
if (mFilename)
PL_strfree(mFilename);
if (mDTDDebug) if (mDTDDebug)
NS_RELEASE(mDTDDebug); NS_RELEASE(mDTDDebug);
@ -281,6 +387,7 @@ void CNavDTD::SetDTDDebug(nsIDTDDebug * aDTDDebug)
NS_ADDREF(mDTDDebug); NS_ADDREF(mDTDDebug);
} }
/** /**
* This method is called to determine if the given DTD can parse * This method is called to determine if the given DTD can parse
* a document in a given source-type. * a document in a given source-type.
@ -308,24 +415,16 @@ eAutoDetectResult CNavDTD::AutoDetectContentType(nsString& aBuffer,nsString& aTy
return result; return result;
} }
/** /**
* *
* @update gess5/18/98 * @update gess5/18/98
* @param * @param
* @return * @return
*/ */
PRInt32 CNavDTD::WillBuildModel(const char* aFilename){ PRInt32 CNavDTD::WillBuildModel(nsString& aFilename){
PRInt32 result=0; PRInt32 result=0;
if (mFilename) { mFilename=aFilename;
PL_strfree(mFilename);
mFilename=0;
}
if(aFilename) {
mFilename = PL_strdup(aFilename);
}
if(mSink) if(mSink)
mSink->WillBuildModel(); mSink->WillBuildModel();
@ -342,7 +441,7 @@ PRInt32 CNavDTD::WillBuildModel(const char* aFilename){
PRInt32 CNavDTD::DidBuildModel(PRInt32 anErrorCode){ PRInt32 CNavDTD::DidBuildModel(PRInt32 anErrorCode){
PRInt32 result=0; PRInt32 result=0;
if((kNoError==anErrorCode) && (mContextStackPos>0)) { if((kNoError==anErrorCode) && (mContextStack.mCount>0)) {
CloseContainersTo(0,eHTMLTag_unknown,PR_FALSE); CloseContainersTo(0,eHTMLTag_unknown,PR_FALSE);
} }
if(mSink) { if(mSink) {
@ -375,7 +474,7 @@ PRInt32 CNavDTD::HandleToken(CToken* aToken){
if(theHandler) { if(theHandler) {
result=(*theHandler)(theToken,this); result=(*theHandler)(theToken,this);
if (mDTDDebug) if (mDTDDebug)
mDTDDebug->Verify(this, mParser, mContextStackPos, mContextStack, mFilename); mDTDDebug->Verify(this, mParser, mContextStack.mCount, mContextStack.mTags, mFilename);
} }
}//if }//if
@ -420,13 +519,13 @@ PRInt32 CNavDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsIP
} }
if(IsContainer(aChildTag)){ if(IsContainer(aChildTag)){
if(PR_TRUE==(PRBool)mLeafBits[mContextStackPos-1]) { if(PR_TRUE==mContextStack.mBits[mContextStack.mCount-1]) {
CloseTransientStyles(aChildTag); CloseTransientStyles(aChildTag);
} }
result=OpenContainer(aNode,PR_TRUE); result=OpenContainer(aNode,PR_TRUE);
} }
else { else {
if(PR_FALSE==(PRBool)mLeafBits[mContextStackPos-1]) { if(PR_FALSE==mContextStack.mBits[mContextStack.mCount-1]) {
OpenTransientStyles(aChildTag); OpenTransientStyles(aChildTag);
} }
result=AddLeaf(aNode); result=AddLeaf(aNode);
@ -576,16 +675,8 @@ PRInt32 CNavDTD::HandleEndToken(CToken* aToken) {
// we have to handle explicit styles the way it does. That means // we have to handle explicit styles the way it does. That means
// that we keep an internal style stack.When an EndToken occurs, // that we keep an internal style stack.When an EndToken occurs,
// we should see if it is an explicit style tag. If so, we can // we should see if it is an explicit style tag. If so, we can
// close AND explicit style tag (goofy, huh?) // close the explicit style tag (goofy, huh?)
/*
if(0!=strchr(gStyleTags,tokenTagType)){
eHTMLTags topTag=GetTopNode();
if(0!=strchr(gStyleTags,topTag)){
tokenTagType=topTag;
}
}
*/
//now check to see if this token should be omitted... //now check to see if this token should be omitted...
if(PR_TRUE==CanOmitEndTag(GetTopNode(),tokenTagType)) { if(PR_TRUE==CanOmitEndTag(GetTopNode(),tokenTagType)) {
@ -622,7 +713,7 @@ PRInt32 CNavDTD::HandleEndToken(CToken* aToken) {
// Empty the transient style stack (we just closed any extra // Empty the transient style stack (we just closed any extra
// ones off so it's safe to do it now) because they don't carry // ones off so it's safe to do it now) because they don't carry
// forward across table cell boundaries. // forward across table cell boundaries.
mStyleStackPos = 0; mStyleStack.mCount=0;
break; break;
default: default:
@ -1148,8 +1239,8 @@ PRBool CNavDTD::CanContain(PRInt32 aParent,PRInt32 aChild) {
break; //singletons can't contain anything... break; //singletons can't contain anything...
case eHTMLTag_li: case eHTMLTag_li:
if ((eHTMLTag_li == aChild) || if ((eHTMLTag_li == aChild) || //XXX this is temporary!!!
(eHTMLTag_ul == aChild) || // XXX this is temporary!!! (eHTMLTag_ul == aChild) ||
(eHTMLTag_ol == aChild) || (eHTMLTag_ol == aChild) ||
(eHTMLTag_menu == aChild) || (eHTMLTag_menu == aChild) ||
(eHTMLTag_dir == aChild)) { (eHTMLTag_dir == aChild)) {
@ -1620,29 +1711,6 @@ PRBool CNavDTD::BackwardPropagate(nsString& aVector,eHTMLTags aParentTag,eHTMLTa
return PRBool(aParentTag==theParentTag); return PRBool(aParentTag==theParentTag);
} }
/**
*
* @update gess6/4/98
* @param aTag is the id of the html container being opened
* @return 0 if all is well.
*/
PRInt32 CNavDTD::DidOpenContainer(eHTMLTags aTag,PRBool /*anExplicitOpen*/){
PRInt32 result=0;
return result;
}
/**
*
* @update gess6/4/98
* @param
* @return
*/
PRInt32 CNavDTD::DidCloseContainer(eHTMLTags aTag,PRBool/*anExplicitClosure*/){
PRInt32 result=0;
return result;
}
/** /**
* This method allows the caller to determine if a form * This method allows the caller to determine if a form
* element is currently open. * element is currently open.
@ -1672,9 +1740,7 @@ PRBool CNavDTD::HasOpenContainer(eHTMLTags aContainer) const {
* @return tag id of topmost node in contextstack * @return tag id of topmost node in contextstack
*/ */
eHTMLTags CNavDTD::GetTopNode() const { eHTMLTags CNavDTD::GetTopNode() const {
if(mContextStackPos) return mContextStack.Last();
return (eHTMLTags)(int)mContextStack[mContextStackPos-1];
return eHTMLTag_unknown;
} }
@ -1688,8 +1754,8 @@ eHTMLTags CNavDTD::GetTopNode() const {
*/ */
PRInt32 CNavDTD::GetTopmostIndexOf(eHTMLTags aTag) const { PRInt32 CNavDTD::GetTopmostIndexOf(eHTMLTags aTag) const {
int i=0; int i=0;
for(i=mContextStackPos-1;i>=0;i--){ for(i=mContextStack.mCount-1;i>=0;i--){
if((eHTMLTags)(int)mContextStack[i]==aTag) if(mContextStack.mTags[i]==aTag)
return i; return i;
} }
return kNotFound; return kNotFound;
@ -1720,8 +1786,8 @@ PRInt32 CNavDTD::OpenTransientStyles(eHTMLTags aTag){
eHTMLTags parentTag=GetTopNode(); eHTMLTags parentTag=GetTopNode();
if(CanContainStyles(parentTag)) { if(CanContainStyles(parentTag)) {
for(pos=0;pos<mStyleStackPos;pos++) { for(pos=0;pos<mStyleStack.mCount;pos++) {
eHTMLTags theTag=(eHTMLTags)(int)mStyleStack[pos]; eHTMLTags theTag=mStyleStack.mTags[pos];
if(PR_FALSE==HasOpenContainer(theTag)) { if(PR_FALSE==HasOpenContainer(theTag)) {
CStartToken token(GetTagName(theTag)); CStartToken token(GetTagName(theTag));
@ -1735,7 +1801,7 @@ PRInt32 CNavDTD::OpenTransientStyles(eHTMLTags aTag){
default: default:
token.SetTypeID(theTag); //open the html container... token.SetTypeID(theTag); //open the html container...
result=OpenContainer(theNode,PR_FALSE); result=OpenContainer(theNode,PR_FALSE);
mLeafBits.ReplaceElementAt((void*)PR_TRUE,mContextStackPos-1); mContextStack.mBits[mContextStack.mCount-1]=PR_TRUE;
} //switch } //switch
} }
if(kNoError!=result) if(kNoError!=result)
@ -1761,11 +1827,11 @@ PRInt32 CNavDTD::OpenTransientStyles(eHTMLTags aTag){
PRInt32 CNavDTD::CloseTransientStyles(eHTMLTags aTag){ PRInt32 CNavDTD::CloseTransientStyles(eHTMLTags aTag){
PRInt32 result=0; PRInt32 result=0;
if((mStyleStackPos>0) && (mLeafBits[mContextStackPos-1])) { if((mStyleStack.mCount>0) && (mContextStack.mBits[mContextStack.mCount-1])) {
if(0==strchr(gWhitespaceTags,aTag)){ if(0==strchr(gWhitespaceTags,aTag)){
result=CloseContainersTo((eHTMLTags)(int)mStyleStack[0],PR_FALSE); result=CloseContainersTo(mStyleStack.mTags[0],PR_FALSE);
mLeafBits.ReplaceElementAt((void*)PR_FALSE,mContextStackPos-1); mContextStack.mBits[mContextStack.mCount-1]=PR_FALSE;
}//if }//if
}//if }//if
@ -1782,10 +1848,10 @@ PRInt32 CNavDTD::CloseTransientStyles(eHTMLTags aTag){
* @return TRUE if ok, FALSE if error * @return TRUE if ok, FALSE if error
*/ */
PRInt32 CNavDTD::OpenHTML(const nsIParserNode& aNode){ PRInt32 CNavDTD::OpenHTML(const nsIParserNode& aNode){
NS_PRECONDITION(mContextStackPos >= 0, kInvalidTagStackPos); NS_PRECONDITION(mContextStack.mCount >= 0, kInvalidTagStackPos);
PRInt32 result=mSink->OpenHTML(aNode); PRInt32 result=mSink->OpenHTML(aNode);
mContextStack.ReplaceElementAt((void*)aNode.GetNodeType(),mContextStackPos++); mContextStack.Push((eHTMLTags)aNode.GetNodeType());
return result; return result;
} }
@ -1799,9 +1865,9 @@ PRInt32 CNavDTD::OpenHTML(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error * @return TRUE if ok, FALSE if error
*/ */
PRInt32 CNavDTD::CloseHTML(const nsIParserNode& aNode){ PRInt32 CNavDTD::CloseHTML(const nsIParserNode& aNode){
NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos); NS_PRECONDITION(mContextStack.mCount > 0, kInvalidTagStackPos);
PRInt32 result=mSink->CloseHTML(aNode); PRInt32 result=mSink->CloseHTML(aNode);
mContextStack.ReplaceElementAt((void*)eHTMLTag_unknown,--mContextStackPos); mContextStack.Pop();
return result; return result;
} }
@ -1815,7 +1881,7 @@ PRInt32 CNavDTD::CloseHTML(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error * @return TRUE if ok, FALSE if error
*/ */
PRInt32 CNavDTD::OpenHead(const nsIParserNode& aNode){ PRInt32 CNavDTD::OpenHead(const nsIParserNode& aNode){
mContextStack.ReplaceElementAt((void*)eHTMLTag_head,++mContextStackPos); mContextStack.Push(eHTMLTag_head);
PRInt32 result=mSink->OpenHead(aNode); PRInt32 result=mSink->OpenHead(aNode);
return result; return result;
} }
@ -1830,7 +1896,7 @@ PRInt32 CNavDTD::OpenHead(const nsIParserNode& aNode){
*/ */
PRInt32 CNavDTD::CloseHead(const nsIParserNode& aNode){ PRInt32 CNavDTD::CloseHead(const nsIParserNode& aNode){
PRInt32 result=mSink->CloseHead(aNode); PRInt32 result=mSink->CloseHead(aNode);
mContextStack.ReplaceElementAt((void*)eHTMLTag_unknown,--mContextStackPos); mContextStack.Pop();
return result; return result;
} }
@ -1843,7 +1909,7 @@ PRInt32 CNavDTD::CloseHead(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error * @return TRUE if ok, FALSE if error
*/ */
PRInt32 CNavDTD::OpenBody(const nsIParserNode& aNode){ PRInt32 CNavDTD::OpenBody(const nsIParserNode& aNode){
NS_PRECONDITION(mContextStackPos >= 0, kInvalidTagStackPos); NS_PRECONDITION(mContextStack.mCount >= 0, kInvalidTagStackPos);
PRInt32 result=kNoError; PRInt32 result=kNoError;
eHTMLTags topTag=GetTopNode(); eHTMLTags topTag=GetTopNode();
@ -1875,7 +1941,7 @@ PRInt32 CNavDTD::OpenBody(const nsIParserNode& aNode){
if(kNoError==result) { if(kNoError==result) {
result=mSink->OpenBody(aNode); result=mSink->OpenBody(aNode);
mContextStack.ReplaceElementAt((void*)aNode.GetNodeType(),mContextStackPos++); mContextStack.Push((eHTMLTags)aNode.GetNodeType());
} }
return result; return result;
} }
@ -1889,9 +1955,9 @@ PRInt32 CNavDTD::OpenBody(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error * @return TRUE if ok, FALSE if error
*/ */
PRInt32 CNavDTD::CloseBody(const nsIParserNode& aNode){ PRInt32 CNavDTD::CloseBody(const nsIParserNode& aNode){
NS_PRECONDITION(mContextStackPos >= 0, kInvalidTagStackPos); NS_PRECONDITION(mContextStack.mCount >= 0, kInvalidTagStackPos);
PRInt32 result=mSink->CloseBody(aNode); PRInt32 result=mSink->CloseBody(aNode);
mContextStack.ReplaceElementAt((void*)eHTMLTag_unknown,--mContextStackPos); mContextStack.Pop();
return result; return result;
} }
@ -1980,9 +2046,9 @@ PRInt32 CNavDTD::CloseMap(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error * @return TRUE if ok, FALSE if error
*/ */
PRInt32 CNavDTD::OpenFrameset(const nsIParserNode& aNode){ PRInt32 CNavDTD::OpenFrameset(const nsIParserNode& aNode){
NS_PRECONDITION(mContextStackPos >= 0, kInvalidTagStackPos); NS_PRECONDITION(mContextStack.mCount >= 0, kInvalidTagStackPos);
PRInt32 result=mSink->OpenFrameset(aNode); PRInt32 result=mSink->OpenFrameset(aNode);
mContextStack.ReplaceElementAt((void*)aNode.GetNodeType(),mContextStackPos++); mContextStack.Push((eHTMLTags)aNode.GetNodeType());
return result; return result;
} }
@ -1995,9 +2061,9 @@ PRInt32 CNavDTD::OpenFrameset(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error * @return TRUE if ok, FALSE if error
*/ */
PRInt32 CNavDTD::CloseFrameset(const nsIParserNode& aNode){ PRInt32 CNavDTD::CloseFrameset(const nsIParserNode& aNode){
NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos); NS_PRECONDITION(mContextStack.mCount > 0, kInvalidTagStackPos);
PRInt32 result=mSink->CloseFrameset(aNode); PRInt32 result=mSink->CloseFrameset(aNode);
mContextStack.ReplaceElementAt((void*)eHTMLTag_unknown,--mContextStackPos); mContextStack.Pop();
return result; return result;
} }
@ -2011,7 +2077,7 @@ PRInt32 CNavDTD::CloseFrameset(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error * @return TRUE if ok, FALSE if error
*/ */
PRInt32 CNavDTD::OpenContainer(const nsIParserNode& aNode,PRBool aUpdateStyleStack){ PRInt32 CNavDTD::OpenContainer(const nsIParserNode& aNode,PRBool aUpdateStyleStack){
NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos); NS_PRECONDITION(mContextStack.mCount > 0, kInvalidTagStackPos);
PRInt32 result=kNoError; PRInt32 result=kNoError;
eHTMLTags nodeType=(eHTMLTags)aNode.GetNodeType(); eHTMLTags nodeType=(eHTMLTags)aNode.GetNodeType();
@ -2037,7 +2103,7 @@ PRInt32 CNavDTD::OpenContainer(const nsIParserNode& aNode,PRBool aUpdateStyleSta
default: default:
result=mSink->OpenContainer(aNode); result=mSink->OpenContainer(aNode);
mContextStack.ReplaceElementAt((void*)nodeType,mContextStackPos++); mContextStack.Push((eHTMLTags)aNode.GetNodeType());
break; break;
} }
@ -2057,7 +2123,7 @@ PRInt32 CNavDTD::OpenContainer(const nsIParserNode& aNode,PRBool aUpdateStyleSta
* @return TRUE if ok, FALSE if error * @return TRUE if ok, FALSE if error
*/ */
PRInt32 CNavDTD::CloseContainer(const nsIParserNode& aNode,eHTMLTags aTag,PRBool aUpdateStyles){ PRInt32 CNavDTD::CloseContainer(const nsIParserNode& aNode,eHTMLTags aTag,PRBool aUpdateStyles){
NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos); NS_PRECONDITION(mContextStack.mCount > 0, kInvalidTagStackPos);
PRInt32 result=kNoError; //was false PRInt32 result=kNoError; //was false
eHTMLTags nodeType=(eHTMLTags)aNode.GetNodeType(); eHTMLTags nodeType=(eHTMLTags)aNode.GetNodeType();
@ -2085,11 +2151,11 @@ PRInt32 CNavDTD::CloseContainer(const nsIParserNode& aNode,eHTMLTags aTag,PRBool
case eHTMLTag_title: case eHTMLTag_title:
default: default:
result=mSink->CloseContainer(aNode); result=mSink->CloseContainer(aNode);
mContextStack.ReplaceElementAt((void*)eHTMLTag_unknown,--mContextStackPos); mContextStack.Pop();
break; break;
} }
mLeafBits.ReplaceElementAt((void*)PR_FALSE, mContextStackPos); mContextStack.mBits[mContextStack.mCount]=PR_FALSE;
if((kNoError==result) && (PR_TRUE==aUpdateStyles)){ if((kNoError==result) && (PR_TRUE==aUpdateStyles)){
UpdateStyleStackForCloseTag(nodeType,aTag); UpdateStyleStackForCloseTag(nodeType,aTag);
} }
@ -2106,15 +2172,15 @@ PRInt32 CNavDTD::CloseContainer(const nsIParserNode& aNode,eHTMLTags aTag,PRBool
* @return TRUE if ok, FALSE if error * @return TRUE if ok, FALSE if error
*/ */
PRInt32 CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTag,PRBool aUpdateStyles){ PRInt32 CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTag,PRBool aUpdateStyles){
NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos); NS_PRECONDITION(mContextStack.mCount > 0, kInvalidTagStackPos);
PRInt32 result=kNoError; PRInt32 result=kNoError;
CEndToken aToken(gEmpty); CEndToken aToken(gEmpty);
nsCParserNode theNode(&aToken); nsCParserNode theNode(&aToken);
if((anIndex<mContextStackPos) && (anIndex>=0)) { if((anIndex<mContextStack.mCount) && (anIndex>=0)) {
while(mContextStackPos>anIndex) { while(mContextStack.mCount>anIndex) {
eHTMLTags theTag=(eHTMLTags)(int)mContextStack[mContextStackPos-1]; eHTMLTags theTag=mContextStack.Last();
aToken.SetTypeID(theTag); aToken.SetTypeID(theTag);
result=CloseContainer(theNode,aTag,aUpdateStyles); result=CloseContainer(theNode,aTag,aUpdateStyles);
} }
@ -2131,7 +2197,7 @@ PRInt32 CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTag,PRBool aUpdate
* @return TRUE if ok, FALSE if error * @return TRUE if ok, FALSE if error
*/ */
PRInt32 CNavDTD::CloseContainersTo(eHTMLTags aTag,PRBool aUpdateStyles){ PRInt32 CNavDTD::CloseContainersTo(eHTMLTags aTag,PRBool aUpdateStyles){
NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos); NS_PRECONDITION(mContextStack.mCount > 0, kInvalidTagStackPos);
PRInt32 pos=GetTopmostIndexOf(aTag); PRInt32 pos=GetTopmostIndexOf(aTag);
@ -2172,10 +2238,10 @@ PRInt32 CNavDTD::CloseContainersTo(eHTMLTags aTag,PRBool aUpdateStyles){
* @return TRUE if ok, FALSE if error * @return TRUE if ok, FALSE if error
*/ */
PRInt32 CNavDTD::CloseTopmostContainer(){ PRInt32 CNavDTD::CloseTopmostContainer(){
NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos); NS_PRECONDITION(mContextStack.mCount > 0, kInvalidTagStackPos);
CEndToken aToken(gEmpty); CEndToken aToken(gEmpty);
eHTMLTags theTag=(eHTMLTags)(int)mContextStack[mContextStackPos-1]; eHTMLTags theTag=mContextStack.Last();
aToken.SetTypeID(theTag); aToken.SetTypeID(theTag);
nsCParserNode theNode(&aToken); nsCParserNode theNode(&aToken);
return CloseContainer(theNode,theTag,PR_TRUE); return CloseContainer(theNode,theTag,PR_TRUE);
@ -2217,7 +2283,7 @@ PRInt32 CNavDTD::CreateContextStackFor(eHTMLTags aChildTag){
//add code here to build up context stack based on forward propagated context vector... //add code here to build up context stack based on forward propagated context vector...
pos=0; pos=0;
cnt=theVector.Length()-1; cnt=theVector.Length()-1;
if(mContextStack[mContextStackPos-1]==(void*)theVector[cnt]) if(mContextStack.Last()==(eHTMLTags)theVector[cnt])
result=kNoError; result=kNoError;
else result=kContextMismatch; else result=kContextMismatch;
} }
@ -2236,8 +2302,8 @@ PRInt32 CNavDTD::CreateContextStackFor(eHTMLTags aChildTag){
pos=0; pos=0;
cnt=theVector.Length(); cnt=theVector.Length();
result=kNoError; result=kNoError;
while(pos<mContextStackPos) { while(pos<mContextStack.mCount) {
if(mContextStack[pos]==(void*)theVector[cnt-1-pos]) { if(mContextStack.mTags[pos]==(eHTMLTags)theVector[cnt-1-pos]) {
pos++; pos++;
} }
else { else {
@ -2321,7 +2387,7 @@ PRInt32 CNavDTD::UpdateStyleStackForOpenTag(eHTMLTags aTag,eHTMLTags anActualTag
case eHTMLTag_tt: case eHTMLTag_tt:
case eHTMLTag_u: case eHTMLTag_u:
case eHTMLTag_var: case eHTMLTag_var:
mStyleStack.ReplaceElementAt((void*)aTag,mStyleStackPos++); mStyleStack.Push(aTag);
break; break;
case eHTMLTag_h1: case eHTMLTag_h2: case eHTMLTag_h1: case eHTMLTag_h2:
@ -2347,7 +2413,7 @@ PRInt32 CNavDTD::UpdateStyleStackForOpenTag(eHTMLTags aTag,eHTMLTags anActualTag
PRInt32 CNavDTD::UpdateStyleStackForCloseTag(eHTMLTags aTag,eHTMLTags anActualTag){ PRInt32 CNavDTD::UpdateStyleStackForCloseTag(eHTMLTags aTag,eHTMLTags anActualTag){
PRInt32 result=0; PRInt32 result=0;
if(mStyleStackPos>0) { if(mStyleStack.mCount>0) {
switch (aTag) { switch (aTag) {
case eHTMLTag_a: case eHTMLTag_a:
@ -2369,7 +2435,7 @@ PRInt32 CNavDTD::UpdateStyleStackForCloseTag(eHTMLTags aTag,eHTMLTags anActualTa
case eHTMLTag_u: case eHTMLTag_u:
case eHTMLTag_var: case eHTMLTag_var:
if(aTag==anActualTag) if(aTag==anActualTag)
mStyleStack.ReplaceElementAt((void*)eHTMLTag_unknown,--mStyleStackPos); mStyleStack.Pop();
break; break;
case eHTMLTag_h1: case eHTMLTag_h2: case eHTMLTag_h1: case eHTMLTag_h2:
@ -2716,8 +2782,8 @@ PRInt32 CNavDTD::ConsumeToken(CToken*& aToken){
CScanner* theScanner=mParser->GetScanner(); CScanner* theScanner=mParser->GetScanner();
if(kNoError==result){ if(kNoError==result){
PRUnichar aChar; PRUnichar theChar;
result=theScanner->GetChar(aChar); result=theScanner->GetChar(theChar);
switch(result) { switch(result) {
case kEOF: case kEOF:
break; break;
@ -2728,25 +2794,25 @@ PRInt32 CNavDTD::ConsumeToken(CToken*& aToken){
case kNoError: case kNoError:
default: default:
switch(aChar) { switch(theChar) {
case kLessThan: case kLessThan:
return ConsumeTag(aChar,*theScanner,aToken); return ConsumeTag(theChar,*theScanner,aToken);
case kAmpersand: case kAmpersand:
return ConsumeEntity(aChar,*theScanner,aToken); return ConsumeEntity(theChar,*theScanner,aToken);
case kCR: case kLF: case kCR: case kLF:
return ConsumeNewline(aChar,*theScanner,aToken); return ConsumeNewline(theChar,*theScanner,aToken);
case kNotFound: case kNotFound:
break; break;
default: default:
if(!nsString::IsSpace(aChar)) { if(!nsString::IsSpace(theChar)) {
nsAutoString temp(aChar); nsAutoString temp(theChar);
return ConsumeText(temp,*theScanner,aToken); return ConsumeText(temp,*theScanner,aToken);
} }
return ConsumeWhitespace(aChar,*theScanner,aToken); return ConsumeWhitespace(theChar,*theScanner,aToken);
} //switch } //switch
break; break;
} //switch } //switch

Просмотреть файл

@ -45,6 +45,54 @@ class nsIParserNode;
class CITokenHandler; class CITokenHandler;
class nsParser; class nsParser;
/***************************************************************
First define a helper class called CTagStack.
Simple, we've built ourselves a little data structure that
serves as a stack for htmltags (and associated bits).
What's special is that if you #define _dynstack 1, the stack
size can grow dynamically (like you'ld want in a release build.)
If you don't #define _dynstack 1, then the stack is a fixed size,
equal to the eStackSize enum. This makes debugging easier, because
you can see the htmltags on the stack if its not dynamic.
***************************************************************/
//#define _dynstack 1
class CTagStack {
enum {eStackSize=200};
public:
CTagStack(int aDefaultSize=50);
~CTagStack();
void Push(eHTMLTags aTag);
eHTMLTags Pop();
eHTMLTags First() const;
eHTMLTags Last() const;
int mSize;
int mCount;
#ifdef _dynstack
eHTMLTags* mTags;
PRBool* mBits;
#else
eHTMLTags mTags[200];
PRBool mBits[200];
#endif
};
/***************************************************************
Now the main event: CNavDTD.
This not so simple class performs all the duties of token
construction and model building. It works in conjunction with
an nsParser.
***************************************************************/
class CNavDTD : public nsIDTD { class CNavDTD : public nsIDTD {
public: public:
@ -103,7 +151,7 @@ class CNavDTD : public nsIDTD {
* @param * @param
* @return * @return
*/ */
virtual PRInt32 WillBuildModel(const char* aFilename=0); virtual PRInt32 WillBuildModel(nsString& aFilename);
/** /**
* *
@ -251,14 +299,6 @@ class CNavDTD : public nsIDTD {
*/ */
virtual PRBool BackwardPropagate(nsString& aVector,eHTMLTags aParentTag,eHTMLTags aChildTag) const; virtual PRBool BackwardPropagate(nsString& aVector,eHTMLTags aParentTag,eHTMLTags aChildTag) const;
/**
*
* @update gess6/4/98
* @param
* @return
*/
virtual PRInt32 DidOpenContainer(eHTMLTags aTag,PRBool anExplicitOpen);
/** /**
* Ask parser if a given container is open ANYWHERE on stack * Ask parser if a given container is open ANYWHERE on stack
* @update gess5/11/98 * @update gess5/11/98
@ -283,129 +323,36 @@ class CNavDTD : public nsIDTD {
*/ */
virtual PRInt32 GetTopmostIndexOf(eHTMLTags aTag) const; virtual PRInt32 GetTopmostIndexOf(eHTMLTags aTag) const;
/**
*
* @update gess6/4/98
* @param
* @return
*/
virtual PRInt32 DidCloseContainer(eHTMLTags aTag,PRBool anExplicitClosure);
/** /**
* This method gets called when a start token has been consumed and needs * The following set of methods are used to partially construct
* to be handled (possibly added to content model via sink). * the content model (via the sink) according to the type of token.
* @update gess5/11/98 * @update gess5/11/98
* @param aToken is the start token to be handled * @param aToken is the start token to be handled
* @return TRUE if the token was handled. * @return TRUE if the token was handled.
*/ */
PRInt32 HandleStartToken(CToken* aToken); PRInt32 HandleStartToken(CToken* aToken);
/**
* This method gets called when a start token has been consumed, and
* we want to use default start token handling behavior.
* This method gets called automatically by handleStartToken.
*
* @update gess5/11/98
* @param aToken is the start token to be handled
* @param aChildTag is the tag-type of given token
* @param aNode is a node be updated with info from given token
* @return TRUE if the token was handled.
*/
PRInt32 HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsIParserNode& aNode); PRInt32 HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsIParserNode& aNode);
/**
* This method gets called when an end token has been consumed and needs
* to be handled (possibly added to content model via sink).
* @update gess5/11/98
* @param aToken is the end token to be handled
* @return TRUE if the token was handled.
*/
PRInt32 HandleEndToken(CToken* aToken); PRInt32 HandleEndToken(CToken* aToken);
/**
* This method gets called when an entity token has been consumed and needs
* to be handled (possibly added to content model via sink).
* @update gess5/11/98
* @param aToken is the entity token to be handled
* @return TRUE if the token was handled.
*/
PRInt32 HandleEntityToken(CToken* aToken); PRInt32 HandleEntityToken(CToken* aToken);
/**
* This method gets called when a comment token has been consumed and needs
* to be handled (possibly added to content model via sink).
* @update gess5/11/98
* @param aToken is the comment token to be handled
* @return TRUE if the token was handled.
*/
PRInt32 HandleCommentToken(CToken* aToken); PRInt32 HandleCommentToken(CToken* aToken);
/**
* This method gets called when a skipped-content token has been consumed and needs
* to be handled (possibly added to content model via sink).
* @update gess5/11/98
* @param aToken is the skipped-content token to be handled
* @return TRUE if the token was handled.
*/
PRInt32 HandleSkippedContentToken(CToken* aToken); PRInt32 HandleSkippedContentToken(CToken* aToken);
/**
* This method gets called when an attribute token has been consumed and needs
* to be handled (possibly added to content model via sink).
* @update gess5/11/98
* @param aToken is the attribute token to be handled
* @return TRUE if the token was handled.
*/
PRInt32 HandleAttributeToken(CToken* aToken); PRInt32 HandleAttributeToken(CToken* aToken);
/**
* This method gets called when a script token has been consumed and needs
* to be handled (possibly added to content model via sink).
* @update gess5/11/98
* @param aToken is the script token to be handled
* @return TRUE if the token was handled.
*/
PRInt32 HandleScriptToken(CToken* aToken); PRInt32 HandleScriptToken(CToken* aToken);
/**
* This method gets called when a style token has been consumed and needs
* to be handled (possibly added to content model via sink).
* @update gess5/11/98
* @param aToken is the style token to be handled
* @return TRUE if the token was handled.
*/
PRInt32 HandleStyleToken(CToken* aToken); PRInt32 HandleStyleToken(CToken* aToken);
protected: protected:
/** /**
* Causes token handlers to be registered for this parser. * The following methods are use to create and manage
* DO NOT CALL THIS! IT'S DEPRECATED! * the dynamic set of token handlers.
* @update gess5/11/98
*/
void InitializeDefaultTokenHandlers();
/**
* DEPRECATED
* @update gess5/11/98 * @update gess5/11/98
*/ */
void InitializeDefaultTokenHandlers();
CITokenHandler* GetTokenHandler(eHTMLTokenTypes aType) const; CITokenHandler* GetTokenHandler(eHTMLTokenTypes aType) const;
/**
* DEPRECATED
* @update gess5/11/98
*/
CITokenHandler* AddTokenHandler(CITokenHandler* aHandler); CITokenHandler* AddTokenHandler(CITokenHandler* aHandler);
void DeleteTokenHandlers(void);
/**
* DEPRECATED
* @update gess5/11/98
*/
void DeleteTokenHandlers(void);
//************************************************* //*************************************************
@ -414,145 +361,43 @@ protected:
//************************************************* //*************************************************
/** /**
* This cover method opens the given node as a HTML item in * The next set of method open given HTML element.
* content sink. *
* @update gess5/11/98 * @update gess5/11/98
* @param HTML (node) to be opened in content sink. * @param HTML (node) to be opened in content sink.
* @return TRUE if all went well. * @return TRUE if all went well.
*/ */
PRInt32 OpenHTML(const nsIParserNode& aNode); PRInt32 OpenHTML(const nsIParserNode& aNode);
/**
*
* @update gess5/11/98
* @param
* @return
*/
PRInt32 CloseHTML(const nsIParserNode& aNode);
/**
* This cover method opens the given node as a head item in
* content sink.
* @update gess5/11/98
* @param HEAD (node) to be opened in content sink.
* @return TRUE if all went well.
*/
PRInt32 OpenHead(const nsIParserNode& aNode); PRInt32 OpenHead(const nsIParserNode& aNode);
/**
* This cover method causes the content-sink head to be closed
* @update gess5/11/98
* @param aNode is the node to be closed in sink (usually ignored)
* @return TRUE if all went well.
*/
PRInt32 CloseHead(const nsIParserNode& aNode);
/**
* This cover method opens the given node as a body item in
* content sink.
* @update gess5/11/98
* @param BODY (node) to be opened in content sink.
* @return TRUE if all went well.
*/
PRInt32 OpenBody(const nsIParserNode& aNode); PRInt32 OpenBody(const nsIParserNode& aNode);
/**
* This cover method causes the content-sink body to be closed
* @update gess5/11/98
* @param aNode is the body node to be closed in sink (usually ignored)
* @return TRUE if all went well.
*/
PRInt32 CloseBody(const nsIParserNode& aNode);
/**
* This cover method opens the given node as a form item in
* content sink.
* @update gess5/11/98
* @param FORM (node) to be opened in content sink.
* @return TRUE if all went well.
*/
PRInt32 OpenForm(const nsIParserNode& aNode); PRInt32 OpenForm(const nsIParserNode& aNode);
/**
* This cover method causes the content-sink form to be closed
* @update gess5/11/98
* @param aNode is the form node to be closed in sink (usually ignored)
* @return TRUE if all went well.
*/
PRInt32 CloseForm(const nsIParserNode& aNode);
/**
* This cover method opens the given node as a form item in
* content sink.
* @update gess5/11/98
* @param FORM (node) to be opened in content sink.
* @return TRUE if all went well.
*/
PRInt32 OpenMap(const nsIParserNode& aNode); PRInt32 OpenMap(const nsIParserNode& aNode);
/**
* This cover method causes the content-sink form to be closed
* @update gess5/11/98
* @param aNode is the form node to be closed in sink (usually ignored)
* @return TRUE if all went well.
*/
PRInt32 CloseMap(const nsIParserNode& aNode);
/**
* This cover method opens the given node as a frameset item in
* content sink.
* @update gess5/11/98
* @param FRAMESET (node) to be opened in content sink.
* @return TRUE if all went well.
*/
PRInt32 OpenFrameset(const nsIParserNode& aNode); PRInt32 OpenFrameset(const nsIParserNode& aNode);
/**
* This cover method causes the content-sink frameset to be closed
* @update gess5/11/98
* @param aNode is the frameeset node to be closed in sink (usually ignored)
* @return TRUE if all went well.
*/
PRInt32 CloseFrameset(const nsIParserNode& aNode);
/**
* This cover method opens the given node as a generic container in
* content sink.
* @update gess5/11/98
* @param generic container (node) to be opened in content sink.
* @return TRUE if all went well.
*/
PRInt32 OpenContainer(const nsIParserNode& aNode,PRBool aUpdateStyleStack); PRInt32 OpenContainer(const nsIParserNode& aNode,PRBool aUpdateStyleStack);
/** /**
* This cover method causes a generic containre in the content-sink to be closed * The next set of methods close the given HTML element.
*
* @update gess5/11/98 * @update gess5/11/98
* @param aNode is the node to be closed in sink (usually ignored) * @param HTML (node) to be opened in content sink.
* @return TRUE if all went well. * @return TRUE if all went well.
*/ */
PRInt32 CloseHTML(const nsIParserNode& aNode);
PRInt32 CloseHead(const nsIParserNode& aNode);
PRInt32 CloseBody(const nsIParserNode& aNode);
PRInt32 CloseForm(const nsIParserNode& aNode);
PRInt32 CloseMap(const nsIParserNode& aNode);
PRInt32 CloseFrameset(const nsIParserNode& aNode);
PRInt32 CloseContainer(const nsIParserNode& aNode,eHTMLTags anActualTag,PRBool aUpdateStyles); PRInt32 CloseContainer(const nsIParserNode& aNode,eHTMLTags anActualTag,PRBool aUpdateStyles);
/** /**
* This cover method causes the topmost container to be closed in sink * The special purpose methods automatically close
* one or more open containers.
* @update gess5/11/98 * @update gess5/11/98
* @return TRUE if all went well. * @return TRUE if all went well.
*/ */
PRInt32 CloseTopmostContainer(); PRInt32 CloseTopmostContainer();
/**
* Cause all containers down to topmost given tag to be closed
* @update gess5/11/98
* @param aTag is the tag at which auto-closure should stop (inclusive)
* @return TRUE if all went well -- otherwise FALSE
*/
PRInt32 CloseContainersTo(eHTMLTags aTag,PRBool aUpdateStyles); PRInt32 CloseContainersTo(eHTMLTags aTag,PRBool aUpdateStyles);
/**
* Cause all containers down to given position to be closed
* @update gess5/11/98
* @param anIndex is the stack pos at which auto-closure should stop (inclusive)
* @return TRUE if all went well -- otherwise FALSE
*/
PRInt32 CloseContainersTo(PRInt32 anIndex,eHTMLTags aTag,PRBool aUpdateStyles); PRInt32 CloseContainersTo(PRInt32 anIndex,eHTMLTags aTag,PRBool aUpdateStyles);
/** /**
@ -603,81 +448,22 @@ protected:
CToken* CreateTokenOfType(eHTMLTokenTypes aType); CToken* CreateTokenOfType(eHTMLTokenTypes aType);
/** /**
* Retrieve the next TAG from the given scanner. * The following methods consume a particular type
* of HTML token.
*
* @update gess 5/11/98 * @update gess 5/11/98
* @param aScanner is the input source * @param aScanner is the input source
* @param aToken is the next token (or null) * @param aToken is the next token (or null)
* @return error code * @return error code
*/ */
PRInt32 ConsumeTag(PRUnichar aChar,CScanner& aScanner,CToken*& aToken); PRInt32 ConsumeTag(PRUnichar aChar,CScanner& aScanner,CToken*& aToken);
/**
* Retrieve next START tag from given scanner.
* @update gess 5/11/98
* @param aScanner is the input source
* @param aToken is the next token (or null)
* @return error code
*/
PRInt32 ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,CToken*& aToken); PRInt32 ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,CToken*& aToken);
/**
* Retrieve collection of HTML/XML attributes from given scanner
* @update gess 5/11/98
* @param aScanner is the input source
* @param aToken is the next token (or null)
* @return error code
*/
PRInt32 ConsumeAttributes(PRUnichar aChar,CScanner& aScanner,CStartToken* aToken); PRInt32 ConsumeAttributes(PRUnichar aChar,CScanner& aScanner,CStartToken* aToken);
/**
* Retrieve a sequence of text from given scanner.
* @update gess 5/11/98
* @param aString will contain retrieved text.
* @param aScanner is the input source
* @param aToken is the next token (or null)
* @return error code
*/
PRInt32 ConsumeText(const nsString& aString,CScanner& aScanner,CToken*& aToken);
/**
* Retrieve an entity from given scanner
* @update gess 5/11/98
* @param aChar last char read from scanner
* @param aScanner is the input source
* @param aToken is the next token (or null)
* @return error code
*/
PRInt32 ConsumeEntity(PRUnichar aChar,CScanner& aScanner,CToken*& aToken); PRInt32 ConsumeEntity(PRUnichar aChar,CScanner& aScanner,CToken*& aToken);
/**
* Retrieve a whitespace sequence from the given scanner
* @update gess 5/11/98
* @param aChar last char read from scanner
* @param aScanner is the input source
* @param aToken is the next token (or null)
* @return error code
*/
PRInt32 ConsumeWhitespace(PRUnichar aChar,CScanner& aScanner,CToken*& aToken); PRInt32 ConsumeWhitespace(PRUnichar aChar,CScanner& aScanner,CToken*& aToken);
/**
* Retrieve a comment from the given scanner
* @update gess 5/11/98
* @param aChar last char read from scanner
* @param aScanner is the input source
* @param aToken is the next token (or null)
* @return error code
*/
PRInt32 ConsumeComment(PRUnichar aChar,CScanner& aScanner,CToken*& aToken); PRInt32 ConsumeComment(PRUnichar aChar,CScanner& aScanner,CToken*& aToken);
/**
* Retrieve newlines from given scanner
* @update gess 5/11/98
* @param aChar last char read from scanner
* @param aScanner is the input source
* @param aToken is the next token (or null)
* @return error code
*/
PRInt32 ConsumeNewline(PRUnichar aChar,CScanner& aScanner,CToken*& aToken); PRInt32 ConsumeNewline(PRUnichar aChar,CScanner& aScanner,CToken*& aToken);
PRInt32 ConsumeText(const nsString& aString,CScanner& aScanner,CToken*& aToken);
/** /**
* Causes content to be skipped up to sequence contained in aString. * Causes content to be skipped up to sequence contained in aString.
@ -700,16 +486,13 @@ protected:
CITokenHandler* mTokenHandlers[eToken_last]; CITokenHandler* mTokenHandlers[eToken_last];
nsVoidArray mLeafBits; CTagStack mContextStack;
nsVoidArray mContextStack; CTagStack mStyleStack;
PRInt32 mContextStackPos;
nsVoidArray mStyleStack;
PRInt32 mStyleStackPos;
PRBool mHasOpenForm; PRBool mHasOpenForm;
PRBool mHasOpenMap; PRBool mHasOpenMap;
nsDeque mTokenDeque; nsDeque mTokenDeque;
char* mFilename; nsString mFilename;
nsIDTDDebug* mDTDDebug; nsIDTDDebug* mDTDDebug;
}; };

Просмотреть файл

@ -178,7 +178,7 @@ eAutoDetectResult COtherDTD::AutoDetectContentType(nsString& aBuffer,nsString& a
* @param * @param
* @return * @return
*/ */
PRInt32 COtherDTD::WillBuildModel(const char* aFilename) { PRInt32 COtherDTD::WillBuildModel(nsString& aFilename) {
return CNavDTD::WillBuildModel(aFilename); return CNavDTD::WillBuildModel(aFilename);
} }
@ -464,25 +464,6 @@ PRBool COtherDTD::BackwardPropagate(nsString& aVector,eHTMLTags aParentTag,eHTML
return CNavDTD::BackwardPropagate(aVector,aParentTag,aChildTag); return CNavDTD::BackwardPropagate(aVector,aParentTag,aChildTag);
} }
/**
*
* @update gess6/4/98
* @param aTag is the id of the html container being opened
* @return 0 if all is well.
*/
PRInt32 COtherDTD::DidOpenContainer(eHTMLTags aTag,PRBool anExplicitOpen){
return CNavDTD::DidOpenContainer(aTag,anExplicitOpen);
}
/**
*
* @update gess6/4/98
* @param
* @return
*/
PRInt32 COtherDTD::DidCloseContainer(eHTMLTags aTag,PRBool anExplicitClosure){
return CNavDTD::DidOpenContainer(aTag,anExplicitClosure);
}
/********************************************* /*********************************************
Here comes code that handles the interface Here comes code that handles the interface

Просмотреть файл

@ -87,7 +87,7 @@ class COtherDTD : public CNavDTD {
* @param * @param
* @return * @return
*/ */
virtual PRInt32 WillBuildModel(const char* aFilename=0); virtual PRInt32 WillBuildModel(nsString& aString);
/** /**
* *
@ -218,22 +218,6 @@ class COtherDTD : public CNavDTD {
*/ */
virtual PRBool BackwardPropagate(nsString& aVector,eHTMLTags aParentTag,eHTMLTags aChildTag) const; virtual PRBool BackwardPropagate(nsString& aVector,eHTMLTags aParentTag,eHTMLTags aChildTag) const;
/**
*
* @update gess6/4/98
* @param
* @return
*/
virtual PRInt32 DidOpenContainer(eHTMLTags aTag,PRBool anExplicitOpen);
/**
*
* @update gess6/4/98
* @param
* @return
*/
virtual PRInt32 DidCloseContainer(eHTMLTags aTag,PRBool anExplicitClosure);
/** /**
* This method gets called when a start token has been consumed and needs * This method gets called when a start token has been consumed and needs
* to be handled (possibly added to content model via sink). * to be handled (possibly added to content model via sink).

Просмотреть файл

@ -0,0 +1,85 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/**
* MODULE NOTES:
* @update gess 4/1/98
*
*/
#include "CParserContext.h"
#include "nsToken.h"
class CTokenDeallocator: public nsDequeFunctor{
public:
virtual void* operator()(void* anObject) {
CToken* aToken = (CToken*)anObject;
delete aToken;
return 0;
}
};
CTokenDeallocator gTokenDeallocator;
CParserContext::CParserContext(CScanner* aScanner,
CParserContext* aPreviousContext,
nsIStreamObserver* aListener) :
mTokenDeque(gTokenDeallocator),
mSourceType()
{
mScanner=aScanner;
mPrevContext=aPreviousContext;
mListener=aListener;
NS_IF_ADDREF(mListener);
mMajorIteration=mMinorIteration=-1;
mParseMode=eParseMode_unknown;
mAutoDetectStatus=eUnknownDetect;
mTransferBuffer=new char[eTransferBufferSize+1];
mCurrentPos=0;
mMarkPos=0;
mDTD=0;
}
/**
* Destructor for parser context
* NOTE: DO NOT destroy the dtd here.
* @update gess7/11/98
*/
CParserContext::~CParserContext(){
if(mCurrentPos)
delete mCurrentPos;
if(mMarkPos)
delete mMarkPos;
if(mScanner)
delete mScanner;
if(mTransferBuffer)
delete [] mTransferBuffer;
//Remember that it's ok to simply
//ignore the DTD and the prevcontext.
}

Просмотреть файл

@ -0,0 +1,80 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/**
* MODULE NOTES:
* @update gess 4/1/98
*
*/
#ifndef __CParserContext
#define __CParserContext
#include "nsIParser.h"
#include "nsDeque.h"
#include "nsParserTypes.h"
#include "nsIURL.h"
#include "nsIDTD.h"
#include "nsScanner.h"
#include "nsIStreamListener.h"
/**
* Note that the parser is given FULL access to all
* data in a parsercontext. Hey, that what it's for!
*/
class CParserContext {
public:
enum {eTransferBufferSize=4096};
CParserContext( CScanner* aScanner,
CParserContext* aPreviousContext=0,
nsIStreamObserver* aListener=0);
~CParserContext();
PRInt32 mMajorIteration;
PRInt32 mMinorIteration;
nsString mSourceType;
eAutoDetectResult mAutoDetectStatus;
nsDequeIterator* mCurrentPos;
nsDequeIterator* mMarkPos;
nsDeque mTokenDeque;
CScanner* mScanner;
nsIDTD* mDTD;
eParseMode mParseMode;
char* mTransferBuffer;
nsIStreamObserver* mListener;
CParserContext* mPrevContext;
};
#endif

Просмотреть файл

@ -251,7 +251,7 @@ eAutoDetectResult CRtfDTD::AutoDetectContentType(nsString& aBuffer,nsString& aTy
* @param * @param
* @return * @return
*/ */
PRInt32 CRtfDTD::WillBuildModel(const char* aFilename){ PRInt32 CRtfDTD::WillBuildModel(nsString& aFilename){
PRInt32 result=0; PRInt32 result=0;
return result; return result;
} }

Просмотреть файл

@ -190,7 +190,7 @@ class CRtfDTD : public nsIDTD {
* @param * @param
* @return * @return
*/ */
virtual PRInt32 WillBuildModel(const char* aFilename=0); virtual PRInt32 WillBuildModel(nsString& aFilename);
/** /**
* *

Просмотреть файл

@ -34,6 +34,7 @@ CPPSRCS = \
nsValidDTD.cpp \ nsValidDTD.cpp \
nsWellFormedDTD.cpp \ nsWellFormedDTD.cpp \
nsParser.cpp \ nsParser.cpp \
CParserContext.cpp \
nsHTMLTokens.cpp \ nsHTMLTokens.cpp \
nsHTMLTags.cpp \ nsHTMLTags.cpp \
prstrm.cpp \ prstrm.cpp \

Просмотреть файл

@ -34,6 +34,7 @@ CPPSRCS= \
nsHTMLTags.obj \ nsHTMLTags.obj \
nsHTMLTokens.obj \ nsHTMLTokens.obj \
nsParser.obj \ nsParser.obj \
CParserContext.obj \
nsParserNode.obj \ nsParserNode.obj \
nsScanner.obj \ nsScanner.obj \
nsToken.obj \ nsToken.obj \
@ -53,6 +54,7 @@ CPP_OBJS= \
.\$(OBJDIR)\nsHTMLTags.obj \ .\$(OBJDIR)\nsHTMLTags.obj \
.\$(OBJDIR)\nsHTMLTokens.obj \ .\$(OBJDIR)\nsHTMLTokens.obj \
.\$(OBJDIR)\nsParser.obj \ .\$(OBJDIR)\nsParser.obj \
.\$(OBJDIR)\CParserContext.obj \
.\$(OBJDIR)\nsParserNode.obj \ .\$(OBJDIR)\nsParserNode.obj \
.\$(OBJDIR)\nsScanner.obj \ .\$(OBJDIR)\nsScanner.obj \
.\$(OBJDIR)\nsToken.obj \ .\$(OBJDIR)\nsToken.obj \

Просмотреть файл

@ -67,7 +67,7 @@ public:
void SetVerificationDirectory(char * verify_dir); void SetVerificationDirectory(char * verify_dir);
void SetRecordStatistics(PRBool bval); void SetRecordStatistics(PRBool bval);
PRBool Verify(nsIDTD * aDTD, nsParser * aParser, int ContextStackPos, nsVoidArray &aContextStack, char * aURLRef); PRBool Verify(nsIDTD * aDTD, nsParser * aParser, int ContextStackPos, eHTMLTags aContextStack[], nsString& aURLRef);
void DumpVectorRecord(void); void DumpVectorRecord(void);
// global table for storing vector statistics and the size // global table for storing vector statistics and the size
@ -78,8 +78,8 @@ private:
char * mVerificationDir; char * mVerificationDir;
PRBool mRecordingStatistics; PRBool mRecordingStatistics;
PRBool DebugRecord(char * path, char * pURLRef, char * filename); PRBool DebugRecord(char * path, nsString& pURLRef, char * filename);
void NoteVector(nsVoidArray & aTags,PRInt32 count, PRBool good_vector); void NoteVector(eHTMLTags aTags[],PRInt32 count, PRBool good_vector);
void MakeVectorString(char * vector_string, VectorInfo * pInfo); void MakeVectorString(char * vector_string, VectorInfo * pInfo);
}; };
@ -188,7 +188,7 @@ void CDTDDebug::SetRecordStatistics(PRBool bval)
* @return TRUE if it is already record (dont rerecord) * @return TRUE if it is already record (dont rerecord)
*/ */
PRBool CDTDDebug::DebugRecord(char * path, char * pURLRef, char * filename) PRBool CDTDDebug::DebugRecord(char * path, nsString& aURLRef, char * filename)
{ {
char recordPath[2048]; char recordPath[2048];
PRIntn oflags = 0; PRIntn oflags = 0;
@ -215,7 +215,9 @@ PRBool CDTDDebug::DebugRecord(char * path, char * pURLRef, char * filename)
// vectors are stored on the format iof "URL vector filename" // vectors are stored on the format iof "URL vector filename"
// where the vector contains the verification path and // where the vector contains the verification path and
// the filename contains the debug source dump // the filename contains the debug source dump
sprintf(string,"%s %s %s\r\n", pURLRef, path, filename); char buffer[513];
aURLRef.ToCString(buffer,sizeof(buffer)-1);
sprintf(string,"%s %s %s\r\n", buffer, path, filename);
// get the file size, read in the file and parse it line at // get the file size, read in the file and parse it line at
// a time to check to see if we have already recorded this // a time to check to see if we have already recorded this
@ -310,7 +312,7 @@ static int compare( const void *arg1, const void *arg2 )
* @return * @return
*/ */
void CDTDDebug::NoteVector(nsVoidArray & aTags,PRInt32 count, PRBool good_vector) void CDTDDebug::NoteVector(eHTMLTags aTags[],PRInt32 count, PRBool good_vector)
{ {
// if the table doesn't exist, create it // if the table doesn't exist, create it
if (!mVectorInfoArray) { if (!mVectorInfoArray) {
@ -327,7 +329,7 @@ void CDTDDebug::NoteVector(nsVoidArray & aTags,PRInt32 count, PRBool good_vector
PRBool match = PR_TRUE; PRBool match = PR_TRUE;
for (PRInt32 j = 0; j < count; j++) for (PRInt32 j = 0; j < count; j++)
if (mVectorInfoArray[i]->vector[j] != (eHTMLTags)(int)aTags[j]) { if (mVectorInfoArray[i]->vector[j] != aTags[j]) {
match = PR_FALSE; match = PR_FALSE;
break; break;
} }
@ -348,7 +350,7 @@ void CDTDDebug::NoteVector(nsVoidArray & aTags,PRInt32 count, PRBool good_vector
pVectorInfo->good_vector = good_vector; pVectorInfo->good_vector = good_vector;
pVectorInfo->vector = (eHTMLTags*)PR_Malloc(count*sizeof(eHTMLTags)); pVectorInfo->vector = (eHTMLTags*)PR_Malloc(count*sizeof(eHTMLTags));
for (PRInt32 i = 0; i < count; i++) for (PRInt32 i = 0; i < count; i++)
pVectorInfo->vector[i] = (eHTMLTags)(int)aTags[i]; pVectorInfo->vector[i] = aTags[i];
mVectorInfoArray[mVectorCount++] = pVectorInfo; mVectorInfoArray[mVectorCount++] = pVectorInfo;
// have we maxed out the table? grow it.. sort it.. love it. // have we maxed out the table? grow it.. sort it.. love it.
@ -467,7 +469,7 @@ void CDTDDebug::DumpVectorRecord(void)
* @return TRUE if we know how to handle it, else false * @return TRUE if we know how to handle it, else false
*/ */
PRBool CDTDDebug::Verify(nsIDTD * aDTD, nsParser * aParser, int aContextStackPos, nsVoidArray &aContextStack, char * aURLRef) PRBool CDTDDebug::Verify(nsIDTD * aDTD, nsParser * aParser, int aContextStackPos, eHTMLTags aContextStack[], nsString& aURLRef)
{ {
PRBool result=PR_TRUE; PRBool result=PR_TRUE;
@ -477,7 +479,7 @@ PRBool CDTDDebug::Verify(nsIDTD * aDTD, nsParser * aParser, int aContextStackPo
if(aDTD && aContextStackPos>1) { if(aDTD && aContextStackPos>1) {
for (int i = 0; i < aContextStackPos-1; i++) for (int i = 0; i < aContextStackPos-1; i++)
if (!aDTD->CanContain((eHTMLTags)(int)aContextStack[i],(eHTMLTags)(int)aContextStack[i+1])) { if (!aDTD->CanContain(aContextStack[i],aContextStack[i+1])) {
result = PR_FALSE; result = PR_FALSE;
break; break;
} }
@ -495,7 +497,7 @@ PRBool CDTDDebug::Verify(nsIDTD * aDTD, nsParser * aParser, int aContextStackPo
int i=0; int i=0;
for(i=0;i<aContextStackPos;i++){ for(i=0;i<aContextStackPos;i++){
strcat(path,"/"); strcat(path,"/");
const char* name=GetTagName((eHTMLTags)(int)aContextStack[i]); const char* name=GetTagName(aContextStack[i]);
strcat(path,name); strcat(path,name);
PR_MkDir(path,0); PR_MkDir(path,0);
} }

Просмотреть файл

@ -30,7 +30,7 @@
#include "nsHTMLContentSinkStream.h" #include "nsHTMLContentSinkStream.h"
#include "nsHTMLTokens.h" #include "nsHTMLTokens.h"
#include <iostream.h> #include <iostream.h>
#include "nsString.h" #include "nsstring.h"
#include "nsParserTypes.h" #include "nsParserTypes.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
@ -89,8 +89,8 @@ NS_IMPL_RELEASE(CHTMLContentSinkStream)
* @param nsIParser** ptr to newly instantiated parser * @param nsIParser** ptr to newly instantiated parser
* @return NS_xxx error result * @return NS_xxx error result
*/ */
NS_HTMLPARS nsresult NS_New_HTML_ContentSinkStream(CHTMLContentSinkStream** aInstancePtrResult) { NS_HTMLPARS nsresult NS_New_HTML_ContentSinkStream(CHTMLContentSinkStream** aInstancePtrResult,ostream* aStream) {
CHTMLContentSinkStream* it = new CHTMLContentSinkStream(); CHTMLContentSinkStream* it = new CHTMLContentSinkStream(aStream);
if (it == 0) { if (it == 0) {
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
@ -99,25 +99,14 @@ NS_HTMLPARS nsresult NS_New_HTML_ContentSinkStream(CHTMLContentSinkStream** aIns
return it->QueryInterface(kClassIID, (void **) aInstancePtrResult); return it->QueryInterface(kClassIID, (void **) aInstancePtrResult);
} }
/** /**
* Construct a content sink stream. * Construct a content sink stream.
* @update gess7/7/98 * @update gess7/7/98
* @param * @param
* @return * @return
*/ */
CHTMLContentSinkStream::CHTMLContentSinkStream() { CHTMLContentSinkStream::CHTMLContentSinkStream(ostream* aStream) {
mOutput=&cout; mOutput=(0==aStream) ? &cout : aStream;
}
/**
* Construct a content sink stream.
* @update gess7/7/98
* @param
* @return
*/
CHTMLContentSinkStream::CHTMLContentSinkStream(ostream& aStream) {
mOutput=&aStream;
} }
@ -132,17 +121,6 @@ CHTMLContentSinkStream::~CHTMLContentSinkStream() {
} }
/**
*
* @update gess7/7/98
* @param
* @return
*/
void CHTMLContentSinkStream::SetOutputStream(ostream& aStream) {
mOutput=&aStream;
}
/** /**
* *
* @update gess7/7/98 * @update gess7/7/98
@ -171,7 +149,7 @@ void WriteAttributes(const nsIParserNode& aNode,ostream& aStream) {
* @param * @param
* @return * @return
*/ */
void OpenTagWithAttributes(const char* theTag,const nsIParserNode& aNode,int tab,ostream& aStream,PRBool aNewline) { void OpenTagWithAttributes(const char* theTag,const nsIParserNode& aNode,int tab,ostream& aStream,bool aNewline) {
int i=0; int i=0;
for(i=0;i<tab*gTabSize;i++) for(i=0;i<tab*gTabSize;i++)
aStream << " "; aStream << " ";
@ -189,7 +167,7 @@ void OpenTagWithAttributes(const char* theTag,const nsIParserNode& aNode,int tab
* @param * @param
* @return * @return
*/ */
void OpenTag(const char* theTag,int tab,ostream& aStream,PRBool aNewline) { void OpenTag(const char* theTag,int tab,ostream& aStream,bool aNewline) {
int i=0; int i=0;
for(i=0;i<tab*gTabSize;i++) for(i=0;i<tab*gTabSize;i++)
aStream << " "; aStream << " ";
@ -221,7 +199,7 @@ void CloseTag(const char* theTag,int tab,ostream& aStream) {
*/ */
void WritePair(eHTMLTags aTag,const nsString& theContent,int tab,ostream& aStream) { void WritePair(eHTMLTags aTag,const nsString& theContent,int tab,ostream& aStream) {
const char* titleStr = GetTagName(aTag); const char* titleStr = GetTagName(aTag);
OpenTag(titleStr,tab,aStream,PR_FALSE); OpenTag(titleStr,tab,aStream,false);
theContent.ToCString(gBuffer,sizeof(gBuffer)-1); theContent.ToCString(gBuffer,sizeof(gBuffer)-1);
aStream << gBuffer; aStream << gBuffer;
CloseTag(titleStr,0,aStream); CloseTag(titleStr,0,aStream);
@ -237,7 +215,7 @@ void WritePair(eHTMLTags aTag,const nsString& theContent,int tab,ostream& aStrea
*/ */
void WriteSingleton(eHTMLTags aTag,const nsString& theContent,int tab,ostream& aStream) { void WriteSingleton(eHTMLTags aTag,const nsString& theContent,int tab,ostream& aStream) {
const char* titleStr = GetTagName(aTag); const char* titleStr = GetTagName(aTag);
OpenTag(titleStr,tab,aStream,PR_FALSE); OpenTag(titleStr,tab,aStream,false);
if(theContent.Length()) { if(theContent.Length()) {
theContent.ToCString(gBuffer,sizeof(gBuffer)-1); theContent.ToCString(gBuffer,sizeof(gBuffer)-1);
aStream << gBuffer; aStream << gBuffer;
@ -275,7 +253,7 @@ PRInt32 CHTMLContentSinkStream::OpenHTML(const nsIParserNode& aNode){
mTabLevel++; mTabLevel++;
if(mOutput) { if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_html); const char* theTag= GetTagName(eHTMLTag_html);
OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,PR_TRUE); OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,true);
} }
return result; return result;
} }
@ -311,7 +289,7 @@ PRInt32 CHTMLContentSinkStream::OpenHead(const nsIParserNode& aNode){
mTabLevel++; mTabLevel++;
if(mOutput) { if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_head); const char* theTag= GetTagName(eHTMLTag_head);
OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,PR_TRUE); OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,true);
} }
return result; return result;
} }
@ -347,7 +325,7 @@ PRInt32 CHTMLContentSinkStream::OpenBody(const nsIParserNode& aNode){
mTabLevel++; mTabLevel++;
if(mOutput) { if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_body); const char* theTag= GetTagName(eHTMLTag_body);
OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,PR_TRUE); OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,true);
} }
return result; return result;
} }
@ -383,7 +361,7 @@ PRInt32 CHTMLContentSinkStream::OpenForm(const nsIParserNode& aNode){
mTabLevel++; mTabLevel++;
if(mOutput) { if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_form); const char* theTag= GetTagName(eHTMLTag_form);
OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,PR_TRUE); OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,true);
} }
return result; return result;
} }
@ -419,7 +397,7 @@ PRInt32 CHTMLContentSinkStream::OpenFrameset(const nsIParserNode& aNode){
mTabLevel++; mTabLevel++;
if(mOutput) { if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_frameset); const char* theTag= GetTagName(eHTMLTag_frameset);
OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,PR_TRUE); OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,true);
} }
return result; return result;
} }
@ -487,7 +465,7 @@ PRInt32 CHTMLContentSinkStream::OpenContainer(const nsIParserNode& aNode){
{ {
const nsString& name=aNode.GetName(); const nsString& name=aNode.GetName();
const char* tagName= GetTagName(nodeType); const char* tagName= GetTagName(nodeType);
OpenTagWithAttributes(tagName,aNode,mTabLevel,*mOutput,PR_TRUE); OpenTagWithAttributes(tagName,aNode,mTabLevel,*mOutput,true);
} }
break; break;
} }

Просмотреть файл

@ -52,15 +52,7 @@ class CHTMLContentSinkStream : public nsIHTMLContentSink {
* @param * @param
* @return * @return
*/ */
CHTMLContentSinkStream(); CHTMLContentSinkStream(ostream* aStream);
/**
*
* @update gess7/7/98
* @param
* @return
*/
CHTMLContentSinkStream(ostream& aStream);
/** /**
* *
@ -71,14 +63,6 @@ class CHTMLContentSinkStream : public nsIHTMLContentSink {
virtual ~CHTMLContentSinkStream(); virtual ~CHTMLContentSinkStream();
/**
*
* @update gess7/7/98
* @param
* @return
*/
void SetOutputStream(ostream& aStream);
/** /**
* This method gets called by the parser when it encounters * This method gets called by the parser when it encounters
* a title tag and wants to set the document title in the sink. * a title tag and wants to set the document title in the sink.
@ -249,7 +233,7 @@ protected:
}; };
extern NS_HTMLPARS nsresult NS_New_HTML_ContentSinkStream(CHTMLContentSinkStream** aInstancePtrResult); extern NS_HTMLPARS nsresult NS_New_HTML_ContentSinkStream(CHTMLContentSinkStream** aInstancePtrResult,ostream* aStream);
#endif #endif

Просмотреть файл

@ -99,7 +99,7 @@ class nsIDTD : public nsISupports {
* @param * @param
* @return * @return
*/ */
virtual PRInt32 WillBuildModel(const char* aFilename=0)=0; virtual PRInt32 WillBuildModel(nsString& aFilename)=0;
/** /**
* *

Просмотреть файл

@ -47,7 +47,7 @@ public:
virtual void SetRecordStatistics(PRBool bval) = 0; virtual void SetRecordStatistics(PRBool bval) = 0;
virtual PRBool Verify(nsIDTD * aDTD, nsParser * aParser, int ContextStackPos, nsVoidArray & aContextStack, char * aURLRef) = 0; virtual PRBool Verify(nsIDTD * aDTD, nsParser * aParser, int ContextStackPos, eHTMLTags aContextStack[], nsString& aURLRef) = 0;
virtual void DumpVectorRecord(void) = 0; virtual void DumpVectorRecord(void) = 0;

Просмотреть файл

@ -23,6 +23,7 @@
#include "nsISupports.h" #include "nsISupports.h"
#include "nsIStreamListener.h" #include "nsIStreamListener.h"
#include "nsIDTD.h" #include "nsIDTD.h"
#include "nsIInputStream.h"
#define NS_IPARSER_IID \ #define NS_IPARSER_IID \
{0x355cbba0, 0xbf7d, 0x11d1, \ {0x355cbba0, 0xbf7d, 0x11d1, \
@ -67,20 +68,18 @@ class nsIParser : public nsISupports {
* until you wind up with HTML in your actual content model. * until you wind up with HTML in your actual content model.
******************************************************************************************/ ******************************************************************************************/
virtual PRInt32 Parse(nsIURL* aURL,nsIStreamObserver* aListener = nsnull,nsIDTDDebug * aDTDDebug = 0) = 0; virtual PRInt32 Parse(nsIURL* aURL,nsIStreamObserver* aListener = nsnull,nsIDTDDebug * aDTDDebug = 0) = 0;
virtual PRInt32 Parse(const char* aFilename)=0; virtual PRInt32 Parse(nsIInputStream* pIStream,nsIStreamObserver* aListener,nsIDTDDebug* aDTDDebug = 0)=0;
virtual PRInt32 Parse(nsString& aFilename)=0;
virtual PRInt32 Parse(fstream& aStream)=0; virtual PRInt32 Parse(fstream& aStream)=0;
virtual PRInt32 Parse(nsString& anHTMLString,PRBool appendTokens)=0; virtual PRInt32 Parse(nsString& anHTMLString,PRBool appendTokens)=0;
virtual PRInt32 ResumeParse(void)=0;
/** /**
* This method gets called when the tokens have been consumed, and it's time * This method gets called when the tokens have been consumed, and it's time
* to build the model via the content sink. * to build the model via the content sink.
* @update gess5/11/98 * @update gess5/11/98
* @return YES if model building went well -- NO otherwise. * @return YES if model building went well -- NO otherwise.
*/ */
virtual PRInt32 IterateTokens(void)=0; virtual PRInt32 BuildModel(void)=0;
}; };

Просмотреть файл

@ -26,7 +26,6 @@
#include "prenv.h" //this is here for debug reasons... #include "prenv.h" //this is here for debug reasons...
#include "plstr.h" #include "plstr.h"
#include <fstream.h> #include <fstream.h>
#include "nsIInputStream.h"
#include "nsIParserFilter.h" #include "nsIParserFilter.h"
#include "nsIDTDDebug.h" #include "nsIDTDDebug.h"
#include "nshtmlpars.h" #include "nshtmlpars.h"
@ -47,13 +46,10 @@ static const char* kNullURL = "Error: Null URL given";
static const char* kNullFilename= "Error: Null filename given"; static const char* kNullFilename= "Error: Null filename given";
static const char* kNullTokenizer = "Error: Unable to construct tokenizer"; static const char* kNullTokenizer = "Error: Unable to construct tokenizer";
static const char* kHTMLTextContentType = "text/html"; static const char* kHTMLTextContentType = "text/html";
static nsString kUnknownFilename("unknown");
static const int gTransferBufferSize=4096; //size of the buffer used in moving data from iistream static const int gTransferBufferSize=4096; //size of the buffer used in moving data from iistream
#define DEBUG_SAVE_SOURCE_DOC 1
#ifdef DEBUG_SAVE_SOURCE_DOC
fstream* gTempStream=0;
#endif
/** /**
@ -84,7 +80,7 @@ public:
} }
}; };
CTokenDeallocator gTokenDeallocator; CTokenDeallocator gTokenDeallocator2;
class CDTDDeallocator: public nsDequeFunctor{ class CDTDDeallocator: public nsDequeFunctor{
public: public:
@ -114,6 +110,7 @@ public:
CSharedParserObjects() : mDeallocator(), mDTDDeque(mDeallocator) { CSharedParserObjects() : mDeallocator(), mDTDDeque(mDeallocator) {
} }
~CSharedParserObjects() { ~CSharedParserObjects() {
} }
@ -141,25 +138,13 @@ CSharedParserObjects gSharedParserObjects;
* @param * @param
* @return * @return
*/ */
nsParser::nsParser() : nsParser::nsParser() {
mTokenDeque(gTokenDeallocator),
mSourceType(),
mTargetType()
{
NS_INIT_REFCNT(); NS_INIT_REFCNT();
mDTDDebug = 0; mDTDDebug = 0;
mParserFilter = 0; mParserFilter = 0;
mObserver = 0; mObserver = 0;
mTransferBuffer=0;
mSink=0; mSink=0;
mCurrentPos=0; mParserContext=0;
mMarkPos=0;
mParseMode=eParseMode_unknown;
mURL=0;
mDTD=0;
mScanner=0;
mTransferBuffer=new char[gTransferBufferSize+1];
mAutoDetectStatus=eUnknownDetect;
} }
@ -172,20 +157,12 @@ nsParser::nsParser() :
*/ */
nsParser::~nsParser() { nsParser::~nsParser() {
NS_IF_RELEASE(mObserver); NS_IF_RELEASE(mObserver);
NS_IF_RELEASE(mDTDDebug); // NS_IF_RELEASE(mDTDDebug);
if(mTransferBuffer)
delete [] mTransferBuffer;
mTransferBuffer=0;
NS_RELEASE(mSink); NS_RELEASE(mSink);
if(mCurrentPos)
delete mCurrentPos;
mCurrentPos=0;
if(mScanner)
delete mScanner;
mScanner=0;
NS_IF_RELEASE(mURL);
//don't forget to add code here to delete
//what may be several contexts...
delete mParserContext;
} }
@ -298,7 +275,9 @@ void nsParser::RegisterDTD(nsIDTD* aDTD){
* @return * @return
*/ */
CScanner* nsParser::GetScanner(void){ CScanner* nsParser::GetScanner(void){
return mScanner; if(mParserContext)
return mParserContext->mScanner;
return 0;
} }
/** /**
@ -311,6 +290,7 @@ CScanner* nsParser::GetScanner(void){
eParseMode DetermineParseMode() { eParseMode DetermineParseMode() {
const char* theModeStr= PR_GetEnv("PARSE_MODE"); const char* theModeStr= PR_GetEnv("PARSE_MODE");
const char* other="other"; const char* other="other";
eParseMode result=eParseMode_navigator; eParseMode result=eParseMode_navigator;
if(theModeStr) if(theModeStr)
@ -326,25 +306,23 @@ eParseMode DetermineParseMode() {
* @param * @param
* @return * @return
*/ */
PRBool FindSuitableDTD( eParseMode aMode, PRBool FindSuitableDTD( CParserContext& aParserContext) {
nsString& aSourceType,
nsString& aTargetType,
nsIDTD*& aDefaultDTD) {
//Let's start by tring the defaultDTD, if one exists... //Let's start by tring the defaultDTD, if one exists...
if(aDefaultDTD && (aDefaultDTD->CanParse(aSourceType,0))) if(aParserContext.mDTD && (aParserContext.mDTD->CanParse(aParserContext.mSourceType,0)))
return PR_TRUE; return PR_TRUE;
PRBool result=PR_FALSE; PRBool result=PR_FALSE;
nsDequeIterator b=gSharedParserObjects.mDTDDeque.Begin(); nsDequeIterator b=gSharedParserObjects.mDTDDeque.Begin();
nsDequeIterator e=gSharedParserObjects.mDTDDeque.End(); nsDequeIterator e=gSharedParserObjects.mDTDDeque.End();
while(b<e){ while(b<e){
nsIDTD* theDTD=(nsIDTD*)b.GetCurrent(); nsIDTD* theDTD=(nsIDTD*)b.GetCurrent();
if(theDTD) { if(theDTD) {
result=theDTD->CanParse(aSourceType,0); result=theDTD->CanParse(aParserContext.mSourceType,0);
if(result){ if(result){
aDefaultDTD=theDTD; aParserContext.mDTD=theDTD;
break; break;
} }
} }
@ -371,22 +349,22 @@ eAutoDetectResult nsParser::AutoDetectContentType(nsString& aBuffer,nsString& aT
// recognize the content in the scanner. // recognize the content in the scanner.
// Somebody should say yes, or we can't continue. // Somebody should say yes, or we can't continue.
//This method may change mSourceType and mDTD. //This method may change mSourceType and mParserContext->mDTD.
//It absolutely changes mAutoDetectStatus //It absolutely changes mParserContext->mAutoDetectStatus
nsDequeIterator b=gSharedParserObjects.mDTDDeque.Begin(); nsDequeIterator b=gSharedParserObjects.mDTDDeque.Begin();
nsDequeIterator e=gSharedParserObjects.mDTDDeque.End(); nsDequeIterator e=gSharedParserObjects.mDTDDeque.End();
mAutoDetectStatus=eUnknownDetect; mParserContext->mAutoDetectStatus=eUnknownDetect;
while((b<e) && (eUnknownDetect==mAutoDetectStatus)){ while((b<e) && (eUnknownDetect==mParserContext->mAutoDetectStatus)){
nsIDTD* theDTD=(nsIDTD*)b.GetCurrent(); nsIDTD* theDTD=(nsIDTD*)b.GetCurrent();
if(theDTD) { if(theDTD) {
mAutoDetectStatus=theDTD->AutoDetectContentType(aBuffer,aType); mParserContext->mAutoDetectStatus=theDTD->AutoDetectContentType(aBuffer,aType);
} }
b++; b++;
} }
return mAutoDetectStatus; return mParserContext->mAutoDetectStatus;
} }
@ -401,27 +379,18 @@ eAutoDetectResult nsParser::AutoDetectContentType(nsString& aBuffer,nsString& aT
* @param * @param
* @return * @return
*/ */
PRInt32 nsParser::WillBuildModel(const char* aFilename){ PRInt32 nsParser::WillBuildModel(nsString& aFilename){
mMajorIteration=-1; mParserContext->mMajorIteration=-1;
mMinorIteration=-1; mParserContext->mMinorIteration=-1;
mParseMode=DetermineParseMode(); mParserContext->mParseMode=DetermineParseMode();
if(PR_TRUE==FindSuitableDTD(mParseMode,mSourceType,mTargetType,mDTD)) { if(PR_TRUE==FindSuitableDTD(*mParserContext)) {
mDTD->SetParser(this); mParserContext->mDTD->SetParser(this);
mDTD->SetContentSink(mSink); mParserContext->mDTD->SetContentSink(mSink);
mDTD->WillBuildModel(aFilename); mParserContext->mDTD->WillBuildModel(aFilename);
} }
#ifdef DEBUG_SAVE_SOURCE_DOC
#if defined(XP_UNIX) && (defined(IRIX) || defined(MKLINUX))
/* XXX: IRIX does not support ios::binary */
gTempStream =new fstream("/tmp/out.html",ios::out);
#else
gTempStream = new fstream("c:/temp/out.html",ios::out|ios::binary);
#endif
#endif
return kNoError; return kNoError;
} }
@ -434,18 +403,10 @@ PRInt32 nsParser::WillBuildModel(const char* aFilename){
PRInt32 nsParser::DidBuildModel(PRInt32 anErrorCode) { PRInt32 nsParser::DidBuildModel(PRInt32 anErrorCode) {
//One last thing...close any open containers. //One last thing...close any open containers.
PRInt32 result=anErrorCode; PRInt32 result=anErrorCode;
if(mDTD) { if(mParserContext->mDTD) {
result=mDTD->DidBuildModel(anErrorCode); result=mParserContext->mDTD->DidBuildModel(anErrorCode);
} }
#ifdef DEBUG_SAVE_SOURCE_DOC
if(gTempStream) {
gTempStream->close();
delete gTempStream;
gTempStream=0;
}
#endif
return result; return result;
} }
@ -460,22 +421,21 @@ PRInt32 nsParser::DidBuildModel(PRInt32 anErrorCode) {
* @param aFilename -- const char* containing file to be parsed. * @param aFilename -- const char* containing file to be parsed.
* @return PR_TRUE if parse succeeded, PR_FALSE otherwise. * @return PR_TRUE if parse succeeded, PR_FALSE otherwise.
*/ */
PRBool nsParser::Parse(const char* aFilename){ PRInt32 nsParser::Parse(nsString& aFilename){
NS_PRECONDITION(0!=aFilename,kNullFilename);
PRInt32 status=kBadFilename; PRInt32 status=kBadFilename;
if(aFilename) { if(aFilename) {
//ok, time to create our tokenizer and begin the process //ok, time to create our tokenizer and begin the process
mTargetType=kHTMLTextContentType;
mScanner=new CScanner(aFilename,mParseMode); mParserContext = new CParserContext(new CScanner(aFilename),mParserContext);
if(mScanner) { mParserContext->mScanner->Eof();
mScanner->Eof(); if(eValidDetect==AutoDetectContentType(mParserContext->mScanner->GetBuffer(),
if(eValidDetect==AutoDetectContentType(mScanner->GetBuffer(),mSourceType)) { mParserContext->mSourceType))
WillBuildModel(aFilename); {
status=ResumeParse(); WillBuildModel(aFilename);
DidBuildModel(status); status=ResumeParse();
} DidBuildModel(status);
} //if } //if
} }
return status; return status;
@ -488,11 +448,35 @@ PRBool nsParser::Parse(const char* aFilename){
* @return TRUE if all went well -- FALSE otherwise * @return TRUE if all went well -- FALSE otherwise
*/ */
PRInt32 nsParser::Parse(fstream& aStream){ PRInt32 nsParser::Parse(fstream& aStream){
PRInt32 result=0;
return result; PRInt32 status=kNoError;
//ok, time to create our tokenizer and begin the process
mParserContext = new CParserContext(new CScanner(kUnknownFilename,aStream,PR_FALSE),mParserContext);
mParserContext->mScanner->Eof();
if(eValidDetect==AutoDetectContentType(mParserContext->mScanner->GetBuffer(),
mParserContext->mSourceType)) {
WillBuildModel(mParserContext->mScanner->GetFilename());
status=ResumeParse();
DidBuildModel(status);
} //if
return status;
} }
/**
*
* @update gess7/13/98
* @param
* @return
*/
PRInt32 nsParser::Parse(nsIInputStream* pIStream,nsIStreamObserver* aListener,nsIDTDDebug* aDTDDebug){
PRInt32 result=kNoError;
return result;
}
/** /**
* This is the main controlling routine in the parsing process. * This is the main controlling routine in the parsing process.
* Note that it may get called multiple times for the same scanner, * Note that it may get called multiple times for the same scanner,
@ -512,19 +496,14 @@ PRInt32 nsParser::Parse(nsIURL* aURL,nsIStreamObserver* aListener, nsIDTDDebug *
PRInt32 status=kBadURL; PRInt32 status=kBadURL;
/* Disable DTD Debug for now...
mDTDDebug = aDTDDebug; mDTDDebug = aDTDDebug;
NS_IF_ADDREF(mDTDDebug); NS_IF_ADDREF(mDTDDebug);
*/
NS_IF_RELEASE(mURL);
mURL = aURL;
NS_IF_ADDREF(mURL);
NS_IF_RELEASE(mObserver);
mObserver = aListener;
NS_IF_ADDREF(mObserver);
if(mURL) { if(aURL) {
mScanner=new CScanner(mParseMode); nsAutoString theName(aURL->GetSpec());
mParserContext=new CParserContext(new CScanner(theName,PR_FALSE),mParserContext,aListener);
status=NS_OK; status=NS_OK;
} }
return status; return status;
@ -533,6 +512,8 @@ PRInt32 nsParser::Parse(nsIURL* aURL,nsIStreamObserver* aListener, nsIDTDDebug *
/** /**
* Call this method if all you want to do is parse 1 string full of HTML text. * Call this method if all you want to do is parse 1 string full of HTML text.
* In particular, this method should be called by the DOM when it has an HTML
* string to feed to the parser in real-time.
* *
* @update gess5/11/98 * @update gess5/11/98
* @param anHTMLString contains a string-full of real HTML * @param anHTMLString contains a string-full of real HTML
@ -542,11 +523,10 @@ PRInt32 nsParser::Parse(nsIURL* aURL,nsIStreamObserver* aListener, nsIDTDDebug *
PRInt32 nsParser::Parse(nsString& aSourceBuffer,PRBool appendTokens){ PRInt32 nsParser::Parse(nsString& aSourceBuffer,PRBool appendTokens){
PRInt32 result=kNoError; PRInt32 result=kNoError;
mTargetType=kHTMLTextContentType; mParserContext = new CParserContext(new CScanner(kUnknownFilename),mParserContext,0);
mScanner=new CScanner(); mParserContext->mScanner->Append(aSourceBuffer);
mScanner->Append(aSourceBuffer); if(eValidDetect==AutoDetectContentType(aSourceBuffer,mParserContext->mSourceType)) {
if(eValidDetect==AutoDetectContentType(aSourceBuffer,mSourceType)) { WillBuildModel(mParserContext->mScanner->GetFilename());
WillBuildModel("");
result=ResumeParse(); result=ResumeParse();
DidBuildModel(result); DidBuildModel(result);
} }
@ -567,12 +547,12 @@ PRInt32 nsParser::Parse(nsString& aSourceBuffer,PRBool appendTokens){
PRInt32 nsParser::ResumeParse() { PRInt32 nsParser::ResumeParse() {
PRInt32 result=kNoError; PRInt32 result=kNoError;
mDTD->WillResumeParse(); mParserContext->mDTD->WillResumeParse();
if(kNoError==result) { if(kNoError==result) {
result=Tokenize(); result=Tokenize();
if(kInterrupted==result) if(kInterrupted==result)
mDTD->WillInterruptParse(); mParserContext->mDTD->WillInterruptParse();
IterateTokens(); BuildModel();
} }
return result; return result;
} }
@ -585,26 +565,28 @@ PRInt32 nsParser::ResumeParse() {
* @param * @param
* @return PR_TRUE if parse succeeded, PR_FALSE otherwise. * @return PR_TRUE if parse succeeded, PR_FALSE otherwise.
*/ */
PRInt32 nsParser::IterateTokens() { PRInt32 nsParser::BuildModel() {
nsDequeIterator e=mTokenDeque.End();
nsDequeIterator e=mParserContext->mTokenDeque.End();
nsDequeIterator theMarkPos(e); nsDequeIterator theMarkPos(e);
mMajorIteration++;
if(!mCurrentPos) // mParserContext->mMajorIteration++;
mCurrentPos=new nsDequeIterator(mTokenDeque.Begin());
if(!mParserContext->mCurrentPos)
mParserContext->mCurrentPos=new nsDequeIterator(mParserContext->mTokenDeque.Begin());
PRInt32 result=kNoError; PRInt32 result=kNoError;
while((kNoError==result) && ((*mCurrentPos<e))){ while((kNoError==result) && ((*mParserContext->mCurrentPos<e))){
mMinorIteration++; mParserContext->mMinorIteration++;
CToken* theToken=(CToken*)mCurrentPos->GetCurrent(); CToken* theToken=(CToken*)mParserContext->mCurrentPos->GetCurrent();
theMarkPos=*mCurrentPos; theMarkPos=*mParserContext->mCurrentPos;
result=mDTD->HandleToken(theToken); result=mParserContext->mDTD->HandleToken(theToken);
++(*mCurrentPos); ++(*mParserContext->mCurrentPos);
} }
if(kInterrupted==result) if(kInterrupted==result)
*mCurrentPos=theMarkPos; *mParserContext->mCurrentPos=theMarkPos;
return result; return result;
} }
@ -619,17 +601,17 @@ PRInt32 nsParser::IterateTokens() {
* @return error code (should be 0) * @return error code (should be 0)
*/ */
PRInt32 nsParser::CollectAttributes(nsCParserNode& aNode,PRInt32 aCount){ PRInt32 nsParser::CollectAttributes(nsCParserNode& aNode,PRInt32 aCount){
nsDequeIterator end=mTokenDeque.End(); nsDequeIterator end=mParserContext->mTokenDeque.End();
int attr=0; int attr=0;
for(attr=0;attr<aCount;attr++) { for(attr=0;attr<aCount;attr++) {
if(*mCurrentPos<end) { if(*mParserContext->mCurrentPos<end) {
CToken* tkn=(CToken*)(++(*mCurrentPos)); CToken* tkn=(CToken*)(++(*mParserContext->mCurrentPos));
if(tkn){ if(tkn){
if(eToken_attribute==eHTMLTokenTypes(tkn->GetTokenType())){ if(eToken_attribute==eHTMLTokenTypes(tkn->GetTokenType())){
aNode.AddAttribute(tkn); aNode.AddAttribute(tkn);
} }
else (*mCurrentPos)--; else (*mParserContext->mCurrentPos)--;
} }
else return kInterrupted; else return kInterrupted;
} }
@ -649,18 +631,18 @@ PRInt32 nsParser::CollectAttributes(nsCParserNode& aNode,PRInt32 aCount){
*/ */
PRInt32 nsParser::CollectSkippedContent(nsCParserNode& aNode,PRInt32& aCount) { PRInt32 nsParser::CollectSkippedContent(nsCParserNode& aNode,PRInt32& aCount) {
eHTMLTokenTypes subtype=eToken_attribute; eHTMLTokenTypes subtype=eToken_attribute;
nsDequeIterator end=mTokenDeque.End(); nsDequeIterator end=mParserContext->mTokenDeque.End();
PRInt32 result=kNoError; PRInt32 result=kNoError;
aCount=0; aCount=0;
while((*mCurrentPos!=end) && (eToken_attribute==subtype)) { while((*mParserContext->mCurrentPos!=end) && (eToken_attribute==subtype)) {
CToken* tkn=(CToken*)(++(*mCurrentPos)); CToken* tkn=(CToken*)(++(*mParserContext->mCurrentPos));
subtype=eHTMLTokenTypes(tkn->GetTokenType()); subtype=eHTMLTokenTypes(tkn->GetTokenType());
if(eToken_skippedcontent==subtype) { if(eToken_skippedcontent==subtype) {
aNode.SetSkippedContent(tkn); aNode.SetSkippedContent(tkn);
aCount++; aCount++;
} }
else (*mCurrentPos)--; else (*mParserContext->mCurrentPos)--;
} }
return result; return result;
} }
@ -710,10 +692,9 @@ nsresult nsParser::OnStartBinding(const char *aSourceType){
if (nsnull != mObserver) { if (nsnull != mObserver) {
mObserver->OnStartBinding(aSourceType); mObserver->OnStartBinding(aSourceType);
} }
mAutoDetectStatus=eUnknownDetect; mParserContext->mAutoDetectStatus=eUnknownDetect;
mDTD=0; mParserContext->mDTD=0;
mParserContext->mSourceType=aSourceType;
mSourceType=aSourceType;
return kNoError; return kNoError;
} }
@ -732,37 +713,33 @@ nsresult nsParser::OnDataAvailable(nsIInputStream *pIStream, PRInt32 length){
mListener->OnDataAvailable(pIStream, length); mListener->OnDataAvailable(pIStream, length);
} }
*/ */
int len=0;
int offset=0;
if(eInvalidDetect==mAutoDetectStatus) { if(eInvalidDetect==mParserContext->mAutoDetectStatus) {
if(mScanner) { if(mParserContext->mScanner) {
mScanner->GetBuffer().Truncate(); mParserContext->mScanner->GetBuffer().Truncate();
} }
} }
do { int len=1; //init to a non-zero value
PRInt32 err; int err;
len = pIStream->Read(&err, mTransferBuffer, 0, gTransferBufferSize); int offset=0;
if(len>0) {
#ifdef DEBUG_SAVE_SOURCE_DOC while (len > 0) {
if(gTempStream) { len = pIStream->Read(&err, mParserContext->mTransferBuffer, 0, mParserContext->eTransferBufferSize);
gTempStream->write(mTransferBuffer,len); if(len>0) {
}
#endif
if (mParserFilter) if(mParserFilter)
mParserFilter->RawBuffer(mTransferBuffer, &len); mParserFilter->RawBuffer(mParserContext->mTransferBuffer, &len);
mScanner->Append(mTransferBuffer,len);
if(eUnknownDetect==mAutoDetectStatus) { mParserContext->mScanner->Append(mParserContext->mTransferBuffer,len);
if(eValidDetect==AutoDetectContentType(mScanner->GetBuffer(),mSourceType)) {
nsresult result=WillBuildModel(mURL->GetSpec()); if(eUnknownDetect==mParserContext->mAutoDetectStatus) {
} //if if(eValidDetect==AutoDetectContentType(mParserContext->mScanner->GetBuffer(),mParserContext->mSourceType)) {
} nsresult result=WillBuildModel(mParserContext->mScanner->GetFilename());
} //if } //if
} while (len > 0); }
} //if
}
nsresult result=ResumeParse(); nsresult result=ResumeParse();
return result; return result;
@ -797,7 +774,7 @@ nsresult nsParser::OnStopBinding(PRInt32 status, const nsString& aMsg){
* @return new token or null * @return new token or null
*/ */
PRInt32 nsParser::ConsumeToken(CToken*& aToken) { PRInt32 nsParser::ConsumeToken(CToken*& aToken) {
PRInt32 result=mDTD->ConsumeToken(aToken); PRInt32 result=mParserContext->mDTD->ConsumeToken(aToken);
return result; return result;
} }
@ -811,39 +788,11 @@ PRInt32 nsParser::ConsumeToken(CToken*& aToken) {
* @param * @param
* @return TRUE if it's ok to proceed * @return TRUE if it's ok to proceed
*/ */
PRBool nsParser::WillTokenize(void){ PRBool nsParser::WillTokenize(){
PRBool result=PR_TRUE; PRBool result=PR_TRUE;
return result; return result;
} }
/**
*
* @update gess 3/25/98
* @return TRUE if it's ok to proceed
*/
PRInt32 nsParser::Tokenize(nsString& aSourceBuffer,PRBool appendTokens){
CToken* theToken=0;
PRInt32 result=kNoError;
PRInt32 debugCounter=0; //this can be removed. It's only for debugging...
WillTokenize();
while(kNoError==result) {
debugCounter++;
result=ConsumeToken(theToken);
if(theToken && (kNoError==result)) {
#ifdef VERBOSE_DEBUG
theToken->DebugDumpToken(cout);
#endif
mTokenDeque.Push(theToken);
}
}
if(kEOF==result)
result=kNoError;
DidTokenize();
return result;
}
/** /**
* This is the primary control routine. It iteratively * This is the primary control routine. It iteratively
@ -853,14 +802,14 @@ PRInt32 nsParser::Tokenize(nsString& aSourceBuffer,PRBool appendTokens){
* @update gess 3/25/98 * @update gess 3/25/98
* @return error code * @return error code
*/ */
PRInt32 nsParser::Tokenize(void) { PRInt32 nsParser::Tokenize(){
CToken* theToken=0; CToken* theToken=0;
PRInt32 result=kNoError; PRInt32 result=kNoError;
PRBool done=(0==mMajorIteration) ? (!WillTokenize()) : PR_FALSE; PRBool done=(0==++mParserContext->mMajorIteration) ? (!WillTokenize()) : PR_FALSE;
while((PR_FALSE==done) && (kNoError==result)) { while((PR_FALSE==done) && (kNoError==result)) {
mScanner->Mark(); mParserContext->mScanner->Mark();
result=ConsumeToken(theToken); result=ConsumeToken(theToken);
if(kNoError==result) { if(kNoError==result) {
if(theToken) { if(theToken) {
@ -868,14 +817,14 @@ PRInt32 nsParser::Tokenize(void) {
#ifdef VERBOSE_DEBUG #ifdef VERBOSE_DEBUG
theToken->DebugDumpToken(cout); theToken->DebugDumpToken(cout);
#endif #endif
mTokenDeque.Push(theToken); mParserContext->mTokenDeque.Push(theToken);
} }
} }
else { else {
if(theToken) if(theToken)
delete theToken; delete theToken;
mScanner->RewindToMark(); mParserContext->mScanner->RewindToMark();
} }
} }
if((PR_TRUE==done) && (kInterrupted!=result)) if((PR_TRUE==done) && (kInterrupted!=result))
@ -892,7 +841,7 @@ PRInt32 nsParser::Tokenize(void) {
* @param * @param
* @return TRUE if all went well * @return TRUE if all went well
*/ */
PRBool nsParser::DidTokenize(void) { PRBool nsParser::DidTokenize(){
PRBool result=PR_TRUE; PRBool result=PR_TRUE;
#ifdef VERBOSE_DEBUG #ifdef VERBOSE_DEBUG
@ -912,8 +861,8 @@ PRBool nsParser::DidTokenize(void) {
* @return * @return
*/ */
void nsParser::DebugDumpTokens(ostream& out) { void nsParser::DebugDumpTokens(ostream& out) {
nsDequeIterator b=mTokenDeque.Begin(); nsDequeIterator b=mParserContext->mTokenDeque.Begin();
nsDequeIterator e=mTokenDeque.End(); nsDequeIterator e=mParserContext->mTokenDeque.End();
CToken* theToken; CToken* theToken;
while(b!=e) { while(b!=e) {
@ -933,8 +882,8 @@ void nsParser::DebugDumpTokens(ostream& out) {
* @return * @return
*/ */
void nsParser::DebugDumpSource(ostream& out) { void nsParser::DebugDumpSource(ostream& out) {
nsDequeIterator b=mTokenDeque.Begin(); nsDequeIterator b=mParserContext->mTokenDeque.Begin();
nsDequeIterator e=mTokenDeque.End(); nsDequeIterator e=mParserContext->mTokenDeque.End();
CToken* theToken; CToken* theToken;
while(b!=e) { while(b!=e) {

Просмотреть файл

@ -60,7 +60,7 @@
#include "nsParserNode.h" #include "nsParserNode.h"
#include "nsParserTypes.h" #include "nsParserTypes.h"
#include "nsIURL.h" #include "nsIURL.h"
#include "CParserContext.h"
#define NS_PARSER_IID \ #define NS_PARSER_IID \
{0x2ce606b0, 0xbee6, 0x11d1, \ {0x2ce606b0, 0xbee6, 0x11d1, \
@ -69,7 +69,6 @@
class IContentSink; class IContentSink;
class nsIHTMLContentSink; class nsIHTMLContentSink;
class nsIURL;
class nsIDTD; class nsIDTD;
class nsIDTDDebug; class nsIDTDDebug;
class CScanner; class CScanner;
@ -119,14 +118,26 @@ friend class CTokenHandler;
virtual CScanner* GetScanner(void); virtual CScanner* GetScanner(void);
/** /**
* Cause parser to parse input from given URL in given mode * Cause parser to parse input from given URL
* @update gess5/11/98 * @update gess5/11/98
* @param aURL is a descriptor for source document * @param aURL is a descriptor for source document
* @param aListener is a listener to forward notifications to * @param aListener is a listener to forward notifications to
* @return TRUE if all went well -- FALSE otherwise * @return TRUE if all went well -- FALSE otherwise
*/ */
virtual PRInt32 Parse(nsIURL* aURL, virtual PRInt32 Parse(nsIURL* aURL,
nsIStreamObserver* aListener, nsIDTDDebug * aDTDDebug = 0); nsIStreamObserver* aListener,
nsIDTDDebug* aDTDDebug = 0);
/**
* Cause parser to parse input from given nsIInputStream
* @update gess5/11/98
* @param pIStream is an nsIInputStream
* @param aListener is a listener to forward notifications to
* @return TRUE if all went well -- FALSE otherwise
*/
virtual PRInt32 Parse(nsIInputStream* pIStream,
nsIStreamObserver* aListener,
nsIDTDDebug* aDTDDebug = 0);
/** /**
* Cause parser to parse input from given file in given mode * Cause parser to parse input from given file in given mode
@ -134,7 +145,7 @@ friend class CTokenHandler;
* @param aFilename is a path for file document * @param aFilename is a path for file document
* @return TRUE if all went well -- FALSE otherwise * @return TRUE if all went well -- FALSE otherwise
*/ */
virtual PRInt32 Parse(const char* aFilename); virtual PRInt32 Parse(nsString& aFilename);
/** /**
* Cause parser to parse input from given stream * Cause parser to parse input from given stream
@ -157,7 +168,7 @@ friend class CTokenHandler;
* @update gess5/11/98 * @update gess5/11/98
* @return TRUE if all went well, otherwise FALSE * @return TRUE if all went well, otherwise FALSE
*/ */
virtual PRInt32 ResumeParse(void); virtual PRInt32 ResumeParse();
/** /**
* Causes the parser to scan foward, collecting nearby (sequential) * Causes the parser to scan foward, collecting nearby (sequential)
@ -208,7 +219,7 @@ protected:
* @param * @param
* @return * @return
*/ */
PRInt32 WillBuildModel(const char* aFilename=0); PRInt32 WillBuildModel(nsString& aFilename);
/** /**
* *
@ -224,7 +235,7 @@ protected:
* @update gess5/11/98 * @update gess5/11/98
* @return YES if model building went well -- NO otherwise. * @return YES if model building went well -- NO otherwise.
*/ */
virtual PRInt32 IterateTokens(void); virtual PRInt32 BuildModel(void);
private: private:
@ -251,15 +262,9 @@ private:
* @param * @param
* @return TRUE if it's ok to proceed * @return TRUE if it's ok to proceed
*/ */
PRBool WillTokenize(void); PRBool WillTokenize();
/**
*
* @update gess 3/25/98
* @return TRUE if it's ok to proceed
*/
PRInt32 Tokenize(nsString& aSourceBuffer,PRBool appendTokens);
/** /**
* This is the primary control routine. It iteratively * This is the primary control routine. It iteratively
* consumes tokens until an error occurs or you run out * consumes tokens until an error occurs or you run out
@ -268,7 +273,7 @@ private:
* @update gess 3/25/98 * @update gess 3/25/98
* @return error code * @return error code
*/ */
PRInt32 Tokenize(void); PRInt32 Tokenize();
/** /**
* This is the tail-end of the code sandwich for the * This is the tail-end of the code sandwich for the
@ -279,7 +284,7 @@ private:
* @param * @param
* @return TRUE if all went well * @return TRUE if all went well
*/ */
PRBool DidTokenize(void); PRBool DidTokenize();
/** /**
* This debug routine is used to cause the tokenizer to * This debug routine is used to cause the tokenizer to
@ -311,27 +316,42 @@ protected:
// And now, some data members... // And now, some data members...
//********************************************* //*********************************************
nsIStreamObserver* mObserver; /*****************************************************
nsIContentSink* mSink; All of these moved into the parse-context object:
nsIParserFilter* mParserFilter;
nsDequeIterator* mCurrentPos;
nsDequeIterator* mMarkPos;
nsIDTD* mDTD;
eParseMode mParseMode;
char* mTransferBuffer;
PRInt32 mMajorIteration; PRInt32 mMajorIteration;
PRInt32 mMinorIteration; PRInt32 mMinorIteration;
nsDeque mTokenDeque;
CScanner* mScanner;
nsIURL* mURL; nsIURL* mURL;
nsIDTDDebug* mDTDDebug;
nsString mSourceType; nsString mSourceType;
nsString mTargetType; nsString mTargetType;
eAutoDetectResult mAutoDetectStatus; eAutoDetectResult mAutoDetectStatus;
nsDequeIterator* mCurrentPos;
nsDequeIterator* mMarkPos;
nsDeque mTokenDeque;
CScanner* mScanner;
nsIDTD* mDTD;
eParseMode mParseMode;
char* mTransferBuffer;
*****************************************************/
CParserContext* mParserContext;
/*****************************************************
The above fields are moving into parse-context
*****************************************************/
nsIStreamObserver* mObserver;
nsIContentSink* mSink;
nsIParserFilter* mParserFilter;
nsIDTDDebug* mDTDDebug;
}; };

Просмотреть файл

@ -19,10 +19,8 @@
//#define __INCREMENTAL 1 //#define __INCREMENTAL 1
#include "nsScanner.h" #include "nsScanner.h"
#include "nsIURL.h"
#include "nsDebug.h" #include "nsDebug.h"
const char* gURLRef=0;
const char* kBadHTMLText="<H3>Oops...</H3>You just tried to read a non-existent document: <BR>"; const char* kBadHTMLText="<H3>Oops...</H3>You just tried to read a non-existent document: <BR>";
#ifdef __INCREMENTAL #ifdef __INCREMENTAL
@ -31,89 +29,55 @@ const int kBufsize=1;
const int kBufsize=64; const int kBufsize=64;
#endif #endif
/** /**
* Use this constructor if you want an incremental (callback) * Use this constructor if you want i/o to be based on an
* based input stream. * incremental netstream. If you pass a null filename, you
* can still provide data to the scanner via append.
* *
* @update gess 5/12/98 * @update gess 5/12/98
* @param aMode represents the parser mode (nav, other) * @param aFilename --
* @return * @return
*/ */
CScanner::CScanner(eParseMode aMode) : mBuffer("") { CScanner::CScanner(nsString& aFilename,PRBool aCreateStream) :
mBuffer(""), mFilename(aFilename)
{
mOffset=0; mOffset=0;
mMarkPos=-1; mMarkPos=-1;
mTotalRead=0; mTotalRead=0;
mParseMode=aMode; mOwnsStream=aCreateStream;
mNetStream=0;
mFileStream=0; mFileStream=0;
mIncremental=PR_TRUE; if(aCreateStream) {
mOwnsStream=PR_TRUE; char buffer[513];
aFilename.ToCString(buffer,sizeof(buffer)-1);
#if defined(XP_UNIX) && (defined(IRIX) || defined(MKLINUX))
/* XXX: IRIX does not support ios::binary */
mFileStream=new fstream(buffer,ios::in);
#else
mFileStream=new fstream(buffer,ios::in|ios::binary);
#endif
} //if
} }
/** /**
* Use this constructor if you want i/o to be file based. * Use this constructor if you want i/o to be stream based.
* *
* @update gess 5/12/98 * @update gess 5/12/98
* @param aMode represents the parser mode (nav, other) * @param aStream --
* @param assumeOwnership --
* @param aFilename --
* @return * @return
*/ */
CScanner::CScanner(const char* aFilename,eParseMode aMode) : mBuffer("") { CScanner::CScanner(nsString& aFilename,fstream& aStream,PRBool assumeOwnership) :
NS_ASSERTION(0!=aFilename,"Error: Null filename!"); mBuffer(""), mFilename(aFilename)
{
mOffset=0; mOffset=0;
mMarkPos=-1; mMarkPos=-1;
mTotalRead=0; mTotalRead=0;
mParseMode=aMode; mOwnsStream=assumeOwnership;
mNetStream=0;
mIncremental=PR_FALSE;
mOwnsStream=PR_TRUE;
#if defined(XP_UNIX) && (defined(IRIX) || defined(MKLINUX))
/* XXX: IRIX does not support ios::binary */
mFileStream=new fstream(aFilename,ios::in);
#else
mFileStream=new fstream(aFilename,ios::in|ios::binary);
#endif
}
/**
* Use this constructor if you want i/o to be file based.
*
* @update gess 5/12/98
* @param aMode represents the parser mode (nav, other)
* @return
*/
CScanner::CScanner(fstream& aStream,eParseMode aMode) : mBuffer("") {
mOffset=0;
mMarkPos=-1;
mTotalRead=0;
mParseMode=aMode;
mNetStream=0;
mIncremental=PR_FALSE;
mOwnsStream=PR_FALSE;
mFileStream=&aStream; mFileStream=&aStream;
} }
/**
* Use this constructor if you want i/o to be based on a
* non-incremental netstream.
*
* @update gess 5/12/98
* @param aMode represents the parser mode (nav, other)
* @return
*/
CScanner::CScanner(nsIURL* aURL,eParseMode aMode) : mBuffer("") {
NS_ASSERTION(0!=aURL,"Error: Null URL!");
mOffset=0;
mMarkPos=-1;
mTotalRead=0;
mParseMode=aMode;
mFileStream=0;
PRInt32 error=0;
mIncremental=PR_FALSE;
mNetStream=aURL->Open(&error);
gURLRef=aURL->GetSpec();
mOwnsStream=PR_FALSE;
}
/** /**
* default destructor * default destructor
@ -128,13 +92,7 @@ CScanner::~CScanner() {
if(mOwnsStream) if(mOwnsStream)
delete mFileStream; delete mFileStream;
} }
else if(mNetStream) {
mNetStream->Close();
mNetStream->Release();
}
mFileStream=0; mFileStream=0;
mNetStream=0;
gURLRef=0;
} }
/** /**
@ -200,34 +158,9 @@ void _PreCompressBuffer(nsString& aBuffer,PRInt32& anOffset,PRInt32& aMarkPos){
} }
/**
* This method should only be called by the parser when
* we're doing incremental i/o over the net.
*
* @update gess 5/12/98
* @param aBuffer contains next blob of i/o data
* @param aSize contains size of buffer
* @return 0 if all went well, otherwise error code.
*/
PRInt32 CScanner::IncrementalAppend(const char* aBuffer,PRInt32 aSize){
NS_ASSERTION(((!mFileStream) && (!mNetStream)),"Error: Should only be called during incremental net i/o!");
PRInt32 result=0;
if((!mFileStream) && (!mNetStream)) {
_PreCompressBuffer(mBuffer,mOffset,mMarkPos);
//now that the buffer is (possibly) shortened, let's append the new data.
if(0<aSize) {
mBuffer.Append(aBuffer,aSize);
mTotalRead+=aSize;
}
}
return result;
}
/** /**
* Grab data from underlying stream. * Append data to our underlying input buffer as
* if it were read from an input stream.
* *
* @update gess4/3/98 * @update gess4/3/98
* @return error code * @return error code
@ -235,6 +168,7 @@ PRInt32 CScanner::IncrementalAppend(const char* aBuffer,PRInt32 aSize){
PRBool CScanner::Append(nsString& aBuffer) { PRBool CScanner::Append(nsString& aBuffer) {
_PreCompressBuffer(mBuffer,mOffset,mMarkPos); _PreCompressBuffer(mBuffer,mOffset,mMarkPos);
mBuffer.Append(aBuffer); mBuffer.Append(aBuffer);
mTotalRead+=aBuffer.Length();
return PR_TRUE; return PR_TRUE;
} }
@ -248,6 +182,7 @@ PRBool CScanner::Append(nsString& aBuffer) {
PRBool CScanner::Append(const char* aBuffer, PRInt32 aLen){ PRBool CScanner::Append(const char* aBuffer, PRInt32 aLen){
_PreCompressBuffer(mBuffer,mOffset,mMarkPos); _PreCompressBuffer(mBuffer,mOffset,mMarkPos);
mBuffer.Append(aBuffer,aLen); mBuffer.Append(aBuffer,aLen);
mTotalRead+=aLen;
return PR_TRUE; return PR_TRUE;
} }
@ -262,18 +197,18 @@ PRInt32 CScanner::FillBuffer(void) {
_PreCompressBuffer(mBuffer,mOffset,mMarkPos); _PreCompressBuffer(mBuffer,mOffset,mMarkPos);
if((!mIncremental) && (!mNetStream) && (!mFileStream)) { if(!mFileStream) {
//This is DEBUG code!!!!!! XXX DEBUG XXX //This is DEBUG code!!!!!! XXX DEBUG XXX
//If you're here, it means someone tried to load a //If you're here, it means someone tried to load a
//non-existent document. So as a favor, we emit a //non-existent document. So as a favor, we emit a
//little bit of HTML explaining the error. //little bit of HTML explaining the error.
if(0==mTotalRead) { if(0==mTotalRead) {
mBuffer.Append((const char*)kBadHTMLText); mBuffer.Append((const char*)kBadHTMLText);
mBuffer.Append((const char*)gURLRef); mBuffer.Append(mFilename);
} }
else return 0; else return kInterrupted;
} }
else if(!mIncremental) { else {
PRInt32 numread=0; PRInt32 numread=0;
char buf[kBufsize+1]; char buf[kBufsize+1];
buf[kBufsize]=0; buf[kBufsize]=0;
@ -282,17 +217,11 @@ PRInt32 CScanner::FillBuffer(void) {
mFileStream->read(buf,kBufsize); mFileStream->read(buf,kBufsize);
numread=mFileStream->gcount(); numread=mFileStream->gcount();
} }
else if(mNetStream) {
numread=mNetStream->Read(&anError,buf,0,kBufsize);
if(1==anError)
anError=kEOF;
}
mOffset=mBuffer.Length(); mOffset=mBuffer.Length();
if((0<numread) && (0==anError)) if((0<numread) && (0==anError))
mBuffer.Append((const char*)buf,numread); mBuffer.Append((const char*)buf,numread);
mTotalRead+=mBuffer.Length(); mTotalRead+=mBuffer.Length();
} }
else anError=kInterrupted;
return anError; return anError;
} }
@ -308,9 +237,7 @@ PRInt32 CScanner::Eof() {
PRInt32 theError=0; PRInt32 theError=0;
if(mOffset>=mBuffer.Length()) { if(mOffset>=mBuffer.Length()) {
if(!mIncremental) theError=FillBuffer();
theError=FillBuffer();
else return kInterrupted;
} }
if(0==theError) if(0==theError)
@ -451,21 +378,21 @@ PRInt32 CScanner::SkipPast(nsString& aValidSet){
* @return error code * @return error code
*/ */
PRInt32 CScanner::ReadWhile(nsString& aString,nsString& aValidSet,PRBool addTerminal){ PRInt32 CScanner::ReadWhile(nsString& aString,nsString& aValidSet,PRBool addTerminal){
PRUnichar ch=0; PRUnichar theChar=0;
PRInt32 result=kNoError; PRInt32 result=kNoError;
PRInt32 wrPos=0; PRInt32 wrPos=0;
while(kNoError==result) { while(kNoError==result) {
result=GetChar(ch); result=GetChar(theChar);
if(kNoError==result) { if(kNoError==result) {
PRInt32 pos=aValidSet.Find(ch); PRInt32 pos=aValidSet.Find(theChar);
if(kNotFound==pos) { if(kNotFound==pos) {
if(addTerminal) if(addTerminal)
aString+=ch; aString+=theChar;
else PutBack(ch); else PutBack(theChar);
break; break;
} }
else aString+=ch; else aString+=theChar;
} }
} }
return result; return result;
@ -535,6 +462,18 @@ nsString& CScanner::GetBuffer(void) {
return mBuffer; return mBuffer;
} }
/**
* Retrieve the name of the file that the scanner is reading from.
* In some cases, it's just a given name, because the scanner isn't
* really reading from a file.
*
* @update gess 5/12/98
* @return
*/
nsString& CScanner::GetFilename(void) {
return mFilename;
}
/** /**
* Conduct self test. Actually, selftesting for this class * Conduct self test. Actually, selftesting for this class
* occurs in the parser selftest. * occurs in the parser selftest.

Просмотреть файл

@ -35,43 +35,21 @@
#include "nsString.h" #include "nsString.h"
#include "nsParserTypes.h" #include "nsParserTypes.h"
#include "prtypes.h" #include "prtypes.h"
#include "nsIInputStream.h"
#include <fstream.h> #include <fstream.h>
class nsIURL;
//class ifstream;
class CScanner { class CScanner {
public: public:
/** /**
* Use this constructor if you want an incremental (callback) * Use this constructor if you want i/o to be based on
* based input stream. * a file (therefore a stream) or just data you provide via Append().
* *
* @update gess 5/12/98 * @update gess 5/12/98
* @param aMode represents the parser mode (nav, other) * @param aMode represents the parser mode (nav, other)
* @return * @return
*/ */
CScanner(eParseMode aMode=eParseMode_navigator); CScanner(nsString& aFilename,PRBool aCreateStream=PR_TRUE);
/**
* Use this constructor if you want i/o to be based on a
* non-incremental netstream.
*
* @update gess 5/12/98
* @param aMode represents the parser mode (nav, other)
* @return
*/
CScanner(nsIURL* aURL,eParseMode aMode=eParseMode_navigator);
/**
* Use this constructor if you want i/o to be file based.
*
* @update gess 5/12/98
* @param aMode represents the parser mode (nav, other)
* @return
*/
CScanner(const char* aFilename,eParseMode aMode=eParseMode_navigator);
/** /**
* Use this constructor if you want i/o to be stream based. * Use this constructor if you want i/o to be stream based.
@ -80,7 +58,7 @@ class CScanner {
* @param aMode represents the parser mode (nav, other) * @param aMode represents the parser mode (nav, other)
* @return * @return
*/ */
CScanner(fstream& aStream,eParseMode aMode=eParseMode_navigator); CScanner(nsString& aFilename,fstream& aStream,PRBool assumeOwnership=PR_TRUE);
~CScanner(); ~CScanner();
@ -241,16 +219,17 @@ class CScanner {
* @param * @param
* @return * @return
*/ */
PRInt32 IncrementalAppend(const char* aBuffer,PRInt32 aSize); nsString& GetBuffer(void);
/** /**
* * Retrieve the name of the file that the scanner is reading from.
* In some cases, it's just a given name, because the scanner isn't
* really reading from a file.
* *
* @update gess 5/12/98 * @update gess 5/12/98
* @param
* @return * @return
*/ */
nsString& GetBuffer(void); nsString& GetFilename(void);
static void SelfTest(); static void SelfTest();
@ -268,13 +247,11 @@ class CScanner {
fstream* mFileStream; fstream* mFileStream;
nsIInputStream* mNetStream;
nsString mBuffer; nsString mBuffer;
nsString mFilename;
PRInt32 mOffset; PRInt32 mOffset;
PRInt32 mMarkPos; PRInt32 mMarkPos;
PRInt32 mTotalRead; PRInt32 mTotalRead;
eParseMode mParseMode;
PRBool mIncremental;
PRBool mOwnsStream; PRBool mOwnsStream;
}; };

Просмотреть файл

@ -190,7 +190,7 @@ eAutoDetectResult CValidDTD::AutoDetectContentType(nsString& aBuffer,nsString& a
* @param * @param
* @return * @return
*/ */
PRInt32 CValidDTD::WillBuildModel(const char* aFilename){ PRInt32 CValidDTD::WillBuildModel(nsString& aFilename){
PRInt32 result=0; PRInt32 result=0;
return result; return result;
} }

Просмотреть файл

@ -108,7 +108,7 @@ class CValidDTD : public nsIDTD {
* @param * @param
* @return * @return
*/ */
virtual PRInt32 WillBuildModel(const char* aFilename=0); virtual PRInt32 WillBuildModel(nsString& aFilename);
/** /**
* *

Просмотреть файл

@ -177,7 +177,7 @@ eAutoDetectResult CWellFormedDTD::AutoDetectContentType(nsString& aBuffer,nsStri
* @param * @param
* @return * @return
*/ */
PRInt32 CWellFormedDTD::WillBuildModel(const char* aFilename){ PRInt32 CWellFormedDTD::WillBuildModel(nsString& aFilename){
PRInt32 result=0; PRInt32 result=0;
return result; return result;
} }

Просмотреть файл

@ -97,7 +97,7 @@ class CWellFormedDTD : public nsIDTD {
* @param * @param
* @return * @return
*/ */
virtual PRInt32 WillBuildModel(const char* aFilename=0); virtual PRInt32 WillBuildModel(nsString& aFilename);
/** /**
* *