performance and bug fixes: r=buster a=chofmann

This commit is contained in:
rickg%netscape.com 1999-09-30 04:04:53 +00:00
Родитель 6f744b281a
Коммит 8a6e39e993
22 изменённых файлов: 3348 добавлений и 2640 удалений

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

@ -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