зеркало из https://github.com/mozilla/gecko-dev.git
performance and bug fixes: r=buster a=chofmann
This commit is contained in:
Родитель
6f744b281a
Коммит
8a6e39e993
|
@ -25,7 +25,6 @@
|
|||
#include "nsIParser.h"
|
||||
#include "nsIHTMLContentSink.h"
|
||||
#include "nsScanner.h"
|
||||
#include "nsTokenHandler.h"
|
||||
#include "nsIDTDDebug.h"
|
||||
#include "prenv.h" //this is here for debug reasons...
|
||||
#include "prtypes.h" //this is here for debug reasons...
|
||||
|
@ -59,9 +58,11 @@ static NS_DEFINE_IID(kClassIID, NS_INAVHTML_DTD_IID);
|
|||
static const char* kNullToken = "Error: Null token given";
|
||||
static const char* kInvalidTagStackPos = "Error: invalid tag stack position";
|
||||
static char* kVerificationDir = "c:/temp";
|
||||
static char gShowCRC=0;
|
||||
static CTokenRecycler* gRecycler=0;
|
||||
|
||||
|
||||
#ifdef RICKG_DEBUG
|
||||
static char gShowCRC=0;
|
||||
#endif
|
||||
|
||||
static eHTMLTags gFormElementTags[]= {
|
||||
eHTMLTag_button, eHTMLTag_fieldset, eHTMLTag_input,
|
||||
|
@ -231,112 +232,6 @@ NS_IMPL_ADDREF(CNavDTD)
|
|||
NS_IMPL_RELEASE(CNavDTD)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @update gess 6/9/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
static
|
||||
PRInt32 NavDispatchTokenHandler(CToken* aToken,nsIDTD* aDTD) {
|
||||
PRInt32 result=0;
|
||||
CHTMLToken* theToken= (CHTMLToken*)(aToken);
|
||||
eHTMLTokenTypes theType= (eHTMLTokenTypes)theToken->GetTokenType();
|
||||
CNavDTD* theDTD=(CNavDTD*)aDTD;
|
||||
|
||||
if(aDTD) {
|
||||
switch(theType) {
|
||||
case eToken_start:
|
||||
case eToken_whitespace:
|
||||
case eToken_newline:
|
||||
case eToken_text:
|
||||
result=theDTD->HandleStartToken(aToken); break;
|
||||
case eToken_end:
|
||||
result=theDTD->HandleEndToken(aToken); break;
|
||||
case eToken_comment:
|
||||
result=theDTD->HandleCommentToken(aToken); break;
|
||||
case eToken_entity:
|
||||
result=theDTD->HandleEntityToken(aToken); break;
|
||||
case eToken_attribute:
|
||||
result=theDTD->HandleAttributeToken(aToken); break;
|
||||
case eToken_style:
|
||||
result=theDTD->HandleStyleToken(aToken); break;
|
||||
case eToken_instruction:
|
||||
result=theDTD->HandleProcessingInstructionToken(aToken); break;
|
||||
case eToken_doctypeDecl:
|
||||
result=theDTD->HandleDocTypeDeclToken(aToken); break;
|
||||
default:
|
||||
result=0;
|
||||
}//switch
|
||||
}//if
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a handler.
|
||||
*
|
||||
* @update gess 4/2/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
CITokenHandler* CNavDTD::AddTokenHandler(CITokenHandler* aHandler) {
|
||||
NS_ASSERTION(0!=aHandler,"Error: Null handler");
|
||||
|
||||
if(aHandler) {
|
||||
eHTMLTokenTypes type=(eHTMLTokenTypes)aHandler->GetTokenType();
|
||||
if(type<eToken_last) {
|
||||
mTokenHandlers[type]=aHandler;
|
||||
}
|
||||
else {
|
||||
//add code here to handle dynamic tokens...
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* init the set of default token handlers...
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void CNavDTD::InitializeDefaultTokenHandlers() {
|
||||
AddTokenHandler(new CTokenHandler(NavDispatchTokenHandler,eToken_start));
|
||||
|
||||
AddTokenHandler(new CTokenHandler(NavDispatchTokenHandler,eToken_end));
|
||||
AddTokenHandler(new CTokenHandler(NavDispatchTokenHandler,eToken_comment));
|
||||
AddTokenHandler(new CTokenHandler(NavDispatchTokenHandler,eToken_entity));
|
||||
|
||||
AddTokenHandler(new CTokenHandler(NavDispatchTokenHandler,eToken_whitespace));
|
||||
AddTokenHandler(new CTokenHandler(NavDispatchTokenHandler,eToken_newline));
|
||||
AddTokenHandler(new CTokenHandler(NavDispatchTokenHandler,eToken_text));
|
||||
|
||||
AddTokenHandler(new CTokenHandler(NavDispatchTokenHandler,eToken_attribute));
|
||||
// AddTokenHandler(new CTokenHandler(NavDispatchTokenHandler,eToken_script));
|
||||
AddTokenHandler(new CTokenHandler(NavDispatchTokenHandler,eToken_style));
|
||||
AddTokenHandler(new CTokenHandler(NavDispatchTokenHandler,eToken_skippedcontent));
|
||||
AddTokenHandler(new CTokenHandler(NavDispatchTokenHandler,eToken_instruction));
|
||||
AddTokenHandler(new CTokenHandler(NavDispatchTokenHandler,eToken_doctypeDecl));
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a tag handler for the given tag type, given in string.
|
||||
*
|
||||
* @update gess 4/2/98
|
||||
* @param aString contains name of tag to be handled
|
||||
* @return valid tag handler (if found) or null
|
||||
*/
|
||||
void CNavDTD::DeleteTokenHandlers(void) {
|
||||
for(int i=eToken_unknown;i<eToken_last;i++){
|
||||
delete mTokenHandlers[i];
|
||||
mTokenHandlers[i]=0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
|
@ -350,12 +245,10 @@ CNavDTD::CNavDTD() : nsIDTD(), mMisplacedContent(0), mSkippedContent(0), mShared
|
|||
mParser=0;
|
||||
mDTDDebug=0;
|
||||
mLineNumber=1;
|
||||
nsCRT::zero(mTokenHandlers,sizeof(mTokenHandlers));
|
||||
mHasOpenBody=PR_FALSE;
|
||||
mHasOpenHead=0;
|
||||
mHasOpenForm=PR_FALSE;
|
||||
mHasOpenMap=PR_FALSE;
|
||||
InitializeDefaultTokenHandlers();
|
||||
mHeadContext=new nsDTDContext();
|
||||
mBodyContext=new nsDTDContext();
|
||||
mFormContext=0;
|
||||
|
@ -365,12 +258,18 @@ CNavDTD::CNavDTD() : nsIDTD(), mMisplacedContent(0), mSkippedContent(0), mShared
|
|||
mExpectedCRC32=0;
|
||||
mSaveBadTokens = PR_FALSE;
|
||||
mDTDState=NS_OK;
|
||||
|
||||
if(!gHTMLElements) {
|
||||
InitializeElementTable();
|
||||
}
|
||||
|
||||
// DebugDumpContainmentRules2(*this,"c:/temp/DTDRules.new","New CNavDTD Containment Rules");
|
||||
#ifdef RICKG_DEBUG
|
||||
nsHTMLElement::DebugDumpContainment("c:/temp/rules.new","ElementTable Rules");
|
||||
nsHTMLElement::DebugDumpMembership("c:/temp/table.out");
|
||||
nsHTMLElement::DebugDumpContainType("c:/temp/ctnrules.out");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -399,7 +298,7 @@ void CNavDTD::RecycleNode(nsCParserNode* aNode) {
|
|||
|
||||
/**
|
||||
*
|
||||
* @update gess1/8/99
|
||||
* @update gess1/8/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
|
@ -415,7 +314,6 @@ const nsIID& CNavDTD::GetMostDerivedIID(void)const {
|
|||
* @return
|
||||
*/
|
||||
CNavDTD::~CNavDTD(){
|
||||
DeleteTokenHandlers();
|
||||
delete mHeadContext;
|
||||
delete mBodyContext;
|
||||
if(mTokenizer)
|
||||
|
@ -543,9 +441,9 @@ nsresult CNavDTD::WillBuildModel(nsString& aFilename,PRBool aNotifySink,nsString
|
|||
* as you can. Not all tokens may make sense, so you may not be able to
|
||||
* read them all (until more come in later).
|
||||
*
|
||||
* @update gess5/18/98
|
||||
* @param aParser is the parser object that's driving this process
|
||||
* @return error code (almost always NS_OK)
|
||||
* @update gess5/18/98
|
||||
* @param aParser is the parser object that's driving this process
|
||||
* @return error code (almost always NS_OK)
|
||||
*/
|
||||
nsresult CNavDTD::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsITokenObserver* anObserver,nsIContentSink* aSink) {
|
||||
nsresult result=NS_OK;
|
||||
|
@ -693,6 +591,7 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
|||
execSkipContent=PR_TRUE;
|
||||
gRecycler->RecycleToken(aToken);
|
||||
theToken=(CHTMLToken*)mSkippedContent.PopFront();
|
||||
theType=eToken_start;
|
||||
// result=HandleStartToken(theToken);
|
||||
}
|
||||
else {
|
||||
|
@ -729,6 +628,7 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
|||
mTokenizer->PushTokenFront(aToken); //put this token back...
|
||||
mTokenizer->PrependTokens(mMisplacedContent); //push misplaced content
|
||||
theToken=(CHTMLToken*)gRecycler->CreateTokenOfType(eToken_start,theTag=eHTMLTag_body);
|
||||
theType=eToken_start;
|
||||
//now open a body...
|
||||
}
|
||||
}
|
||||
|
@ -748,30 +648,55 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
|||
}
|
||||
else {
|
||||
|
||||
CITokenHandler* theHandler=GetTokenHandler(theType);
|
||||
if(theHandler) {
|
||||
mParser=(nsParser*)aParser;
|
||||
result=(*theHandler)(theToken,this);
|
||||
if(NS_SUCCEEDED(result) || (NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
if(theToken->mRecycle)
|
||||
gRecycler->RecycleToken(theToken);
|
||||
}
|
||||
else if(result==NS_ERROR_HTMLPARSER_STOPPARSING)
|
||||
return result;
|
||||
else return NS_OK;
|
||||
/*************************************************************/
|
||||
// CAUTION: Here we are forgetting to push the ATTRIBUTE Tokens.
|
||||
// So, before you uncomment this part please make sure
|
||||
// that the attribute tokens are also accounted for.
|
||||
|
||||
//else if(NS_ERROR_HTMLPARSER_MISPLACED!=result)
|
||||
// mTokenizer->PushTokenFront(theToken);
|
||||
//else result=NS_OK;
|
||||
/***************************************************************/
|
||||
if (mDTDDebug) {
|
||||
//mDTDDebug->Verify(this, mParser, mBodyContext->GetCount(), mBodyContext->mStack, mFilename);
|
||||
}
|
||||
} //if
|
||||
mParser=(nsParser*)aParser;
|
||||
|
||||
switch(theType) {
|
||||
case eToken_start:
|
||||
case eToken_whitespace:
|
||||
case eToken_newline:
|
||||
case eToken_text:
|
||||
result=HandleStartToken(theToken); break;
|
||||
case eToken_end:
|
||||
result=HandleEndToken(theToken); break;
|
||||
case eToken_comment:
|
||||
result=HandleCommentToken(theToken); break;
|
||||
case eToken_entity:
|
||||
result=HandleEntityToken(theToken); break;
|
||||
case eToken_attribute:
|
||||
result=HandleAttributeToken(theToken); break;
|
||||
case eToken_style:
|
||||
result=HandleStyleToken(theToken); break;
|
||||
case eToken_instruction:
|
||||
result=HandleProcessingInstructionToken(theToken); break;
|
||||
case eToken_doctypeDecl:
|
||||
result=HandleDocTypeDeclToken(theToken); break;
|
||||
default:
|
||||
break;
|
||||
}//switch
|
||||
|
||||
|
||||
if(NS_SUCCEEDED(result) || (NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
if(theToken->mRecycle)
|
||||
gRecycler->RecycleToken(theToken);
|
||||
}
|
||||
else if(result==NS_ERROR_HTMLPARSER_STOPPARSING)
|
||||
return result;
|
||||
else return NS_OK;
|
||||
|
||||
/*************************************************************/
|
||||
// CAUTION: Here we are forgetting to push the ATTRIBUTE Tokens.
|
||||
// So, before you uncomment this part please make sure
|
||||
// that the attribute tokens are also accounted for.
|
||||
|
||||
//else if(NS_ERROR_HTMLPARSER_MISPLACED!=result)
|
||||
// mTokenizer->PushTokenFront(theToken);
|
||||
//else result=NS_OK;
|
||||
/***************************************************************/
|
||||
#if 0
|
||||
if (mDTDDebug) {
|
||||
mDTDDebug->Verify(this, mParser, mBodyContext->GetCount(), mBodyContext->mStack, mFilename);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -784,7 +709,7 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
|||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aHandler -- object to receive subsequent tokens...
|
||||
* @return error code (usually 0)
|
||||
* @return error code (usually 0)
|
||||
*/
|
||||
nsresult CNavDTD::CaptureTokenPump(nsITagHandler* aHandler) {
|
||||
nsresult result=NS_OK;
|
||||
|
@ -796,7 +721,7 @@ nsresult CNavDTD::CaptureTokenPump(nsITagHandler* aHandler) {
|
|||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aHandler -- object that received tokens...
|
||||
* @return error code (usually 0)
|
||||
* @return error code (usually 0)
|
||||
*/
|
||||
nsresult CNavDTD::ReleaseTokenPump(nsITagHandler* aHandler){
|
||||
nsresult result=NS_OK;
|
||||
|
@ -1839,42 +1764,34 @@ nsresult CNavDTD::CollectAttributes(nsCParserNode& aNode,eHTMLTags aTag,PRInt32
|
|||
* @param holds the number of skipped content elements encountered
|
||||
* @return Error condition.
|
||||
*/
|
||||
nsresult CNavDTD::CollectSkippedContent(nsCParserNode& aNode,PRInt32& aCount) {
|
||||
nsresult CNavDTD::CollectSkippedContent(nsCParserNode& aNode,PRInt32 &aCount) {
|
||||
|
||||
CTokenRecycler* theRecycler=(CTokenRecycler*)mTokenizer->GetTokenRecycler();
|
||||
|
||||
eHTMLTags theNodeTag=(eHTMLTags)aNode.GetNodeType();
|
||||
|
||||
int aIndex=0;
|
||||
int aMax=mSkippedContent.GetSize();
|
||||
nsAutoString theTempStr;
|
||||
nsAutoString theStr;
|
||||
|
||||
for(aIndex=0;aIndex<aMax;aIndex++){
|
||||
CHTMLToken* theNextToken=(CHTMLToken*)mSkippedContent.PopFront();
|
||||
theNextToken->GetSource(theTempStr);
|
||||
|
||||
eHTMLTokenTypes theTokenType=(eHTMLTokenTypes)theNextToken->GetTokenType();
|
||||
|
||||
if((eHTMLTag_textarea==theNodeTag) && (eToken_entity==theTokenType)) {
|
||||
((CEntityToken*)theNextToken)->TranslateToUnicodeStr(theTempStr);
|
||||
}
|
||||
else theNextToken->GetSource(theTempStr);
|
||||
|
||||
theStr+=theTempStr;
|
||||
theRecycler->RecycleToken(theNextToken);
|
||||
}
|
||||
|
||||
aNode.SetSkippedContent(theStr);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finds a tag handler for the given tag type.
|
||||
*
|
||||
* @update gess 4/2/98
|
||||
* @param aTagType type of tag to be handled
|
||||
* @return valid tag handler (if found) or null
|
||||
*/
|
||||
CITokenHandler* CNavDTD::GetTokenHandler(eHTMLTokenTypes aType) const {
|
||||
CITokenHandler* result=0;
|
||||
if((aType>0) && (aType<eToken_last)) {
|
||||
result=mTokenHandlers[aType];
|
||||
}
|
||||
else {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************
|
||||
The preceeding tables determine the set of elements each tag can contain...
|
||||
|
@ -2041,15 +1958,14 @@ PRBool CNavDTD::IsContainer(PRInt32 aTag) const {
|
|||
* @param aChild -- tag type of child
|
||||
* @return TRUE if propagation closes; false otherwise
|
||||
*/
|
||||
PRBool CNavDTD::ForwardPropagate(nsEntryStack& aStack,eHTMLTags aParentTag,eHTMLTags aChildTag) {
|
||||
PRBool CNavDTD::ForwardPropagate(nsString& aSequence,eHTMLTags aParentTag,eHTMLTags aChildTag) {
|
||||
PRBool result=PR_FALSE;
|
||||
|
||||
switch(aParentTag) {
|
||||
case eHTMLTag_table:
|
||||
{
|
||||
static eHTMLTags tableTags[]={eHTMLTag_tr,eHTMLTag_td};
|
||||
if(FindTagInSet(aChildTag,tableTags,sizeof(tableTags)/sizeof(eHTMLTag_unknown))) {
|
||||
return BackwardPropagate(aStack,aParentTag,aChildTag);
|
||||
if((eHTMLTag_tr==aChildTag) || (eHTMLTag_td==aChildTag)) {
|
||||
return BackwardPropagate(aSequence,aParentTag,aChildTag);
|
||||
}
|
||||
}
|
||||
//otherwise, intentionally fall through...
|
||||
|
@ -2058,9 +1974,8 @@ PRBool CNavDTD::ForwardPropagate(nsEntryStack& aStack,eHTMLTags aParentTag,eHTML
|
|||
{
|
||||
PRBool theCanContainResult=CanContain(eHTMLTag_td,aChildTag);
|
||||
if(PR_TRUE==theCanContainResult) {
|
||||
aStack.Push(eHTMLTag_td);
|
||||
result=BackwardPropagate(aStack,aParentTag,eHTMLTag_td);
|
||||
// result=PR_TRUE;
|
||||
aSequence.Append((PRUnichar)eHTMLTag_td);
|
||||
result=BackwardPropagate(aSequence,aParentTag,eHTMLTag_td);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -2086,9 +2001,10 @@ PRBool CNavDTD::ForwardPropagate(nsEntryStack& aStack,eHTMLTags aParentTag,eHTML
|
|||
* @param aChild -- tag type of child
|
||||
* @return TRUE if propagation closes; false otherwise
|
||||
*/
|
||||
PRBool CNavDTD::BackwardPropagate(nsEntryStack& aStack,eHTMLTags aParentTag,eHTMLTags aChildTag) const {
|
||||
PRBool CNavDTD::BackwardPropagate(nsString& aSequence,eHTMLTags aParentTag,eHTMLTags aChildTag) const {
|
||||
|
||||
eHTMLTags theParentTag=aParentTag; //just init to get past first condition...
|
||||
|
||||
do {
|
||||
CTagList* theRootTags=gHTMLElements[aChildTag].GetRootTags();
|
||||
if(theRootTags) {
|
||||
|
@ -2096,7 +2012,7 @@ PRBool CNavDTD::BackwardPropagate(nsEntryStack& aStack,eHTMLTags aParentTag,eHTM
|
|||
if(CanContain(theParentTag,aChildTag)) {
|
||||
//we've found a complete sequence, so push the parent...
|
||||
aChildTag=theParentTag;
|
||||
aStack.Push(theParentTag);
|
||||
aSequence.Append((PRUnichar)theParentTag);
|
||||
}
|
||||
}
|
||||
else break;
|
||||
|
@ -2853,9 +2769,37 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode& aNode){
|
|||
OpenTransientStyles(theTag);
|
||||
|
||||
STOP_TIMER();
|
||||
|
||||
|
||||
result=mSink->AddLeaf(aNode);
|
||||
|
||||
#if 1
|
||||
PRBool done=false;
|
||||
nsCParserNode* theNode=CreateNode();
|
||||
while(!done) {
|
||||
CToken* theToken=mTokenizer->PeekToken();
|
||||
if(theToken) {
|
||||
eHTMLTags theTag=(eHTMLTags)theToken->GetTypeID();
|
||||
switch(theTag) {
|
||||
case eHTMLTag_newline:
|
||||
mLineNumber++;
|
||||
case eHTMLTag_text:
|
||||
case eHTMLTag_whitespace:
|
||||
{
|
||||
theToken=mTokenizer->PopToken();
|
||||
theNode->Init(theToken,mLineNumber,GetTokenRecycler());
|
||||
result=mSink->AddLeaf(*theNode);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
done=PR_TRUE;
|
||||
} //switch
|
||||
}//if
|
||||
else done=PR_TRUE;
|
||||
} //while
|
||||
RecycleNode(theNode);
|
||||
|
||||
#endif
|
||||
|
||||
START_TIMER();
|
||||
|
||||
}
|
||||
|
@ -2932,60 +2876,36 @@ nsresult CNavDTD::AddHeadLeaf(nsIParserNode& aNode){
|
|||
*/
|
||||
nsresult CNavDTD::CreateContextStackFor(eHTMLTags aChildTag){
|
||||
|
||||
static nsEntryStack kPropagationStack;
|
||||
kPropagationStack.Empty();
|
||||
nsAutoString theSequence;
|
||||
|
||||
nsresult result=(nsresult)kContextMismatch;
|
||||
eHTMLTags theTop=mBodyContext->Last();
|
||||
PRBool bResult=ForwardPropagate(kPropagationStack,theTop,aChildTag);
|
||||
PRBool bResult=ForwardPropagate(theSequence,theTop,aChildTag);
|
||||
|
||||
if(PR_FALSE==bResult){
|
||||
|
||||
if(eHTMLTag_unknown!=theTop) {
|
||||
if(theTop!=aChildTag) //dont even bother if we're already inside a similar element...
|
||||
bResult=BackwardPropagate(kPropagationStack,theTop,aChildTag);
|
||||
|
||||
/*****************************************************************************
|
||||
OH NOOOO!...
|
||||
|
||||
We found a pretty fundamental flaw in the backward propagation code.
|
||||
The previous version propagated from a child to a target parent, and
|
||||
then again from the target parent to the root.
|
||||
Only thing is, that won't work in cases where a container exists that's
|
||||
not in the usual hiearchy:
|
||||
|
||||
<html><body>
|
||||
<div>
|
||||
<table>
|
||||
<!--missing TR>
|
||||
<td>cell text</td>
|
||||
</tr>
|
||||
</table> ...etc...
|
||||
|
||||
In this case, we'd propagate fine from the <TD> to the <TABLE>, and
|
||||
then from the table to the <html>. Unfortunately, the <DIV> won't show
|
||||
up in the propagated form, and then we get out of sync with the actual
|
||||
context stack when it comes to autogenerate containers.
|
||||
******************************************************************************/
|
||||
|
||||
bResult=BackwardPropagate(theSequence,theTop,aChildTag);
|
||||
} //if
|
||||
else bResult=BackwardPropagate(kPropagationStack,eHTMLTag_html,aChildTag);
|
||||
else bResult=BackwardPropagate(theSequence,eHTMLTag_html,aChildTag);
|
||||
} //elseif
|
||||
|
||||
if((0==mBodyContext->GetCount()) || (mBodyContext->Last()==kPropagationStack.Pop()))
|
||||
PRInt32 theLen=theSequence.Length();
|
||||
eHTMLTags theTag=(eHTMLTags)theSequence[--theLen];
|
||||
|
||||
if((0==mBodyContext->GetCount()) || (mBodyContext->Last()==theTag))
|
||||
result=NS_OK;
|
||||
|
||||
//now, build up the stack according to the tags
|
||||
//you have that aren't in the stack...
|
||||
nsAutoString theEmpty;
|
||||
CStartToken theToken(theEmpty);
|
||||
PRInt32 count = kPropagationStack.GetCount();
|
||||
if(PR_TRUE==bResult){
|
||||
while(count>0) {
|
||||
eHTMLTags theTag=kPropagationStack.Pop();
|
||||
while(theLen) {
|
||||
theTag=(eHTMLTags)theSequence[--theLen];
|
||||
theToken.SetTypeID(theTag); //open the container...
|
||||
HandleStartToken(&theToken);
|
||||
count--;
|
||||
}
|
||||
result=NS_OK;
|
||||
}
|
||||
|
@ -2993,31 +2913,6 @@ nsresult CNavDTD::CreateContextStackFor(eHTMLTags aChildTag){
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method gets called to ensure that the context
|
||||
* stack is properly set up for the given child.
|
||||
* We pop containers off the stack (all the way down
|
||||
* html) until we get a container that can contain
|
||||
* the given child.
|
||||
*
|
||||
* @update gess 4/8/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsresult CNavDTD::ReduceContextStackFor(eHTMLTags aChildTag){
|
||||
nsresult result=NS_OK;
|
||||
eHTMLTags theTopTag=mBodyContext->Last();
|
||||
|
||||
while( (theTopTag!=kNotFound) &&
|
||||
(PR_FALSE==CanContain(theTopTag,aChildTag)) &&
|
||||
(PR_FALSE==CanPropagate(theTopTag,aChildTag))){
|
||||
CloseTopmostContainer();
|
||||
theTopTag=mBodyContext->Last();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method causes all explicit style-tag containers that
|
||||
* are opened to be reflected on our internal style-stack.
|
||||
|
@ -3060,7 +2955,7 @@ CNavDTD::UpdateStyleStackForCloseTag(eHTMLTags aTag,eHTMLTags anActualTag){
|
|||
|
||||
/**
|
||||
*
|
||||
* @update gess8/4/98
|
||||
* @update gess8/4/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
|
@ -3071,7 +2966,7 @@ nsITokenRecycler* CNavDTD::GetTokenRecycler(void){
|
|||
|
||||
/**
|
||||
* Retrieve the preferred tokenizer for use by this DTD.
|
||||
* @update gess12/28/98
|
||||
* @update gess12/28/98
|
||||
* @param none
|
||||
* @return ptr to tokenizer
|
||||
*/
|
||||
|
@ -3118,7 +3013,7 @@ nsresult CNavDTD::WillInterruptParse(void){
|
|||
|
||||
/**
|
||||
*
|
||||
* @update gpk03/14/99
|
||||
* @update gpk03/14/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
|
|
|
@ -95,7 +95,6 @@
|
|||
class nsIHTMLContentSink;
|
||||
class nsIDTDDebug;
|
||||
class nsIParserNode;
|
||||
class CITokenHandler;
|
||||
class nsParser;
|
||||
class nsDTDContext;
|
||||
class nsEntryStack;
|
||||
|
@ -315,7 +314,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
|
|||
* @param aChild -- tag type of child
|
||||
* @return True if closure was achieved -- other false
|
||||
*/
|
||||
virtual PRBool ForwardPropagate(nsEntryStack& aTagStack,eHTMLTags aParentTag,eHTMLTags aChildTag);
|
||||
virtual PRBool ForwardPropagate(nsString& aSequence,eHTMLTags aParentTag,eHTMLTags aChildTag);
|
||||
|
||||
/**
|
||||
* This method tries to design a context map (without actually
|
||||
|
@ -326,7 +325,16 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
|
|||
* @param aChild -- tag type of child
|
||||
* @return True if closure was achieved -- other false
|
||||
*/
|
||||
virtual PRBool BackwardPropagate(nsEntryStack& aTagStack,eHTMLTags aParentTag,eHTMLTags aChildTag) const;
|
||||
virtual PRBool BackwardPropagate(nsString& aSequence,eHTMLTags aParentTag,eHTMLTags aChildTag) const;
|
||||
|
||||
/**
|
||||
* Attempt forward and/or backward propagation for the given
|
||||
* child within the current context vector stack.
|
||||
* @update gess5/11/98
|
||||
* @param type of child to be propagated.
|
||||
* @return TRUE if succeeds, otherwise FALSE
|
||||
*/
|
||||
nsresult CreateContextStackFor(eHTMLTags aChildTag);
|
||||
|
||||
/**
|
||||
* Ask parser if a given container is open ANYWHERE on stack
|
||||
|
@ -388,17 +396,6 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
|
|||
NS_IMETHOD StringTagToIntTag(nsString &aTag, PRInt32* aIntTag) const;
|
||||
|
||||
|
||||
/**
|
||||
* 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;
|
||||
CITokenHandler* AddTokenHandler(CITokenHandler* aHandler);
|
||||
void DeleteTokenHandlers(void);
|
||||
|
||||
|
||||
/**
|
||||
* The following set of methods are used to partially construct
|
||||
* the content model (via the sink) according to the type of token.
|
||||
|
@ -473,25 +470,6 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
|
|||
nsresult AddLeaf(const nsIParserNode& aNode);
|
||||
nsresult AddHeadLeaf(nsIParserNode& aNode);
|
||||
|
||||
/**
|
||||
* Causes auto-closures of context vector stack in order to find a
|
||||
* proper home for the given child. Propagation may also occur as
|
||||
* a fall out.
|
||||
* @update gess5/11/98
|
||||
* @param child to be added (somewhere) to context vector stack.
|
||||
* @return error code - 0 if all went well.
|
||||
*/
|
||||
nsresult ReduceContextStackFor(eHTMLTags aChildTag);
|
||||
|
||||
/**
|
||||
* Attempt forward and/or backward propagation for the given
|
||||
* child within the current context vector stack.
|
||||
* @update gess5/11/98
|
||||
* @param type of child to be propagated.
|
||||
* @return TRUE if succeeds, otherwise FALSE
|
||||
*/
|
||||
nsresult CreateContextStackFor(eHTMLTags aChildTag);
|
||||
|
||||
/**
|
||||
* This set of methods is used to create and manage the set of
|
||||
* transient styles that occur as a result of poorly formed HTML
|
||||
|
@ -521,8 +499,6 @@ protected:
|
|||
|
||||
nsIHTMLContentSink* mSink;
|
||||
|
||||
CITokenHandler* mTokenHandlers[eToken_last];
|
||||
|
||||
nsDTDContext* mHeadContext;
|
||||
nsDTDContext* mBodyContext;
|
||||
nsDTDContext* mFormContext;
|
||||
|
@ -548,6 +524,7 @@ protected:
|
|||
|
||||
PRUint32 mComputedCRC32;
|
||||
PRUint32 mExpectedCRC32;
|
||||
|
||||
};
|
||||
|
||||
extern NS_HTMLPARS nsresult NS_NewNavHTMLDTD(nsIDTD** aInstancePtrResult);
|
||||
|
|
|
@ -600,22 +600,6 @@ nsresult COtherDTD::CreateContextStackFor(eHTMLTags aChildTag){
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method gets called to ensure that the context
|
||||
* stack is properly set up for the given child.
|
||||
* We pop containers off the stack (all the way down
|
||||
* html) until we get a container that can contain
|
||||
* the given child.
|
||||
*
|
||||
* @update gess 4/8/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsresult COtherDTD::ReduceContextStackFor(eHTMLTags aChildTag){
|
||||
return CNavDTD::ReduceContextStackFor(aChildTag);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method causes all explicit style-tag containers that
|
||||
* are opened to be reflected on our internal style-stack.
|
||||
|
|
|
@ -361,15 +361,6 @@ private:
|
|||
*/
|
||||
nsresult AddLeaf(const nsIParserNode& aNode);
|
||||
|
||||
/**
|
||||
* Causes auto-closures of context vector stack in order to find a
|
||||
* proper home for the given child. Propagation may also occur as
|
||||
* a fall out.
|
||||
* @update gess5/11/98
|
||||
* @param child to be added (somewhere) to context vector stack.
|
||||
* @return TRUE if succeeds, otherwise FALSE
|
||||
*/
|
||||
nsresult ReduceContextStackFor(eHTMLTags aChildTag);
|
||||
|
||||
/**
|
||||
* Attempt forward and/or backward propagation for the given
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -61,6 +61,8 @@ public:
|
|||
//*********************************************************************************************
|
||||
|
||||
|
||||
extern void InitializeElementTable(void);
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
|
@ -135,9 +137,7 @@ struct nsHTMLElement {
|
|||
eHTMLTags mSkipTarget; //If set, then we skip all content until this tag is seen
|
||||
};
|
||||
|
||||
extern nsHTMLElement gHTMLElements[];
|
||||
extern CTagList gFramesetKids;
|
||||
extern CTagList gHeadingTags;
|
||||
extern nsHTMLElement* gHTMLElements;
|
||||
|
||||
//special property bits...
|
||||
static const int kDiscardTag = 0x0001; //tells us to toss this tag
|
||||
|
|
|
@ -33,8 +33,6 @@
|
|||
|
||||
|
||||
static const char* gUserdefined = "userdefined";
|
||||
static const char* gIdentChars="-0123456789:ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";
|
||||
static const char* gNumChars="0123456789ABCDEFabcdef";
|
||||
|
||||
const PRInt32 kMAXNAMELEN=10;
|
||||
|
||||
|
@ -211,7 +209,7 @@ nsresult CStartToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
|
|||
//NOTE: We don't Consume the tag attributes here, nor do we eat the ">"
|
||||
|
||||
mTextValue=aChar;
|
||||
nsresult result=aScanner.ReadWhile(mTextValue,gIdentChars,PR_TRUE,PR_FALSE);
|
||||
nsresult result=aScanner.ReadIdentifier(mTextValue);
|
||||
mTypeID = nsHTMLTags::LookupTag(mTextValue);
|
||||
|
||||
//Good. Now, let's skip whitespace after the identifier,
|
||||
|
@ -439,12 +437,12 @@ PRInt32 CTextToken::GetTokenType(void) {
|
|||
* @return error result
|
||||
*/
|
||||
nsresult CTextToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
|
||||
static const char* theTerminals="&<\r\n";
|
||||
static const char* theTerminals="\n\r&<";
|
||||
nsresult result=NS_OK;
|
||||
PRBool done=PR_FALSE;
|
||||
|
||||
while((NS_OK==result) && (!done)) {
|
||||
result=aScanner.ReadUntil(mTextValue,theTerminals,PR_FALSE,PR_FALSE);
|
||||
result=aScanner.ReadUntil(mTextValue,theTerminals,PR_TRUE,PR_FALSE);
|
||||
if(NS_OK==result) {
|
||||
result=aScanner.Peek(aChar);
|
||||
if(((kCR==aChar) || (kNewLine==aChar)) && (NS_OK==result)) {
|
||||
|
@ -599,12 +597,12 @@ PRInt32 CCDATASectionToken::GetTokenType(void) {
|
|||
* @return error result
|
||||
*/
|
||||
nsresult CCDATASectionToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
|
||||
static const char* theTerminals="]\r";
|
||||
static const char* theTerminals="\r]";
|
||||
nsresult result=NS_OK;
|
||||
PRBool done=PR_FALSE;
|
||||
|
||||
while((NS_OK==result) && (!done)) {
|
||||
result=aScanner.ReadUntil(mTextValue,theTerminals,PR_FALSE,PR_FALSE);
|
||||
result=aScanner.ReadUntil(mTextValue,theTerminals,PR_TRUE,PR_FALSE);
|
||||
if(NS_OK==result) {
|
||||
result=aScanner.Peek(aChar);
|
||||
if((kCR==aChar) && (NS_OK==result)) {
|
||||
|
@ -1143,7 +1141,7 @@ nsresult ConsumeQuotedString(PRUnichar aChar,nsString& aString,nsScanner& aScann
|
|||
static
|
||||
nsresult ConsumeAttributeValueText(PRUnichar,nsString& aString,nsScanner& aScanner){
|
||||
static const char* theTerminals="\b\t\n\r >";
|
||||
nsresult result=aScanner.ReadUntil(aString,theTerminals,PR_FALSE,PR_FALSE);
|
||||
nsresult result=aScanner.ReadUntil(aString,theTerminals,PR_TRUE,PR_FALSE);
|
||||
|
||||
//Let's force quotes if either the first or last char is quoted.
|
||||
PRUnichar theLast=aString.Last();
|
||||
|
@ -1196,9 +1194,7 @@ nsresult CAttributeToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
|
|||
result=aScanner.GetChar(aChar); //skip the hash sign...
|
||||
if(NS_OK==result) {
|
||||
mTextKey=aChar;
|
||||
|
||||
static const char* gDigits="0123456789";
|
||||
result=aScanner.ReadWhile(mTextKey,gDigits,PR_TRUE,PR_FALSE);
|
||||
result=aScanner.ReadNumber(mTextKey);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -1345,10 +1341,8 @@ PRInt32 CWhitespaceToken::GetTokenType(void) {
|
|||
* @return error result
|
||||
*/
|
||||
nsresult CWhitespaceToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
|
||||
|
||||
mTextValue=aChar;
|
||||
static const char* theWhitespace="\b\t ";
|
||||
nsresult result=aScanner.ReadWhile(mTextValue,theWhitespace,PR_FALSE,PR_FALSE);
|
||||
nsresult result=aScanner.ReadWhitespace(mTextValue);
|
||||
if(NS_OK==result) {
|
||||
mTextValue.StripChars("\r");
|
||||
}
|
||||
|
@ -1460,10 +1454,10 @@ PRInt32 CEntityToken::ConsumeEntity(PRUnichar aChar,nsString& aString,nsScanner&
|
|||
aString+=theChar;
|
||||
}
|
||||
if(NS_OK==result){
|
||||
result=aScanner.ReadWhile(aString,gNumChars,PR_TRUE,PR_FALSE);
|
||||
result=aScanner.ReadNumber(aString);
|
||||
}
|
||||
}
|
||||
else result=aScanner.ReadWhile(aString,gIdentChars,PR_TRUE,PR_FALSE);
|
||||
else result=aScanner.ReadIdentifier(aString);
|
||||
if(NS_OK==result) {
|
||||
result=aScanner.Peek(theChar);
|
||||
if(NS_OK==result) {
|
||||
|
|
|
@ -196,9 +196,11 @@ nsParser::nsParser(nsITokenObserver* anObserver) : mCommand(""), mUnusedInput(""
|
|||
mDTDVerification=PR_FALSE;
|
||||
mCharsetSource=kCharsetUninitialized;
|
||||
mInternalState=NS_OK;
|
||||
|
||||
|
||||
#ifdef RAPTOR_PERF_METRICS
|
||||
mParseTime.Reset();
|
||||
mDTDTime.Reset();
|
||||
mTokenizeTime.Reset();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -697,8 +699,9 @@ nsresult nsParser::Parse(nsIURI* aURL,nsIStreamObserver* aListener,PRBool aVerif
|
|||
nsCRT::free(spec);
|
||||
#endif
|
||||
|
||||
CParserContext* pc=new CParserContext(new nsScanner(theName,PR_FALSE, mCharset, mCharsetSource),aKey,aListener);
|
||||
if(pc) {
|
||||
nsScanner* theScanner=new nsScanner(theName,PR_FALSE,mCharset,mCharsetSource);
|
||||
CParserContext* pc=new CParserContext(theScanner,aKey,aListener);
|
||||
if(pc && theScanner) {
|
||||
pc->mMultipart=PR_TRUE;
|
||||
pc->mContextType=CParserContext::eCTURL;
|
||||
PushContext(*pc);
|
||||
|
@ -729,8 +732,10 @@ nsresult nsParser::Parse(nsIInputStream& aStream,PRBool aVerifyEnabled, void* aK
|
|||
nsAutoString theUnknownFilename("unknown");
|
||||
|
||||
nsInputStream input(&aStream);
|
||||
CParserContext* pc=new CParserContext(new nsScanner(theUnknownFilename, input, mCharset, mCharsetSource),aKey,0);
|
||||
if(pc) {
|
||||
|
||||
nsScanner* theScanner=new nsScanner(theUnknownFilename,input,mCharset,mCharsetSource);
|
||||
CParserContext* pc=new CParserContext(theScanner,aKey,0);
|
||||
if(pc && theScanner) {
|
||||
PushContext(*pc);
|
||||
pc->mSourceType=kHTMLTextContentType;
|
||||
pc->mStreamListenerState=eOnStart;
|
||||
|
@ -776,8 +781,10 @@ nsresult nsParser::Parse(const nsString& aSourceBuffer,void* aKey,const nsString
|
|||
|
||||
if((!mParserContext) || (mParserContext->mKey!=aKey)) {
|
||||
//only make a new context if we dont have one, OR if we do, but has a different context key...
|
||||
pc=new CParserContext(new nsScanner(mUnusedInput, mCharset, mCharsetSource),aKey, 0);
|
||||
if(pc) {
|
||||
|
||||
nsScanner* theScanner=new nsScanner(mUnusedInput,mCharset,mCharsetSource);
|
||||
pc=new CParserContext(theScanner,aKey, 0);
|
||||
if(pc && theScanner) {
|
||||
PushContext(*pc);
|
||||
pc->mStreamListenerState=eOnStart;
|
||||
pc->mContextType=CParserContext::eCTString;
|
||||
|
@ -918,6 +925,7 @@ nsresult nsParser::ResumeParse(nsIDTD* aDefaultDTD, PRBool aIsFinalChunk) {
|
|||
if(mParserContext->mDTD) {
|
||||
mParserContext->mDTD->WillResumeParse();
|
||||
if(NS_OK==result) {
|
||||
|
||||
result=Tokenize(aIsFinalChunk);
|
||||
result=BuildModel();
|
||||
|
||||
|
@ -946,6 +954,14 @@ nsresult nsParser::ResumeParse(nsIDTD* aDefaultDTD, PRBool aIsFinalChunk) {
|
|||
mParseTime.Print();
|
||||
RAPTOR_STOPWATCH_TRACE(("\n"));
|
||||
|
||||
printf("DTD Time: ");
|
||||
mDTDTime.Print();
|
||||
printf("\n");
|
||||
|
||||
printf("Tokenize Time: ");
|
||||
mTokenizeTime.Print();
|
||||
printf("\n");
|
||||
|
||||
#endif
|
||||
return mInternalState;
|
||||
}
|
||||
|
@ -997,8 +1013,11 @@ nsresult nsParser::BuildModel() {
|
|||
}
|
||||
|
||||
nsIDTD* theRootDTD=theRootContext->mDTD;
|
||||
if(theRootDTD)
|
||||
if(theRootDTD) {
|
||||
NS_START_STOPWATCH(mDTDTime);
|
||||
result=theRootDTD->BuildModel(this,theTokenizer,mTokenObserver,mSink);
|
||||
NS_STOP_STOPWATCH(mDTDTime);
|
||||
}
|
||||
}
|
||||
else{
|
||||
mInternalState=result=NS_ERROR_HTMLPARSER_BADTOKENIZER;
|
||||
|
@ -1442,6 +1461,9 @@ nsresult nsParser::Tokenize(PRBool aIsFinalChunk){
|
|||
|
||||
nsITokenizer* theTokenizer=mParserContext->mDTD->GetTokenizer();
|
||||
if(theTokenizer){
|
||||
|
||||
NS_START_STOPWATCH(mTokenizeTime);
|
||||
|
||||
WillTokenize(aIsFinalChunk);
|
||||
while(NS_SUCCEEDED(result)) {
|
||||
mParserContext->mScanner->Mark();
|
||||
|
@ -1458,6 +1480,9 @@ nsresult nsParser::Tokenize(PRBool aIsFinalChunk){
|
|||
}
|
||||
}
|
||||
DidTokenize(aIsFinalChunk);
|
||||
|
||||
NS_STOP_STOPWATCH(mTokenizeTime);
|
||||
|
||||
}
|
||||
else{
|
||||
result=mInternalState=NS_ERROR_HTMLPARSER_BADTOKENIZER;
|
||||
|
|
|
@ -386,6 +386,8 @@ protected:
|
|||
public:
|
||||
Stopwatch mTotalTime;
|
||||
Stopwatch mParseTime;
|
||||
Stopwatch mDTDTime;
|
||||
Stopwatch mTokenizeTime;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
|
|
@ -48,7 +48,7 @@ const int kBufsize=64;
|
|||
* @return
|
||||
*/
|
||||
nsScanner::nsScanner(nsString& anHTMLString, const nsString& aCharset, nsCharsetSource aSource) :
|
||||
mBuffer(anHTMLString), mFilename("")
|
||||
mBuffer(anHTMLString), mFilename(""), mUnicodeXferBuf("")
|
||||
{
|
||||
mTotalRead=mBuffer.Length();
|
||||
mIncremental=PR_FALSE;
|
||||
|
@ -72,7 +72,7 @@ nsScanner::nsScanner(nsString& anHTMLString, const nsString& aCharset, nsCharset
|
|||
* @return
|
||||
*/
|
||||
nsScanner::nsScanner(nsString& aFilename,PRBool aCreateStream, const nsString& aCharset, nsCharsetSource aSource) :
|
||||
mBuffer(""), mFilename(aFilename)
|
||||
mBuffer(""), mFilename(aFilename), mUnicodeXferBuf("")
|
||||
{
|
||||
mIncremental=PR_TRUE;
|
||||
mOffset=0;
|
||||
|
@ -87,7 +87,6 @@ nsScanner::nsScanner(nsString& aFilename,PRBool aCreateStream, const nsString& a
|
|||
mCharset = "";
|
||||
mCharsetSource = kCharsetUninitialized;
|
||||
SetDocumentCharset(aCharset, aSource);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -100,7 +99,7 @@ nsScanner::nsScanner(nsString& aFilename,PRBool aCreateStream, const nsString& a
|
|||
* @return
|
||||
*/
|
||||
nsScanner::nsScanner(nsString& aFilename,nsInputStream& aStream,const nsString& aCharset, nsCharsetSource aSource) :
|
||||
mBuffer(""), mFilename(aFilename)
|
||||
mBuffer(""), mFilename(aFilename) , mUnicodeXferBuf("")
|
||||
{
|
||||
mIncremental=PR_FALSE;
|
||||
mOffset=0;
|
||||
|
@ -249,9 +248,12 @@ PRBool nsScanner::Append(const char* aBuffer, PRUint32 aLen){
|
|||
|
||||
if(mUnicodeDecoder) {
|
||||
PRInt32 unicharBufLen = 0;
|
||||
mUnicodeDecoder->GetMaxLength(aBuffer, aLen, &unicharBufLen);
|
||||
PRUnichar *unichars = new PRUnichar [ unicharBufLen+1 ];
|
||||
nsresult res;
|
||||
mUnicodeDecoder->GetMaxLength(aBuffer, aLen, &unicharBufLen);
|
||||
mUnicodeXferBuf.SetCapacity(unicharBufLen+32);
|
||||
mUnicodeXferBuf.Truncate();
|
||||
PRUnichar *unichars = (PRUnichar*)mUnicodeXferBuf.GetUnicode();
|
||||
|
||||
nsresult res;
|
||||
do {
|
||||
PRInt32 srcLength = aLen;
|
||||
PRInt32 unicharLength = unicharBufLen;
|
||||
|
@ -286,7 +288,7 @@ PRBool nsScanner::Append(const char* aBuffer, PRUint32 aLen){
|
|||
// we continue convert the bytes data into Unicode
|
||||
// if we have conversion error and we have more data.
|
||||
|
||||
delete[] unichars;
|
||||
// delete[] unichars;
|
||||
}
|
||||
else {
|
||||
mBuffer.Append(aBuffer,aLen);
|
||||
|
@ -296,6 +298,7 @@ PRBool nsScanner::Append(const char* aBuffer, PRUint32 aLen){
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
||||
PRBool nsScanner::Append(const PRUnichar* aBuffer, PRUint32 aLen){
|
||||
mBuffer.Append(aBuffer,aLen);
|
||||
mTotalRead+=aLen;
|
||||
|
@ -374,13 +377,12 @@ nsresult nsScanner::Eof() {
|
|||
*/
|
||||
nsresult nsScanner::GetChar(PRUnichar& aChar) {
|
||||
nsresult result=NS_OK;
|
||||
|
||||
aChar=0;
|
||||
aChar=0;
|
||||
if(mOffset>=(PRUint32)mBuffer.Length())
|
||||
result=Eof();
|
||||
|
||||
if(NS_OK == result) {
|
||||
aChar=mBuffer.CharAt(mOffset++);
|
||||
aChar=GetCharAt(mBuffer,mOffset++);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -401,7 +403,7 @@ nsresult nsScanner::Peek(PRUnichar& aChar) {
|
|||
result=Eof();
|
||||
|
||||
if(NS_OK == result) {
|
||||
aChar=mBuffer.CharAt(mOffset);
|
||||
aChar=GetCharAt(mBuffer,mOffset);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -430,12 +432,58 @@ nsresult nsScanner::PutBack(PRUnichar aChar) {
|
|||
* @return error status
|
||||
*/
|
||||
nsresult nsScanner::SkipWhitespace(void) {
|
||||
|
||||
PRUnichar theChar=0;
|
||||
nsresult result=Peek(theChar);
|
||||
const PRUnichar* theBuf=mBuffer.GetUnicode();
|
||||
PRInt32 theOrigin=mOffset;
|
||||
PRBool found=PR_FALSE;
|
||||
|
||||
#if 1
|
||||
while(NS_OK==result) {
|
||||
|
||||
theChar=theBuf[mOffset++];
|
||||
if(theChar) {
|
||||
switch(theChar) {
|
||||
case ' ':
|
||||
case '\r':
|
||||
case '\n':
|
||||
case '\b':
|
||||
case '\t':
|
||||
found=PR_TRUE;
|
||||
break;
|
||||
default:
|
||||
found=PR_FALSE;
|
||||
break;
|
||||
}
|
||||
if(!found) {
|
||||
mOffset-=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mOffset-=1;
|
||||
result=Peek(theChar);
|
||||
theBuf=mBuffer.GetUnicode();
|
||||
theOrigin=mOffset;
|
||||
}
|
||||
}
|
||||
|
||||
//DoErrTest(aString);
|
||||
|
||||
return result;
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static const char* gSpaces=" \n\r\t\b";
|
||||
|
||||
int len=strlen(gSpaces);
|
||||
CBufDescriptor buf(gSpaces,PR_TRUE,len+1,len);
|
||||
nsAutoString theWS(buf);
|
||||
return SkipOver(theWS);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -446,6 +494,7 @@ nsresult nsScanner::SkipWhitespace(void) {
|
|||
* @return error code
|
||||
*/
|
||||
nsresult nsScanner::SkipOver(PRUnichar aSkipChar){
|
||||
|
||||
PRUnichar ch=0;
|
||||
nsresult result=NS_OK;
|
||||
|
||||
|
@ -460,6 +509,7 @@ nsresult nsScanner::SkipOver(PRUnichar aSkipChar){
|
|||
else break;
|
||||
} //while
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -470,6 +520,7 @@ nsresult nsScanner::SkipOver(PRUnichar aSkipChar){
|
|||
* @return error code
|
||||
*/
|
||||
nsresult nsScanner::SkipOver(nsString& aSkipSet){
|
||||
|
||||
PRUnichar theChar=0;
|
||||
nsresult result=NS_OK;
|
||||
|
||||
|
@ -485,6 +536,7 @@ nsresult nsScanner::SkipOver(nsString& aSkipSet){
|
|||
else break;
|
||||
} //while
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -515,6 +567,21 @@ nsresult nsScanner::SkipTo(nsString& aValidSet){
|
|||
}
|
||||
|
||||
|
||||
void DoErrTest(nsString& aString) {
|
||||
PRInt32 pos=aString.FindChar(0);
|
||||
if(kNotFound<pos) {
|
||||
if(aString.Length()-1!=pos)
|
||||
int x=10;
|
||||
}
|
||||
}
|
||||
|
||||
void DoErrTest(nsCString& aString) {
|
||||
PRInt32 pos=aString.FindChar(0);
|
||||
if(kNotFound<pos) {
|
||||
if(aString.Length()-1!=pos)
|
||||
int x=10;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip over chars as long as they're in aValidSet
|
||||
|
@ -529,6 +596,160 @@ nsresult nsScanner::SkipPast(nsString& aValidSet){
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume characters until you find the terminal char
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aString receives new data from stream
|
||||
* @param addTerminal tells us whether to append terminal to aString
|
||||
* @return error code
|
||||
*/
|
||||
nsresult nsScanner::ReadIdentifier(nsString& aString) {
|
||||
|
||||
PRUnichar theChar=0;
|
||||
nsresult result=Peek(theChar);
|
||||
const PRUnichar* theBuf=mBuffer.GetUnicode();
|
||||
PRInt32 theOrigin=mOffset;
|
||||
PRBool found=PR_FALSE;
|
||||
|
||||
while(NS_OK==result) {
|
||||
|
||||
theChar=theBuf[mOffset++];
|
||||
if(theChar) {
|
||||
found=PR_FALSE;
|
||||
switch(theChar) {
|
||||
case ':':
|
||||
case '_':
|
||||
case '-':
|
||||
found=PR_TRUE;
|
||||
break;
|
||||
default:
|
||||
if(('a'<=theChar) && (theChar<='z'))
|
||||
found=PR_TRUE;
|
||||
else if(('A'<=theChar) && (theChar<='Z'))
|
||||
found=PR_TRUE;
|
||||
else if(('0'<=theChar) && (theChar<='9'))
|
||||
found=PR_TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!found) {
|
||||
mOffset-=1;
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
mOffset-=1;
|
||||
result=Peek(theChar);
|
||||
theBuf=mBuffer.GetUnicode();
|
||||
theOrigin=mOffset;
|
||||
}
|
||||
}
|
||||
|
||||
//DoErrTest(aString);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume characters until you find the terminal char
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aString receives new data from stream
|
||||
* @param addTerminal tells us whether to append terminal to aString
|
||||
* @return error code
|
||||
*/
|
||||
nsresult nsScanner::ReadNumber(nsString& aString) {
|
||||
|
||||
PRUnichar theChar=0;
|
||||
nsresult result=Peek(theChar);
|
||||
const PRUnichar* theBuf=mBuffer.GetUnicode();
|
||||
PRInt32 theOrigin=mOffset;
|
||||
PRBool found=PR_FALSE;
|
||||
|
||||
while(NS_OK==result) {
|
||||
|
||||
theChar=theBuf[mOffset++];
|
||||
if(theChar) {
|
||||
found=PR_FALSE;
|
||||
if(('a'<=theChar) && (theChar<='f'))
|
||||
found=PR_TRUE;
|
||||
else if(('A'<=theChar) && (theChar<='F'))
|
||||
found=PR_TRUE;
|
||||
else if(('0'<=theChar) && (theChar<='9'))
|
||||
found=PR_TRUE;
|
||||
if(!found) {
|
||||
mOffset-=1;
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
mOffset-=1;
|
||||
result=Peek(theChar);
|
||||
theBuf=mBuffer.GetUnicode();
|
||||
theOrigin=mOffset;
|
||||
}
|
||||
}
|
||||
|
||||
//DoErrTest(aString);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume characters until you find the terminal char
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aString receives new data from stream
|
||||
* @param addTerminal tells us whether to append terminal to aString
|
||||
* @return error code
|
||||
*/
|
||||
nsresult nsScanner::ReadWhitespace(nsString& aString) {
|
||||
|
||||
PRUnichar theChar=0;
|
||||
nsresult result=Peek(theChar);
|
||||
const PRUnichar* theBuf=mBuffer.GetUnicode();
|
||||
PRInt32 theOrigin=mOffset;
|
||||
PRBool found=PR_FALSE;
|
||||
|
||||
while(NS_OK==result) {
|
||||
|
||||
theChar=theBuf[mOffset++];
|
||||
if(theChar) {
|
||||
switch(theChar) {
|
||||
case ' ':
|
||||
case '\b':
|
||||
case '\t':
|
||||
found=PR_TRUE;
|
||||
break;
|
||||
default:
|
||||
found=PR_FALSE;
|
||||
break;
|
||||
}
|
||||
if(!found) {
|
||||
mOffset-=1;
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
mOffset-=1;
|
||||
result=Peek(theChar);
|
||||
theBuf=mBuffer.GetUnicode();
|
||||
theOrigin=mOffset;
|
||||
}
|
||||
}
|
||||
|
||||
//DoErrTest(aString);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume chars as long as they are <i>in</i> the
|
||||
* given validSet of input chars.
|
||||
|
@ -546,23 +767,36 @@ nsresult nsScanner::ReadWhile(nsString& aString,
|
|||
|
||||
NS_ASSERTION(((PR_FALSE==anOrderedSet) || aValidSet.IsOrdered()),kUnorderedStringError);
|
||||
|
||||
PRUnichar theChar=0;
|
||||
nsresult result=NS_OK;
|
||||
PRUnichar theChar=0;
|
||||
nsresult result=Peek(theChar);
|
||||
const PRUnichar* theBuf=mBuffer.GetUnicode();
|
||||
PRInt32 theOrigin=mOffset;
|
||||
|
||||
while(NS_OK==result) {
|
||||
result=GetChar(theChar);
|
||||
if(NS_OK==result) {
|
||||
|
||||
theChar=theBuf[mOffset++];
|
||||
if(theChar) {
|
||||
PRInt32 pos=(anOrderedSet) ? aValidSet.BinarySearch(theChar) : aValidSet.FindChar(theChar);
|
||||
if(kNotFound==pos) {
|
||||
if(addTerminal)
|
||||
aString+=theChar;
|
||||
else PutBack(theChar);
|
||||
if(!addTerminal)
|
||||
mOffset-=1;
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
break;
|
||||
}
|
||||
else aString+=theChar;
|
||||
}
|
||||
else {
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
mOffset-=1;
|
||||
result=Peek(theChar);
|
||||
theBuf=mBuffer.GetUnicode();
|
||||
theOrigin=mOffset;
|
||||
}
|
||||
}
|
||||
|
||||
//DoErrTest(aString);
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -582,23 +816,36 @@ nsresult nsScanner::ReadWhile(nsString& aString,
|
|||
|
||||
NS_ASSERTION(((PR_FALSE==anOrderedSet) || aValidSet.IsOrdered()),kUnorderedStringError);
|
||||
|
||||
PRUnichar theChar=0;
|
||||
nsresult result=NS_OK;
|
||||
PRUnichar theChar=0;
|
||||
nsresult result=Peek(theChar);
|
||||
const PRUnichar* theBuf=mBuffer.GetUnicode();
|
||||
PRInt32 theOrigin=mOffset;
|
||||
|
||||
while(NS_OK==result) {
|
||||
result=GetChar(theChar);
|
||||
if(NS_OK==result) {
|
||||
|
||||
theChar=theBuf[mOffset++];
|
||||
if(theChar) {
|
||||
PRInt32 pos=(anOrderedSet) ? aValidSet.BinarySearch(theChar) : aValidSet.FindChar(theChar);
|
||||
if(kNotFound==pos) {
|
||||
if(addTerminal)
|
||||
aString+=theChar;
|
||||
else PutBack(theChar);
|
||||
if(!addTerminal)
|
||||
mOffset-=1;
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
break;
|
||||
}
|
||||
else aString+=theChar;
|
||||
}
|
||||
else {
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
mOffset-=1;
|
||||
result=Peek(theChar);
|
||||
theBuf=mBuffer.GetUnicode();
|
||||
theOrigin=mOffset;
|
||||
}
|
||||
}
|
||||
|
||||
//DoErrTest(aString);
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -648,23 +895,37 @@ nsresult nsScanner::ReadUntil(nsString& aString,
|
|||
|
||||
NS_ASSERTION(((PR_FALSE==anOrderedSet) || aTerminalSet.IsOrdered()),kUnorderedStringError);
|
||||
|
||||
PRUnichar theChar=0;
|
||||
nsresult result=NS_OK;
|
||||
|
||||
while(NS_OK == result) {
|
||||
result=GetChar(theChar);
|
||||
if(NS_OK==result) {
|
||||
PRUnichar theChar=0;
|
||||
nsresult result=Peek(theChar);
|
||||
const PRUnichar* theBuf=mBuffer.GetUnicode();
|
||||
PRInt32 theOrigin=mOffset;
|
||||
|
||||
while(NS_OK==result) {
|
||||
|
||||
theChar=theBuf[mOffset++];
|
||||
if(theChar) {
|
||||
PRInt32 pos=(anOrderedSet) ? aTerminalSet.BinarySearch(theChar) : aTerminalSet.FindChar(theChar);
|
||||
if(kNotFound!=pos) {
|
||||
if(addTerminal)
|
||||
aString+=theChar;
|
||||
else PutBack(theChar);
|
||||
if(!addTerminal)
|
||||
mOffset-=1;
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
break;
|
||||
}
|
||||
else aString+=theChar;
|
||||
}
|
||||
else {
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
mOffset-=1;
|
||||
result=Peek(theChar);
|
||||
theBuf=mBuffer.GetUnicode();
|
||||
theOrigin=mOffset;
|
||||
}
|
||||
}
|
||||
|
||||
//DoErrTest(aString);
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -684,25 +945,39 @@ nsresult nsScanner::ReadUntil(nsString& aString,
|
|||
|
||||
NS_ASSERTION(((PR_FALSE==anOrderedSet) || aTerminalSet.IsOrdered()),kUnorderedStringError);
|
||||
|
||||
PRUnichar theChar=0;
|
||||
nsresult result=NS_OK;
|
||||
|
||||
while(NS_OK == result) {
|
||||
result=GetChar(theChar);
|
||||
if(NS_OK==result) {
|
||||
PRUnichar theChar=0;
|
||||
nsresult result=Peek(theChar);
|
||||
const PRUnichar* theBuf=mBuffer.GetUnicode();
|
||||
PRInt32 theOrigin=mOffset;
|
||||
|
||||
while(NS_OK==result) {
|
||||
|
||||
theChar=theBuf[mOffset++];
|
||||
if(theChar) {
|
||||
PRInt32 pos=(anOrderedSet) ? aTerminalSet.BinarySearch(theChar) : aTerminalSet.FindChar(theChar);
|
||||
if(kNotFound!=pos) {
|
||||
if(addTerminal)
|
||||
aString+=theChar;
|
||||
else PutBack(theChar);
|
||||
if(!addTerminal)
|
||||
mOffset-=1;
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
break;
|
||||
}
|
||||
else aString+=theChar;
|
||||
}
|
||||
else {
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
mOffset-=1;
|
||||
result=Peek(theChar);
|
||||
theBuf=mBuffer.GetUnicode();
|
||||
theOrigin=mOffset;
|
||||
}
|
||||
}
|
||||
|
||||
//DoErrTest(aString);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Consume characters until you encounter one contained in given
|
||||
* input set.
|
||||
|
@ -744,18 +1019,35 @@ nsresult nsScanner::ReadUntil(nsString& aString,
|
|||
PRBool addTerminal){
|
||||
PRUnichar theChar=0;
|
||||
nsresult result=NS_OK;
|
||||
PRInt32 thePos=0;
|
||||
|
||||
const PRUnichar* theBuf=mBuffer.GetUnicode();
|
||||
PRInt32 theOrigin=mOffset;
|
||||
result=Peek(theChar);
|
||||
PRUint32 theLen=mBuffer.Length();
|
||||
|
||||
while(NS_OK==result) {
|
||||
result=GetChar(theChar);
|
||||
if(theChar==aTerminalChar) {
|
||||
if(addTerminal)
|
||||
aString+=theChar;
|
||||
else PutBack(theChar);
|
||||
break;
|
||||
|
||||
theChar=theBuf[mOffset++];
|
||||
if(theChar) {
|
||||
if(aTerminalChar==theChar) {
|
||||
if(!addTerminal)
|
||||
mOffset-=1;
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
aString.Append(&theBuf[theOrigin],theLen-theOrigin-1);
|
||||
mOffset=theLen;
|
||||
result=Peek(theChar);
|
||||
theLen=mBuffer.Length();
|
||||
}
|
||||
else aString+=theChar;
|
||||
}
|
||||
|
||||
//DoErrTest(aString);
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -163,6 +163,18 @@ class nsScanner {
|
|||
*/
|
||||
nsresult Eof(void);
|
||||
|
||||
/**
|
||||
* Consume characters until you find the terminal char
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aString receives new data from stream
|
||||
* @param addTerminal tells us whether to append terminal to aString
|
||||
* @return error code
|
||||
*/
|
||||
nsresult ReadIdentifier(nsString& aString);
|
||||
nsresult ReadNumber(nsString& aString);
|
||||
nsresult ReadWhitespace(nsString& aString);
|
||||
|
||||
/**
|
||||
* Consume characters until you find the terminal char
|
||||
*
|
||||
|
@ -299,7 +311,7 @@ class nsScanner {
|
|||
|
||||
protected:
|
||||
|
||||
enum {eBufferSizeThreshold=512};
|
||||
enum {eBufferSizeThreshold=0x1000}; //4K
|
||||
|
||||
/**
|
||||
* Internal method used to cause the internal buffer to
|
||||
|
@ -320,6 +332,7 @@ class nsScanner {
|
|||
nsCharsetSource mCharsetSource;
|
||||
nsString mCharset;
|
||||
nsIUnicodeDecoder *mUnicodeDecoder;
|
||||
nsString mUnicodeXferBuf;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "nsIParser.h"
|
||||
#include "nsIHTMLContentSink.h"
|
||||
#include "nsScanner.h"
|
||||
#include "nsTokenHandler.h"
|
||||
#include "nsIDTDDebug.h"
|
||||
#include "prenv.h" //this is here for debug reasons...
|
||||
#include "prtypes.h" //this is here for debug reasons...
|
||||
|
@ -59,9 +58,11 @@ static NS_DEFINE_IID(kClassIID, NS_INAVHTML_DTD_IID);
|
|||
static const char* kNullToken = "Error: Null token given";
|
||||
static const char* kInvalidTagStackPos = "Error: invalid tag stack position";
|
||||
static char* kVerificationDir = "c:/temp";
|
||||
static char gShowCRC=0;
|
||||
static CTokenRecycler* gRecycler=0;
|
||||
|
||||
|
||||
#ifdef RICKG_DEBUG
|
||||
static char gShowCRC=0;
|
||||
#endif
|
||||
|
||||
static eHTMLTags gFormElementTags[]= {
|
||||
eHTMLTag_button, eHTMLTag_fieldset, eHTMLTag_input,
|
||||
|
@ -231,112 +232,6 @@ NS_IMPL_ADDREF(CNavDTD)
|
|||
NS_IMPL_RELEASE(CNavDTD)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @update gess 6/9/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
static
|
||||
PRInt32 NavDispatchTokenHandler(CToken* aToken,nsIDTD* aDTD) {
|
||||
PRInt32 result=0;
|
||||
CHTMLToken* theToken= (CHTMLToken*)(aToken);
|
||||
eHTMLTokenTypes theType= (eHTMLTokenTypes)theToken->GetTokenType();
|
||||
CNavDTD* theDTD=(CNavDTD*)aDTD;
|
||||
|
||||
if(aDTD) {
|
||||
switch(theType) {
|
||||
case eToken_start:
|
||||
case eToken_whitespace:
|
||||
case eToken_newline:
|
||||
case eToken_text:
|
||||
result=theDTD->HandleStartToken(aToken); break;
|
||||
case eToken_end:
|
||||
result=theDTD->HandleEndToken(aToken); break;
|
||||
case eToken_comment:
|
||||
result=theDTD->HandleCommentToken(aToken); break;
|
||||
case eToken_entity:
|
||||
result=theDTD->HandleEntityToken(aToken); break;
|
||||
case eToken_attribute:
|
||||
result=theDTD->HandleAttributeToken(aToken); break;
|
||||
case eToken_style:
|
||||
result=theDTD->HandleStyleToken(aToken); break;
|
||||
case eToken_instruction:
|
||||
result=theDTD->HandleProcessingInstructionToken(aToken); break;
|
||||
case eToken_doctypeDecl:
|
||||
result=theDTD->HandleDocTypeDeclToken(aToken); break;
|
||||
default:
|
||||
result=0;
|
||||
}//switch
|
||||
}//if
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a handler.
|
||||
*
|
||||
* @update gess 4/2/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
CITokenHandler* CNavDTD::AddTokenHandler(CITokenHandler* aHandler) {
|
||||
NS_ASSERTION(0!=aHandler,"Error: Null handler");
|
||||
|
||||
if(aHandler) {
|
||||
eHTMLTokenTypes type=(eHTMLTokenTypes)aHandler->GetTokenType();
|
||||
if(type<eToken_last) {
|
||||
mTokenHandlers[type]=aHandler;
|
||||
}
|
||||
else {
|
||||
//add code here to handle dynamic tokens...
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* init the set of default token handlers...
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void CNavDTD::InitializeDefaultTokenHandlers() {
|
||||
AddTokenHandler(new CTokenHandler(NavDispatchTokenHandler,eToken_start));
|
||||
|
||||
AddTokenHandler(new CTokenHandler(NavDispatchTokenHandler,eToken_end));
|
||||
AddTokenHandler(new CTokenHandler(NavDispatchTokenHandler,eToken_comment));
|
||||
AddTokenHandler(new CTokenHandler(NavDispatchTokenHandler,eToken_entity));
|
||||
|
||||
AddTokenHandler(new CTokenHandler(NavDispatchTokenHandler,eToken_whitespace));
|
||||
AddTokenHandler(new CTokenHandler(NavDispatchTokenHandler,eToken_newline));
|
||||
AddTokenHandler(new CTokenHandler(NavDispatchTokenHandler,eToken_text));
|
||||
|
||||
AddTokenHandler(new CTokenHandler(NavDispatchTokenHandler,eToken_attribute));
|
||||
// AddTokenHandler(new CTokenHandler(NavDispatchTokenHandler,eToken_script));
|
||||
AddTokenHandler(new CTokenHandler(NavDispatchTokenHandler,eToken_style));
|
||||
AddTokenHandler(new CTokenHandler(NavDispatchTokenHandler,eToken_skippedcontent));
|
||||
AddTokenHandler(new CTokenHandler(NavDispatchTokenHandler,eToken_instruction));
|
||||
AddTokenHandler(new CTokenHandler(NavDispatchTokenHandler,eToken_doctypeDecl));
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a tag handler for the given tag type, given in string.
|
||||
*
|
||||
* @update gess 4/2/98
|
||||
* @param aString contains name of tag to be handled
|
||||
* @return valid tag handler (if found) or null
|
||||
*/
|
||||
void CNavDTD::DeleteTokenHandlers(void) {
|
||||
for(int i=eToken_unknown;i<eToken_last;i++){
|
||||
delete mTokenHandlers[i];
|
||||
mTokenHandlers[i]=0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
|
@ -350,12 +245,10 @@ CNavDTD::CNavDTD() : nsIDTD(), mMisplacedContent(0), mSkippedContent(0), mShared
|
|||
mParser=0;
|
||||
mDTDDebug=0;
|
||||
mLineNumber=1;
|
||||
nsCRT::zero(mTokenHandlers,sizeof(mTokenHandlers));
|
||||
mHasOpenBody=PR_FALSE;
|
||||
mHasOpenHead=0;
|
||||
mHasOpenForm=PR_FALSE;
|
||||
mHasOpenMap=PR_FALSE;
|
||||
InitializeDefaultTokenHandlers();
|
||||
mHeadContext=new nsDTDContext();
|
||||
mBodyContext=new nsDTDContext();
|
||||
mFormContext=0;
|
||||
|
@ -365,12 +258,18 @@ CNavDTD::CNavDTD() : nsIDTD(), mMisplacedContent(0), mSkippedContent(0), mShared
|
|||
mExpectedCRC32=0;
|
||||
mSaveBadTokens = PR_FALSE;
|
||||
mDTDState=NS_OK;
|
||||
|
||||
if(!gHTMLElements) {
|
||||
InitializeElementTable();
|
||||
}
|
||||
|
||||
// DebugDumpContainmentRules2(*this,"c:/temp/DTDRules.new","New CNavDTD Containment Rules");
|
||||
#ifdef RICKG_DEBUG
|
||||
nsHTMLElement::DebugDumpContainment("c:/temp/rules.new","ElementTable Rules");
|
||||
nsHTMLElement::DebugDumpMembership("c:/temp/table.out");
|
||||
nsHTMLElement::DebugDumpContainType("c:/temp/ctnrules.out");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -399,7 +298,7 @@ void CNavDTD::RecycleNode(nsCParserNode* aNode) {
|
|||
|
||||
/**
|
||||
*
|
||||
* @update gess1/8/99
|
||||
* @update gess1/8/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
|
@ -415,7 +314,6 @@ const nsIID& CNavDTD::GetMostDerivedIID(void)const {
|
|||
* @return
|
||||
*/
|
||||
CNavDTD::~CNavDTD(){
|
||||
DeleteTokenHandlers();
|
||||
delete mHeadContext;
|
||||
delete mBodyContext;
|
||||
if(mTokenizer)
|
||||
|
@ -543,9 +441,9 @@ nsresult CNavDTD::WillBuildModel(nsString& aFilename,PRBool aNotifySink,nsString
|
|||
* as you can. Not all tokens may make sense, so you may not be able to
|
||||
* read them all (until more come in later).
|
||||
*
|
||||
* @update gess5/18/98
|
||||
* @param aParser is the parser object that's driving this process
|
||||
* @return error code (almost always NS_OK)
|
||||
* @update gess5/18/98
|
||||
* @param aParser is the parser object that's driving this process
|
||||
* @return error code (almost always NS_OK)
|
||||
*/
|
||||
nsresult CNavDTD::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsITokenObserver* anObserver,nsIContentSink* aSink) {
|
||||
nsresult result=NS_OK;
|
||||
|
@ -693,6 +591,7 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
|||
execSkipContent=PR_TRUE;
|
||||
gRecycler->RecycleToken(aToken);
|
||||
theToken=(CHTMLToken*)mSkippedContent.PopFront();
|
||||
theType=eToken_start;
|
||||
// result=HandleStartToken(theToken);
|
||||
}
|
||||
else {
|
||||
|
@ -729,6 +628,7 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
|||
mTokenizer->PushTokenFront(aToken); //put this token back...
|
||||
mTokenizer->PrependTokens(mMisplacedContent); //push misplaced content
|
||||
theToken=(CHTMLToken*)gRecycler->CreateTokenOfType(eToken_start,theTag=eHTMLTag_body);
|
||||
theType=eToken_start;
|
||||
//now open a body...
|
||||
}
|
||||
}
|
||||
|
@ -748,30 +648,55 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
|||
}
|
||||
else {
|
||||
|
||||
CITokenHandler* theHandler=GetTokenHandler(theType);
|
||||
if(theHandler) {
|
||||
mParser=(nsParser*)aParser;
|
||||
result=(*theHandler)(theToken,this);
|
||||
if(NS_SUCCEEDED(result) || (NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
if(theToken->mRecycle)
|
||||
gRecycler->RecycleToken(theToken);
|
||||
}
|
||||
else if(result==NS_ERROR_HTMLPARSER_STOPPARSING)
|
||||
return result;
|
||||
else return NS_OK;
|
||||
/*************************************************************/
|
||||
// CAUTION: Here we are forgetting to push the ATTRIBUTE Tokens.
|
||||
// So, before you uncomment this part please make sure
|
||||
// that the attribute tokens are also accounted for.
|
||||
|
||||
//else if(NS_ERROR_HTMLPARSER_MISPLACED!=result)
|
||||
// mTokenizer->PushTokenFront(theToken);
|
||||
//else result=NS_OK;
|
||||
/***************************************************************/
|
||||
if (mDTDDebug) {
|
||||
//mDTDDebug->Verify(this, mParser, mBodyContext->GetCount(), mBodyContext->mStack, mFilename);
|
||||
}
|
||||
} //if
|
||||
mParser=(nsParser*)aParser;
|
||||
|
||||
switch(theType) {
|
||||
case eToken_start:
|
||||
case eToken_whitespace:
|
||||
case eToken_newline:
|
||||
case eToken_text:
|
||||
result=HandleStartToken(theToken); break;
|
||||
case eToken_end:
|
||||
result=HandleEndToken(theToken); break;
|
||||
case eToken_comment:
|
||||
result=HandleCommentToken(theToken); break;
|
||||
case eToken_entity:
|
||||
result=HandleEntityToken(theToken); break;
|
||||
case eToken_attribute:
|
||||
result=HandleAttributeToken(theToken); break;
|
||||
case eToken_style:
|
||||
result=HandleStyleToken(theToken); break;
|
||||
case eToken_instruction:
|
||||
result=HandleProcessingInstructionToken(theToken); break;
|
||||
case eToken_doctypeDecl:
|
||||
result=HandleDocTypeDeclToken(theToken); break;
|
||||
default:
|
||||
break;
|
||||
}//switch
|
||||
|
||||
|
||||
if(NS_SUCCEEDED(result) || (NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
if(theToken->mRecycle)
|
||||
gRecycler->RecycleToken(theToken);
|
||||
}
|
||||
else if(result==NS_ERROR_HTMLPARSER_STOPPARSING)
|
||||
return result;
|
||||
else return NS_OK;
|
||||
|
||||
/*************************************************************/
|
||||
// CAUTION: Here we are forgetting to push the ATTRIBUTE Tokens.
|
||||
// So, before you uncomment this part please make sure
|
||||
// that the attribute tokens are also accounted for.
|
||||
|
||||
//else if(NS_ERROR_HTMLPARSER_MISPLACED!=result)
|
||||
// mTokenizer->PushTokenFront(theToken);
|
||||
//else result=NS_OK;
|
||||
/***************************************************************/
|
||||
#if 0
|
||||
if (mDTDDebug) {
|
||||
mDTDDebug->Verify(this, mParser, mBodyContext->GetCount(), mBodyContext->mStack, mFilename);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -784,7 +709,7 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
|||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aHandler -- object to receive subsequent tokens...
|
||||
* @return error code (usually 0)
|
||||
* @return error code (usually 0)
|
||||
*/
|
||||
nsresult CNavDTD::CaptureTokenPump(nsITagHandler* aHandler) {
|
||||
nsresult result=NS_OK;
|
||||
|
@ -796,7 +721,7 @@ nsresult CNavDTD::CaptureTokenPump(nsITagHandler* aHandler) {
|
|||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aHandler -- object that received tokens...
|
||||
* @return error code (usually 0)
|
||||
* @return error code (usually 0)
|
||||
*/
|
||||
nsresult CNavDTD::ReleaseTokenPump(nsITagHandler* aHandler){
|
||||
nsresult result=NS_OK;
|
||||
|
@ -1839,42 +1764,34 @@ nsresult CNavDTD::CollectAttributes(nsCParserNode& aNode,eHTMLTags aTag,PRInt32
|
|||
* @param holds the number of skipped content elements encountered
|
||||
* @return Error condition.
|
||||
*/
|
||||
nsresult CNavDTD::CollectSkippedContent(nsCParserNode& aNode,PRInt32& aCount) {
|
||||
nsresult CNavDTD::CollectSkippedContent(nsCParserNode& aNode,PRInt32 &aCount) {
|
||||
|
||||
CTokenRecycler* theRecycler=(CTokenRecycler*)mTokenizer->GetTokenRecycler();
|
||||
|
||||
eHTMLTags theNodeTag=(eHTMLTags)aNode.GetNodeType();
|
||||
|
||||
int aIndex=0;
|
||||
int aMax=mSkippedContent.GetSize();
|
||||
nsAutoString theTempStr;
|
||||
nsAutoString theStr;
|
||||
|
||||
for(aIndex=0;aIndex<aMax;aIndex++){
|
||||
CHTMLToken* theNextToken=(CHTMLToken*)mSkippedContent.PopFront();
|
||||
theNextToken->GetSource(theTempStr);
|
||||
|
||||
eHTMLTokenTypes theTokenType=(eHTMLTokenTypes)theNextToken->GetTokenType();
|
||||
|
||||
if((eHTMLTag_textarea==theNodeTag) && (eToken_entity==theTokenType)) {
|
||||
((CEntityToken*)theNextToken)->TranslateToUnicodeStr(theTempStr);
|
||||
}
|
||||
else theNextToken->GetSource(theTempStr);
|
||||
|
||||
theStr+=theTempStr;
|
||||
theRecycler->RecycleToken(theNextToken);
|
||||
}
|
||||
|
||||
aNode.SetSkippedContent(theStr);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finds a tag handler for the given tag type.
|
||||
*
|
||||
* @update gess 4/2/98
|
||||
* @param aTagType type of tag to be handled
|
||||
* @return valid tag handler (if found) or null
|
||||
*/
|
||||
CITokenHandler* CNavDTD::GetTokenHandler(eHTMLTokenTypes aType) const {
|
||||
CITokenHandler* result=0;
|
||||
if((aType>0) && (aType<eToken_last)) {
|
||||
result=mTokenHandlers[aType];
|
||||
}
|
||||
else {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************
|
||||
The preceeding tables determine the set of elements each tag can contain...
|
||||
|
@ -2041,15 +1958,14 @@ PRBool CNavDTD::IsContainer(PRInt32 aTag) const {
|
|||
* @param aChild -- tag type of child
|
||||
* @return TRUE if propagation closes; false otherwise
|
||||
*/
|
||||
PRBool CNavDTD::ForwardPropagate(nsEntryStack& aStack,eHTMLTags aParentTag,eHTMLTags aChildTag) {
|
||||
PRBool CNavDTD::ForwardPropagate(nsString& aSequence,eHTMLTags aParentTag,eHTMLTags aChildTag) {
|
||||
PRBool result=PR_FALSE;
|
||||
|
||||
switch(aParentTag) {
|
||||
case eHTMLTag_table:
|
||||
{
|
||||
static eHTMLTags tableTags[]={eHTMLTag_tr,eHTMLTag_td};
|
||||
if(FindTagInSet(aChildTag,tableTags,sizeof(tableTags)/sizeof(eHTMLTag_unknown))) {
|
||||
return BackwardPropagate(aStack,aParentTag,aChildTag);
|
||||
if((eHTMLTag_tr==aChildTag) || (eHTMLTag_td==aChildTag)) {
|
||||
return BackwardPropagate(aSequence,aParentTag,aChildTag);
|
||||
}
|
||||
}
|
||||
//otherwise, intentionally fall through...
|
||||
|
@ -2058,9 +1974,8 @@ PRBool CNavDTD::ForwardPropagate(nsEntryStack& aStack,eHTMLTags aParentTag,eHTML
|
|||
{
|
||||
PRBool theCanContainResult=CanContain(eHTMLTag_td,aChildTag);
|
||||
if(PR_TRUE==theCanContainResult) {
|
||||
aStack.Push(eHTMLTag_td);
|
||||
result=BackwardPropagate(aStack,aParentTag,eHTMLTag_td);
|
||||
// result=PR_TRUE;
|
||||
aSequence.Append((PRUnichar)eHTMLTag_td);
|
||||
result=BackwardPropagate(aSequence,aParentTag,eHTMLTag_td);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -2086,9 +2001,10 @@ PRBool CNavDTD::ForwardPropagate(nsEntryStack& aStack,eHTMLTags aParentTag,eHTML
|
|||
* @param aChild -- tag type of child
|
||||
* @return TRUE if propagation closes; false otherwise
|
||||
*/
|
||||
PRBool CNavDTD::BackwardPropagate(nsEntryStack& aStack,eHTMLTags aParentTag,eHTMLTags aChildTag) const {
|
||||
PRBool CNavDTD::BackwardPropagate(nsString& aSequence,eHTMLTags aParentTag,eHTMLTags aChildTag) const {
|
||||
|
||||
eHTMLTags theParentTag=aParentTag; //just init to get past first condition...
|
||||
|
||||
do {
|
||||
CTagList* theRootTags=gHTMLElements[aChildTag].GetRootTags();
|
||||
if(theRootTags) {
|
||||
|
@ -2096,7 +2012,7 @@ PRBool CNavDTD::BackwardPropagate(nsEntryStack& aStack,eHTMLTags aParentTag,eHTM
|
|||
if(CanContain(theParentTag,aChildTag)) {
|
||||
//we've found a complete sequence, so push the parent...
|
||||
aChildTag=theParentTag;
|
||||
aStack.Push(theParentTag);
|
||||
aSequence.Append((PRUnichar)theParentTag);
|
||||
}
|
||||
}
|
||||
else break;
|
||||
|
@ -2853,9 +2769,37 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode& aNode){
|
|||
OpenTransientStyles(theTag);
|
||||
|
||||
STOP_TIMER();
|
||||
|
||||
|
||||
result=mSink->AddLeaf(aNode);
|
||||
|
||||
#if 1
|
||||
PRBool done=false;
|
||||
nsCParserNode* theNode=CreateNode();
|
||||
while(!done) {
|
||||
CToken* theToken=mTokenizer->PeekToken();
|
||||
if(theToken) {
|
||||
eHTMLTags theTag=(eHTMLTags)theToken->GetTypeID();
|
||||
switch(theTag) {
|
||||
case eHTMLTag_newline:
|
||||
mLineNumber++;
|
||||
case eHTMLTag_text:
|
||||
case eHTMLTag_whitespace:
|
||||
{
|
||||
theToken=mTokenizer->PopToken();
|
||||
theNode->Init(theToken,mLineNumber,GetTokenRecycler());
|
||||
result=mSink->AddLeaf(*theNode);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
done=PR_TRUE;
|
||||
} //switch
|
||||
}//if
|
||||
else done=PR_TRUE;
|
||||
} //while
|
||||
RecycleNode(theNode);
|
||||
|
||||
#endif
|
||||
|
||||
START_TIMER();
|
||||
|
||||
}
|
||||
|
@ -2932,60 +2876,36 @@ nsresult CNavDTD::AddHeadLeaf(nsIParserNode& aNode){
|
|||
*/
|
||||
nsresult CNavDTD::CreateContextStackFor(eHTMLTags aChildTag){
|
||||
|
||||
static nsEntryStack kPropagationStack;
|
||||
kPropagationStack.Empty();
|
||||
nsAutoString theSequence;
|
||||
|
||||
nsresult result=(nsresult)kContextMismatch;
|
||||
eHTMLTags theTop=mBodyContext->Last();
|
||||
PRBool bResult=ForwardPropagate(kPropagationStack,theTop,aChildTag);
|
||||
PRBool bResult=ForwardPropagate(theSequence,theTop,aChildTag);
|
||||
|
||||
if(PR_FALSE==bResult){
|
||||
|
||||
if(eHTMLTag_unknown!=theTop) {
|
||||
if(theTop!=aChildTag) //dont even bother if we're already inside a similar element...
|
||||
bResult=BackwardPropagate(kPropagationStack,theTop,aChildTag);
|
||||
|
||||
/*****************************************************************************
|
||||
OH NOOOO!...
|
||||
|
||||
We found a pretty fundamental flaw in the backward propagation code.
|
||||
The previous version propagated from a child to a target parent, and
|
||||
then again from the target parent to the root.
|
||||
Only thing is, that won't work in cases where a container exists that's
|
||||
not in the usual hiearchy:
|
||||
|
||||
<html><body>
|
||||
<div>
|
||||
<table>
|
||||
<!--missing TR>
|
||||
<td>cell text</td>
|
||||
</tr>
|
||||
</table> ...etc...
|
||||
|
||||
In this case, we'd propagate fine from the <TD> to the <TABLE>, and
|
||||
then from the table to the <html>. Unfortunately, the <DIV> won't show
|
||||
up in the propagated form, and then we get out of sync with the actual
|
||||
context stack when it comes to autogenerate containers.
|
||||
******************************************************************************/
|
||||
|
||||
bResult=BackwardPropagate(theSequence,theTop,aChildTag);
|
||||
} //if
|
||||
else bResult=BackwardPropagate(kPropagationStack,eHTMLTag_html,aChildTag);
|
||||
else bResult=BackwardPropagate(theSequence,eHTMLTag_html,aChildTag);
|
||||
} //elseif
|
||||
|
||||
if((0==mBodyContext->GetCount()) || (mBodyContext->Last()==kPropagationStack.Pop()))
|
||||
PRInt32 theLen=theSequence.Length();
|
||||
eHTMLTags theTag=(eHTMLTags)theSequence[--theLen];
|
||||
|
||||
if((0==mBodyContext->GetCount()) || (mBodyContext->Last()==theTag))
|
||||
result=NS_OK;
|
||||
|
||||
//now, build up the stack according to the tags
|
||||
//you have that aren't in the stack...
|
||||
nsAutoString theEmpty;
|
||||
CStartToken theToken(theEmpty);
|
||||
PRInt32 count = kPropagationStack.GetCount();
|
||||
if(PR_TRUE==bResult){
|
||||
while(count>0) {
|
||||
eHTMLTags theTag=kPropagationStack.Pop();
|
||||
while(theLen) {
|
||||
theTag=(eHTMLTags)theSequence[--theLen];
|
||||
theToken.SetTypeID(theTag); //open the container...
|
||||
HandleStartToken(&theToken);
|
||||
count--;
|
||||
}
|
||||
result=NS_OK;
|
||||
}
|
||||
|
@ -2993,31 +2913,6 @@ nsresult CNavDTD::CreateContextStackFor(eHTMLTags aChildTag){
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method gets called to ensure that the context
|
||||
* stack is properly set up for the given child.
|
||||
* We pop containers off the stack (all the way down
|
||||
* html) until we get a container that can contain
|
||||
* the given child.
|
||||
*
|
||||
* @update gess 4/8/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsresult CNavDTD::ReduceContextStackFor(eHTMLTags aChildTag){
|
||||
nsresult result=NS_OK;
|
||||
eHTMLTags theTopTag=mBodyContext->Last();
|
||||
|
||||
while( (theTopTag!=kNotFound) &&
|
||||
(PR_FALSE==CanContain(theTopTag,aChildTag)) &&
|
||||
(PR_FALSE==CanPropagate(theTopTag,aChildTag))){
|
||||
CloseTopmostContainer();
|
||||
theTopTag=mBodyContext->Last();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method causes all explicit style-tag containers that
|
||||
* are opened to be reflected on our internal style-stack.
|
||||
|
@ -3060,7 +2955,7 @@ CNavDTD::UpdateStyleStackForCloseTag(eHTMLTags aTag,eHTMLTags anActualTag){
|
|||
|
||||
/**
|
||||
*
|
||||
* @update gess8/4/98
|
||||
* @update gess8/4/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
|
@ -3071,7 +2966,7 @@ nsITokenRecycler* CNavDTD::GetTokenRecycler(void){
|
|||
|
||||
/**
|
||||
* Retrieve the preferred tokenizer for use by this DTD.
|
||||
* @update gess12/28/98
|
||||
* @update gess12/28/98
|
||||
* @param none
|
||||
* @return ptr to tokenizer
|
||||
*/
|
||||
|
@ -3118,7 +3013,7 @@ nsresult CNavDTD::WillInterruptParse(void){
|
|||
|
||||
/**
|
||||
*
|
||||
* @update gpk03/14/99
|
||||
* @update gpk03/14/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
|
|
|
@ -95,7 +95,6 @@
|
|||
class nsIHTMLContentSink;
|
||||
class nsIDTDDebug;
|
||||
class nsIParserNode;
|
||||
class CITokenHandler;
|
||||
class nsParser;
|
||||
class nsDTDContext;
|
||||
class nsEntryStack;
|
||||
|
@ -315,7 +314,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
|
|||
* @param aChild -- tag type of child
|
||||
* @return True if closure was achieved -- other false
|
||||
*/
|
||||
virtual PRBool ForwardPropagate(nsEntryStack& aTagStack,eHTMLTags aParentTag,eHTMLTags aChildTag);
|
||||
virtual PRBool ForwardPropagate(nsString& aSequence,eHTMLTags aParentTag,eHTMLTags aChildTag);
|
||||
|
||||
/**
|
||||
* This method tries to design a context map (without actually
|
||||
|
@ -326,7 +325,16 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
|
|||
* @param aChild -- tag type of child
|
||||
* @return True if closure was achieved -- other false
|
||||
*/
|
||||
virtual PRBool BackwardPropagate(nsEntryStack& aTagStack,eHTMLTags aParentTag,eHTMLTags aChildTag) const;
|
||||
virtual PRBool BackwardPropagate(nsString& aSequence,eHTMLTags aParentTag,eHTMLTags aChildTag) const;
|
||||
|
||||
/**
|
||||
* Attempt forward and/or backward propagation for the given
|
||||
* child within the current context vector stack.
|
||||
* @update gess5/11/98
|
||||
* @param type of child to be propagated.
|
||||
* @return TRUE if succeeds, otherwise FALSE
|
||||
*/
|
||||
nsresult CreateContextStackFor(eHTMLTags aChildTag);
|
||||
|
||||
/**
|
||||
* Ask parser if a given container is open ANYWHERE on stack
|
||||
|
@ -388,17 +396,6 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
|
|||
NS_IMETHOD StringTagToIntTag(nsString &aTag, PRInt32* aIntTag) const;
|
||||
|
||||
|
||||
/**
|
||||
* 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;
|
||||
CITokenHandler* AddTokenHandler(CITokenHandler* aHandler);
|
||||
void DeleteTokenHandlers(void);
|
||||
|
||||
|
||||
/**
|
||||
* The following set of methods are used to partially construct
|
||||
* the content model (via the sink) according to the type of token.
|
||||
|
@ -473,25 +470,6 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
|
|||
nsresult AddLeaf(const nsIParserNode& aNode);
|
||||
nsresult AddHeadLeaf(nsIParserNode& aNode);
|
||||
|
||||
/**
|
||||
* Causes auto-closures of context vector stack in order to find a
|
||||
* proper home for the given child. Propagation may also occur as
|
||||
* a fall out.
|
||||
* @update gess5/11/98
|
||||
* @param child to be added (somewhere) to context vector stack.
|
||||
* @return error code - 0 if all went well.
|
||||
*/
|
||||
nsresult ReduceContextStackFor(eHTMLTags aChildTag);
|
||||
|
||||
/**
|
||||
* Attempt forward and/or backward propagation for the given
|
||||
* child within the current context vector stack.
|
||||
* @update gess5/11/98
|
||||
* @param type of child to be propagated.
|
||||
* @return TRUE if succeeds, otherwise FALSE
|
||||
*/
|
||||
nsresult CreateContextStackFor(eHTMLTags aChildTag);
|
||||
|
||||
/**
|
||||
* This set of methods is used to create and manage the set of
|
||||
* transient styles that occur as a result of poorly formed HTML
|
||||
|
@ -521,8 +499,6 @@ protected:
|
|||
|
||||
nsIHTMLContentSink* mSink;
|
||||
|
||||
CITokenHandler* mTokenHandlers[eToken_last];
|
||||
|
||||
nsDTDContext* mHeadContext;
|
||||
nsDTDContext* mBodyContext;
|
||||
nsDTDContext* mFormContext;
|
||||
|
@ -548,6 +524,7 @@ protected:
|
|||
|
||||
PRUint32 mComputedCRC32;
|
||||
PRUint32 mExpectedCRC32;
|
||||
|
||||
};
|
||||
|
||||
extern NS_HTMLPARS nsresult NS_NewNavHTMLDTD(nsIDTD** aInstancePtrResult);
|
||||
|
|
|
@ -600,22 +600,6 @@ nsresult COtherDTD::CreateContextStackFor(eHTMLTags aChildTag){
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method gets called to ensure that the context
|
||||
* stack is properly set up for the given child.
|
||||
* We pop containers off the stack (all the way down
|
||||
* html) until we get a container that can contain
|
||||
* the given child.
|
||||
*
|
||||
* @update gess 4/8/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsresult COtherDTD::ReduceContextStackFor(eHTMLTags aChildTag){
|
||||
return CNavDTD::ReduceContextStackFor(aChildTag);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method causes all explicit style-tag containers that
|
||||
* are opened to be reflected on our internal style-stack.
|
||||
|
|
|
@ -361,15 +361,6 @@ private:
|
|||
*/
|
||||
nsresult AddLeaf(const nsIParserNode& aNode);
|
||||
|
||||
/**
|
||||
* Causes auto-closures of context vector stack in order to find a
|
||||
* proper home for the given child. Propagation may also occur as
|
||||
* a fall out.
|
||||
* @update gess5/11/98
|
||||
* @param child to be added (somewhere) to context vector stack.
|
||||
* @return TRUE if succeeds, otherwise FALSE
|
||||
*/
|
||||
nsresult ReduceContextStackFor(eHTMLTags aChildTag);
|
||||
|
||||
/**
|
||||
* Attempt forward and/or backward propagation for the given
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -61,6 +61,8 @@ public:
|
|||
//*********************************************************************************************
|
||||
|
||||
|
||||
extern void InitializeElementTable(void);
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
|
@ -135,9 +137,7 @@ struct nsHTMLElement {
|
|||
eHTMLTags mSkipTarget; //If set, then we skip all content until this tag is seen
|
||||
};
|
||||
|
||||
extern nsHTMLElement gHTMLElements[];
|
||||
extern CTagList gFramesetKids;
|
||||
extern CTagList gHeadingTags;
|
||||
extern nsHTMLElement* gHTMLElements;
|
||||
|
||||
//special property bits...
|
||||
static const int kDiscardTag = 0x0001; //tells us to toss this tag
|
||||
|
|
|
@ -33,8 +33,6 @@
|
|||
|
||||
|
||||
static const char* gUserdefined = "userdefined";
|
||||
static const char* gIdentChars="-0123456789:ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";
|
||||
static const char* gNumChars="0123456789ABCDEFabcdef";
|
||||
|
||||
const PRInt32 kMAXNAMELEN=10;
|
||||
|
||||
|
@ -211,7 +209,7 @@ nsresult CStartToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
|
|||
//NOTE: We don't Consume the tag attributes here, nor do we eat the ">"
|
||||
|
||||
mTextValue=aChar;
|
||||
nsresult result=aScanner.ReadWhile(mTextValue,gIdentChars,PR_TRUE,PR_FALSE);
|
||||
nsresult result=aScanner.ReadIdentifier(mTextValue);
|
||||
mTypeID = nsHTMLTags::LookupTag(mTextValue);
|
||||
|
||||
//Good. Now, let's skip whitespace after the identifier,
|
||||
|
@ -439,12 +437,12 @@ PRInt32 CTextToken::GetTokenType(void) {
|
|||
* @return error result
|
||||
*/
|
||||
nsresult CTextToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
|
||||
static const char* theTerminals="&<\r\n";
|
||||
static const char* theTerminals="\n\r&<";
|
||||
nsresult result=NS_OK;
|
||||
PRBool done=PR_FALSE;
|
||||
|
||||
while((NS_OK==result) && (!done)) {
|
||||
result=aScanner.ReadUntil(mTextValue,theTerminals,PR_FALSE,PR_FALSE);
|
||||
result=aScanner.ReadUntil(mTextValue,theTerminals,PR_TRUE,PR_FALSE);
|
||||
if(NS_OK==result) {
|
||||
result=aScanner.Peek(aChar);
|
||||
if(((kCR==aChar) || (kNewLine==aChar)) && (NS_OK==result)) {
|
||||
|
@ -599,12 +597,12 @@ PRInt32 CCDATASectionToken::GetTokenType(void) {
|
|||
* @return error result
|
||||
*/
|
||||
nsresult CCDATASectionToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
|
||||
static const char* theTerminals="]\r";
|
||||
static const char* theTerminals="\r]";
|
||||
nsresult result=NS_OK;
|
||||
PRBool done=PR_FALSE;
|
||||
|
||||
while((NS_OK==result) && (!done)) {
|
||||
result=aScanner.ReadUntil(mTextValue,theTerminals,PR_FALSE,PR_FALSE);
|
||||
result=aScanner.ReadUntil(mTextValue,theTerminals,PR_TRUE,PR_FALSE);
|
||||
if(NS_OK==result) {
|
||||
result=aScanner.Peek(aChar);
|
||||
if((kCR==aChar) && (NS_OK==result)) {
|
||||
|
@ -1143,7 +1141,7 @@ nsresult ConsumeQuotedString(PRUnichar aChar,nsString& aString,nsScanner& aScann
|
|||
static
|
||||
nsresult ConsumeAttributeValueText(PRUnichar,nsString& aString,nsScanner& aScanner){
|
||||
static const char* theTerminals="\b\t\n\r >";
|
||||
nsresult result=aScanner.ReadUntil(aString,theTerminals,PR_FALSE,PR_FALSE);
|
||||
nsresult result=aScanner.ReadUntil(aString,theTerminals,PR_TRUE,PR_FALSE);
|
||||
|
||||
//Let's force quotes if either the first or last char is quoted.
|
||||
PRUnichar theLast=aString.Last();
|
||||
|
@ -1196,9 +1194,7 @@ nsresult CAttributeToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
|
|||
result=aScanner.GetChar(aChar); //skip the hash sign...
|
||||
if(NS_OK==result) {
|
||||
mTextKey=aChar;
|
||||
|
||||
static const char* gDigits="0123456789";
|
||||
result=aScanner.ReadWhile(mTextKey,gDigits,PR_TRUE,PR_FALSE);
|
||||
result=aScanner.ReadNumber(mTextKey);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -1345,10 +1341,8 @@ PRInt32 CWhitespaceToken::GetTokenType(void) {
|
|||
* @return error result
|
||||
*/
|
||||
nsresult CWhitespaceToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
|
||||
|
||||
mTextValue=aChar;
|
||||
static const char* theWhitespace="\b\t ";
|
||||
nsresult result=aScanner.ReadWhile(mTextValue,theWhitespace,PR_FALSE,PR_FALSE);
|
||||
nsresult result=aScanner.ReadWhitespace(mTextValue);
|
||||
if(NS_OK==result) {
|
||||
mTextValue.StripChars("\r");
|
||||
}
|
||||
|
@ -1460,10 +1454,10 @@ PRInt32 CEntityToken::ConsumeEntity(PRUnichar aChar,nsString& aString,nsScanner&
|
|||
aString+=theChar;
|
||||
}
|
||||
if(NS_OK==result){
|
||||
result=aScanner.ReadWhile(aString,gNumChars,PR_TRUE,PR_FALSE);
|
||||
result=aScanner.ReadNumber(aString);
|
||||
}
|
||||
}
|
||||
else result=aScanner.ReadWhile(aString,gIdentChars,PR_TRUE,PR_FALSE);
|
||||
else result=aScanner.ReadIdentifier(aString);
|
||||
if(NS_OK==result) {
|
||||
result=aScanner.Peek(theChar);
|
||||
if(NS_OK==result) {
|
||||
|
|
|
@ -196,9 +196,11 @@ nsParser::nsParser(nsITokenObserver* anObserver) : mCommand(""), mUnusedInput(""
|
|||
mDTDVerification=PR_FALSE;
|
||||
mCharsetSource=kCharsetUninitialized;
|
||||
mInternalState=NS_OK;
|
||||
|
||||
|
||||
#ifdef RAPTOR_PERF_METRICS
|
||||
mParseTime.Reset();
|
||||
mDTDTime.Reset();
|
||||
mTokenizeTime.Reset();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -697,8 +699,9 @@ nsresult nsParser::Parse(nsIURI* aURL,nsIStreamObserver* aListener,PRBool aVerif
|
|||
nsCRT::free(spec);
|
||||
#endif
|
||||
|
||||
CParserContext* pc=new CParserContext(new nsScanner(theName,PR_FALSE, mCharset, mCharsetSource),aKey,aListener);
|
||||
if(pc) {
|
||||
nsScanner* theScanner=new nsScanner(theName,PR_FALSE,mCharset,mCharsetSource);
|
||||
CParserContext* pc=new CParserContext(theScanner,aKey,aListener);
|
||||
if(pc && theScanner) {
|
||||
pc->mMultipart=PR_TRUE;
|
||||
pc->mContextType=CParserContext::eCTURL;
|
||||
PushContext(*pc);
|
||||
|
@ -729,8 +732,10 @@ nsresult nsParser::Parse(nsIInputStream& aStream,PRBool aVerifyEnabled, void* aK
|
|||
nsAutoString theUnknownFilename("unknown");
|
||||
|
||||
nsInputStream input(&aStream);
|
||||
CParserContext* pc=new CParserContext(new nsScanner(theUnknownFilename, input, mCharset, mCharsetSource),aKey,0);
|
||||
if(pc) {
|
||||
|
||||
nsScanner* theScanner=new nsScanner(theUnknownFilename,input,mCharset,mCharsetSource);
|
||||
CParserContext* pc=new CParserContext(theScanner,aKey,0);
|
||||
if(pc && theScanner) {
|
||||
PushContext(*pc);
|
||||
pc->mSourceType=kHTMLTextContentType;
|
||||
pc->mStreamListenerState=eOnStart;
|
||||
|
@ -776,8 +781,10 @@ nsresult nsParser::Parse(const nsString& aSourceBuffer,void* aKey,const nsString
|
|||
|
||||
if((!mParserContext) || (mParserContext->mKey!=aKey)) {
|
||||
//only make a new context if we dont have one, OR if we do, but has a different context key...
|
||||
pc=new CParserContext(new nsScanner(mUnusedInput, mCharset, mCharsetSource),aKey, 0);
|
||||
if(pc) {
|
||||
|
||||
nsScanner* theScanner=new nsScanner(mUnusedInput,mCharset,mCharsetSource);
|
||||
pc=new CParserContext(theScanner,aKey, 0);
|
||||
if(pc && theScanner) {
|
||||
PushContext(*pc);
|
||||
pc->mStreamListenerState=eOnStart;
|
||||
pc->mContextType=CParserContext::eCTString;
|
||||
|
@ -918,6 +925,7 @@ nsresult nsParser::ResumeParse(nsIDTD* aDefaultDTD, PRBool aIsFinalChunk) {
|
|||
if(mParserContext->mDTD) {
|
||||
mParserContext->mDTD->WillResumeParse();
|
||||
if(NS_OK==result) {
|
||||
|
||||
result=Tokenize(aIsFinalChunk);
|
||||
result=BuildModel();
|
||||
|
||||
|
@ -946,6 +954,14 @@ nsresult nsParser::ResumeParse(nsIDTD* aDefaultDTD, PRBool aIsFinalChunk) {
|
|||
mParseTime.Print();
|
||||
RAPTOR_STOPWATCH_TRACE(("\n"));
|
||||
|
||||
printf("DTD Time: ");
|
||||
mDTDTime.Print();
|
||||
printf("\n");
|
||||
|
||||
printf("Tokenize Time: ");
|
||||
mTokenizeTime.Print();
|
||||
printf("\n");
|
||||
|
||||
#endif
|
||||
return mInternalState;
|
||||
}
|
||||
|
@ -997,8 +1013,11 @@ nsresult nsParser::BuildModel() {
|
|||
}
|
||||
|
||||
nsIDTD* theRootDTD=theRootContext->mDTD;
|
||||
if(theRootDTD)
|
||||
if(theRootDTD) {
|
||||
NS_START_STOPWATCH(mDTDTime);
|
||||
result=theRootDTD->BuildModel(this,theTokenizer,mTokenObserver,mSink);
|
||||
NS_STOP_STOPWATCH(mDTDTime);
|
||||
}
|
||||
}
|
||||
else{
|
||||
mInternalState=result=NS_ERROR_HTMLPARSER_BADTOKENIZER;
|
||||
|
@ -1442,6 +1461,9 @@ nsresult nsParser::Tokenize(PRBool aIsFinalChunk){
|
|||
|
||||
nsITokenizer* theTokenizer=mParserContext->mDTD->GetTokenizer();
|
||||
if(theTokenizer){
|
||||
|
||||
NS_START_STOPWATCH(mTokenizeTime);
|
||||
|
||||
WillTokenize(aIsFinalChunk);
|
||||
while(NS_SUCCEEDED(result)) {
|
||||
mParserContext->mScanner->Mark();
|
||||
|
@ -1458,6 +1480,9 @@ nsresult nsParser::Tokenize(PRBool aIsFinalChunk){
|
|||
}
|
||||
}
|
||||
DidTokenize(aIsFinalChunk);
|
||||
|
||||
NS_STOP_STOPWATCH(mTokenizeTime);
|
||||
|
||||
}
|
||||
else{
|
||||
result=mInternalState=NS_ERROR_HTMLPARSER_BADTOKENIZER;
|
||||
|
|
|
@ -386,6 +386,8 @@ protected:
|
|||
public:
|
||||
Stopwatch mTotalTime;
|
||||
Stopwatch mParseTime;
|
||||
Stopwatch mDTDTime;
|
||||
Stopwatch mTokenizeTime;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
|
|
@ -48,7 +48,7 @@ const int kBufsize=64;
|
|||
* @return
|
||||
*/
|
||||
nsScanner::nsScanner(nsString& anHTMLString, const nsString& aCharset, nsCharsetSource aSource) :
|
||||
mBuffer(anHTMLString), mFilename("")
|
||||
mBuffer(anHTMLString), mFilename(""), mUnicodeXferBuf("")
|
||||
{
|
||||
mTotalRead=mBuffer.Length();
|
||||
mIncremental=PR_FALSE;
|
||||
|
@ -72,7 +72,7 @@ nsScanner::nsScanner(nsString& anHTMLString, const nsString& aCharset, nsCharset
|
|||
* @return
|
||||
*/
|
||||
nsScanner::nsScanner(nsString& aFilename,PRBool aCreateStream, const nsString& aCharset, nsCharsetSource aSource) :
|
||||
mBuffer(""), mFilename(aFilename)
|
||||
mBuffer(""), mFilename(aFilename), mUnicodeXferBuf("")
|
||||
{
|
||||
mIncremental=PR_TRUE;
|
||||
mOffset=0;
|
||||
|
@ -87,7 +87,6 @@ nsScanner::nsScanner(nsString& aFilename,PRBool aCreateStream, const nsString& a
|
|||
mCharset = "";
|
||||
mCharsetSource = kCharsetUninitialized;
|
||||
SetDocumentCharset(aCharset, aSource);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -100,7 +99,7 @@ nsScanner::nsScanner(nsString& aFilename,PRBool aCreateStream, const nsString& a
|
|||
* @return
|
||||
*/
|
||||
nsScanner::nsScanner(nsString& aFilename,nsInputStream& aStream,const nsString& aCharset, nsCharsetSource aSource) :
|
||||
mBuffer(""), mFilename(aFilename)
|
||||
mBuffer(""), mFilename(aFilename) , mUnicodeXferBuf("")
|
||||
{
|
||||
mIncremental=PR_FALSE;
|
||||
mOffset=0;
|
||||
|
@ -249,9 +248,12 @@ PRBool nsScanner::Append(const char* aBuffer, PRUint32 aLen){
|
|||
|
||||
if(mUnicodeDecoder) {
|
||||
PRInt32 unicharBufLen = 0;
|
||||
mUnicodeDecoder->GetMaxLength(aBuffer, aLen, &unicharBufLen);
|
||||
PRUnichar *unichars = new PRUnichar [ unicharBufLen+1 ];
|
||||
nsresult res;
|
||||
mUnicodeDecoder->GetMaxLength(aBuffer, aLen, &unicharBufLen);
|
||||
mUnicodeXferBuf.SetCapacity(unicharBufLen+32);
|
||||
mUnicodeXferBuf.Truncate();
|
||||
PRUnichar *unichars = (PRUnichar*)mUnicodeXferBuf.GetUnicode();
|
||||
|
||||
nsresult res;
|
||||
do {
|
||||
PRInt32 srcLength = aLen;
|
||||
PRInt32 unicharLength = unicharBufLen;
|
||||
|
@ -286,7 +288,7 @@ PRBool nsScanner::Append(const char* aBuffer, PRUint32 aLen){
|
|||
// we continue convert the bytes data into Unicode
|
||||
// if we have conversion error and we have more data.
|
||||
|
||||
delete[] unichars;
|
||||
// delete[] unichars;
|
||||
}
|
||||
else {
|
||||
mBuffer.Append(aBuffer,aLen);
|
||||
|
@ -296,6 +298,7 @@ PRBool nsScanner::Append(const char* aBuffer, PRUint32 aLen){
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
||||
PRBool nsScanner::Append(const PRUnichar* aBuffer, PRUint32 aLen){
|
||||
mBuffer.Append(aBuffer,aLen);
|
||||
mTotalRead+=aLen;
|
||||
|
@ -374,13 +377,12 @@ nsresult nsScanner::Eof() {
|
|||
*/
|
||||
nsresult nsScanner::GetChar(PRUnichar& aChar) {
|
||||
nsresult result=NS_OK;
|
||||
|
||||
aChar=0;
|
||||
aChar=0;
|
||||
if(mOffset>=(PRUint32)mBuffer.Length())
|
||||
result=Eof();
|
||||
|
||||
if(NS_OK == result) {
|
||||
aChar=mBuffer.CharAt(mOffset++);
|
||||
aChar=GetCharAt(mBuffer,mOffset++);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -401,7 +403,7 @@ nsresult nsScanner::Peek(PRUnichar& aChar) {
|
|||
result=Eof();
|
||||
|
||||
if(NS_OK == result) {
|
||||
aChar=mBuffer.CharAt(mOffset);
|
||||
aChar=GetCharAt(mBuffer,mOffset);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -430,12 +432,58 @@ nsresult nsScanner::PutBack(PRUnichar aChar) {
|
|||
* @return error status
|
||||
*/
|
||||
nsresult nsScanner::SkipWhitespace(void) {
|
||||
|
||||
PRUnichar theChar=0;
|
||||
nsresult result=Peek(theChar);
|
||||
const PRUnichar* theBuf=mBuffer.GetUnicode();
|
||||
PRInt32 theOrigin=mOffset;
|
||||
PRBool found=PR_FALSE;
|
||||
|
||||
#if 1
|
||||
while(NS_OK==result) {
|
||||
|
||||
theChar=theBuf[mOffset++];
|
||||
if(theChar) {
|
||||
switch(theChar) {
|
||||
case ' ':
|
||||
case '\r':
|
||||
case '\n':
|
||||
case '\b':
|
||||
case '\t':
|
||||
found=PR_TRUE;
|
||||
break;
|
||||
default:
|
||||
found=PR_FALSE;
|
||||
break;
|
||||
}
|
||||
if(!found) {
|
||||
mOffset-=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mOffset-=1;
|
||||
result=Peek(theChar);
|
||||
theBuf=mBuffer.GetUnicode();
|
||||
theOrigin=mOffset;
|
||||
}
|
||||
}
|
||||
|
||||
//DoErrTest(aString);
|
||||
|
||||
return result;
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static const char* gSpaces=" \n\r\t\b";
|
||||
|
||||
int len=strlen(gSpaces);
|
||||
CBufDescriptor buf(gSpaces,PR_TRUE,len+1,len);
|
||||
nsAutoString theWS(buf);
|
||||
return SkipOver(theWS);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -446,6 +494,7 @@ nsresult nsScanner::SkipWhitespace(void) {
|
|||
* @return error code
|
||||
*/
|
||||
nsresult nsScanner::SkipOver(PRUnichar aSkipChar){
|
||||
|
||||
PRUnichar ch=0;
|
||||
nsresult result=NS_OK;
|
||||
|
||||
|
@ -460,6 +509,7 @@ nsresult nsScanner::SkipOver(PRUnichar aSkipChar){
|
|||
else break;
|
||||
} //while
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -470,6 +520,7 @@ nsresult nsScanner::SkipOver(PRUnichar aSkipChar){
|
|||
* @return error code
|
||||
*/
|
||||
nsresult nsScanner::SkipOver(nsString& aSkipSet){
|
||||
|
||||
PRUnichar theChar=0;
|
||||
nsresult result=NS_OK;
|
||||
|
||||
|
@ -485,6 +536,7 @@ nsresult nsScanner::SkipOver(nsString& aSkipSet){
|
|||
else break;
|
||||
} //while
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -515,6 +567,21 @@ nsresult nsScanner::SkipTo(nsString& aValidSet){
|
|||
}
|
||||
|
||||
|
||||
void DoErrTest(nsString& aString) {
|
||||
PRInt32 pos=aString.FindChar(0);
|
||||
if(kNotFound<pos) {
|
||||
if(aString.Length()-1!=pos)
|
||||
int x=10;
|
||||
}
|
||||
}
|
||||
|
||||
void DoErrTest(nsCString& aString) {
|
||||
PRInt32 pos=aString.FindChar(0);
|
||||
if(kNotFound<pos) {
|
||||
if(aString.Length()-1!=pos)
|
||||
int x=10;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip over chars as long as they're in aValidSet
|
||||
|
@ -529,6 +596,160 @@ nsresult nsScanner::SkipPast(nsString& aValidSet){
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume characters until you find the terminal char
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aString receives new data from stream
|
||||
* @param addTerminal tells us whether to append terminal to aString
|
||||
* @return error code
|
||||
*/
|
||||
nsresult nsScanner::ReadIdentifier(nsString& aString) {
|
||||
|
||||
PRUnichar theChar=0;
|
||||
nsresult result=Peek(theChar);
|
||||
const PRUnichar* theBuf=mBuffer.GetUnicode();
|
||||
PRInt32 theOrigin=mOffset;
|
||||
PRBool found=PR_FALSE;
|
||||
|
||||
while(NS_OK==result) {
|
||||
|
||||
theChar=theBuf[mOffset++];
|
||||
if(theChar) {
|
||||
found=PR_FALSE;
|
||||
switch(theChar) {
|
||||
case ':':
|
||||
case '_':
|
||||
case '-':
|
||||
found=PR_TRUE;
|
||||
break;
|
||||
default:
|
||||
if(('a'<=theChar) && (theChar<='z'))
|
||||
found=PR_TRUE;
|
||||
else if(('A'<=theChar) && (theChar<='Z'))
|
||||
found=PR_TRUE;
|
||||
else if(('0'<=theChar) && (theChar<='9'))
|
||||
found=PR_TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!found) {
|
||||
mOffset-=1;
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
mOffset-=1;
|
||||
result=Peek(theChar);
|
||||
theBuf=mBuffer.GetUnicode();
|
||||
theOrigin=mOffset;
|
||||
}
|
||||
}
|
||||
|
||||
//DoErrTest(aString);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume characters until you find the terminal char
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aString receives new data from stream
|
||||
* @param addTerminal tells us whether to append terminal to aString
|
||||
* @return error code
|
||||
*/
|
||||
nsresult nsScanner::ReadNumber(nsString& aString) {
|
||||
|
||||
PRUnichar theChar=0;
|
||||
nsresult result=Peek(theChar);
|
||||
const PRUnichar* theBuf=mBuffer.GetUnicode();
|
||||
PRInt32 theOrigin=mOffset;
|
||||
PRBool found=PR_FALSE;
|
||||
|
||||
while(NS_OK==result) {
|
||||
|
||||
theChar=theBuf[mOffset++];
|
||||
if(theChar) {
|
||||
found=PR_FALSE;
|
||||
if(('a'<=theChar) && (theChar<='f'))
|
||||
found=PR_TRUE;
|
||||
else if(('A'<=theChar) && (theChar<='F'))
|
||||
found=PR_TRUE;
|
||||
else if(('0'<=theChar) && (theChar<='9'))
|
||||
found=PR_TRUE;
|
||||
if(!found) {
|
||||
mOffset-=1;
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
mOffset-=1;
|
||||
result=Peek(theChar);
|
||||
theBuf=mBuffer.GetUnicode();
|
||||
theOrigin=mOffset;
|
||||
}
|
||||
}
|
||||
|
||||
//DoErrTest(aString);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume characters until you find the terminal char
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aString receives new data from stream
|
||||
* @param addTerminal tells us whether to append terminal to aString
|
||||
* @return error code
|
||||
*/
|
||||
nsresult nsScanner::ReadWhitespace(nsString& aString) {
|
||||
|
||||
PRUnichar theChar=0;
|
||||
nsresult result=Peek(theChar);
|
||||
const PRUnichar* theBuf=mBuffer.GetUnicode();
|
||||
PRInt32 theOrigin=mOffset;
|
||||
PRBool found=PR_FALSE;
|
||||
|
||||
while(NS_OK==result) {
|
||||
|
||||
theChar=theBuf[mOffset++];
|
||||
if(theChar) {
|
||||
switch(theChar) {
|
||||
case ' ':
|
||||
case '\b':
|
||||
case '\t':
|
||||
found=PR_TRUE;
|
||||
break;
|
||||
default:
|
||||
found=PR_FALSE;
|
||||
break;
|
||||
}
|
||||
if(!found) {
|
||||
mOffset-=1;
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
mOffset-=1;
|
||||
result=Peek(theChar);
|
||||
theBuf=mBuffer.GetUnicode();
|
||||
theOrigin=mOffset;
|
||||
}
|
||||
}
|
||||
|
||||
//DoErrTest(aString);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume chars as long as they are <i>in</i> the
|
||||
* given validSet of input chars.
|
||||
|
@ -546,23 +767,36 @@ nsresult nsScanner::ReadWhile(nsString& aString,
|
|||
|
||||
NS_ASSERTION(((PR_FALSE==anOrderedSet) || aValidSet.IsOrdered()),kUnorderedStringError);
|
||||
|
||||
PRUnichar theChar=0;
|
||||
nsresult result=NS_OK;
|
||||
PRUnichar theChar=0;
|
||||
nsresult result=Peek(theChar);
|
||||
const PRUnichar* theBuf=mBuffer.GetUnicode();
|
||||
PRInt32 theOrigin=mOffset;
|
||||
|
||||
while(NS_OK==result) {
|
||||
result=GetChar(theChar);
|
||||
if(NS_OK==result) {
|
||||
|
||||
theChar=theBuf[mOffset++];
|
||||
if(theChar) {
|
||||
PRInt32 pos=(anOrderedSet) ? aValidSet.BinarySearch(theChar) : aValidSet.FindChar(theChar);
|
||||
if(kNotFound==pos) {
|
||||
if(addTerminal)
|
||||
aString+=theChar;
|
||||
else PutBack(theChar);
|
||||
if(!addTerminal)
|
||||
mOffset-=1;
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
break;
|
||||
}
|
||||
else aString+=theChar;
|
||||
}
|
||||
else {
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
mOffset-=1;
|
||||
result=Peek(theChar);
|
||||
theBuf=mBuffer.GetUnicode();
|
||||
theOrigin=mOffset;
|
||||
}
|
||||
}
|
||||
|
||||
//DoErrTest(aString);
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -582,23 +816,36 @@ nsresult nsScanner::ReadWhile(nsString& aString,
|
|||
|
||||
NS_ASSERTION(((PR_FALSE==anOrderedSet) || aValidSet.IsOrdered()),kUnorderedStringError);
|
||||
|
||||
PRUnichar theChar=0;
|
||||
nsresult result=NS_OK;
|
||||
PRUnichar theChar=0;
|
||||
nsresult result=Peek(theChar);
|
||||
const PRUnichar* theBuf=mBuffer.GetUnicode();
|
||||
PRInt32 theOrigin=mOffset;
|
||||
|
||||
while(NS_OK==result) {
|
||||
result=GetChar(theChar);
|
||||
if(NS_OK==result) {
|
||||
|
||||
theChar=theBuf[mOffset++];
|
||||
if(theChar) {
|
||||
PRInt32 pos=(anOrderedSet) ? aValidSet.BinarySearch(theChar) : aValidSet.FindChar(theChar);
|
||||
if(kNotFound==pos) {
|
||||
if(addTerminal)
|
||||
aString+=theChar;
|
||||
else PutBack(theChar);
|
||||
if(!addTerminal)
|
||||
mOffset-=1;
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
break;
|
||||
}
|
||||
else aString+=theChar;
|
||||
}
|
||||
else {
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
mOffset-=1;
|
||||
result=Peek(theChar);
|
||||
theBuf=mBuffer.GetUnicode();
|
||||
theOrigin=mOffset;
|
||||
}
|
||||
}
|
||||
|
||||
//DoErrTest(aString);
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -648,23 +895,37 @@ nsresult nsScanner::ReadUntil(nsString& aString,
|
|||
|
||||
NS_ASSERTION(((PR_FALSE==anOrderedSet) || aTerminalSet.IsOrdered()),kUnorderedStringError);
|
||||
|
||||
PRUnichar theChar=0;
|
||||
nsresult result=NS_OK;
|
||||
|
||||
while(NS_OK == result) {
|
||||
result=GetChar(theChar);
|
||||
if(NS_OK==result) {
|
||||
PRUnichar theChar=0;
|
||||
nsresult result=Peek(theChar);
|
||||
const PRUnichar* theBuf=mBuffer.GetUnicode();
|
||||
PRInt32 theOrigin=mOffset;
|
||||
|
||||
while(NS_OK==result) {
|
||||
|
||||
theChar=theBuf[mOffset++];
|
||||
if(theChar) {
|
||||
PRInt32 pos=(anOrderedSet) ? aTerminalSet.BinarySearch(theChar) : aTerminalSet.FindChar(theChar);
|
||||
if(kNotFound!=pos) {
|
||||
if(addTerminal)
|
||||
aString+=theChar;
|
||||
else PutBack(theChar);
|
||||
if(!addTerminal)
|
||||
mOffset-=1;
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
break;
|
||||
}
|
||||
else aString+=theChar;
|
||||
}
|
||||
else {
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
mOffset-=1;
|
||||
result=Peek(theChar);
|
||||
theBuf=mBuffer.GetUnicode();
|
||||
theOrigin=mOffset;
|
||||
}
|
||||
}
|
||||
|
||||
//DoErrTest(aString);
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -684,25 +945,39 @@ nsresult nsScanner::ReadUntil(nsString& aString,
|
|||
|
||||
NS_ASSERTION(((PR_FALSE==anOrderedSet) || aTerminalSet.IsOrdered()),kUnorderedStringError);
|
||||
|
||||
PRUnichar theChar=0;
|
||||
nsresult result=NS_OK;
|
||||
|
||||
while(NS_OK == result) {
|
||||
result=GetChar(theChar);
|
||||
if(NS_OK==result) {
|
||||
PRUnichar theChar=0;
|
||||
nsresult result=Peek(theChar);
|
||||
const PRUnichar* theBuf=mBuffer.GetUnicode();
|
||||
PRInt32 theOrigin=mOffset;
|
||||
|
||||
while(NS_OK==result) {
|
||||
|
||||
theChar=theBuf[mOffset++];
|
||||
if(theChar) {
|
||||
PRInt32 pos=(anOrderedSet) ? aTerminalSet.BinarySearch(theChar) : aTerminalSet.FindChar(theChar);
|
||||
if(kNotFound!=pos) {
|
||||
if(addTerminal)
|
||||
aString+=theChar;
|
||||
else PutBack(theChar);
|
||||
if(!addTerminal)
|
||||
mOffset-=1;
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
break;
|
||||
}
|
||||
else aString+=theChar;
|
||||
}
|
||||
else {
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
mOffset-=1;
|
||||
result=Peek(theChar);
|
||||
theBuf=mBuffer.GetUnicode();
|
||||
theOrigin=mOffset;
|
||||
}
|
||||
}
|
||||
|
||||
//DoErrTest(aString);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Consume characters until you encounter one contained in given
|
||||
* input set.
|
||||
|
@ -744,18 +1019,35 @@ nsresult nsScanner::ReadUntil(nsString& aString,
|
|||
PRBool addTerminal){
|
||||
PRUnichar theChar=0;
|
||||
nsresult result=NS_OK;
|
||||
PRInt32 thePos=0;
|
||||
|
||||
const PRUnichar* theBuf=mBuffer.GetUnicode();
|
||||
PRInt32 theOrigin=mOffset;
|
||||
result=Peek(theChar);
|
||||
PRUint32 theLen=mBuffer.Length();
|
||||
|
||||
while(NS_OK==result) {
|
||||
result=GetChar(theChar);
|
||||
if(theChar==aTerminalChar) {
|
||||
if(addTerminal)
|
||||
aString+=theChar;
|
||||
else PutBack(theChar);
|
||||
break;
|
||||
|
||||
theChar=theBuf[mOffset++];
|
||||
if(theChar) {
|
||||
if(aTerminalChar==theChar) {
|
||||
if(!addTerminal)
|
||||
mOffset-=1;
|
||||
aString.Append(&theBuf[theOrigin],mOffset-theOrigin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
aString.Append(&theBuf[theOrigin],theLen-theOrigin-1);
|
||||
mOffset=theLen;
|
||||
result=Peek(theChar);
|
||||
theLen=mBuffer.Length();
|
||||
}
|
||||
else aString+=theChar;
|
||||
}
|
||||
|
||||
//DoErrTest(aString);
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -163,6 +163,18 @@ class nsScanner {
|
|||
*/
|
||||
nsresult Eof(void);
|
||||
|
||||
/**
|
||||
* Consume characters until you find the terminal char
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aString receives new data from stream
|
||||
* @param addTerminal tells us whether to append terminal to aString
|
||||
* @return error code
|
||||
*/
|
||||
nsresult ReadIdentifier(nsString& aString);
|
||||
nsresult ReadNumber(nsString& aString);
|
||||
nsresult ReadWhitespace(nsString& aString);
|
||||
|
||||
/**
|
||||
* Consume characters until you find the terminal char
|
||||
*
|
||||
|
@ -299,7 +311,7 @@ class nsScanner {
|
|||
|
||||
protected:
|
||||
|
||||
enum {eBufferSizeThreshold=512};
|
||||
enum {eBufferSizeThreshold=0x1000}; //4K
|
||||
|
||||
/**
|
||||
* Internal method used to cause the internal buffer to
|
||||
|
@ -320,6 +332,7 @@ class nsScanner {
|
|||
nsCharsetSource mCharsetSource;
|
||||
nsString mCharset;
|
||||
nsIUnicodeDecoder *mUnicodeDecoder;
|
||||
nsString mUnicodeXferBuf;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче