dynamic DTD support

git-svn-id: svn://10.0.0.236/trunk@5278 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
rickg
1998-07-10 05:35:23 +00:00
parent 45923e2e1b
commit 837fc0806e
56 changed files with 6482 additions and 468 deletions

View File

@@ -904,7 +904,7 @@ void HTMLContentSink::ReflowNewContent()
shell->ContentAppended(mBody);
NS_RELEASE(shell);
}
}
}
#endif
}

View File

@@ -36,6 +36,12 @@
#include "nsIWebWidget.h"
#include "CNavDTD.h"
//#define rickgdebug 1
#ifdef rickgdebug
#include "nsHTMLContentSinkStream.h"
#endif
static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID);
static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID);
static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID);
@@ -104,6 +110,13 @@ nsHTMLDocument::StartDocumentLoad(nsIURL *aURL,
nsresult rv = NS_NewParser(&parser);
if (NS_OK == rv) {
nsIHTMLContentSink* sink;
#ifdef rickgdebug
rv = NS_New_HTML_ContentSinkStream(&sink);
#else
rv = NS_NewHTMLContentSink(&sink, this, aURL, aWebWidget);
#endif
rv = NS_NewHTMLContentSink(&sink, this, aURL, aWebWidget);
if (NS_OK == rv) {
nsIHTMLCSSStyleSheet* styleAttrSheet;
@@ -129,10 +142,9 @@ nsHTMLDocument::StartDocumentLoad(nsIURL *aURL,
nsIDTD* theDTD=0;
NS_NewNavHTMLDTD(&theDTD);
parser->RegisterDTD(theDTD);
parser->RegisterDTD(theDTD);
parser->SetContentSink(sink);
parser->BeginParse(aURL);
parser->Parse(aURL);
}
NS_RELEASE(sink);
}

View File

@@ -282,18 +282,33 @@ void CNavDTD::SetDTDDebug(nsIDTDDebug * aDTDDebug)
}
/**
* This method gets called by the parser to determine if this DTD can handle
* the requested process for the requested content type.
*
* This method is called to determine if the given DTD can parse
* a document in a given source-type.
* NOTE: Parsing always assumes that the end result will involve
* storing the result in the main content model.
* @update gess6/24/98
* @param
* @return TRUE if the DTD can handle the process for this type; FALSE otherwise.
* @param
* @return TRUE if this DTD can satisfy the request; FALSE otherwise.
*/
PRBool CNavDTD::IsCapableOf(eProcessType aProcessType, nsString& aContentType,PRInt32 aVersion){
PRBool CNavDTD::CanParse(nsString& aContentType, PRInt32 aVersion){
PRBool result=aContentType.Equals(kHTMLTextContentType);
return result;
}
/**
*
* @update gess7/7/98
* @param
* @return
*/
eAutoDetectResult CNavDTD::AutoDetectContentType(nsString& aBuffer,nsString& aType){
eAutoDetectResult result=eUnknownDetect;
if(PR_TRUE==aType.Equals(kHTMLTextContentType))
result=eValidDetect;
return result;
}
/**
*

View File

@@ -70,13 +70,24 @@ class CNavDTD : public nsIDTD {
*/
virtual ~CNavDTD();
/**
* This method is called to determine if the given DTD can parse
* a document in a given source-type.
* NOTE: Parsing always assumes that the end result will involve
* storing the result in the main content model.
* @update gess6/24/98
* @param
* @return TRUE if this DTD can satisfy the request; FALSE otherwise.
*/
virtual PRBool CanParse(nsString& aContentType, PRInt32 aVersion);
/**
*
* @update gess7/1/98
* @update gess7/7/98
* @param
* @return
*/
virtual PRBool IsCapableOf(eProcessType aProcessType, nsString& aString, PRInt32 aVersion);
virtual eAutoDetectResult AutoDetectContentType(nsString& aBuffer,nsString& aType);
/**
*

View File

@@ -149,17 +149,29 @@ COtherDTD::~COtherDTD(){
}
/**
* This method gets called by the parser to determine if this DTD can handle
* the requested process for the requested content type.
*
* This method is called to determine if the given DTD can parse
* a document in a given source-type.
* NOTE: Parsing always assumes that the end result will involve
* storing the result in the main content model.
* @update gess6/24/98
* @param
* @return TRUE if the DTD can handle the process for this type; FALSE otherwise.
* @param
* @return TRUE if this DTD can satisfy the request; FALSE otherwise.
*/
PRBool COtherDTD::IsCapableOf(eProcessType aProcessType, nsString& aContentType,PRInt32 aVersion){
return CNavDTD::IsCapableOf(aProcessType,aContentType,aVersion);
PRBool COtherDTD::CanParse(nsString& aContentType, PRInt32 aVersion){
return CNavDTD::CanParse(aContentType,aVersion);
}
/**
*
* @update gess7/7/98
* @param
* @return
*/
eAutoDetectResult COtherDTD::AutoDetectContentType(nsString& aBuffer,nsString& aType){
return CNavDTD::AutoDetectContentType(aBuffer,aType);
}
/**
*
* @update gess5/18/98

View File

@@ -62,7 +62,24 @@ class COtherDTD : public CNavDTD {
*/
virtual ~COtherDTD();
virtual PRBool IsCapableOf(eProcessType aProcessType, nsString& aString,PRInt32 aVersion);
/**
* This method is called to determine if the given DTD can parse
* a document in a given source-type.
* NOTE: Parsing always assumes that the end result will involve
* storing the result in the main content model.
* @update gess6/24/98
* @param
* @return TRUE if this DTD can satisfy the request; FALSE otherwise.
*/
virtual PRBool CanParse(nsString& aContentType, PRInt32 aVersion);
/**
*
* @update gess7/7/98
* @param
* @return
*/
virtual eAutoDetectResult AutoDetectContentType(nsString& aBuffer,nsString& aType);
/**
*

View File

@@ -0,0 +1,622 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/**
* MODULE NOTES:
* @update gess 4/8/98
*
*
*/
/**
* TRANSIENT STYLE-HANDLING NOTES:
* @update gess 6/15/98
*
* ...add comments here about transient style stack.
*
*/
#include "nsIDTDDebug.h"
#include "CRtfDTD.h"
#include "nsCRT.h"
#include "nsParser.h"
#include "nsScanner.h"
#include "nsParserTypes.h"
#include "nsTokenHandler.h"
#include "prenv.h" //this is here for debug reasons...
#include "prtypes.h" //this is here for debug reasons...
#include "prio.h"
#include "plstr.h"
#ifdef XP_PC
#include <direct.h> //this is here for debug reasons...
#endif
#include "prmem.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIDTDIID, NS_IDTD_IID);
static NS_DEFINE_IID(kClassIID, NS_RTF_DTD_IID);
static const char* kNullURL = "Error: Null URL given";
static const char* kNullFilename= "Error: Null filename given";
static const char* kNullTokenizer = "Error: Unable to construct tokenizer";
static const char* kNullToken = "Error: Null token given";
static const char* kInvalidTagStackPos = "Error: invalid tag stack position";
static const char* kRTFTextContentType = "application/rtf";
static const char* kRTFDocHeader= "{\\rtf0";
static nsString gAlphaChars("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
static nsAutoString gDigits("-0123456789");
static nsAutoString gEmpty;
struct RTFEntry {
char mName[10];
eRTFTags mTagID;
};
static RTFEntry gRTFTable[] = {
{"$",eRTFCtrl_unknown},
{"'",eRTFCtrl_quote},
{"*",eRTFCtrl_star},
{"0x0a",eRTFCtrl_linefeed},
{"0x0d",eRTFCtrl_return},
{"\\",eRTFCtrl_begincontrol},
{"b",eRTFCtrl_bold},
{"bin",eRTFCtrl_bin},
{"blue",eRTFCtrl_blue},
{"cols",eRTFCtrl_cols},
{"comment",eRTFCtrl_comment},
{"f",eRTFCtrl_font},
{"fonttbl",eRTFCtrl_fonttable},
{"green",eRTFCtrl_green},
{"i",eRTFCtrl_italic},
{"margb",eRTFCtrl_bottommargin},
{"margl",eRTFCtrl_leftmargin},
{"margr",eRTFCtrl_rightmargin},
{"margt",eRTFCtrl_topmargin},
{"par",eRTFCtrl_par},
{"pard",eRTFCtrl_pard},
{"plain",eRTFCtrl_plain},
{"qc",eRTFCtrl_justified},
{"qj",eRTFCtrl_fulljustified},
{"ql",eRTFCtrl_leftjustified},
{"qr",eRTFCtrl_rightjustified},
{"rdblquote",eRTFCtrl_rdoublequote},
{"red",eRTFCtrl_red},
{"rtf",eRTFCtrl_rtf},
{"tab",eRTFCtrl_tab},
{"title",eRTFCtrl_title},
{"u",eRTFCtrl_underline},
{"{",eRTFCtrl_startgroup},
{"}",eRTFCtrl_endgroup},
{"~",eRTFCtrl_last} //make sure this stays the last token...
};
/**
*
* @update gess4/25/98
* @param
* @return
*/
const char* GetTagName(eRTFTags aTag) {
const char* result=0;
PRInt32 cnt=sizeof(gRTFTable)/sizeof(RTFEntry);
PRInt32 low=0;
PRInt32 high=cnt-1;
PRInt32 middle=kNotFound;
while(low<=high) {
middle=(PRInt32)(low+high)/2;
if(aTag==gRTFTable[middle].mTagID)
return gRTFTable[middle].mName;
if(aTag<gRTFTable[middle].mTagID)
high=middle-1;
else low=middle+1;
}
return "";
}
/**
* This method gets called as part of our COM-like interfaces.
* Its purpose is to create an interface to parser object
* of some type.
*
* @update gess 4/8/98
* @param nsIID id of object to discover
* @param aInstancePtr ptr to newly discovered interface
* @return NS_xxx result code
*/
nsresult CRtfDTD::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if(aIID.Equals(kISupportsIID)) { //do IUnknown...
*aInstancePtr = (nsIDTD*)(this);
}
else if(aIID.Equals(kIDTDIID)) { //do IParser base class...
*aInstancePtr = (nsIDTD*)(this);
}
else if(aIID.Equals(kClassIID)) { //do this class...
*aInstancePtr = (CRtfDTD*)(this);
}
else {
*aInstancePtr=0;
return NS_NOINTERFACE;
}
((nsISupports*) *aInstancePtr)->AddRef();
return NS_OK;
}
/**
* This method is defined in nsIParser. It is used to
* cause the COM-like construction of an nsParser.
*
* @update gess 4/8/98
* @param nsIParser** ptr to newly instantiated parser
* @return NS_xxx error result
*/
NS_HTMLPARS nsresult NS_NewRTF_DTD(nsIDTD** aInstancePtrResult)
{
CRtfDTD* it = new CRtfDTD();
if (it == 0) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kClassIID, (void **) aInstancePtrResult);
}
NS_IMPL_ADDREF(CRtfDTD)
NS_IMPL_RELEASE(CRtfDTD)
/**
* Default constructor
*
* @update gess 4/9/98
* @param
* @return
*/
CRtfDTD::CRtfDTD() : nsIDTD() {
NS_INIT_REFCNT();
mParser=0;
mFilename=0;
}
/**
* Default destructor
*
* @update gess 4/9/98
* @param
* @return
*/
CRtfDTD::~CRtfDTD(){
}
/**
* This method is called to determine if the given DTD can parse
* a document in a given source-type.
* NOTE: Parsing always assumes that the end result will involve
* storing the result in the main content model.
* @update gess6/24/98
* @param
* @return TRUE if this DTD can satisfy the request; FALSE otherwise.
*/
PRBool CRtfDTD::CanParse(nsString& aContentType, PRInt32 aVersion){
PRBool result=aContentType.Equals(kRTFTextContentType);
return result;
}
/**
*
* @update gess7/7/98
* @param
* @return
*/
eAutoDetectResult CRtfDTD::AutoDetectContentType(nsString& aBuffer,nsString& aType){
eAutoDetectResult result=eUnknownDetect;
if(kNotFound!=aBuffer.Find(kRTFDocHeader))
if(PR_TRUE==aType.Equals(kRTFTextContentType))
result=eValidDetect;
return result;
}
/**
*
* @update gess5/18/98
* @param
* @return
*/
PRInt32 CRtfDTD::WillBuildModel(const char* aFilename){
PRInt32 result=0;
return result;
}
/**
*
* @update gess5/18/98
* @param
* @return
*/
PRInt32 CRtfDTD::DidBuildModel(PRInt32 anErrorCode){
PRInt32 result=0;
return result;
}
/**
*
*
* @update gess 3/25/98
* @param
* @return
*/
void CRtfDTD::SetParser(nsIParser* aParser) {
mParser=(nsParser*)aParser;
}
/**
* This method gets called in order to set the content
* sink for this parser to dump nodes to.
*
* @update gess 3/25/98
* @param nsIContentSink interface for node receiver
* @return
*/
nsIContentSink* CRtfDTD::SetContentSink(nsIContentSink* aSink) {
return 0;
}
/*******************************************************************
These methods use to be hidden in the tokenizer-delegate.
That file merged with the DTD, since the separation wasn't really
buying us anything.
*******************************************************************/
/**
* This gets called when we've just read a '\' char.
* It means we need to read an RTF control word.
*
* @update gess 3/25/98
* @param aToken ptr-ref to new token we create
* @return error code -- preferably kNoError
*/
PRInt32 CRtfDTD::ConsumeControlWord(CToken*& aToken){
PRInt32 result=kNoError;
CRTFControlWord* cw=new CRTFControlWord("");
if(cw){
CScanner* theScanner=mParser->GetScanner();
cw->Consume(*theScanner);
aToken=cw;
}
return result;
}
/**
* This gets called when we've just read a '{' or '}' group char.
* It means we have just started or ended an RTF group.
*
* @update gess 3/25/98
* @param aToken ptr-ref to new token we create
* @return error code -- preferably kNoError
*/
static char* keys[] = {"}","{"};
PRInt32 CRtfDTD::ConsumeGroupTag(CToken*& aToken,PRBool aStartGroup){
PRInt32 result=kNoError;
CRTFGroup* cw=new CRTFGroup(keys[PR_TRUE==aStartGroup],aStartGroup);
if(cw){
CScanner* theScanner=mParser->GetScanner();
cw->Consume(*theScanner);
aToken=cw;
}
return result;
}
/**
* This gets called when we've just read plain text char.
* It means we need to read RTF content.
*
* @update gess 3/25/98
* @param aToken ptr-ref to new token we create
* @return error code -- preferably kNoError
*/
PRInt32 CRtfDTD::ConsumeContent(PRUnichar aChar,CToken*& aToken){
PRInt32 result=kNoError;
PRUnichar buffer[2] = {0,0};
buffer[0]=aChar;
CRTFContent * cw=new CRTFContent(buffer);
if(cw){
CScanner* theScanner=mParser->GetScanner();
cw->Consume(*theScanner);
aToken=cw;
}
return result;
}
/**
* This method repeatedly called by the tokenizer.
* Each time, we determine the kind of token were about to
* read, and then we call the appropriate method to handle
* that token type.
*
* @update gess 3/25/98
* @param aChar: last char read
* @param aScanner: see nsScanner.h
* @param anErrorCode: arg that will hold error condition
* @return new token or null
*/
PRInt32 CRtfDTD::ConsumeToken(CToken*& aToken){
CScanner* theScanner=mParser->GetScanner();
PRUnichar aChar;
PRInt32 result=theScanner->GetChar(aChar);
switch(result) {
case kEOF:
break;
case kInterrupted:
theScanner->RewindToMark();
break;
case kNoError:
default:
switch(aChar) {
case kLeftBrace:
result=ConsumeGroupTag(aToken,PR_TRUE); break;
case kRightBrace:
result=ConsumeGroupTag(aToken,PR_FALSE); break;
case kBackSlash:
result=ConsumeControlWord(aToken); break;
case kCR:
case kSpace:
case kTab:
case kLF:
break;
default:
result=ConsumeContent(aChar,aToken); break;
} //switch
break;
} //switch
if(kNoError==result)
result=theScanner->Eof();
return result;
}
/**
*
* @update gess5/18/98
* @param
* @return
*/
void CRtfDTD::WillResumeParse(void){
return;
}
/**
*
* @update gess5/18/98
* @param
* @return
*/
void CRtfDTD::WillInterruptParse(void){
return;
}
/**
*
* @update jevering6/23/98
* @param
* @return
*/
void CRtfDTD::SetDTDDebug(nsIDTDDebug * aDTDDebug) {
}
/**
* This method is called to determine whether or not a tag
* of one type can contain a tag of another type.
*
* @update gess 3/25/98
* @param aParent -- int tag of parent container
* @param aChild -- int tag of child container
* @return PR_TRUE if parent can contain child
*/
PRBool CRtfDTD::CanContain(PRInt32 aParent,PRInt32 aChild){
PRBool result=PR_FALSE;
return result;
}
/**
*
* @update gess 3/25/98
* @param aToken -- token object to be put into content model
* @return 0 if all is well; non-zero is an error
*/
PRInt32 CRtfDTD::HandleGroup(CToken* aToken){
PRInt32 result=kNoError;
return result;
}
/**
*
* @update gess 3/25/98
* @param aToken -- token object to be put into content model
* @return 0 if all is well; non-zero is an error
*/
PRInt32 CRtfDTD::HandleControlWord(CToken* aToken){
PRInt32 result=kNoError;
return result;
}
/**
*
* @update gess 3/25/98
* @param aToken -- token object to be put into content model
* @return 0 if all is well; non-zero is an error
*/
PRInt32 CRtfDTD::HandleContent(CToken* aToken){
PRInt32 result=kNoError;
return result;
}
/**
*
* @update gess 3/25/98
* @param aToken -- token object to be put into content model
* @return 0 if all is well; non-zero is an error
*/
PRInt32 CRtfDTD::HandleToken(CToken* aToken) {
PRInt32 result=0;
if(aToken) {
eRTFTokenTypes theType=eRTFTokenTypes(aToken->GetTokenType());
switch(theType) {
case eRTFToken_group:
result=HandleGroup(aToken); break;
case eRTFToken_controlword:
result=HandleControlWord(aToken); break;
case eRTFToken_content:
result=HandleContent(aToken); break;
default:
break;
//everything else is just text or attributes of controls...
}
}//if
return result;
}
/***************************************************************
Heres's the RTFControlWord subclass...
***************************************************************/
CRTFControlWord::CRTFControlWord(char* aKey) : CToken(aKey), mArgument("") {
}
PRInt32 CRTFControlWord::GetTokenType() {
return eRTFToken_controlword;
}
PRInt32 CRTFControlWord::Consume(CScanner& aScanner){
PRInt32 result=aScanner.ReadWhile(mTextValue,gAlphaChars,PR_FALSE);
if(kNoError==result) {
//ok, now look for an option parameter...
PRUnichar ch;
result=aScanner.Peek(ch);
switch(ch) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case kMinus:
result=aScanner.ReadWhile(mArgument,gDigits,PR_FALSE);
break;
case kSpace:
default:
break;
}
}
if(kNoError==result)
result=aScanner.SkipWhitespace();
return result;
}
/***************************************************************
Heres's the RTFGroup subclass...
***************************************************************/
CRTFGroup::CRTFGroup(char* aKey,PRBool aStartGroup) : CToken(aKey) {
mStart=aStartGroup;
}
PRInt32 CRTFGroup::GetTokenType() {
return eRTFToken_group;
}
void CRTFGroup::SetGroupStart(PRBool aFlag){
mStart=aFlag;
}
PRBool CRTFGroup::IsGroupStart(){
return mStart;
}
PRInt32 CRTFGroup::Consume(CScanner& aScanner){
PRInt32 result=kNoError;
if(PR_FALSE==mStart)
result=aScanner.SkipWhitespace();
return result;
}
/***************************************************************
Heres's the RTFContent subclass...
***************************************************************/
CRTFContent::CRTFContent(PRUnichar* aKey) : CToken(aKey) {
}
PRInt32 CRTFContent::GetTokenType() {
return eRTFToken_content;
}
/**
* We're supposed to read text until we encounter one
* of the RTF control characters: \.{,}.
* @update gess7/9/98
* @param
* @return
*/
static nsString textTerminators("\\{}");
PRInt32 CRTFContent::Consume(CScanner& aScanner){
PRInt32 result=aScanner.ReadUntil(mTextValue,textTerminators,PR_FALSE);
return result;
}

View File

@@ -0,0 +1,339 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/**
* MODULE NOTES:
* @update gess 4/8/98
*
*
*/
#ifndef NS_NAVHTMLDTD__
#define NS_NAVHTMLDTD__
#include "nsIDTD.h"
#include "nsISupports.h"
#include "nsHTMLTokens.h"
#include "nshtmlpars.h"
#include "nsVoidArray.h"
#include "nsDeque.h"
#define NS_RTF_DTD_IID \
{0xa39c6bfc, 0x15f0, 0x11d2, \
{0x80, 0x41, 0x00, 0x10, 0x4b, 0x98, 0x3f, 0xd4}}
class nsIParserNode;
class nsParser;
enum eRTFTokenTypes {
eRTFToken_unknown=0,
eRTFToken_group, // '{'
eRTFToken_controlword, // '\'
eRTFToken_content, // contains all document content
//everything else is just text or attributes of controls...
eRTFToken_last //make sure this stays the last token...
};
enum eRTFTags {
eRTFCtrl_unknown=0,
eRTFCtrl_quote,
eRTFCtrl_star,
eRTFCtrl_linefeed,
eRTFCtrl_return,
eRTFCtrl_begincontrol,
eRTFCtrl_bold,
eRTFCtrl_bin,
eRTFCtrl_blue,
eRTFCtrl_cols,
eRTFCtrl_comment,
eRTFCtrl_italic,
eRTFCtrl_font,
eRTFCtrl_fonttable,
eRTFCtrl_green,
eRTFCtrl_bottommargin,
eRTFCtrl_leftmargin,
eRTFCtrl_rightmargin,
eRTFCtrl_topmargin,
eRTFCtrl_par,
eRTFCtrl_pard,
eRTFCtrl_plain,
eRTFCtrl_justified,
eRTFCtrl_fulljustified,
eRTFCtrl_leftjustified,
eRTFCtrl_rightjustified,
eRTFCtrl_rdoublequote,
eRTFCtrl_red,
eRTFCtrl_rtf,
eRTFCtrl_tab,
eRTFCtrl_title,
eRTFCtrl_underline,
eRTFCtrl_startgroup,
eRTFCtrl_endgroup,
eRTFCtrl_last //make sure this stays the last token...
};
/**
*
* @update gess7/8/98
* @param
* @return
*/
class CRTFControlWord : public CToken {
public:
CRTFControlWord(char* aKey);
virtual PRInt32 GetTokenType();
virtual PRInt32 Consume(CScanner& aScanner);
protected:
nsString mArgument;
};
/**
*
* @update gess7/8/98
* @param
* @return
*/
class CRTFGroup: public CToken {
public:
CRTFGroup(char* aKey,PRBool aStartGroup);
virtual PRInt32 GetTokenType();
virtual void SetGroupStart(PRBool aFlag);
virtual PRBool IsGroupStart();
virtual PRInt32 Consume(CScanner& aScanner);
protected:
PRBool mStart;
};
/**
*
* @update gess7/8/98
* @param
* @return
*/
class CRTFContent: public CToken {
public:
CRTFContent(PRUnichar* aValue);
virtual PRInt32 GetTokenType();
virtual PRInt32 Consume(CScanner& aScanner);
};
class CRtfDTD : public nsIDTD {
public:
NS_DECL_ISUPPORTS
/**
*
*
* @update gess 4/9/98
* @param
* @return
*/
CRtfDTD();
/**
*
*
* @update gess 4/9/98
* @param
* @return
*/
virtual ~CRtfDTD();
/**
* This method is called to determine if the given DTD can parse
* a document in a given source-type.
* NOTE: Parsing always assumes that the end result will involve
* storing the result in the main content model.
* @update gess6/24/98
* @param
* @return TRUE if this DTD can satisfy the request; FALSE otherwise.
*/
virtual PRBool CanParse(nsString& aContentType, PRInt32 aVersion);
/**
*
* @update gess7/7/98
* @param
* @return
*/
virtual eAutoDetectResult AutoDetectContentType(nsString& aBuffer,nsString& aType);
/**
*
* @update gess5/18/98
* @param
* @return
*/
virtual PRInt32 WillBuildModel(const char* aFilename=0);
/**
*
* @update gess5/18/98
* @param
* @return
*/
virtual PRInt32 DidBuildModel(PRInt32 anErrorCode);
/**
*
* @update gess 3/25/98
* @param aToken -- token object to be put into content model
* @return 0 if all is well; non-zero is an error
*/
virtual PRInt32 HandleGroup(CToken* aToken);
/**
*
* @update gess 3/25/98
* @param aToken -- token object to be put into content model
* @return 0 if all is well; non-zero is an error
*/
virtual PRInt32 HandleControlWord(CToken* aToken);
/**
*
* @update gess 3/25/98
* @param aToken -- token object to be put into content model
* @return 0 if all is well; non-zero is an error
*/
virtual PRInt32 HandleContent(CToken* aToken);
/**
*
* @update gess 3/25/98
* @param aToken -- token object to be put into content model
* @return 0 if all is well; non-zero is an error
*/
virtual PRInt32 HandleToken(CToken* aToken);
/**
*
*
* @update gess 3/25/98
* @param
* @return
*/
virtual void SetParser(nsIParser* aParser);
/**
* Cause the tokenizer to consume the next token, and
* return an error result.
*
* @update gess 3/25/98
* @param anError -- ref to error code
* @return new token or null
*/
virtual PRInt32 ConsumeControlWord(CToken*& aToken);
/**
* Cause the tokenizer to consume the next token, and
* return an error result.
*
* @update gess 3/25/98
* @param anError -- ref to error code
* @return new token or null
*/
virtual PRInt32 ConsumeGroupTag(CToken*& aToken,PRBool aStartTag);
/**
* Cause the tokenizer to consume the next token, and
* return an error result.
*
* @update gess 3/25/98
* @param anError -- ref to error code
* @return new token or null
*/
virtual PRInt32 ConsumeContent(PRUnichar aChar,CToken*& aToken);
/**
* Cause the tokenizer to consume the next token, and
* return an error result.
*
* @update gess 3/25/98
* @param anError -- ref to error code
* @return new token or null
*/
virtual PRInt32 ConsumeToken(CToken*& aToken);
/**
*
* @update gess5/18/98
* @param
* @return
*/
virtual void WillResumeParse(void);
/**
*
* @update gess5/18/98
* @param
* @return
*/
virtual void WillInterruptParse(void);
/**
* Select given content sink into parser for parser output
* @update gess5/11/98
* @param aSink is the new sink to be used by parser
* @return old sink, or NULL
*/
virtual nsIContentSink* SetContentSink(nsIContentSink* aSink);
/**
*
* @update jevering6/23/98
* @param
* @return
*/
virtual void SetDTDDebug(nsIDTDDebug * aDTDDebug);
/**
* This method is called to determine whether or not a tag
* of one type can contain a tag of another type.
*
* @update gess 3/25/98
* @param aParent -- int tag of parent container
* @param aChild -- int tag of child container
* @return PR_TRUE if parent can contain child
*/
virtual PRBool CanContain(PRInt32 aParent,PRInt32 aChild);
protected:
nsParser* mParser;
char* mFilename;
};
extern NS_HTMLPARS nsresult NS_NewRTF_DTD(nsIDTD** aInstancePtrResult);
#endif

View File

@@ -5,6 +5,7 @@
nshtmlpars.h
nsIContentSink.h
nsIHTMLContentSink.h
nsHTMLContentSinkStream.h
nsHTMLTokens.h
nsIParserNode.h
nsIParser.h
@@ -12,3 +13,4 @@ nsToken.h
nsIDTDDebug.h
nsIDTD.h
CNavDTD.h
CRTFDTD.h

View File

@@ -30,16 +30,21 @@ CPPSRCS = \
nsTokenHandler.cpp \
CNavDTD.cpp \
COtherDTD.cpp \
CRtfDTD.cpp \
nsValidDTD.cpp \
nsWellFormedDTD.cpp \
nsParser.cpp \
nsHTMLTokens.cpp \
nsHTMLTags.cpp \
prstrm.cpp \
nsHTMLContentSinkStream.cpp \
$(NULL)
EXPORTS = \
nshtmlpars.h \
nsIContentSink.h \
nsIHTMLContentSink.h \
nsHTMLContentSinkStream.h \
nsHTMLTokens.h \
nsIParserNode.h \
nsIParser.h \
@@ -48,6 +53,9 @@ EXPORTS = \
nsToken.h \
CNavDTD.h \
COtherDTD.h \
nsWellFormedDTD.h \
nsValidDTD.h \
CRTFDTD.h \
$(NULL)
EXTRA_EXPORTS = \

View File

@@ -26,6 +26,9 @@ REQUIRES=xpcom raptor netlib
CPPSRCS= \
CNavDTD.obj \
COtherDTD.obj \
CRTFDTD.obj \
nsWellFormedDTD.obj \
nsValidDTD.obj \
nsDTDDebug.obj \
nsHTMLContentSink.obj \
nsHTMLTags.obj \
@@ -35,12 +38,16 @@ CPPSRCS= \
nsScanner.obj \
nsToken.obj \
nsTokenHandler.obj \
nsHTMLContentSinkStream.obj \
prstrm.obj \
$(NULL)
CPP_OBJS= \
.\$(OBJDIR)\CNavDTD.obj \
.\$(OBJDIR)\CRTFDTD.obj \
.\$(OBJDIR)\COtherDTD.obj \
.\$(OBJDIR)\nsWellFormedDTD.obj \
.\$(OBJDIR)\nsValidDTD.obj \
.\$(OBJDIR)\nsDTDDebug.obj \
.\$(OBJDIR)\nsHTMLContentSink.obj \
.\$(OBJDIR)\nsHTMLTags.obj \
@@ -50,6 +57,7 @@ CPP_OBJS= \
.\$(OBJDIR)\nsScanner.obj \
.\$(OBJDIR)\nsToken.obj \
.\$(OBJDIR)\nsTokenHandler.obj \
.\$(OBJDIR)\nsHTMLContentSinkStream.obj \
.\$(OBJDIR)\prstrm.obj \
$(NULL)
@@ -57,6 +65,7 @@ EXPORTS= \
nshtmlpars.h \
nsIContentSink.h \
nsIHTMLContentSink.h \
nsHTMLContentSinkStream.h \
nsHTMLTokens.h \
nsIParserNode.h \
nsIParser.h \
@@ -64,6 +73,9 @@ EXPORTS= \
nsIDTDDebug.h \
nsIParserFilter.h \
CNavDTD.h \
nsWellFormedDTD.h \
nsValidDTD.h \
CRTFDTD.h \
COtherDTD.h \
nsIDTD.h \
$(NULL)

View File

@@ -0,0 +1,646 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/**
* MODULE NOTES:
* @update gess 4/1/98
*
* This file declares the concrete HTMLContentSink class.
* This class is used during the parsing process as the
* primary interface between the parser and the content
* model.
*/
#include "nsHTMLContentSinkStream.h"
#include "nsHTMLTokens.h"
#include <iostream.h>
#include "nsstring.h"
#include "nsParserTypes.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIContentSinkIID,NS_IHTMLCONTENTSINK_IID);
static NS_DEFINE_IID(kClassIID, NS_HTMLCONTENTSINK_STREAM_IID);
static char* gHeaderComment = "<!-- This page was created by the NGLayout output system. -->";
static char* gDocTypeHeader = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">";
const int gTabSize=2;
static char gBuffer[500];
/**
* This method gets called as part of our COM-like interfaces.
* Its purpose is to create an interface to parser object
* of some type.
*
* @update gess 4/8/98
* @param nsIID id of object to discover
* @param aInstancePtr ptr to newly discovered interface
* @return NS_xxx result code
*/
nsresult CHTMLContentSinkStream::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if(aIID.Equals(kISupportsIID)) { //do IUnknown...
*aInstancePtr = (nsIContentSink*)(this);
}
else if(aIID.Equals(kIContentSinkIID)) { //do IParser base class...
*aInstancePtr = (nsIContentSink*)(this);
}
else if(aIID.Equals(kClassIID)) { //do this class...
*aInstancePtr = (CHTMLContentSinkStream*)(this);
}
else {
*aInstancePtr=0;
return NS_NOINTERFACE;
}
((nsISupports*) *aInstancePtr)->AddRef();
return NS_OK;
}
NS_IMPL_ADDREF(CHTMLContentSinkStream)
NS_IMPL_RELEASE(CHTMLContentSinkStream)
/**
* This method is defined in nsIParser. It is used to
* cause the COM-like construction of an nsParser.
*
* @update gess 4/8/98
* @param nsIParser** ptr to newly instantiated parser
* @return NS_xxx error result
*/
NS_HTMLPARS nsresult NS_New_HTML_ContentSinkStream(CHTMLContentSinkStream** aInstancePtrResult) {
CHTMLContentSinkStream* it = new CHTMLContentSinkStream();
if (it == 0) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kClassIID, (void **) aInstancePtrResult);
}
/**
* Construct a content sink stream.
* @update gess7/7/98
* @param
* @return
*/
CHTMLContentSinkStream::CHTMLContentSinkStream() {
mOutput=&cout;
}
/**
* Construct a content sink stream.
* @update gess7/7/98
* @param
* @return
*/
CHTMLContentSinkStream::CHTMLContentSinkStream(ostream& aStream) {
mOutput=&aStream;
}
/**
*
* @update gess7/7/98
* @param
* @return
*/
CHTMLContentSinkStream::~CHTMLContentSinkStream() {
mOutput=0; //we don't own the stream we're given; just forget it.
}
/**
*
* @update gess7/7/98
* @param
* @return
*/
void CHTMLContentSinkStream::SetOutputStream(ostream& aStream) {
mOutput=&aStream;
}
/**
*
* @update gess7/7/98
* @param
* @return
*/
void WriteAttributes(const nsIParserNode& aNode,ostream& aStream) {
int theCount=aNode.GetAttributeCount();
if(theCount) {
int i=0;
for(i=0;i<theCount;i++){
const nsString& key=aNode.GetKeyAt(i);
key.ToCString(gBuffer,sizeof(gBuffer)-1);
aStream << " " << gBuffer << char(kEqual);
const nsString& value=aNode.GetValueAt(i);
value.ToCString(gBuffer,sizeof(gBuffer)-1);
aStream << gBuffer;
}
}
}
/**
*
* @update gess7/5/98
* @param
* @return
*/
void OpenTagWithAttributes(const char* theTag,const nsIParserNode& aNode,int tab,ostream& aStream,bool aNewline) {
int i=0;
for(i=0;i<tab*gTabSize;i++)
aStream << " ";
aStream << (char)kLessThan << theTag;
WriteAttributes(aNode,aStream);
aStream << (char)kGreaterThan;
if(aNewline)
aStream << endl;
}
/**
*
* @update gess7/5/98
* @param
* @return
*/
void OpenTag(const char* theTag,int tab,ostream& aStream,bool aNewline) {
int i=0;
for(i=0;i<tab*gTabSize;i++)
aStream << " ";
aStream << (char)kLessThan << theTag << (char)kGreaterThan;
if(aNewline)
aStream << endl;
}
/**
*
* @update gess7/5/98
* @param
* @return
*/
void CloseTag(const char* theTag,int tab,ostream& aStream) {
int i=0;
for(i=0;i<tab*gTabSize;i++)
aStream << " ";
aStream << (char)kLessThan << (char)kForwardSlash << theTag << (char)kGreaterThan << endl;
}
/**
*
* @update gess7/5/98
* @param
* @return
*/
void WritePair(eHTMLTags aTag,const nsString& theContent,int tab,ostream& aStream) {
const char* titleStr = GetTagName(aTag);
OpenTag(titleStr,tab,aStream,false);
theContent.ToCString(gBuffer,sizeof(gBuffer)-1);
aStream << gBuffer;
CloseTag(titleStr,0,aStream);
}
/**
*
* @update gess7/5/98
* @param
* @return
*/
void WriteSingleton(eHTMLTags aTag,const nsString& theContent,int tab,ostream& aStream) {
const char* titleStr = GetTagName(aTag);
OpenTag(titleStr,tab,aStream,false);
if(theContent.Length()) {
theContent.ToCString(gBuffer,sizeof(gBuffer)-1);
aStream << gBuffer;
}
aStream << endl;
}
/**
* This method gets called by the parser when it encounters
* a title tag and wants to set the document title in the sink.
*
* @update 4/1/98 gess
* @param nsString reference to new title value
* @return PR_TRUE if successful.
*/
PRBool CHTMLContentSinkStream::SetTitle(const nsString& aValue){
PRBool result=PR_FALSE;
if(mOutput) {
WritePair(eHTMLTag_title,aValue,1+mTabLevel,*mOutput);
}
return result;
}
/**
* This method is used to open the outer HTML container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
PRInt32 CHTMLContentSinkStream::OpenHTML(const nsIParserNode& aNode){
PRInt32 result=0;
mTabLevel++;
if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_html);
OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,true);
}
return result;
}
/**
* This method is used to close the outer HTML container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
PRInt32 CHTMLContentSinkStream::CloseHTML(const nsIParserNode& aNode){
PRInt32 result=0;
if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_html);
CloseTag(theTag,0,*mOutput);
}
mTabLevel--;
return result;
}
/**
* This method is used to open the only HEAD container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
PRInt32 CHTMLContentSinkStream::OpenHead(const nsIParserNode& aNode){
PRInt32 result=0;
mTabLevel++;
if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_head);
OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,true);
}
return result;
}
/**
* This method is used to close the only HEAD container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
PRInt32 CHTMLContentSinkStream::CloseHead(const nsIParserNode& aNode){
PRInt32 result=0;
if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_head);
CloseTag(theTag,mTabLevel,*mOutput);
}
mTabLevel--;
return result;
}
/**
* This method is used to open the main BODY container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
PRInt32 CHTMLContentSinkStream::OpenBody(const nsIParserNode& aNode){
PRInt32 result=0;
mTabLevel++;
if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_body);
OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,true);
}
return result;
}
/**
* This method is used to close the main BODY container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
PRInt32 CHTMLContentSinkStream::CloseBody(const nsIParserNode& aNode){
PRInt32 result=0;
if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_body);
CloseTag(theTag,mTabLevel,*mOutput);
}
mTabLevel--;
return result;
}
/**
* This method is used to open a new FORM container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
PRInt32 CHTMLContentSinkStream::OpenForm(const nsIParserNode& aNode){
PRInt32 result=0;
mTabLevel++;
if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_form);
OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,true);
}
return result;
}
/**
* This method is used to close the outer FORM container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
PRInt32 CHTMLContentSinkStream::CloseForm(const nsIParserNode& aNode){
PRInt32 result=0;
if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_form);
CloseTag(theTag,mTabLevel,*mOutput);
}
mTabLevel--;
return result;
}
/**
* This method is used to open the FRAMESET container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
PRInt32 CHTMLContentSinkStream::OpenFrameset(const nsIParserNode& aNode){
PRInt32 result=0;
mTabLevel++;
if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_frameset);
OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,true);
}
return result;
}
/**
* This method is used to close the FRAMESET container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
PRInt32 CHTMLContentSinkStream::CloseFrameset(const nsIParserNode& aNode){
PRInt32 result=0;
if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_frameset);
CloseTag(theTag,mTabLevel,*mOutput);
}
mTabLevel--;
return result;
}
/**
* This method is used to a general container.
* This includes: OL,UL,DIR,SPAN,TABLE,H[1..6],etc.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
PRInt32 CHTMLContentSinkStream::OpenContainer(const nsIParserNode& aNode){
PRInt32 result=0;
mTabLevel++;
if(mOutput) {
eHTMLTags nodeType=(eHTMLTags)aNode.GetNodeType();
switch(nodeType) {
case eHTMLTag_html:
result=OpenHTML(aNode); break;
case eHTMLTag_body:
result=OpenBody(aNode); break;
case eHTMLTag_title:
{
const nsString& title=aNode.GetName();
result=SetTitle(title);
}
break;
case eHTMLTag_head:
result=OpenHead(aNode); break;
case eHTMLTag_style:
break;
case eHTMLTag_form:
result=OpenForm(aNode); break;
default:
//this is the hard one. You have to decode aNode manually.
{
const nsString& name=aNode.GetName();
const char* tagName= GetTagName(nodeType);
OpenTagWithAttributes(tagName,aNode,mTabLevel,*mOutput,true);
}
break;
}
}
return result;
}
/**
* This method is used to close a generic container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
PRInt32 CHTMLContentSinkStream::CloseContainer(const nsIParserNode& aNode){
PRInt32 result=0;
if(mOutput) {
eHTMLTags nodeType=(eHTMLTags)aNode.GetNodeType();
switch(nodeType) {
case eHTMLTag_html:
result=CloseHTML(aNode); break;
case eHTMLTag_style:
break;
case eHTMLTag_head:
result=CloseHead(aNode); break;
case eHTMLTag_body:
result=CloseBody(aNode); break;
case eHTMLTag_form:
result=CloseForm(aNode); break;
case eHTMLTag_title:
// result=SetTitle(aNode); break;
default:
{
const nsString& name=aNode.GetName();
const char* tagName= GetTagName(nodeType);
//(*mOutput) << endl;
CloseTag(tagName,mTabLevel,*mOutput);
}
break;
}
}
mTabLevel--;
return result;
}
/**
* This method is used to add a leaf to the currently
* open container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
PRInt32 CHTMLContentSinkStream::AddLeaf(const nsIParserNode& aNode){
PRInt32 result=0;
if(mOutput) {
eHTMLTags nodeType=(eHTMLTags)aNode.GetNodeType();
switch(nodeType) {
case eHTMLTag_hr:
case eHTMLTag_br:
{
nsAutoString empty;
WriteSingleton(nodeType,empty,1+mTabLevel,*mOutput);
}
break;
case eHTMLTag_style:
{
const nsString& skipped=aNode.GetSkippedContent();
WritePair(nodeType,skipped,1+mTabLevel,*mOutput);
}
break;
case eHTMLTag_newline:
case eHTMLTag_whitespace:
break;
default:
{
int i=0;
for(i=0;i<(1+mTabLevel)*gTabSize;i++)
(*mOutput) << " ";
const nsString& text=aNode.GetText();
text.ToCString(gBuffer,sizeof(gBuffer)-1);
(*mOutput) << gBuffer << endl;
}
}//switch
}
return result;
}
/**
* This method gets called when the parser begins the process
* of building the content model via the content sink.
*
* @update 5/7/98 gess
*/
void CHTMLContentSinkStream::WillBuildModel(void){
mTabLevel=-1;
if(mOutput) {
(*mOutput) << gHeaderComment << endl;
(*mOutput) << gDocTypeHeader << endl;
}
}
/**
* This method gets called when the parser concludes the process
* of building the content model via the content sink.
*
* @param aQualityLevel describes how well formed the doc was.
* 0=GOOD; 1=FAIR; 2=POOR;
* @update 5/7/98 gess
*/
void CHTMLContentSinkStream::DidBuildModel(PRInt32 aQualityLevel) {
}
/**
* This method gets called when the parser gets i/o blocked,
* and wants to notify the sink that it may be a while before
* more data is available.
*
* @update 5/7/98 gess
*/
void CHTMLContentSinkStream::WillInterrupt(void) {
}
/**
* This method gets called when the parser i/o gets unblocked,
* and we're about to start dumping content again to the sink.
*
* @update 5/7/98 gess
*/
void CHTMLContentSinkStream::WillResume(void) {
}

View File

@@ -0,0 +1,259 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/**
* MODULE NOTES:
* @update gess 4/1/98
*
* This file declares the concrete HTMLContentSink class.
* This class is used during the parsing process as the
* primary interface between the parser and the content
* model.
*/
#ifndef NS_HTMLCONTENTSINK_STREAM
#define NS_ITMLCONTENTSINK_STREAM
#include "nsIParserNode.h"
#include "nsIHTMLContentSink.h"
#include "nshtmlpars.h"
#define NS_HTMLCONTENTSINK_STREAM_IID \
{0xa39c6bff, 0x15f0, 0x11d2, \
{0x80, 0x41, 0x0, 0x10, 0x4b, 0x98, 0x3f, 0xd4}}
class ostream;
class CHTMLContentSinkStream : public nsIHTMLContentSink {
public:
NS_DECL_ISUPPORTS
/**
*
* @update gess7/7/98
* @param
* @return
*/
CHTMLContentSinkStream();
/**
*
* @update gess7/7/98
* @param
* @return
*/
CHTMLContentSinkStream(ostream& aStream);
/**
*
* @update gess7/7/98
* @param
* @return
*/
virtual ~CHTMLContentSinkStream();
/**
*
* @update gess7/7/98
* @param
* @return
*/
void SetOutputStream(ostream& aStream);
/**
* This method gets called by the parser when it encounters
* a title tag and wants to set the document title in the sink.
*
* @update 4/1/98 gess
* @param nsString reference to new title value
* @return PR_TRUE if successful.
*/
virtual PRBool SetTitle(const nsString& aValue);
/**
* This method is used to open the outer HTML container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
virtual PRInt32 OpenHTML(const nsIParserNode& aNode);
/**
* This method is used to close the outer HTML container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
virtual PRInt32 CloseHTML(const nsIParserNode& aNode);
/**
* This method is used to open the only HEAD container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
virtual PRInt32 OpenHead(const nsIParserNode& aNode);
/**
* This method is used to close the only HEAD container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
virtual PRInt32 CloseHead(const nsIParserNode& aNode);
/**
* This method is used to open the main BODY container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
virtual PRInt32 OpenBody(const nsIParserNode& aNode);
/**
* This method is used to close the main BODY container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
virtual PRInt32 CloseBody(const nsIParserNode& aNode);
/**
* This method is used to open a new FORM container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
virtual PRInt32 OpenForm(const nsIParserNode& aNode);
/**
* This method is used to close the outer FORM container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
virtual PRInt32 CloseForm(const nsIParserNode& aNode);
/**
* This method is used to open the FRAMESET container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
virtual PRInt32 OpenFrameset(const nsIParserNode& aNode);
/**
* This method is used to close the FRAMESET container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
virtual PRInt32 CloseFrameset(const nsIParserNode& aNode);
/**
* This method is used to a general container.
* This includes: OL,UL,DIR,SPAN,TABLE,H[1..6],etc.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
virtual PRInt32 OpenContainer(const nsIParserNode& aNode);
/**
* This method is used to close a generic container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
virtual PRInt32 CloseContainer(const nsIParserNode& aNode);
/**
* This method is used to add a leaf to the currently
* open container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
virtual PRInt32 AddLeaf(const nsIParserNode& aNode);
/**
* This method gets called when the parser begins the process
* of building the content model via the content sink.
*
* @update 5/7/98 gess
*/
virtual void WillBuildModel(void);
/**
* This method gets called when the parser concludes the process
* of building the content model via the content sink.
*
* @param aQualityLevel describes how well formed the doc was.
* 0=GOOD; 1=FAIR; 2=POOR;
* @update 5/7/98 gess
*/
virtual void DidBuildModel(PRInt32 aQualityLevel);
/**
* This method gets called when the parser gets i/o blocked,
* and wants to notify the sink that it may be a while before
* more data is available.
*
* @update 5/7/98 gess
*/
virtual void WillInterrupt(void);
/**
* This method gets called when the parser i/o gets unblocked,
* and we're about to start dumping content again to the sink.
*
* @update 5/7/98 gess
*/
virtual void WillResume(void);
protected:
ostream* mOutput;
int mTabLevel;
};
extern NS_HTMLPARS nsresult NS_New_HTML_ContentSinkStream(CHTMLContentSinkStream** aInstancePtrResult);
#endif

View File

@@ -247,7 +247,7 @@ PRInt32 CStartToken::Consume(PRUnichar aChar, CScanner& aScanner) {
//and see if the next char is ">". If so, we have a complete
//tag without attributes.
if(kNoError==result) {
result=aScanner.SkipWhite();
result=aScanner.SkipWhitespace();
if(kNoError==result) {
result=aScanner.GetChar(aChar);
if(kNoError==result) {
@@ -678,7 +678,7 @@ PRInt32 ConsumeAttributeValueText(PRUnichar aChar,nsString& aString,CScanner& aS
*/
PRInt32 CAttributeToken::Consume(PRUnichar aChar, CScanner& aScanner) {
aScanner.SkipWhite(); //skip leading whitespace
aScanner.SkipWhitespace(); //skip leading whitespace
PRInt32 result=aScanner.Peek(aChar);
if(kNoError==result) {
if(kQuote==aChar) { //if you're here, handle quoted key...
@@ -703,12 +703,12 @@ PRInt32 CAttributeToken::Consume(PRUnichar aChar, CScanner& aScanner) {
}
//now it's time to Consume the (optional) value...
if(!(result=aScanner.SkipWhite())) {
if(!(result=aScanner.SkipWhitespace())) {
if(!(result=aScanner.Peek(aChar))) {
if(kEqual==aChar){
result=aScanner.GetChar(aChar); //skip the equal sign...
if(kNoError==result) {
result=aScanner.SkipWhite(); //now skip any intervening whitespace
result=aScanner.SkipWhitespace(); //now skip any intervening whitespace
if(kNoError==result) {
result=aScanner.GetChar(aChar); //and grab the next char.
if(kNoError==result) {
@@ -722,7 +722,7 @@ PRInt32 CAttributeToken::Consume(PRUnichar aChar, CScanner& aScanner) {
}
}//if
if(kNoError==result)
result=aScanner.SkipWhite();
result=aScanner.SkipWhitespace();
}//if
}//if
}//if

View File

@@ -60,15 +60,6 @@ class nsIContentSink : public nsISupports {
*/
virtual PRInt32 CloseContainer(const nsIParserNode& aNode) = 0;
/**
* This method gets called by the parser when a the
* topmost container in the content sink needs to be closed.
*
* @update 4/1/98 gess
* @return PR_TRUE if successful.
*/
virtual PRInt32 CloseTopmostContainer() = 0;
/**
* This gets called by the parser when you want to add
* a leaf node to the current container in the content

View File

@@ -41,7 +41,6 @@ class nsIDTDDebug;
class nsIURL;
class nsString;
enum eProcessType {eParsing, eConverting};
enum eAutoDetectResult {eUnknownDetect, eValidDetect, eInvalidDetect};
class nsIDTD : public nsISupports {
@@ -76,12 +75,23 @@ class nsIDTD : public nsISupports {
virtual nsIContentSink* SetContentSink(nsIContentSink* aSink)=0;
/**
*
* This method is called to determine if the given DTD can parse
* a document in a given source-type.
* NOTE: Parsing always assumes that the end result will involve
* storing the result in the main content model.
* @update gess6/24/98
* @param
* @return TRUE if this DTD can satisfy the request; FALSE otherwise.
*/
virtual PRBool CanParse(nsString& aContentType, PRInt32 aVersion)=0;
/**
*
* @update gess7/7/98
* @param
* @return
*/
virtual PRBool IsCapableOf(eProcessType aProcessType, nsString& aContentType, PRInt32 aVersion)=0;
virtual eAutoDetectResult AutoDetectContentType(nsString& aBuffer,nsString& aType)=0;
/**
*
@@ -136,13 +146,16 @@ class nsIDTD : public nsISupports {
virtual void WillInterruptParse(void)=0;
/**
*
* @update jevering 6/18/98
* @param aParent parent tag
* @param aChild child tag
* @return PR_TRUE if valid container
* This method is called to determine whether or not a tag
* of one type can contain a tag of another type.
*
* @update gess 3/25/98
* @param aParent -- int tag of parent container
* @param aChild -- int tag of child container
* @return PR_TRUE if parent can contain child
*/
virtual PRBool CanContain(PRInt32 aParent, PRInt32 aChild) = 0;
virtual PRBool CanContain(PRInt32 aParent,PRInt32 aChild)=0;
/**
*

View File

@@ -62,7 +62,7 @@
*/
#ifndef NS_IHTMLCONTENTSINK
#define NS_ITMLCONTENTSINK
#define NS_IHTMLCONTENTSINK
#include "nsIParserNode.h"
#include "nsIContentSink.h"
@@ -194,16 +194,6 @@ class nsIHTMLContentSink : public nsIContentSink {
*/
virtual PRInt32 CloseContainer(const nsIParserNode& aNode)=0;
/**
* This method is used to close the topmost container, regardless
* of the type.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
virtual PRInt32 CloseTopmostContainer()=0;
/**
* This method is used to add a leaf to the currently
* open container.

View File

@@ -35,6 +35,7 @@ class nsString;
class CToken;
class nsIURL;
class nsIDTDDebug;
class fstream;
/**
* This class defines the iparser interface. This XPCOM
@@ -49,7 +50,7 @@ class nsIParser : public nsISupports {
virtual nsIContentSink* SetContentSink(nsIContentSink* aContentSink)=0;
virtual eAutoDetectResult AutoDetectContentType(nsString& aBuffer)=0;
virtual eAutoDetectResult AutoDetectContentType(nsString& aBuffer,nsString& aType)=0;
/**
* Cause the tokenizer to consume the next token, and
@@ -61,26 +62,15 @@ class nsIParser : public nsISupports {
*/
virtual PRInt32 ConsumeToken(CToken*& aToken)=0;
virtual PRInt32 BeginParse(nsIURL* aURL,
nsIStreamObserver* aListener = nsnull,
nsIDTDDebug * aDTDDebug = 0) = 0;
/******************************************************************************************
* Parse methods always begin with an input source, and perform conversions
* until you wind up with HTML in your actual content model.
******************************************************************************************/
virtual PRInt32 Parse(nsIURL* aURL,nsIStreamObserver* aListener = nsnull,nsIDTDDebug * aDTDDebug = 0) = 0;
virtual PRInt32 Parse(const char* aFilename)=0;
virtual PRInt32 Parse(fstream& aStream)=0;
virtual PRInt32 Parse(nsString& anHTMLString,PRBool appendTokens)=0;
/******************************************************************************************
* Convert methods start input source (of known or unknown form), and perform conversions
* until you wind up with a <i>stream</i> in your target form.
* The internal content model is never effected.
******************************************************************************************/
virtual PRInt32 Convert(nsIURL* aURL,char* aSourceForm,char* aTargetForm,nsIStreamListener* aListener) = 0;
virtual PRInt32 Convert(const char* aFilename,char* aSourceForm,char* aTargetForm)=0;
virtual PRInt32 Convert(nsString& anHTMLString,char* aSourceForm,char* aTargetForm,PRBool appendTokens)=0;
virtual PRInt32 ResumeParse(void)=0;

View File

@@ -31,6 +31,13 @@
#include "nsIDTDDebug.h"
#include "nshtmlpars.h"
#define rickgdebug 1
#ifdef rickgdebug
#include "CRtfDTD.h"
#include "nsWellFormedDTD.h"
#endif
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kClassIID, NS_PARSER_IID);
static NS_DEFINE_IID(kIParserIID, NS_IPARSER_IID);
@@ -136,7 +143,8 @@ CSharedParserObjects gSharedParserObjects;
*/
nsParser::nsParser() :
mTokenDeque(gTokenDeallocator),
mContentType()
mSourceType(),
mTargetType()
{
NS_INIT_REFCNT();
mDTDDebug = 0;
@@ -270,6 +278,15 @@ nsIContentSink* nsParser::SetContentSink(nsIContentSink* aSink) {
* @return nothing.
*/
void nsParser::RegisterDTD(nsIDTD* aDTD){
#ifdef rickgdebug
nsIDTD* rv=0;
NS_NewRTF_DTD(&rv);
gSharedParserObjects.RegisterDTD(rv);
NS_NewWellFormed_DTD(&rv);
gSharedParserObjects.RegisterDTD(rv);
#endif
gSharedParserObjects.RegisterDTD(aDTD);
}
@@ -309,28 +326,31 @@ eParseMode DetermineParseMode() {
* @param
* @return
*/
PRBool FindSuitableDTD(eProcessType aProcessType,eParseMode aMode,nsString& aContentType, nsIDTD*& aDefaultDTD) {
PRBool result=PR_FALSE;
PRBool FindSuitableDTD( eParseMode aMode,
nsString& aSourceType,
nsString& aTargetType,
nsIDTD*& aDefaultDTD) {
if(aDefaultDTD) {
if(aDefaultDTD->IsCapableOf(aProcessType,aContentType,0)) {
result=PR_TRUE;
}
}
else {
nsDequeIterator b=gSharedParserObjects.mDTDDeque.Begin();
nsDequeIterator e=gSharedParserObjects.mDTDDeque.End();
//Let's start by tring the defaultDTD, if one exists...
if(aDefaultDTD && (aDefaultDTD->CanParse(aSourceType,0)))
return PR_TRUE;
while(b<e){
nsIDTD* theDTD=(nsIDTD*)b.GetCurrent();
if(theDTD && theDTD->IsCapableOf(aProcessType,aContentType,0)) {
PRBool result=PR_FALSE;
nsDequeIterator b=gSharedParserObjects.mDTDDeque.Begin();
nsDequeIterator e=gSharedParserObjects.mDTDDeque.End();
while(b<e){
nsIDTD* theDTD=(nsIDTD*)b.GetCurrent();
if(theDTD) {
result=theDTD->CanParse(aSourceType,0);
if(result){
aDefaultDTD=theDTD;
result=PR_TRUE;
break;
}
++b;
}
}
b++;
}
return result;
}
@@ -341,22 +361,30 @@ PRBool FindSuitableDTD(eProcessType aProcessType,eParseMode aMode,nsString& aCon
*
* @update gess6/22/98
* @param aBuffer -- nsString containing sample data to be analyzed.
* @param aType -- may hold typename given from netlib; will hold result given by DTD's.
* @return auto-detect result: eValid, eInvalid, eUnknown
*/
eAutoDetectResult nsParser::AutoDetectContentType(nsString& aBuffer) {
eAutoDetectResult nsParser::AutoDetectContentType(nsString& aBuffer,nsString& aType) {
//The process:
// You should go out and ask each DTD if they
// recognize the content in the scanner.
// Somebody should say yes, or we can't continue.
//This method may change mContentType and mDTD.
//This method may change mSourceType and mDTD.
//It absolutely changes mAutoDetectStatus
nsDequeIterator b=gSharedParserObjects.mDTDDeque.Begin();
nsDequeIterator e=gSharedParserObjects.mDTDDeque.End();
mAutoDetectStatus=eUnknownDetect;
if(PR_TRUE==mContentType.Equals(kHTMLTextContentType)) {
mAutoDetectStatus=eValidDetect;
}
while((b<e) && (eUnknownDetect==mAutoDetectStatus)){
nsIDTD* theDTD=(nsIDTD*)b.GetCurrent();
if(theDTD) {
mAutoDetectStatus=theDTD->AutoDetectContentType(aBuffer,aType);
}
b++;
}
return mAutoDetectStatus;
}
@@ -373,13 +401,13 @@ eAutoDetectResult nsParser::AutoDetectContentType(nsString& aBuffer) {
* @param
* @return
*/
PRInt32 nsParser::WillBuildModel(eProcessType aProcessType, const char* aFilename){
PRInt32 nsParser::WillBuildModel(const char* aFilename){
mMajorIteration=-1;
mMinorIteration=-1;
mParseMode=DetermineParseMode();
if(PR_TRUE==FindSuitableDTD(aProcessType,mParseMode,mContentType,mDTD)) {
if(PR_TRUE==FindSuitableDTD(mParseMode,mSourceType,mTargetType,mDTD)) {
mDTD->SetParser(this);
mDTD->SetContentSink(mSink);
mDTD->WillBuildModel(aFilename);
@@ -439,11 +467,12 @@ PRBool nsParser::Parse(const char* aFilename){
if(aFilename) {
//ok, time to create our tokenizer and begin the process
mTargetType=kHTMLTextContentType;
mScanner=new CScanner(aFilename,mParseMode);
if(mScanner) {
mScanner->Eof();
if(eValidDetect==AutoDetectContentType(mScanner->GetBuffer())) {
WillBuildModel(eParsing,aFilename);
if(eValidDetect==AutoDetectContentType(mScanner->GetBuffer(),mSourceType)) {
WillBuildModel(aFilename);
status=ResumeParse();
DidBuildModel(status);
}
@@ -452,6 +481,18 @@ PRBool nsParser::Parse(const char* aFilename){
return status;
}
/**
* Cause parser to parse input from given stream
* @update gess5/11/98
* @param aStream is the i/o source
* @return TRUE if all went well -- FALSE otherwise
*/
PRInt32 nsParser::Parse(fstream& aStream){
PRInt32 result=0;
return result;
}
/**
* This is the main controlling routine in the parsing process.
* Note that it may get called multiple times for the same scanner,
@@ -467,54 +508,6 @@ PRBool nsParser::Parse(const char* aFilename){
* @return PR_TRUE if parse succeeded, PR_FALSE otherwise.
*/
PRInt32 nsParser::Parse(nsIURL* aURL,nsIStreamObserver* aListener, nsIDTDDebug * aDTDDebug) {
PRInt32 status;
status = BeginParse(aURL, aListener, aDTDDebug);
if (NS_OK == status) {
status=mURL->Open(this);
}
return status;
}
/**
* Call this method if all you want to do is parse 1 string full of HTML text.
*
* @update gess5/11/98
* @param anHTMLString contains a string-full of real HTML
* @param appendTokens tells us whether we should insert tokens inline, or append them.
* @return TRUE if all went well -- FALSE otherwise
*/
PRInt32 nsParser::Parse(nsString& aSourceBuffer,PRBool appendTokens){
PRInt32 result=kNoError;
mScanner=new CScanner();
mScanner->Append(aSourceBuffer);
if(eValidDetect==AutoDetectContentType(aSourceBuffer)) {
WillBuildModel(eParsing,"from-string");
result=ResumeParse();
DidBuildModel(result);
}
return result;
}
/**
* This is the main controlling routine in the parsing process.
* Note that it may get called multiple times for the same scanner,
* since this is a pushed based system, and all the tokens may
* not have been consumed by the scanner during a given invocation
* of this method.
*
* NOTE: We don't call willbuildmodel here, because it will happen
* as a result of calling OnStartBinding later on.
*
* @update gess 3/25/98
* @param aFilename -- const char* containing file to be parsed.
* @return PR_TRUE if parse succeeded, PR_FALSE otherwise.
*/
PRInt32 nsParser::BeginParse(nsIURL* aURL,nsIStreamObserver* aListener, nsIDTDDebug * aDTDDebug) {
NS_PRECONDITION(0!=aURL,kNullURL);
PRInt32 status=kBadURL;
@@ -537,36 +530,27 @@ PRInt32 nsParser::BeginParse(nsIURL* aURL,nsIStreamObserver* aListener, nsIDTDDe
return status;
}
/**
*
* @update gess6/23/98
* @param
* @return
*/
PRInt32 nsParser::Convert(nsIURL* aURL,char* aSourceForm,char* aTargetForm,nsIStreamListener* aListener) {
PRInt32 result=0;
return result;
}
/**
*
* @update gess6/23/98
* @param
* @return
* Call this method if all you want to do is parse 1 string full of HTML text.
*
* @update gess5/11/98
* @param anHTMLString contains a string-full of real HTML
* @param appendTokens tells us whether we should insert tokens inline, or append them.
* @return TRUE if all went well -- FALSE otherwise
*/
PRInt32 nsParser::Convert(const char* aFilename,char* aSourceForm,char* aTargetForm) {
PRInt32 result=0;
return result;
}
PRInt32 nsParser::Parse(nsString& aSourceBuffer,PRBool appendTokens){
PRInt32 result=kNoError;
/**
*
* @update gess6/23/98
* @param
* @return
*/
PRInt32 nsParser::Convert(nsString& anHTMLString,char* aSourceForm,char* aTargetForm,PRBool appendTokens){
PRInt32 result=0;
mTargetType=kHTMLTextContentType;
mScanner=new CScanner();
mScanner->Append(aSourceBuffer);
if(eValidDetect==AutoDetectContentType(aSourceBuffer,mSourceType)) {
WillBuildModel("");
result=ResumeParse();
DidBuildModel(result);
}
return result;
}
@@ -722,14 +706,14 @@ nsParser::OnProgress(PRInt32 aProgress, PRInt32 aProgressMax,
* @param
* @return
*/
nsresult nsParser::OnStartBinding(const char *aContentType){
nsresult nsParser::OnStartBinding(const char *aSourceType){
if (nsnull != mObserver) {
mObserver->OnStartBinding(aContentType);
mObserver->OnStartBinding(aSourceType);
}
mAutoDetectStatus=eUnknownDetect;
mDTD=0;
mContentType=aContentType;
mSourceType=aSourceType;
return kNoError;
}
@@ -773,8 +757,8 @@ nsresult nsParser::OnDataAvailable(nsIInputStream *pIStream, PRInt32 length){
mScanner->Append(mTransferBuffer,len);
if(eUnknownDetect==mAutoDetectStatus) {
if(eValidDetect==AutoDetectContentType(mScanner->GetBuffer())) {
nsresult result=WillBuildModel(eParsing,mURL->GetSpec());
if(eValidDetect==AutoDetectContentType(mScanner->GetBuffer(),mSourceType)) {
nsresult result=WillBuildModel(mURL->GetSpec());
} //if
}
} //if

View File

@@ -74,7 +74,7 @@ class nsIDTD;
class nsIDTDDebug;
class CScanner;
class nsIParserFilter;
class fstream;
class nsParser : public nsIParser, public nsIStreamListener {
@@ -118,10 +118,6 @@ friend class CTokenHandler;
*/
virtual CScanner* GetScanner(void);
virtual PRInt32 BeginParse(nsIURL* aURL,
nsIStreamObserver* aListener,
nsIDTDDebug * aDTDDebug = 0);
/**
* Cause parser to parse input from given URL in given mode
* @update gess5/11/98
@@ -136,11 +132,18 @@ friend class CTokenHandler;
* Cause parser to parse input from given file in given mode
* @update gess5/11/98
* @param aFilename is a path for file document
* @param aMode is the desired parser mode (Nav, other, etc.)
* @return TRUE if all went well -- FALSE otherwise
*/
virtual PRInt32 Parse(const char* aFilename);
/**
* Cause parser to parse input from given stream
* @update gess5/11/98
* @param aStream is the i/o source
* @return TRUE if all went well -- FALSE otherwise
*/
virtual PRInt32 Parse(fstream& aStream);
/**
* @update gess5/11/98
* @param anHTMLString contains a string-full of real HTML
@@ -149,15 +152,6 @@ friend class CTokenHandler;
*/
virtual PRInt32 Parse(nsString& anHTMLString,PRBool appendTokens);
/******************************************************************************************
* Convert methods start input source (of known or unknown form), and perform conversions
* until you wind up with a <i>stream</i> in your target form.
* The internal content model is never effected.
******************************************************************************************/
virtual PRInt32 Convert(nsIURL* aURL,char* aSourceForm, char* aTargetForm,nsIStreamListener* aListener);
virtual PRInt32 Convert(const char* aFilename,char* aSourceForm,char* aTargetForm);
virtual PRInt32 Convert(nsString& anHTMLString,char* aSourceForm,char* aTargetForm,PRBool appendTokens);
/**
* This method gets called (automatically) during incremental parsing
* @update gess5/11/98
@@ -214,7 +208,7 @@ protected:
* @param
* @return
*/
PRInt32 WillBuildModel(eProcessType theProcessType=eParsing,const char* aFilename=0);
PRInt32 WillBuildModel(const char* aFilename=0);
/**
*
@@ -309,7 +303,7 @@ private:
* @param
* @return TRUE if we figured it out.
*/
eAutoDetectResult AutoDetectContentType(nsString& aBuffer);
eAutoDetectResult AutoDetectContentType(nsString& aBuffer,nsString& aType);
protected:
@@ -335,7 +329,8 @@ protected:
CScanner* mScanner;
nsIURL* mURL;
nsIDTDDebug* mDTDDebug;
nsString mContentType;
nsString mSourceType;
nsString mTargetType;
eAutoDetectResult mAutoDetectStatus;
};

View File

@@ -42,40 +42,41 @@ enum eParseMode {
};
const PRInt32 kEOF = 1000000L;
const PRInt32 kUnknownError = -1000;
const PRInt32 kCantPropagate = -6;
const PRInt32 kContextMismatch = -5;
const PRInt32 kBadFilename = -4;
const PRInt32 kBadURL = -3;
const PRInt32 kInterrupted = -2;
const PRInt32 kNotFound = -1;
const PRInt32 kNoError = 0;
const PRInt32 kEOF = 1000000L;
const PRInt32 kUnknownError = -1000;
const PRInt32 kCantPropagate = -6;
const PRInt32 kContextMismatch = -5;
const PRInt32 kBadFilename = -4;
const PRInt32 kBadURL = -3;
const PRInt32 kInterrupted = -2;
const PRInt32 kNotFound = -1;
const PRInt32 kNoError = 0;
const PRUint32 kNewLine = '\n';
const PRUint32 kCR = '\r';
const PRUint32 kLF = '\n';
const PRUint32 kTab = '\t';
const PRUint32 kSpace = ' ';
const PRUint32 kQuote = '"';
const PRUint32 kApostrophe = '\'';
const PRUint32 kLessThan = '<';
const PRUint32 kGreaterThan = '>';
const PRUint32 kAmpersand = '&';
const PRUint32 kForwardSlash = '/';
const PRUint32 kEqual = '=';
const PRUint32 kMinus = '-';
const PRUint32 kPlus = '+';
const PRUint32 kExclamation = '!';
const PRUint32 kSemicolon = ';';
const PRUint32 kHashsign = '#';
const PRUint32 kAsterisk = '*';
const PRUint32 kUnderbar = '_';
const PRUint32 kComma = ',';
const PRUint32 kLeftParen = '(';
const PRUint32 kRightParen = ')';
const PRUint32 kLeftBrace = '{';
const PRUint32 kRightBrace = '}';
const PRUint32 kNewLine = '\n';
const PRUint32 kCR = '\r';
const PRUint32 kLF = '\n';
const PRUint32 kTab = '\t';
const PRUint32 kSpace = ' ';
const PRUint32 kQuote = '"';
const PRUint32 kApostrophe = '\'';
const PRUint32 kLessThan = '<';
const PRUint32 kGreaterThan = '>';
const PRUint32 kAmpersand = '&';
const PRUint32 kForwardSlash = '/';
const PRUint32 kBackSlash = '\\';
const PRUint32 kEqual = '=';
const PRUint32 kMinus = '-';
const PRUint32 kPlus = '+';
const PRUint32 kExclamation = '!';
const PRUint32 kSemicolon = ';';
const PRUint32 kHashsign = '#';
const PRUint32 kAsterisk = '*';
const PRUint32 kUnderbar = '_';
const PRUint32 kComma = ',';
const PRUint32 kLeftParen = '(';
const PRUint32 kRightParen = ')';
const PRUint32 kLeftBrace = '{';
const PRUint32 kRightBrace = '}';
#endif

View File

@@ -47,6 +47,7 @@ CScanner::CScanner(eParseMode aMode) : mBuffer("") {
mNetStream=0;
mFileStream=0;
mIncremental=PR_TRUE;
mOwnsStream=PR_TRUE;
}
/**
@@ -64,6 +65,7 @@ CScanner::CScanner(const char* aFilename,eParseMode aMode) : mBuffer("") {
mParseMode=aMode;
mNetStream=0;
mIncremental=PR_FALSE;
mOwnsStream=PR_TRUE;
#if defined(XP_UNIX) && (defined(IRIX) || defined(MKLINUX))
/* XXX: IRIX does not support ios::binary */
mFileStream=new fstream(aFilename,ios::in);
@@ -72,6 +74,24 @@ CScanner::CScanner(const char* aFilename,eParseMode aMode) : mBuffer("") {
#endif
}
/**
* Use this constructor if you want i/o to be file based.
*
* @update gess 5/12/98
* @param aMode represents the parser mode (nav, other)
* @return
*/
CScanner::CScanner(fstream& aStream,eParseMode aMode) : mBuffer("") {
mOffset=0;
mMarkPos=-1;
mTotalRead=0;
mParseMode=aMode;
mNetStream=0;
mIncremental=PR_FALSE;
mOwnsStream=PR_FALSE;
mFileStream=&aStream;
}
/**
* Use this constructor if you want i/o to be based on a
* non-incremental netstream.
@@ -91,6 +111,7 @@ CScanner::CScanner(nsIURL* aURL,eParseMode aMode) : mBuffer("") {
mIncremental=PR_FALSE;
mNetStream=aURL->Open(&error);
gURLRef=aURL->GetSpec();
mOwnsStream=PR_FALSE;
}
@@ -104,7 +125,8 @@ CScanner::CScanner(nsIURL* aURL,eParseMode aMode) : mBuffer("") {
CScanner::~CScanner() {
if(mFileStream) {
mFileStream->close();
delete mFileStream;
if(mOwnsStream)
delete mFileStream;
}
else if(mNetStream) {
mNetStream->Close();
@@ -354,7 +376,7 @@ PRInt32 CScanner::PutBack(PRUnichar aChar) {
* @param
* @return error status
*/
PRInt32 CScanner::SkipWhite(void) {
PRInt32 CScanner::SkipWhitespace(void) {
static nsAutoString chars(" \n\r\t");
return SkipOver(chars);
}

View File

@@ -25,7 +25,7 @@
* how to consume characters out of an (internal) stream.
* This class also offers a series of utility methods
* that most tokenizers want, such as readUntil(),
* readWhile() and SkipWhite().
* readWhile() and SkipWhitespace().
*/
@@ -73,6 +73,16 @@ class CScanner {
*/
CScanner(const char* aFilename,eParseMode aMode=eParseMode_navigator);
/**
* Use this constructor if you want i/o to be stream based.
*
* @update gess 5/12/98
* @param aMode represents the parser mode (nav, other)
* @return
*/
CScanner(fstream& aStream,eParseMode aMode=eParseMode_navigator);
~CScanner();
/**
@@ -136,7 +146,7 @@ class CScanner {
* @update gess 3/25/98
* @return error status
*/
PRInt32 SkipWhite(void);
PRInt32 SkipWhitespace(void);
/**
* Determine if the scanner has reached EOF.
@@ -265,6 +275,7 @@ class CScanner {
PRInt32 mTotalRead;
eParseMode mParseMode;
PRBool mIncremental;
PRBool mOwnsStream;
};
#endif

View File

@@ -0,0 +1,334 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/**
* MODULE NOTES:
* @update gess 4/8/98
*
*
*/
/**
* TRANSIENT STYLE-HANDLING NOTES:
* @update gess 6/15/98
*
* ...add comments here about transient style stack.
*
*/
#include "nsIDTDDebug.h"
#include "nsValidDTD.h"
#include "nsCRT.h"
#include "nsParser.h"
#include "nsScanner.h"
#include "nsParserTypes.h"
#include "nsTokenHandler.h"
#include "prenv.h" //this is here for debug reasons...
#include "prtypes.h" //this is here for debug reasons...
#include "prio.h"
#include "plstr.h"
#ifdef XP_PC
#include <direct.h> //this is here for debug reasons...
#endif
#include "prmem.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIDTDIID, NS_IDTD_IID);
static NS_DEFINE_IID(kClassIID, NS_VALID_DTD_IID);
static const char* kNullURL = "Error: Null URL given";
static const char* kNullFilename= "Error: Null filename given";
static const char* kNullTokenizer = "Error: Unable to construct tokenizer";
static const char* kNullToken = "Error: Null token given";
static const char* kInvalidTagStackPos = "Error: invalid tag stack position";
static const char* kRTFTextContentType = "text/xml";
static nsAutoString gEmpty;
/**
* This method gets called as part of our COM-like interfaces.
* Its purpose is to create an interface to parser object
* of some type.
*
* @update gess 4/8/98
* @param nsIID id of object to discover
* @param aInstancePtr ptr to newly discovered interface
* @return NS_xxx result code
*/
nsresult CValidDTD::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if(aIID.Equals(kISupportsIID)) { //do IUnknown...
*aInstancePtr = (nsIDTD*)(this);
}
else if(aIID.Equals(kIDTDIID)) { //do IParser base class...
*aInstancePtr = (nsIDTD*)(this);
}
else if(aIID.Equals(kClassIID)) { //do this class...
*aInstancePtr = (CValidDTD*)(this);
}
else {
*aInstancePtr=0;
return NS_NOINTERFACE;
}
((nsISupports*) *aInstancePtr)->AddRef();
return NS_OK;
}
/**
* This method is defined in nsIParser. It is used to
* cause the COM-like construction of an nsParser.
*
* @update gess 4/8/98
* @param nsIParser** ptr to newly instantiated parser
* @return NS_xxx error result
*/
NS_HTMLPARS nsresult NS_NewValid_DTD(nsIDTD** aInstancePtrResult)
{
CValidDTD* it = new CValidDTD();
if (it == 0) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kClassIID, (void **) aInstancePtrResult);
}
NS_IMPL_ADDREF(CValidDTD)
NS_IMPL_RELEASE(CValidDTD)
/**
* Default constructor
*
* @update gess 4/9/98
* @param
* @return
*/
CValidDTD::CValidDTD() : nsIDTD() {
NS_INIT_REFCNT();
mParser=0;
mFilename=0;
}
/**
* Default destructor
*
* @update gess 4/9/98
* @param
* @return
*/
CValidDTD::~CValidDTD(){
}
/**
* This method is called to determine if the given DTD can parse
* a document in a given source-type.
* NOTE: Parsing always assumes that the end result will involve
* storing the result in the main content model.
* @update gess6/24/98
* @param
* @return TRUE if this DTD can satisfy the request; FALSE otherwise.
*/
PRBool CValidDTD::CanParse(nsString& aContentType, PRInt32 aVersion){
PRBool result=aContentType.Equals(kRTFTextContentType);
return result;
}
/**
* This method is called to determine if the given DTD can perform
* a document conversion from a given source-type to a given target-type.
* NOTE: conversion always assumes an input stream and an outputstream.
* @update gess6/24/98
* @param
* @return TRUE if this DTD can satisfy the request; FALSE otherwise.
*/
PRBool CValidDTD::CanConvert(nsString& aSourceType, nsString& aTargetType, PRInt32 aVersion){
PRBool result=PR_TRUE;
return result;
}
/**
*
* @update gess7/7/98
* @param
* @return
*/
eAutoDetectResult CValidDTD::AutoDetectContentType(nsString& aBuffer,nsString& aType){
eAutoDetectResult result=eUnknownDetect;
return result;
}
/**
*
* @update gess5/18/98
* @param
* @return
*/
PRInt32 CValidDTD::WillBuildModel(const char* aFilename){
PRInt32 result=0;
return result;
}
/**
*
* @update gess5/18/98
* @param
* @return
*/
PRInt32 CValidDTD::DidBuildModel(PRInt32 anErrorCode){
PRInt32 result=0;
return result;
}
/**
*
*
* @update gess 3/25/98
* @param
* @return
*/
void CValidDTD::SetParser(nsIParser* aParser) {
mParser=(nsParser*)aParser;
}
/**
* This method gets called in order to set the content
* sink for this parser to dump nodes to.
*
* @update gess 3/25/98
* @param nsIContentSink interface for node receiver
* @return
*/
nsIContentSink* CValidDTD::SetContentSink(nsIContentSink* aSink) {
return 0;
}
/*******************************************************************
These methods use to be hidden in the tokenizer-delegate.
That file merged with the DTD, since the separation wasn't really
buying us anything.
*******************************************************************/
/**
* This method repeatedly called by the tokenizer.
* Each time, we determine the kind of token were about to
* read, and then we call the appropriate method to handle
* that token type.
*
* @update gess 3/25/98
* @param aChar: last char read
* @param aScanner: see nsScanner.h
* @param anErrorCode: arg that will hold error condition
* @return new token or null
*/
PRInt32 CValidDTD::ConsumeToken(CToken*& aToken){
CScanner* theScanner=mParser->GetScanner();
PRUnichar aChar;
PRInt32 result=theScanner->GetChar(aChar);
switch(result) {
case kEOF:
break;
case kInterrupted:
theScanner->RewindToMark();
break;
case kNoError:
default:
switch(aChar) {
case kLessThan:
default:
break;
} //switch
break;
} //switch
if(kNoError==result)
result=theScanner->Eof();
return result;
}
/**
*
* @update gess5/18/98
* @param
* @return
*/
void CValidDTD::WillResumeParse(void){
return;
}
/**
*
* @update gess5/18/98
* @param
* @return
*/
void CValidDTD::WillInterruptParse(void){
return;
}
/**
*
* @update jevering6/23/98
* @param
* @return
*/
void CValidDTD::SetDTDDebug(nsIDTDDebug * aDTDDebug) {
}
/**
* This method is called to determine whether or not a tag
* of one type can contain a tag of another type.
*
* @update gess 3/25/98
* @param aParent -- int tag of parent container
* @param aChild -- int tag of child container
* @return PR_TRUE if parent can contain child
*/
PRBool CValidDTD::CanContain(PRInt32 aParent,PRInt32 aChild){
PRBool result=PR_FALSE;
return result;
}
/**
*
* @update gess 3/25/98
* @param aToken -- token object to be put into content model
* @return 0 if all is well; non-zero is an error
*/
PRInt32 CValidDTD::HandleToken(CToken* aToken) {
PRInt32 result=0;
return result;
}

View File

@@ -0,0 +1,205 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/**
* MODULE NOTES:
* @update gess 4/8/98
*
*
*/
#ifndef __NS_VALID_DTD
#define __NS_VALID_DTD
#include "nsIDTD.h"
#include "nsISupports.h"
#include "nsHTMLTokens.h"
#include "nshtmlpars.h"
#include "nsVoidArray.h"
#include "nsDeque.h"
#define NS_VALID_DTD_IID \
{0xa39c6bfe, 0x15f0, 0x11d2, \
{0x80, 0x41, 0x0, 0x10, 0x4b, 0x98, 0x3f, 0xd4}}
class nsIHTMLContentSink;
class nsIDTDDebug;
class nsIParserNode;
class CITokenHandler;
class nsParser;
class CValidDTD : public nsIDTD {
public:
NS_DECL_ISUPPORTS
/**
*
*
* @update gess 4/9/98
* @param
* @return
*/
CValidDTD();
/**
*
*
* @update gess 4/9/98
* @param
* @return
*/
virtual ~CValidDTD();
/**
* This method is called to determine if the given DTD can parse
* a document in a given source-type.
* NOTE: Parsing always assumes that the end result will involve
* storing the result in the main content model.
* @update gess6/24/98
* @param
* @return TRUE if this DTD can satisfy the request; FALSE otherwise.
*/
virtual PRBool CanParse(nsString& aContentType, PRInt32 aVersion);
/**
* This method is called to determine if the given DTD can perform
* a document conversion from a given source-type to a given target-type.
* NOTE: conversion always assumes an input stream and an outputstream.
* @update gess6/24/98
* @param
* @return TRUE if this DTD can satisfy the request; FALSE otherwise.
*/
virtual PRBool CanConvert(nsString& aSourceType, nsString& aTargetType, PRInt32 aVersion);
/**
*
* @update gess7/7/98
* @param
* @return
*/
virtual eAutoDetectResult AutoDetectContentType(nsString& aBuffer,nsString& aType);
/**
*
* @update gess5/18/98
* @param
* @return
*/
virtual PRInt32 WillBuildModel(const char* aFilename=0);
/**
*
* @update gess5/18/98
* @param
* @return
*/
virtual PRInt32 DidBuildModel(PRInt32 anErrorCode);
/**
*
* @update gess 3/25/98
* @param aToken -- token object to be put into content model
* @return 0 if all is well; non-zero is an error
*/
virtual PRInt32 HandleToken(CToken* aToken);
/**
*
*
* @update gess 3/25/98
* @param
* @return
*/
virtual void SetParser(nsIParser* aParser);
/**
* Cause the tokenizer to consume the next token, and
* return an error result.
*
* @update gess 3/25/98
* @param anError -- ref to error code
* @return new token or null
*/
virtual PRInt32 ConsumeToken(CToken*& aToken);
/**
*
* @update gess5/18/98
* @param
* @return
*/
virtual void WillResumeParse(void);
/**
*
* @update gess5/18/98
* @param
* @return
*/
virtual void WillInterruptParse(void);
/**
* Select given content sink into parser for parser output
* @update gess5/11/98
* @param aSink is the new sink to be used by parser
* @return old sink, or NULL
*/
virtual nsIContentSink* SetContentSink(nsIContentSink* aSink);
/**
*
* @update jevering6/23/98
* @param
* @return
*/
virtual void SetDTDDebug(nsIDTDDebug * aDTDDebug);
/**
* This method is called to determine whether or not a tag
* of one type can contain a tag of another type.
*
* @update gess 3/25/98
* @param aParent -- int tag of parent container
* @param aChild -- int tag of child container
* @return PR_TRUE if parent can contain child
*/
virtual PRBool CanContain(PRInt32 aParent,PRInt32 aChild);
protected:
nsParser* mParser;
nsIHTMLContentSink* mSink;
char* mFilename;
};
extern NS_HTMLPARS nsresult NS_NewValid_DTD(nsIDTD** aInstancePtrResult);
#endif

View File

@@ -0,0 +1,321 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/**
* MODULE NOTES:
* @update gess 4/8/98
*
*
*/
/**
* TRANSIENT STYLE-HANDLING NOTES:
* @update gess 6/15/98
*
* ...add comments here about transient style stack.
*
*/
#include "nsIDTDDebug.h"
#include "nsWellFormedDTD.h"
#include "nsCRT.h"
#include "nsParser.h"
#include "nsScanner.h"
#include "nsParserTypes.h"
#include "nsTokenHandler.h"
#include "prenv.h" //this is here for debug reasons...
#include "prtypes.h" //this is here for debug reasons...
#include "prio.h"
#include "plstr.h"
#ifdef XP_PC
#include <direct.h> //this is here for debug reasons...
#endif
#include "prmem.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIDTDIID, NS_IDTD_IID);
static NS_DEFINE_IID(kClassIID, NS_WELLFORMED_DTD_IID);
static const char* kNullURL = "Error: Null URL given";
static const char* kNullFilename= "Error: Null filename given";
static const char* kNullTokenizer = "Error: Unable to construct tokenizer";
static const char* kNullToken = "Error: Null token given";
static const char* kInvalidTagStackPos = "Error: invalid tag stack position";
static const char* kRTFTextContentType = "text/xml";
static nsAutoString gEmpty;
/**
* This method gets called as part of our COM-like interfaces.
* Its purpose is to create an interface to parser object
* of some type.
*
* @update gess 4/8/98
* @param nsIID id of object to discover
* @param aInstancePtr ptr to newly discovered interface
* @return NS_xxx result code
*/
nsresult CWellFormedDTD::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if(aIID.Equals(kISupportsIID)) { //do IUnknown...
*aInstancePtr = (nsIDTD*)(this);
}
else if(aIID.Equals(kIDTDIID)) { //do IParser base class...
*aInstancePtr = (nsIDTD*)(this);
}
else if(aIID.Equals(kClassIID)) { //do this class...
*aInstancePtr = (CWellFormedDTD*)(this);
}
else {
*aInstancePtr=0;
return NS_NOINTERFACE;
}
((nsISupports*) *aInstancePtr)->AddRef();
return NS_OK;
}
/**
* This method is defined in nsIParser. It is used to
* cause the COM-like construction of an nsParser.
*
* @update gess 4/8/98
* @param nsIParser** ptr to newly instantiated parser
* @return NS_xxx error result
*/
NS_HTMLPARS nsresult NS_NewWellFormed_DTD(nsIDTD** aInstancePtrResult)
{
CWellFormedDTD* it = new CWellFormedDTD();
if (it == 0) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kClassIID, (void **) aInstancePtrResult);
}
NS_IMPL_ADDREF(CWellFormedDTD)
NS_IMPL_RELEASE(CWellFormedDTD)
/**
* Default constructor
*
* @update gess 4/9/98
* @param
* @return
*/
CWellFormedDTD::CWellFormedDTD() : nsIDTD() {
NS_INIT_REFCNT();
mParser=0;
mFilename=0;
}
/**
* Default destructor
*
* @update gess 4/9/98
* @param
* @return
*/
CWellFormedDTD::~CWellFormedDTD(){
}
/**
* This method is called to determine if the given DTD can parse
* a document in a given source-type.
* NOTE: Parsing always assumes that the end result will involve
* storing the result in the main content model.
* @update gess6/24/98
* @param
* @return TRUE if this DTD can satisfy the request; FALSE otherwise.
*/
PRBool CWellFormedDTD::CanParse(nsString& aContentType, PRInt32 aVersion){
PRBool result=aContentType.Equals(kRTFTextContentType);
return result;
}
/**
*
* @update gess7/7/98
* @param
* @return
*/
eAutoDetectResult CWellFormedDTD::AutoDetectContentType(nsString& aBuffer,nsString& aType){
eAutoDetectResult result=eUnknownDetect;
return result;
}
/**
*
* @update gess5/18/98
* @param
* @return
*/
PRInt32 CWellFormedDTD::WillBuildModel(const char* aFilename){
PRInt32 result=0;
return result;
}
/**
*
* @update gess5/18/98
* @param
* @return
*/
PRInt32 CWellFormedDTD::DidBuildModel(PRInt32 anErrorCode){
PRInt32 result=0;
return result;
}
/**
*
*
* @update gess 3/25/98
* @param
* @return
*/
void CWellFormedDTD::SetParser(nsIParser* aParser) {
mParser=(nsParser*)aParser;
}
/**
* This method gets called in order to set the content
* sink for this parser to dump nodes to.
*
* @update gess 3/25/98
* @param nsIContentSink interface for node receiver
* @return
*/
nsIContentSink* CWellFormedDTD::SetContentSink(nsIContentSink* aSink) {
return 0;
}
/*******************************************************************
These methods use to be hidden in the tokenizer-delegate.
That file merged with the DTD, since the separation wasn't really
buying us anything.
*******************************************************************/
/**
* This method repeatedly called by the tokenizer.
* Each time, we determine the kind of token were about to
* read, and then we call the appropriate method to handle
* that token type.
*
* @update gess 3/25/98
* @param aChar: last char read
* @param aScanner: see nsScanner.h
* @param anErrorCode: arg that will hold error condition
* @return new token or null
*/
PRInt32 CWellFormedDTD::ConsumeToken(CToken*& aToken){
CScanner* theScanner=mParser->GetScanner();
PRUnichar aChar;
PRInt32 result=theScanner->GetChar(aChar);
switch(result) {
case kEOF:
break;
case kInterrupted:
theScanner->RewindToMark();
break;
case kNoError:
default:
switch(aChar) {
case kLessThan:
default:
break;
} //switch
break;
} //switch
if(kNoError==result)
result=theScanner->Eof();
return result;
}
/**
*
* @update gess5/18/98
* @param
* @return
*/
void CWellFormedDTD::WillResumeParse(void){
return;
}
/**
*
* @update gess5/18/98
* @param
* @return
*/
void CWellFormedDTD::WillInterruptParse(void){
return;
}
/**
*
* @update jevering6/23/98
* @param
* @return
*/
void CWellFormedDTD::SetDTDDebug(nsIDTDDebug * aDTDDebug) {
}
/**
* This method is called to determine whether or not a tag
* of one type can contain a tag of another type.
*
* @update gess 3/25/98
* @param aParent -- int tag of parent container
* @param aChild -- int tag of child container
* @return PR_TRUE if parent can contain child
*/
PRBool CWellFormedDTD::CanContain(PRInt32 aParent,PRInt32 aChild){
PRBool result=PR_FALSE;
return result;
}
/**
*
* @update gess 3/25/98
* @param aToken -- token object to be put into content model
* @return 0 if all is well; non-zero is an error
*/
PRInt32 CWellFormedDTD::HandleToken(CToken* aToken) {
PRInt32 result=0;
return result;
}

View File

@@ -0,0 +1,194 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/**
* MODULE NOTES:
* @update gess 4/8/98
*
*
*/
#ifndef __NS_WELLFORMED_DTD
#define __NS_WELLFORMED_DTD
#include "nsIDTD.h"
#include "nsISupports.h"
#include "nsHTMLTokens.h"
#include "nshtmlpars.h"
#include "nsVoidArray.h"
#include "nsDeque.h"
#define NS_WELLFORMED_DTD_IID \
{0xa39c6bfd, 0x15f0, 0x11d2, \
{0x80, 0x41, 0x0, 0x10, 0x4b, 0x98, 0x3f, 0xd4}}
class nsIHTMLContentSink;
class nsIDTDDebug;
class nsIParserNode;
class CITokenHandler;
class nsParser;
class CWellFormedDTD : public nsIDTD {
public:
NS_DECL_ISUPPORTS
/**
*
*
* @update gess 4/9/98
* @param
* @return
*/
CWellFormedDTD();
/**
*
*
* @update gess 4/9/98
* @param
* @return
*/
virtual ~CWellFormedDTD();
/**
* This method is called to determine if the given DTD can parse
* a document in a given source-type.
* NOTE: Parsing always assumes that the end result will involve
* storing the result in the main content model.
* @update gess6/24/98
* @param
* @return TRUE if this DTD can satisfy the request; FALSE otherwise.
*/
virtual PRBool CanParse(nsString& aContentType, PRInt32 aVersion);
/**
*
* @update gess7/7/98
* @param
* @return
*/
virtual eAutoDetectResult AutoDetectContentType(nsString& aBuffer,nsString& aType);
/**
*
* @update gess5/18/98
* @param
* @return
*/
virtual PRInt32 WillBuildModel(const char* aFilename=0);
/**
*
* @update gess5/18/98
* @param
* @return
*/
virtual PRInt32 DidBuildModel(PRInt32 anErrorCode);
/**
*
* @update gess 3/25/98
* @param aToken -- token object to be put into content model
* @return 0 if all is well; non-zero is an error
*/
virtual PRInt32 HandleToken(CToken* aToken);
/**
*
*
* @update gess 3/25/98
* @param
* @return
*/
virtual void SetParser(nsIParser* aParser);
/**
* Cause the tokenizer to consume the next token, and
* return an error result.
*
* @update gess 3/25/98
* @param anError -- ref to error code
* @return new token or null
*/
virtual PRInt32 ConsumeToken(CToken*& aToken);
/**
*
* @update gess5/18/98
* @param
* @return
*/
virtual void WillResumeParse(void);
/**
*
* @update gess5/18/98
* @param
* @return
*/
virtual void WillInterruptParse(void);
/**
* Select given content sink into parser for parser output
* @update gess5/11/98
* @param aSink is the new sink to be used by parser
* @return old sink, or NULL
*/
virtual nsIContentSink* SetContentSink(nsIContentSink* aSink);
/**
*
* @update jevering6/23/98
* @param
* @return
*/
virtual void SetDTDDebug(nsIDTDDebug * aDTDDebug);
/**
* This method is called to determine whether or not a tag
* of one type can contain a tag of another type.
*
* @update gess 3/25/98
* @param aParent -- int tag of parent container
* @param aChild -- int tag of child container
* @return PR_TRUE if parent can contain child
*/
virtual PRBool CanContain(PRInt32 aParent,PRInt32 aChild);
protected:
nsParser* mParser;
nsIHTMLContentSink* mSink;
char* mFilename;
};
extern NS_HTMLPARS nsresult NS_NewWellFormed_DTD(nsIDTD** aInstancePtrResult);
#endif

View File

@@ -904,7 +904,7 @@ void HTMLContentSink::ReflowNewContent()
shell->ContentAppended(mBody);
NS_RELEASE(shell);
}
}
}
#endif
}

View File

@@ -36,6 +36,12 @@
#include "nsIWebWidget.h"
#include "CNavDTD.h"
//#define rickgdebug 1
#ifdef rickgdebug
#include "nsHTMLContentSinkStream.h"
#endif
static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID);
static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID);
static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID);
@@ -104,6 +110,13 @@ nsHTMLDocument::StartDocumentLoad(nsIURL *aURL,
nsresult rv = NS_NewParser(&parser);
if (NS_OK == rv) {
nsIHTMLContentSink* sink;
#ifdef rickgdebug
rv = NS_New_HTML_ContentSinkStream(&sink);
#else
rv = NS_NewHTMLContentSink(&sink, this, aURL, aWebWidget);
#endif
rv = NS_NewHTMLContentSink(&sink, this, aURL, aWebWidget);
if (NS_OK == rv) {
nsIHTMLCSSStyleSheet* styleAttrSheet;
@@ -129,10 +142,9 @@ nsHTMLDocument::StartDocumentLoad(nsIURL *aURL,
nsIDTD* theDTD=0;
NS_NewNavHTMLDTD(&theDTD);
parser->RegisterDTD(theDTD);
parser->RegisterDTD(theDTD);
parser->SetContentSink(sink);
parser->BeginParse(aURL);
parser->Parse(aURL);
}
NS_RELEASE(sink);
}

View File

@@ -282,18 +282,33 @@ void CNavDTD::SetDTDDebug(nsIDTDDebug * aDTDDebug)
}
/**
* This method gets called by the parser to determine if this DTD can handle
* the requested process for the requested content type.
*
* This method is called to determine if the given DTD can parse
* a document in a given source-type.
* NOTE: Parsing always assumes that the end result will involve
* storing the result in the main content model.
* @update gess6/24/98
* @param
* @return TRUE if the DTD can handle the process for this type; FALSE otherwise.
* @param
* @return TRUE if this DTD can satisfy the request; FALSE otherwise.
*/
PRBool CNavDTD::IsCapableOf(eProcessType aProcessType, nsString& aContentType,PRInt32 aVersion){
PRBool CNavDTD::CanParse(nsString& aContentType, PRInt32 aVersion){
PRBool result=aContentType.Equals(kHTMLTextContentType);
return result;
}
/**
*
* @update gess7/7/98
* @param
* @return
*/
eAutoDetectResult CNavDTD::AutoDetectContentType(nsString& aBuffer,nsString& aType){
eAutoDetectResult result=eUnknownDetect;
if(PR_TRUE==aType.Equals(kHTMLTextContentType))
result=eValidDetect;
return result;
}
/**
*

View File

@@ -70,13 +70,24 @@ class CNavDTD : public nsIDTD {
*/
virtual ~CNavDTD();
/**
* This method is called to determine if the given DTD can parse
* a document in a given source-type.
* NOTE: Parsing always assumes that the end result will involve
* storing the result in the main content model.
* @update gess6/24/98
* @param
* @return TRUE if this DTD can satisfy the request; FALSE otherwise.
*/
virtual PRBool CanParse(nsString& aContentType, PRInt32 aVersion);
/**
*
* @update gess7/1/98
* @update gess7/7/98
* @param
* @return
*/
virtual PRBool IsCapableOf(eProcessType aProcessType, nsString& aString, PRInt32 aVersion);
virtual eAutoDetectResult AutoDetectContentType(nsString& aBuffer,nsString& aType);
/**
*

View File

@@ -149,17 +149,29 @@ COtherDTD::~COtherDTD(){
}
/**
* This method gets called by the parser to determine if this DTD can handle
* the requested process for the requested content type.
*
* This method is called to determine if the given DTD can parse
* a document in a given source-type.
* NOTE: Parsing always assumes that the end result will involve
* storing the result in the main content model.
* @update gess6/24/98
* @param
* @return TRUE if the DTD can handle the process for this type; FALSE otherwise.
* @param
* @return TRUE if this DTD can satisfy the request; FALSE otherwise.
*/
PRBool COtherDTD::IsCapableOf(eProcessType aProcessType, nsString& aContentType,PRInt32 aVersion){
return CNavDTD::IsCapableOf(aProcessType,aContentType,aVersion);
PRBool COtherDTD::CanParse(nsString& aContentType, PRInt32 aVersion){
return CNavDTD::CanParse(aContentType,aVersion);
}
/**
*
* @update gess7/7/98
* @param
* @return
*/
eAutoDetectResult COtherDTD::AutoDetectContentType(nsString& aBuffer,nsString& aType){
return CNavDTD::AutoDetectContentType(aBuffer,aType);
}
/**
*
* @update gess5/18/98

View File

@@ -62,7 +62,24 @@ class COtherDTD : public CNavDTD {
*/
virtual ~COtherDTD();
virtual PRBool IsCapableOf(eProcessType aProcessType, nsString& aString,PRInt32 aVersion);
/**
* This method is called to determine if the given DTD can parse
* a document in a given source-type.
* NOTE: Parsing always assumes that the end result will involve
* storing the result in the main content model.
* @update gess6/24/98
* @param
* @return TRUE if this DTD can satisfy the request; FALSE otherwise.
*/
virtual PRBool CanParse(nsString& aContentType, PRInt32 aVersion);
/**
*
* @update gess7/7/98
* @param
* @return
*/
virtual eAutoDetectResult AutoDetectContentType(nsString& aBuffer,nsString& aType);
/**
*

View File

@@ -0,0 +1,622 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/**
* MODULE NOTES:
* @update gess 4/8/98
*
*
*/
/**
* TRANSIENT STYLE-HANDLING NOTES:
* @update gess 6/15/98
*
* ...add comments here about transient style stack.
*
*/
#include "nsIDTDDebug.h"
#include "CRtfDTD.h"
#include "nsCRT.h"
#include "nsParser.h"
#include "nsScanner.h"
#include "nsParserTypes.h"
#include "nsTokenHandler.h"
#include "prenv.h" //this is here for debug reasons...
#include "prtypes.h" //this is here for debug reasons...
#include "prio.h"
#include "plstr.h"
#ifdef XP_PC
#include <direct.h> //this is here for debug reasons...
#endif
#include "prmem.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIDTDIID, NS_IDTD_IID);
static NS_DEFINE_IID(kClassIID, NS_RTF_DTD_IID);
static const char* kNullURL = "Error: Null URL given";
static const char* kNullFilename= "Error: Null filename given";
static const char* kNullTokenizer = "Error: Unable to construct tokenizer";
static const char* kNullToken = "Error: Null token given";
static const char* kInvalidTagStackPos = "Error: invalid tag stack position";
static const char* kRTFTextContentType = "application/rtf";
static const char* kRTFDocHeader= "{\\rtf0";
static nsString gAlphaChars("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
static nsAutoString gDigits("-0123456789");
static nsAutoString gEmpty;
struct RTFEntry {
char mName[10];
eRTFTags mTagID;
};
static RTFEntry gRTFTable[] = {
{"$",eRTFCtrl_unknown},
{"'",eRTFCtrl_quote},
{"*",eRTFCtrl_star},
{"0x0a",eRTFCtrl_linefeed},
{"0x0d",eRTFCtrl_return},
{"\\",eRTFCtrl_begincontrol},
{"b",eRTFCtrl_bold},
{"bin",eRTFCtrl_bin},
{"blue",eRTFCtrl_blue},
{"cols",eRTFCtrl_cols},
{"comment",eRTFCtrl_comment},
{"f",eRTFCtrl_font},
{"fonttbl",eRTFCtrl_fonttable},
{"green",eRTFCtrl_green},
{"i",eRTFCtrl_italic},
{"margb",eRTFCtrl_bottommargin},
{"margl",eRTFCtrl_leftmargin},
{"margr",eRTFCtrl_rightmargin},
{"margt",eRTFCtrl_topmargin},
{"par",eRTFCtrl_par},
{"pard",eRTFCtrl_pard},
{"plain",eRTFCtrl_plain},
{"qc",eRTFCtrl_justified},
{"qj",eRTFCtrl_fulljustified},
{"ql",eRTFCtrl_leftjustified},
{"qr",eRTFCtrl_rightjustified},
{"rdblquote",eRTFCtrl_rdoublequote},
{"red",eRTFCtrl_red},
{"rtf",eRTFCtrl_rtf},
{"tab",eRTFCtrl_tab},
{"title",eRTFCtrl_title},
{"u",eRTFCtrl_underline},
{"{",eRTFCtrl_startgroup},
{"}",eRTFCtrl_endgroup},
{"~",eRTFCtrl_last} //make sure this stays the last token...
};
/**
*
* @update gess4/25/98
* @param
* @return
*/
const char* GetTagName(eRTFTags aTag) {
const char* result=0;
PRInt32 cnt=sizeof(gRTFTable)/sizeof(RTFEntry);
PRInt32 low=0;
PRInt32 high=cnt-1;
PRInt32 middle=kNotFound;
while(low<=high) {
middle=(PRInt32)(low+high)/2;
if(aTag==gRTFTable[middle].mTagID)
return gRTFTable[middle].mName;
if(aTag<gRTFTable[middle].mTagID)
high=middle-1;
else low=middle+1;
}
return "";
}
/**
* This method gets called as part of our COM-like interfaces.
* Its purpose is to create an interface to parser object
* of some type.
*
* @update gess 4/8/98
* @param nsIID id of object to discover
* @param aInstancePtr ptr to newly discovered interface
* @return NS_xxx result code
*/
nsresult CRtfDTD::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if(aIID.Equals(kISupportsIID)) { //do IUnknown...
*aInstancePtr = (nsIDTD*)(this);
}
else if(aIID.Equals(kIDTDIID)) { //do IParser base class...
*aInstancePtr = (nsIDTD*)(this);
}
else if(aIID.Equals(kClassIID)) { //do this class...
*aInstancePtr = (CRtfDTD*)(this);
}
else {
*aInstancePtr=0;
return NS_NOINTERFACE;
}
((nsISupports*) *aInstancePtr)->AddRef();
return NS_OK;
}
/**
* This method is defined in nsIParser. It is used to
* cause the COM-like construction of an nsParser.
*
* @update gess 4/8/98
* @param nsIParser** ptr to newly instantiated parser
* @return NS_xxx error result
*/
NS_HTMLPARS nsresult NS_NewRTF_DTD(nsIDTD** aInstancePtrResult)
{
CRtfDTD* it = new CRtfDTD();
if (it == 0) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kClassIID, (void **) aInstancePtrResult);
}
NS_IMPL_ADDREF(CRtfDTD)
NS_IMPL_RELEASE(CRtfDTD)
/**
* Default constructor
*
* @update gess 4/9/98
* @param
* @return
*/
CRtfDTD::CRtfDTD() : nsIDTD() {
NS_INIT_REFCNT();
mParser=0;
mFilename=0;
}
/**
* Default destructor
*
* @update gess 4/9/98
* @param
* @return
*/
CRtfDTD::~CRtfDTD(){
}
/**
* This method is called to determine if the given DTD can parse
* a document in a given source-type.
* NOTE: Parsing always assumes that the end result will involve
* storing the result in the main content model.
* @update gess6/24/98
* @param
* @return TRUE if this DTD can satisfy the request; FALSE otherwise.
*/
PRBool CRtfDTD::CanParse(nsString& aContentType, PRInt32 aVersion){
PRBool result=aContentType.Equals(kRTFTextContentType);
return result;
}
/**
*
* @update gess7/7/98
* @param
* @return
*/
eAutoDetectResult CRtfDTD::AutoDetectContentType(nsString& aBuffer,nsString& aType){
eAutoDetectResult result=eUnknownDetect;
if(kNotFound!=aBuffer.Find(kRTFDocHeader))
if(PR_TRUE==aType.Equals(kRTFTextContentType))
result=eValidDetect;
return result;
}
/**
*
* @update gess5/18/98
* @param
* @return
*/
PRInt32 CRtfDTD::WillBuildModel(const char* aFilename){
PRInt32 result=0;
return result;
}
/**
*
* @update gess5/18/98
* @param
* @return
*/
PRInt32 CRtfDTD::DidBuildModel(PRInt32 anErrorCode){
PRInt32 result=0;
return result;
}
/**
*
*
* @update gess 3/25/98
* @param
* @return
*/
void CRtfDTD::SetParser(nsIParser* aParser) {
mParser=(nsParser*)aParser;
}
/**
* This method gets called in order to set the content
* sink for this parser to dump nodes to.
*
* @update gess 3/25/98
* @param nsIContentSink interface for node receiver
* @return
*/
nsIContentSink* CRtfDTD::SetContentSink(nsIContentSink* aSink) {
return 0;
}
/*******************************************************************
These methods use to be hidden in the tokenizer-delegate.
That file merged with the DTD, since the separation wasn't really
buying us anything.
*******************************************************************/
/**
* This gets called when we've just read a '\' char.
* It means we need to read an RTF control word.
*
* @update gess 3/25/98
* @param aToken ptr-ref to new token we create
* @return error code -- preferably kNoError
*/
PRInt32 CRtfDTD::ConsumeControlWord(CToken*& aToken){
PRInt32 result=kNoError;
CRTFControlWord* cw=new CRTFControlWord("");
if(cw){
CScanner* theScanner=mParser->GetScanner();
cw->Consume(*theScanner);
aToken=cw;
}
return result;
}
/**
* This gets called when we've just read a '{' or '}' group char.
* It means we have just started or ended an RTF group.
*
* @update gess 3/25/98
* @param aToken ptr-ref to new token we create
* @return error code -- preferably kNoError
*/
static char* keys[] = {"}","{"};
PRInt32 CRtfDTD::ConsumeGroupTag(CToken*& aToken,PRBool aStartGroup){
PRInt32 result=kNoError;
CRTFGroup* cw=new CRTFGroup(keys[PR_TRUE==aStartGroup],aStartGroup);
if(cw){
CScanner* theScanner=mParser->GetScanner();
cw->Consume(*theScanner);
aToken=cw;
}
return result;
}
/**
* This gets called when we've just read plain text char.
* It means we need to read RTF content.
*
* @update gess 3/25/98
* @param aToken ptr-ref to new token we create
* @return error code -- preferably kNoError
*/
PRInt32 CRtfDTD::ConsumeContent(PRUnichar aChar,CToken*& aToken){
PRInt32 result=kNoError;
PRUnichar buffer[2] = {0,0};
buffer[0]=aChar;
CRTFContent * cw=new CRTFContent(buffer);
if(cw){
CScanner* theScanner=mParser->GetScanner();
cw->Consume(*theScanner);
aToken=cw;
}
return result;
}
/**
* This method repeatedly called by the tokenizer.
* Each time, we determine the kind of token were about to
* read, and then we call the appropriate method to handle
* that token type.
*
* @update gess 3/25/98
* @param aChar: last char read
* @param aScanner: see nsScanner.h
* @param anErrorCode: arg that will hold error condition
* @return new token or null
*/
PRInt32 CRtfDTD::ConsumeToken(CToken*& aToken){
CScanner* theScanner=mParser->GetScanner();
PRUnichar aChar;
PRInt32 result=theScanner->GetChar(aChar);
switch(result) {
case kEOF:
break;
case kInterrupted:
theScanner->RewindToMark();
break;
case kNoError:
default:
switch(aChar) {
case kLeftBrace:
result=ConsumeGroupTag(aToken,PR_TRUE); break;
case kRightBrace:
result=ConsumeGroupTag(aToken,PR_FALSE); break;
case kBackSlash:
result=ConsumeControlWord(aToken); break;
case kCR:
case kSpace:
case kTab:
case kLF:
break;
default:
result=ConsumeContent(aChar,aToken); break;
} //switch
break;
} //switch
if(kNoError==result)
result=theScanner->Eof();
return result;
}
/**
*
* @update gess5/18/98
* @param
* @return
*/
void CRtfDTD::WillResumeParse(void){
return;
}
/**
*
* @update gess5/18/98
* @param
* @return
*/
void CRtfDTD::WillInterruptParse(void){
return;
}
/**
*
* @update jevering6/23/98
* @param
* @return
*/
void CRtfDTD::SetDTDDebug(nsIDTDDebug * aDTDDebug) {
}
/**
* This method is called to determine whether or not a tag
* of one type can contain a tag of another type.
*
* @update gess 3/25/98
* @param aParent -- int tag of parent container
* @param aChild -- int tag of child container
* @return PR_TRUE if parent can contain child
*/
PRBool CRtfDTD::CanContain(PRInt32 aParent,PRInt32 aChild){
PRBool result=PR_FALSE;
return result;
}
/**
*
* @update gess 3/25/98
* @param aToken -- token object to be put into content model
* @return 0 if all is well; non-zero is an error
*/
PRInt32 CRtfDTD::HandleGroup(CToken* aToken){
PRInt32 result=kNoError;
return result;
}
/**
*
* @update gess 3/25/98
* @param aToken -- token object to be put into content model
* @return 0 if all is well; non-zero is an error
*/
PRInt32 CRtfDTD::HandleControlWord(CToken* aToken){
PRInt32 result=kNoError;
return result;
}
/**
*
* @update gess 3/25/98
* @param aToken -- token object to be put into content model
* @return 0 if all is well; non-zero is an error
*/
PRInt32 CRtfDTD::HandleContent(CToken* aToken){
PRInt32 result=kNoError;
return result;
}
/**
*
* @update gess 3/25/98
* @param aToken -- token object to be put into content model
* @return 0 if all is well; non-zero is an error
*/
PRInt32 CRtfDTD::HandleToken(CToken* aToken) {
PRInt32 result=0;
if(aToken) {
eRTFTokenTypes theType=eRTFTokenTypes(aToken->GetTokenType());
switch(theType) {
case eRTFToken_group:
result=HandleGroup(aToken); break;
case eRTFToken_controlword:
result=HandleControlWord(aToken); break;
case eRTFToken_content:
result=HandleContent(aToken); break;
default:
break;
//everything else is just text or attributes of controls...
}
}//if
return result;
}
/***************************************************************
Heres's the RTFControlWord subclass...
***************************************************************/
CRTFControlWord::CRTFControlWord(char* aKey) : CToken(aKey), mArgument("") {
}
PRInt32 CRTFControlWord::GetTokenType() {
return eRTFToken_controlword;
}
PRInt32 CRTFControlWord::Consume(CScanner& aScanner){
PRInt32 result=aScanner.ReadWhile(mTextValue,gAlphaChars,PR_FALSE);
if(kNoError==result) {
//ok, now look for an option parameter...
PRUnichar ch;
result=aScanner.Peek(ch);
switch(ch) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case kMinus:
result=aScanner.ReadWhile(mArgument,gDigits,PR_FALSE);
break;
case kSpace:
default:
break;
}
}
if(kNoError==result)
result=aScanner.SkipWhitespace();
return result;
}
/***************************************************************
Heres's the RTFGroup subclass...
***************************************************************/
CRTFGroup::CRTFGroup(char* aKey,PRBool aStartGroup) : CToken(aKey) {
mStart=aStartGroup;
}
PRInt32 CRTFGroup::GetTokenType() {
return eRTFToken_group;
}
void CRTFGroup::SetGroupStart(PRBool aFlag){
mStart=aFlag;
}
PRBool CRTFGroup::IsGroupStart(){
return mStart;
}
PRInt32 CRTFGroup::Consume(CScanner& aScanner){
PRInt32 result=kNoError;
if(PR_FALSE==mStart)
result=aScanner.SkipWhitespace();
return result;
}
/***************************************************************
Heres's the RTFContent subclass...
***************************************************************/
CRTFContent::CRTFContent(PRUnichar* aKey) : CToken(aKey) {
}
PRInt32 CRTFContent::GetTokenType() {
return eRTFToken_content;
}
/**
* We're supposed to read text until we encounter one
* of the RTF control characters: \.{,}.
* @update gess7/9/98
* @param
* @return
*/
static nsString textTerminators("\\{}");
PRInt32 CRTFContent::Consume(CScanner& aScanner){
PRInt32 result=aScanner.ReadUntil(mTextValue,textTerminators,PR_FALSE);
return result;
}

View File

@@ -0,0 +1,339 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/**
* MODULE NOTES:
* @update gess 4/8/98
*
*
*/
#ifndef NS_NAVHTMLDTD__
#define NS_NAVHTMLDTD__
#include "nsIDTD.h"
#include "nsISupports.h"
#include "nsHTMLTokens.h"
#include "nshtmlpars.h"
#include "nsVoidArray.h"
#include "nsDeque.h"
#define NS_RTF_DTD_IID \
{0xa39c6bfc, 0x15f0, 0x11d2, \
{0x80, 0x41, 0x00, 0x10, 0x4b, 0x98, 0x3f, 0xd4}}
class nsIParserNode;
class nsParser;
enum eRTFTokenTypes {
eRTFToken_unknown=0,
eRTFToken_group, // '{'
eRTFToken_controlword, // '\'
eRTFToken_content, // contains all document content
//everything else is just text or attributes of controls...
eRTFToken_last //make sure this stays the last token...
};
enum eRTFTags {
eRTFCtrl_unknown=0,
eRTFCtrl_quote,
eRTFCtrl_star,
eRTFCtrl_linefeed,
eRTFCtrl_return,
eRTFCtrl_begincontrol,
eRTFCtrl_bold,
eRTFCtrl_bin,
eRTFCtrl_blue,
eRTFCtrl_cols,
eRTFCtrl_comment,
eRTFCtrl_italic,
eRTFCtrl_font,
eRTFCtrl_fonttable,
eRTFCtrl_green,
eRTFCtrl_bottommargin,
eRTFCtrl_leftmargin,
eRTFCtrl_rightmargin,
eRTFCtrl_topmargin,
eRTFCtrl_par,
eRTFCtrl_pard,
eRTFCtrl_plain,
eRTFCtrl_justified,
eRTFCtrl_fulljustified,
eRTFCtrl_leftjustified,
eRTFCtrl_rightjustified,
eRTFCtrl_rdoublequote,
eRTFCtrl_red,
eRTFCtrl_rtf,
eRTFCtrl_tab,
eRTFCtrl_title,
eRTFCtrl_underline,
eRTFCtrl_startgroup,
eRTFCtrl_endgroup,
eRTFCtrl_last //make sure this stays the last token...
};
/**
*
* @update gess7/8/98
* @param
* @return
*/
class CRTFControlWord : public CToken {
public:
CRTFControlWord(char* aKey);
virtual PRInt32 GetTokenType();
virtual PRInt32 Consume(CScanner& aScanner);
protected:
nsString mArgument;
};
/**
*
* @update gess7/8/98
* @param
* @return
*/
class CRTFGroup: public CToken {
public:
CRTFGroup(char* aKey,PRBool aStartGroup);
virtual PRInt32 GetTokenType();
virtual void SetGroupStart(PRBool aFlag);
virtual PRBool IsGroupStart();
virtual PRInt32 Consume(CScanner& aScanner);
protected:
PRBool mStart;
};
/**
*
* @update gess7/8/98
* @param
* @return
*/
class CRTFContent: public CToken {
public:
CRTFContent(PRUnichar* aValue);
virtual PRInt32 GetTokenType();
virtual PRInt32 Consume(CScanner& aScanner);
};
class CRtfDTD : public nsIDTD {
public:
NS_DECL_ISUPPORTS
/**
*
*
* @update gess 4/9/98
* @param
* @return
*/
CRtfDTD();
/**
*
*
* @update gess 4/9/98
* @param
* @return
*/
virtual ~CRtfDTD();
/**
* This method is called to determine if the given DTD can parse
* a document in a given source-type.
* NOTE: Parsing always assumes that the end result will involve
* storing the result in the main content model.
* @update gess6/24/98
* @param
* @return TRUE if this DTD can satisfy the request; FALSE otherwise.
*/
virtual PRBool CanParse(nsString& aContentType, PRInt32 aVersion);
/**
*
* @update gess7/7/98
* @param
* @return
*/
virtual eAutoDetectResult AutoDetectContentType(nsString& aBuffer,nsString& aType);
/**
*
* @update gess5/18/98
* @param
* @return
*/
virtual PRInt32 WillBuildModel(const char* aFilename=0);
/**
*
* @update gess5/18/98
* @param
* @return
*/
virtual PRInt32 DidBuildModel(PRInt32 anErrorCode);
/**
*
* @update gess 3/25/98
* @param aToken -- token object to be put into content model
* @return 0 if all is well; non-zero is an error
*/
virtual PRInt32 HandleGroup(CToken* aToken);
/**
*
* @update gess 3/25/98
* @param aToken -- token object to be put into content model
* @return 0 if all is well; non-zero is an error
*/
virtual PRInt32 HandleControlWord(CToken* aToken);
/**
*
* @update gess 3/25/98
* @param aToken -- token object to be put into content model
* @return 0 if all is well; non-zero is an error
*/
virtual PRInt32 HandleContent(CToken* aToken);
/**
*
* @update gess 3/25/98
* @param aToken -- token object to be put into content model
* @return 0 if all is well; non-zero is an error
*/
virtual PRInt32 HandleToken(CToken* aToken);
/**
*
*
* @update gess 3/25/98
* @param
* @return
*/
virtual void SetParser(nsIParser* aParser);
/**
* Cause the tokenizer to consume the next token, and
* return an error result.
*
* @update gess 3/25/98
* @param anError -- ref to error code
* @return new token or null
*/
virtual PRInt32 ConsumeControlWord(CToken*& aToken);
/**
* Cause the tokenizer to consume the next token, and
* return an error result.
*
* @update gess 3/25/98
* @param anError -- ref to error code
* @return new token or null
*/
virtual PRInt32 ConsumeGroupTag(CToken*& aToken,PRBool aStartTag);
/**
* Cause the tokenizer to consume the next token, and
* return an error result.
*
* @update gess 3/25/98
* @param anError -- ref to error code
* @return new token or null
*/
virtual PRInt32 ConsumeContent(PRUnichar aChar,CToken*& aToken);
/**
* Cause the tokenizer to consume the next token, and
* return an error result.
*
* @update gess 3/25/98
* @param anError -- ref to error code
* @return new token or null
*/
virtual PRInt32 ConsumeToken(CToken*& aToken);
/**
*
* @update gess5/18/98
* @param
* @return
*/
virtual void WillResumeParse(void);
/**
*
* @update gess5/18/98
* @param
* @return
*/
virtual void WillInterruptParse(void);
/**
* Select given content sink into parser for parser output
* @update gess5/11/98
* @param aSink is the new sink to be used by parser
* @return old sink, or NULL
*/
virtual nsIContentSink* SetContentSink(nsIContentSink* aSink);
/**
*
* @update jevering6/23/98
* @param
* @return
*/
virtual void SetDTDDebug(nsIDTDDebug * aDTDDebug);
/**
* This method is called to determine whether or not a tag
* of one type can contain a tag of another type.
*
* @update gess 3/25/98
* @param aParent -- int tag of parent container
* @param aChild -- int tag of child container
* @return PR_TRUE if parent can contain child
*/
virtual PRBool CanContain(PRInt32 aParent,PRInt32 aChild);
protected:
nsParser* mParser;
char* mFilename;
};
extern NS_HTMLPARS nsresult NS_NewRTF_DTD(nsIDTD** aInstancePtrResult);
#endif

View File

@@ -5,6 +5,7 @@
nshtmlpars.h
nsIContentSink.h
nsIHTMLContentSink.h
nsHTMLContentSinkStream.h
nsHTMLTokens.h
nsIParserNode.h
nsIParser.h
@@ -12,3 +13,4 @@ nsToken.h
nsIDTDDebug.h
nsIDTD.h
CNavDTD.h
CRTFDTD.h

View File

@@ -30,16 +30,21 @@ CPPSRCS = \
nsTokenHandler.cpp \
CNavDTD.cpp \
COtherDTD.cpp \
CRtfDTD.cpp \
nsValidDTD.cpp \
nsWellFormedDTD.cpp \
nsParser.cpp \
nsHTMLTokens.cpp \
nsHTMLTags.cpp \
prstrm.cpp \
nsHTMLContentSinkStream.cpp \
$(NULL)
EXPORTS = \
nshtmlpars.h \
nsIContentSink.h \
nsIHTMLContentSink.h \
nsHTMLContentSinkStream.h \
nsHTMLTokens.h \
nsIParserNode.h \
nsIParser.h \
@@ -48,6 +53,9 @@ EXPORTS = \
nsToken.h \
CNavDTD.h \
COtherDTD.h \
nsWellFormedDTD.h \
nsValidDTD.h \
CRTFDTD.h \
$(NULL)
EXTRA_EXPORTS = \

View File

@@ -26,6 +26,9 @@ REQUIRES=xpcom raptor netlib
CPPSRCS= \
CNavDTD.obj \
COtherDTD.obj \
CRTFDTD.obj \
nsWellFormedDTD.obj \
nsValidDTD.obj \
nsDTDDebug.obj \
nsHTMLContentSink.obj \
nsHTMLTags.obj \
@@ -35,12 +38,16 @@ CPPSRCS= \
nsScanner.obj \
nsToken.obj \
nsTokenHandler.obj \
nsHTMLContentSinkStream.obj \
prstrm.obj \
$(NULL)
CPP_OBJS= \
.\$(OBJDIR)\CNavDTD.obj \
.\$(OBJDIR)\CRTFDTD.obj \
.\$(OBJDIR)\COtherDTD.obj \
.\$(OBJDIR)\nsWellFormedDTD.obj \
.\$(OBJDIR)\nsValidDTD.obj \
.\$(OBJDIR)\nsDTDDebug.obj \
.\$(OBJDIR)\nsHTMLContentSink.obj \
.\$(OBJDIR)\nsHTMLTags.obj \
@@ -50,6 +57,7 @@ CPP_OBJS= \
.\$(OBJDIR)\nsScanner.obj \
.\$(OBJDIR)\nsToken.obj \
.\$(OBJDIR)\nsTokenHandler.obj \
.\$(OBJDIR)\nsHTMLContentSinkStream.obj \
.\$(OBJDIR)\prstrm.obj \
$(NULL)
@@ -57,6 +65,7 @@ EXPORTS= \
nshtmlpars.h \
nsIContentSink.h \
nsIHTMLContentSink.h \
nsHTMLContentSinkStream.h \
nsHTMLTokens.h \
nsIParserNode.h \
nsIParser.h \
@@ -64,6 +73,9 @@ EXPORTS= \
nsIDTDDebug.h \
nsIParserFilter.h \
CNavDTD.h \
nsWellFormedDTD.h \
nsValidDTD.h \
CRTFDTD.h \
COtherDTD.h \
nsIDTD.h \
$(NULL)

View File

@@ -0,0 +1,646 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/**
* MODULE NOTES:
* @update gess 4/1/98
*
* This file declares the concrete HTMLContentSink class.
* This class is used during the parsing process as the
* primary interface between the parser and the content
* model.
*/
#include "nsHTMLContentSinkStream.h"
#include "nsHTMLTokens.h"
#include <iostream.h>
#include "nsstring.h"
#include "nsParserTypes.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIContentSinkIID,NS_IHTMLCONTENTSINK_IID);
static NS_DEFINE_IID(kClassIID, NS_HTMLCONTENTSINK_STREAM_IID);
static char* gHeaderComment = "<!-- This page was created by the NGLayout output system. -->";
static char* gDocTypeHeader = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">";
const int gTabSize=2;
static char gBuffer[500];
/**
* This method gets called as part of our COM-like interfaces.
* Its purpose is to create an interface to parser object
* of some type.
*
* @update gess 4/8/98
* @param nsIID id of object to discover
* @param aInstancePtr ptr to newly discovered interface
* @return NS_xxx result code
*/
nsresult CHTMLContentSinkStream::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if(aIID.Equals(kISupportsIID)) { //do IUnknown...
*aInstancePtr = (nsIContentSink*)(this);
}
else if(aIID.Equals(kIContentSinkIID)) { //do IParser base class...
*aInstancePtr = (nsIContentSink*)(this);
}
else if(aIID.Equals(kClassIID)) { //do this class...
*aInstancePtr = (CHTMLContentSinkStream*)(this);
}
else {
*aInstancePtr=0;
return NS_NOINTERFACE;
}
((nsISupports*) *aInstancePtr)->AddRef();
return NS_OK;
}
NS_IMPL_ADDREF(CHTMLContentSinkStream)
NS_IMPL_RELEASE(CHTMLContentSinkStream)
/**
* This method is defined in nsIParser. It is used to
* cause the COM-like construction of an nsParser.
*
* @update gess 4/8/98
* @param nsIParser** ptr to newly instantiated parser
* @return NS_xxx error result
*/
NS_HTMLPARS nsresult NS_New_HTML_ContentSinkStream(CHTMLContentSinkStream** aInstancePtrResult) {
CHTMLContentSinkStream* it = new CHTMLContentSinkStream();
if (it == 0) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kClassIID, (void **) aInstancePtrResult);
}
/**
* Construct a content sink stream.
* @update gess7/7/98
* @param
* @return
*/
CHTMLContentSinkStream::CHTMLContentSinkStream() {
mOutput=&cout;
}
/**
* Construct a content sink stream.
* @update gess7/7/98
* @param
* @return
*/
CHTMLContentSinkStream::CHTMLContentSinkStream(ostream& aStream) {
mOutput=&aStream;
}
/**
*
* @update gess7/7/98
* @param
* @return
*/
CHTMLContentSinkStream::~CHTMLContentSinkStream() {
mOutput=0; //we don't own the stream we're given; just forget it.
}
/**
*
* @update gess7/7/98
* @param
* @return
*/
void CHTMLContentSinkStream::SetOutputStream(ostream& aStream) {
mOutput=&aStream;
}
/**
*
* @update gess7/7/98
* @param
* @return
*/
void WriteAttributes(const nsIParserNode& aNode,ostream& aStream) {
int theCount=aNode.GetAttributeCount();
if(theCount) {
int i=0;
for(i=0;i<theCount;i++){
const nsString& key=aNode.GetKeyAt(i);
key.ToCString(gBuffer,sizeof(gBuffer)-1);
aStream << " " << gBuffer << char(kEqual);
const nsString& value=aNode.GetValueAt(i);
value.ToCString(gBuffer,sizeof(gBuffer)-1);
aStream << gBuffer;
}
}
}
/**
*
* @update gess7/5/98
* @param
* @return
*/
void OpenTagWithAttributes(const char* theTag,const nsIParserNode& aNode,int tab,ostream& aStream,bool aNewline) {
int i=0;
for(i=0;i<tab*gTabSize;i++)
aStream << " ";
aStream << (char)kLessThan << theTag;
WriteAttributes(aNode,aStream);
aStream << (char)kGreaterThan;
if(aNewline)
aStream << endl;
}
/**
*
* @update gess7/5/98
* @param
* @return
*/
void OpenTag(const char* theTag,int tab,ostream& aStream,bool aNewline) {
int i=0;
for(i=0;i<tab*gTabSize;i++)
aStream << " ";
aStream << (char)kLessThan << theTag << (char)kGreaterThan;
if(aNewline)
aStream << endl;
}
/**
*
* @update gess7/5/98
* @param
* @return
*/
void CloseTag(const char* theTag,int tab,ostream& aStream) {
int i=0;
for(i=0;i<tab*gTabSize;i++)
aStream << " ";
aStream << (char)kLessThan << (char)kForwardSlash << theTag << (char)kGreaterThan << endl;
}
/**
*
* @update gess7/5/98
* @param
* @return
*/
void WritePair(eHTMLTags aTag,const nsString& theContent,int tab,ostream& aStream) {
const char* titleStr = GetTagName(aTag);
OpenTag(titleStr,tab,aStream,false);
theContent.ToCString(gBuffer,sizeof(gBuffer)-1);
aStream << gBuffer;
CloseTag(titleStr,0,aStream);
}
/**
*
* @update gess7/5/98
* @param
* @return
*/
void WriteSingleton(eHTMLTags aTag,const nsString& theContent,int tab,ostream& aStream) {
const char* titleStr = GetTagName(aTag);
OpenTag(titleStr,tab,aStream,false);
if(theContent.Length()) {
theContent.ToCString(gBuffer,sizeof(gBuffer)-1);
aStream << gBuffer;
}
aStream << endl;
}
/**
* This method gets called by the parser when it encounters
* a title tag and wants to set the document title in the sink.
*
* @update 4/1/98 gess
* @param nsString reference to new title value
* @return PR_TRUE if successful.
*/
PRBool CHTMLContentSinkStream::SetTitle(const nsString& aValue){
PRBool result=PR_FALSE;
if(mOutput) {
WritePair(eHTMLTag_title,aValue,1+mTabLevel,*mOutput);
}
return result;
}
/**
* This method is used to open the outer HTML container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
PRInt32 CHTMLContentSinkStream::OpenHTML(const nsIParserNode& aNode){
PRInt32 result=0;
mTabLevel++;
if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_html);
OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,true);
}
return result;
}
/**
* This method is used to close the outer HTML container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
PRInt32 CHTMLContentSinkStream::CloseHTML(const nsIParserNode& aNode){
PRInt32 result=0;
if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_html);
CloseTag(theTag,0,*mOutput);
}
mTabLevel--;
return result;
}
/**
* This method is used to open the only HEAD container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
PRInt32 CHTMLContentSinkStream::OpenHead(const nsIParserNode& aNode){
PRInt32 result=0;
mTabLevel++;
if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_head);
OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,true);
}
return result;
}
/**
* This method is used to close the only HEAD container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
PRInt32 CHTMLContentSinkStream::CloseHead(const nsIParserNode& aNode){
PRInt32 result=0;
if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_head);
CloseTag(theTag,mTabLevel,*mOutput);
}
mTabLevel--;
return result;
}
/**
* This method is used to open the main BODY container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
PRInt32 CHTMLContentSinkStream::OpenBody(const nsIParserNode& aNode){
PRInt32 result=0;
mTabLevel++;
if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_body);
OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,true);
}
return result;
}
/**
* This method is used to close the main BODY container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
PRInt32 CHTMLContentSinkStream::CloseBody(const nsIParserNode& aNode){
PRInt32 result=0;
if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_body);
CloseTag(theTag,mTabLevel,*mOutput);
}
mTabLevel--;
return result;
}
/**
* This method is used to open a new FORM container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
PRInt32 CHTMLContentSinkStream::OpenForm(const nsIParserNode& aNode){
PRInt32 result=0;
mTabLevel++;
if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_form);
OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,true);
}
return result;
}
/**
* This method is used to close the outer FORM container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
PRInt32 CHTMLContentSinkStream::CloseForm(const nsIParserNode& aNode){
PRInt32 result=0;
if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_form);
CloseTag(theTag,mTabLevel,*mOutput);
}
mTabLevel--;
return result;
}
/**
* This method is used to open the FRAMESET container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
PRInt32 CHTMLContentSinkStream::OpenFrameset(const nsIParserNode& aNode){
PRInt32 result=0;
mTabLevel++;
if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_frameset);
OpenTagWithAttributes(theTag,aNode,mTabLevel,*mOutput,true);
}
return result;
}
/**
* This method is used to close the FRAMESET container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
PRInt32 CHTMLContentSinkStream::CloseFrameset(const nsIParserNode& aNode){
PRInt32 result=0;
if(mOutput) {
const char* theTag= GetTagName(eHTMLTag_frameset);
CloseTag(theTag,mTabLevel,*mOutput);
}
mTabLevel--;
return result;
}
/**
* This method is used to a general container.
* This includes: OL,UL,DIR,SPAN,TABLE,H[1..6],etc.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
PRInt32 CHTMLContentSinkStream::OpenContainer(const nsIParserNode& aNode){
PRInt32 result=0;
mTabLevel++;
if(mOutput) {
eHTMLTags nodeType=(eHTMLTags)aNode.GetNodeType();
switch(nodeType) {
case eHTMLTag_html:
result=OpenHTML(aNode); break;
case eHTMLTag_body:
result=OpenBody(aNode); break;
case eHTMLTag_title:
{
const nsString& title=aNode.GetName();
result=SetTitle(title);
}
break;
case eHTMLTag_head:
result=OpenHead(aNode); break;
case eHTMLTag_style:
break;
case eHTMLTag_form:
result=OpenForm(aNode); break;
default:
//this is the hard one. You have to decode aNode manually.
{
const nsString& name=aNode.GetName();
const char* tagName= GetTagName(nodeType);
OpenTagWithAttributes(tagName,aNode,mTabLevel,*mOutput,true);
}
break;
}
}
return result;
}
/**
* This method is used to close a generic container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
PRInt32 CHTMLContentSinkStream::CloseContainer(const nsIParserNode& aNode){
PRInt32 result=0;
if(mOutput) {
eHTMLTags nodeType=(eHTMLTags)aNode.GetNodeType();
switch(nodeType) {
case eHTMLTag_html:
result=CloseHTML(aNode); break;
case eHTMLTag_style:
break;
case eHTMLTag_head:
result=CloseHead(aNode); break;
case eHTMLTag_body:
result=CloseBody(aNode); break;
case eHTMLTag_form:
result=CloseForm(aNode); break;
case eHTMLTag_title:
// result=SetTitle(aNode); break;
default:
{
const nsString& name=aNode.GetName();
const char* tagName= GetTagName(nodeType);
//(*mOutput) << endl;
CloseTag(tagName,mTabLevel,*mOutput);
}
break;
}
}
mTabLevel--;
return result;
}
/**
* This method is used to add a leaf to the currently
* open container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
PRInt32 CHTMLContentSinkStream::AddLeaf(const nsIParserNode& aNode){
PRInt32 result=0;
if(mOutput) {
eHTMLTags nodeType=(eHTMLTags)aNode.GetNodeType();
switch(nodeType) {
case eHTMLTag_hr:
case eHTMLTag_br:
{
nsAutoString empty;
WriteSingleton(nodeType,empty,1+mTabLevel,*mOutput);
}
break;
case eHTMLTag_style:
{
const nsString& skipped=aNode.GetSkippedContent();
WritePair(nodeType,skipped,1+mTabLevel,*mOutput);
}
break;
case eHTMLTag_newline:
case eHTMLTag_whitespace:
break;
default:
{
int i=0;
for(i=0;i<(1+mTabLevel)*gTabSize;i++)
(*mOutput) << " ";
const nsString& text=aNode.GetText();
text.ToCString(gBuffer,sizeof(gBuffer)-1);
(*mOutput) << gBuffer << endl;
}
}//switch
}
return result;
}
/**
* This method gets called when the parser begins the process
* of building the content model via the content sink.
*
* @update 5/7/98 gess
*/
void CHTMLContentSinkStream::WillBuildModel(void){
mTabLevel=-1;
if(mOutput) {
(*mOutput) << gHeaderComment << endl;
(*mOutput) << gDocTypeHeader << endl;
}
}
/**
* This method gets called when the parser concludes the process
* of building the content model via the content sink.
*
* @param aQualityLevel describes how well formed the doc was.
* 0=GOOD; 1=FAIR; 2=POOR;
* @update 5/7/98 gess
*/
void CHTMLContentSinkStream::DidBuildModel(PRInt32 aQualityLevel) {
}
/**
* This method gets called when the parser gets i/o blocked,
* and wants to notify the sink that it may be a while before
* more data is available.
*
* @update 5/7/98 gess
*/
void CHTMLContentSinkStream::WillInterrupt(void) {
}
/**
* This method gets called when the parser i/o gets unblocked,
* and we're about to start dumping content again to the sink.
*
* @update 5/7/98 gess
*/
void CHTMLContentSinkStream::WillResume(void) {
}

View File

@@ -0,0 +1,259 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/**
* MODULE NOTES:
* @update gess 4/1/98
*
* This file declares the concrete HTMLContentSink class.
* This class is used during the parsing process as the
* primary interface between the parser and the content
* model.
*/
#ifndef NS_HTMLCONTENTSINK_STREAM
#define NS_ITMLCONTENTSINK_STREAM
#include "nsIParserNode.h"
#include "nsIHTMLContentSink.h"
#include "nshtmlpars.h"
#define NS_HTMLCONTENTSINK_STREAM_IID \
{0xa39c6bff, 0x15f0, 0x11d2, \
{0x80, 0x41, 0x0, 0x10, 0x4b, 0x98, 0x3f, 0xd4}}
class ostream;
class CHTMLContentSinkStream : public nsIHTMLContentSink {
public:
NS_DECL_ISUPPORTS
/**
*
* @update gess7/7/98
* @param
* @return
*/
CHTMLContentSinkStream();
/**
*
* @update gess7/7/98
* @param
* @return
*/
CHTMLContentSinkStream(ostream& aStream);
/**
*
* @update gess7/7/98
* @param
* @return
*/
virtual ~CHTMLContentSinkStream();
/**
*
* @update gess7/7/98
* @param
* @return
*/
void SetOutputStream(ostream& aStream);
/**
* This method gets called by the parser when it encounters
* a title tag and wants to set the document title in the sink.
*
* @update 4/1/98 gess
* @param nsString reference to new title value
* @return PR_TRUE if successful.
*/
virtual PRBool SetTitle(const nsString& aValue);
/**
* This method is used to open the outer HTML container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
virtual PRInt32 OpenHTML(const nsIParserNode& aNode);
/**
* This method is used to close the outer HTML container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
virtual PRInt32 CloseHTML(const nsIParserNode& aNode);
/**
* This method is used to open the only HEAD container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
virtual PRInt32 OpenHead(const nsIParserNode& aNode);
/**
* This method is used to close the only HEAD container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
virtual PRInt32 CloseHead(const nsIParserNode& aNode);
/**
* This method is used to open the main BODY container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
virtual PRInt32 OpenBody(const nsIParserNode& aNode);
/**
* This method is used to close the main BODY container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
virtual PRInt32 CloseBody(const nsIParserNode& aNode);
/**
* This method is used to open a new FORM container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
virtual PRInt32 OpenForm(const nsIParserNode& aNode);
/**
* This method is used to close the outer FORM container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
virtual PRInt32 CloseForm(const nsIParserNode& aNode);
/**
* This method is used to open the FRAMESET container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
virtual PRInt32 OpenFrameset(const nsIParserNode& aNode);
/**
* This method is used to close the FRAMESET container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
virtual PRInt32 CloseFrameset(const nsIParserNode& aNode);
/**
* This method is used to a general container.
* This includes: OL,UL,DIR,SPAN,TABLE,H[1..6],etc.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
virtual PRInt32 OpenContainer(const nsIParserNode& aNode);
/**
* This method is used to close a generic container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
virtual PRInt32 CloseContainer(const nsIParserNode& aNode);
/**
* This method is used to add a leaf to the currently
* open container.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
virtual PRInt32 AddLeaf(const nsIParserNode& aNode);
/**
* This method gets called when the parser begins the process
* of building the content model via the content sink.
*
* @update 5/7/98 gess
*/
virtual void WillBuildModel(void);
/**
* This method gets called when the parser concludes the process
* of building the content model via the content sink.
*
* @param aQualityLevel describes how well formed the doc was.
* 0=GOOD; 1=FAIR; 2=POOR;
* @update 5/7/98 gess
*/
virtual void DidBuildModel(PRInt32 aQualityLevel);
/**
* This method gets called when the parser gets i/o blocked,
* and wants to notify the sink that it may be a while before
* more data is available.
*
* @update 5/7/98 gess
*/
virtual void WillInterrupt(void);
/**
* This method gets called when the parser i/o gets unblocked,
* and we're about to start dumping content again to the sink.
*
* @update 5/7/98 gess
*/
virtual void WillResume(void);
protected:
ostream* mOutput;
int mTabLevel;
};
extern NS_HTMLPARS nsresult NS_New_HTML_ContentSinkStream(CHTMLContentSinkStream** aInstancePtrResult);
#endif

View File

@@ -247,7 +247,7 @@ PRInt32 CStartToken::Consume(PRUnichar aChar, CScanner& aScanner) {
//and see if the next char is ">". If so, we have a complete
//tag without attributes.
if(kNoError==result) {
result=aScanner.SkipWhite();
result=aScanner.SkipWhitespace();
if(kNoError==result) {
result=aScanner.GetChar(aChar);
if(kNoError==result) {
@@ -678,7 +678,7 @@ PRInt32 ConsumeAttributeValueText(PRUnichar aChar,nsString& aString,CScanner& aS
*/
PRInt32 CAttributeToken::Consume(PRUnichar aChar, CScanner& aScanner) {
aScanner.SkipWhite(); //skip leading whitespace
aScanner.SkipWhitespace(); //skip leading whitespace
PRInt32 result=aScanner.Peek(aChar);
if(kNoError==result) {
if(kQuote==aChar) { //if you're here, handle quoted key...
@@ -703,12 +703,12 @@ PRInt32 CAttributeToken::Consume(PRUnichar aChar, CScanner& aScanner) {
}
//now it's time to Consume the (optional) value...
if(!(result=aScanner.SkipWhite())) {
if(!(result=aScanner.SkipWhitespace())) {
if(!(result=aScanner.Peek(aChar))) {
if(kEqual==aChar){
result=aScanner.GetChar(aChar); //skip the equal sign...
if(kNoError==result) {
result=aScanner.SkipWhite(); //now skip any intervening whitespace
result=aScanner.SkipWhitespace(); //now skip any intervening whitespace
if(kNoError==result) {
result=aScanner.GetChar(aChar); //and grab the next char.
if(kNoError==result) {
@@ -722,7 +722,7 @@ PRInt32 CAttributeToken::Consume(PRUnichar aChar, CScanner& aScanner) {
}
}//if
if(kNoError==result)
result=aScanner.SkipWhite();
result=aScanner.SkipWhitespace();
}//if
}//if
}//if

View File

@@ -60,15 +60,6 @@ class nsIContentSink : public nsISupports {
*/
virtual PRInt32 CloseContainer(const nsIParserNode& aNode) = 0;
/**
* This method gets called by the parser when a the
* topmost container in the content sink needs to be closed.
*
* @update 4/1/98 gess
* @return PR_TRUE if successful.
*/
virtual PRInt32 CloseTopmostContainer() = 0;
/**
* This gets called by the parser when you want to add
* a leaf node to the current container in the content

View File

@@ -41,7 +41,6 @@ class nsIDTDDebug;
class nsIURL;
class nsString;
enum eProcessType {eParsing, eConverting};
enum eAutoDetectResult {eUnknownDetect, eValidDetect, eInvalidDetect};
class nsIDTD : public nsISupports {
@@ -76,12 +75,23 @@ class nsIDTD : public nsISupports {
virtual nsIContentSink* SetContentSink(nsIContentSink* aSink)=0;
/**
*
* This method is called to determine if the given DTD can parse
* a document in a given source-type.
* NOTE: Parsing always assumes that the end result will involve
* storing the result in the main content model.
* @update gess6/24/98
* @param
* @return TRUE if this DTD can satisfy the request; FALSE otherwise.
*/
virtual PRBool CanParse(nsString& aContentType, PRInt32 aVersion)=0;
/**
*
* @update gess7/7/98
* @param
* @return
*/
virtual PRBool IsCapableOf(eProcessType aProcessType, nsString& aContentType, PRInt32 aVersion)=0;
virtual eAutoDetectResult AutoDetectContentType(nsString& aBuffer,nsString& aType)=0;
/**
*
@@ -136,13 +146,16 @@ class nsIDTD : public nsISupports {
virtual void WillInterruptParse(void)=0;
/**
*
* @update jevering 6/18/98
* @param aParent parent tag
* @param aChild child tag
* @return PR_TRUE if valid container
* This method is called to determine whether or not a tag
* of one type can contain a tag of another type.
*
* @update gess 3/25/98
* @param aParent -- int tag of parent container
* @param aChild -- int tag of child container
* @return PR_TRUE if parent can contain child
*/
virtual PRBool CanContain(PRInt32 aParent, PRInt32 aChild) = 0;
virtual PRBool CanContain(PRInt32 aParent,PRInt32 aChild)=0;
/**
*

View File

@@ -62,7 +62,7 @@
*/
#ifndef NS_IHTMLCONTENTSINK
#define NS_ITMLCONTENTSINK
#define NS_IHTMLCONTENTSINK
#include "nsIParserNode.h"
#include "nsIContentSink.h"
@@ -194,16 +194,6 @@ class nsIHTMLContentSink : public nsIContentSink {
*/
virtual PRInt32 CloseContainer(const nsIParserNode& aNode)=0;
/**
* This method is used to close the topmost container, regardless
* of the type.
*
* @update 4/1/98 gess
* @param nsIParserNode reference to parser node interface
* @return PR_TRUE if successful.
*/
virtual PRInt32 CloseTopmostContainer()=0;
/**
* This method is used to add a leaf to the currently
* open container.

View File

@@ -35,6 +35,7 @@ class nsString;
class CToken;
class nsIURL;
class nsIDTDDebug;
class fstream;
/**
* This class defines the iparser interface. This XPCOM
@@ -49,7 +50,7 @@ class nsIParser : public nsISupports {
virtual nsIContentSink* SetContentSink(nsIContentSink* aContentSink)=0;
virtual eAutoDetectResult AutoDetectContentType(nsString& aBuffer)=0;
virtual eAutoDetectResult AutoDetectContentType(nsString& aBuffer,nsString& aType)=0;
/**
* Cause the tokenizer to consume the next token, and
@@ -61,26 +62,15 @@ class nsIParser : public nsISupports {
*/
virtual PRInt32 ConsumeToken(CToken*& aToken)=0;
virtual PRInt32 BeginParse(nsIURL* aURL,
nsIStreamObserver* aListener = nsnull,
nsIDTDDebug * aDTDDebug = 0) = 0;
/******************************************************************************************
* Parse methods always begin with an input source, and perform conversions
* until you wind up with HTML in your actual content model.
******************************************************************************************/
virtual PRInt32 Parse(nsIURL* aURL,nsIStreamObserver* aListener = nsnull,nsIDTDDebug * aDTDDebug = 0) = 0;
virtual PRInt32 Parse(const char* aFilename)=0;
virtual PRInt32 Parse(fstream& aStream)=0;
virtual PRInt32 Parse(nsString& anHTMLString,PRBool appendTokens)=0;
/******************************************************************************************
* Convert methods start input source (of known or unknown form), and perform conversions
* until you wind up with a <i>stream</i> in your target form.
* The internal content model is never effected.
******************************************************************************************/
virtual PRInt32 Convert(nsIURL* aURL,char* aSourceForm,char* aTargetForm,nsIStreamListener* aListener) = 0;
virtual PRInt32 Convert(const char* aFilename,char* aSourceForm,char* aTargetForm)=0;
virtual PRInt32 Convert(nsString& anHTMLString,char* aSourceForm,char* aTargetForm,PRBool appendTokens)=0;
virtual PRInt32 ResumeParse(void)=0;

View File

@@ -31,6 +31,13 @@
#include "nsIDTDDebug.h"
#include "nshtmlpars.h"
#define rickgdebug 1
#ifdef rickgdebug
#include "CRtfDTD.h"
#include "nsWellFormedDTD.h"
#endif
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kClassIID, NS_PARSER_IID);
static NS_DEFINE_IID(kIParserIID, NS_IPARSER_IID);
@@ -136,7 +143,8 @@ CSharedParserObjects gSharedParserObjects;
*/
nsParser::nsParser() :
mTokenDeque(gTokenDeallocator),
mContentType()
mSourceType(),
mTargetType()
{
NS_INIT_REFCNT();
mDTDDebug = 0;
@@ -270,6 +278,15 @@ nsIContentSink* nsParser::SetContentSink(nsIContentSink* aSink) {
* @return nothing.
*/
void nsParser::RegisterDTD(nsIDTD* aDTD){
#ifdef rickgdebug
nsIDTD* rv=0;
NS_NewRTF_DTD(&rv);
gSharedParserObjects.RegisterDTD(rv);
NS_NewWellFormed_DTD(&rv);
gSharedParserObjects.RegisterDTD(rv);
#endif
gSharedParserObjects.RegisterDTD(aDTD);
}
@@ -309,28 +326,31 @@ eParseMode DetermineParseMode() {
* @param
* @return
*/
PRBool FindSuitableDTD(eProcessType aProcessType,eParseMode aMode,nsString& aContentType, nsIDTD*& aDefaultDTD) {
PRBool result=PR_FALSE;
PRBool FindSuitableDTD( eParseMode aMode,
nsString& aSourceType,
nsString& aTargetType,
nsIDTD*& aDefaultDTD) {
if(aDefaultDTD) {
if(aDefaultDTD->IsCapableOf(aProcessType,aContentType,0)) {
result=PR_TRUE;
}
}
else {
nsDequeIterator b=gSharedParserObjects.mDTDDeque.Begin();
nsDequeIterator e=gSharedParserObjects.mDTDDeque.End();
//Let's start by tring the defaultDTD, if one exists...
if(aDefaultDTD && (aDefaultDTD->CanParse(aSourceType,0)))
return PR_TRUE;
while(b<e){
nsIDTD* theDTD=(nsIDTD*)b.GetCurrent();
if(theDTD && theDTD->IsCapableOf(aProcessType,aContentType,0)) {
PRBool result=PR_FALSE;
nsDequeIterator b=gSharedParserObjects.mDTDDeque.Begin();
nsDequeIterator e=gSharedParserObjects.mDTDDeque.End();
while(b<e){
nsIDTD* theDTD=(nsIDTD*)b.GetCurrent();
if(theDTD) {
result=theDTD->CanParse(aSourceType,0);
if(result){
aDefaultDTD=theDTD;
result=PR_TRUE;
break;
}
++b;
}
}
b++;
}
return result;
}
@@ -341,22 +361,30 @@ PRBool FindSuitableDTD(eProcessType aProcessType,eParseMode aMode,nsString& aCon
*
* @update gess6/22/98
* @param aBuffer -- nsString containing sample data to be analyzed.
* @param aType -- may hold typename given from netlib; will hold result given by DTD's.
* @return auto-detect result: eValid, eInvalid, eUnknown
*/
eAutoDetectResult nsParser::AutoDetectContentType(nsString& aBuffer) {
eAutoDetectResult nsParser::AutoDetectContentType(nsString& aBuffer,nsString& aType) {
//The process:
// You should go out and ask each DTD if they
// recognize the content in the scanner.
// Somebody should say yes, or we can't continue.
//This method may change mContentType and mDTD.
//This method may change mSourceType and mDTD.
//It absolutely changes mAutoDetectStatus
nsDequeIterator b=gSharedParserObjects.mDTDDeque.Begin();
nsDequeIterator e=gSharedParserObjects.mDTDDeque.End();
mAutoDetectStatus=eUnknownDetect;
if(PR_TRUE==mContentType.Equals(kHTMLTextContentType)) {
mAutoDetectStatus=eValidDetect;
}
while((b<e) && (eUnknownDetect==mAutoDetectStatus)){
nsIDTD* theDTD=(nsIDTD*)b.GetCurrent();
if(theDTD) {
mAutoDetectStatus=theDTD->AutoDetectContentType(aBuffer,aType);
}
b++;
}
return mAutoDetectStatus;
}
@@ -373,13 +401,13 @@ eAutoDetectResult nsParser::AutoDetectContentType(nsString& aBuffer) {
* @param
* @return
*/
PRInt32 nsParser::WillBuildModel(eProcessType aProcessType, const char* aFilename){
PRInt32 nsParser::WillBuildModel(const char* aFilename){
mMajorIteration=-1;
mMinorIteration=-1;
mParseMode=DetermineParseMode();
if(PR_TRUE==FindSuitableDTD(aProcessType,mParseMode,mContentType,mDTD)) {
if(PR_TRUE==FindSuitableDTD(mParseMode,mSourceType,mTargetType,mDTD)) {
mDTD->SetParser(this);
mDTD->SetContentSink(mSink);
mDTD->WillBuildModel(aFilename);
@@ -439,11 +467,12 @@ PRBool nsParser::Parse(const char* aFilename){
if(aFilename) {
//ok, time to create our tokenizer and begin the process
mTargetType=kHTMLTextContentType;
mScanner=new CScanner(aFilename,mParseMode);
if(mScanner) {
mScanner->Eof();
if(eValidDetect==AutoDetectContentType(mScanner->GetBuffer())) {
WillBuildModel(eParsing,aFilename);
if(eValidDetect==AutoDetectContentType(mScanner->GetBuffer(),mSourceType)) {
WillBuildModel(aFilename);
status=ResumeParse();
DidBuildModel(status);
}
@@ -452,6 +481,18 @@ PRBool nsParser::Parse(const char* aFilename){
return status;
}
/**
* Cause parser to parse input from given stream
* @update gess5/11/98
* @param aStream is the i/o source
* @return TRUE if all went well -- FALSE otherwise
*/
PRInt32 nsParser::Parse(fstream& aStream){
PRInt32 result=0;
return result;
}
/**
* This is the main controlling routine in the parsing process.
* Note that it may get called multiple times for the same scanner,
@@ -467,54 +508,6 @@ PRBool nsParser::Parse(const char* aFilename){
* @return PR_TRUE if parse succeeded, PR_FALSE otherwise.
*/
PRInt32 nsParser::Parse(nsIURL* aURL,nsIStreamObserver* aListener, nsIDTDDebug * aDTDDebug) {
PRInt32 status;
status = BeginParse(aURL, aListener, aDTDDebug);
if (NS_OK == status) {
status=mURL->Open(this);
}
return status;
}
/**
* Call this method if all you want to do is parse 1 string full of HTML text.
*
* @update gess5/11/98
* @param anHTMLString contains a string-full of real HTML
* @param appendTokens tells us whether we should insert tokens inline, or append them.
* @return TRUE if all went well -- FALSE otherwise
*/
PRInt32 nsParser::Parse(nsString& aSourceBuffer,PRBool appendTokens){
PRInt32 result=kNoError;
mScanner=new CScanner();
mScanner->Append(aSourceBuffer);
if(eValidDetect==AutoDetectContentType(aSourceBuffer)) {
WillBuildModel(eParsing,"from-string");
result=ResumeParse();
DidBuildModel(result);
}
return result;
}
/**
* This is the main controlling routine in the parsing process.
* Note that it may get called multiple times for the same scanner,
* since this is a pushed based system, and all the tokens may
* not have been consumed by the scanner during a given invocation
* of this method.
*
* NOTE: We don't call willbuildmodel here, because it will happen
* as a result of calling OnStartBinding later on.
*
* @update gess 3/25/98
* @param aFilename -- const char* containing file to be parsed.
* @return PR_TRUE if parse succeeded, PR_FALSE otherwise.
*/
PRInt32 nsParser::BeginParse(nsIURL* aURL,nsIStreamObserver* aListener, nsIDTDDebug * aDTDDebug) {
NS_PRECONDITION(0!=aURL,kNullURL);
PRInt32 status=kBadURL;
@@ -537,36 +530,27 @@ PRInt32 nsParser::BeginParse(nsIURL* aURL,nsIStreamObserver* aListener, nsIDTDDe
return status;
}
/**
*
* @update gess6/23/98
* @param
* @return
*/
PRInt32 nsParser::Convert(nsIURL* aURL,char* aSourceForm,char* aTargetForm,nsIStreamListener* aListener) {
PRInt32 result=0;
return result;
}
/**
*
* @update gess6/23/98
* @param
* @return
* Call this method if all you want to do is parse 1 string full of HTML text.
*
* @update gess5/11/98
* @param anHTMLString contains a string-full of real HTML
* @param appendTokens tells us whether we should insert tokens inline, or append them.
* @return TRUE if all went well -- FALSE otherwise
*/
PRInt32 nsParser::Convert(const char* aFilename,char* aSourceForm,char* aTargetForm) {
PRInt32 result=0;
return result;
}
PRInt32 nsParser::Parse(nsString& aSourceBuffer,PRBool appendTokens){
PRInt32 result=kNoError;
/**
*
* @update gess6/23/98
* @param
* @return
*/
PRInt32 nsParser::Convert(nsString& anHTMLString,char* aSourceForm,char* aTargetForm,PRBool appendTokens){
PRInt32 result=0;
mTargetType=kHTMLTextContentType;
mScanner=new CScanner();
mScanner->Append(aSourceBuffer);
if(eValidDetect==AutoDetectContentType(aSourceBuffer,mSourceType)) {
WillBuildModel("");
result=ResumeParse();
DidBuildModel(result);
}
return result;
}
@@ -722,14 +706,14 @@ nsParser::OnProgress(PRInt32 aProgress, PRInt32 aProgressMax,
* @param
* @return
*/
nsresult nsParser::OnStartBinding(const char *aContentType){
nsresult nsParser::OnStartBinding(const char *aSourceType){
if (nsnull != mObserver) {
mObserver->OnStartBinding(aContentType);
mObserver->OnStartBinding(aSourceType);
}
mAutoDetectStatus=eUnknownDetect;
mDTD=0;
mContentType=aContentType;
mSourceType=aSourceType;
return kNoError;
}
@@ -773,8 +757,8 @@ nsresult nsParser::OnDataAvailable(nsIInputStream *pIStream, PRInt32 length){
mScanner->Append(mTransferBuffer,len);
if(eUnknownDetect==mAutoDetectStatus) {
if(eValidDetect==AutoDetectContentType(mScanner->GetBuffer())) {
nsresult result=WillBuildModel(eParsing,mURL->GetSpec());
if(eValidDetect==AutoDetectContentType(mScanner->GetBuffer(),mSourceType)) {
nsresult result=WillBuildModel(mURL->GetSpec());
} //if
}
} //if

View File

@@ -74,7 +74,7 @@ class nsIDTD;
class nsIDTDDebug;
class CScanner;
class nsIParserFilter;
class fstream;
class nsParser : public nsIParser, public nsIStreamListener {
@@ -118,10 +118,6 @@ friend class CTokenHandler;
*/
virtual CScanner* GetScanner(void);
virtual PRInt32 BeginParse(nsIURL* aURL,
nsIStreamObserver* aListener,
nsIDTDDebug * aDTDDebug = 0);
/**
* Cause parser to parse input from given URL in given mode
* @update gess5/11/98
@@ -136,11 +132,18 @@ friend class CTokenHandler;
* Cause parser to parse input from given file in given mode
* @update gess5/11/98
* @param aFilename is a path for file document
* @param aMode is the desired parser mode (Nav, other, etc.)
* @return TRUE if all went well -- FALSE otherwise
*/
virtual PRInt32 Parse(const char* aFilename);
/**
* Cause parser to parse input from given stream
* @update gess5/11/98
* @param aStream is the i/o source
* @return TRUE if all went well -- FALSE otherwise
*/
virtual PRInt32 Parse(fstream& aStream);
/**
* @update gess5/11/98
* @param anHTMLString contains a string-full of real HTML
@@ -149,15 +152,6 @@ friend class CTokenHandler;
*/
virtual PRInt32 Parse(nsString& anHTMLString,PRBool appendTokens);
/******************************************************************************************
* Convert methods start input source (of known or unknown form), and perform conversions
* until you wind up with a <i>stream</i> in your target form.
* The internal content model is never effected.
******************************************************************************************/
virtual PRInt32 Convert(nsIURL* aURL,char* aSourceForm, char* aTargetForm,nsIStreamListener* aListener);
virtual PRInt32 Convert(const char* aFilename,char* aSourceForm,char* aTargetForm);
virtual PRInt32 Convert(nsString& anHTMLString,char* aSourceForm,char* aTargetForm,PRBool appendTokens);
/**
* This method gets called (automatically) during incremental parsing
* @update gess5/11/98
@@ -214,7 +208,7 @@ protected:
* @param
* @return
*/
PRInt32 WillBuildModel(eProcessType theProcessType=eParsing,const char* aFilename=0);
PRInt32 WillBuildModel(const char* aFilename=0);
/**
*
@@ -309,7 +303,7 @@ private:
* @param
* @return TRUE if we figured it out.
*/
eAutoDetectResult AutoDetectContentType(nsString& aBuffer);
eAutoDetectResult AutoDetectContentType(nsString& aBuffer,nsString& aType);
protected:
@@ -335,7 +329,8 @@ protected:
CScanner* mScanner;
nsIURL* mURL;
nsIDTDDebug* mDTDDebug;
nsString mContentType;
nsString mSourceType;
nsString mTargetType;
eAutoDetectResult mAutoDetectStatus;
};

View File

@@ -42,40 +42,41 @@ enum eParseMode {
};
const PRInt32 kEOF = 1000000L;
const PRInt32 kUnknownError = -1000;
const PRInt32 kCantPropagate = -6;
const PRInt32 kContextMismatch = -5;
const PRInt32 kBadFilename = -4;
const PRInt32 kBadURL = -3;
const PRInt32 kInterrupted = -2;
const PRInt32 kNotFound = -1;
const PRInt32 kNoError = 0;
const PRInt32 kEOF = 1000000L;
const PRInt32 kUnknownError = -1000;
const PRInt32 kCantPropagate = -6;
const PRInt32 kContextMismatch = -5;
const PRInt32 kBadFilename = -4;
const PRInt32 kBadURL = -3;
const PRInt32 kInterrupted = -2;
const PRInt32 kNotFound = -1;
const PRInt32 kNoError = 0;
const PRUint32 kNewLine = '\n';
const PRUint32 kCR = '\r';
const PRUint32 kLF = '\n';
const PRUint32 kTab = '\t';
const PRUint32 kSpace = ' ';
const PRUint32 kQuote = '"';
const PRUint32 kApostrophe = '\'';
const PRUint32 kLessThan = '<';
const PRUint32 kGreaterThan = '>';
const PRUint32 kAmpersand = '&';
const PRUint32 kForwardSlash = '/';
const PRUint32 kEqual = '=';
const PRUint32 kMinus = '-';
const PRUint32 kPlus = '+';
const PRUint32 kExclamation = '!';
const PRUint32 kSemicolon = ';';
const PRUint32 kHashsign = '#';
const PRUint32 kAsterisk = '*';
const PRUint32 kUnderbar = '_';
const PRUint32 kComma = ',';
const PRUint32 kLeftParen = '(';
const PRUint32 kRightParen = ')';
const PRUint32 kLeftBrace = '{';
const PRUint32 kRightBrace = '}';
const PRUint32 kNewLine = '\n';
const PRUint32 kCR = '\r';
const PRUint32 kLF = '\n';
const PRUint32 kTab = '\t';
const PRUint32 kSpace = ' ';
const PRUint32 kQuote = '"';
const PRUint32 kApostrophe = '\'';
const PRUint32 kLessThan = '<';
const PRUint32 kGreaterThan = '>';
const PRUint32 kAmpersand = '&';
const PRUint32 kForwardSlash = '/';
const PRUint32 kBackSlash = '\\';
const PRUint32 kEqual = '=';
const PRUint32 kMinus = '-';
const PRUint32 kPlus = '+';
const PRUint32 kExclamation = '!';
const PRUint32 kSemicolon = ';';
const PRUint32 kHashsign = '#';
const PRUint32 kAsterisk = '*';
const PRUint32 kUnderbar = '_';
const PRUint32 kComma = ',';
const PRUint32 kLeftParen = '(';
const PRUint32 kRightParen = ')';
const PRUint32 kLeftBrace = '{';
const PRUint32 kRightBrace = '}';
#endif

View File

@@ -47,6 +47,7 @@ CScanner::CScanner(eParseMode aMode) : mBuffer("") {
mNetStream=0;
mFileStream=0;
mIncremental=PR_TRUE;
mOwnsStream=PR_TRUE;
}
/**
@@ -64,6 +65,7 @@ CScanner::CScanner(const char* aFilename,eParseMode aMode) : mBuffer("") {
mParseMode=aMode;
mNetStream=0;
mIncremental=PR_FALSE;
mOwnsStream=PR_TRUE;
#if defined(XP_UNIX) && (defined(IRIX) || defined(MKLINUX))
/* XXX: IRIX does not support ios::binary */
mFileStream=new fstream(aFilename,ios::in);
@@ -72,6 +74,24 @@ CScanner::CScanner(const char* aFilename,eParseMode aMode) : mBuffer("") {
#endif
}
/**
* Use this constructor if you want i/o to be file based.
*
* @update gess 5/12/98
* @param aMode represents the parser mode (nav, other)
* @return
*/
CScanner::CScanner(fstream& aStream,eParseMode aMode) : mBuffer("") {
mOffset=0;
mMarkPos=-1;
mTotalRead=0;
mParseMode=aMode;
mNetStream=0;
mIncremental=PR_FALSE;
mOwnsStream=PR_FALSE;
mFileStream=&aStream;
}
/**
* Use this constructor if you want i/o to be based on a
* non-incremental netstream.
@@ -91,6 +111,7 @@ CScanner::CScanner(nsIURL* aURL,eParseMode aMode) : mBuffer("") {
mIncremental=PR_FALSE;
mNetStream=aURL->Open(&error);
gURLRef=aURL->GetSpec();
mOwnsStream=PR_FALSE;
}
@@ -104,7 +125,8 @@ CScanner::CScanner(nsIURL* aURL,eParseMode aMode) : mBuffer("") {
CScanner::~CScanner() {
if(mFileStream) {
mFileStream->close();
delete mFileStream;
if(mOwnsStream)
delete mFileStream;
}
else if(mNetStream) {
mNetStream->Close();
@@ -354,7 +376,7 @@ PRInt32 CScanner::PutBack(PRUnichar aChar) {
* @param
* @return error status
*/
PRInt32 CScanner::SkipWhite(void) {
PRInt32 CScanner::SkipWhitespace(void) {
static nsAutoString chars(" \n\r\t");
return SkipOver(chars);
}

View File

@@ -25,7 +25,7 @@
* how to consume characters out of an (internal) stream.
* This class also offers a series of utility methods
* that most tokenizers want, such as readUntil(),
* readWhile() and SkipWhite().
* readWhile() and SkipWhitespace().
*/
@@ -73,6 +73,16 @@ class CScanner {
*/
CScanner(const char* aFilename,eParseMode aMode=eParseMode_navigator);
/**
* Use this constructor if you want i/o to be stream based.
*
* @update gess 5/12/98
* @param aMode represents the parser mode (nav, other)
* @return
*/
CScanner(fstream& aStream,eParseMode aMode=eParseMode_navigator);
~CScanner();
/**
@@ -136,7 +146,7 @@ class CScanner {
* @update gess 3/25/98
* @return error status
*/
PRInt32 SkipWhite(void);
PRInt32 SkipWhitespace(void);
/**
* Determine if the scanner has reached EOF.
@@ -265,6 +275,7 @@ class CScanner {
PRInt32 mTotalRead;
eParseMode mParseMode;
PRBool mIncremental;
PRBool mOwnsStream;
};
#endif

View File

@@ -0,0 +1,334 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/**
* MODULE NOTES:
* @update gess 4/8/98
*
*
*/
/**
* TRANSIENT STYLE-HANDLING NOTES:
* @update gess 6/15/98
*
* ...add comments here about transient style stack.
*
*/
#include "nsIDTDDebug.h"
#include "nsValidDTD.h"
#include "nsCRT.h"
#include "nsParser.h"
#include "nsScanner.h"
#include "nsParserTypes.h"
#include "nsTokenHandler.h"
#include "prenv.h" //this is here for debug reasons...
#include "prtypes.h" //this is here for debug reasons...
#include "prio.h"
#include "plstr.h"
#ifdef XP_PC
#include <direct.h> //this is here for debug reasons...
#endif
#include "prmem.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIDTDIID, NS_IDTD_IID);
static NS_DEFINE_IID(kClassIID, NS_VALID_DTD_IID);
static const char* kNullURL = "Error: Null URL given";
static const char* kNullFilename= "Error: Null filename given";
static const char* kNullTokenizer = "Error: Unable to construct tokenizer";
static const char* kNullToken = "Error: Null token given";
static const char* kInvalidTagStackPos = "Error: invalid tag stack position";
static const char* kRTFTextContentType = "text/xml";
static nsAutoString gEmpty;
/**
* This method gets called as part of our COM-like interfaces.
* Its purpose is to create an interface to parser object
* of some type.
*
* @update gess 4/8/98
* @param nsIID id of object to discover
* @param aInstancePtr ptr to newly discovered interface
* @return NS_xxx result code
*/
nsresult CValidDTD::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if(aIID.Equals(kISupportsIID)) { //do IUnknown...
*aInstancePtr = (nsIDTD*)(this);
}
else if(aIID.Equals(kIDTDIID)) { //do IParser base class...
*aInstancePtr = (nsIDTD*)(this);
}
else if(aIID.Equals(kClassIID)) { //do this class...
*aInstancePtr = (CValidDTD*)(this);
}
else {
*aInstancePtr=0;
return NS_NOINTERFACE;
}
((nsISupports*) *aInstancePtr)->AddRef();
return NS_OK;
}
/**
* This method is defined in nsIParser. It is used to
* cause the COM-like construction of an nsParser.
*
* @update gess 4/8/98
* @param nsIParser** ptr to newly instantiated parser
* @return NS_xxx error result
*/
NS_HTMLPARS nsresult NS_NewValid_DTD(nsIDTD** aInstancePtrResult)
{
CValidDTD* it = new CValidDTD();
if (it == 0) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kClassIID, (void **) aInstancePtrResult);
}
NS_IMPL_ADDREF(CValidDTD)
NS_IMPL_RELEASE(CValidDTD)
/**
* Default constructor
*
* @update gess 4/9/98
* @param
* @return
*/
CValidDTD::CValidDTD() : nsIDTD() {
NS_INIT_REFCNT();
mParser=0;
mFilename=0;
}
/**
* Default destructor
*
* @update gess 4/9/98
* @param
* @return
*/
CValidDTD::~CValidDTD(){
}
/**
* This method is called to determine if the given DTD can parse
* a document in a given source-type.
* NOTE: Parsing always assumes that the end result will involve
* storing the result in the main content model.
* @update gess6/24/98
* @param
* @return TRUE if this DTD can satisfy the request; FALSE otherwise.
*/
PRBool CValidDTD::CanParse(nsString& aContentType, PRInt32 aVersion){
PRBool result=aContentType.Equals(kRTFTextContentType);
return result;
}
/**
* This method is called to determine if the given DTD can perform
* a document conversion from a given source-type to a given target-type.
* NOTE: conversion always assumes an input stream and an outputstream.
* @update gess6/24/98
* @param
* @return TRUE if this DTD can satisfy the request; FALSE otherwise.
*/
PRBool CValidDTD::CanConvert(nsString& aSourceType, nsString& aTargetType, PRInt32 aVersion){
PRBool result=PR_TRUE;
return result;
}
/**
*
* @update gess7/7/98
* @param
* @return
*/
eAutoDetectResult CValidDTD::AutoDetectContentType(nsString& aBuffer,nsString& aType){
eAutoDetectResult result=eUnknownDetect;
return result;
}
/**
*
* @update gess5/18/98
* @param
* @return
*/
PRInt32 CValidDTD::WillBuildModel(const char* aFilename){
PRInt32 result=0;
return result;
}
/**
*
* @update gess5/18/98
* @param
* @return
*/
PRInt32 CValidDTD::DidBuildModel(PRInt32 anErrorCode){
PRInt32 result=0;
return result;
}
/**
*
*
* @update gess 3/25/98
* @param
* @return
*/
void CValidDTD::SetParser(nsIParser* aParser) {
mParser=(nsParser*)aParser;
}
/**
* This method gets called in order to set the content
* sink for this parser to dump nodes to.
*
* @update gess 3/25/98
* @param nsIContentSink interface for node receiver
* @return
*/
nsIContentSink* CValidDTD::SetContentSink(nsIContentSink* aSink) {
return 0;
}
/*******************************************************************
These methods use to be hidden in the tokenizer-delegate.
That file merged with the DTD, since the separation wasn't really
buying us anything.
*******************************************************************/
/**
* This method repeatedly called by the tokenizer.
* Each time, we determine the kind of token were about to
* read, and then we call the appropriate method to handle
* that token type.
*
* @update gess 3/25/98
* @param aChar: last char read
* @param aScanner: see nsScanner.h
* @param anErrorCode: arg that will hold error condition
* @return new token or null
*/
PRInt32 CValidDTD::ConsumeToken(CToken*& aToken){
CScanner* theScanner=mParser->GetScanner();
PRUnichar aChar;
PRInt32 result=theScanner->GetChar(aChar);
switch(result) {
case kEOF:
break;
case kInterrupted:
theScanner->RewindToMark();
break;
case kNoError:
default:
switch(aChar) {
case kLessThan:
default:
break;
} //switch
break;
} //switch
if(kNoError==result)
result=theScanner->Eof();
return result;
}
/**
*
* @update gess5/18/98
* @param
* @return
*/
void CValidDTD::WillResumeParse(void){
return;
}
/**
*
* @update gess5/18/98
* @param
* @return
*/
void CValidDTD::WillInterruptParse(void){
return;
}
/**
*
* @update jevering6/23/98
* @param
* @return
*/
void CValidDTD::SetDTDDebug(nsIDTDDebug * aDTDDebug) {
}
/**
* This method is called to determine whether or not a tag
* of one type can contain a tag of another type.
*
* @update gess 3/25/98
* @param aParent -- int tag of parent container
* @param aChild -- int tag of child container
* @return PR_TRUE if parent can contain child
*/
PRBool CValidDTD::CanContain(PRInt32 aParent,PRInt32 aChild){
PRBool result=PR_FALSE;
return result;
}
/**
*
* @update gess 3/25/98
* @param aToken -- token object to be put into content model
* @return 0 if all is well; non-zero is an error
*/
PRInt32 CValidDTD::HandleToken(CToken* aToken) {
PRInt32 result=0;
return result;
}

View File

@@ -0,0 +1,205 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/**
* MODULE NOTES:
* @update gess 4/8/98
*
*
*/
#ifndef __NS_VALID_DTD
#define __NS_VALID_DTD
#include "nsIDTD.h"
#include "nsISupports.h"
#include "nsHTMLTokens.h"
#include "nshtmlpars.h"
#include "nsVoidArray.h"
#include "nsDeque.h"
#define NS_VALID_DTD_IID \
{0xa39c6bfe, 0x15f0, 0x11d2, \
{0x80, 0x41, 0x0, 0x10, 0x4b, 0x98, 0x3f, 0xd4}}
class nsIHTMLContentSink;
class nsIDTDDebug;
class nsIParserNode;
class CITokenHandler;
class nsParser;
class CValidDTD : public nsIDTD {
public:
NS_DECL_ISUPPORTS
/**
*
*
* @update gess 4/9/98
* @param
* @return
*/
CValidDTD();
/**
*
*
* @update gess 4/9/98
* @param
* @return
*/
virtual ~CValidDTD();
/**
* This method is called to determine if the given DTD can parse
* a document in a given source-type.
* NOTE: Parsing always assumes that the end result will involve
* storing the result in the main content model.
* @update gess6/24/98
* @param
* @return TRUE if this DTD can satisfy the request; FALSE otherwise.
*/
virtual PRBool CanParse(nsString& aContentType, PRInt32 aVersion);
/**
* This method is called to determine if the given DTD can perform
* a document conversion from a given source-type to a given target-type.
* NOTE: conversion always assumes an input stream and an outputstream.
* @update gess6/24/98
* @param
* @return TRUE if this DTD can satisfy the request; FALSE otherwise.
*/
virtual PRBool CanConvert(nsString& aSourceType, nsString& aTargetType, PRInt32 aVersion);
/**
*
* @update gess7/7/98
* @param
* @return
*/
virtual eAutoDetectResult AutoDetectContentType(nsString& aBuffer,nsString& aType);
/**
*
* @update gess5/18/98
* @param
* @return
*/
virtual PRInt32 WillBuildModel(const char* aFilename=0);
/**
*
* @update gess5/18/98
* @param
* @return
*/
virtual PRInt32 DidBuildModel(PRInt32 anErrorCode);
/**
*
* @update gess 3/25/98
* @param aToken -- token object to be put into content model
* @return 0 if all is well; non-zero is an error
*/
virtual PRInt32 HandleToken(CToken* aToken);
/**
*
*
* @update gess 3/25/98
* @param
* @return
*/
virtual void SetParser(nsIParser* aParser);
/**
* Cause the tokenizer to consume the next token, and
* return an error result.
*
* @update gess 3/25/98
* @param anError -- ref to error code
* @return new token or null
*/
virtual PRInt32 ConsumeToken(CToken*& aToken);
/**
*
* @update gess5/18/98
* @param
* @return
*/
virtual void WillResumeParse(void);
/**
*
* @update gess5/18/98
* @param
* @return
*/
virtual void WillInterruptParse(void);
/**
* Select given content sink into parser for parser output
* @update gess5/11/98
* @param aSink is the new sink to be used by parser
* @return old sink, or NULL
*/
virtual nsIContentSink* SetContentSink(nsIContentSink* aSink);
/**
*
* @update jevering6/23/98
* @param
* @return
*/
virtual void SetDTDDebug(nsIDTDDebug * aDTDDebug);
/**
* This method is called to determine whether or not a tag
* of one type can contain a tag of another type.
*
* @update gess 3/25/98
* @param aParent -- int tag of parent container
* @param aChild -- int tag of child container
* @return PR_TRUE if parent can contain child
*/
virtual PRBool CanContain(PRInt32 aParent,PRInt32 aChild);
protected:
nsParser* mParser;
nsIHTMLContentSink* mSink;
char* mFilename;
};
extern NS_HTMLPARS nsresult NS_NewValid_DTD(nsIDTD** aInstancePtrResult);
#endif

View File

@@ -0,0 +1,321 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/**
* MODULE NOTES:
* @update gess 4/8/98
*
*
*/
/**
* TRANSIENT STYLE-HANDLING NOTES:
* @update gess 6/15/98
*
* ...add comments here about transient style stack.
*
*/
#include "nsIDTDDebug.h"
#include "nsWellFormedDTD.h"
#include "nsCRT.h"
#include "nsParser.h"
#include "nsScanner.h"
#include "nsParserTypes.h"
#include "nsTokenHandler.h"
#include "prenv.h" //this is here for debug reasons...
#include "prtypes.h" //this is here for debug reasons...
#include "prio.h"
#include "plstr.h"
#ifdef XP_PC
#include <direct.h> //this is here for debug reasons...
#endif
#include "prmem.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIDTDIID, NS_IDTD_IID);
static NS_DEFINE_IID(kClassIID, NS_WELLFORMED_DTD_IID);
static const char* kNullURL = "Error: Null URL given";
static const char* kNullFilename= "Error: Null filename given";
static const char* kNullTokenizer = "Error: Unable to construct tokenizer";
static const char* kNullToken = "Error: Null token given";
static const char* kInvalidTagStackPos = "Error: invalid tag stack position";
static const char* kRTFTextContentType = "text/xml";
static nsAutoString gEmpty;
/**
* This method gets called as part of our COM-like interfaces.
* Its purpose is to create an interface to parser object
* of some type.
*
* @update gess 4/8/98
* @param nsIID id of object to discover
* @param aInstancePtr ptr to newly discovered interface
* @return NS_xxx result code
*/
nsresult CWellFormedDTD::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if(aIID.Equals(kISupportsIID)) { //do IUnknown...
*aInstancePtr = (nsIDTD*)(this);
}
else if(aIID.Equals(kIDTDIID)) { //do IParser base class...
*aInstancePtr = (nsIDTD*)(this);
}
else if(aIID.Equals(kClassIID)) { //do this class...
*aInstancePtr = (CWellFormedDTD*)(this);
}
else {
*aInstancePtr=0;
return NS_NOINTERFACE;
}
((nsISupports*) *aInstancePtr)->AddRef();
return NS_OK;
}
/**
* This method is defined in nsIParser. It is used to
* cause the COM-like construction of an nsParser.
*
* @update gess 4/8/98
* @param nsIParser** ptr to newly instantiated parser
* @return NS_xxx error result
*/
NS_HTMLPARS nsresult NS_NewWellFormed_DTD(nsIDTD** aInstancePtrResult)
{
CWellFormedDTD* it = new CWellFormedDTD();
if (it == 0) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kClassIID, (void **) aInstancePtrResult);
}
NS_IMPL_ADDREF(CWellFormedDTD)
NS_IMPL_RELEASE(CWellFormedDTD)
/**
* Default constructor
*
* @update gess 4/9/98
* @param
* @return
*/
CWellFormedDTD::CWellFormedDTD() : nsIDTD() {
NS_INIT_REFCNT();
mParser=0;
mFilename=0;
}
/**
* Default destructor
*
* @update gess 4/9/98
* @param
* @return
*/
CWellFormedDTD::~CWellFormedDTD(){
}
/**
* This method is called to determine if the given DTD can parse
* a document in a given source-type.
* NOTE: Parsing always assumes that the end result will involve
* storing the result in the main content model.
* @update gess6/24/98
* @param
* @return TRUE if this DTD can satisfy the request; FALSE otherwise.
*/
PRBool CWellFormedDTD::CanParse(nsString& aContentType, PRInt32 aVersion){
PRBool result=aContentType.Equals(kRTFTextContentType);
return result;
}
/**
*
* @update gess7/7/98
* @param
* @return
*/
eAutoDetectResult CWellFormedDTD::AutoDetectContentType(nsString& aBuffer,nsString& aType){
eAutoDetectResult result=eUnknownDetect;
return result;
}
/**
*
* @update gess5/18/98
* @param
* @return
*/
PRInt32 CWellFormedDTD::WillBuildModel(const char* aFilename){
PRInt32 result=0;
return result;
}
/**
*
* @update gess5/18/98
* @param
* @return
*/
PRInt32 CWellFormedDTD::DidBuildModel(PRInt32 anErrorCode){
PRInt32 result=0;
return result;
}
/**
*
*
* @update gess 3/25/98
* @param
* @return
*/
void CWellFormedDTD::SetParser(nsIParser* aParser) {
mParser=(nsParser*)aParser;
}
/**
* This method gets called in order to set the content
* sink for this parser to dump nodes to.
*
* @update gess 3/25/98
* @param nsIContentSink interface for node receiver
* @return
*/
nsIContentSink* CWellFormedDTD::SetContentSink(nsIContentSink* aSink) {
return 0;
}
/*******************************************************************
These methods use to be hidden in the tokenizer-delegate.
That file merged with the DTD, since the separation wasn't really
buying us anything.
*******************************************************************/
/**
* This method repeatedly called by the tokenizer.
* Each time, we determine the kind of token were about to
* read, and then we call the appropriate method to handle
* that token type.
*
* @update gess 3/25/98
* @param aChar: last char read
* @param aScanner: see nsScanner.h
* @param anErrorCode: arg that will hold error condition
* @return new token or null
*/
PRInt32 CWellFormedDTD::ConsumeToken(CToken*& aToken){
CScanner* theScanner=mParser->GetScanner();
PRUnichar aChar;
PRInt32 result=theScanner->GetChar(aChar);
switch(result) {
case kEOF:
break;
case kInterrupted:
theScanner->RewindToMark();
break;
case kNoError:
default:
switch(aChar) {
case kLessThan:
default:
break;
} //switch
break;
} //switch
if(kNoError==result)
result=theScanner->Eof();
return result;
}
/**
*
* @update gess5/18/98
* @param
* @return
*/
void CWellFormedDTD::WillResumeParse(void){
return;
}
/**
*
* @update gess5/18/98
* @param
* @return
*/
void CWellFormedDTD::WillInterruptParse(void){
return;
}
/**
*
* @update jevering6/23/98
* @param
* @return
*/
void CWellFormedDTD::SetDTDDebug(nsIDTDDebug * aDTDDebug) {
}
/**
* This method is called to determine whether or not a tag
* of one type can contain a tag of another type.
*
* @update gess 3/25/98
* @param aParent -- int tag of parent container
* @param aChild -- int tag of child container
* @return PR_TRUE if parent can contain child
*/
PRBool CWellFormedDTD::CanContain(PRInt32 aParent,PRInt32 aChild){
PRBool result=PR_FALSE;
return result;
}
/**
*
* @update gess 3/25/98
* @param aToken -- token object to be put into content model
* @return 0 if all is well; non-zero is an error
*/
PRInt32 CWellFormedDTD::HandleToken(CToken* aToken) {
PRInt32 result=0;
return result;
}

View File

@@ -0,0 +1,194 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/**
* MODULE NOTES:
* @update gess 4/8/98
*
*
*/
#ifndef __NS_WELLFORMED_DTD
#define __NS_WELLFORMED_DTD
#include "nsIDTD.h"
#include "nsISupports.h"
#include "nsHTMLTokens.h"
#include "nshtmlpars.h"
#include "nsVoidArray.h"
#include "nsDeque.h"
#define NS_WELLFORMED_DTD_IID \
{0xa39c6bfd, 0x15f0, 0x11d2, \
{0x80, 0x41, 0x0, 0x10, 0x4b, 0x98, 0x3f, 0xd4}}
class nsIHTMLContentSink;
class nsIDTDDebug;
class nsIParserNode;
class CITokenHandler;
class nsParser;
class CWellFormedDTD : public nsIDTD {
public:
NS_DECL_ISUPPORTS
/**
*
*
* @update gess 4/9/98
* @param
* @return
*/
CWellFormedDTD();
/**
*
*
* @update gess 4/9/98
* @param
* @return
*/
virtual ~CWellFormedDTD();
/**
* This method is called to determine if the given DTD can parse
* a document in a given source-type.
* NOTE: Parsing always assumes that the end result will involve
* storing the result in the main content model.
* @update gess6/24/98
* @param
* @return TRUE if this DTD can satisfy the request; FALSE otherwise.
*/
virtual PRBool CanParse(nsString& aContentType, PRInt32 aVersion);
/**
*
* @update gess7/7/98
* @param
* @return
*/
virtual eAutoDetectResult AutoDetectContentType(nsString& aBuffer,nsString& aType);
/**
*
* @update gess5/18/98
* @param
* @return
*/
virtual PRInt32 WillBuildModel(const char* aFilename=0);
/**
*
* @update gess5/18/98
* @param
* @return
*/
virtual PRInt32 DidBuildModel(PRInt32 anErrorCode);
/**
*
* @update gess 3/25/98
* @param aToken -- token object to be put into content model
* @return 0 if all is well; non-zero is an error
*/
virtual PRInt32 HandleToken(CToken* aToken);
/**
*
*
* @update gess 3/25/98
* @param
* @return
*/
virtual void SetParser(nsIParser* aParser);
/**
* Cause the tokenizer to consume the next token, and
* return an error result.
*
* @update gess 3/25/98
* @param anError -- ref to error code
* @return new token or null
*/
virtual PRInt32 ConsumeToken(CToken*& aToken);
/**
*
* @update gess5/18/98
* @param
* @return
*/
virtual void WillResumeParse(void);
/**
*
* @update gess5/18/98
* @param
* @return
*/
virtual void WillInterruptParse(void);
/**
* Select given content sink into parser for parser output
* @update gess5/11/98
* @param aSink is the new sink to be used by parser
* @return old sink, or NULL
*/
virtual nsIContentSink* SetContentSink(nsIContentSink* aSink);
/**
*
* @update jevering6/23/98
* @param
* @return
*/
virtual void SetDTDDebug(nsIDTDDebug * aDTDDebug);
/**
* This method is called to determine whether or not a tag
* of one type can contain a tag of another type.
*
* @update gess 3/25/98
* @param aParent -- int tag of parent container
* @param aChild -- int tag of child container
* @return PR_TRUE if parent can contain child
*/
virtual PRBool CanContain(PRInt32 aParent,PRInt32 aChild);
protected:
nsParser* mParser;
nsIHTMLContentSink* mSink;
char* mFilename;
};
extern NS_HTMLPARS nsresult NS_NewWellFormed_DTD(nsIDTD** aInstancePtrResult);
#endif

View File

@@ -107,6 +107,8 @@ nsDocFactoryImpl::nsDocFactoryImpl()
NS_DEFINE_IID(kIDocumentLoaderFactoryIID, NS_IDOCUMENTLOADERFACTORY_IID);
NS_IMPL_ISUPPORTS(nsDocFactoryImpl,kIDocumentLoaderFactoryIID);
static char* gValidTypes[] = {"text/html","text/xml","application/rtf",0};
NS_IMETHODIMP
nsDocFactoryImpl::CreateInstance(nsIURL* aURL,
const char* aContentType,
@@ -118,16 +120,15 @@ nsDocFactoryImpl::CreateInstance(nsIURL* aURL,
nsIDocument* doc = nsnull;
nsIWebWidget* ww = nsnull;
/*
* XXX:
* All of this code should be replaced by a registry and factories
* for each content type...
*/
if (0 != PL_strcmp("text/html", aContentType)) {
rv = NS_ERROR_FAILURE;
goto done;
int typeIndex=0;
while(gValidTypes[typeIndex]) {
if (0== PL_strcmp(gValidTypes[typeIndex++], aContentType)) {
goto nextstep;
}
}
goto done;
nextstep:
/*
* Create the HTML document...
*/

View File

@@ -107,6 +107,8 @@ nsDocFactoryImpl::nsDocFactoryImpl()
NS_DEFINE_IID(kIDocumentLoaderFactoryIID, NS_IDOCUMENTLOADERFACTORY_IID);
NS_IMPL_ISUPPORTS(nsDocFactoryImpl,kIDocumentLoaderFactoryIID);
static char* gValidTypes[] = {"text/html","text/xml","application/rtf",0};
NS_IMETHODIMP
nsDocFactoryImpl::CreateInstance(nsIURL* aURL,
const char* aContentType,
@@ -118,16 +120,15 @@ nsDocFactoryImpl::CreateInstance(nsIURL* aURL,
nsIDocument* doc = nsnull;
nsIWebWidget* ww = nsnull;
/*
* XXX:
* All of this code should be replaced by a registry and factories
* for each content type...
*/
if (0 != PL_strcmp("text/html", aContentType)) {
rv = NS_ERROR_FAILURE;
goto done;
int typeIndex=0;
while(gValidTypes[typeIndex]) {
if (0== PL_strcmp(gValidTypes[typeIndex++], aContentType)) {
goto nextstep;
}
}
goto done;
nextstep:
/*
* Create the HTML document...
*/