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};
/************************************************************************
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.
* 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;
}
/**
* This method is defined in nsIParser. It is used to
* cause the COM-like construction of an nsParser.
@ -234,15 +344,13 @@ static CNavTokenDeallocator gTokenKiller;
* @param
* @return
*/
CNavDTD::CNavDTD() : nsIDTD(), mTokenDeque(gTokenKiller) {
CNavDTD::CNavDTD() : nsIDTD(), mTokenDeque(gTokenKiller),
mContextStack(), mStyleStack() {
NS_INIT_REFCNT();
mParser=0;
mFilename=0;
mSink = nsnull;
mDTDDebug=0;
nsCRT::zero(mTokenHandlers,sizeof(mTokenHandlers));
mContextStackPos=0;
mStyleStackPos=0;
mHasOpenForm=PR_FALSE;
mHasOpenMap=PR_FALSE;
InitializeDefaultTokenHandlers();
@ -257,8 +365,6 @@ CNavDTD::CNavDTD() : nsIDTD(), mTokenDeque(gTokenKiller) {
*/
CNavDTD::~CNavDTD(){
DeleteTokenHandlers();
if (mFilename)
PL_strfree(mFilename);
if (mDTDDebug)
NS_RELEASE(mDTDDebug);
@ -281,6 +387,7 @@ void CNavDTD::SetDTDDebug(nsIDTDDebug * aDTDDebug)
NS_ADDREF(mDTDDebug);
}
/**
* This method is called to determine if the given DTD can parse
* a document in a given source-type.
@ -308,24 +415,16 @@ eAutoDetectResult CNavDTD::AutoDetectContentType(nsString& aBuffer,nsString& aTy
return result;
}
/**
*
* @update gess5/18/98
* @param
* @return
*/
PRInt32 CNavDTD::WillBuildModel(const char* aFilename){
PRInt32 CNavDTD::WillBuildModel(nsString& aFilename){
PRInt32 result=0;
if (mFilename) {
PL_strfree(mFilename);
mFilename=0;
}
if(aFilename) {
mFilename = PL_strdup(aFilename);
}
mFilename=aFilename;
if(mSink)
mSink->WillBuildModel();
@ -342,7 +441,7 @@ PRInt32 CNavDTD::WillBuildModel(const char* aFilename){
PRInt32 CNavDTD::DidBuildModel(PRInt32 anErrorCode){
PRInt32 result=0;
if((kNoError==anErrorCode) && (mContextStackPos>0)) {
if((kNoError==anErrorCode) && (mContextStack.mCount>0)) {
CloseContainersTo(0,eHTMLTag_unknown,PR_FALSE);
}
if(mSink) {
@ -375,7 +474,7 @@ PRInt32 CNavDTD::HandleToken(CToken* aToken){
if(theHandler) {
result=(*theHandler)(theToken,this);
if (mDTDDebug)
mDTDDebug->Verify(this, mParser, mContextStackPos, mContextStack, mFilename);
mDTDDebug->Verify(this, mParser, mContextStack.mCount, mContextStack.mTags, mFilename);
}
}//if
@ -420,13 +519,13 @@ PRInt32 CNavDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsIP
}
if(IsContainer(aChildTag)){
if(PR_TRUE==(PRBool)mLeafBits[mContextStackPos-1]) {
if(PR_TRUE==mContextStack.mBits[mContextStack.mCount-1]) {
CloseTransientStyles(aChildTag);
}
result=OpenContainer(aNode,PR_TRUE);
}
else {
if(PR_FALSE==(PRBool)mLeafBits[mContextStackPos-1]) {
if(PR_FALSE==mContextStack.mBits[mContextStack.mCount-1]) {
OpenTransientStyles(aChildTag);
}
result=AddLeaf(aNode);
@ -576,16 +675,8 @@ PRInt32 CNavDTD::HandleEndToken(CToken* aToken) {
// we have to handle explicit styles the way it does. That means
// 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
// 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...
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
// ones off so it's safe to do it now) because they don't carry
// forward across table cell boundaries.
mStyleStackPos = 0;
mStyleStack.mCount=0;
break;
default:
@ -1148,8 +1239,8 @@ PRBool CNavDTD::CanContain(PRInt32 aParent,PRInt32 aChild) {
break; //singletons can't contain anything...
case eHTMLTag_li:
if ((eHTMLTag_li == aChild) ||
(eHTMLTag_ul == aChild) || // XXX this is temporary!!!
if ((eHTMLTag_li == aChild) || //XXX this is temporary!!!
(eHTMLTag_ul == aChild) ||
(eHTMLTag_ol == aChild) ||
(eHTMLTag_menu == aChild) ||
(eHTMLTag_dir == aChild)) {
@ -1620,29 +1711,6 @@ PRBool CNavDTD::BackwardPropagate(nsString& aVector,eHTMLTags aParentTag,eHTMLTa
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
* element is currently open.
@ -1672,9 +1740,7 @@ PRBool CNavDTD::HasOpenContainer(eHTMLTags aContainer) const {
* @return tag id of topmost node in contextstack
*/
eHTMLTags CNavDTD::GetTopNode() const {
if(mContextStackPos)
return (eHTMLTags)(int)mContextStack[mContextStackPos-1];
return eHTMLTag_unknown;
return mContextStack.Last();
}
@ -1688,8 +1754,8 @@ eHTMLTags CNavDTD::GetTopNode() const {
*/
PRInt32 CNavDTD::GetTopmostIndexOf(eHTMLTags aTag) const {
int i=0;
for(i=mContextStackPos-1;i>=0;i--){
if((eHTMLTags)(int)mContextStack[i]==aTag)
for(i=mContextStack.mCount-1;i>=0;i--){
if(mContextStack.mTags[i]==aTag)
return i;
}
return kNotFound;
@ -1720,8 +1786,8 @@ PRInt32 CNavDTD::OpenTransientStyles(eHTMLTags aTag){
eHTMLTags parentTag=GetTopNode();
if(CanContainStyles(parentTag)) {
for(pos=0;pos<mStyleStackPos;pos++) {
eHTMLTags theTag=(eHTMLTags)(int)mStyleStack[pos];
for(pos=0;pos<mStyleStack.mCount;pos++) {
eHTMLTags theTag=mStyleStack.mTags[pos];
if(PR_FALSE==HasOpenContainer(theTag)) {
CStartToken token(GetTagName(theTag));
@ -1735,7 +1801,7 @@ PRInt32 CNavDTD::OpenTransientStyles(eHTMLTags aTag){
default:
token.SetTypeID(theTag); //open the html container...
result=OpenContainer(theNode,PR_FALSE);
mLeafBits.ReplaceElementAt((void*)PR_TRUE,mContextStackPos-1);
mContextStack.mBits[mContextStack.mCount-1]=PR_TRUE;
} //switch
}
if(kNoError!=result)
@ -1761,11 +1827,11 @@ PRInt32 CNavDTD::OpenTransientStyles(eHTMLTags aTag){
PRInt32 CNavDTD::CloseTransientStyles(eHTMLTags aTag){
PRInt32 result=0;
if((mStyleStackPos>0) && (mLeafBits[mContextStackPos-1])) {
if((mStyleStack.mCount>0) && (mContextStack.mBits[mContextStack.mCount-1])) {
if(0==strchr(gWhitespaceTags,aTag)){
result=CloseContainersTo((eHTMLTags)(int)mStyleStack[0],PR_FALSE);
mLeafBits.ReplaceElementAt((void*)PR_FALSE,mContextStackPos-1);
result=CloseContainersTo(mStyleStack.mTags[0],PR_FALSE);
mContextStack.mBits[mContextStack.mCount-1]=PR_FALSE;
}//if
}//if
@ -1782,10 +1848,10 @@ PRInt32 CNavDTD::CloseTransientStyles(eHTMLTags aTag){
* @return TRUE if ok, FALSE if error
*/
PRInt32 CNavDTD::OpenHTML(const nsIParserNode& aNode){
NS_PRECONDITION(mContextStackPos >= 0, kInvalidTagStackPos);
NS_PRECONDITION(mContextStack.mCount >= 0, kInvalidTagStackPos);
PRInt32 result=mSink->OpenHTML(aNode);
mContextStack.ReplaceElementAt((void*)aNode.GetNodeType(),mContextStackPos++);
mContextStack.Push((eHTMLTags)aNode.GetNodeType());
return result;
}
@ -1799,9 +1865,9 @@ PRInt32 CNavDTD::OpenHTML(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error
*/
PRInt32 CNavDTD::CloseHTML(const nsIParserNode& aNode){
NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos);
NS_PRECONDITION(mContextStack.mCount > 0, kInvalidTagStackPos);
PRInt32 result=mSink->CloseHTML(aNode);
mContextStack.ReplaceElementAt((void*)eHTMLTag_unknown,--mContextStackPos);
mContextStack.Pop();
return result;
}
@ -1815,7 +1881,7 @@ PRInt32 CNavDTD::CloseHTML(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error
*/
PRInt32 CNavDTD::OpenHead(const nsIParserNode& aNode){
mContextStack.ReplaceElementAt((void*)eHTMLTag_head,++mContextStackPos);
mContextStack.Push(eHTMLTag_head);
PRInt32 result=mSink->OpenHead(aNode);
return result;
}
@ -1830,7 +1896,7 @@ PRInt32 CNavDTD::OpenHead(const nsIParserNode& aNode){
*/
PRInt32 CNavDTD::CloseHead(const nsIParserNode& aNode){
PRInt32 result=mSink->CloseHead(aNode);
mContextStack.ReplaceElementAt((void*)eHTMLTag_unknown,--mContextStackPos);
mContextStack.Pop();
return result;
}
@ -1843,7 +1909,7 @@ PRInt32 CNavDTD::CloseHead(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error
*/
PRInt32 CNavDTD::OpenBody(const nsIParserNode& aNode){
NS_PRECONDITION(mContextStackPos >= 0, kInvalidTagStackPos);
NS_PRECONDITION(mContextStack.mCount >= 0, kInvalidTagStackPos);
PRInt32 result=kNoError;
eHTMLTags topTag=GetTopNode();
@ -1875,7 +1941,7 @@ PRInt32 CNavDTD::OpenBody(const nsIParserNode& aNode){
if(kNoError==result) {
result=mSink->OpenBody(aNode);
mContextStack.ReplaceElementAt((void*)aNode.GetNodeType(),mContextStackPos++);
mContextStack.Push((eHTMLTags)aNode.GetNodeType());
}
return result;
}
@ -1889,9 +1955,9 @@ PRInt32 CNavDTD::OpenBody(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error
*/
PRInt32 CNavDTD::CloseBody(const nsIParserNode& aNode){
NS_PRECONDITION(mContextStackPos >= 0, kInvalidTagStackPos);
NS_PRECONDITION(mContextStack.mCount >= 0, kInvalidTagStackPos);
PRInt32 result=mSink->CloseBody(aNode);
mContextStack.ReplaceElementAt((void*)eHTMLTag_unknown,--mContextStackPos);
mContextStack.Pop();
return result;
}
@ -1980,9 +2046,9 @@ PRInt32 CNavDTD::CloseMap(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error
*/
PRInt32 CNavDTD::OpenFrameset(const nsIParserNode& aNode){
NS_PRECONDITION(mContextStackPos >= 0, kInvalidTagStackPos);
NS_PRECONDITION(mContextStack.mCount >= 0, kInvalidTagStackPos);
PRInt32 result=mSink->OpenFrameset(aNode);
mContextStack.ReplaceElementAt((void*)aNode.GetNodeType(),mContextStackPos++);
mContextStack.Push((eHTMLTags)aNode.GetNodeType());
return result;
}
@ -1995,9 +2061,9 @@ PRInt32 CNavDTD::OpenFrameset(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error
*/
PRInt32 CNavDTD::CloseFrameset(const nsIParserNode& aNode){
NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos);
NS_PRECONDITION(mContextStack.mCount > 0, kInvalidTagStackPos);
PRInt32 result=mSink->CloseFrameset(aNode);
mContextStack.ReplaceElementAt((void*)eHTMLTag_unknown,--mContextStackPos);
mContextStack.Pop();
return result;
}
@ -2011,7 +2077,7 @@ PRInt32 CNavDTD::CloseFrameset(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error
*/
PRInt32 CNavDTD::OpenContainer(const nsIParserNode& aNode,PRBool aUpdateStyleStack){
NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos);
NS_PRECONDITION(mContextStack.mCount > 0, kInvalidTagStackPos);
PRInt32 result=kNoError;
eHTMLTags nodeType=(eHTMLTags)aNode.GetNodeType();
@ -2037,7 +2103,7 @@ PRInt32 CNavDTD::OpenContainer(const nsIParserNode& aNode,PRBool aUpdateStyleSta
default:
result=mSink->OpenContainer(aNode);
mContextStack.ReplaceElementAt((void*)nodeType,mContextStackPos++);
mContextStack.Push((eHTMLTags)aNode.GetNodeType());
break;
}
@ -2057,7 +2123,7 @@ PRInt32 CNavDTD::OpenContainer(const nsIParserNode& aNode,PRBool aUpdateStyleSta
* @return TRUE if ok, FALSE if error
*/
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
eHTMLTags nodeType=(eHTMLTags)aNode.GetNodeType();
@ -2085,11 +2151,11 @@ PRInt32 CNavDTD::CloseContainer(const nsIParserNode& aNode,eHTMLTags aTag,PRBool
case eHTMLTag_title:
default:
result=mSink->CloseContainer(aNode);
mContextStack.ReplaceElementAt((void*)eHTMLTag_unknown,--mContextStackPos);
mContextStack.Pop();
break;
}
mLeafBits.ReplaceElementAt((void*)PR_FALSE, mContextStackPos);
mContextStack.mBits[mContextStack.mCount]=PR_FALSE;
if((kNoError==result) && (PR_TRUE==aUpdateStyles)){
UpdateStyleStackForCloseTag(nodeType,aTag);
}
@ -2106,15 +2172,15 @@ PRInt32 CNavDTD::CloseContainer(const nsIParserNode& aNode,eHTMLTags aTag,PRBool
* @return TRUE if ok, FALSE if error
*/
PRInt32 CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTag,PRBool aUpdateStyles){
NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos);
NS_PRECONDITION(mContextStack.mCount > 0, kInvalidTagStackPos);
PRInt32 result=kNoError;
CEndToken aToken(gEmpty);
nsCParserNode theNode(&aToken);
if((anIndex<mContextStackPos) && (anIndex>=0)) {
while(mContextStackPos>anIndex) {
eHTMLTags theTag=(eHTMLTags)(int)mContextStack[mContextStackPos-1];
if((anIndex<mContextStack.mCount) && (anIndex>=0)) {
while(mContextStack.mCount>anIndex) {
eHTMLTags theTag=mContextStack.Last();
aToken.SetTypeID(theTag);
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
*/
PRInt32 CNavDTD::CloseContainersTo(eHTMLTags aTag,PRBool aUpdateStyles){
NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos);
NS_PRECONDITION(mContextStack.mCount > 0, kInvalidTagStackPos);
PRInt32 pos=GetTopmostIndexOf(aTag);
@ -2172,10 +2238,10 @@ PRInt32 CNavDTD::CloseContainersTo(eHTMLTags aTag,PRBool aUpdateStyles){
* @return TRUE if ok, FALSE if error
*/
PRInt32 CNavDTD::CloseTopmostContainer(){
NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos);
NS_PRECONDITION(mContextStack.mCount > 0, kInvalidTagStackPos);
CEndToken aToken(gEmpty);
eHTMLTags theTag=(eHTMLTags)(int)mContextStack[mContextStackPos-1];
eHTMLTags theTag=mContextStack.Last();
aToken.SetTypeID(theTag);
nsCParserNode theNode(&aToken);
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...
pos=0;
cnt=theVector.Length()-1;
if(mContextStack[mContextStackPos-1]==(void*)theVector[cnt])
if(mContextStack.Last()==(eHTMLTags)theVector[cnt])
result=kNoError;
else result=kContextMismatch;
}
@ -2236,8 +2302,8 @@ PRInt32 CNavDTD::CreateContextStackFor(eHTMLTags aChildTag){
pos=0;
cnt=theVector.Length();
result=kNoError;
while(pos<mContextStackPos) {
if(mContextStack[pos]==(void*)theVector[cnt-1-pos]) {
while(pos<mContextStack.mCount) {
if(mContextStack.mTags[pos]==(eHTMLTags)theVector[cnt-1-pos]) {
pos++;
}
else {
@ -2321,7 +2387,7 @@ PRInt32 CNavDTD::UpdateStyleStackForOpenTag(eHTMLTags aTag,eHTMLTags anActualTag
case eHTMLTag_tt:
case eHTMLTag_u:
case eHTMLTag_var:
mStyleStack.ReplaceElementAt((void*)aTag,mStyleStackPos++);
mStyleStack.Push(aTag);
break;
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 result=0;
if(mStyleStackPos>0) {
if(mStyleStack.mCount>0) {
switch (aTag) {
case eHTMLTag_a:
@ -2369,7 +2435,7 @@ PRInt32 CNavDTD::UpdateStyleStackForCloseTag(eHTMLTags aTag,eHTMLTags anActualTa
case eHTMLTag_u:
case eHTMLTag_var:
if(aTag==anActualTag)
mStyleStack.ReplaceElementAt((void*)eHTMLTag_unknown,--mStyleStackPos);
mStyleStack.Pop();
break;
case eHTMLTag_h1: case eHTMLTag_h2:
@ -2716,8 +2782,8 @@ PRInt32 CNavDTD::ConsumeToken(CToken*& aToken){
CScanner* theScanner=mParser->GetScanner();
if(kNoError==result){
PRUnichar aChar;
result=theScanner->GetChar(aChar);
PRUnichar theChar;
result=theScanner->GetChar(theChar);
switch(result) {
case kEOF:
break;
@ -2728,25 +2794,25 @@ PRInt32 CNavDTD::ConsumeToken(CToken*& aToken){
case kNoError:
default:
switch(aChar) {
switch(theChar) {
case kLessThan:
return ConsumeTag(aChar,*theScanner,aToken);
return ConsumeTag(theChar,*theScanner,aToken);
case kAmpersand:
return ConsumeEntity(aChar,*theScanner,aToken);
return ConsumeEntity(theChar,*theScanner,aToken);
case kCR: case kLF:
return ConsumeNewline(aChar,*theScanner,aToken);
return ConsumeNewline(theChar,*theScanner,aToken);
case kNotFound:
break;
default:
if(!nsString::IsSpace(aChar)) {
nsAutoString temp(aChar);
if(!nsString::IsSpace(theChar)) {
nsAutoString temp(theChar);
return ConsumeText(temp,*theScanner,aToken);
}
return ConsumeWhitespace(aChar,*theScanner,aToken);
return ConsumeWhitespace(theChar,*theScanner,aToken);
} //switch
break;
} //switch

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

@ -45,6 +45,54 @@ class nsIParserNode;
class CITokenHandler;
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 {
public:
@ -103,7 +151,7 @@ class CNavDTD : public nsIDTD {
* @param
* @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;
/**
*
* @update gess6/4/98
* @param
* @return
*/
virtual PRInt32 DidOpenContainer(eHTMLTags aTag,PRBool anExplicitOpen);
/**
* Ask parser if a given container is open ANYWHERE on stack
* @update gess5/11/98
@ -283,129 +323,36 @@ class CNavDTD : public nsIDTD {
*/
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
* to be handled (possibly added to content model via sink).
* The following set of methods are used to partially construct
* the content model (via the sink) according to the type of token.
* @update gess5/11/98
* @param aToken is the start token to be handled
* @return TRUE if the token was handled.
*/
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);
/**
* 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);
/**
* 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);
/**
* 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);
/**
* 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);
/**
* 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);
/**
* 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);
/**
* 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);
protected:
/**
* Causes token handlers to be registered for this parser.
* DO NOT CALL THIS! IT'S DEPRECATED!
* @update gess5/11/98
*/
void InitializeDefaultTokenHandlers();
/**
* DEPRECATED
* The following methods are use to create and manage
* the dynamic set of token handlers.
* @update gess5/11/98
*/
void InitializeDefaultTokenHandlers();
CITokenHandler* GetTokenHandler(eHTMLTokenTypes aType) const;
/**
* DEPRECATED
* @update gess5/11/98
*/
CITokenHandler* AddTokenHandler(CITokenHandler* aHandler);
/**
* DEPRECATED
* @update gess5/11/98
*/
void DeleteTokenHandlers(void);
void DeleteTokenHandlers(void);
//*************************************************
@ -414,145 +361,43 @@ protected:
//*************************************************
/**
* This cover method opens the given node as a HTML item in
* content sink.
* The next set of method open given HTML element.
*
* @update gess5/11/98
* @param HTML (node) to be opened in content sink.
* @return TRUE if all went well.
*/
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);
/**
* 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);
/**
* 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);
/**
* 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);
/**
* 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);
/**
* 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);
/**
* 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
* @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.
*/
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);
/**
* 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
* @return TRUE if all went well.
*/
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);
/**
* 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);
/**
@ -603,81 +448,22 @@ protected:
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
* @param aScanner is the input source
* @param aToken is the next token (or null)
* @return error code
*/
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);
/**
* 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);
/**
* 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);
/**
* 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);
/**
* 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);
/**
* 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 ConsumeText(const nsString& aString,CScanner& aScanner,CToken*& aToken);
/**
* Causes content to be skipped up to sequence contained in aString.
@ -700,16 +486,13 @@ protected:
CITokenHandler* mTokenHandlers[eToken_last];
nsVoidArray mLeafBits;
nsVoidArray mContextStack;
PRInt32 mContextStackPos;
nsVoidArray mStyleStack;
PRInt32 mStyleStackPos;
CTagStack mContextStack;
CTagStack mStyleStack;
PRBool mHasOpenForm;
PRBool mHasOpenMap;
nsDeque mTokenDeque;
char* mFilename;
nsString mFilename;
nsIDTDDebug* mDTDDebug;
};

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

@ -178,7 +178,7 @@ eAutoDetectResult COtherDTD::AutoDetectContentType(nsString& aBuffer,nsString& a
* @param
* @return
*/
PRInt32 COtherDTD::WillBuildModel(const char* aFilename) {
PRInt32 COtherDTD::WillBuildModel(nsString& aFilename) {
return CNavDTD::WillBuildModel(aFilename);
}
@ -464,25 +464,6 @@ PRBool COtherDTD::BackwardPropagate(nsString& aVector,eHTMLTags aParentTag,eHTML
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

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

@ -87,7 +87,7 @@ class COtherDTD : public CNavDTD {
* @param
* @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;
/**
*
* @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
* 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
* @return
*/
PRInt32 CRtfDTD::WillBuildModel(const char* aFilename){
PRInt32 CRtfDTD::WillBuildModel(nsString& aFilename){
PRInt32 result=0;
return result;
}

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

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

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

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

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

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

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

@ -67,7 +67,7 @@ public:
void SetVerificationDirectory(char * verify_dir);
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);
// global table for storing vector statistics and the size
@ -78,8 +78,8 @@ private:
char * mVerificationDir;
PRBool mRecordingStatistics;
PRBool DebugRecord(char * path, char * pURLRef, char * filename);
void NoteVector(nsVoidArray & aTags,PRInt32 count, PRBool good_vector);
PRBool DebugRecord(char * path, nsString& pURLRef, char * filename);
void NoteVector(eHTMLTags aTags[],PRInt32 count, PRBool good_vector);
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)
*/
PRBool CDTDDebug::DebugRecord(char * path, char * pURLRef, char * filename)
PRBool CDTDDebug::DebugRecord(char * path, nsString& aURLRef, char * filename)
{
char recordPath[2048];
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"
// where the vector contains the verification path and
// 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
// 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
*/
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 (!mVectorInfoArray) {
@ -327,7 +329,7 @@ void CDTDDebug::NoteVector(nsVoidArray & aTags,PRInt32 count, PRBool good_vector
PRBool match = PR_TRUE;
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;
break;
}
@ -348,7 +350,7 @@ void CDTDDebug::NoteVector(nsVoidArray & aTags,PRInt32 count, PRBool good_vector
pVectorInfo->good_vector = good_vector;
pVectorInfo->vector = (eHTMLTags*)PR_Malloc(count*sizeof(eHTMLTags));
for (PRInt32 i = 0; i < count; i++)
pVectorInfo->vector[i] = (eHTMLTags)(int)aTags[i];
pVectorInfo->vector[i] = aTags[i];
mVectorInfoArray[mVectorCount++] = pVectorInfo;
// 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
*/
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;
@ -477,7 +479,7 @@ PRBool CDTDDebug::Verify(nsIDTD * aDTD, nsParser * aParser, int aContextStackPo
if(aDTD && aContextStackPos>1) {
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;
break;
}
@ -495,7 +497,7 @@ PRBool CDTDDebug::Verify(nsIDTD * aDTD, nsParser * aParser, int aContextStackPo
int i=0;
for(i=0;i<aContextStackPos;i++){
strcat(path,"/");
const char* name=GetTagName((eHTMLTags)(int)aContextStack[i]);
const char* name=GetTagName(aContextStack[i]);
strcat(path,name);
PR_MkDir(path,0);
}

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

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

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

@ -52,15 +52,7 @@ class CHTMLContentSinkStream : public nsIHTMLContentSink {
* @param
* @return
*/
CHTMLContentSinkStream();
/**
*
* @update gess7/7/98
* @param
* @return
*/
CHTMLContentSinkStream(ostream& aStream);
CHTMLContentSinkStream(ostream* aStream);
/**
*
@ -71,14 +63,6 @@ class CHTMLContentSinkStream : public nsIHTMLContentSink {
virtual ~CHTMLContentSinkStream();
/**
*
* @update gess7/7/98
* @param
* @return
*/
void SetOutputStream(ostream& aStream);
/**
* This method gets called by the parser when it encounters
* 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

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

@ -99,7 +99,7 @@ class nsIDTD : public nsISupports {
* @param
* @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 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;

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

@ -23,6 +23,7 @@
#include "nsISupports.h"
#include "nsIStreamListener.h"
#include "nsIDTD.h"
#include "nsIInputStream.h"
#define NS_IPARSER_IID \
{0x355cbba0, 0xbf7d, 0x11d1, \
@ -67,20 +68,18 @@ class nsIParser : public nsISupports {
* 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(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(nsString& anHTMLString,PRBool appendTokens)=0;
virtual PRInt32 ResumeParse(void)=0;
/**
* This method gets called when the tokens have been consumed, and it's time
* to build the model via the content sink.
* @update gess5/11/98
* @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 "plstr.h"
#include <fstream.h>
#include "nsIInputStream.h"
#include "nsIParserFilter.h"
#include "nsIDTDDebug.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* kNullTokenizer = "Error: Unable to construct tokenizer";
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
#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{
public:
@ -114,6 +110,7 @@ public:
CSharedParserObjects() : mDeallocator(), mDTDDeque(mDeallocator) {
}
~CSharedParserObjects() {
}
@ -141,25 +138,13 @@ CSharedParserObjects gSharedParserObjects;
* @param
* @return
*/
nsParser::nsParser() :
mTokenDeque(gTokenDeallocator),
mSourceType(),
mTargetType()
{
nsParser::nsParser() {
NS_INIT_REFCNT();
mDTDDebug = 0;
mParserFilter = 0;
mObserver = 0;
mTransferBuffer=0;
mSink=0;
mCurrentPos=0;
mMarkPos=0;
mParseMode=eParseMode_unknown;
mURL=0;
mDTD=0;
mScanner=0;
mTransferBuffer=new char[gTransferBufferSize+1];
mAutoDetectStatus=eUnknownDetect;
mParserContext=0;
}
@ -172,20 +157,12 @@ nsParser::nsParser() :
*/
nsParser::~nsParser() {
NS_IF_RELEASE(mObserver);
NS_IF_RELEASE(mDTDDebug);
if(mTransferBuffer)
delete [] mTransferBuffer;
mTransferBuffer=0;
// NS_IF_RELEASE(mDTDDebug);
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
*/
CScanner* nsParser::GetScanner(void){
return mScanner;
if(mParserContext)
return mParserContext->mScanner;
return 0;
}
/**
@ -311,6 +290,7 @@ CScanner* nsParser::GetScanner(void){
eParseMode DetermineParseMode() {
const char* theModeStr= PR_GetEnv("PARSE_MODE");
const char* other="other";
eParseMode result=eParseMode_navigator;
if(theModeStr)
@ -326,25 +306,23 @@ eParseMode DetermineParseMode() {
* @param
* @return
*/
PRBool FindSuitableDTD( eParseMode aMode,
nsString& aSourceType,
nsString& aTargetType,
nsIDTD*& aDefaultDTD) {
PRBool FindSuitableDTD( CParserContext& aParserContext) {
//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;
PRBool result=PR_FALSE;
nsDequeIterator b=gSharedParserObjects.mDTDDeque.Begin();
nsDequeIterator e=gSharedParserObjects.mDTDDeque.End();
while(b<e){
nsIDTD* theDTD=(nsIDTD*)b.GetCurrent();
if(theDTD) {
result=theDTD->CanParse(aSourceType,0);
result=theDTD->CanParse(aParserContext.mSourceType,0);
if(result){
aDefaultDTD=theDTD;
aParserContext.mDTD=theDTD;
break;
}
}
@ -371,22 +349,22 @@ eAutoDetectResult nsParser::AutoDetectContentType(nsString& aBuffer,nsString& aT
// recognize the content in the scanner.
// Somebody should say yes, or we can't continue.
//This method may change mSourceType and mDTD.
//It absolutely changes mAutoDetectStatus
//This method may change mSourceType and mParserContext->mDTD.
//It absolutely changes mParserContext->mAutoDetectStatus
nsDequeIterator b=gSharedParserObjects.mDTDDeque.Begin();
nsDequeIterator e=gSharedParserObjects.mDTDDeque.End();
mAutoDetectStatus=eUnknownDetect;
while((b<e) && (eUnknownDetect==mAutoDetectStatus)){
mParserContext->mAutoDetectStatus=eUnknownDetect;
while((b<e) && (eUnknownDetect==mParserContext->mAutoDetectStatus)){
nsIDTD* theDTD=(nsIDTD*)b.GetCurrent();
if(theDTD) {
mAutoDetectStatus=theDTD->AutoDetectContentType(aBuffer,aType);
mParserContext->mAutoDetectStatus=theDTD->AutoDetectContentType(aBuffer,aType);
}
b++;
}
return mAutoDetectStatus;
return mParserContext->mAutoDetectStatus;
}
@ -401,27 +379,18 @@ eAutoDetectResult nsParser::AutoDetectContentType(nsString& aBuffer,nsString& aT
* @param
* @return
*/
PRInt32 nsParser::WillBuildModel(const char* aFilename){
PRInt32 nsParser::WillBuildModel(nsString& aFilename){
mMajorIteration=-1;
mMinorIteration=-1;
mParserContext->mMajorIteration=-1;
mParserContext->mMinorIteration=-1;
mParseMode=DetermineParseMode();
if(PR_TRUE==FindSuitableDTD(mParseMode,mSourceType,mTargetType,mDTD)) {
mDTD->SetParser(this);
mDTD->SetContentSink(mSink);
mDTD->WillBuildModel(aFilename);
mParserContext->mParseMode=DetermineParseMode();
if(PR_TRUE==FindSuitableDTD(*mParserContext)) {
mParserContext->mDTD->SetParser(this);
mParserContext->mDTD->SetContentSink(mSink);
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;
}
@ -434,18 +403,10 @@ PRInt32 nsParser::WillBuildModel(const char* aFilename){
PRInt32 nsParser::DidBuildModel(PRInt32 anErrorCode) {
//One last thing...close any open containers.
PRInt32 result=anErrorCode;
if(mDTD) {
result=mDTD->DidBuildModel(anErrorCode);
if(mParserContext->mDTD) {
result=mParserContext->mDTD->DidBuildModel(anErrorCode);
}
#ifdef DEBUG_SAVE_SOURCE_DOC
if(gTempStream) {
gTempStream->close();
delete gTempStream;
gTempStream=0;
}
#endif
return result;
}
@ -460,22 +421,21 @@ PRInt32 nsParser::DidBuildModel(PRInt32 anErrorCode) {
* @param aFilename -- const char* containing file to be parsed.
* @return PR_TRUE if parse succeeded, PR_FALSE otherwise.
*/
PRBool nsParser::Parse(const char* aFilename){
NS_PRECONDITION(0!=aFilename,kNullFilename);
PRInt32 nsParser::Parse(nsString& aFilename){
PRInt32 status=kBadFilename;
if(aFilename) {
//ok, time to create our tokenizer and begin the process
mTargetType=kHTMLTextContentType;
mScanner=new CScanner(aFilename,mParseMode);
if(mScanner) {
mScanner->Eof();
if(eValidDetect==AutoDetectContentType(mScanner->GetBuffer(),mSourceType)) {
WillBuildModel(aFilename);
status=ResumeParse();
DidBuildModel(status);
}
mParserContext = new CParserContext(new CScanner(aFilename),mParserContext);
mParserContext->mScanner->Eof();
if(eValidDetect==AutoDetectContentType(mParserContext->mScanner->GetBuffer(),
mParserContext->mSourceType))
{
WillBuildModel(aFilename);
status=ResumeParse();
DidBuildModel(status);
} //if
}
return status;
@ -488,11 +448,35 @@ PRBool nsParser::Parse(const char* aFilename){
* @return TRUE if all went well -- FALSE otherwise
*/
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.
* 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;
/* Disable DTD Debug for now...
mDTDDebug = aDTDDebug;
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) {
mScanner=new CScanner(mParseMode);
if(aURL) {
nsAutoString theName(aURL->GetSpec());
mParserContext=new CParserContext(new CScanner(theName,PR_FALSE),mParserContext,aListener);
status=NS_OK;
}
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.
* 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
* @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 result=kNoError;
mTargetType=kHTMLTextContentType;
mScanner=new CScanner();
mScanner->Append(aSourceBuffer);
if(eValidDetect==AutoDetectContentType(aSourceBuffer,mSourceType)) {
WillBuildModel("");
mParserContext = new CParserContext(new CScanner(kUnknownFilename),mParserContext,0);
mParserContext->mScanner->Append(aSourceBuffer);
if(eValidDetect==AutoDetectContentType(aSourceBuffer,mParserContext->mSourceType)) {
WillBuildModel(mParserContext->mScanner->GetFilename());
result=ResumeParse();
DidBuildModel(result);
}
@ -567,12 +547,12 @@ PRInt32 nsParser::Parse(nsString& aSourceBuffer,PRBool appendTokens){
PRInt32 nsParser::ResumeParse() {
PRInt32 result=kNoError;
mDTD->WillResumeParse();
mParserContext->mDTD->WillResumeParse();
if(kNoError==result) {
result=Tokenize();
if(kInterrupted==result)
mDTD->WillInterruptParse();
IterateTokens();
mParserContext->mDTD->WillInterruptParse();
BuildModel();
}
return result;
}
@ -585,26 +565,28 @@ PRInt32 nsParser::ResumeParse() {
* @param
* @return PR_TRUE if parse succeeded, PR_FALSE otherwise.
*/
PRInt32 nsParser::IterateTokens() {
nsDequeIterator e=mTokenDeque.End();
nsDequeIterator theMarkPos(e);
mMajorIteration++;
PRInt32 nsParser::BuildModel() {
if(!mCurrentPos)
mCurrentPos=new nsDequeIterator(mTokenDeque.Begin());
nsDequeIterator e=mParserContext->mTokenDeque.End();
nsDequeIterator theMarkPos(e);
// mParserContext->mMajorIteration++;
if(!mParserContext->mCurrentPos)
mParserContext->mCurrentPos=new nsDequeIterator(mParserContext->mTokenDeque.Begin());
PRInt32 result=kNoError;
while((kNoError==result) && ((*mCurrentPos<e))){
mMinorIteration++;
CToken* theToken=(CToken*)mCurrentPos->GetCurrent();
while((kNoError==result) && ((*mParserContext->mCurrentPos<e))){
mParserContext->mMinorIteration++;
CToken* theToken=(CToken*)mParserContext->mCurrentPos->GetCurrent();
theMarkPos=*mCurrentPos;
result=mDTD->HandleToken(theToken);
++(*mCurrentPos);
theMarkPos=*mParserContext->mCurrentPos;
result=mParserContext->mDTD->HandleToken(theToken);
++(*mParserContext->mCurrentPos);
}
if(kInterrupted==result)
*mCurrentPos=theMarkPos;
*mParserContext->mCurrentPos=theMarkPos;
return result;
}
@ -619,17 +601,17 @@ PRInt32 nsParser::IterateTokens() {
* @return error code (should be 0)
*/
PRInt32 nsParser::CollectAttributes(nsCParserNode& aNode,PRInt32 aCount){
nsDequeIterator end=mTokenDeque.End();
nsDequeIterator end=mParserContext->mTokenDeque.End();
int attr=0;
for(attr=0;attr<aCount;attr++) {
if(*mCurrentPos<end) {
CToken* tkn=(CToken*)(++(*mCurrentPos));
if(*mParserContext->mCurrentPos<end) {
CToken* tkn=(CToken*)(++(*mParserContext->mCurrentPos));
if(tkn){
if(eToken_attribute==eHTMLTokenTypes(tkn->GetTokenType())){
aNode.AddAttribute(tkn);
}
else (*mCurrentPos)--;
else (*mParserContext->mCurrentPos)--;
}
else return kInterrupted;
}
@ -649,18 +631,18 @@ PRInt32 nsParser::CollectAttributes(nsCParserNode& aNode,PRInt32 aCount){
*/
PRInt32 nsParser::CollectSkippedContent(nsCParserNode& aNode,PRInt32& aCount) {
eHTMLTokenTypes subtype=eToken_attribute;
nsDequeIterator end=mTokenDeque.End();
nsDequeIterator end=mParserContext->mTokenDeque.End();
PRInt32 result=kNoError;
aCount=0;
while((*mCurrentPos!=end) && (eToken_attribute==subtype)) {
CToken* tkn=(CToken*)(++(*mCurrentPos));
while((*mParserContext->mCurrentPos!=end) && (eToken_attribute==subtype)) {
CToken* tkn=(CToken*)(++(*mParserContext->mCurrentPos));
subtype=eHTMLTokenTypes(tkn->GetTokenType());
if(eToken_skippedcontent==subtype) {
aNode.SetSkippedContent(tkn);
aCount++;
}
else (*mCurrentPos)--;
else (*mParserContext->mCurrentPos)--;
}
return result;
}
@ -710,10 +692,9 @@ nsresult nsParser::OnStartBinding(const char *aSourceType){
if (nsnull != mObserver) {
mObserver->OnStartBinding(aSourceType);
}
mAutoDetectStatus=eUnknownDetect;
mDTD=0;
mSourceType=aSourceType;
mParserContext->mAutoDetectStatus=eUnknownDetect;
mParserContext->mDTD=0;
mParserContext->mSourceType=aSourceType;
return kNoError;
}
@ -732,37 +713,33 @@ nsresult nsParser::OnDataAvailable(nsIInputStream *pIStream, PRInt32 length){
mListener->OnDataAvailable(pIStream, length);
}
*/
int len=0;
int offset=0;
if(eInvalidDetect==mAutoDetectStatus) {
if(mScanner) {
mScanner->GetBuffer().Truncate();
if(eInvalidDetect==mParserContext->mAutoDetectStatus) {
if(mParserContext->mScanner) {
mParserContext->mScanner->GetBuffer().Truncate();
}
}
do {
PRInt32 err;
len = pIStream->Read(&err, mTransferBuffer, 0, gTransferBufferSize);
if(len>0) {
int len=1; //init to a non-zero value
int err;
int offset=0;
#ifdef DEBUG_SAVE_SOURCE_DOC
if(gTempStream) {
gTempStream->write(mTransferBuffer,len);
}
#endif
while (len > 0) {
len = pIStream->Read(&err, mParserContext->mTransferBuffer, 0, mParserContext->eTransferBufferSize);
if(len>0) {
if (mParserFilter)
mParserFilter->RawBuffer(mTransferBuffer, &len);
mScanner->Append(mTransferBuffer,len);
if(mParserFilter)
mParserFilter->RawBuffer(mParserContext->mTransferBuffer, &len);
if(eUnknownDetect==mAutoDetectStatus) {
if(eValidDetect==AutoDetectContentType(mScanner->GetBuffer(),mSourceType)) {
nsresult result=WillBuildModel(mURL->GetSpec());
} //if
}
} //if
} while (len > 0);
mParserContext->mScanner->Append(mParserContext->mTransferBuffer,len);
if(eUnknownDetect==mParserContext->mAutoDetectStatus) {
if(eValidDetect==AutoDetectContentType(mParserContext->mScanner->GetBuffer(),mParserContext->mSourceType)) {
nsresult result=WillBuildModel(mParserContext->mScanner->GetFilename());
} //if
}
} //if
}
nsresult result=ResumeParse();
return result;
@ -797,7 +774,7 @@ nsresult nsParser::OnStopBinding(PRInt32 status, const nsString& aMsg){
* @return new token or null
*/
PRInt32 nsParser::ConsumeToken(CToken*& aToken) {
PRInt32 result=mDTD->ConsumeToken(aToken);
PRInt32 result=mParserContext->mDTD->ConsumeToken(aToken);
return result;
}
@ -811,39 +788,11 @@ PRInt32 nsParser::ConsumeToken(CToken*& aToken) {
* @param
* @return TRUE if it's ok to proceed
*/
PRBool nsParser::WillTokenize(void){
PRBool nsParser::WillTokenize(){
PRBool result=PR_TRUE;
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
@ -853,14 +802,14 @@ PRInt32 nsParser::Tokenize(nsString& aSourceBuffer,PRBool appendTokens){
* @update gess 3/25/98
* @return error code
*/
PRInt32 nsParser::Tokenize(void) {
PRInt32 nsParser::Tokenize(){
CToken* theToken=0;
PRInt32 result=kNoError;
PRBool done=(0==mMajorIteration) ? (!WillTokenize()) : PR_FALSE;
PRBool done=(0==++mParserContext->mMajorIteration) ? (!WillTokenize()) : PR_FALSE;
while((PR_FALSE==done) && (kNoError==result)) {
mScanner->Mark();
mParserContext->mScanner->Mark();
result=ConsumeToken(theToken);
if(kNoError==result) {
if(theToken) {
@ -868,14 +817,14 @@ PRInt32 nsParser::Tokenize(void) {
#ifdef VERBOSE_DEBUG
theToken->DebugDumpToken(cout);
#endif
mTokenDeque.Push(theToken);
mParserContext->mTokenDeque.Push(theToken);
}
}
else {
if(theToken)
delete theToken;
mScanner->RewindToMark();
mParserContext->mScanner->RewindToMark();
}
}
if((PR_TRUE==done) && (kInterrupted!=result))
@ -892,7 +841,7 @@ PRInt32 nsParser::Tokenize(void) {
* @param
* @return TRUE if all went well
*/
PRBool nsParser::DidTokenize(void) {
PRBool nsParser::DidTokenize(){
PRBool result=PR_TRUE;
#ifdef VERBOSE_DEBUG
@ -912,8 +861,8 @@ PRBool nsParser::DidTokenize(void) {
* @return
*/
void nsParser::DebugDumpTokens(ostream& out) {
nsDequeIterator b=mTokenDeque.Begin();
nsDequeIterator e=mTokenDeque.End();
nsDequeIterator b=mParserContext->mTokenDeque.Begin();
nsDequeIterator e=mParserContext->mTokenDeque.End();
CToken* theToken;
while(b!=e) {
@ -933,8 +882,8 @@ void nsParser::DebugDumpTokens(ostream& out) {
* @return
*/
void nsParser::DebugDumpSource(ostream& out) {
nsDequeIterator b=mTokenDeque.Begin();
nsDequeIterator e=mTokenDeque.End();
nsDequeIterator b=mParserContext->mTokenDeque.Begin();
nsDequeIterator e=mParserContext->mTokenDeque.End();
CToken* theToken;
while(b!=e) {

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

@ -60,7 +60,7 @@
#include "nsParserNode.h"
#include "nsParserTypes.h"
#include "nsIURL.h"
#include "CParserContext.h"
#define NS_PARSER_IID \
{0x2ce606b0, 0xbee6, 0x11d1, \
@ -69,7 +69,6 @@
class IContentSink;
class nsIHTMLContentSink;
class nsIURL;
class nsIDTD;
class nsIDTDDebug;
class CScanner;
@ -119,14 +118,26 @@ friend class CTokenHandler;
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
* @param aURL is a descriptor for source document
* @param aListener is a listener to forward notifications to
* @return TRUE if all went well -- FALSE otherwise
*/
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
@ -134,7 +145,7 @@ friend class CTokenHandler;
* @param aFilename is a path for file document
* @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
@ -157,7 +168,7 @@ friend class CTokenHandler;
* @update gess5/11/98
* @return TRUE if all went well, otherwise FALSE
*/
virtual PRInt32 ResumeParse(void);
virtual PRInt32 ResumeParse();
/**
* Causes the parser to scan foward, collecting nearby (sequential)
@ -208,7 +219,7 @@ protected:
* @param
* @return
*/
PRInt32 WillBuildModel(const char* aFilename=0);
PRInt32 WillBuildModel(nsString& aFilename);
/**
*
@ -224,7 +235,7 @@ protected:
* @update gess5/11/98
* @return YES if model building went well -- NO otherwise.
*/
virtual PRInt32 IterateTokens(void);
virtual PRInt32 BuildModel(void);
private:
@ -251,14 +262,8 @@ private:
* @param
* @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
@ -268,7 +273,7 @@ private:
* @update gess 3/25/98
* @return error code
*/
PRInt32 Tokenize(void);
PRInt32 Tokenize();
/**
* This is the tail-end of the code sandwich for the
@ -279,7 +284,7 @@ private:
* @param
* @return TRUE if all went well
*/
PRBool DidTokenize(void);
PRBool DidTokenize();
/**
* This debug routine is used to cause the tokenizer to
@ -311,27 +316,42 @@ protected:
// And now, some data members...
//*********************************************
nsIStreamObserver* mObserver;
nsIContentSink* mSink;
nsIParserFilter* mParserFilter;
nsDequeIterator* mCurrentPos;
nsDequeIterator* mMarkPos;
nsIDTD* mDTD;
eParseMode mParseMode;
char* mTransferBuffer;
/*****************************************************
All of these moved into the parse-context object:
PRInt32 mMajorIteration;
PRInt32 mMinorIteration;
nsDeque mTokenDeque;
CScanner* mScanner;
nsIURL* mURL;
nsIDTDDebug* mDTDDebug;
nsString mSourceType;
nsString mTargetType;
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
#include "nsScanner.h"
#include "nsIURL.h"
#include "nsDebug.h"
const char* gURLRef=0;
const char* kBadHTMLText="<H3>Oops...</H3>You just tried to read a non-existent document: <BR>";
#ifdef __INCREMENTAL
@ -31,89 +29,55 @@ const int kBufsize=1;
const int kBufsize=64;
#endif
/**
* Use this constructor if you want an incremental (callback)
* based input stream.
* Use this constructor if you want i/o to be based on an
* incremental netstream. If you pass a null filename, you
* can still provide data to the scanner via append.
*
* @update gess 5/12/98
* @param aMode represents the parser mode (nav, other)
* @param aFilename --
* @return
*/
CScanner::CScanner(eParseMode aMode) : mBuffer("") {
CScanner::CScanner(nsString& aFilename,PRBool aCreateStream) :
mBuffer(""), mFilename(aFilename)
{
mOffset=0;
mMarkPos=-1;
mTotalRead=0;
mParseMode=aMode;
mNetStream=0;
mOwnsStream=aCreateStream;
mFileStream=0;
mIncremental=PR_TRUE;
mOwnsStream=PR_TRUE;
if(aCreateStream) {
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
* @param aMode represents the parser mode (nav, other)
* @param aStream --
* @param assumeOwnership --
* @param aFilename --
* @return
*/
CScanner::CScanner(const char* aFilename,eParseMode aMode) : mBuffer("") {
NS_ASSERTION(0!=aFilename,"Error: Null filename!");
CScanner::CScanner(nsString& aFilename,fstream& aStream,PRBool assumeOwnership) :
mBuffer(""), mFilename(aFilename)
{
mOffset=0;
mMarkPos=-1;
mTotalRead=0;
mParseMode=aMode;
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;
mOwnsStream=assumeOwnership;
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
@ -128,13 +92,7 @@ CScanner::~CScanner() {
if(mOwnsStream)
delete mFileStream;
}
else if(mNetStream) {
mNetStream->Close();
mNetStream->Release();
}
mFileStream=0;
mNetStream=0;
gURLRef=0;
}
/**
@ -201,33 +159,8 @@ 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
* @return error code
@ -235,6 +168,7 @@ PRInt32 CScanner::IncrementalAppend(const char* aBuffer,PRInt32 aSize){
PRBool CScanner::Append(nsString& aBuffer) {
_PreCompressBuffer(mBuffer,mOffset,mMarkPos);
mBuffer.Append(aBuffer);
mTotalRead+=aBuffer.Length();
return PR_TRUE;
}
@ -248,6 +182,7 @@ PRBool CScanner::Append(nsString& aBuffer) {
PRBool CScanner::Append(const char* aBuffer, PRInt32 aLen){
_PreCompressBuffer(mBuffer,mOffset,mMarkPos);
mBuffer.Append(aBuffer,aLen);
mTotalRead+=aLen;
return PR_TRUE;
}
@ -262,18 +197,18 @@ PRInt32 CScanner::FillBuffer(void) {
_PreCompressBuffer(mBuffer,mOffset,mMarkPos);
if((!mIncremental) && (!mNetStream) && (!mFileStream)) {
if(!mFileStream) {
//This is DEBUG code!!!!!! XXX DEBUG XXX
//If you're here, it means someone tried to load a
//non-existent document. So as a favor, we emit a
//little bit of HTML explaining the error.
if(0==mTotalRead) {
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;
char buf[kBufsize+1];
buf[kBufsize]=0;
@ -282,17 +217,11 @@ PRInt32 CScanner::FillBuffer(void) {
mFileStream->read(buf,kBufsize);
numread=mFileStream->gcount();
}
else if(mNetStream) {
numread=mNetStream->Read(&anError,buf,0,kBufsize);
if(1==anError)
anError=kEOF;
}
mOffset=mBuffer.Length();
if((0<numread) && (0==anError))
mBuffer.Append((const char*)buf,numread);
mTotalRead+=mBuffer.Length();
}
else anError=kInterrupted;
return anError;
}
@ -308,9 +237,7 @@ PRInt32 CScanner::Eof() {
PRInt32 theError=0;
if(mOffset>=mBuffer.Length()) {
if(!mIncremental)
theError=FillBuffer();
else return kInterrupted;
theError=FillBuffer();
}
if(0==theError)
@ -451,21 +378,21 @@ PRInt32 CScanner::SkipPast(nsString& aValidSet){
* @return error code
*/
PRInt32 CScanner::ReadWhile(nsString& aString,nsString& aValidSet,PRBool addTerminal){
PRUnichar ch=0;
PRUnichar theChar=0;
PRInt32 result=kNoError;
PRInt32 wrPos=0;
while(kNoError==result) {
result=GetChar(ch);
result=GetChar(theChar);
if(kNoError==result) {
PRInt32 pos=aValidSet.Find(ch);
PRInt32 pos=aValidSet.Find(theChar);
if(kNotFound==pos) {
if(addTerminal)
aString+=ch;
else PutBack(ch);
aString+=theChar;
else PutBack(theChar);
break;
}
else aString+=ch;
else aString+=theChar;
}
}
return result;
@ -535,6 +462,18 @@ nsString& CScanner::GetBuffer(void) {
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
* occurs in the parser selftest.

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

@ -35,43 +35,21 @@
#include "nsString.h"
#include "nsParserTypes.h"
#include "prtypes.h"
#include "nsIInputStream.h"
#include <fstream.h>
class nsIURL;
//class ifstream;
class CScanner {
public:
/**
* Use this constructor if you want an incremental (callback)
* based input stream.
* Use this constructor if you want i/o to be based on
* a file (therefore a stream) or just data you provide via Append().
*
* @update gess 5/12/98
* @param aMode represents the parser mode (nav, other)
* @return
*/
CScanner(eParseMode aMode=eParseMode_navigator);
/**
* 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);
CScanner(nsString& aFilename,PRBool aCreateStream=PR_TRUE);
/**
* 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)
* @return
*/
CScanner(fstream& aStream,eParseMode aMode=eParseMode_navigator);
CScanner(nsString& aFilename,fstream& aStream,PRBool assumeOwnership=PR_TRUE);
~CScanner();
@ -241,16 +219,17 @@ class CScanner {
* @param
* @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
* @param
* @return
*/
nsString& GetBuffer(void);
nsString& GetFilename(void);
static void SelfTest();
@ -268,13 +247,11 @@ class CScanner {
fstream* mFileStream;
nsIInputStream* mNetStream;
nsString mBuffer;
nsString mFilename;
PRInt32 mOffset;
PRInt32 mMarkPos;
PRInt32 mTotalRead;
eParseMode mParseMode;
PRBool mIncremental;
PRBool mOwnsStream;
};

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

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

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

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

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

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

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

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

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

@ -91,6 +91,115 @@ static char gWhitespaceTags[]={
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.
* 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;
}
/**
* This method is defined in nsIParser. It is used to
* cause the COM-like construction of an nsParser.
@ -234,15 +344,13 @@ static CNavTokenDeallocator gTokenKiller;
* @param
* @return
*/
CNavDTD::CNavDTD() : nsIDTD(), mTokenDeque(gTokenKiller) {
CNavDTD::CNavDTD() : nsIDTD(), mTokenDeque(gTokenKiller),
mContextStack(), mStyleStack() {
NS_INIT_REFCNT();
mParser=0;
mFilename=0;
mSink = nsnull;
mDTDDebug=0;
nsCRT::zero(mTokenHandlers,sizeof(mTokenHandlers));
mContextStackPos=0;
mStyleStackPos=0;
mHasOpenForm=PR_FALSE;
mHasOpenMap=PR_FALSE;
InitializeDefaultTokenHandlers();
@ -257,8 +365,6 @@ CNavDTD::CNavDTD() : nsIDTD(), mTokenDeque(gTokenKiller) {
*/
CNavDTD::~CNavDTD(){
DeleteTokenHandlers();
if (mFilename)
PL_strfree(mFilename);
if (mDTDDebug)
NS_RELEASE(mDTDDebug);
@ -281,6 +387,7 @@ void CNavDTD::SetDTDDebug(nsIDTDDebug * aDTDDebug)
NS_ADDREF(mDTDDebug);
}
/**
* This method is called to determine if the given DTD can parse
* a document in a given source-type.
@ -308,24 +415,16 @@ eAutoDetectResult CNavDTD::AutoDetectContentType(nsString& aBuffer,nsString& aTy
return result;
}
/**
*
* @update gess5/18/98
* @param
* @return
*/
PRInt32 CNavDTD::WillBuildModel(const char* aFilename){
PRInt32 CNavDTD::WillBuildModel(nsString& aFilename){
PRInt32 result=0;
if (mFilename) {
PL_strfree(mFilename);
mFilename=0;
}
if(aFilename) {
mFilename = PL_strdup(aFilename);
}
mFilename=aFilename;
if(mSink)
mSink->WillBuildModel();
@ -342,7 +441,7 @@ PRInt32 CNavDTD::WillBuildModel(const char* aFilename){
PRInt32 CNavDTD::DidBuildModel(PRInt32 anErrorCode){
PRInt32 result=0;
if((kNoError==anErrorCode) && (mContextStackPos>0)) {
if((kNoError==anErrorCode) && (mContextStack.mCount>0)) {
CloseContainersTo(0,eHTMLTag_unknown,PR_FALSE);
}
if(mSink) {
@ -375,7 +474,7 @@ PRInt32 CNavDTD::HandleToken(CToken* aToken){
if(theHandler) {
result=(*theHandler)(theToken,this);
if (mDTDDebug)
mDTDDebug->Verify(this, mParser, mContextStackPos, mContextStack, mFilename);
mDTDDebug->Verify(this, mParser, mContextStack.mCount, mContextStack.mTags, mFilename);
}
}//if
@ -420,13 +519,13 @@ PRInt32 CNavDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsIP
}
if(IsContainer(aChildTag)){
if(PR_TRUE==(PRBool)mLeafBits[mContextStackPos-1]) {
if(PR_TRUE==mContextStack.mBits[mContextStack.mCount-1]) {
CloseTransientStyles(aChildTag);
}
result=OpenContainer(aNode,PR_TRUE);
}
else {
if(PR_FALSE==(PRBool)mLeafBits[mContextStackPos-1]) {
if(PR_FALSE==mContextStack.mBits[mContextStack.mCount-1]) {
OpenTransientStyles(aChildTag);
}
result=AddLeaf(aNode);
@ -576,16 +675,8 @@ PRInt32 CNavDTD::HandleEndToken(CToken* aToken) {
// we have to handle explicit styles the way it does. That means
// 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
// 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...
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
// ones off so it's safe to do it now) because they don't carry
// forward across table cell boundaries.
mStyleStackPos = 0;
mStyleStack.mCount=0;
break;
default:
@ -1148,8 +1239,8 @@ PRBool CNavDTD::CanContain(PRInt32 aParent,PRInt32 aChild) {
break; //singletons can't contain anything...
case eHTMLTag_li:
if ((eHTMLTag_li == aChild) ||
(eHTMLTag_ul == aChild) || // XXX this is temporary!!!
if ((eHTMLTag_li == aChild) || //XXX this is temporary!!!
(eHTMLTag_ul == aChild) ||
(eHTMLTag_ol == aChild) ||
(eHTMLTag_menu == aChild) ||
(eHTMLTag_dir == aChild)) {
@ -1620,29 +1711,6 @@ PRBool CNavDTD::BackwardPropagate(nsString& aVector,eHTMLTags aParentTag,eHTMLTa
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
* element is currently open.
@ -1672,9 +1740,7 @@ PRBool CNavDTD::HasOpenContainer(eHTMLTags aContainer) const {
* @return tag id of topmost node in contextstack
*/
eHTMLTags CNavDTD::GetTopNode() const {
if(mContextStackPos)
return (eHTMLTags)(int)mContextStack[mContextStackPos-1];
return eHTMLTag_unknown;
return mContextStack.Last();
}
@ -1688,8 +1754,8 @@ eHTMLTags CNavDTD::GetTopNode() const {
*/
PRInt32 CNavDTD::GetTopmostIndexOf(eHTMLTags aTag) const {
int i=0;
for(i=mContextStackPos-1;i>=0;i--){
if((eHTMLTags)(int)mContextStack[i]==aTag)
for(i=mContextStack.mCount-1;i>=0;i--){
if(mContextStack.mTags[i]==aTag)
return i;
}
return kNotFound;
@ -1720,8 +1786,8 @@ PRInt32 CNavDTD::OpenTransientStyles(eHTMLTags aTag){
eHTMLTags parentTag=GetTopNode();
if(CanContainStyles(parentTag)) {
for(pos=0;pos<mStyleStackPos;pos++) {
eHTMLTags theTag=(eHTMLTags)(int)mStyleStack[pos];
for(pos=0;pos<mStyleStack.mCount;pos++) {
eHTMLTags theTag=mStyleStack.mTags[pos];
if(PR_FALSE==HasOpenContainer(theTag)) {
CStartToken token(GetTagName(theTag));
@ -1735,7 +1801,7 @@ PRInt32 CNavDTD::OpenTransientStyles(eHTMLTags aTag){
default:
token.SetTypeID(theTag); //open the html container...
result=OpenContainer(theNode,PR_FALSE);
mLeafBits.ReplaceElementAt((void*)PR_TRUE,mContextStackPos-1);
mContextStack.mBits[mContextStack.mCount-1]=PR_TRUE;
} //switch
}
if(kNoError!=result)
@ -1761,11 +1827,11 @@ PRInt32 CNavDTD::OpenTransientStyles(eHTMLTags aTag){
PRInt32 CNavDTD::CloseTransientStyles(eHTMLTags aTag){
PRInt32 result=0;
if((mStyleStackPos>0) && (mLeafBits[mContextStackPos-1])) {
if((mStyleStack.mCount>0) && (mContextStack.mBits[mContextStack.mCount-1])) {
if(0==strchr(gWhitespaceTags,aTag)){
result=CloseContainersTo((eHTMLTags)(int)mStyleStack[0],PR_FALSE);
mLeafBits.ReplaceElementAt((void*)PR_FALSE,mContextStackPos-1);
result=CloseContainersTo(mStyleStack.mTags[0],PR_FALSE);
mContextStack.mBits[mContextStack.mCount-1]=PR_FALSE;
}//if
}//if
@ -1782,10 +1848,10 @@ PRInt32 CNavDTD::CloseTransientStyles(eHTMLTags aTag){
* @return TRUE if ok, FALSE if error
*/
PRInt32 CNavDTD::OpenHTML(const nsIParserNode& aNode){
NS_PRECONDITION(mContextStackPos >= 0, kInvalidTagStackPos);
NS_PRECONDITION(mContextStack.mCount >= 0, kInvalidTagStackPos);
PRInt32 result=mSink->OpenHTML(aNode);
mContextStack.ReplaceElementAt((void*)aNode.GetNodeType(),mContextStackPos++);
mContextStack.Push((eHTMLTags)aNode.GetNodeType());
return result;
}
@ -1799,9 +1865,9 @@ PRInt32 CNavDTD::OpenHTML(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error
*/
PRInt32 CNavDTD::CloseHTML(const nsIParserNode& aNode){
NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos);
NS_PRECONDITION(mContextStack.mCount > 0, kInvalidTagStackPos);
PRInt32 result=mSink->CloseHTML(aNode);
mContextStack.ReplaceElementAt((void*)eHTMLTag_unknown,--mContextStackPos);
mContextStack.Pop();
return result;
}
@ -1815,7 +1881,7 @@ PRInt32 CNavDTD::CloseHTML(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error
*/
PRInt32 CNavDTD::OpenHead(const nsIParserNode& aNode){
mContextStack.ReplaceElementAt((void*)eHTMLTag_head,++mContextStackPos);
mContextStack.Push(eHTMLTag_head);
PRInt32 result=mSink->OpenHead(aNode);
return result;
}
@ -1830,7 +1896,7 @@ PRInt32 CNavDTD::OpenHead(const nsIParserNode& aNode){
*/
PRInt32 CNavDTD::CloseHead(const nsIParserNode& aNode){
PRInt32 result=mSink->CloseHead(aNode);
mContextStack.ReplaceElementAt((void*)eHTMLTag_unknown,--mContextStackPos);
mContextStack.Pop();
return result;
}
@ -1843,7 +1909,7 @@ PRInt32 CNavDTD::CloseHead(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error
*/
PRInt32 CNavDTD::OpenBody(const nsIParserNode& aNode){
NS_PRECONDITION(mContextStackPos >= 0, kInvalidTagStackPos);
NS_PRECONDITION(mContextStack.mCount >= 0, kInvalidTagStackPos);
PRInt32 result=kNoError;
eHTMLTags topTag=GetTopNode();
@ -1875,7 +1941,7 @@ PRInt32 CNavDTD::OpenBody(const nsIParserNode& aNode){
if(kNoError==result) {
result=mSink->OpenBody(aNode);
mContextStack.ReplaceElementAt((void*)aNode.GetNodeType(),mContextStackPos++);
mContextStack.Push((eHTMLTags)aNode.GetNodeType());
}
return result;
}
@ -1889,9 +1955,9 @@ PRInt32 CNavDTD::OpenBody(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error
*/
PRInt32 CNavDTD::CloseBody(const nsIParserNode& aNode){
NS_PRECONDITION(mContextStackPos >= 0, kInvalidTagStackPos);
NS_PRECONDITION(mContextStack.mCount >= 0, kInvalidTagStackPos);
PRInt32 result=mSink->CloseBody(aNode);
mContextStack.ReplaceElementAt((void*)eHTMLTag_unknown,--mContextStackPos);
mContextStack.Pop();
return result;
}
@ -1980,9 +2046,9 @@ PRInt32 CNavDTD::CloseMap(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error
*/
PRInt32 CNavDTD::OpenFrameset(const nsIParserNode& aNode){
NS_PRECONDITION(mContextStackPos >= 0, kInvalidTagStackPos);
NS_PRECONDITION(mContextStack.mCount >= 0, kInvalidTagStackPos);
PRInt32 result=mSink->OpenFrameset(aNode);
mContextStack.ReplaceElementAt((void*)aNode.GetNodeType(),mContextStackPos++);
mContextStack.Push((eHTMLTags)aNode.GetNodeType());
return result;
}
@ -1995,9 +2061,9 @@ PRInt32 CNavDTD::OpenFrameset(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error
*/
PRInt32 CNavDTD::CloseFrameset(const nsIParserNode& aNode){
NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos);
NS_PRECONDITION(mContextStack.mCount > 0, kInvalidTagStackPos);
PRInt32 result=mSink->CloseFrameset(aNode);
mContextStack.ReplaceElementAt((void*)eHTMLTag_unknown,--mContextStackPos);
mContextStack.Pop();
return result;
}
@ -2011,7 +2077,7 @@ PRInt32 CNavDTD::CloseFrameset(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error
*/
PRInt32 CNavDTD::OpenContainer(const nsIParserNode& aNode,PRBool aUpdateStyleStack){
NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos);
NS_PRECONDITION(mContextStack.mCount > 0, kInvalidTagStackPos);
PRInt32 result=kNoError;
eHTMLTags nodeType=(eHTMLTags)aNode.GetNodeType();
@ -2037,7 +2103,7 @@ PRInt32 CNavDTD::OpenContainer(const nsIParserNode& aNode,PRBool aUpdateStyleSta
default:
result=mSink->OpenContainer(aNode);
mContextStack.ReplaceElementAt((void*)nodeType,mContextStackPos++);
mContextStack.Push((eHTMLTags)aNode.GetNodeType());
break;
}
@ -2057,7 +2123,7 @@ PRInt32 CNavDTD::OpenContainer(const nsIParserNode& aNode,PRBool aUpdateStyleSta
* @return TRUE if ok, FALSE if error
*/
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
eHTMLTags nodeType=(eHTMLTags)aNode.GetNodeType();
@ -2085,11 +2151,11 @@ PRInt32 CNavDTD::CloseContainer(const nsIParserNode& aNode,eHTMLTags aTag,PRBool
case eHTMLTag_title:
default:
result=mSink->CloseContainer(aNode);
mContextStack.ReplaceElementAt((void*)eHTMLTag_unknown,--mContextStackPos);
mContextStack.Pop();
break;
}
mLeafBits.ReplaceElementAt((void*)PR_FALSE, mContextStackPos);
mContextStack.mBits[mContextStack.mCount]=PR_FALSE;
if((kNoError==result) && (PR_TRUE==aUpdateStyles)){
UpdateStyleStackForCloseTag(nodeType,aTag);
}
@ -2106,15 +2172,15 @@ PRInt32 CNavDTD::CloseContainer(const nsIParserNode& aNode,eHTMLTags aTag,PRBool
* @return TRUE if ok, FALSE if error
*/
PRInt32 CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTag,PRBool aUpdateStyles){
NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos);
NS_PRECONDITION(mContextStack.mCount > 0, kInvalidTagStackPos);
PRInt32 result=kNoError;
CEndToken aToken(gEmpty);
nsCParserNode theNode(&aToken);
if((anIndex<mContextStackPos) && (anIndex>=0)) {
while(mContextStackPos>anIndex) {
eHTMLTags theTag=(eHTMLTags)(int)mContextStack[mContextStackPos-1];
if((anIndex<mContextStack.mCount) && (anIndex>=0)) {
while(mContextStack.mCount>anIndex) {
eHTMLTags theTag=mContextStack.Last();
aToken.SetTypeID(theTag);
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
*/
PRInt32 CNavDTD::CloseContainersTo(eHTMLTags aTag,PRBool aUpdateStyles){
NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos);
NS_PRECONDITION(mContextStack.mCount > 0, kInvalidTagStackPos);
PRInt32 pos=GetTopmostIndexOf(aTag);
@ -2172,10 +2238,10 @@ PRInt32 CNavDTD::CloseContainersTo(eHTMLTags aTag,PRBool aUpdateStyles){
* @return TRUE if ok, FALSE if error
*/
PRInt32 CNavDTD::CloseTopmostContainer(){
NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos);
NS_PRECONDITION(mContextStack.mCount > 0, kInvalidTagStackPos);
CEndToken aToken(gEmpty);
eHTMLTags theTag=(eHTMLTags)(int)mContextStack[mContextStackPos-1];
eHTMLTags theTag=mContextStack.Last();
aToken.SetTypeID(theTag);
nsCParserNode theNode(&aToken);
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...
pos=0;
cnt=theVector.Length()-1;
if(mContextStack[mContextStackPos-1]==(void*)theVector[cnt])
if(mContextStack.Last()==(eHTMLTags)theVector[cnt])
result=kNoError;
else result=kContextMismatch;
}
@ -2236,8 +2302,8 @@ PRInt32 CNavDTD::CreateContextStackFor(eHTMLTags aChildTag){
pos=0;
cnt=theVector.Length();
result=kNoError;
while(pos<mContextStackPos) {
if(mContextStack[pos]==(void*)theVector[cnt-1-pos]) {
while(pos<mContextStack.mCount) {
if(mContextStack.mTags[pos]==(eHTMLTags)theVector[cnt-1-pos]) {
pos++;
}
else {
@ -2321,7 +2387,7 @@ PRInt32 CNavDTD::UpdateStyleStackForOpenTag(eHTMLTags aTag,eHTMLTags anActualTag
case eHTMLTag_tt:
case eHTMLTag_u:
case eHTMLTag_var:
mStyleStack.ReplaceElementAt((void*)aTag,mStyleStackPos++);
mStyleStack.Push(aTag);
break;
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 result=0;
if(mStyleStackPos>0) {
if(mStyleStack.mCount>0) {
switch (aTag) {
case eHTMLTag_a:
@ -2369,7 +2435,7 @@ PRInt32 CNavDTD::UpdateStyleStackForCloseTag(eHTMLTags aTag,eHTMLTags anActualTa
case eHTMLTag_u:
case eHTMLTag_var:
if(aTag==anActualTag)
mStyleStack.ReplaceElementAt((void*)eHTMLTag_unknown,--mStyleStackPos);
mStyleStack.Pop();
break;
case eHTMLTag_h1: case eHTMLTag_h2:
@ -2716,8 +2782,8 @@ PRInt32 CNavDTD::ConsumeToken(CToken*& aToken){
CScanner* theScanner=mParser->GetScanner();
if(kNoError==result){
PRUnichar aChar;
result=theScanner->GetChar(aChar);
PRUnichar theChar;
result=theScanner->GetChar(theChar);
switch(result) {
case kEOF:
break;
@ -2728,25 +2794,25 @@ PRInt32 CNavDTD::ConsumeToken(CToken*& aToken){
case kNoError:
default:
switch(aChar) {
switch(theChar) {
case kLessThan:
return ConsumeTag(aChar,*theScanner,aToken);
return ConsumeTag(theChar,*theScanner,aToken);
case kAmpersand:
return ConsumeEntity(aChar,*theScanner,aToken);
return ConsumeEntity(theChar,*theScanner,aToken);
case kCR: case kLF:
return ConsumeNewline(aChar,*theScanner,aToken);
return ConsumeNewline(theChar,*theScanner,aToken);
case kNotFound:
break;
default:
if(!nsString::IsSpace(aChar)) {
nsAutoString temp(aChar);
if(!nsString::IsSpace(theChar)) {
nsAutoString temp(theChar);
return ConsumeText(temp,*theScanner,aToken);
}
return ConsumeWhitespace(aChar,*theScanner,aToken);
return ConsumeWhitespace(theChar,*theScanner,aToken);
} //switch
break;
} //switch

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

@ -45,6 +45,54 @@ class nsIParserNode;
class CITokenHandler;
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 {
public:
@ -103,7 +151,7 @@ class CNavDTD : public nsIDTD {
* @param
* @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;
/**
*
* @update gess6/4/98
* @param
* @return
*/
virtual PRInt32 DidOpenContainer(eHTMLTags aTag,PRBool anExplicitOpen);
/**
* Ask parser if a given container is open ANYWHERE on stack
* @update gess5/11/98
@ -283,129 +323,36 @@ class CNavDTD : public nsIDTD {
*/
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
* to be handled (possibly added to content model via sink).
* The following set of methods are used to partially construct
* the content model (via the sink) according to the type of token.
* @update gess5/11/98
* @param aToken is the start token to be handled
* @return TRUE if the token was handled.
*/
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);
/**
* 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);
/**
* 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);
/**
* 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);
/**
* 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);
/**
* 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);
/**
* 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);
/**
* 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);
protected:
/**
* Causes token handlers to be registered for this parser.
* DO NOT CALL THIS! IT'S DEPRECATED!
* @update gess5/11/98
*/
void InitializeDefaultTokenHandlers();
/**
* DEPRECATED
* The following methods are use to create and manage
* the dynamic set of token handlers.
* @update gess5/11/98
*/
void InitializeDefaultTokenHandlers();
CITokenHandler* GetTokenHandler(eHTMLTokenTypes aType) const;
/**
* DEPRECATED
* @update gess5/11/98
*/
CITokenHandler* AddTokenHandler(CITokenHandler* aHandler);
/**
* DEPRECATED
* @update gess5/11/98
*/
void DeleteTokenHandlers(void);
void DeleteTokenHandlers(void);
//*************************************************
@ -414,145 +361,43 @@ protected:
//*************************************************
/**
* This cover method opens the given node as a HTML item in
* content sink.
* The next set of method open given HTML element.
*
* @update gess5/11/98
* @param HTML (node) to be opened in content sink.
* @return TRUE if all went well.
*/
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);
/**
* 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);
/**
* 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);
/**
* 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);
/**
* 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);
/**
* 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);
/**
* 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
* @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.
*/
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);
/**
* 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
* @return TRUE if all went well.
*/
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);
/**
* 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);
/**
@ -603,81 +448,22 @@ protected:
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
* @param aScanner is the input source
* @param aToken is the next token (or null)
* @return error code
*/
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);
/**
* 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);
/**
* 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);
/**
* 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);
/**
* 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);
/**
* 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 ConsumeText(const nsString& aString,CScanner& aScanner,CToken*& aToken);
/**
* Causes content to be skipped up to sequence contained in aString.
@ -700,16 +486,13 @@ protected:
CITokenHandler* mTokenHandlers[eToken_last];
nsVoidArray mLeafBits;
nsVoidArray mContextStack;
PRInt32 mContextStackPos;
nsVoidArray mStyleStack;
PRInt32 mStyleStackPos;
CTagStack mContextStack;
CTagStack mStyleStack;
PRBool mHasOpenForm;
PRBool mHasOpenMap;
nsDeque mTokenDeque;
char* mFilename;
nsString mFilename;
nsIDTDDebug* mDTDDebug;
};

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

@ -178,7 +178,7 @@ eAutoDetectResult COtherDTD::AutoDetectContentType(nsString& aBuffer,nsString& a
* @param
* @return
*/
PRInt32 COtherDTD::WillBuildModel(const char* aFilename) {
PRInt32 COtherDTD::WillBuildModel(nsString& aFilename) {
return CNavDTD::WillBuildModel(aFilename);
}
@ -464,25 +464,6 @@ PRBool COtherDTD::BackwardPropagate(nsString& aVector,eHTMLTags aParentTag,eHTML
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

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

@ -87,7 +87,7 @@ class COtherDTD : public CNavDTD {
* @param
* @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;
/**
*
* @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
* 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
* @return
*/
PRInt32 CRtfDTD::WillBuildModel(const char* aFilename){
PRInt32 CRtfDTD::WillBuildModel(nsString& aFilename){
PRInt32 result=0;
return result;
}

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

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

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

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

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

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

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

@ -67,7 +67,7 @@ public:
void SetVerificationDirectory(char * verify_dir);
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);
// global table for storing vector statistics and the size
@ -78,8 +78,8 @@ private:
char * mVerificationDir;
PRBool mRecordingStatistics;
PRBool DebugRecord(char * path, char * pURLRef, char * filename);
void NoteVector(nsVoidArray & aTags,PRInt32 count, PRBool good_vector);
PRBool DebugRecord(char * path, nsString& pURLRef, char * filename);
void NoteVector(eHTMLTags aTags[],PRInt32 count, PRBool good_vector);
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)
*/
PRBool CDTDDebug::DebugRecord(char * path, char * pURLRef, char * filename)
PRBool CDTDDebug::DebugRecord(char * path, nsString& aURLRef, char * filename)
{
char recordPath[2048];
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"
// where the vector contains the verification path and
// 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
// 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
*/
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 (!mVectorInfoArray) {
@ -327,7 +329,7 @@ void CDTDDebug::NoteVector(nsVoidArray & aTags,PRInt32 count, PRBool good_vector
PRBool match = PR_TRUE;
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;
break;
}
@ -348,7 +350,7 @@ void CDTDDebug::NoteVector(nsVoidArray & aTags,PRInt32 count, PRBool good_vector
pVectorInfo->good_vector = good_vector;
pVectorInfo->vector = (eHTMLTags*)PR_Malloc(count*sizeof(eHTMLTags));
for (PRInt32 i = 0; i < count; i++)
pVectorInfo->vector[i] = (eHTMLTags)(int)aTags[i];
pVectorInfo->vector[i] = aTags[i];
mVectorInfoArray[mVectorCount++] = pVectorInfo;
// 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
*/
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;
@ -477,7 +479,7 @@ PRBool CDTDDebug::Verify(nsIDTD * aDTD, nsParser * aParser, int aContextStackPo
if(aDTD && aContextStackPos>1) {
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;
break;
}
@ -495,7 +497,7 @@ PRBool CDTDDebug::Verify(nsIDTD * aDTD, nsParser * aParser, int aContextStackPo
int i=0;
for(i=0;i<aContextStackPos;i++){
strcat(path,"/");
const char* name=GetTagName((eHTMLTags)(int)aContextStack[i]);
const char* name=GetTagName(aContextStack[i]);
strcat(path,name);
PR_MkDir(path,0);
}

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

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

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

@ -52,15 +52,7 @@ class CHTMLContentSinkStream : public nsIHTMLContentSink {
* @param
* @return
*/
CHTMLContentSinkStream();
/**
*
* @update gess7/7/98
* @param
* @return
*/
CHTMLContentSinkStream(ostream& aStream);
CHTMLContentSinkStream(ostream* aStream);
/**
*
@ -71,14 +63,6 @@ class CHTMLContentSinkStream : public nsIHTMLContentSink {
virtual ~CHTMLContentSinkStream();
/**
*
* @update gess7/7/98
* @param
* @return
*/
void SetOutputStream(ostream& aStream);
/**
* This method gets called by the parser when it encounters
* 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

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

@ -99,7 +99,7 @@ class nsIDTD : public nsISupports {
* @param
* @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 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;

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

@ -23,6 +23,7 @@
#include "nsISupports.h"
#include "nsIStreamListener.h"
#include "nsIDTD.h"
#include "nsIInputStream.h"
#define NS_IPARSER_IID \
{0x355cbba0, 0xbf7d, 0x11d1, \
@ -67,20 +68,18 @@ class nsIParser : public nsISupports {
* 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(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(nsString& anHTMLString,PRBool appendTokens)=0;
virtual PRInt32 ResumeParse(void)=0;
/**
* This method gets called when the tokens have been consumed, and it's time
* to build the model via the content sink.
* @update gess5/11/98
* @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 "plstr.h"
#include <fstream.h>
#include "nsIInputStream.h"
#include "nsIParserFilter.h"
#include "nsIDTDDebug.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* kNullTokenizer = "Error: Unable to construct tokenizer";
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
#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{
public:
@ -114,6 +110,7 @@ public:
CSharedParserObjects() : mDeallocator(), mDTDDeque(mDeallocator) {
}
~CSharedParserObjects() {
}
@ -141,25 +138,13 @@ CSharedParserObjects gSharedParserObjects;
* @param
* @return
*/
nsParser::nsParser() :
mTokenDeque(gTokenDeallocator),
mSourceType(),
mTargetType()
{
nsParser::nsParser() {
NS_INIT_REFCNT();
mDTDDebug = 0;
mParserFilter = 0;
mObserver = 0;
mTransferBuffer=0;
mSink=0;
mCurrentPos=0;
mMarkPos=0;
mParseMode=eParseMode_unknown;
mURL=0;
mDTD=0;
mScanner=0;
mTransferBuffer=new char[gTransferBufferSize+1];
mAutoDetectStatus=eUnknownDetect;
mParserContext=0;
}
@ -172,20 +157,12 @@ nsParser::nsParser() :
*/
nsParser::~nsParser() {
NS_IF_RELEASE(mObserver);
NS_IF_RELEASE(mDTDDebug);
if(mTransferBuffer)
delete [] mTransferBuffer;
mTransferBuffer=0;
// NS_IF_RELEASE(mDTDDebug);
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
*/
CScanner* nsParser::GetScanner(void){
return mScanner;
if(mParserContext)
return mParserContext->mScanner;
return 0;
}
/**
@ -311,6 +290,7 @@ CScanner* nsParser::GetScanner(void){
eParseMode DetermineParseMode() {
const char* theModeStr= PR_GetEnv("PARSE_MODE");
const char* other="other";
eParseMode result=eParseMode_navigator;
if(theModeStr)
@ -326,25 +306,23 @@ eParseMode DetermineParseMode() {
* @param
* @return
*/
PRBool FindSuitableDTD( eParseMode aMode,
nsString& aSourceType,
nsString& aTargetType,
nsIDTD*& aDefaultDTD) {
PRBool FindSuitableDTD( CParserContext& aParserContext) {
//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;
PRBool result=PR_FALSE;
nsDequeIterator b=gSharedParserObjects.mDTDDeque.Begin();
nsDequeIterator e=gSharedParserObjects.mDTDDeque.End();
while(b<e){
nsIDTD* theDTD=(nsIDTD*)b.GetCurrent();
if(theDTD) {
result=theDTD->CanParse(aSourceType,0);
result=theDTD->CanParse(aParserContext.mSourceType,0);
if(result){
aDefaultDTD=theDTD;
aParserContext.mDTD=theDTD;
break;
}
}
@ -371,22 +349,22 @@ eAutoDetectResult nsParser::AutoDetectContentType(nsString& aBuffer,nsString& aT
// recognize the content in the scanner.
// Somebody should say yes, or we can't continue.
//This method may change mSourceType and mDTD.
//It absolutely changes mAutoDetectStatus
//This method may change mSourceType and mParserContext->mDTD.
//It absolutely changes mParserContext->mAutoDetectStatus
nsDequeIterator b=gSharedParserObjects.mDTDDeque.Begin();
nsDequeIterator e=gSharedParserObjects.mDTDDeque.End();
mAutoDetectStatus=eUnknownDetect;
while((b<e) && (eUnknownDetect==mAutoDetectStatus)){
mParserContext->mAutoDetectStatus=eUnknownDetect;
while((b<e) && (eUnknownDetect==mParserContext->mAutoDetectStatus)){
nsIDTD* theDTD=(nsIDTD*)b.GetCurrent();
if(theDTD) {
mAutoDetectStatus=theDTD->AutoDetectContentType(aBuffer,aType);
mParserContext->mAutoDetectStatus=theDTD->AutoDetectContentType(aBuffer,aType);
}
b++;
}
return mAutoDetectStatus;
return mParserContext->mAutoDetectStatus;
}
@ -401,27 +379,18 @@ eAutoDetectResult nsParser::AutoDetectContentType(nsString& aBuffer,nsString& aT
* @param
* @return
*/
PRInt32 nsParser::WillBuildModel(const char* aFilename){
PRInt32 nsParser::WillBuildModel(nsString& aFilename){
mMajorIteration=-1;
mMinorIteration=-1;
mParserContext->mMajorIteration=-1;
mParserContext->mMinorIteration=-1;
mParseMode=DetermineParseMode();
if(PR_TRUE==FindSuitableDTD(mParseMode,mSourceType,mTargetType,mDTD)) {
mDTD->SetParser(this);
mDTD->SetContentSink(mSink);
mDTD->WillBuildModel(aFilename);
mParserContext->mParseMode=DetermineParseMode();
if(PR_TRUE==FindSuitableDTD(*mParserContext)) {
mParserContext->mDTD->SetParser(this);
mParserContext->mDTD->SetContentSink(mSink);
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;
}
@ -434,18 +403,10 @@ PRInt32 nsParser::WillBuildModel(const char* aFilename){
PRInt32 nsParser::DidBuildModel(PRInt32 anErrorCode) {
//One last thing...close any open containers.
PRInt32 result=anErrorCode;
if(mDTD) {
result=mDTD->DidBuildModel(anErrorCode);
if(mParserContext->mDTD) {
result=mParserContext->mDTD->DidBuildModel(anErrorCode);
}
#ifdef DEBUG_SAVE_SOURCE_DOC
if(gTempStream) {
gTempStream->close();
delete gTempStream;
gTempStream=0;
}
#endif
return result;
}
@ -460,22 +421,21 @@ PRInt32 nsParser::DidBuildModel(PRInt32 anErrorCode) {
* @param aFilename -- const char* containing file to be parsed.
* @return PR_TRUE if parse succeeded, PR_FALSE otherwise.
*/
PRBool nsParser::Parse(const char* aFilename){
NS_PRECONDITION(0!=aFilename,kNullFilename);
PRInt32 nsParser::Parse(nsString& aFilename){
PRInt32 status=kBadFilename;
if(aFilename) {
//ok, time to create our tokenizer and begin the process
mTargetType=kHTMLTextContentType;
mScanner=new CScanner(aFilename,mParseMode);
if(mScanner) {
mScanner->Eof();
if(eValidDetect==AutoDetectContentType(mScanner->GetBuffer(),mSourceType)) {
WillBuildModel(aFilename);
status=ResumeParse();
DidBuildModel(status);
}
mParserContext = new CParserContext(new CScanner(aFilename),mParserContext);
mParserContext->mScanner->Eof();
if(eValidDetect==AutoDetectContentType(mParserContext->mScanner->GetBuffer(),
mParserContext->mSourceType))
{
WillBuildModel(aFilename);
status=ResumeParse();
DidBuildModel(status);
} //if
}
return status;
@ -488,11 +448,35 @@ PRBool nsParser::Parse(const char* aFilename){
* @return TRUE if all went well -- FALSE otherwise
*/
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.
* 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;
/* Disable DTD Debug for now...
mDTDDebug = aDTDDebug;
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) {
mScanner=new CScanner(mParseMode);
if(aURL) {
nsAutoString theName(aURL->GetSpec());
mParserContext=new CParserContext(new CScanner(theName,PR_FALSE),mParserContext,aListener);
status=NS_OK;
}
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.
* 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
* @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 result=kNoError;
mTargetType=kHTMLTextContentType;
mScanner=new CScanner();
mScanner->Append(aSourceBuffer);
if(eValidDetect==AutoDetectContentType(aSourceBuffer,mSourceType)) {
WillBuildModel("");
mParserContext = new CParserContext(new CScanner(kUnknownFilename),mParserContext,0);
mParserContext->mScanner->Append(aSourceBuffer);
if(eValidDetect==AutoDetectContentType(aSourceBuffer,mParserContext->mSourceType)) {
WillBuildModel(mParserContext->mScanner->GetFilename());
result=ResumeParse();
DidBuildModel(result);
}
@ -567,12 +547,12 @@ PRInt32 nsParser::Parse(nsString& aSourceBuffer,PRBool appendTokens){
PRInt32 nsParser::ResumeParse() {
PRInt32 result=kNoError;
mDTD->WillResumeParse();
mParserContext->mDTD->WillResumeParse();
if(kNoError==result) {
result=Tokenize();
if(kInterrupted==result)
mDTD->WillInterruptParse();
IterateTokens();
mParserContext->mDTD->WillInterruptParse();
BuildModel();
}
return result;
}
@ -585,26 +565,28 @@ PRInt32 nsParser::ResumeParse() {
* @param
* @return PR_TRUE if parse succeeded, PR_FALSE otherwise.
*/
PRInt32 nsParser::IterateTokens() {
nsDequeIterator e=mTokenDeque.End();
nsDequeIterator theMarkPos(e);
mMajorIteration++;
PRInt32 nsParser::BuildModel() {
if(!mCurrentPos)
mCurrentPos=new nsDequeIterator(mTokenDeque.Begin());
nsDequeIterator e=mParserContext->mTokenDeque.End();
nsDequeIterator theMarkPos(e);
// mParserContext->mMajorIteration++;
if(!mParserContext->mCurrentPos)
mParserContext->mCurrentPos=new nsDequeIterator(mParserContext->mTokenDeque.Begin());
PRInt32 result=kNoError;
while((kNoError==result) && ((*mCurrentPos<e))){
mMinorIteration++;
CToken* theToken=(CToken*)mCurrentPos->GetCurrent();
while((kNoError==result) && ((*mParserContext->mCurrentPos<e))){
mParserContext->mMinorIteration++;
CToken* theToken=(CToken*)mParserContext->mCurrentPos->GetCurrent();
theMarkPos=*mCurrentPos;
result=mDTD->HandleToken(theToken);
++(*mCurrentPos);
theMarkPos=*mParserContext->mCurrentPos;
result=mParserContext->mDTD->HandleToken(theToken);
++(*mParserContext->mCurrentPos);
}
if(kInterrupted==result)
*mCurrentPos=theMarkPos;
*mParserContext->mCurrentPos=theMarkPos;
return result;
}
@ -619,17 +601,17 @@ PRInt32 nsParser::IterateTokens() {
* @return error code (should be 0)
*/
PRInt32 nsParser::CollectAttributes(nsCParserNode& aNode,PRInt32 aCount){
nsDequeIterator end=mTokenDeque.End();
nsDequeIterator end=mParserContext->mTokenDeque.End();
int attr=0;
for(attr=0;attr<aCount;attr++) {
if(*mCurrentPos<end) {
CToken* tkn=(CToken*)(++(*mCurrentPos));
if(*mParserContext->mCurrentPos<end) {
CToken* tkn=(CToken*)(++(*mParserContext->mCurrentPos));
if(tkn){
if(eToken_attribute==eHTMLTokenTypes(tkn->GetTokenType())){
aNode.AddAttribute(tkn);
}
else (*mCurrentPos)--;
else (*mParserContext->mCurrentPos)--;
}
else return kInterrupted;
}
@ -649,18 +631,18 @@ PRInt32 nsParser::CollectAttributes(nsCParserNode& aNode,PRInt32 aCount){
*/
PRInt32 nsParser::CollectSkippedContent(nsCParserNode& aNode,PRInt32& aCount) {
eHTMLTokenTypes subtype=eToken_attribute;
nsDequeIterator end=mTokenDeque.End();
nsDequeIterator end=mParserContext->mTokenDeque.End();
PRInt32 result=kNoError;
aCount=0;
while((*mCurrentPos!=end) && (eToken_attribute==subtype)) {
CToken* tkn=(CToken*)(++(*mCurrentPos));
while((*mParserContext->mCurrentPos!=end) && (eToken_attribute==subtype)) {
CToken* tkn=(CToken*)(++(*mParserContext->mCurrentPos));
subtype=eHTMLTokenTypes(tkn->GetTokenType());
if(eToken_skippedcontent==subtype) {
aNode.SetSkippedContent(tkn);
aCount++;
}
else (*mCurrentPos)--;
else (*mParserContext->mCurrentPos)--;
}
return result;
}
@ -710,10 +692,9 @@ nsresult nsParser::OnStartBinding(const char *aSourceType){
if (nsnull != mObserver) {
mObserver->OnStartBinding(aSourceType);
}
mAutoDetectStatus=eUnknownDetect;
mDTD=0;
mSourceType=aSourceType;
mParserContext->mAutoDetectStatus=eUnknownDetect;
mParserContext->mDTD=0;
mParserContext->mSourceType=aSourceType;
return kNoError;
}
@ -732,37 +713,33 @@ nsresult nsParser::OnDataAvailable(nsIInputStream *pIStream, PRInt32 length){
mListener->OnDataAvailable(pIStream, length);
}
*/
int len=0;
int offset=0;
if(eInvalidDetect==mAutoDetectStatus) {
if(mScanner) {
mScanner->GetBuffer().Truncate();
if(eInvalidDetect==mParserContext->mAutoDetectStatus) {
if(mParserContext->mScanner) {
mParserContext->mScanner->GetBuffer().Truncate();
}
}
do {
PRInt32 err;
len = pIStream->Read(&err, mTransferBuffer, 0, gTransferBufferSize);
if(len>0) {
int len=1; //init to a non-zero value
int err;
int offset=0;
#ifdef DEBUG_SAVE_SOURCE_DOC
if(gTempStream) {
gTempStream->write(mTransferBuffer,len);
}
#endif
while (len > 0) {
len = pIStream->Read(&err, mParserContext->mTransferBuffer, 0, mParserContext->eTransferBufferSize);
if(len>0) {
if (mParserFilter)
mParserFilter->RawBuffer(mTransferBuffer, &len);
mScanner->Append(mTransferBuffer,len);
if(mParserFilter)
mParserFilter->RawBuffer(mParserContext->mTransferBuffer, &len);
if(eUnknownDetect==mAutoDetectStatus) {
if(eValidDetect==AutoDetectContentType(mScanner->GetBuffer(),mSourceType)) {
nsresult result=WillBuildModel(mURL->GetSpec());
} //if
}
} //if
} while (len > 0);
mParserContext->mScanner->Append(mParserContext->mTransferBuffer,len);
if(eUnknownDetect==mParserContext->mAutoDetectStatus) {
if(eValidDetect==AutoDetectContentType(mParserContext->mScanner->GetBuffer(),mParserContext->mSourceType)) {
nsresult result=WillBuildModel(mParserContext->mScanner->GetFilename());
} //if
}
} //if
}
nsresult result=ResumeParse();
return result;
@ -797,7 +774,7 @@ nsresult nsParser::OnStopBinding(PRInt32 status, const nsString& aMsg){
* @return new token or null
*/
PRInt32 nsParser::ConsumeToken(CToken*& aToken) {
PRInt32 result=mDTD->ConsumeToken(aToken);
PRInt32 result=mParserContext->mDTD->ConsumeToken(aToken);
return result;
}
@ -811,39 +788,11 @@ PRInt32 nsParser::ConsumeToken(CToken*& aToken) {
* @param
* @return TRUE if it's ok to proceed
*/
PRBool nsParser::WillTokenize(void){
PRBool nsParser::WillTokenize(){
PRBool result=PR_TRUE;
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
@ -853,14 +802,14 @@ PRInt32 nsParser::Tokenize(nsString& aSourceBuffer,PRBool appendTokens){
* @update gess 3/25/98
* @return error code
*/
PRInt32 nsParser::Tokenize(void) {
PRInt32 nsParser::Tokenize(){
CToken* theToken=0;
PRInt32 result=kNoError;
PRBool done=(0==mMajorIteration) ? (!WillTokenize()) : PR_FALSE;
PRBool done=(0==++mParserContext->mMajorIteration) ? (!WillTokenize()) : PR_FALSE;
while((PR_FALSE==done) && (kNoError==result)) {
mScanner->Mark();
mParserContext->mScanner->Mark();
result=ConsumeToken(theToken);
if(kNoError==result) {
if(theToken) {
@ -868,14 +817,14 @@ PRInt32 nsParser::Tokenize(void) {
#ifdef VERBOSE_DEBUG
theToken->DebugDumpToken(cout);
#endif
mTokenDeque.Push(theToken);
mParserContext->mTokenDeque.Push(theToken);
}
}
else {
if(theToken)
delete theToken;
mScanner->RewindToMark();
mParserContext->mScanner->RewindToMark();
}
}
if((PR_TRUE==done) && (kInterrupted!=result))
@ -892,7 +841,7 @@ PRInt32 nsParser::Tokenize(void) {
* @param
* @return TRUE if all went well
*/
PRBool nsParser::DidTokenize(void) {
PRBool nsParser::DidTokenize(){
PRBool result=PR_TRUE;
#ifdef VERBOSE_DEBUG
@ -912,8 +861,8 @@ PRBool nsParser::DidTokenize(void) {
* @return
*/
void nsParser::DebugDumpTokens(ostream& out) {
nsDequeIterator b=mTokenDeque.Begin();
nsDequeIterator e=mTokenDeque.End();
nsDequeIterator b=mParserContext->mTokenDeque.Begin();
nsDequeIterator e=mParserContext->mTokenDeque.End();
CToken* theToken;
while(b!=e) {
@ -933,8 +882,8 @@ void nsParser::DebugDumpTokens(ostream& out) {
* @return
*/
void nsParser::DebugDumpSource(ostream& out) {
nsDequeIterator b=mTokenDeque.Begin();
nsDequeIterator e=mTokenDeque.End();
nsDequeIterator b=mParserContext->mTokenDeque.Begin();
nsDequeIterator e=mParserContext->mTokenDeque.End();
CToken* theToken;
while(b!=e) {

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

@ -60,7 +60,7 @@
#include "nsParserNode.h"
#include "nsParserTypes.h"
#include "nsIURL.h"
#include "CParserContext.h"
#define NS_PARSER_IID \
{0x2ce606b0, 0xbee6, 0x11d1, \
@ -69,7 +69,6 @@
class IContentSink;
class nsIHTMLContentSink;
class nsIURL;
class nsIDTD;
class nsIDTDDebug;
class CScanner;
@ -119,14 +118,26 @@ friend class CTokenHandler;
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
* @param aURL is a descriptor for source document
* @param aListener is a listener to forward notifications to
* @return TRUE if all went well -- FALSE otherwise
*/
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
@ -134,7 +145,7 @@ friend class CTokenHandler;
* @param aFilename is a path for file document
* @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
@ -157,7 +168,7 @@ friend class CTokenHandler;
* @update gess5/11/98
* @return TRUE if all went well, otherwise FALSE
*/
virtual PRInt32 ResumeParse(void);
virtual PRInt32 ResumeParse();
/**
* Causes the parser to scan foward, collecting nearby (sequential)
@ -208,7 +219,7 @@ protected:
* @param
* @return
*/
PRInt32 WillBuildModel(const char* aFilename=0);
PRInt32 WillBuildModel(nsString& aFilename);
/**
*
@ -224,7 +235,7 @@ protected:
* @update gess5/11/98
* @return YES if model building went well -- NO otherwise.
*/
virtual PRInt32 IterateTokens(void);
virtual PRInt32 BuildModel(void);
private:
@ -251,14 +262,8 @@ private:
* @param
* @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
@ -268,7 +273,7 @@ private:
* @update gess 3/25/98
* @return error code
*/
PRInt32 Tokenize(void);
PRInt32 Tokenize();
/**
* This is the tail-end of the code sandwich for the
@ -279,7 +284,7 @@ private:
* @param
* @return TRUE if all went well
*/
PRBool DidTokenize(void);
PRBool DidTokenize();
/**
* This debug routine is used to cause the tokenizer to
@ -311,27 +316,42 @@ protected:
// And now, some data members...
//*********************************************
nsIStreamObserver* mObserver;
nsIContentSink* mSink;
nsIParserFilter* mParserFilter;
nsDequeIterator* mCurrentPos;
nsDequeIterator* mMarkPos;
nsIDTD* mDTD;
eParseMode mParseMode;
char* mTransferBuffer;
/*****************************************************
All of these moved into the parse-context object:
PRInt32 mMajorIteration;
PRInt32 mMinorIteration;
nsDeque mTokenDeque;
CScanner* mScanner;
nsIURL* mURL;
nsIDTDDebug* mDTDDebug;
nsString mSourceType;
nsString mTargetType;
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
#include "nsScanner.h"
#include "nsIURL.h"
#include "nsDebug.h"
const char* gURLRef=0;
const char* kBadHTMLText="<H3>Oops...</H3>You just tried to read a non-existent document: <BR>";
#ifdef __INCREMENTAL
@ -31,89 +29,55 @@ const int kBufsize=1;
const int kBufsize=64;
#endif
/**
* Use this constructor if you want an incremental (callback)
* based input stream.
* Use this constructor if you want i/o to be based on an
* incremental netstream. If you pass a null filename, you
* can still provide data to the scanner via append.
*
* @update gess 5/12/98
* @param aMode represents the parser mode (nav, other)
* @param aFilename --
* @return
*/
CScanner::CScanner(eParseMode aMode) : mBuffer("") {
CScanner::CScanner(nsString& aFilename,PRBool aCreateStream) :
mBuffer(""), mFilename(aFilename)
{
mOffset=0;
mMarkPos=-1;
mTotalRead=0;
mParseMode=aMode;
mNetStream=0;
mOwnsStream=aCreateStream;
mFileStream=0;
mIncremental=PR_TRUE;
mOwnsStream=PR_TRUE;
if(aCreateStream) {
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
* @param aMode represents the parser mode (nav, other)
* @param aStream --
* @param assumeOwnership --
* @param aFilename --
* @return
*/
CScanner::CScanner(const char* aFilename,eParseMode aMode) : mBuffer("") {
NS_ASSERTION(0!=aFilename,"Error: Null filename!");
CScanner::CScanner(nsString& aFilename,fstream& aStream,PRBool assumeOwnership) :
mBuffer(""), mFilename(aFilename)
{
mOffset=0;
mMarkPos=-1;
mTotalRead=0;
mParseMode=aMode;
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;
mOwnsStream=assumeOwnership;
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
@ -128,13 +92,7 @@ CScanner::~CScanner() {
if(mOwnsStream)
delete mFileStream;
}
else if(mNetStream) {
mNetStream->Close();
mNetStream->Release();
}
mFileStream=0;
mNetStream=0;
gURLRef=0;
}
/**
@ -201,33 +159,8 @@ 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
* @return error code
@ -235,6 +168,7 @@ PRInt32 CScanner::IncrementalAppend(const char* aBuffer,PRInt32 aSize){
PRBool CScanner::Append(nsString& aBuffer) {
_PreCompressBuffer(mBuffer,mOffset,mMarkPos);
mBuffer.Append(aBuffer);
mTotalRead+=aBuffer.Length();
return PR_TRUE;
}
@ -248,6 +182,7 @@ PRBool CScanner::Append(nsString& aBuffer) {
PRBool CScanner::Append(const char* aBuffer, PRInt32 aLen){
_PreCompressBuffer(mBuffer,mOffset,mMarkPos);
mBuffer.Append(aBuffer,aLen);
mTotalRead+=aLen;
return PR_TRUE;
}
@ -262,18 +197,18 @@ PRInt32 CScanner::FillBuffer(void) {
_PreCompressBuffer(mBuffer,mOffset,mMarkPos);
if((!mIncremental) && (!mNetStream) && (!mFileStream)) {
if(!mFileStream) {
//This is DEBUG code!!!!!! XXX DEBUG XXX
//If you're here, it means someone tried to load a
//non-existent document. So as a favor, we emit a
//little bit of HTML explaining the error.
if(0==mTotalRead) {
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;
char buf[kBufsize+1];
buf[kBufsize]=0;
@ -282,17 +217,11 @@ PRInt32 CScanner::FillBuffer(void) {
mFileStream->read(buf,kBufsize);
numread=mFileStream->gcount();
}
else if(mNetStream) {
numread=mNetStream->Read(&anError,buf,0,kBufsize);
if(1==anError)
anError=kEOF;
}
mOffset=mBuffer.Length();
if((0<numread) && (0==anError))
mBuffer.Append((const char*)buf,numread);
mTotalRead+=mBuffer.Length();
}
else anError=kInterrupted;
return anError;
}
@ -308,9 +237,7 @@ PRInt32 CScanner::Eof() {
PRInt32 theError=0;
if(mOffset>=mBuffer.Length()) {
if(!mIncremental)
theError=FillBuffer();
else return kInterrupted;
theError=FillBuffer();
}
if(0==theError)
@ -451,21 +378,21 @@ PRInt32 CScanner::SkipPast(nsString& aValidSet){
* @return error code
*/
PRInt32 CScanner::ReadWhile(nsString& aString,nsString& aValidSet,PRBool addTerminal){
PRUnichar ch=0;
PRUnichar theChar=0;
PRInt32 result=kNoError;
PRInt32 wrPos=0;
while(kNoError==result) {
result=GetChar(ch);
result=GetChar(theChar);
if(kNoError==result) {
PRInt32 pos=aValidSet.Find(ch);
PRInt32 pos=aValidSet.Find(theChar);
if(kNotFound==pos) {
if(addTerminal)
aString+=ch;
else PutBack(ch);
aString+=theChar;
else PutBack(theChar);
break;
}
else aString+=ch;
else aString+=theChar;
}
}
return result;
@ -535,6 +462,18 @@ nsString& CScanner::GetBuffer(void) {
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
* occurs in the parser selftest.

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

@ -35,43 +35,21 @@
#include "nsString.h"
#include "nsParserTypes.h"
#include "prtypes.h"
#include "nsIInputStream.h"
#include <fstream.h>
class nsIURL;
//class ifstream;
class CScanner {
public:
/**
* Use this constructor if you want an incremental (callback)
* based input stream.
* Use this constructor if you want i/o to be based on
* a file (therefore a stream) or just data you provide via Append().
*
* @update gess 5/12/98
* @param aMode represents the parser mode (nav, other)
* @return
*/
CScanner(eParseMode aMode=eParseMode_navigator);
/**
* 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);
CScanner(nsString& aFilename,PRBool aCreateStream=PR_TRUE);
/**
* 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)
* @return
*/
CScanner(fstream& aStream,eParseMode aMode=eParseMode_navigator);
CScanner(nsString& aFilename,fstream& aStream,PRBool assumeOwnership=PR_TRUE);
~CScanner();
@ -241,16 +219,17 @@ class CScanner {
* @param
* @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
* @param
* @return
*/
nsString& GetBuffer(void);
nsString& GetFilename(void);
static void SelfTest();
@ -268,13 +247,11 @@ class CScanner {
fstream* mFileStream;
nsIInputStream* mNetStream;
nsString mBuffer;
nsString mFilename;
PRInt32 mOffset;
PRInt32 mMarkPos;
PRInt32 mTotalRead;
eParseMode mParseMode;
PRBool mIncremental;
PRBool mOwnsStream;
};

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

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

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

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

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

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

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

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