You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by tn...@apache.org on 2001/03/21 22:56:36 UTC
cvs commit: xml-xerces/c/src/validators/schema SchemaGrammar.cpp SchemaGrammar.hpp SchemaValidator.cpp SchemaValidator.hpp Makefile.in SchemaElementDecl.cpp SchemaElementDecl.hpp
tng 01/03/21 13:56:35
Modified: c/Projects/OS2/VACPP40 xerces_validators.icc
c/Projects/Win32/VC6/xerces-all/XercesLib XercesLib.dsp
c/samples/EnumVal EnumVal.cpp
c/src/NLS/EN_US XMLErrList_EN_US.Xml
c/src/framework XMLContentModel.hpp XMLElementDecl.cpp
XMLElementDecl.hpp XMLErrorCodes.hpp
XMLValidator.cpp XMLValidator.hpp
XMLValidityCodes.hpp
c/src/internal VecAttributesImpl.cpp VecAttributesImpl.hpp
XMLScanner.cpp XMLScanner.hpp XMLScanner2.cpp
c/src/parsers DOMParser.cpp DOMParser.hpp
SAX2XMLReaderImpl.cpp SAX2XMLReaderImpl.hpp
SAXParser.cpp SAXParser.hpp
c/src/sax Parser.hpp
c/src/util Makefile.in QName.cpp QName.hpp XMLExceptMsgs.hpp
XMLString.cpp XMLString.hpp
c/src/util/MsgLoaders/InMemory CppErrMsgs_EN_US.hpp
c/src/util/MsgLoaders/MsgCatalog XMLMsgCat_EN_US.Msg
c/src/util/Platforms/Win32 Version.rc
c/src/validators/DTD DTDElementDecl.cpp DTDElementDecl.hpp
DTDValidator.cpp DTDValidator.hpp Makefile.in
c/src/validators/common ContentSpecNode.cpp
ContentSpecNode.hpp DFAContentModel.cpp
DFAContentModel.hpp Makefile.in
MixedContentModel.cpp MixedContentModel.hpp
SimpleContentModel.cpp SimpleContentModel.hpp
c/src/validators/schema Makefile.in SchemaElementDecl.cpp
SchemaElementDecl.hpp
Added: c/src/util RefHash3KeysIdPool.c RefHash3KeysIdPool.hpp
c/src/validators/DTD DTDGrammar.cpp DTDGrammar.hpp
DTDScanner.cpp DTDScanner.hpp
c/src/validators/common Grammar.hpp GrammarResolver.cpp
GrammarResolver.hpp
c/src/validators/schema SchemaGrammar.cpp SchemaGrammar.hpp
SchemaValidator.cpp SchemaValidator.hpp
Removed: c/src/validators/DTD DTDValidator2.cpp
Log:
Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
Revision Changes Path
1.5 +12 -5 xml-xerces/c/Projects/OS2/VACPP40/xerces_validators.icc
Index: xerces_validators.icc
===================================================================
RCS file: /home/cvs/xml-xerces/c/Projects/OS2/VACPP40/xerces_validators.icc,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- xerces_validators.icc 2001/02/27 18:48:14 1.4
+++ xerces_validators.icc 2001/03/21 21:55:53 1.5
@@ -5,13 +5,20 @@
BASE_DIR "\\src\\validators\\common\\ContentLeafNameTypeVector.cpp",
BASE_DIR "\\src\\validators\\common\\ContentSpecNode.cpp",
BASE_DIR "\\src\\validators\\common\\DFAContentModel.cpp",
+ BASE_DIR "\\src\\validators\\common\\GrammarResolver.cpp",
BASE_DIR "\\src\\validators\\common\\MixedContentModel.cpp",
- BASE_DIR "\\src\\validators\\common\\SimpleContentModel.cpp"
+ BASE_DIR "\\src\\validators\\common\\SimpleContentModel.cpp",
+ BASE_DIR "\\src\\validators\\datatype\\DatatypeValidator.cpp",
+ BASE_DIR "\\src\\validators\\datatype\\DatatypeValidatorFactory.cpp",
BASE_DIR "\\src\\validators\\DTD\\DTDAttDef.cpp",
BASE_DIR "\\src\\validators\\DTD\\DTDAttDefList.cpp",
BASE_DIR "\\src\\validators\\DTD\\DTDElementDecl.cpp",
+ BASE_DIR "\\src\\validators\\DTD\\DTDGrammar.cpp",
+ BASE_DIR "\\src\\validators\\DTD\\DTDScanner.cpp",
BASE_DIR "\\src\\validators\\DTD\\DTDValidator.cpp",
- BASE_DIR "\\src\\validators\\DTD\\DTDValidator2.cpp",
- BASE_DIR "\\src\\validators\\schema\\SchemaAttDef.cpp"
- BASE_DIR "\\src\\validators\\schema\\SchemaAttDefList.cpp"
- BASE_DIR "\\src\\validators\\schema\\SchemaElementDecl.cpp"
+ BASE_DIR "\\src\\validators\\schema\\SchemaAttDef.cpp",
+ BASE_DIR "\\src\\validators\\schema\\SchemaAttDefList.cpp",
+ BASE_DIR "\\src\\validators\\schema\\SchemaElementDecl.cpp",
+ BASE_DIR "\\src\\validators\\schema\\SchemaGrammar.cpp",
+ BASE_DIR "\\src\\validators\\schema\\SchemaSymbol.cpp",
+ BASE_DIR "\\src\\validators\\schema\\SchemaValidator.cpp"
1.53 +71 -3 xml-xerces/c/Projects/Win32/VC6/xerces-all/XercesLib/XercesLib.dsp
Index: XercesLib.dsp
===================================================================
RCS file: /home/cvs/xml-xerces/c/Projects/Win32/VC6/xerces-all/XercesLib/XercesLib.dsp,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -r1.52 -r1.53
--- XercesLib.dsp 2001/03/02 20:05:23 1.52
+++ XercesLib.dsp 2001/03/21 21:55:56 1.53
@@ -536,6 +536,10 @@
# End Source File
# Begin Source File
+SOURCE=..\..\..\..\..\src\util\RefHash3KeysIdPool.hpp
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\..\..\src\util\RefHashTableOf.hpp
# End Source File
# Begin Source File
@@ -1595,6 +1599,18 @@
# End Source File
# Begin Source File
+SOURCE=..\..\..\..\..\src\validators\common\Grammar.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\..\src\validators\common\GrammarResolver.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\..\src\validators\common\GrammarResolver.hpp
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\..\..\src\validators\common\MixedContentModel.cpp
# End Source File
# Begin Source File
@@ -1615,6 +1631,22 @@
# PROP Default_Filter "*.cpp, *.hpp"
# Begin Source File
+SOURCE=..\..\..\..\..\src\validators\datatype\DatatypeValidator.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\..\src\validators\datatype\DatatypeValidator.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\..\src\validators\datatype\DatatypeValidatorFactory.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\..\src\validators\datatype\DatatypeValidatorFactory.hpp
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\..\..\src\validators\datatype\InvalidDatatypeFacetException.hpp
# End Source File
# Begin Source File
@@ -1659,16 +1691,28 @@
# End Source File
# Begin Source File
-SOURCE=..\..\..\..\..\src\validators\DTD\DTDValidator.cpp
+SOURCE=..\..\..\..\..\src\validators\DTD\DTDGrammar.cpp
# End Source File
# Begin Source File
-SOURCE=..\..\..\..\..\src\validators\DTD\DTDValidator.hpp
+SOURCE=..\..\..\..\..\src\validators\DTD\DTDGrammar.hpp
# End Source File
# Begin Source File
-SOURCE=..\..\..\..\..\src\validators\DTD\DTDValidator2.cpp
+SOURCE=..\..\..\..\..\src\validators\DTD\DTDScanner.cpp
# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\..\src\validators\DTD\DTDScanner.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\..\src\validators\DTD\DTDValidator.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\..\src\validators\DTD\DTDValidator.hpp
+# End Source File
# End Group
# Begin Group "schema"
@@ -1696,6 +1740,30 @@
# Begin Source File
SOURCE=..\..\..\..\..\src\validators\schema\SchemaElementDecl.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\..\src\validators\schema\SchemaGrammar.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\..\src\validators\schema\SchemaGrammar.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\..\src\validators\schema\SchemaSymbols.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\..\src\validators\schema\SchemaSymbols.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\..\src\validators\schema\SchemaValidator.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\..\src\validators\schema\SchemaValidator.hpp
# End Source File
# End Group
# End Group
1.10 +6 -2 xml-xerces/c/samples/EnumVal/EnumVal.cpp
Index: EnumVal.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/samples/EnumVal/EnumVal.cpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- EnumVal.cpp 2000/06/12 22:07:22 1.9
+++ EnumVal.cpp 2001/03/21 21:55:57 1.10
@@ -56,6 +56,9 @@
/*
* $Log: EnumVal.cpp,v $
+ * Revision 1.10 2001/03/21 21:55:57 tng
+ * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+ *
* Revision 1.9 2000/06/12 22:07:22 rahulj
* Correctly rejects unsupported command line options.
*
@@ -241,7 +244,8 @@
// and enumerate the elements, printing them as we go. For each element
// we get an enumerator for its attributes and print them also.
//
- NameIdPoolEnumerator<DTDElementDecl> elemEnum = valToUse->getElemEnumerator();
+ DTDGrammar* grammar = (DTDGrammar*) valToUse->getGrammar();
+ NameIdPoolEnumerator<DTDElementDecl> elemEnum = grammar->getElemEnumerator();
if (elemEnum.hasMoreElements())
{
cout << "\nELEMENTS:\n----------------------------\n";
@@ -251,7 +255,7 @@
cout << " Name: " << StrX(curElem.getFullName()) << "\n";
cout << " Content Model: "
- << StrX(curElem.getFormattedContentModel(*valToUse))
+ << StrX(curElem.getFormattedContentModel(*grammar))
<< "\n";
// Get an enumerator for this guy's attributes if any
1.16 +10 -5 xml-xerces/c/src/NLS/EN_US/XMLErrList_EN_US.Xml
Index: XMLErrList_EN_US.Xml
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/NLS/EN_US/XMLErrList_EN_US.Xml,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- XMLErrList_EN_US.Xml 2001/03/02 20:52:38 1.15
+++ XMLErrList_EN_US.Xml 2001/03/21 21:55:59 1.16
@@ -1,9 +1,9 @@
<?xml version='1.0' encoding='utf-8' ?>
<!DOCTYPE MsgFile SYSTEM "../XMLErrList.Dtd">
-<!-- =====================================================
- A Message file is designed for a particular locale, which is
- indicated in the locale attribute.
+<!-- =====================================================
+ A Message file is designed for a particular locale, which is
+ indicated in the locale attribute.
======================================================= -->
<MsgFile Locale="EN_US">
<MsgDomain Domain="http://apache.org/xml/messages/XMLErrors">
@@ -153,11 +153,12 @@
<Message Id="NoContentForRef" Text="Cannot have child content for an element declaration that has a ref attribute"/>
<Message Id="IncorrectDefaultType" Text="Incorrect type for {0}'s default value: {1}"/>
<Message Id="IllegalAttContent" Text="Illegal content {0} in attribute group"/>
- <Message Id="ValueNotInteger" Text="Value of {0} is not an integer."/>
+ <Message Id="ValueNotInteger" Text="Value of {0} is not an integer."/>
<Message Id="DatatypeError" Text="Datatype error: {0}."/>
<Message Id="TypeAlreadySet" Text="The type of the element has already been declared."/>
- <Message Id="GenericError" Text="Schema error: {0}."/>
+ <Message Id="GenericError" Text="Schema error during parsing"/>
<Message Id="UnexpectedError" Text="UnexpectedError"/>
+ <Message Id="BadSchemaLocation" Text="The schemaLocation attribute does not contain pairs of values."/>
</Error>
</MsgDomain>
<MsgDomain Domain="http://apache.org/xml/messages/XMLValidity">
@@ -204,6 +205,9 @@
<Message Id="PrecisionExceeded" Text="{0} has exceeded the precision Facet {1}"/>
<Message Id="ScaleExceeded" Text="{0} has execeed the scale Facet {1}"/>
<Message Id="NotFloat" Text="{0} is not a float."/>
+ <Message Id="SchemaRootError" Text="Can't get back Schema document's root element {0}."/>
+ <Message Id="WrongTargetNamespace" Text="Schema in {0} has a different target namespace from the one specified in the instance document {1}."/>
+
</Error>
</MsgDomain>
<MsgDomain Domain="http://apache.org/xml/messages/XML4CErrors">
@@ -342,6 +346,7 @@
<Message Id="Parser_Descape4" Text="Invalid Unicode code point"/>
<Message Id="Parser_Descape5" Text="An anchor must not be here"/>
<Message Id="Parser_Process1" Text="This expression is not supported in the current option setting"/>
+ <Message Id="Gen_NoSchemaValidator" Text="A schema was seen but the installed validator does not understand schema"/>
</Error>
</MsgDomain>
<MsgDomain Domain="http://apache.org/xml/messages/XML4JErrors">
1.7 +19 -13 xml-xerces/c/src/framework/XMLContentModel.hpp
Index: XMLContentModel.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/framework/XMLContentModel.hpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- XMLContentModel.hpp 2001/02/27 14:48:30 1.6
+++ XMLContentModel.hpp 2001/03/21 21:56:01 1.7
@@ -1,37 +1,37 @@
/*
* The Apache Software License, Version 1.1
- *
+ *
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- *
+ *
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
+ * notice, this list of conditions and the following disclaimer.
+ *
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
- *
+ *
* 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
+ * if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
- *
+ *
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
- * software without prior written permission. For written
+ * software without prior written permission. For written
* permission, please contact apache\@apache.org.
- *
+ *
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
- *
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@@ -45,7 +45,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
- *
+ *
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
@@ -56,6 +56,9 @@
/*
* $Log: XMLContentModel.hpp,v $
+ * Revision 1.7 2001/03/21 21:56:01 tng
+ * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+ *
* Revision 1.6 2001/02/27 14:48:30 tng
* Schema: Add CMAny and ContentLeafNameTypeVector, by Pei Yong Zhang
*
@@ -89,11 +92,12 @@
#include <util/RefVectorOf.hpp>
class ContentLeafNameTypeVector;
+class Grammar;
/**
* This class defines the abstract interface for all content models. All
* elements have a content model against which (if validating) its content
- * is checked. Each type of validator (DTD, Schema, etc...) can have
+ * is checked. Each type of validator (DTD, Schema, etc...) can have
* different types of content models, and even with each type of validator
* there can be specialized content models. So this simple class provides
* the abstract API via which all the types of contents models are dealt
@@ -122,12 +126,14 @@
(
const unsigned int* childIds
, const unsigned int childCount
+ , const Grammar* grammar = 0
) const = 0;
virtual int validateContentSpecial
(
const unsigned int* childIds
, const unsigned int childCount
+ , const Grammar* grammar = 0
) const = 0;
virtual ContentLeafNameTypeVector* getContentLeafNameTypeVector()
1.6 +3 -3 xml-xerces/c/src/framework/XMLElementDecl.cpp
Index: XMLElementDecl.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/framework/XMLElementDecl.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- XMLElementDecl.cpp 2001/02/26 19:21:27 1.5
+++ XMLElementDecl.cpp 2001/03/21 21:56:01 1.6
@@ -55,7 +55,7 @@
*/
/**
- * $Id: XMLElementDecl.cpp,v 1.5 2001/02/26 19:21:27 tng Exp $
+ * $Id: XMLElementDecl.cpp,v 1.6 2001/03/21 21:56:01 tng Exp $
*/
@@ -92,7 +92,7 @@
// XMLElementDecl: Miscellaneous
// ---------------------------------------------------------------------------
const XMLCh*
-XMLElementDecl::getFormattedContentModel(const XMLValidator& validator) const
+XMLElementDecl::getFormattedContentModel(const Grammar& grammar) const
{
//
// If its not already built, then call the protected virtual method
@@ -103,7 +103,7 @@
// cast off the const-ness.
//
if (!fFormattedModel)
- ((XMLElementDecl*)this)->fFormattedModel = formatContentModel(validator);
+ ((XMLElementDecl*)this)->fFormattedModel = formatContentModel(grammar);
return fFormattedModel;
}
1.12 +22 -18 xml-xerces/c/src/framework/XMLElementDecl.hpp
Index: XMLElementDecl.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/framework/XMLElementDecl.hpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- XMLElementDecl.hpp 2001/03/21 19:29:29 1.11
+++ XMLElementDecl.hpp 2001/03/21 21:56:02 1.12
@@ -56,6 +56,9 @@
/*
* $Log: XMLElementDecl.hpp,v $
+ * Revision 1.12 2001/03/21 21:56:02 tng
+ * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+ *
* Revision 1.11 2001/03/21 19:29:29 tng
* Schema: Content Model Updates, by Pei Yong Zhang.
*
@@ -105,8 +108,8 @@
#include <framework/XMLAttDefList.hpp>
#include <framework/XMLContentModel.hpp>
-class XMLValidator;
class ContentSpecNode;
+class Grammar;
/**
* This class defines the core information of an element declaration. Each
@@ -131,7 +134,7 @@
//
// CreateReasons
// This type is used to store how an element declaration got into
- // the validator's element pool. They are faulted in for various
+ // the grammar's element pool. They are faulted in for various
// reasons.
//
// LookupOpts
@@ -261,6 +264,7 @@
* @return A const pointer to the base name of the element decl.
*/
virtual const XMLCh* getBaseName() const = 0;
+ virtual XMLCh* getBaseName() = 0;
/** Get the URI id of this element type.
*
@@ -355,14 +359,14 @@
* @return A const pointer to the element's content model, via the basic
* abstract content model type.
*/
- const XMLContentModel* getContentModel(XMLValidator* pValidator=0) const;
+ const XMLContentModel* getContentModel(const Grammar* grammar=0) const;
/** Get a pointer to the abstract content model
*
* This method is identical to the previous one, except that it is non
* const.
*/
- XMLContentModel* getContentModel(XMLValidator* pValidator=0);
+ XMLContentModel* getContentModel(const Grammar* grammar=0);
/** Get the create reason for this element type
*
@@ -382,7 +386,7 @@
* This method will return the element decl pool id of this element
* declaration. This uniquely identifies this element type within the
* parse event that it is declared within. This value is assigned by the
- * validator whose decl pool this object belongs to.
+ * grammar whose decl pool this object belongs to.
*
* @return The element decl id of this element declaration.
*/
@@ -447,7 +451,7 @@
/** Set the element decl pool id for this element type
*
* This method will set the pool id of this element decl. This is called
- * by the validator which created this object, and will provide this
+ * by the grammar which created this object, and will provide this
* decl object with a unique id within the parse event that created it.
*/
void setId(const unsigned int newId);
@@ -476,12 +480,12 @@
* or reformatting may occur. But, it will be a technically accurate
* representation of the original content model.
*
- * The format depends upon the validator, since content models are
+ * The format depends upon the grammar, since content models are
* expressed differently in different structural description languages.
*
- * @param validator The validator which owns this object, and which
- * therefore has the information required to format
- * the content model.
+ * @param grammar The grammar which owns this object, and which
+ * therefore has the information required to format
+ * the content model.
*
* @return A pointer to an internal buffer which contains the formatted
* content model. The caller does not own this buffer and should
@@ -489,7 +493,7 @@
*/
const XMLCh* getFormattedContentModel
(
- const XMLValidator& validator
+ const Grammar& grammar
) const;
//@}
@@ -505,10 +509,10 @@
// -----------------------------------------------------------------------
// Protected, virtual methods
// -----------------------------------------------------------------------
- virtual XMLContentModel* makeContentModel(XMLValidator* pValidator=0) const = 0;
+ virtual XMLContentModel* makeContentModel(const Grammar* grammar=0) const = 0;
virtual XMLCh* formatContentModel
(
- const XMLValidator& validator
+ const Grammar& grammar
) const = 0;
@@ -541,7 +545,7 @@
//
// fId
// The unique id of this element. This is created by the derived
- // class, or more accurately the validator that owns the objects
+ // class, or more accurately the grammar that owns the objects
// of the derived types. But, since they all have to have them, we
// let them all store the id here. It is defaulted to have the
// value fgInvalidElem until explicitly set.
@@ -560,18 +564,18 @@
// ---------------------------------------------------------------------------
// XMLElementDecl: Getter methods
// ---------------------------------------------------------------------------
-inline XMLContentModel* XMLElementDecl::getContentModel(XMLValidator* pValidator)
+inline XMLContentModel* XMLElementDecl::getContentModel(const Grammar* grammar)
{
if (!fContentModel)
- fContentModel = makeContentModel(pValidator);
+ fContentModel = makeContentModel(grammar);
return fContentModel;
}
-inline const XMLContentModel* XMLElementDecl::getContentModel(XMLValidator* pValidator) const
+inline const XMLContentModel* XMLElementDecl::getContentModel(const Grammar* grammar) const
{
// Fault in the content model (which requires a cast off of const)
if (!fContentModel)
- ((XMLElementDecl*)this)->fContentModel = makeContentModel(pValidator);
+ ((XMLElementDecl*)this)->fContentModel = makeContentModel(grammar);
return fContentModel;
}
1.4 +4 -3 xml-xerces/c/src/framework/XMLErrorCodes.hpp
Index: XMLErrorCodes.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/framework/XMLErrorCodes.hpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- XMLErrorCodes.hpp 2001/02/15 16:46:35 1.3
+++ XMLErrorCodes.hpp 2001/03/21 21:56:02 1.4
@@ -162,9 +162,10 @@
, TypeAlreadySet = 149
, GenericError = 150
, UnexpectedError = 151
- , E_HighBounds = 152
- , V_LowBounds = 153
- , V_HighBounds = 154
+ , BadSchemaLocation = 152
+ , E_HighBounds = 153
+ , V_LowBounds = 154
+ , V_HighBounds = 155
};
static bool isFatal(const XMLErrs::Codes toCheck)
1.7 +16 -17 xml-xerces/c/src/framework/XMLValidator.cpp
Index: XMLValidator.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/framework/XMLValidator.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- XMLValidator.cpp 2000/03/28 19:43:17 1.6
+++ XMLValidator.cpp 2001/03/21 21:56:02 1.7
@@ -1,37 +1,37 @@
/*
* The Apache Software License, Version 1.1
- *
+ *
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- *
+ *
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
+ * notice, this list of conditions and the following disclaimer.
+ *
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
- *
+ *
* 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
+ * if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
- *
+ *
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
- * software without prior written permission. For written
+ * software without prior written permission. For written
* permission, please contact apache\@apache.org.
- *
+ *
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
- *
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@@ -45,7 +45,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
- *
+ *
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
@@ -56,6 +56,9 @@
/**
* $Log: XMLValidator.cpp,v $
+ * Revision 1.7 2001/03/21 21:56:02 tng
+ * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+ *
* Revision 1.6 2000/03/28 19:43:17 roddey
* Fixes for signed/unsigned warnings. New work for two way transcoding
* stuff.
@@ -315,13 +318,8 @@
XMLValidator::XMLValidator(XMLErrorReporter* const errReporter) :
fBufMgr(0)
- , fEmptyNamespaceId(~0)
, fErrorReporter(errReporter)
- , fGlobalNamespaceId(~0)
, fReaderMgr(0)
, fScanner(0)
- , fUnknownNamespaceId(~0)
- , fXMLNamespaceId(~0)
- , fXMLNSNamespaceId(~0)
{
}
1.10 +68 -390 xml-xerces/c/src/framework/XMLValidator.hpp
Index: XMLValidator.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/framework/XMLValidator.hpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- XMLValidator.hpp 2001/02/26 19:21:33 1.9
+++ XMLValidator.hpp 2001/03/21 21:56:03 1.10
@@ -56,6 +56,9 @@
/*
* $Log: XMLValidator.hpp,v $
+ * Revision 1.10 2001/03/21 21:56:03 tng
+ * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+ *
* Revision 1.9 2001/02/26 19:21:33 tng
* Schema: add parameter prefix in findElem and findAttr.
*
@@ -97,8 +100,6 @@
#define XMLVALIDATOR_HPP
#include <util/XercesDefs.hpp>
-#include <util/XMLEnumerator.hpp>
-#include <util/RefHashTableOf.hpp>
#include <framework/XMLAttr.hpp>
#include <framework/XMLValidityCodes.hpp>
#include <framework/XMLRefInfo.hpp>
@@ -106,13 +107,11 @@
class ReaderMgr;
class XMLBuffer;
class XMLBufferMgr;
-class XMLElementDecl;
-class XMLEntityDecl;
class XMLEntityHandler;
class XMLErrorReporter;
-class XMLNotationDecl;
class XMLMsgLoader;
class XMLScanner;
+class Grammar;
/**
@@ -134,24 +133,6 @@
{
public:
// -----------------------------------------------------------------------
- // Class specific types
- // -----------------------------------------------------------------------
- enum Constants
- {
- Success = -1
- , BadParent = -2
- , BadChild = -3
- };
-
-
- enum LookupOpts
- {
- AddIfNotFound
- , FailIfNotFound
- };
-
-
- // -----------------------------------------------------------------------
// Constructors are hidden, just the virtual destructor is exposed
// -----------------------------------------------------------------------
@@ -169,112 +150,6 @@
// -----------------------------------------------------------------------
- // Getter methods
- // -----------------------------------------------------------------------
-
- /** @name Getter Methods */
- //@{
-
- /**
- * When an attribute name has no prefix, unlike elements, it is not mapped
- * to the global namespace. So, in order to have something to map it to
- * for practical purposes, a id for an empty URL is created and used for
- * such names.
- *
- * @return The URL pool id of the URL for an empty URL "".
- */
- unsigned int getEmptyNamespaceId() const;
-
- /**
- * When namespaces are enabled, any elements whose names have no prefix
- * are mapped to a global namespace. This is the URL id for the URL
- * to which those names are mapped. It has no official standard text,
- * but the parser must use some id here.
- *
- * @return The URL pool id of the URL for the global namespace.
- */
- unsigned int getGlobalNamespaceId() const;
-
- /**
- * When a prefix is found that has not been mapped, an error is issued.
- * However, if the parser has been instructed not to stop on the first
- * fatal error, it needs to be able to continue. To do so, it will map
- * that prefix tot his magic unknown namespace id.
- *
- * @return The URL pool id of the URL for the unknown prefix
- * namespace.
- */
- unsigned int getUnknownNamespaceId() const;
-
- /**
- * The prefix 'xml' is a magic prefix, defined by the XML spec and
- * requiring no prior definition. This method returns the id for the
- * intrinsically defined URL for this prefix.
- *
- * @return The URL pool id of the URL for the 'xml' prefix.
- */
- unsigned int getXMLNamespaceId() const;
-
- /**
- * The prefix 'xmlns' is a magic prefix, defined by the namespace spec
- * and requiring no prior definition. This method returns the id for the
- * intrinsically defined URL for this prefix.
- *
- * @return The URL pool id of the URL for the 'xmlns' prefix.
- */
- unsigned int getXMLNSNamespaceId() const;
-
- //@}
-
-
- // -----------------------------------------------------------------------
- // Setter methods
- //
- // setScannerInfo() is called by the scanner to tell the validator
- // about the stuff it needs to have access to.
- // -----------------------------------------------------------------------
-
- /** @name Setter methods */
- //@{
-
- /**
- * @param owningScanner This is a pointer to the scanner to which the
- * validator belongs. The validator will often
- * need to query state data from the scanner.
- *
- * @param readerMgr This is a pointer to the reader manager that is
- * being used by the scanner.
- *
- * @param bufMgr This is the buffer manager of the scanner. This
- * is provided as a convenience so that the validator
- * doesn't have to create its own buffer manager
- * during the parse process.
- */
- void setScannerInfo
- (
- XMLScanner* const owningScanner
- , ReaderMgr* const readerMgr
- , XMLBufferMgr* const bufMgr
- );
-
- /**
- * This method is called to set an error reporter on the validator via
- * which it will report any errors it sees during parsing or validation.
- * This is generally called by the owning scanner.
- *
- * @param errorReporter A pointer to the error reporter to use. This
- * is not adopted, just referenced so the caller
- * remains responsible for its cleanup, if any.
- */
- void setErrorReporter
- (
- XMLErrorReporter* const errorReporter
- );
-
- //@}
-
-
- // -----------------------------------------------------------------------
// The virtual validator interface
// -----------------------------------------------------------------------
@@ -282,16 +157,6 @@
//@{
/**
- * The derived class should look for the passed URI (case sensitive) in
- * its URI pool. If the URI does not exist, then it should be added to the
- * pool. The new or existing pool id should be returned.
- */
- virtual int addOrFindNSId
- (
- const XMLCh* const uriText
- ) = 0;
-
- /**
* The derived class should look up its declaration of the passed element
* from its element pool. It should then use the content model description
* contained in that element declaration to validate that the passed list
@@ -342,163 +207,12 @@
, const XMLAttDef& attDef
) const = 0;
- /**
- * The derived class should look up an element in its element declaration
- * pool and return a pointer to it. The name should be looked up either via
- * the qName field (if namespaces are off) or via the uriID/baseName combo
- * (if namespaces are on.)
- *
- * The options allow the caller to indicate how the validator should react
- * if the element exists or not. If the element does not exist, the option
- * can indicate that it should be faulted it. If it does not exist and
- * faulting in is not requested, a null pointer should be returned. The
- * wasAdded flag should be set if the declaration was faulted in, else it
- * should be cleared.
- */
- virtual const XMLElementDecl* findElemDecl
- (
- const unsigned int uriId
- , const XMLCh* const baseName
- , const XMLCh* const prefix
- , const XMLCh* const qName
- , const LookupOpts options
- , bool& wasAdded
- ) const = 0;
-
- /*
- * This method is identical to the previous one, except that it is a non-
- * const version.
- */
- virtual XMLElementDecl* findElemDecl
- (
- const unsigned int uriId
- , const XMLCh* const baseName
- , const XMLCh* const prefix
- , const XMLCh* const qName
- , const LookupOpts options
- , bool& wasAdded
- ) = 0;
-
- /**
- * The derived class should look the passed entity declaration name in its
- * entity pool and return a pointer to the declaration object. If the
- * entity is not in the pool, it should return a null pointer.
- *
- * @param entName The name of the entity to look up. Entity names can
- * not be namespace based, so its always just a single
- * unqualified name.
- *
- * @param isPE Indicates whether the name represents a parameter
- * entity or a general entity. The validator should
- * look at the correct pool for the entity type.
- */
- virtual const XMLEntityDecl* findEntityDecl
- (
- const XMLCh* const entName
- , const bool isPE
- ) const = 0;
-
- /**
- * This method is identical to the previous one, except that it is non-
- * const.
- *
- * @param entName The name of the entity to look up. Entity names can
- * not be namespace based, so its always just a single
- * unqualified name.
- *
- * @param isPE Indicates whether the name represents a parameter
- * entity or a general entity. The validator should
- * look at the correct pool for the entity type.
- */
- virtual XMLEntityDecl* findEntityDecl
- (
- const XMLCh* const entName
- , const bool isPE
- ) = 0;
-
- /**
- * The derived class should find the indicate element in its element
- * declaration pool. If namespaces are on, then it should use the uriId
- * and base name. Otherwise, it should use the qName. It should return
- * the element decl pool id for the decl found. If the element is not
- * not found, it should return the value XMLElementDecl::fgInvalidElemId;
- */
- virtual unsigned int findElemId
- (
- const unsigned int uriId
- , const XMLCh* const baseName
- , const XMLCh* const prefix
- , const XMLCh* const qName
- ) const = 0;
-
/**
- * The derived class should look up the passed notation name in its
- * notation decl pool. If the name is not found, it should return a null
- * pointer. If it is found, it should return a pointer to the declaration
- * object.
+ * This method is called by the scanner after a Grammar is scanned.
*/
- virtual const XMLNotationDecl* findNotationDecl
- (
- const XMLCh* const notName
- ) const = 0;
-
- /**
- * This method is identical to the previous method except that it is non-
- * const.
- */
- virtual XMLNotationDecl* findNotationDecl
- (
- const XMLCh* const notName
- ) = 0;
-
- /**
- * The derived class should look up the passed namespace name (prefix) in
- * its namespace name pool and return the id. If not found, it should
- * return zero, which is never a valid pool id.
- */
- virtual unsigned int findNSId
- (
- const XMLCh* const nsName
- ) const = 0;
-
- /**
- * The derived class should return the element from its element decl pool
- * which has the indicated element id. Given that these ids are gotten from
- * the validator itself, it should always be valid. If not, then a major
- * internal error has occured.
- */
- virtual const XMLElementDecl* getElemDecl
- (
- const unsigned int elemId
- ) const = 0;
+ virtual void preContentValidation(bool reuseGrammar) = 0;
/**
- * This method is identical to the previous method, except that it is a
- * non-const version.
- */
- virtual XMLElementDecl* getElemDecl
- (
- const unsigned int elemId
- ) = 0;
-
- /**
- * The derived class should find the passed URI id in its URI pool and
- * copy the text of that URI into the passed buffer. Since these ids are
- * obtained from the validator itself, they should always be valid. If
- * not, then a major internal error has occured.
- */
- virtual bool getURIText
- (
- const unsigned int uriId
- , XMLBuffer& uriBufToFill
- ) const = 0;
-
- virtual const XMLCh* getURIText
- (
- const unsigned int uriId
- ) const = 0;
-
- /**
* This method is called by the scanner after the parse has completed. It
* gives the validator a chance to check certain things that can only be
* checked after the whole document has been parsed, such as referential
@@ -538,11 +252,17 @@
, const XMLCh* const attrValue
) = 0;
+ /**
+ * Retrieve the Grammar used
+ */
+ virtual Grammar* getGrammar(const XMLCh* uri=0) =0;
+ virtual Grammar* getGrammar(const char* uri) =0;
+
+
//@}
// -----------------------------------------------------------------------
- // Virtual DTD handler interface. If handlesDTD() returns true, then
- // scanDTD() will be called when a DOCTYPE is seen.
+ // Virtual DTD handler interface.
// -----------------------------------------------------------------------
/** @name Virtual DTD handler interface */
@@ -554,20 +274,63 @@
*/
virtual bool handlesDTD() const = 0;
+ // -----------------------------------------------------------------------
+ // Virtual Schema handler interface.
+ // -----------------------------------------------------------------------
+
+ /** @name Virtual Schema handler interface */
+
+ /**
+ * This method allows the scanner to ask the validator if it handles
+ * Schema or not.
+ */
+ virtual bool handlesSchema() const = 0;
+
+ //@}
+
+ // -----------------------------------------------------------------------
+ // Setter methods
+ //
+ // setScannerInfo() is called by the scanner to tell the validator
+ // about the stuff it needs to have access to.
+ // -----------------------------------------------------------------------
+
+ /** @name Setter methods */
+ //@{
+
+ /**
+ * @param owningScanner This is a pointer to the scanner to which the
+ * validator belongs. The validator will often
+ * need to query state data from the scanner.
+ *
+ * @param readerMgr This is a pointer to the reader manager that is
+ * being used by the scanner.
+ *
+ * @param bufMgr This is the buffer manager of the scanner. This
+ * is provided as a convenience so that the validator
+ * doesn't have to create its own buffer manager
+ * during the parse process.
+ */
+ void setScannerInfo
+ (
+ XMLScanner* const owningScanner
+ , ReaderMgr* const readerMgr
+ , XMLBufferMgr* const bufMgr
+ );
+
/**
- * This method is called by the scanner when it is time for the validator
- * to parse the DTD. At the time of this call, the parser has parsed up to
- * the [ of the DOCTYPE line. This call should parse to the ]> that ends
- * the DOCTYPE line, and any external subset referenced.
+ * This method is called to set an error reporter on the validator via
+ * which it will report any errors it sees during parsing or validation.
+ * This is generally called by the owning scanner.
*
- * @param reuseValidator Indicates whether the current state of the
- * validator should be kept. If the DTD validator
- * sees any internal subset, it should consider
- * it an error for this to be true. Otherwise, it
- * just ignores any external subset and returns
- * with the state unchanged.
+ * @param errorReporter A pointer to the error reporter to use. This
+ * is not adopted, just referenced so the caller
+ * remains responsible for its cleanup, if any.
*/
- virtual void scanDTD(const bool reuseValidator) = 0;
+ void setErrorReporter
+ (
+ XMLErrorReporter* const errorReporter
+ );
//@}
@@ -638,19 +401,6 @@
XMLScanner* getScanner();
- // -----------------------------------------------------------------------
- // Protected methods
- // -----------------------------------------------------------------------
- void setBaseFields
- (
- const unsigned int emptyNamespaceId
- , const unsigned int globalNamespaceId
- , const unsigned int unknownNamespaceId
- , const unsigned int xmlNamespaceId
- , const unsigned int xmlNSNamespaceId
- );
-
-
private :
// -----------------------------------------------------------------------
// Unimplemented Constructors and Operators
@@ -662,73 +412,18 @@
// -----------------------------------------------------------------------
// Private data members
//
- // fEmptyNamespaceId
- // This is the id of the empty namespace URI. This is a special one
- // because of the xmlns="" type of deal. We have to quickly sense
- // that its the empty namespace.
- //
// fErrorReporter
// The error reporter we are to use, if any.
//
- // fGlobalNamespaceId
- // This is the id of the namespace URI which is assigned to the
- // global namespace. Its for debug purposes only, since there is no
- // real global namespace URI. Its set by the derived class.
- //
- // fUnknownNamespaceId
- // This is the id of the namespace URI which is assigned to the
- // global namespace. Its for debug purposes only, since there is no
- // real global namespace URI. Its set by the derived class.
- //
- // fXMLNamespaceId
- // fXMLNSNamespaceId
- // These are the ids of the namespace URIs which are assigned to the
- // 'xml' and 'xmlns' special prefixes. The former is officially
- // defined but the latter is not, so we just provide one for debug
- // purposes.
// -----------------------------------------------------------------------
XMLBufferMgr* fBufMgr;
- unsigned int fEmptyNamespaceId;
XMLErrorReporter* fErrorReporter;
- unsigned int fGlobalNamespaceId;
ReaderMgr* fReaderMgr;
XMLScanner* fScanner;
- unsigned int fUnknownNamespaceId;
- unsigned int fXMLNamespaceId;
- unsigned int fXMLNSNamespaceId;
};
-// ---------------------------------------------------------------------------
-// XMLValidator: Getter methods
-// ---------------------------------------------------------------------------
-inline unsigned int XMLValidator::getEmptyNamespaceId() const
-{
- return fEmptyNamespaceId;
-}
-
-inline unsigned int XMLValidator::getGlobalNamespaceId() const
-{
- return fGlobalNamespaceId;
-}
-
-inline unsigned int XMLValidator::getUnknownNamespaceId() const
-{
- return fUnknownNamespaceId;
-}
-
-inline unsigned int XMLValidator::getXMLNamespaceId() const
-{
- return fXMLNamespaceId;
-}
-
-inline unsigned int XMLValidator::getXMLNSNamespaceId() const
-{
- return fXMLNSNamespaceId;
-}
-
-
// -----------------------------------------------------------------------
// Setter methods
// -----------------------------------------------------------------------
@@ -783,22 +478,5 @@
return fScanner;
}
-
-// ---------------------------------------------------------------------------
-// XMLValidator: Protected methods
-// ---------------------------------------------------------------------------
-inline void
-XMLValidator::setBaseFields(const unsigned int emptyNamespaceId
- , const unsigned int globalNamespaceId
- , const unsigned int unknownNamespaceId
- , const unsigned int xmlNamespaceId
- , const unsigned int xmlNSNamespaceId)
-{
- fEmptyNamespaceId = emptyNamespaceId;
- fGlobalNamespaceId = globalNamespaceId;
- fUnknownNamespaceId = unknownNamespaceId;
- fXMLNamespaceId = xmlNamespaceId;
- fXMLNSNamespaceId = xmlNSNamespaceId;
-}
#endif
1.4 +7 -5 xml-xerces/c/src/framework/XMLValidityCodes.hpp
Index: XMLValidityCodes.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/framework/XMLValidityCodes.hpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- XMLValidityCodes.hpp 2001/02/15 16:46:35 1.3
+++ XMLValidityCodes.hpp 2001/03/21 21:56:03 1.4
@@ -54,11 +54,13 @@
, PrecisionExceeded = 41
, ScaleExceeded = 42
, NotFloat = 43
- , V_HighBounds = 44
- , W_LowBounds = 45
- , W_HighBounds = 46
- , E_LowBounds = 47
- , E_HighBounds = 48
+ , SchemaRootError = 44
+ , WrongTargetNamespace = 45
+ , V_HighBounds = 46
+ , W_LowBounds = 47
+ , W_HighBounds = 48
+ , E_LowBounds = 49
+ , E_HighBounds = 50
};
static bool isFatal(const XMLValid::Codes toCheck)
1.5 +34 -31 xml-xerces/c/src/internal/VecAttributesImpl.cpp
Index: VecAttributesImpl.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/internal/VecAttributesImpl.cpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- VecAttributesImpl.cpp 2001/02/26 19:44:14 1.4
+++ VecAttributesImpl.cpp 2001/03/21 21:56:04 1.5
@@ -1,37 +1,37 @@
/*
* The Apache Software License, Version 1.1
- *
+ *
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- *
+ *
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
+ * notice, this list of conditions and the following disclaimer.
+ *
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
- *
+ *
* 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
+ * if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
- *
+ *
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
- * software without prior written permission. For written
+ * software without prior written permission. For written
* permission, please contact apache\@apache.org.
- *
+ *
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
- *
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@@ -45,7 +45,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
- *
+ *
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
@@ -56,6 +56,9 @@
/*
* $Log: VecAttributesImpl.cpp,v $
+ * Revision 1.5 2001/03/21 21:56:04 tng
+ * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+ *
* Revision 1.4 2001/02/26 19:44:14 tng
* Schema: add utility class QName, by Pei Yong Zhang.
*
@@ -70,7 +73,7 @@
* Revision 1.1 2000/08/02 18:09:14 jpolast
* initial checkin: attributes vector needed for
* Attributes class as defined by sax2 spec
- *
+ *
*
*/
@@ -90,7 +93,7 @@
fAdopt(false)
, fCount(0)
, fVector(0)
- , fValidator(0)
+ , fScanner(0)
{
}
@@ -128,23 +131,23 @@
}
//fValidator->getURIText(fVector->elementAt(index)->getURIId(), tempBuf) ;
//return tempBuf.getRawBuffer() ;
- return fValidator->getURIText(fVector->elementAt(index)->getURIId());
+ return fScanner->getURIText(fVector->elementAt(index)->getURIId());
}
-const XMLCh* VecAttributesImpl::getLocalName(const unsigned int index) const
+const XMLCh* VecAttributesImpl::getLocalName(const unsigned int index) const
{
if (index >= fCount) {
return 0;
}
- return fVector->elementAt(index)->getName();
+ return fVector->elementAt(index)->getName();
}
-const XMLCh* VecAttributesImpl::getQName(const unsigned int index) const
+const XMLCh* VecAttributesImpl::getQName(const unsigned int index) const
{
if (index >= fCount) {
return 0;
}
- return fVector->elementAt(index)->getQName();
+ return fVector->elementAt(index)->getQName();
}
const XMLCh* VecAttributesImpl::getType(const unsigned int index) const
@@ -163,7 +166,7 @@
return fVector->elementAt(index)->getValue();
}
-int VecAttributesImpl::getIndex(const XMLCh* const uri, const XMLCh* const localPart ) const
+int VecAttributesImpl::getIndex(const XMLCh* const uri, const XMLCh* const localPart ) const
{
//
// Search the vector for the attribute with the given name and return
@@ -173,17 +176,17 @@
for (unsigned int index = 0; index < fCount; index++)
{
const XMLAttr* curElem = fVector->elementAt(index);
-
- fValidator->getURIText(curElem->getURIId(), uriBuffer) ;
+
+ fScanner->getURIText(curElem->getURIId(), uriBuffer) ;
if ( (!XMLString::compareString(curElem->getName(), localPart)) &&
(!XMLString::compareString(uriBuffer.getRawBuffer(), uri)) )
return index ;
}
- return -1;
+ return -1;
}
-int VecAttributesImpl::getIndex(const XMLCh* const qName ) const
+int VecAttributesImpl::getIndex(const XMLCh* const qName ) const
{
//
// Search the vector for the attribute with the given name and return
@@ -196,25 +199,25 @@
if (!XMLString::compareString(curElem->getQName(), qName))
return index ;
}
- return -1;
+ return -1;
}
-const XMLCh* VecAttributesImpl::getType(const XMLCh* const uri, const XMLCh* const localPart ) const
+const XMLCh* VecAttributesImpl::getType(const XMLCh* const uri, const XMLCh* const localPart ) const
{
return getType(getIndex(uri, localPart)) ;
}
-const XMLCh* VecAttributesImpl::getType(const XMLCh* const qName) const
+const XMLCh* VecAttributesImpl::getType(const XMLCh* const qName) const
{
return getType(getIndex(qName)) ;
}
-const XMLCh* VecAttributesImpl::getValue(const XMLCh* const uri, const XMLCh* const localPart ) const
+const XMLCh* VecAttributesImpl::getValue(const XMLCh* const uri, const XMLCh* const localPart ) const
{
return getValue(getIndex(uri, localPart)) ;
}
-const XMLCh* VecAttributesImpl::getValue(const XMLCh* const qName) const
+const XMLCh* VecAttributesImpl::getValue(const XMLCh* const qName) const
{
return getValue(getIndex(qName)) ;
}
@@ -224,7 +227,7 @@
// ---------------------------------------------------------------------------
void VecAttributesImpl::setVector(const RefVectorOf<XMLAttr>* const srcVec
, const unsigned int count
- , const XMLValidator * const validator
+ , const XMLScanner * const scanner
, const bool adopt)
{
//
@@ -238,6 +241,6 @@
fAdopt = adopt;
fCount = count;
fVector = srcVec;
- fValidator = validator ;
+ fScanner = scanner ;
}
1.4 +20 -17 xml-xerces/c/src/internal/VecAttributesImpl.hpp
Index: VecAttributesImpl.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/internal/VecAttributesImpl.hpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- VecAttributesImpl.hpp 2001/02/26 19:44:15 1.3
+++ VecAttributesImpl.hpp 2001/03/21 21:56:04 1.4
@@ -1,37 +1,37 @@
/*
* The Apache Software License, Version 1.1
- *
+ *
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- *
+ *
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
+ * notice, this list of conditions and the following disclaimer.
+ *
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
- *
+ *
* 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
+ * if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
- *
+ *
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
- * software without prior written permission. For written
+ * software without prior written permission. For written
* permission, please contact apache\@apache.org.
- *
+ *
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
- *
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@@ -45,7 +45,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
- *
+ *
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
@@ -56,6 +56,9 @@
/*
* $Log: VecAttributesImpl.hpp,v $
+ * Revision 1.4 2001/03/21 21:56:04 tng
+ * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+ *
* Revision 1.3 2001/02/26 19:44:15 tng
* Schema: add utility class QName, by Pei Yong Zhang.
*
@@ -77,7 +80,7 @@
#include <sax2/Attributes.hpp>
#include <framework/XMLAttr.hpp>
#include <util/RefVectorOf.hpp>
-#include <framework/XMLValidator.hpp>
+#include <internal/XMLScanner.hpp>
#include <framework/XMLBuffer.hpp>
class XMLPARSER_EXPORT VecAttributesImpl : public Attributes
@@ -118,7 +121,7 @@
(
const RefVectorOf<XMLAttr>* const srcVec
, const unsigned int count
- , const XMLValidator * const validator
+ , const XMLScanner * const scanner
, const bool adopt = false
);
@@ -147,8 +150,8 @@
// fVector
// The vector that provides the backing for the list.
//
- // fValidator
- // This is a pointer to the in use validator, so that we can resolve
+ // fScanner
+ // This is a pointer to the in use Scanner, so that we can resolve
// namespace URIs from UriIds
//
// fURIBuffer
@@ -157,7 +160,7 @@
bool fAdopt;
unsigned int fCount;
const RefVectorOf<XMLAttr>* fVector;
- const XMLValidator * fValidator ;
+ const XMLScanner * fScanner ;
//XMLBuffer fURIBuffer ;
};
1.29 +223 -135 xml-xerces/c/src/internal/XMLScanner.cpp
Index: XMLScanner.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/internal/XMLScanner.cpp,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- XMLScanner.cpp 2001/03/06 18:50:58 1.28
+++ XMLScanner.cpp 2001/03/21 21:56:04 1.29
@@ -55,7 +55,7 @@
*/
/*
- * $Id: XMLScanner.cpp,v 1.28 2001/03/06 18:50:58 tng Exp $
+ * $Id: XMLScanner.cpp,v 1.29 2001/03/21 21:56:04 tng Exp $
*/
@@ -78,15 +78,14 @@
#include <framework/LocalFileInputSource.hpp>
#include <framework/URLInputSource.hpp>
#include <framework/XMLDocumentHandler.hpp>
-#include <framework/XMLElementDecl.hpp>
#include <framework/XMLErrorReporter.hpp>
-#include <framework/XMLEntityDecl.hpp>
#include <framework/XMLEntityHandler.hpp>
#include <framework/XMLPScanToken.hpp>
#include <framework/XMLValidator.hpp>
#include <framework/XMLValidityCodes.hpp>
#include <internal/XMLScanner.hpp>
#include <internal/EndOfEntityException.hpp>
+#include <validators/DTD/DTDScanner.hpp>
@@ -96,7 +95,19 @@
static XMLUInt32 gScannerId;
static XMLMsgLoader* gMsgLoader;
+// ---------------------------------------------------------------------------
+// Local const data
+//
+// These are the text for the require char refs that must always be present.
+// We init these into the entity pool upon construction.
+// ---------------------------------------------------------------------------
+static const XMLCh gAmp[] = { chLatin_a, chLatin_m, chLatin_p, chNull };
+static const XMLCh gLT[] = { chLatin_l, chLatin_t, chNull };
+static const XMLCh gGT[] = { chLatin_g, chLatin_t, chNull };
+static const XMLCh gQuot[] = { chLatin_q, chLatin_u, chLatin_o, chLatin_t, chNull };
+static const XMLCh gApos[] = { chLatin_a, chLatin_p, chLatin_o, chLatin_s, chNull };
+
// ---------------------------------------------------------------------------
// Local, static functions
// ---------------------------------------------------------------------------
@@ -138,55 +149,86 @@
// ---------------------------------------------------------------------------
// XMLScanner: Constructors and Destructor
// ---------------------------------------------------------------------------
-XMLScanner::XMLScanner(XMLValidator* const validator) :
+XMLScanner::XMLScanner(XMLValidator* const valToAdopt) :
fAttrList(0)
, fDocHandler(0)
+ , fDocTypeHandler(0)
, fDoNamespaces(false)
, fEntityHandler(0)
, fErrorReporter(0)
, fExitOnFirstFatal(true)
- , fHaveSubset(false)
, fIDRefList(0)
, fInException(false)
, fRawAttrList(0)
- , fReuseValidator(false)
+ , fReuseGrammar(false)
, fScannerId(0)
, fSequenceId(0)
, fStandalone(false)
, fValidate(false)
- , fValidator(validator)
+ , fValidator(valToAdopt)
+ , fValidatorFromUser(false)
, fValScheme(Val_Never)
, fSchemaValidation(false)
-{
- commonInit();
-}
-
-XMLScanner::XMLScanner( XMLDocumentHandler* const docHandler
- , XMLEntityHandler* const entityHandler
- , XMLErrorReporter* const errHandler
- , XMLValidator* const validator) :
+ , fEmptyNamespaceId(0)
+ , fGlobalNamespaceId(0)
+ , fUnknownNamespaceId(0)
+ , fXMLNamespaceId(0)
+ , fXMLNSNamespaceId(0)
+ , fGrammarResolver(0)
+ , fGrammar(0)
+ , fEntityDeclPool(0)
+ , fURIStringPool(0)
+{
+ commonInit();
+
+ if (fValidator) {
+ fValidatorFromUser = true;
+ initValidator();
+ }
+}
+
+XMLScanner::XMLScanner( XMLDocumentHandler* const docHandler
+ , DocTypeHandler* const docTypeHandler
+ , XMLEntityHandler* const entityHandler
+ , XMLErrorReporter* const errHandler
+ , XMLValidator* const valToAdopt) :
fAttrList(0)
, fDocHandler(docHandler)
+ , fDocTypeHandler(docTypeHandler)
, fDoNamespaces(false)
, fEntityHandler(entityHandler)
, fErrorReporter(errHandler)
, fExitOnFirstFatal(true)
- , fHaveSubset(false)
, fIDRefList(0)
, fInException(false)
, fRawAttrList(0)
- , fReuseValidator(false)
+ , fReuseGrammar(false)
, fScannerId(0)
, fSequenceId(0)
, fStandalone(false)
, fValidate(false)
- , fValidator(validator)
+ , fValidator(valToAdopt)
+ , fValidatorFromUser(false)
, fValScheme(Val_Never)
, fSchemaValidation(false)
-{
- commonInit();
+ , fEmptyNamespaceId(0)
+ , fGlobalNamespaceId(0)
+ , fUnknownNamespaceId(0)
+ , fXMLNamespaceId(0)
+ , fXMLNSNamespaceId(0)
+ , fGrammarResolver(0)
+ , fGrammar(0)
+ , fEntityDeclPool(0)
+ , fURIStringPool(0)
+{
+ commonInit();
+
+ if (fValidator){
+ fValidatorFromUser = true;
+ initValidator();
+ }
}
XMLScanner::~XMLScanner()
@@ -194,6 +236,13 @@
delete fAttrList;
delete fIDRefList;
delete fRawAttrList;
+ delete fValidator;
+ delete fEntityDeclPool;
+
+ //fGrammarResolver will delete the fGrammar as well
+ delete fGrammarResolver;
+
+ delete fURIStringPool;
}
@@ -201,7 +250,7 @@
// XMLScanner: Main entry point to scan a document
// ---------------------------------------------------------------------------
void XMLScanner::scanDocument( const XMLCh* const systemId
- , const bool reuseValidator)
+ , const bool reuseGrammar)
{
//
// First we try to parse it as a URL. If that fails, we assume its
@@ -239,20 +288,20 @@
}
Janitor<InputSource> janSrc(srcToUse);
- scanDocument(*srcToUse, reuseValidator);
+ scanDocument(*srcToUse, reuseGrammar);
}
void XMLScanner::scanDocument( const char* const systemId
- , const bool reuseValidator)
+ , const bool reuseGrammar)
{
// We just delegate this to the XMLCh version after transcoding
XMLCh* tmpBuf = XMLString::transcode(systemId);
ArrayJanitor<XMLCh> janBuf(tmpBuf);
- scanDocument(tmpBuf, reuseValidator);
+ scanDocument(tmpBuf, reuseGrammar);
}
-void XMLScanner::scanDocument(const InputSource& src, const bool reuseValidator)
+void XMLScanner::scanDocument(const InputSource& src, const bool reuseGrammar)
{
//
// Bump up the sequence id for this parser instance. This will invalidate
@@ -261,11 +310,8 @@
fSequenceId++;
// Store the reuse validator flag
- fReuseValidator = reuseValidator;
+ fReuseGrammar = reuseGrammar;
- // Clear some flags for new round
- fHaveSubset = false;
-
try
{
//
@@ -286,16 +332,6 @@
scanProlog();
//
- // At this point, we know which type of validation we are going to
- // use (if the plugged in validator handles either DTD or Schemas)
- // since we will have seen the DOCTYPE or PI that set it up. So lets
- // ask the validator whether it requires namespaces or not. If it
- // does, we have to override the namespace enablement flag.
- //
- if (fValidator->requiresNamespaces() && !fDoNamespaces)
- fDoNamespaces = true;
-
- //
// If we got to the end of input, then its not a valid XML file.
// Else, go on to scan the content.
//
@@ -305,18 +341,6 @@
}
else
{
- //
- // Set our validation flag at this point. If the validation
- // scheme is not auto, then take that. Else see if we saw any
- // subset.
- //
- if (fValScheme == Val_Never)
- fValidate = false;
- else if (fValScheme == Val_Always)
- fValidate = true;
- else
- fValidate = fHaveSubset;
-
// Scan content, and tell it its not an external entity
if (scanContent(false))
{
@@ -424,7 +448,7 @@
//
bool XMLScanner::scanFirst( const XMLCh* const systemId
, XMLPScanToken& toFill
- , const bool reuseValidator)
+ , const bool reuseGrammar)
{
//
// First we try to parse it as a URL. If that fails, we assume its
@@ -456,25 +480,25 @@
}
Janitor<InputSource> janSrc(srcToUse);
- return scanFirst(*srcToUse, toFill, reuseValidator);
+ return scanFirst(*srcToUse, toFill, reuseGrammar);
}
bool XMLScanner::scanFirst( const char* const systemId
, XMLPScanToken& toFill
- , const bool reuseValidator)
+ , const bool reuseGrammar)
{
// We just delegate this to the XMLCh version after transcoding
XMLCh* tmpBuf = XMLString::transcode(systemId);
ArrayJanitor<XMLCh> janBuf(tmpBuf);
- return scanFirst(tmpBuf, toFill, reuseValidator);
+ return scanFirst(tmpBuf, toFill, reuseGrammar);
}
bool XMLScanner::scanFirst( const InputSource& src
, XMLPScanToken& toFill
- , const bool reuseValidator)
+ , const bool reuseGrammar)
{
// Store the reuse validator flag
- fReuseValidator = reuseValidator;
+ fReuseGrammar = reuseGrammar;
//
// Bump up the sequence id for this new scan cycle. This will invalidate
@@ -493,9 +517,6 @@
if (fDocHandler)
fDocHandler->startDocument();
- // Clear some flags for new round
- fHaveSubset = false;
-
try
{
//
@@ -504,28 +525,6 @@
// first.
//
scanProlog();
-
- //
- // At this point, we know which type of validation we are going to
- // use (if the plugged in validator handles either DTD or Schemas)
- // since we will have seen the DOCTYPE or PI that set it up. So lets
- // ask the validator whether it requires namespaces or not. If it
- // does, we have to override the namespace enablement flag.
- //
- if (fValidator->requiresNamespaces() && !fDoNamespaces)
- fDoNamespaces = true;
-
- //
- // Set our validation flag at this point. If the validation
- // scheme is not auto, then take that. Else see if we saw any
- // subset.
- //
- if (fValScheme == Val_Never)
- fValidate = false;
- else if (fValScheme == Val_Always)
- fValidate = true;
- else
- fValidate = fHaveSubset;
}
//
@@ -844,14 +843,63 @@
//
fIDRefList = new RefHashTableOf<XMLRefInfo>(109);
+ // Create the EntityDeclPool
+ fEntityDeclPool = new NameIdPool<DTDEntityDecl>(109);
+
+ // Create the GrammarResolver
+ fGrammarResolver = new GrammarResolver();
+
+ resetEntityDeclPool();
+}
+
+
+
+void XMLScanner::initValidator() {
//
// Tell the validator about the stuff it needs to know in order to
// do its work.
//
fValidator->setScannerInfo(this, &fReaderMgr, &fBufMgr);
+ fValidator->setErrorReporter(fErrorReporter);
+
+ // So lets ask the validator whether it requires namespaces or not. If it
+ // does, we have to override the namespace enablement flag.
+ if (fValidator->requiresNamespaces() && !fDoNamespaces)
+ setDoNamespaces(true);
+
+ if (fValidator->handlesSchema())
+ ((SchemaValidator*) fValidator)->setGrammarResolver(fGrammarResolver);
}
+void XMLScanner::resetEntityDeclPool() {
+ fEntityDeclPool->removeAll();
+ //
+ // Add the default entity entries for the character refs that must always
+ // be present. We indicate that they are from the internal subset. They
+ // aren't really, but they have to look that way so that they are still
+ // valid for use within a standalone document.
+ //
+ // We also mark them as special char entities, which allows them to be
+ // used in places whether other non-numeric general entities cannot.
+ //
+ fEntityDeclPool->put(new DTDEntityDecl(gAmp, chAmpersand, true, true));
+ fEntityDeclPool->put(new DTDEntityDecl(gLT, chOpenAngle, true, true));
+ fEntityDeclPool->put(new DTDEntityDecl(gGT, chCloseAngle, true, true));
+ fEntityDeclPool->put(new DTDEntityDecl(gQuot, chDoubleQuote, true, true));
+ fEntityDeclPool->put(new DTDEntityDecl(gApos, chSingleQuote, true, true));
+}
+
+void XMLScanner::resetURIPool() {
+ fURIStringPool->flushAll();
+
+ fEmptyNamespaceId = fURIStringPool->addOrFind(XMLUni::fgZeroLenString);
+ fGlobalNamespaceId = fURIStringPool->addOrFind(XMLUni::fgGlobalNSURIName);
+ fUnknownNamespaceId = fURIStringPool->addOrFind(XMLUni::fgUnknownURIName);
+ fXMLNamespaceId = fURIStringPool->addOrFind(XMLUni::fgXMLURIName);
+ fXMLNSNamespaceId = fURIStringPool->addOrFind(XMLUni::fgXMLNSURIName);
+}
+
// ---------------------------------------------------------------------------
// XMLScanner: Error emitting methods
// ---------------------------------------------------------------------------
@@ -1507,17 +1555,17 @@
// Ask the validator for the element id for the {uri}name we got. He owns
// the element decl pool.
//
- elemId = fValidator->findElemId
+ elemId = fGrammar->getElemId
(
uriId
, bbName.getBuffer().getRawBuffer()
- , bbPrefix.getBuffer().getRawBuffer()
, qnameBuf.getRawBuffer()
+ , 0
);
}
else
{
- elemId = fValidator->findElemId(0, 0, 0, qnameBuf.getRawBuffer());
+ elemId = fGrammar->getElemId(0, 0, qnameBuf.getRawBuffer(), 0);
}
//
@@ -1598,7 +1646,7 @@
fValidator->emitError
(
XMLValid::EmptyNotValidForContent
- , topElem->fThisElement->getFormattedContentModel(*fValidator)
+ , topElem->fThisElement->getFormattedContentModel(*fGrammar)
);
}
else if ((unsigned int)res >= topElem->fChildCount)
@@ -1606,13 +1654,13 @@
fValidator->emitError
(
XMLValid::NotEnoughElemsForCM
- , topElem->fThisElement->getFormattedContentModel(*fValidator)
+ , topElem->fThisElement->getFormattedContentModel(*fGrammar)
);
}
else
{
// Find the element decl for the evil spawn
- XMLElementDecl* decl = fValidator->getElemDecl
+ XMLElementDecl* decl = fGrammar->getElemDecl
(
topElem->fChildIds[res]
);
@@ -1621,7 +1669,7 @@
(
XMLValid::ElementNotValidForContent
, decl->getFullName()
- , topElem->fThisElement->getFormattedContentModel(*fValidator)
+ , topElem->fThisElement->getFormattedContentModel(*fGrammar)
);
}
}
@@ -1900,18 +1948,49 @@
}
else if (fReaderMgr.skippedString(XMLUni::fgDocTypeString))
{
+
//
- // We have a doc type. So, ask the validator if it
- // supports DTD scanning. if so, let it scan the
- // DTD.
+ // We have a doc type. So, create a DTDScanner and
+ // store the Grammar in DTDGrammar.
//
- if (fValidator->handlesDTD())
- fValidator->scanDTD(fReuseValidator);
- else
- ThrowXML(RuntimeException, XMLExcepts::Gen_NoDTDValidator);
+
+ DTDScanner dtdScanner((DTDGrammar*)fGrammar, fDocTypeHandler);
+ dtdScanner.setScannerInfo(this, &fReaderMgr, &fBufMgr);
+ dtdScanner.scanDocTypeDecl(fReuseGrammar);
+
+ //
+ // Since we have seen a grammar, set our validation flag
+ // at this point if the validation scheme is auto
+ //
+ if (fValScheme == Val_Auto)
+ fValidate = true;
+
+ // if validating, then set up the validator
+ if (fValidate) {
+ if (fValidator) {
+ if (!fValidator->handlesDTD())
+ ThrowXML(RuntimeException, XMLExcepts::Gen_NoDTDValidator);
+ }
+ else {
+ fValidator = new DTDValidator();
+ initValidator();
+ }
+
+ ((DTDValidator*) fValidator)->setDTDGrammar((DTDGrammar*)fGrammar);
+ //
+ // At this point, we know which type of validation we are going to
+ // use (if the plugged in validator handles either DTD or Schemas)
+ // since we will have seen the DOCTYPE or PI that set it up. So lets
+ // ask the validator whether it requires namespaces or not. If it
+ // does, we have to override the namespace enablement flag.
+ //
+ if (fValidator->requiresNamespaces() && !fDoNamespaces)
+ fDoNamespaces = true;
- // Set the 'have subset' flag
- fHaveSubset = true;
+ // if validating, then validate the DTD scan so far
+ fValidator->preContentValidation(fReuseGrammar);
+ }
+
}
else
{
@@ -2002,13 +2081,13 @@
// We tell him to fault in a decl if he does not find one.
//
bool wasAdded;
- XMLElementDecl* elemDecl = fValidator->findElemDecl
+ XMLElementDecl* elemDecl = fGrammar->findOrAddElemDecl
(
0
, 0
, 0
, fQNameBuf.getRawBuffer()
- , XMLValidator::AddIfNotFound
+ , 0
, wasAdded
);
@@ -2212,7 +2291,7 @@
{
// This is to tell the reuse Validator that this attribute was
// faulted-in, was not an attribute in the attdef originally
- if(!fReuseValidator)
+ if(!fReuseGrammar)
attDef->setCreateReason(XMLAttDef::JustFaultIn);
fValidator->emitError
@@ -2229,7 +2308,7 @@
// then emit an error
if (fValidate)
{
- if (fReuseValidator && attDef->getCreateReason()==XMLAttDef::JustFaultIn)
+ if (fReuseGrammar && attDef->getCreateReason()==XMLAttDef::JustFaultIn)
{
//reset the CreateReason to avoid redundant error
attDef->setCreateReason(XMLAttDef::NoReason);
@@ -2316,11 +2395,14 @@
if (!wasAdded)
{
// Let the validator pass judgement on the attribute value
- fValidator->validateAttrValue
- (
- *attDef
- , fAttValueBuf.getRawBuffer()
- );
+ if (fValidate)
+ {
+ fValidator->validateAttrValue
+ (
+ *attDef
+ , fAttValueBuf.getRawBuffer()
+ );
+ }
}
//
@@ -2333,7 +2415,7 @@
{
curAtt = new XMLAttr
(
- fValidator->getEmptyNamespaceId()
+ -1
, fAttNameBuf.getRawBuffer()
, XMLUni::fgZeroLenString
, fAttValueBuf.getRawBuffer()
@@ -2347,7 +2429,7 @@
curAtt = fAttrList->elementAt(attCount);
curAtt->set
(
- fValidator->getEmptyNamespaceId()
+ -1
, fAttNameBuf.getRawBuffer()
, XMLUni::fgZeroLenString
, fAttValueBuf.getRawBuffer()
@@ -2459,7 +2541,7 @@
{
curAtt = new XMLAttr
(
- fValidator->getEmptyNamespaceId()
+ -1
, curDef.getFullName()
, XMLUni::fgZeroLenString
, curDef.getValue()
@@ -2474,7 +2556,7 @@
curAtt = fAttrList->elementAt(attCount);
curAtt->set
(
- fValidator->getEmptyNamespaceId()
+ -1
, curDef.getFullName()
, XMLUni::fgZeroLenString
, curDef.getValue()
@@ -2505,7 +2587,7 @@
(
XMLValid::ElementNotValidForContent
, elemDecl->getFullName()
- , elemDecl->getFormattedContentModel(*fValidator)
+ , elemDecl->getFormattedContentModel(*fGrammar)
);
}
}
@@ -2619,28 +2701,11 @@
fElemStack.addLevel();
//
- // Make an initial pass through the list and find any xmlns attributes.
- // When we find one, send it off to be used to update the element stack's
- // namespace mappings.
+ // Make an initial pass through the list and find any xmlns attributes or
+ // schema attributes.
//
if (attCount)
- {
- for (unsigned int index = 0; index < attCount; index++)
- {
- //
- // If either the key begins with "xmlns:" or its just plain
- // "xmlns", then use it to update the map.
- //
- const KVStringPair* curPair = fRawAttrList->elementAt(index);
- if (!XMLString::compareNString( curPair->getKey()
- , XMLUni::fgXMLNSColonString
- , 6)
- || !XMLString::compareString(curPair->getKey(), XMLUni::fgXMLNSString))
- {
- updateNSMap(curPair->getKey(), curPair->getValue());
- }
- }
- }
+ scanRawAttrListforNameSpaces(fRawAttrList, attCount);
//
// Resolve the qualified name to a URI and name so that we can look up
@@ -2667,13 +2732,13 @@
// not find it.
//
bool wasAdded;
- XMLElementDecl* elemDecl = fValidator->findElemDecl
+ XMLElementDecl* elemDecl = fGrammar->findOrAddElemDecl
(
uriId
, fNameBuf.getRawBuffer()
, fPrefixBuf.getRawBuffer()
, fQNameBuf.getRawBuffer()
- , XMLValidator::AddIfNotFound
+ , 0
, wasAdded
);
@@ -2780,7 +2845,7 @@
(
XMLValid::ElementNotValidForContent
, elemDecl->getFullName()
- , elemDecl->getFormattedContentModel(*fValidator)
+ , elemDecl->getFormattedContentModel(*fGrammar)
);
}
}
@@ -3023,3 +3088,26 @@
emitError(XMLErrs::ContradictoryEncoding, bbEncoding.getRawBuffer());
}
}
+
+const XMLCh* XMLScanner::getURIText(const unsigned int uriId) const
+{
+ // Look up the URI in the string pool and return its id
+ const XMLCh* value = fURIStringPool->getValueForId(uriId);
+ if (!value)
+ return XMLUni::fgZeroLenString;
+
+ return value;
+}
+
+bool XMLScanner::getURIText( const unsigned int uriId
+ , XMLBuffer& uriBufToFill) const
+{
+ // Look up the URI in the string pool and return its id
+ const XMLCh* value = fURIStringPool->getValueForId(uriId);
+ if (!value)
+ return false;
+
+ uriBufToFill.set(value);
+ return true;
+}
+
1.11 +267 -51 xml-xerces/c/src/internal/XMLScanner.hpp
Index: XMLScanner.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/internal/XMLScanner.hpp,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- XMLScanner.hpp 2001/02/15 15:56:27 1.10
+++ XMLScanner.hpp 2001/03/21 21:56:05 1.11
@@ -56,6 +56,9 @@
/*
* $Log: XMLScanner.hpp,v $
+ * Revision 1.11 2001/03/21 21:56:05 tng
+ * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+ *
* Revision 1.10 2001/02/15 15:56:27 tng
* Schema: Add setSchemaValidation and getSchemaValidation for DOMParser and SAXParser.
* Add feature "http://apache.org/xml/features/validation/schema" for SAX2XMLReader.
@@ -119,13 +122,17 @@
#include <framework/XMLPScanToken.hpp>
#include <internal/ElemStack.hpp>
#include <internal/ReaderMgr.hpp>
+#include <validators/DTD/DTDValidator.hpp>
+#include <validators/schema/SchemaValidator.hpp>
class InputSource;
class XMLDocumentHandler;
-class XMLDocumentTypeHandler;
+class DocTypeHandler;
class XMLElementDecl;
class XMLEntityHandler;
+class EntityResolver;
class XMLErrorReporter;
+class ErrorHandler;
class XMLMsgLoader;
class XMLValidator;
@@ -199,14 +206,15 @@
// -----------------------------------------------------------------------
XMLScanner
(
- XMLValidator* const validator
+ XMLValidator* const valToAdopt
);
XMLScanner
(
- XMLDocumentHandler* const docHandler
- , XMLEntityHandler* const entityHandler
- , XMLErrorReporter* const errReporter
- , XMLValidator* const validator
+ XMLDocumentHandler* const docHandler
+ , DocTypeHandler* const docTypeHandler
+ , XMLEntityHandler* const entityHandler
+ , XMLErrorReporter* const errReporter
+ , XMLValidator* const valToAdopt
);
~XMLScanner();
@@ -238,6 +246,8 @@
// -----------------------------------------------------------------------
const XMLDocumentHandler* getDocHandler() const;
XMLDocumentHandler* getDocHandler();
+ const DocTypeHandler* getDocTypeHandler() const;
+ DocTypeHandler* getDocTypeHandler();
bool getDoNamespaces() const;
ValSchemes getValidationScheme() const;
bool getSchemaValidation() const;
@@ -263,18 +273,88 @@
bool getStandalone() const;
const XMLValidator* getValidator() const;
XMLValidator* getValidator();
+ const Grammar* getCurrentGrammar() const;
+ Grammar* getCurrentGrammar();
+
+ // -----------------------------------------------------------------------
+ // Getter methods
+ // -----------------------------------------------------------------------
+ /**
+ * When an attribute name has no prefix, unlike elements, it is not mapped
+ * to the global namespace. So, in order to have something to map it to
+ * for practical purposes, a id for an empty URL is created and used for
+ * such names.
+ *
+ * @return The URL pool id of the URL for an empty URL "".
+ */
+ unsigned int getEmptyNamespaceId() const;
+
+ /**
+ * When namespaces are enabled, any elements whose names have no prefix
+ * are mapped to a global namespace. This is the URL id for the URL
+ * to which those names are mapped. It has no official standard text,
+ * but the parser must use some id here.
+ *
+ * @return The URL pool id of the URL for the global namespace.
+ */
+ unsigned int getGlobalNamespaceId() const;
+
+ /**
+ * When a prefix is found that has not been mapped, an error is issued.
+ * However, if the parser has been instructed not to stop on the first
+ * fatal error, it needs to be able to continue. To do so, it will map
+ * that prefix tot his magic unknown namespace id.
+ *
+ * @return The URL pool id of the URL for the unknown prefix
+ * namespace.
+ */
+ unsigned int getUnknownNamespaceId() const;
+
+ /**
+ * The prefix 'xml' is a magic prefix, defined by the XML spec and
+ * requiring no prior definition. This method returns the id for the
+ * intrinsically defined URL for this prefix.
+ *
+ * @return The URL pool id of the URL for the 'xml' prefix.
+ */
+ unsigned int getXMLNamespaceId() const;
+
+ /**
+ * The prefix 'xmlns' is a magic prefix, defined by the namespace spec
+ * and requiring no prior definition. This method returns the id for the
+ * intrinsically defined URL for this prefix.
+ *
+ * @return The URL pool id of the URL for the 'xmlns' prefix.
+ */
+ unsigned int getXMLNSNamespaceId() const;
+
+ /**
+ * This method find the passed URI id in its URI pool and
+ * copy the text of that URI into the passed buffer.
+ */
+ bool getURIText
+ (
+ const unsigned int uriId
+ , XMLBuffer& uriBufToFill
+ ) const;
+ const XMLCh* getURIText(const unsigned int uriId) const;
+
+
// -----------------------------------------------------------------------
// Setter methods
// -----------------------------------------------------------------------
void setDocHandler(XMLDocumentHandler* const docHandler);
+ void setDocTypeHandler(DocTypeHandler* const docTypeHandler);
void setDoNamespaces(const bool doNamespaces);
void setEntityHandler(XMLEntityHandler* const docTypeHandler);
+ void setEntityResolver(EntityResolver* const handler);
void setErrorReporter(XMLErrorReporter* const errHandler);
+ void setErrorHandler(ErrorHandler* const handler);
void setExitOnFirstFatal(const bool newValue);
void setValidationScheme(const ValSchemes newScheme);
- void setValidator(XMLValidator* const validator);
+ void setValidator(XMLValidator* const valToAdopt);
void setSchemaValidation(const bool doSchema);
// -----------------------------------------------------------------------
@@ -294,36 +374,36 @@
void scanDocument
(
const InputSource& src
- , const bool reuseValidator = false
+ , const bool reuseGrammar = false
);
void scanDocument
(
const XMLCh* const systemId
- , const bool reuseValidator = false
+ , const bool reuseGrammar = false
);
void scanDocument
(
const char* const systemId
- , const bool reuseValidator = false
+ , const bool reuseGrammar = false
);
bool scanFirst
(
const InputSource& src
, XMLPScanToken& toFill
- , const bool reuseValidator = false
+ , const bool reuseGrammar = false
);
bool scanFirst
(
const XMLCh* const systemId
, XMLPScanToken& toFill
- , const bool reuseValidator = false
+ , const bool reuseGrammar = false
);
bool scanFirst
(
const char* const systemId
, XMLPScanToken& toFill
- , const bool reuseValidator = false
+ , const bool reuseGrammar = false
);
bool scanNext(XMLPScanToken& toFill);
@@ -342,13 +422,6 @@
, IDType_Either
};
- enum DTDSubsets
- {
- Subset_Internal
- , Subset_External
- };
-
-
// -----------------------------------------------------------------------
// Unimplemented constructors and operators
// -----------------------------------------------------------------------
@@ -361,6 +434,9 @@
// Private helper methods
// -----------------------------------------------------------------------
void commonInit();
+ void initValidator();
+ void resetEntityDeclPool();
+ void resetURIPool();
// -----------------------------------------------------------------------
@@ -385,6 +461,7 @@
, const XMLAttDef::AttTypes type
, XMLBuffer& toFill
);
+
unsigned int resolveQName
(
const XMLCh* const qName
@@ -420,6 +497,9 @@
, const XMLCh* const fullName
, const XMLCh* const enumList
);
+ void scanRawAttrListforNameSpaces(const RefVectorOf<KVStringPair>* theRawAttrList, int attCount);
+ void parseSchemaLocation(const XMLCh* const schemaLocationStr);
+ void resolveSchemaGrammar(const XMLCh* const loc, const XMLCh* const uri);
// -----------------------------------------------------------------------
@@ -448,7 +528,6 @@
bool scanCharRef(XMLCh& toFill, XMLCh& second);
void scanComment();
bool scanContent(const bool extEntity);
- void scanDocTypeDecl();
void scanEndTag(bool& gotData);
EntityExpRes scanEntityRef
(
@@ -492,13 +571,6 @@
// just reuse it over and over, allowing it to grow to meet the
// peek need.
//
- // fBaseDir
- // This is the base directory, from which the initial XML file
- // was loaded. It is set after the file is successfully opened,
- // so we know it to be valid. If the initial file had no path
- // component, then this is left null. It is used to handle relative
- // paths of DTD and external entity system ids.
- //
// fBufMgr
// This is a manager for temporary buffers used during scanning.
// For efficiency we must use a set of static buffers, but we have
@@ -509,6 +581,9 @@
// The client code's document handler. If zero, then no document
// handler callouts are done. We don't adopt it.
//
+ // fDocTypeHandler
+ // The client code's document type handler (used by DTD Validator).
+ //
// fDoNamespaces
// This flag indicates whether the client code wants us to do
// namespaces or not. If the installed validator indicates that it
@@ -522,20 +597,23 @@
// The client code's entity handler. If zero, then no entity handler
// callouts are done. We don't adopt it.
//
+ // fEntityResolver
+ // The client code's entity resolver. Need to store this info for
+ // Schema parse entity resolving.
+ //
// fErrorReporter
- // The client code's error handler. If zero, then no error handler
+ // The client code's error reporter. If zero, then no error reporter
// callouts are done. We don't adopt it.
//
+ // fErrorHandler
+ // The client code's error handler. Need to store this info for
+ // Schema parse error handling.
+ //
// fExitOnFirstFatal
// This indicates whether we bail out on the first fatal XML error
// or not. It defaults to true, which is the strict XML way, but it
// can be changed.
//
- // fHaveSubset
- // Indicates whether any internal/external DTD subset has been seen
- // so far. Its cleared before a new parse, so it is used along with
- // fValScheme to know whether we should validate or not.
- //
// fIDRefList
// This is a list of XMLRefInfo objects. This member lets us do all
// needed ID-IDREF balancing checks.
@@ -556,11 +634,11 @@
// methods to do specialized checking for chars, sequences of chars,
// skipping chars, etc...
//
- // fReuseValidator
+ // fReuseGrammar
// This flag is set on a per-scan basis. So its provided in the
// scanDocument() and scanFirst() methods, and applies for that
- // one pass. It indicates that the validator should not be reused
- // and that any external structural description should be ignored.
+ // one pass. It indicates if the Grammar should be reused or not.
+ // If so, then all the Grammar will be ignored.
// There cannot be any internal subset.
//
// fScannerId
@@ -573,15 +651,17 @@
// no, but can be overridden in the XMLDecl.
//
// fValidate
- // Indicates whether any validation should be done. Once we reach
- // the point past the DOCTYPE, we check fHaveSubset and fValScheme
- // and use them to set this flag, which is then used to control
- // whether validation is done.
+ // Indicates whether any validation should be done. This is defined
+ // by the existence of a Grammar together with fValScheme.
//
// fValidator
// The installed validator. We look at them via the abstract
// validator interface, and don't know what it actual is.
//
+ // fValidatorFromUser
+ // This flag indicates whether the validator was installed from
+ // user. If false, then the validator was created by the Scanner.
+ //
// fValScheme
// This is the currently set validation scheme. It defaults to
// 'never', but can be set by the client.
@@ -601,27 +681,68 @@
// fixed buffers for performance reasons. These are used a lot and
// there are a number of them, so asking the buffer manager each
// time for new buffers is a bit too much overhead.
+ //
+ // fEmptyNamespaceId
+ // This is the id of the empty namespace URI. This is a special one
+ // because of the xmlns="" type of deal. We have to quickly sense
+ // that its the empty namespace.
+ //
+ // fGlobalNamespaceId
+ // This is the id of the namespace URI which is assigned to the
+ // global namespace. Its for debug purposes only, since there is no
+ // real global namespace URI. Its set by the derived class.
+ //
+ // fUnknownNamespaceId
+ // This is the id of the namespace URI which is assigned to the
+ // global namespace. Its for debug purposes only, since there is no
+ // real global namespace URI. Its set by the derived class.
+ //
+ // fXMLNamespaceId
+ // fXMLNSNamespaceId
+ // These are the ids of the namespace URIs which are assigned to the
+ // 'xml' and 'xmlns' special prefixes. The former is officially
+ // defined but the latter is not, so we just provide one for debug
+ // purposes.
+ //
+ // fGrammarResolver
+ // Grammar Pool that stores all the Grammar
+ //
+ // fGrammar
+ // Current Grammar used by the Scanner and Validator
+ //
+ // fEntityDeclPool
+ // This is a pool of EntityDecl objects, which contains all of the
+ // general entities that are declared in the DTD subsets, plus the
+ // default entities (such as > < ...) defined by the XML Standard.
+ //
+ // fURIStringPool
+ // This is a pool for URIs with unique ids assigned. We use a standard
+ // string pool class. This pool is going to be shared by all Grammar.
+ // Use only if namespace is turned on.
+ //
// -----------------------------------------------------------------------
RefVectorOf<XMLAttr>* fAttrList;
- XMLCh* fBaseDir;
XMLBufferMgr fBufMgr;
XMLDocumentHandler* fDocHandler;
+ DocTypeHandler* fDocTypeHandler;
bool fDoNamespaces;
ElemStack fElemStack;
XMLEntityHandler* fEntityHandler;
+ EntityResolver* fEntityResolver;
XMLErrorReporter* fErrorReporter;
+ ErrorHandler* fErrorHandler;
bool fExitOnFirstFatal;
- bool fHaveSubset;
RefHashTableOf<XMLRefInfo>* fIDRefList;
bool fInException;
RefVectorOf<KVStringPair>* fRawAttrList;
ReaderMgr fReaderMgr;
- bool fReuseValidator;
+ bool fReuseGrammar;
XMLUInt32 fScannerId;
XMLUInt32 fSequenceId;
bool fStandalone;
bool fValidate;
XMLValidator* fValidator;
+ bool fValidatorFromUser;
ValSchemes fValScheme;
bool fSchemaValidation;
@@ -632,6 +753,17 @@
XMLBuffer fQNameBuf;
XMLBuffer fPrefixBuf;
XMLBuffer fURIBuf;
+
+ unsigned int fEmptyNamespaceId;
+ unsigned int fGlobalNamespaceId;
+ unsigned int fUnknownNamespaceId;
+ unsigned int fXMLNamespaceId;
+ unsigned int fXMLNSNamespaceId;
+
+ GrammarResolver* fGrammarResolver;
+ Grammar* fGrammar;
+ NameIdPool<DTDEntityDecl>* fEntityDeclPool;
+ XMLStringPool* fURIStringPool;
};
@@ -649,6 +781,16 @@
return fDocHandler;
}
+inline const DocTypeHandler* XMLScanner::getDocTypeHandler() const
+{
+ return fDocTypeHandler;
+}
+
+inline DocTypeHandler* XMLScanner::getDocTypeHandler()
+{
+ return fDocTypeHandler;
+}
+
inline bool XMLScanner::getDoNamespaces() const
{
return fDoNamespaces;
@@ -724,36 +866,94 @@
return fValidator;
}
+inline const Grammar* XMLScanner::getCurrentGrammar() const
+{
+ return fGrammar;
+}
+
+inline Grammar* XMLScanner::getCurrentGrammar()
+{
+ return fGrammar;
+}
+
inline bool XMLScanner::getSchemaValidation() const
{
return fSchemaValidation;
}
-
// ---------------------------------------------------------------------------
-// XMLScanner: Setter methods
+// XMLValidator: Getter methods
// ---------------------------------------------------------------------------
-inline void XMLScanner::setDoNamespaces(const bool doNamespaces)
+inline unsigned int XMLScanner::getEmptyNamespaceId() const
{
- fDoNamespaces = doNamespaces;
+ return fEmptyNamespaceId;
}
+inline unsigned int XMLScanner::getGlobalNamespaceId() const
+{
+ return fGlobalNamespaceId;
+}
+
+inline unsigned int XMLScanner::getUnknownNamespaceId() const
+{
+ return fUnknownNamespaceId;
+}
+
+inline unsigned int XMLScanner::getXMLNamespaceId() const
+{
+ return fXMLNamespaceId;
+}
+
+inline unsigned int XMLScanner::getXMLNSNamespaceId() const
+{
+ return fXMLNSNamespaceId;
+}
+
+// ---------------------------------------------------------------------------
+// XMLScanner: Setter methods
+// ---------------------------------------------------------------------------
inline void XMLScanner::setDocHandler(XMLDocumentHandler* const docHandler)
{
fDocHandler = docHandler;
}
+inline void XMLScanner::setDocTypeHandler(DocTypeHandler* const docTypeHandler)
+{
+ fDocTypeHandler = docTypeHandler;
+}
+
+inline void XMLScanner::setDoNamespaces(const bool doNamespaces)
+{
+ fDoNamespaces = doNamespaces;
+ if (fDoNamespaces) {
+ if (!fURIStringPool) {
+ fURIStringPool = new XMLStringPool();
+ resetURIPool();
+ }
+ }
+}
+
inline void XMLScanner::setErrorReporter(XMLErrorReporter* const errHandler)
{
fErrorReporter = errHandler;
}
+inline void XMLScanner::setErrorHandler(ErrorHandler* const handler)
+{
+ fErrorHandler = handler;
+}
+
inline void XMLScanner::setEntityHandler(XMLEntityHandler* const entityHandler)
{
fEntityHandler = entityHandler;
fReaderMgr.setEntityHandler(entityHandler);
}
+inline void XMLScanner::setEntityResolver(EntityResolver* const handler)
+{
+ fEntityResolver = handler;
+}
+
inline void XMLScanner::setExitOnFirstFatal(const bool newValue)
{
fExitOnFirstFatal = newValue;
@@ -762,11 +962,19 @@
inline void XMLScanner::setValidationScheme(const ValSchemes newScheme)
{
fValScheme = newScheme;
+
+ // validation flag for Val_Auto is set to false by default,
+ // and will be turned to true if a grammar is seen
+ if (fValScheme == Val_Always)
+ fValidate = true;
+ else
+ fValidate = false;
}
-inline void XMLScanner::setValidator(XMLValidator* const validator)
+inline void XMLScanner::setValidator(XMLValidator* const valToAdopt)
{
- fValidator = validator;
+ delete fValidator;
+ fValidator = valToAdopt;
}
inline void XMLScanner::setSchemaValidation(const bool doSchema)
@@ -791,6 +999,12 @@
fValScheme = Val_Always;
else
fValScheme = Val_Never;
-}
+ // validation flag for Val_Auto is set to false by default,
+ // and will be turned to true if a grammar is seen
+ if (fValScheme == Val_Always)
+ fValidate = true;
+ else
+ fValidate = false;
+}
#endif
1.21 +242 -33 xml-xerces/c/src/internal/XMLScanner2.cpp
Index: XMLScanner2.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/internal/XMLScanner2.cpp,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- XMLScanner2.cpp 2001/02/26 19:21:51 1.20
+++ XMLScanner2.cpp 2001/03/21 21:56:05 1.21
@@ -55,7 +55,7 @@
*/
/*
- * $Id: XMLScanner2.cpp,v 1.20 2001/02/26 19:21:51 tng Exp $
+ * $Id: XMLScanner2.cpp,v 1.21 2001/03/21 21:56:05 tng Exp $
*/
@@ -71,20 +71,24 @@
#include <util/BinMemInputStream.hpp>
#include <util/Janitor.hpp>
#include <util/PlatformUtils.hpp>
+#include <util/TransService.hpp>
#include <util/UnexpectedEOFException.hpp>
#include <util/XMLUniDefs.hpp>
#include <util/XMLUni.hpp>
#include <sax/InputSource.hpp>
#include <framework/XMLErrorReporter.hpp>
#include <framework/XMLDocumentHandler.hpp>
-#include <framework/XMLElementDecl.hpp>
-#include <framework/XMLEntityDecl.hpp>
#include <framework/XMLEntityHandler.hpp>
#include <framework/XMLPScanToken.hpp>
#include <framework/XMLRefInfo.hpp>
#include <framework/XMLValidator.hpp>
#include <internal/XMLScanner.hpp>
#include <internal/EndOfEntityException.hpp>
+#include <parsers/DOMParser.hpp>
+#include <dom/DOM_DOMException.hpp>
+#include <sax/EntityResolver.hpp>
+#include <validators/schema/SchemaSymbols.hpp>
+#include <validators/schema/SchemaGrammar.hpp>
@@ -195,8 +199,8 @@
// boolean flag that lets us quickly below know which we are dealing
// with.
//
- const bool isNSAttr = (uriId == fValidator->getXMLNSNamespaceId())
- || (uriId == fValidator->getXMLNamespaceId())
+ const bool isNSAttr = (uriId == fXMLNSNamespaceId)
+ || (uriId == fXMLNamespaceId)
|| !XMLString::compareString(suffPtr, XMLUni::fgXMLNSString);
@@ -234,11 +238,12 @@
{
// This is to tell the reuse Validator that this attribute was
// faulted-in, was not an attribute in the attdef originally
- if(!fReuseValidator)
+ if(!fReuseGrammar)
attDef->setCreateReason(XMLAttDef::JustFaultIn);
XMLBuffer bufURI;
- fValidator->getURIText(uriId, bufURI);
+ getURIText(uriId, bufURI);
+
XMLBuffer bufMsg;
bufMsg.append(chOpenCurly);
bufMsg.append(bufURI.getRawBuffer());
@@ -258,13 +263,14 @@
// then emit an error
if (fValidate && !isNSAttr)
{
- if (fReuseValidator && attDef->getCreateReason()==XMLAttDef::JustFaultIn)
+ if (fReuseGrammar && attDef->getCreateReason()==XMLAttDef::JustFaultIn)
{
//reset the CreateReason to avoid redundant error
attDef->setCreateReason(XMLAttDef::NoReason);
XMLBuffer bufURI;
- fValidator->getURIText(uriId, bufURI);
+ getURIText(uriId, bufURI);
+
XMLBuffer bufMsg;
bufMsg.append(chOpenCurly);
bufMsg.append(bufURI.getRawBuffer());
@@ -301,11 +307,14 @@
//
if (!wasAdded)
{
- fValidator->validateAttrValue
- (
- *attDef
- , normBuf.getRawBuffer()
- );
+ if (fValidate)
+ {
+ fValidator->validateAttrValue
+ (
+ *attDef
+ , normBuf.getRawBuffer()
+ );
+ }
}
// Save the type for later use
@@ -594,7 +603,6 @@
return retVal;
}
-
unsigned int
XMLScanner::resolvePrefix( const XMLCh* const prefix
, const ElemStack::MapModes mode)
@@ -606,9 +614,9 @@
// URI that we define (so that it maps to something checkable.)
//
if (!XMLString::compareString(prefix, XMLUni::fgXMLNSString))
- return fValidator->getXMLNSNamespaceId();
+ return fXMLNSNamespaceId;
else if (!XMLString::compareString(prefix, XMLUni::fgXMLString))
- return fValidator->getXMLNamespaceId();
+ return fXMLNamespaceId;
//
@@ -638,9 +646,9 @@
// URI that we define (so that it maps to something checkable.)
//
if (!XMLString::compareString(prefix, XMLUni::fgXMLNSString))
- return fValidator->getXMLNSNamespaceId();
+ return fXMLNSNamespaceId;
else if (!XMLString::compareString(prefix, XMLUni::fgXMLString))
- return fValidator->getXMLNamespaceId();
+ return fXMLNamespaceId;
//
// Ask the element stack to search up itself for a mapping for the
@@ -652,8 +660,9 @@
// If it was unknown, then the URI was faked in but we have to issue an error
if (unknown)
emitError(XMLErrs::UnknownPrefix, prefix);
+
+ getURIText(uriId,bufToFill);
- fValidator->getURIText(uriId, bufToFill);
return uriId;
}
@@ -712,9 +721,9 @@
// URI that we define (so that it maps to something checkable.)
//
if (!XMLString::compareString(prefixBuf.getRawBuffer(), XMLUni::fgXMLNSString))
- uriId = fValidator->getXMLNSNamespaceId();
+ uriId = fXMLNSNamespaceId;
else if (!XMLString::compareString(prefixBuf.getRawBuffer(), XMLUni::fgXMLString))
- uriId = fValidator->getXMLNamespaceId();
+ uriId = fXMLNamespaceId;
else
{
bool unknown;
@@ -726,7 +735,6 @@
return uriId;
}
-
//
// This method will reset the scanner data structures, and related plugged
// in stuff, for a new scan session. We get the input source for the primary
@@ -739,14 +747,38 @@
// This call implicitly tells us that we are going to reuse the scanner
// if it was previously used. So tell the validator to reset itself.
//
- // But, if the fReuseValidator flag is set, then don't reset it.
+ // But, if the fReuseGrammar flag is set, then don't reset it.
//
// NOTE: The ReaderMgr is flushed on the way out, because that is
// required to insure that files are closed.
//
- if (!fReuseValidator)
- fValidator->reset();
+ if (!fReuseGrammar) {
+ fGrammarResolver->reset();
+
+ // Create a default Grammar first
+ fGrammar = new DTDGrammar(fEntityDeclPool);
+ fGrammarResolver->putGrammar(XMLUni::fgZeroLenString, fGrammar);
+
+ resetEntityDeclPool();
+
+ if (fDoNamespaces) {
+ if (!fURIStringPool)
+ fURIStringPool = new XMLStringPool();
+ resetURIPool();
+ }
+ }
+ if (fValidate && !fValidator) {
+ // create a default validator
+ fValidator = new DTDValidator();
+ initValidator();
+ }
+
+ if (fValidator) {
+ if (fValidator->handlesDTD() && !fValidator->getGrammar())
+ ((DTDValidator*) fValidator)->setDTDGrammar((DTDGrammar*)fGrammar);
+ }
+
//
// And for all installed handlers, send reset events. This gives them
// a chance to flush any cached data.
@@ -767,11 +799,11 @@
//
fElemStack.reset
(
- fValidator->getEmptyNamespaceId()
- , fValidator->getGlobalNamespaceId()
- , fValidator->getUnknownNamespaceId()
- , fValidator->getXMLNamespaceId()
- , fValidator->getXMLNSNamespaceId()
+ fEmptyNamespaceId
+ , fGlobalNamespaceId
+ , fUnknownNamespaceId
+ , fXMLNamespaceId
+ , fXMLNSNamespaceId
);
// Reset some status flags
@@ -1019,10 +1051,187 @@
fElemStack.addPrefix
(
prefPtr
- , fValidator->addOrFindNSId(normalBuf.getRawBuffer())
+ , fURIStringPool->addOrFind(normalBuf.getRawBuffer())
);
}
+void XMLScanner::scanRawAttrListforNameSpaces(const RefVectorOf<KVStringPair>* theRawAttrList, int attCount) {
+
+ // Indicate if the schema URI (e.g. "http://www.w3.org/2000/10/XMLSchema-instance")
+ // has been seen
+ bool seeXsi = false;
+
+ // Schema prefix xxx (e.g. xmlns:xxx="http://www.w3.org/2000/10/XMLSchema-instance")
+ const XMLCh* fXsiPrefix;
+
+ // Schema type
+ const XMLCh* fXsiType;
+
+ //
+ // Make an initial pass through the list and find any xmlns attributes or
+ // schema attributes.
+ // When we find one, send it off to be used to update the element stack's
+ // namespace mappings.
+ //
+
+ int index = 0;
+
+ for (index = 0; index < attCount; index++)
+ {
+ // each attribute has the prefix:suffix="value"
+ const KVStringPair* curPair = fRawAttrList->elementAt(index);
+ const XMLCh* valuePtr = curPair->getValue();
+ const XMLCh* rawPtr = curPair->getKey();
+
+ QName attName(rawPtr);
+ const XMLCh* suffPtr = attName.getLocalPart();
+
+ // If either the key begins with "xmlns:" or its just plain
+ // "xmlns", then use it to update the map.
+ //
+ if (!XMLString::compareNString(rawPtr, XMLUni::fgXMLNSColonString, 6)
+ || !XMLString::compareString(rawPtr, XMLUni::fgXMLNSString))
+ {
+ updateNSMap(rawPtr, valuePtr);
+
+ // if the schema URI is seen in the the valuePtr, set the boolean seeXsi
+ if (!XMLString::compareString(valuePtr, SchemaSymbols::fgURI_XSI)) {
+ fXsiPrefix = suffPtr;
+ seeXsi = true;
+ }
+ }
+ }
+
+ // walk through the list again to deal with "xsi:...."
+ if (fSchemaValidation && seeXsi)
+ {
+ for (index = 0; index < attCount; index++)
+ {
+ // each attribute has the prefix:suffix="value"
+ const KVStringPair* curPair = fRawAttrList->elementAt(index);
+ const XMLCh* valuePtr = curPair->getValue();
+ const XMLCh* rawPtr = curPair->getKey();
+
+ QName attName(rawPtr);
+ const XMLCh* prefPtr = attName.getPrefix();
+ const XMLCh* suffPtr = attName.getLocalPart();
+
+ // if schema URI has been seen, scan for the schema location and uri
+ // and resolve the schema grammar; or scan for schema type
+ if (!XMLString::compareString(prefPtr, fXsiPrefix)) {
+ if (!XMLString::compareString(suffPtr, SchemaSymbols::fgXSI_SCHEMALOCACTION))
+ parseSchemaLocation(valuePtr);
+ else if (!XMLString::compareString(suffPtr, SchemaSymbols::fgXSI_NONAMESPACESCHEMALOCACTION))
+ resolveSchemaGrammar(valuePtr, XMLUni::fgZeroLenString);
+ else if (!XMLString::compareString(suffPtr, SchemaSymbols::fgXSI_TYPE))
+ fXsiType = valuePtr;
+ }
+ }
+
+ // set up the SchemaValidator if validating
+ if(fValidate) {
+ if (fValidator) {
+ if (!fValidator->handlesSchema())
+ {
+ // the fValidator is from user
+ if (fValidatorFromUser)
+ ThrowXML(RuntimeException, XMLExcepts::Gen_NoSchemaValidator);
+ else {
+ // the fValidator is created by the Scanner, replace it with a SchemaValidator
+ delete fValidator;
+ fValidator = new SchemaValidator();
+ initValidator();
+ }
+ }
+ }
+ else {
+ fValidator = new SchemaValidator();
+ initValidator();
+ }
+
+ if (fXsiType)
+ ((SchemaValidator*)fValidator)->setXsiTypeAttValue(fXsiType);
+
+ //
+ // At this point, we know which type of validation we are going to
+ // use (if the plugged in validator handles either DTD or Schemas)
+ // since we will have seen the DOCTYPE or PI that set it up. So lets
+ // ask the validator whether it requires namespaces or not. If it
+ // does, we have to override the namespace enablement flag.
+ //
+ if (fValidator->requiresNamespaces() && !fDoNamespaces)
+ fDoNamespaces = true;
+
+ }
+ }
+}
+
+void XMLScanner::parseSchemaLocation(const XMLCh* const schemaLocationStr)
+{
+ RefVectorOf<XMLCh>* schemaLocation = XMLString::tokenizeString(schemaLocationStr);
+ unsigned int size = schemaLocation->size();
+ if (size % 2 != 0 ) {
+ emitError(XMLErrs::BadSchemaLocation);
+ } else {
+ for(unsigned int i=0; i<size; i=i+2) {
+ resolveSchemaGrammar(schemaLocation->elementAt(i), schemaLocation->elementAt(i+1));
+ }
+ }
+
+ delete schemaLocation;
+}
+
+void XMLScanner::resolveSchemaGrammar(const XMLCh* const loc, const XMLCh* const uri) {
+
+ SchemaGrammar* grammar = (SchemaGrammar*) fGrammarResolver->getGrammar(uri);
+
+ if (!grammar) {
+ DOMParser parser;
+ parser.setValidationScheme(DOMParser::Val_Never);
+ parser.setDoNamespaces(true);
+ parser.setErrorHandler(fErrorHandler);
+ parser.setEntityResolver(fEntityResolver);
+
+ try {
+ parser.parse( loc );
+ }
+ catch (...)
+ {
+ emitError(XMLErrs::GenericError);
+ }
+
+ DOM_Document document = parser.getDocument(); //Our Grammar
+
+ DOM_Element root = document.getDocumentElement();// This is what we pass to TraverserSchema
+ if (root.getNodeName().equals(SchemaSymbols::fgELT_SCHEMA)) {
+ fValidator->emitError(XMLValid::SchemaRootError, loc);
+ }
+ else
+ {
+ if (!uri || root.getAttribute(SchemaSymbols::fgATT_TARGETNAMESPACE).equals(uri))
+ fValidator->emitError(XMLValid::WrongTargetNamespace, loc, uri);
+
+ grammar = new SchemaGrammar();
+ grammar->setGrammarDocument(document);
+ grammar->setTargetNamespace(root.getAttribute(SchemaSymbols::fgATT_TARGETNAMESPACE).rawBuffer());
+
+ // pass parser's entity resolver (local Resolver), which also has reference to user's
+ // entity resolver, and also can fall-back to entityhandler's expandSystemId()
+// TraverseSchema traverseSchema;
+// traverseSchema.TraverseSchema(root, grammar, source.getSystemId());
+ fGrammarResolver->putGrammar(grammar->getTargetNamespace(), grammar);
+ }
+ }
+ fGrammar = grammar;
+
+ //
+ // Since we have seen a grammar, set our validation flag
+ // at this point if the validation scheme is auto
+ //
+ if (fValScheme == Val_Auto)
+ fValidate = true;
+
+}
// ---------------------------------------------------------------------------
// XMLScanner: Private parsing methods
@@ -2121,7 +2330,7 @@
emitError(XMLErrs::PartialMarkupInEntity);
// Look up the name in the general entity pool
- XMLEntityDecl* decl = fValidator->findEntityDecl(bbName.getRawBuffer(), false);
+ XMLEntityDecl* decl = fGrammar->getEntityDecl(bbName.getRawBuffer());
// If it does not exist, then obviously an error
if (!decl)
1.41 +32 -146 xml-xerces/c/src/parsers/DOMParser.cpp
Index: DOMParser.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/parsers/DOMParser.cpp,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -r1.40 -r1.41
--- DOMParser.cpp 2001/02/16 17:58:10 1.40
+++ DOMParser.cpp 2001/03/21 21:56:07 1.41
@@ -59,7 +59,7 @@
* handler with the scanner. In these handler methods, appropriate DOM nodes
* are created and added to the DOM tree.
*
-* $Id: DOMParser.cpp,v 1.40 2001/02/16 17:58:10 tng Exp $
+* $Id: DOMParser.cpp,v 1.41 2001/03/21 21:56:07 tng Exp $
*
*/
@@ -104,25 +104,14 @@
, fIncludeIgnorableWhitespace(true)
, fNodeStack(0)
, fScanner(0)
-, fOldDocTypeHandler(0)
-, fValidator(valToAdopt)
{
-
- // Create the validator if one was not provided
- if (!fValidator)
- fValidator = new DTDValidator;
-
- //If the user already registered the doctypehandler then chain it
- fOldDocTypeHandler = ((DTDValidator*)fValidator)->getDocTypeHandler();
-
- //register the new doctypehandler
- ((DTDValidator*)fValidator)->setDocTypeHandler(this);
//
// Create a scanner and tell it what validator to use. Then set us
// as the document event handler so we can fill the DOM document.
//
- fScanner = new XMLScanner(fValidator);
+ fScanner = new XMLScanner(valToAdopt);
fScanner->setDocHandler(this);
+ fScanner->setDocTypeHandler(this);
fNodeStack = new ValueStackOf<DOM_Node>(64);
this->reset();
@@ -135,7 +124,6 @@
{
delete fNodeStack;
delete fScanner;
- delete fValidator;
}
@@ -163,7 +151,7 @@
// ---------------------------------------------------------------------------
const XMLValidator& DOMParser::getValidator() const
{
- return *fValidator;
+ return *fScanner->getValidator();
}
bool DOMParser::getDoNamespaces() const
@@ -205,25 +193,27 @@
void DOMParser::setErrorHandler(ErrorHandler* const handler)
{
fErrorHandler = handler;
- if (fErrorHandler)
- {
+ if (fErrorHandler) {
fScanner->setErrorReporter(this);
- fValidator->setErrorReporter(this);
+ fScanner->setErrorHandler(fErrorHandler);
}
- else
- {
+ else {
fScanner->setErrorReporter(0);
- fValidator->setErrorReporter(0);
+ fScanner->setErrorHandler(0);
}
}
void DOMParser::setEntityResolver(EntityResolver* const handler)
{
fEntityResolver = handler;
- if (fEntityResolver)
+ if (fEntityResolver) {
fScanner->setEntityHandler(this);
- else
+ fScanner->setEntityResolver(fEntityResolver);
+ }
+ else {
fScanner->setEntityHandler(0);
+ fScanner->setEntityResolver(0);
+ }
}
void DOMParser::setExitOnFirstFatalError(const bool newState)
@@ -247,11 +237,10 @@
}
-
// ---------------------------------------------------------------------------
// DOMParser: Parsing methods
// ---------------------------------------------------------------------------
-void DOMParser::parse(const InputSource& source, const bool reuseValidator)
+void DOMParser::parse(const InputSource& source, const bool reuseGrammar)
{
// Avoid multiple entrance
if (fParseInProgress)
@@ -260,7 +249,7 @@
try
{
fParseInProgress = true;
- fScanner->scanDocument(source, reuseValidator);
+ fScanner->scanDocument(source, reuseGrammar);
fParseInProgress = false;
}
@@ -271,7 +260,7 @@
}
}
-void DOMParser::parse(const XMLCh* const systemId, const bool reuseValidator)
+void DOMParser::parse(const XMLCh* const systemId, const bool reuseGrammar)
{
// Avoid multiple entrance
if (fParseInProgress)
@@ -280,7 +269,7 @@
try
{
fParseInProgress = true;
- fScanner->scanDocument(systemId, reuseValidator);
+ fScanner->scanDocument(systemId, reuseGrammar);
fParseInProgress = false;
}
@@ -291,7 +280,7 @@
}
}
-void DOMParser::parse(const char* const systemId, const bool reuseValidator)
+void DOMParser::parse(const char* const systemId, const bool reuseGrammar)
{
// Avoid multiple entrance
if (fParseInProgress)
@@ -300,7 +289,7 @@
try
{
fParseInProgress = true;
- fScanner->scanDocument(systemId, reuseValidator);
+ fScanner->scanDocument(systemId, reuseGrammar);
fParseInProgress = false;
}
@@ -318,7 +307,7 @@
// ---------------------------------------------------------------------------
bool DOMParser::parseFirst( const XMLCh* const systemId
, XMLPScanToken& toFill
- , const bool reuseValidator)
+ , const bool reuseGrammar)
{
//
// Avoid multiple entrance. We cannot enter here while a regular parse
@@ -327,12 +316,12 @@
if (fParseInProgress)
ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
- return fScanner->scanFirst(systemId, toFill, reuseValidator);
+ return fScanner->scanFirst(systemId, toFill, reuseGrammar);
}
bool DOMParser::parseFirst( const char* const systemId
, XMLPScanToken& toFill
- , const bool reuseValidator)
+ , const bool reuseGrammar)
{
//
// Avoid multiple entrance. We cannot enter here while a regular parse
@@ -341,12 +330,12 @@
if (fParseInProgress)
ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
- return fScanner->scanFirst(systemId, toFill, reuseValidator);
+ return fScanner->scanFirst(systemId, toFill, reuseGrammar);
}
bool DOMParser::parseFirst( const InputSource& source
, XMLPScanToken& toFill
- , const bool reuseValidator)
+ , const bool reuseGrammar)
{
//
// Avoid multiple entrance. We cannot enter here while a regular parse
@@ -355,7 +344,7 @@
if (fParseInProgress)
ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
- return fScanner->scanFirst(source, toFill, reuseValidator);
+ return fScanner->scanFirst(source, toFill, reuseGrammar);
}
bool DOMParser::parseNext(XMLPScanToken& token)
@@ -601,8 +590,8 @@
if (fScanner -> getDoNamespaces()) { //DOM Level 2, doNamespaces on
XMLBuffer buf;
DOMString namespaceURI = 0;
- if (urlId != fValidator -> getGlobalNamespaceId()) { //TagName has a prefix
- fValidator -> getURIText(urlId, buf); //get namespaceURI
+ if (urlId != fScanner->getGlobalNamespaceId()) { //TagName has a prefix
+ fScanner->getURIText(urlId, buf); //get namespaceURI
namespaceURI = DOMString(buf.getRawBuffer());
}
elem = fDocument.createElementNS(namespaceURI, elemDecl.getFullName());
@@ -615,9 +604,9 @@
unsigned int attrURIId = oneAttrib -> getURIId();
namespaceURI = 0;
if (!XMLString::compareString(oneAttrib -> getName(), XMLNS)) //for xmlns=...
- attrURIId = fValidator -> getXMLNSNamespaceId();
- if (attrURIId != fValidator -> getEmptyNamespaceId()) { //TagName has a prefix
- fValidator -> getURIText(attrURIId, buf); //get namespaceURI
+ attrURIId = fScanner->getXMLNSNamespaceId();
+ if (attrURIId != fScanner->getEmptyNamespaceId()) { //TagName has a prefix
+ fScanner->getURIText(attrURIId, buf); //get namespaceURI
namespaceURI = DOMString(buf.getRawBuffer());
}
AttrImpl *attr = elemImpl->setAttributeNS(namespaceURI, oneAttrib -> getQName(),
@@ -759,11 +748,6 @@
, const bool ignoring
)
{
- if(fOldDocTypeHandler)
- {
- fOldDocTypeHandler->attDef(elemDecl,attDef, ignoring );
- }
-
if (fDocumentType->isIntSubsetReading())
{
DOMString attString;
@@ -877,10 +861,6 @@
const XMLCh* const comment
)
{
- if (fOldDocTypeHandler)
- {
- fOldDocTypeHandler->doctypeComment(comment);
- }
if (fDocumentType->isIntSubsetReading())
{
if (comment != 0)
@@ -906,18 +886,11 @@
, const bool hasIntSubset
)
{
- if (fOldDocTypeHandler)
- {
- fOldDocTypeHandler->doctypeDecl(elemDecl, publicId, systemId, hasIntSubset);
- }
-
DOM_DocumentType dt;
dt = fDocument.getImplementation().createDocumentType(elemDecl.getFullName(), publicId, systemId);
fDocumentType = (DocumentTypeImpl*)dt.fImpl;
((DocumentImpl*)fDocument.fImpl)->setDocumentType(fDocumentType);
- populateDocumentType(); // Add the entities and notations to this DocType.
-
}
void DOMParser::doctypePI
@@ -926,10 +899,6 @@
, const XMLCh* const data
)
{
- if (fOldDocTypeHandler)
- {
- fOldDocTypeHandler->doctypePI(target, data);
- }
if (fDocumentType->isIntSubsetReading())
{
//add these chars to internalSubset variable
@@ -954,11 +923,6 @@
, const unsigned int length
)
{
- if (fOldDocTypeHandler)
- {
- fOldDocTypeHandler->doctypeWhitespace(chars, length);
- }
-
if (fDocumentType->isIntSubsetReading())
fDocumentType->internalSubset.appendData(chars);
}
@@ -969,10 +933,6 @@
, const bool isIgnored
)
{
- if (fOldDocTypeHandler)
- {
- fOldDocTypeHandler->elementDecl(decl, isIgnored);
- }
if (fDocumentType->isIntSubsetReading())
{
DOMString elemDecl;
@@ -984,7 +944,7 @@
elemDecl.appendData(decl.getFullName());
//get the ContentSpec information
- const XMLCh* contentModel = decl.getFormattedContentModel(*fValidator);
+ const XMLCh* contentModel = decl.getFormattedContentModel(*fScanner->getCurrentGrammar());
if (contentModel != 0) {
elemDecl.appendData(chSpace);
elemDecl.appendData(contentModel);
@@ -1000,11 +960,6 @@
const DTDElementDecl& elemDecl
)
{
- if (fOldDocTypeHandler)
- {
- fOldDocTypeHandler->endAttList(elemDecl);
- }
-
// this section sets up default attributes.
// default attribute nodes are stored in a NamedNodeMap DocumentTypeImpl::elements
// default attribute data attached to the document is used to conform to the
@@ -1052,18 +1007,10 @@
void DOMParser::endIntSubset()
{
fDocumentType->intSubsetReading = false;
- if (fOldDocTypeHandler)
- {
- fOldDocTypeHandler->endIntSubset();
- }
}
void DOMParser::endExtSubset()
{
- if (fOldDocTypeHandler)
- {
- fOldDocTypeHandler->endExtSubset();
- }
}
void DOMParser::entityDecl
@@ -1142,10 +1089,6 @@
fDocumentType->internalSubset.appendData(entityName);
}
- if (fOldDocTypeHandler)
- {
- fOldDocTypeHandler->entityDecl(entityDecl, isPEDecl, isIgnored);
- }
}
void DOMParser::resetDocType()
@@ -1165,10 +1108,6 @@
fDocumentType->notations->setNamedItem( notation );
- if (fOldDocTypeHandler)
- {
- fOldDocTypeHandler->notationDecl(notDecl, isIgnored);
- }
}
void DOMParser::startAttList
@@ -1176,27 +1115,15 @@
const DTDElementDecl& elemDecl
)
{
- if (fOldDocTypeHandler)
- {
- fOldDocTypeHandler->startAttList(elemDecl);
- }
}
void DOMParser::startIntSubset()
{
fDocumentType->intSubsetReading = true;
- if (fOldDocTypeHandler)
- {
- fOldDocTypeHandler->startIntSubset();
- }
}
void DOMParser::startExtSubset()
{
- if (fOldDocTypeHandler)
- {
- fOldDocTypeHandler->startExtSubset();
- }
}
void DOMParser::TextDecl
@@ -1205,45 +1132,4 @@
, const XMLCh* const encodingStr
)
{
- if (fOldDocTypeHandler)
- {
- fOldDocTypeHandler->TextDecl(versionStr, encodingStr);
- }
-}
-
-
-// to populate the entities in the documentType
-void DOMParser::populateDocumentType()
-{
- if (fDocumentType == null)
- return;
-
-
- NameIdPoolEnumerator<DTDEntityDecl> entityPoolEnum = ((DTDValidator*)fValidator)->getEntityEnumerator();
-
-
- while(entityPoolEnum.hasMoreElements()) {
-
- DTDEntityDecl* entityDecl = &entityPoolEnum.nextElement();
-
- EntityImpl* entity = ((DocumentImpl*)fDocument.fImpl)->createEntity(entityDecl->getName());
- entity->setPublicId(entityDecl->getPublicId());
- entity->setSystemId(entityDecl->getSystemId());
- entity->setNotationName(entityDecl->getNotationName());
-
- fDocumentType->entities->setNamedItem( entity );
- }
-
- NameIdPoolEnumerator<XMLNotationDecl> notationPoolEnum = ((DTDValidator*)fValidator)->getNotationEnumerator();
-
- while(notationPoolEnum.hasMoreElements()) {
- XMLNotationDecl* notationDecl = ¬ationPoolEnum.nextElement();
-
- NotationImpl* notation = ((DocumentImpl*)fDocument.fImpl)->createNotation(notationDecl->getName());
- notation->setPublicId(notationDecl->getPublicId());
- notation->setPublicId(notationDecl->getPublicId());
-
- fDocumentType->notations->setNamedItem( notation );
- }
-
}
1.17 +31 -44 xml-xerces/c/src/parsers/DOMParser.hpp
Index: DOMParser.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/parsers/DOMParser.hpp,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- DOMParser.hpp 2001/02/15 15:56:28 1.16
+++ DOMParser.hpp 2001/03/21 21:56:07 1.17
@@ -55,7 +55,7 @@
*/
/*
- * $Id: DOMParser.hpp,v 1.16 2001/02/15 15:56:28 tng Exp $
+ * $Id: DOMParser.hpp,v 1.17 2001/03/21 21:56:07 tng Exp $
*
*/
@@ -72,7 +72,6 @@
#include <validators/DTD/DocTypeHandler.hpp>
#include <dom/DOM_DocumentType.hpp>
#include <validators/DTD/DTDElementDecl.hpp>
-#include <validators/DTD/DTDValidator.hpp>
class EntityResolver;
class ErrorHandler;
@@ -120,7 +119,7 @@
*
* Constructor with an instance of validator class to use for
* validation. If you don't provide a validator, a default one will
- * be created for you.
+ * be created for you in the scanner.
*
* @param valToAdopt Pointer to the validator instance to use. The
* parser is responsible for freeing the memory.
@@ -517,12 +516,12 @@
*
* @param source A const reference to the InputSource object which
* points to the XML file to be parsed.
- * @param reuseValidator The flag indicating whether the existing
- * validator should be reused or not for this
- * parsing run.
+ * @param reuseGrammar The flag indicating whether the existing Grammar
+ * should be reused or not for this parsing run.
+ * If true, there cannot be any internal subset.
* @see Parser#parse(InputSource)
*/
- void parse(const InputSource& source, const bool reuseValidator = false);
+ void parse(const InputSource& source, const bool reuseGrammar = false);
/** Parse via a file path or URL
*
@@ -532,13 +531,13 @@
*
* @param systemId A const XMLCh pointer to the Unicode string which
* contains the path to the XML file to be parsed.
- * @param reuseValidator The flag indicating whether the existing
- * validator should be reused or not for this
- * parsing run.
+ * @param reuseGrammar The flag indicating whether the existing Grammar
+ * should be reused or not for this parsing run.
+ * If true, there cannot be any internal subset.
*
* @see Parser#parse(XMLCh*)
*/
- void parse(const XMLCh* const systemId, const bool reuseValidator = false);
+ void parse(const XMLCh* const systemId, const bool reuseGrammar = false);
/** Parse via a file path or URL (in the local code page)
*
@@ -547,11 +546,11 @@
*
* @param systemId A const char pointer to a native string which
* contains the path to the XML file to be parsed.
- * @param reuseValidator The flag indicating whether the existing
- * validator should be reused or not for this
- * parsing run.
+ * @param reuseGrammar The flag indicating whether the existing Grammar
+ * should be reused or not for this parsing run.
+ * If true, there cannot be any internal subset.
*/
- void parse(const char* const systemId, const bool reuseValidator = false);
+ void parse(const char* const systemId, const bool reuseGrammar = false);
/** Begin a progressive parse operation
*
@@ -570,9 +569,9 @@
* @param toFill A token maintaing state information to maintain
* internal consistency between invocation of 'parseNext'
* calls.
- * @param reuseValidator The flag indicating whether the existing
- * validator should be reused or not for this parsing
- * process.
+ * @param reuseGrammar The flag indicating whether the existing Grammar
+ * should be reused or not for this parsing process.
+ * If true, there cannot be any internal subset.
* @return 'true', if successful in parsing the prolog. It indicates the
* user can go ahead with parsing the rest of the file. It
* returns 'false' to indicate that the parser could not parse
@@ -586,7 +585,7 @@
(
const XMLCh* const systemId
, XMLPScanToken& toFill
- , const bool reuseValidator = false
+ , const bool reuseGrammar = false
);
/** Begin a progressive parse operation
@@ -606,9 +605,9 @@
* @param toFill A token maintaing state information to maintain
* internal consistency between invocation of 'parseNext'
* calls.
- * @param reuseValidator The flag indicating whether the existing
- * validator should be reused or not for this parsing
- * run.
+ * @param reuseGrammar The flag indicating whether the existing Grammar
+ * should be reused or not for this parsing run.
+ * If true, there cannot be any internal subset.
*
* @return 'true', if successful in parsing the prolog. It indicates the
* user can go ahead with parsing the rest of the file. It
@@ -623,7 +622,7 @@
(
const char* const systemId
, XMLPScanToken& toFill
- , const bool reuseValidator = false
+ , const bool reuseGrammar = false
);
/** Begin a progressive parse operation
@@ -643,9 +642,9 @@
* @param toFill A token maintaing state information to maintain
* internal consistency between invocation of 'parseNext'
* calls.
- * @param reuseValidator The flag indicating whether the existing
- * validator should be reused or not for this parsing
- * process.
+ * @param reuseGrammar The flag indicating whether the existing Grammar
+ * should be reused or not for this parsing process.
+ * If true, there cannot be any internal subset.
*
* @return 'true', if successful in parsing the prolog. It indicates the
* user can go ahead with parsing the rest of the file. It
@@ -660,7 +659,7 @@
(
const InputSource& source
, XMLPScanToken& toFill
- , const bool reuseValidator = false
+ , const bool reuseGrammar = false
);
/** Continue a progressive parse operation
@@ -1107,7 +1106,10 @@
* @see #getDoValidation
*/
void setDoValidation(const bool newState);
- //doctypehandler interfaces
+
+ /**
+ * Deprecated doctypehandler interfaces
+ */
virtual void attDef
(
const DTDElementDecl& elemDecl
@@ -1233,9 +1235,6 @@
private :
- //local private function to populate the doctype data
- virtual void populateDocumentType();
-
// -----------------------------------------------------------------------
// Private data members
//
@@ -1272,12 +1271,6 @@
// The scanner used for this parser. This is created during the
// constructor.
//
- // fValidator
- // The validator that is installed. If none is provided, we will
- // create and install a DTD validator. We install this on the
- // scanner we create, which it will use to do validation. We set
- // ourself on it as the error reporter for validity errors.
- //
// fWithinElement
// A flag to indicate that the parser is within at least one level
// of element processing.
@@ -1286,10 +1279,6 @@
// Used to store and update the documentType variable information
// in fDocument
//
- // fOldDocTypeHandler
- // Used to chain the old documentType node if the user has set it
- // from outside
- //
// fToCreateXMLDecTypeNode
// A flag to create a DOM_XMLDecl node in the ODM tree if it exists
// This is an extension to xerces implementation
@@ -1305,10 +1294,8 @@
ValueStackOf<DOM_Node>* fNodeStack;
bool fParseInProgress;
XMLScanner* fScanner;
- XMLValidator* fValidator;
bool fWithinElement;
- DocumentTypeImpl* fDocumentType;
- DocTypeHandler* fOldDocTypeHandler;
+ DocumentTypeImpl* fDocumentType;
bool fToCreateXMLDeclTypeNode;
};
1.9 +82 -69 xml-xerces/c/src/parsers/SAX2XMLReaderImpl.cpp
Index: SAX2XMLReaderImpl.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/parsers/SAX2XMLReaderImpl.cpp,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- SAX2XMLReaderImpl.cpp 2001/02/15 15:56:29 1.8
+++ SAX2XMLReaderImpl.cpp 2001/03/21 21:56:08 1.9
@@ -56,6 +56,9 @@
/*
* $Log: SAX2XMLReaderImpl.cpp,v $
+ * Revision 1.9 2001/03/21 21:56:08 tng
+ * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+ *
* Revision 1.8 2001/02/15 15:56:29 tng
* Schema: Add setSchemaValidation and getSchemaValidation for DOMParser and SAXParser.
* Add feature "http://apache.org/xml/features/validation/schema" for SAX2XMLReader.
@@ -139,7 +142,6 @@
#include <sax/SAXException.hpp>
#include <internal/XMLScanner.hpp>
#include <parsers/SAX2XMLReaderImpl.hpp>
-#include <validators/DTD/DTDValidator.hpp>
#include <string.h>
// SAX2 Core: http://xml.org/sax/features/validation
@@ -207,8 +209,8 @@
chLatin_m, chLatin_i, chLatin_c, chNull
};
-//Xerces: http://apache.org/xml/features/validation/reuse-validator
-const XMLCh SAX2XMLReaderImpl::SAX_XERCES_REUSEVALIDATOR[] = {
+//Xerces: http://apache.org/xml/features/validation/reuse-grammar
+const XMLCh SAX2XMLReaderImpl::SAX_XERCES_REUSEGRAMMAR[] = {
chLatin_h, chLatin_t, chLatin_t, chLatin_p,
chColon, chForwardSlash, chForwardSlash,
chLatin_a, chLatin_p, chLatin_a, chLatin_c, chLatin_h, chLatin_e, chPeriod,
@@ -220,11 +222,9 @@
chLatin_v, chLatin_a, chLatin_l,
chLatin_i, chLatin_d, chLatin_a, chLatin_t,
chLatin_i, chLatin_o, chLatin_n, chForwardSlash,
- chLatin_r, chLatin_e, chLatin_u, chLatin_s,
- chLatin_e, chDash, chLatin_v,
- chLatin_a, chLatin_l,
- chLatin_i, chLatin_d, chLatin_a, chLatin_t,
- chLatin_o, chLatin_r, chNull
+ chLatin_r, chLatin_e, chLatin_u, chLatin_s, chLatin_e, chDash,
+ chLatin_g, chLatin_r, chLatin_a, chLatin_m, chLatin_m,
+ chLatin_a, chLatin_r, chNull
};
//Xerces: http://apache.org/xml/features/validation/schema
@@ -244,26 +244,45 @@
chLatin_m, chLatin_a, chNull
};
+//deprecated
+//Xerces: http://apache.org/xml/features/validation/reuse-validator
+const XMLCh SAX2XMLReaderImpl::SAX_XERCES_REUSEVALIDATOR[] = {
+ chLatin_h, chLatin_t, chLatin_t, chLatin_p,
+ chColon, chForwardSlash, chForwardSlash,
+ chLatin_a, chLatin_p, chLatin_a, chLatin_c, chLatin_h, chLatin_e, chPeriod,
+ chLatin_o, chLatin_r, chLatin_g, chForwardSlash,
+ chLatin_x, chLatin_m, chLatin_l, chForwardSlash,
+ chLatin_f, chLatin_e, chLatin_a,
+ chLatin_t, chLatin_u, chLatin_r,
+ chLatin_e, chLatin_s, chForwardSlash,
+ chLatin_v, chLatin_a, chLatin_l,
+ chLatin_i, chLatin_d, chLatin_a, chLatin_t,
+ chLatin_i, chLatin_o, chLatin_n, chForwardSlash,
+ chLatin_r, chLatin_e, chLatin_u, chLatin_s,
+ chLatin_e, chDash, chLatin_v,
+ chLatin_a, chLatin_l,
+ chLatin_i, chLatin_d, chLatin_a, chLatin_t,
+ chLatin_o, chLatin_r, chNull
+};
+
SAX2XMLReaderImpl::SAX2XMLReaderImpl() :
fDocHandler(0)
, fDTDHandler(0)
, fElemDepth(0)
, fEntityResolver(0)
, fErrorHandler(0)
- , fLexicalHandler(0)
+ , fLexicalHandler(0)
, fAdvDHCount(0)
, fAdvDHList(0)
, fAdvDHListSize(32)
, fParseInProgress(false)
, fScanner(0)
- , fValidator(0)
{
- // Create the validator if one was not provided.
- if (!fValidator)
- fValidator = new DTDValidator;
-
- // Create our scanner and tell it what validator to use
- fScanner = new XMLScanner(fValidator);
+ //
+ // Create a scanner and tell it what validator to use. Then set us
+ // as the document event handler so we can fill the DOM document.
+ //
+ fScanner = new XMLScanner(0);
// Create the initial advanced handler list array and zero it out
fAdvDHList = new XMLDocumentHandler*[fAdvDHListSize];
@@ -280,7 +299,7 @@
fautoValidation = false;
// default: reuseValidator is off
- freuseValidator = false;
+ fReuseGrammar = false;
// default: schema is on
setSchemaValidation(true);
@@ -294,10 +313,9 @@
{
delete [] fAdvDHList;
delete fScanner;
- delete fValidator;
- delete fPrefixes;
- delete tempAttrVec;
- delete prefixCounts ;
+ delete fPrefixes;
+ delete tempAttrVec;
+ delete prefixCounts ;
}
@@ -305,10 +323,13 @@
// SAX2XMLReaderImpl Validator functions
// ---------------------------------------------------------------------------
void SAX2XMLReaderImpl::setValidator(XMLValidator* valueToAdopt)
+{
+ fScanner->setValidator(valueToAdopt);
+}
+
+XMLValidator* SAX2XMLReaderImpl::getValidator() const
{
- if (fValidator)
- delete fValidator;
- fValidator = valueToAdopt;
+ return fScanner->getValidator();
}
// ---------------------------------------------------------------------------
@@ -340,17 +361,11 @@
void SAX2XMLReaderImpl::setDTDHandler(DTDHandler* const handler)
{
- //
- // <TBD>
- // This gets tricky. We can only set this if its a DTD validator, but it
- // might not be. We'll have to think about this one once there is more
- // than a DTD validator available.
- //
fDTDHandler = handler;
if (fDTDHandler)
- ((DTDValidator*)fValidator)->setDocTypeHandler(this);
+ fScanner->setDocTypeHandler(this);
else
- ((DTDValidator*)fValidator)->setDocTypeHandler(0);
+ fScanner->setDocTypeHandler(0);
}
@@ -358,19 +373,13 @@
{
//
// Store the handler. Then either install or deinstall us as the
- // error reporter on the scanner and validator.
+ // error reporter on the scanner.
//
fErrorHandler = handler;
if (fErrorHandler)
- {
fScanner->setErrorReporter(this);
- fValidator->setErrorReporter(this);
- }
else
- {
fScanner->setErrorReporter(0);
- fValidator->setErrorReporter(0);
- }
}
@@ -398,7 +407,7 @@
try
{
fParseInProgress = true;
- fScanner->scanDocument(source, freuseValidator);
+ fScanner->scanDocument(source, fReuseGrammar);
fParseInProgress = false;
}
@@ -418,7 +427,7 @@
try
{
fParseInProgress = true;
- fScanner->scanDocument(systemId, freuseValidator);
+ fScanner->scanDocument(systemId, fReuseGrammar);
fParseInProgress = false;
}
@@ -438,7 +447,7 @@
try
{
fParseInProgress = true;
- fScanner->scanDocument(systemId, freuseValidator);
+ fScanner->scanDocument(systemId, fReuseGrammar);
fParseInProgress = false;
}
@@ -673,15 +682,15 @@
}
prefixCounts->push(numPrefix) ;
if (!fnamespacePrefix)
- fAttrList.setVector(tempAttrVec, tempAttrVec->size(), fScanner->getValidator());
+ fAttrList.setVector(tempAttrVec, tempAttrVec->size(), fScanner);
else
- fAttrList.setVector(&attrList, attrCount, fScanner->getValidator());
+ fAttrList.setVector(&attrList, attrCount, fScanner);
// call startElement() with namespace declarations
XMLBufBid URIBufferBid ( &fStringBuffers ) ;
XMLBuffer &URIBuffer = URIBufferBid.getBuffer() ;
- fScanner->getValidator()->getURIText(elemURLId, (XMLBuffer &)URIBuffer);
+ fScanner->getURIText(elemURLId, (XMLBuffer &)URIBuffer);
fDocHandler->startElement(URIBuffer.getRawBuffer(),
elemDecl.getBaseName(),
@@ -690,7 +699,7 @@
}
else
{
- fAttrList.setVector(&attrList, attrCount, fScanner->getValidator());
+ fAttrList.setVector(&attrList, attrCount, fScanner);
fDocHandler->startElement(XMLUni::fgZeroLenString,
elemDecl.getBaseName(),
elemDecl.getFullName(),
@@ -708,7 +717,7 @@
XMLBufBid URIBufferBid ( &fStringBuffers ) ;
XMLBuffer &URIBuffer = URIBufferBid.getBuffer() ;
- fScanner->getValidator()->getURIText(elemURLId, (XMLBuffer &)URIBuffer);
+ fScanner->getURIText(elemURLId, (XMLBuffer &)URIBuffer);
fDocHandler->endElement( URIBuffer.getRawBuffer(),
elemDecl.getBaseName(),
@@ -765,7 +774,7 @@
XMLBufBid URIBufferBid ( &fStringBuffers ) ;
XMLBuffer &URIBuffer = URIBufferBid.getBuffer() ;
- fScanner->getValidator()->getURIText(uriId, URIBuffer ) ;
+ fScanner->getURIText(uriId, URIBuffer ) ;
fDocHandler->endElement( URIBuffer.getRawBuffer(),
elemDecl.getBaseName(),
elemDecl.getFullName() );
@@ -1051,10 +1060,9 @@
if (XMLString::compareIString(name, SAX2XMLReaderImpl::SAX_CORE_NAMESPACES) == 0)
{
setDoNamespaces(value);
- return;
}
- if (XMLString::compareIString(name, SAX2XMLReaderImpl::SAX_CORE_VALIDATION) == 0)
+ else if (XMLString::compareIString(name, SAX2XMLReaderImpl::SAX_CORE_VALIDATION) == 0)
{
fValidation = value;
if (fValidation)
@@ -1064,17 +1072,15 @@
setValidationScheme(Val_Always);
else
setValidationScheme(Val_Never);
- return;
}
- if (XMLString::compareIString(name, SAX2XMLReaderImpl::SAX_CORE_NAMESPACES_PREFIXES) == 0)
+ else if (XMLString::compareIString(name, SAX2XMLReaderImpl::SAX_CORE_NAMESPACES_PREFIXES) == 0)
{
fnamespacePrefix = value;
- return;
}
- if (XMLString::compareIString(name, SAX2XMLReaderImpl::SAX_XERCES_DYNAMIC) == 0)
+ else if (XMLString::compareIString(name, SAX2XMLReaderImpl::SAX_XERCES_DYNAMIC) == 0)
{
fautoValidation = value;
// for auto validation, the sax2 core validation feature must also be enabled.
@@ -1085,40 +1091,45 @@
setValidationScheme(Val_Always);
else
setValidationScheme(Val_Never);
- return;
}
- if (XMLString::compareIString(name, SAX2XMLReaderImpl::SAX_XERCES_REUSEVALIDATOR) == 0)
+ else if (XMLString::compareIString(name, SAX2XMLReaderImpl::SAX_XERCES_REUSEVALIDATOR) == 0)
{
- freuseValidator = value;
- return;
+ fReuseGrammar = value;
}
- if (XMLString::compareIString(name, SAX2XMLReaderImpl::SAX_XERCES_SCHEMA) == 0)
+ else if (XMLString::compareIString(name, SAX2XMLReaderImpl::SAX_XERCES_REUSEGRAMMAR) == 0)
{
+ fReuseGrammar = value;
+ }
+
+ else if (XMLString::compareIString(name, SAX2XMLReaderImpl::SAX_XERCES_SCHEMA) == 0)
+ {
setSchemaValidation(value);
- return;
}
- throw SAXNotRecognizedException("Unknown Feature");
+ else
+ throw SAXNotRecognizedException("Unknown Feature");
}
bool SAX2XMLReaderImpl::getFeature(const XMLCh* const name) const
{
if (XMLString::compareIString(name, SAX2XMLReaderImpl::SAX_CORE_NAMESPACES) == 0)
return getDoNamespaces();
- if (XMLString::compareIString(name, SAX2XMLReaderImpl::SAX_CORE_VALIDATION) == 0)
+ else if (XMLString::compareIString(name, SAX2XMLReaderImpl::SAX_CORE_VALIDATION) == 0)
return fValidation;
- if (XMLString::compareIString(name, SAX2XMLReaderImpl::SAX_CORE_NAMESPACES_PREFIXES) == 0)
+ else if (XMLString::compareIString(name, SAX2XMLReaderImpl::SAX_CORE_NAMESPACES_PREFIXES) == 0)
return fnamespacePrefix;
- if (XMLString::compareIString(name, SAX2XMLReaderImpl::SAX_XERCES_DYNAMIC) == 0)
+ else if (XMLString::compareIString(name, SAX2XMLReaderImpl::SAX_XERCES_DYNAMIC) == 0)
return fautoValidation;
- if (XMLString::compareIString(name, SAX2XMLReaderImpl::SAX_XERCES_REUSEVALIDATOR) == 0)
- return freuseValidator;
- if (XMLString::compareIString(name, SAX2XMLReaderImpl::SAX_XERCES_SCHEMA) == 0)
+ else if (XMLString::compareIString(name, SAX2XMLReaderImpl::SAX_XERCES_REUSEVALIDATOR) == 0)
+ return fReuseGrammar;
+ else if (XMLString::compareIString(name, SAX2XMLReaderImpl::SAX_XERCES_REUSEGRAMMAR) == 0)
+ return fReuseGrammar;
+ else if (XMLString::compareIString(name, SAX2XMLReaderImpl::SAX_XERCES_SCHEMA) == 0)
return getSchemaValidation();
-
- throw SAXNotRecognizedException("Unknown Feature");
+ else
+ throw SAXNotRecognizedException("Unknown Feature");
return false;
}
1.6 +12 -10 xml-xerces/c/src/parsers/SAX2XMLReaderImpl.hpp
Index: SAX2XMLReaderImpl.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/parsers/SAX2XMLReaderImpl.hpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- SAX2XMLReaderImpl.hpp 2001/02/15 15:56:29 1.5
+++ SAX2XMLReaderImpl.hpp 2001/03/21 21:56:08 1.6
@@ -56,6 +56,9 @@
/*
* $Log: SAX2XMLReaderImpl.hpp,v $
+ * Revision 1.6 2001/03/21 21:56:08 tng
+ * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+ *
* Revision 1.5 2001/02/15 15:56:29 tng
* Schema: Add setSchemaValidation and getSchemaValidation for DOMParser and SAXParser.
* Add feature "http://apache.org/xml/features/validation/schema" for SAX2XMLReader.
@@ -133,6 +136,7 @@
static const XMLCh SAX_CORE_NAMESPACES_PREFIXES[];
static const XMLCh SAX_XERCES_DYNAMIC[];
static const XMLCh SAX_XERCES_REUSEVALIDATOR[];
+ static const XMLCh SAX_XERCES_REUSEGRAMMAR[];
static const XMLCh SAX_XERCES_SCHEMA[];
SAX2XMLReaderImpl() ;
@@ -538,7 +542,7 @@
* <br>http://xml.org/sax/features/namespaces (default: true)
* <br>http://xml.org/sax/features/namespace-prefixes (default: true)
* <br>http://apache.org/xml/features/validation/dynamic (default: false)
- * <br>http://apache.org/xml/features/validation/reuse-validator (default: false)
+ * <br>http://apache.org/xml/features/validation/reuse-grammar (default: false)
* <br>http://apache.org/xml/features/validation/schema (default: true)
*
* @param name The unique identifier (URI) of the feature.
@@ -983,7 +987,7 @@
* <b>SAX2XMLReader assumes responsibility for the validator. It will be
* deleted when the XMLReader is destroyed.</b>
*
- * @return A pointer to the validator. An application should not deleted
+ * @return A pointer to the validator. An application should not delete
* the object returned.
*
*/
@@ -1017,8 +1021,9 @@
// fValidation
// Indicates whether the 'validation' core features is on or off
//
- // freuseValidator
- // Tells the parser whether it should reuse the validator or not
+ // fReuseGrammar
+ // Tells the parser whether it should reuse the grammar or not.
+ // If true, there cannot be any internal subset.
//
// fStringBuffers
// Any temporary strings we need are pulled out of this pool
@@ -1038,7 +1043,7 @@
bool fnamespacePrefix;
bool fautoValidation;
bool fValidation;
- bool freuseValidator;
+ bool fReuseGrammar;
XMLBufferMgr fStringBuffers ;
RefStackOf<XMLBuffer> * fPrefixes ;
@@ -1054,7 +1059,6 @@
unsigned int fAdvDHListSize;
bool fParseInProgress;
XMLScanner* fScanner;
- XMLValidator* fValidator;
// internal function used to set the state of validation: always, never, or auto
void setValidationScheme(const ValSchemes newScheme);
@@ -1094,9 +1098,5 @@
return fLexicalHandler;
}
-inline XMLValidator* SAX2XMLReaderImpl::getValidator() const
-{
- return fValidator;
-}
#endif
1.16 +22 -36 xml-xerces/c/src/parsers/SAXParser.cpp
Index: SAXParser.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/parsers/SAXParser.cpp,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- SAXParser.cpp 2001/02/15 15:56:29 1.15
+++ SAXParser.cpp 2001/03/21 21:56:08 1.16
@@ -56,6 +56,9 @@
/*
* $Log: SAXParser.cpp,v $
+ * Revision 1.16 2001/03/21 21:56:08 tng
+ * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+ *
* Revision 1.15 2001/02/15 15:56:29 tng
* Schema: Add setSchemaValidation and getSchemaValidation for DOMParser and SAXParser.
* Add feature "http://apache.org/xml/features/validation/schema" for SAX2XMLReader.
@@ -134,7 +137,6 @@
#include <sax/SAXParseException.hpp>
#include <internal/XMLScanner.hpp>
#include <parsers/SAXParser.hpp>
-#include <validators/DTD/DTDValidator.hpp>
#include <string.h>
@@ -153,14 +155,9 @@
, fAdvDHListSize(32)
, fParseInProgress(false)
, fScanner(0)
- , fValidator(valToAdopt)
{
- // Create the validator if one was not provided.
- if (!fValidator)
- fValidator = new DTDValidator;
-
// Create our scanner and tell it what validator to use
- fScanner = new XMLScanner(fValidator);
+ fScanner = new XMLScanner(valToAdopt);
// Create the initial advanced handler list array and zero it out
fAdvDHList = new XMLDocumentHandler*[fAdvDHListSize];
@@ -172,7 +169,6 @@
{
delete [] fAdvDHList;
delete fScanner;
- delete fValidator;
}
@@ -271,7 +267,7 @@
// ---------------------------------------------------------------------------
const XMLValidator& SAXParser::getValidator() const
{
- return *fValidator;
+ return *fScanner->getValidator();
}
@@ -339,7 +335,7 @@
// ---------------------------------------------------------------------------
// SAXParser: Overrides of the SAX Parser interface
// ---------------------------------------------------------------------------
-void SAXParser::parse(const InputSource& source, const bool reuseValidator)
+void SAXParser::parse(const InputSource& source, const bool reuseGrammar)
{
// Avoid multiple entrance
if (fParseInProgress)
@@ -348,7 +344,7 @@
try
{
fParseInProgress = true;
- fScanner->scanDocument(source, reuseValidator);
+ fScanner->scanDocument(source, reuseGrammar);
fParseInProgress = false;
}
@@ -359,7 +355,7 @@
}
}
-void SAXParser::parse(const XMLCh* const systemId, const bool reuseValidator)
+void SAXParser::parse(const XMLCh* const systemId, const bool reuseGrammar)
{
// Avoid multiple entrance
if (fParseInProgress)
@@ -368,7 +364,7 @@
try
{
fParseInProgress = true;
- fScanner->scanDocument(systemId, reuseValidator);
+ fScanner->scanDocument(systemId, reuseGrammar);
fParseInProgress = false;
}
@@ -379,7 +375,7 @@
}
}
-void SAXParser::parse(const char* const systemId, const bool reuseValidator)
+void SAXParser::parse(const char* const systemId, const bool reuseGrammar)
{
// Avoid multiple entrance
if (fParseInProgress)
@@ -388,7 +384,7 @@
try
{
fParseInProgress = true;
- fScanner->scanDocument(systemId, reuseValidator);
+ fScanner->scanDocument(systemId, reuseGrammar);
fParseInProgress = false;
}
@@ -425,17 +421,11 @@
void SAXParser::setDTDHandler(DTDHandler* const handler)
{
- //
- // <TBD>
- // This gets tricky. We can only set this if its a DTD validator, but it
- // might not be. We'll have to think about this one once there is more
- // than a DTD validator available.
- //
fDTDHandler = handler;
if (fDTDHandler)
- ((DTDValidator*)fValidator)->setDocTypeHandler(this);
+ fScanner->setDocTypeHandler(this);
else
- ((DTDValidator*)fValidator)->setDocTypeHandler(0);
+ fScanner->setDocTypeHandler(0);
}
@@ -443,19 +433,13 @@
{
//
// Store the handler. Then either install or deinstall us as the
- // error reporter on the scanner and validator.
+ // error reporter on the scanner.
//
fErrorHandler = handler;
if (fErrorHandler)
- {
fScanner->setErrorReporter(this);
- fValidator->setErrorReporter(this);
- }
else
- {
fScanner->setErrorReporter(0);
- fValidator->setErrorReporter(0);
- }
}
@@ -475,7 +459,7 @@
// ---------------------------------------------------------------------------
bool SAXParser::parseFirst( const XMLCh* const systemId
, XMLPScanToken& toFill
- , const bool reuseValidator)
+ , const bool reuseGrammar)
{
//
// Avoid multiple entrance. We cannot enter here while a regular parse
@@ -484,12 +468,12 @@
if (fParseInProgress)
ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
- return fScanner->scanFirst(systemId, toFill, reuseValidator);
+ return fScanner->scanFirst(systemId, toFill, reuseGrammar);
}
bool SAXParser::parseFirst( const char* const systemId
, XMLPScanToken& toFill
- , const bool reuseValidator)
+ , const bool reuseGrammar)
{
//
// Avoid multiple entrance. We cannot enter here while a regular parse
@@ -498,12 +482,12 @@
if (fParseInProgress)
ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
- return fScanner->scanFirst(systemId, toFill, reuseValidator);
+ return fScanner->scanFirst(systemId, toFill, reuseGrammar);
}
bool SAXParser::parseFirst( const InputSource& source
, XMLPScanToken& toFill
- , const bool reuseValidator)
+ , const bool reuseGrammar)
{
//
// Avoid multiple entrance. We cannot enter here while a regular parse
@@ -512,7 +496,7 @@
if (fParseInProgress)
ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
- return fScanner->scanFirst(source, toFill, reuseValidator);
+ return fScanner->scanFirst(source, toFill, reuseGrammar);
}
bool SAXParser::parseNext(XMLPScanToken& token)
1.12 +29 -31 xml-xerces/c/src/parsers/SAXParser.hpp
Index: SAXParser.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/parsers/SAXParser.hpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- SAXParser.hpp 2001/02/15 15:56:29 1.11
+++ SAXParser.hpp 2001/03/21 21:56:09 1.12
@@ -56,6 +56,9 @@
/*
* $Log: SAXParser.hpp,v $
+ * Revision 1.12 2001/03/21 21:56:09 tng
+ * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+ *
* Revision 1.11 2001/02/15 15:56:29 tng
* Schema: Add setSchemaValidation and getSchemaValidation for DOMParser and SAXParser.
* Add feature "http://apache.org/xml/features/validation/schema" for SAX2XMLReader.
@@ -408,13 +411,13 @@
*
* @param source A const reference to the InputSource object which
* points to the XML file to be parsed.
- * @param reuseValidator The flag indicating whether the existing
- * validator should be reused or not for this
- * parsing run.
+ * @param reuseGrammar The flag indicating whether the existing Grammar
+ * should be reused or not for this parsing run.
+ * If true, there cannot be any internal subset.
*
* @see Parser#parse(InputSource)
*/
- virtual void parse(const InputSource& source, const bool reuseValidator = false);
+ virtual void parse(const InputSource& source, const bool reuseGrammar = false);
/**
* This method invokes the parsing process on the XML file specified by
@@ -422,13 +425,13 @@
*
* @param systemId A const XMLCh pointer to the Unicode string which
* contains the path to the XML file to be parsed.
- * @param reuseValidator The flag indicating whether the existing
- * validator should be reused or not for this
- * parsing run.
+ * @param reuseGrammar The flag indicating whether the existing Grammar
+ * should be reused or not for this parsing run.
+ * If true, there cannot be any internal subset.
*
* @see Parser#parse(XMLCh*)
*/
- virtual void parse(const XMLCh* const systemId, const bool reuseValidator = false);
+ virtual void parse(const XMLCh* const systemId, const bool reuseGrammar = false);
/**
* This method invokes the parsing process on the XML file specified by
@@ -436,11 +439,11 @@
*
* @param systemId A const char pointer to a native string which
* contains the path to the XML file to be parsed.
- * @param reuseValidator The flag indicating whether the existing
- * validator should be reused or not for this
- * parsing run.
+ * @param reuseGrammar The flag indicating whether the existing Grammar
+ * should be reused or not for this parsing run.
+ * If true, there cannot be any internal subset.
*/
- virtual void parse(const char* const systemId, const bool reuseValidator = false);
+ virtual void parse(const char* const systemId, const bool reuseGrammar = false);
/**
* This method installs the user specified SAX Document Handler
@@ -516,10 +519,9 @@
* @param toFill A token maintaing state information to maintain
* internal consistency between invocation of 'parseNext'
* calls.
- * @param reuseValidator The flag indicating whether the existing
- * validator
- * should be reused or not for this parsing
- * run.
+ * @param reuseGrammar The flag indicating whether the existing Grammar
+ * should be reused or not for this parsing run.
+ * If true, there cannot be any internal subset.
*
* @return 'true', if successful in parsing the prolog. It indicates the
* user can go ahead with parsing the rest of the file. It
@@ -534,7 +536,7 @@
(
const XMLCh* const systemId
, XMLPScanToken& toFill
- , const bool reuseValidator = false
+ , const bool reuseGrammar = false
);
/** Begin a progressive parse operation
@@ -554,9 +556,9 @@
* @param toFill A token maintaing state information to maintain
* internal consIstency between invocation of 'parseNext'
* calls.
- * @param reuseValidator The flag indicating whether the existing
- * validator should be reused or not for this parsing
- * run.
+ * @param reuseGrammar The flag indicating whether the existing Grammar
+ * should be reused or not for this parsing run.
+ * If true, there cannot be any internal subset.
*
* @return 'true', if successful in parsing the prolog. It indicates the
* user can go ahead with parsing the rest of the file. It
@@ -571,7 +573,7 @@
(
const char* const systemId
, XMLPScanToken& toFill
- , const bool reuseValidator = false
+ , const bool reuseGrammar = false
);
/** Begin a progressive parse operation
@@ -591,9 +593,9 @@
* @param toFill A token maintaing state information to maintain
* internal consistency between invocation of 'parseNext'
* calls.
- * @param reuseValidator The flag indicating whether the existing
- * validator should be reused or not for this parsing
- * process.
+ * @param reuseGrammar The flag indicating whether the existing Grammar
+ * should be reused or not for this parsing run.
+ * If true, there cannot be any internal subset.
*
* @return 'true', if successful in parsing the prolog. It indicates the
* user can go ahead with parsing the rest of the file. It
@@ -608,7 +610,7 @@
(
const InputSource& source
, XMLPScanToken& toFill
- , const bool reuseValidator = false
+ , const bool reuseGrammar = false
);
/** Continue a progressive parse operation
@@ -1371,11 +1373,6 @@
// The scanner being used by this parser. It is created internally
// during construction.
//
- // fValidator
- // The validator that is installed. If none is provided, we will
- // create and install a DTD validator. We install this on the
- // scanner we create, which it will use to do validation. We set
- // ourself on it as the error reporter for validity errors.
// -----------------------------------------------------------------------
VecAttrListImpl fAttrList;
DocumentHandler* fDocHandler;
@@ -1388,7 +1385,6 @@
unsigned int fAdvDHListSize;
bool fParseInProgress;
XMLScanner* fScanner;
- XMLValidator* fValidator;
};
1.7 +31 -26 xml-xerces/c/src/sax/Parser.hpp
Index: Parser.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/sax/Parser.hpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- Parser.hpp 2000/03/02 19:54:35 1.6
+++ Parser.hpp 2001/03/21 21:56:10 1.7
@@ -1,37 +1,37 @@
/*
* The Apache Software License, Version 1.1
- *
+ *
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- *
+ *
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
+ * notice, this list of conditions and the following disclaimer.
+ *
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
- *
+ *
* 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
+ * if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
- *
+ *
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
- * software without prior written permission. For written
+ * software without prior written permission. For written
* permission, please contact apache\@apache.org.
- *
+ *
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
- *
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@@ -45,7 +45,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
- *
+ *
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
@@ -56,6 +56,9 @@
/*
* $Log: Parser.hpp,v $
+ * Revision 1.7 2001/03/21 21:56:10 tng
+ * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+ *
* Revision 1.6 2000/03/02 19:54:35 roddey
* This checkin includes many changes done while waiting for the
* 1.1.0 code to be finished. I can't list them all here, but a list is
@@ -115,7 +118,7 @@
#include <util/XercesDefs.hpp>
-class SAX_EXPORT Parser
+class SAX_EXPORT Parser
{
public:
/** @name Constructors and Destructor */
@@ -155,7 +158,7 @@
* @see HandlerBase#HandlerBase
*/
virtual void setEntityResolver(EntityResolver* const resolver) = 0;
-
+
/**
* Allow an application to register a DTD event handler.
*
@@ -225,9 +228,9 @@
*
* @param source The input source for the top-level of the
* XML document.
- * @param reuseValidator Indicates whether the validator should be
- * reused, ignoring any external subset. If true, there
- * cannot be any internal subset.
+ * @param reuseGrammar The flag indicating whether the existing Grammar
+ * should be reused or not for this parsing run.
+ * If true, there cannot be any internal subset.
* @exception SAXException Any SAX exception, possibly
* wrapping another exception.
* @exception XMLException An exception from the parser or client
@@ -241,7 +244,7 @@
virtual void parse
(
const InputSource& source
- , const bool reuseValidator = false
+ , const bool reuseGrammar = false
) = 0;
/**
@@ -257,9 +260,9 @@
* by the application before it is passed to the parser.
*
* @param systemId The system identifier (URI).
- * @param reuseValidator Indicates whether the validator should be
- * reused, ignoring any external subset. If true, there
- * cannot be any internal subset.
+ * @param reuseGrammar The flag indicating whether the existing Grammar
+ * should be reused or not for this parsing run.
+ * If true, there cannot be any internal subset.
* @exception SAXException Any SAX exception, possibly
* wrapping another exception.
* @exception XMLException An exception from the parser or client
@@ -269,7 +272,7 @@
virtual void parse
(
const XMLCh* const systemId
- , const bool reuseValidator = false
+ , const bool reuseGrammar = false
) = 0;
/**
@@ -285,9 +288,9 @@
* by the application before it is passed to the parser.
*
* @param systemId The system identifier (URI).
- * @param reuseValidator Indicates whether the validator should be
- * reused, ignoring any external subset. If true, there
- * cannot be any internal subset.
+ * @param reuseGrammar The flag indicating whether the existing Grammar
+ * should be reused or not for this parsing run.
+ * If true, there cannot be any internal subset.
* @exception SAXException Any SAX exception, possibly
* wrapping another exception.
* @exception XMLException An exception from the parser or client
@@ -297,7 +300,7 @@
virtual void parse
(
const char* const systemId
- , const bool reuseValidator = false
+ , const bool reuseGrammar = false
) = 0;
//@}
1.31 +5 -0 xml-xerces/c/src/util/Makefile.in
Index: Makefile.in
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/util/Makefile.in,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -r1.30 -r1.31
--- Makefile.in 2001/03/02 20:06:19 1.30
+++ Makefile.in 2001/03/21 21:56:11 1.31
@@ -55,6 +55,9 @@
#
#
# $Log: Makefile.in,v $
+# Revision 1.31 2001/03/21 21:56:11 tng
+# Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+#
# Revision 1.30 2001/03/02 20:06:19 knoaman
# Schema: Regular expression project and configuration file changes
#
@@ -267,6 +270,7 @@
QName.hpp \
RefArrayOf.hpp \
RefHash2KeysTableOf.hpp \
+ RefHash3KeysIdPool.hpp \
RefHashTableOf.hpp \
RefStackOf.hpp \
RefVectorOf.hpp \
@@ -313,6 +317,7 @@
NameIdPool.c \
RefArrayOf.c \
RefHash2KeysTableOf.c \
+ RefHash3KeysIdPool.c \
RefHashTableOf.c \
RefStackOf.c \
RefVectorOf.c \
1.4 +54 -0 xml-xerces/c/src/util/QName.cpp
Index: QName.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/util/QName.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- QName.cpp 2001/02/27 14:48:35 1.3
+++ QName.cpp 2001/03/21 21:56:11 1.4
@@ -56,6 +56,9 @@
/*
* $Log: QName.cpp,v $
+ * Revision 1.4 2001/03/21 21:56:11 tng
+ * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+ *
* Revision 1.3 2001/02/27 14:48:35 tng
* Schema: Add CMAny and ContentLeafNameTypeVector, by Pei Yong Zhang
*
@@ -168,6 +171,57 @@
// QName: Getter methods
// ---------------------------------------------------------------------------
const XMLCh* QName::getRawName() const
+{
+ //
+ // If there is no buffer, or if there is but we've not faulted in the
+ // value yet, then we have to do that now.
+ //
+ if (!fRawName || !*fRawName)
+ {
+ //
+ // Calculate the worst case size buffer we will need. We use the
+ // current high water marks of the prefix and name buffers, so it
+ // might be a little wasteful of memory but we don't have to do
+ // string len operations on the two strings.
+ //
+ const unsigned int neededLen = fPrefixBufSz + fLocalPartBufSz + 1;
+
+ //
+ // If no buffer, or the current one is too small, then allocate one
+ // and get rid of any old one.
+ //
+ if (!fRawName || (neededLen > fRawNameBufSz))
+ {
+ delete [] fRawName;
+
+ // We have to cast off the const'ness to do this
+ ((QName*)this)->fRawNameBufSz = neededLen;
+ ((QName*)this)->fRawName = new XMLCh[neededLen + 1];
+
+ // Make sure its initially empty
+ *fRawName = 0;
+ }
+
+ //
+ // If we have a prefix, then do the prefix:name version. Else, its
+ // just the name.
+ //
+ if (*fPrefix)
+ {
+ const XMLCh colonStr[] = { chColon, chNull };
+ XMLString::copyString(fRawName, fPrefix);
+ XMLString::catString(fRawName, colonStr);
+ XMLString::catString(fRawName, fLocalPart);
+ }
+ else
+ {
+ XMLString::copyString(fRawName, fLocalPart);
+ }
+ }
+ return fRawName;
+}
+
+XMLCh* QName::getRawName()
{
//
// If there is no buffer, or if there is but we've not faulted in the
1.4 +25 -3 xml-xerces/c/src/util/QName.hpp
Index: QName.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/util/QName.hpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- QName.hpp 2001/02/27 14:48:39 1.3
+++ QName.hpp 2001/03/21 21:56:12 1.4
@@ -56,6 +56,9 @@
/*
* $Log: QName.hpp,v $
+ * Revision 1.4 2001/03/21 21:56:12 tng
+ * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+ *
* Revision 1.3 2001/02/27 14:48:39 tng
* Schema: Add CMAny and ContentLeafNameTypeVector, by Pei Yong Zhang
*
@@ -105,12 +108,16 @@
// Getters
// -----------------------------------------------------------------------
const XMLCh* getPrefix() const;
+ XMLCh* getPrefix();
- const XMLCh* getLocalPart() const;
+ const XMLCh* getLocalPart() const;
+ XMLCh* getLocalPart();
- const int getURI() const;
+ const int getURI() const;
+ int getURI();
- const XMLCh* getRawName() const;
+ const XMLCh* getRawName() const;
+ XMLCh* getRawName();
// -----------------------------------------------------------------------
// Setters
@@ -192,12 +199,27 @@
return fPrefix;
}
+inline XMLCh* QName::getPrefix()
+{
+ return fPrefix;
+}
+
inline const XMLCh* QName::getLocalPart() const
{
return fLocalPart;
}
+inline XMLCh* QName::getLocalPart()
+{
+ return fLocalPart;
+}
+
inline const int QName::getURI() const
+{
+ return fURIId;
+}
+
+inline int QName::getURI()
{
return fURIId;
}
1.12 +6 -5 xml-xerces/c/src/util/XMLExceptMsgs.hpp
Index: XMLExceptMsgs.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/util/XMLExceptMsgs.hpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- XMLExceptMsgs.hpp 2001/03/02 20:52:43 1.11
+++ XMLExceptMsgs.hpp 2001/03/21 21:56:12 1.12
@@ -144,11 +144,12 @@
, Parser_Descape4 = 133
, Parser_Descape5 = 134
, Parser_Process1 = 135
- , E_HighBounds = 136
- , W_LowBounds = 137
- , W_HighBounds = 138
- , V_LowBounds = 139
- , V_HighBounds = 140
+ , Gen_NoSchemaValidator = 136
+ , E_HighBounds = 137
+ , W_LowBounds = 138
+ , W_HighBounds = 139
+ , V_LowBounds = 140
+ , V_HighBounds = 141
};
};
1.15 +60 -18 xml-xerces/c/src/util/XMLString.cpp
Index: XMLString.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/util/XMLString.cpp,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- XMLString.cpp 2001/03/02 20:52:44 1.14
+++ XMLString.cpp 2001/03/21 21:56:12 1.15
@@ -1,37 +1,37 @@
/*
* The Apache Software License, Version 1.1
- *
+ *
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- *
+ *
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
+ * notice, this list of conditions and the following disclaimer.
+ *
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
- *
+ *
* 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
+ * if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
- *
+ *
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
- * software without prior written permission. For written
+ * software without prior written permission. For written
* permission, please contact apache\@apache.org.
- *
+ *
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
- *
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@@ -45,7 +45,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
- *
+ *
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
@@ -55,7 +55,7 @@
*/
/*
- * $Id: XMLString.cpp,v 1.14 2001/03/02 20:52:44 knoaman Exp $
+ * $Id: XMLString.cpp,v 1.15 2001/03/21 21:56:12 tng Exp $
*/
@@ -564,7 +564,7 @@
}
// Cap off at the scrap point
- if (scrape)
+ if (scrape != len)
toTrim[scrape] = 0;
if (skip)
@@ -592,7 +592,7 @@
const int copySize = endIndex - startIndex;
// Make sure the start index is within the XMLString bounds
- if (startIndex > srcLen-1 || endIndex > srcLen - 1)
+ if (startIndex > srcLen-1 || endIndex > srcLen )
ThrowXML(ArrayIndexOutOfBoundsException, XMLExcepts::Str_StartIndexPastEnd);
for (int i= startIndex; i < endIndex; i++) {
@@ -611,7 +611,7 @@
, const unsigned int maxChars
, const unsigned int radix)
{
- static const XMLCh digitList[16] =
+ static const XMLCh digitList[16] =
{
chDigit_0, chDigit_1, chDigit_2, chDigit_3, chDigit_4, chDigit_5
, chDigit_6, chDigit_7, chDigit_8, chDigit_9, chLatin_A, chLatin_B
@@ -1143,7 +1143,7 @@
}
// Cap off at the scrap point
- if (scrape)
+ if (scrape != len)
toTrim[scrape] = 0;
if (skip)
@@ -1185,7 +1185,7 @@
const int copySize = endIndex - startIndex;
// Make sure the start index is within the XMLString bounds
- if (startIndex > srcLen-1 || endIndex > srcLen - 1)
+ if (startIndex > srcLen-1 || endIndex > srcLen )
ThrowXML(ArrayIndexOutOfBoundsException, XMLExcepts::Str_StartIndexPastEnd);
for (int i= startIndex; i < endIndex; i++) {
@@ -1196,6 +1196,48 @@
targetStr[copySize] = 0;
}
+RefVectorOf<XMLCh>* XMLString::tokenizeString(const XMLCh* const tokenizeSrc)
+{
+ XMLCh* orgText = replicate(tokenizeSrc);
+ ArrayJanitor<XMLCh> janText(orgText);
+ XMLCh* tokenizeStr = orgText;
+
+ RefVectorOf<XMLCh>* tokenStack = new RefVectorOf<XMLCh>(16, true);
+
+ unsigned int len = stringLen(tokenizeStr);
+ unsigned int skip;
+ unsigned int index = 0;
+
+ while (index != len) {
+ // find the first non-space character
+ for (skip = index; skip < len; skip++)
+ {
+ if (!XMLPlatformUtils::fgTransService->isSpace(tokenizeStr[skip]))
+ break;
+ }
+ index = skip;
+
+ // find the delimiter (space character)
+ for (; skip < len; skip++)
+ {
+ if (XMLPlatformUtils::fgTransService->isSpace(tokenizeStr[skip]))
+ break;
+ }
+
+ // we reached the end of the string
+ if (skip == index)
+ break;
+
+ // these tokens are adopted in the RefVector and will be deleted
+ // when the vector is deleted by the caller
+ XMLCh* token = new XMLCh[skip+1-index];
+
+ XMLString::subString(token, tokenizeStr, index, skip);
+ tokenStack->addElement(token);
+ index = skip;
+ }
+ return tokenStack;
+}
// ---------------------------------------------------------------------------
// XMLString: Private static methods
1.17 +47 -33 xml-xerces/c/src/util/XMLString.hpp
Index: XMLString.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/util/XMLString.hpp,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- XMLString.hpp 2001/03/02 20:52:46 1.16
+++ XMLString.hpp 2001/03/21 21:56:13 1.17
@@ -56,6 +56,9 @@
/*
* $Log: XMLString.hpp,v $
+ * Revision 1.17 2001/03/21 21:56:13 tng
+ * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+ *
* Revision 1.16 2001/03/02 20:52:46 knoaman
* Schema: Regular expression - misc. updates for error messages,
* and additions of new functions to XMLString class.
@@ -152,6 +155,7 @@
#define XMLSTRING_HPP
#include <util/XercesDefs.hpp>
+#include <util/RefVectorOf.hpp>
class XMLLCPTranscoder;
@@ -385,8 +389,8 @@
* @return The return value indicates the relation of <code>str1</code> to
* <code>str2</code> as follows
* Less than 0 means <code>str1</code> is less than <code>str2</code>
- * Equal to 0 means <code>str1</code> is identical to <code>str2</code>
- * Greater than 0 means <code>str1</code> is more than <code>str2</code>
+ * Equal to 0 means <code>str1</code> is identical to <code>str2</code>
+ * Greater than 0 means <code>str1</code> is more than <code>str2</code>
*/
static int compareIString
(
@@ -401,8 +405,8 @@
* @return The return value indicates the relation of <code>str1</code> to
* <code>str2</code> as follows
* Less than 0 means <code>str1</code> is less than <code>str2</code>
- * Equal to 0 means <code>str1</code> is identical to <code>str2</code>
- * Greater than 0 means <code>str1</code> is more than <code>str2</code>
+ * Equal to 0 means <code>str1</code> is identical to <code>str2</code>
+ * Greater than 0 means <code>str1</code> is more than <code>str2</code>
*/
static int compareIString
(
@@ -421,8 +425,8 @@
* @return The return value indicates the relation of <code>str1</code> to
* <code>str2</code> as follows
* Less than 0 means <code>str1</code> is less than <code>str2</code>
- * Equal to 0 means <code>str1</code> is identical to <code>str2</code>
- * Greater than 0 means <code>str1</code> is more than <code>str2</code>
+ * Equal to 0 means <code>str1</code> is identical to <code>str2</code>
+ * Greater than 0 means <code>str1</code> is more than <code>str2</code>
*/
static int compareNString
(
@@ -441,8 +445,8 @@
* @return The return value indicates the relation of <code>str1</code> to
* <code>str2</code> as follows
* Less than 0 means <code>str1</code> is less than <code>str2</code>
- * Equal to 0 means <code>str1</code> is identical to <code>str2</code>
- * Greater than 0 means <code>str1</code> is more than <code>str2</code>
+ * Equal to 0 means <code>str1</code> is identical to <code>str2</code>
+ * Greater than 0 means <code>str1</code> is more than <code>str2</code>
*/
static int compareNString
(
@@ -462,8 +466,8 @@
* @return The return value indicates the relation of <code>str1</code> to
* <code>str2</code> as follows
* Less than 0 means <code>str1</code> is less than <code>str2</code>
- * Equal to 0 means <code>str1</code> is identical to <code>str2</code>
- * Greater than 0 means <code>str1</code> is more than <code>str2</code>
+ * Equal to 0 means <code>str1</code> is identical to <code>str2</code>
+ * Greater than 0 means <code>str1</code> is more than <code>str2</code>
*/
static int compareNIString
(
@@ -483,8 +487,8 @@
* @return The return value indicates the relation of <code>str1</code> to
* <code>str2</code> as follows
* Less than 0 means <code>str1</code> is less than <code>str2</code>
- * Equal to 0 means <code>str1</code> is identical to <code>str2</code>
- * Greater than 0 means <code>str1</code> is more than <code>str2</code>
+ * Equal to 0 means <code>str1</code> is identical to <code>str2</code>
+ * Greater than 0 means <code>str1</code> is more than <code>str2</code>
*/
static int compareNIString
(
@@ -502,8 +506,8 @@
* @return The return value indicates the relation of <code>str1</code> to
* <code>str2</code> as follows
* Less than 0 means <code>str1</code> is less than <code>str2</code>
- * Equal to 0 means <code>str1</code> is identical to <code>str2</code>
- * Greater than 0 means <code>str1</code> is more than <code>str2</code>
+ * Equal to 0 means <code>str1</code> is identical to <code>str2</code>
+ * Greater than 0 means <code>str1</code> is more than <code>str2</code>
*/
static int compareString
(
@@ -519,8 +523,8 @@
* @return The return value indicates the relation of <code>str1</code> to
* <code>str2</code> as follows
* Less than 0 means <code>str1</code> is less than <code>str2</code>
- * Equal to 0 means <code>str1</code> is identical to <code>str2</code>
- * Greater than 0 means <code>str1</code> is more than <code>str2</code>
+ * Equal to 0 means <code>str1</code> is identical to <code>str2</code>
+ * Greater than 0 means <code>str1</code> is more than <code>str2</code>
*/
static int compareString
(
@@ -528,7 +532,7 @@
, const XMLCh* const str2
);
- /** Lexicographically compares <code>str1</code> and <code>str2</code>
+ /** Lexicographically compares <code>str1</code> and <code>str2</code>
* regions and returns true if they are equal, otherwise false.
*
* A substring of <code>str1</code> is compared to a substring of
@@ -550,9 +554,9 @@
* @param str2 Null-terminated string to compare
* @param offset2 Starting offset of str2
* @param charsCount The number of characters to compare
- * @return true if the specified subregion of <code>str1</code> exactly
- * matches the specified subregion of <code>str2></code>; false
- * otherwise.
+ * @return true if the specified subregion of <code>str1</code> exactly
+ * matches the specified subregion of <code>str2></code>; false
+ * otherwise.
*/
static bool regionMatches
(
@@ -563,8 +567,8 @@
, const unsigned int charCount
);
- /** Lexicographically compares <code>str1</code> and <code>str2</code>
- * regions without regard to case and returns true if they are equal,
+ /** Lexicographically compares <code>str1</code> and <code>str2</code>
+ * regions without regard to case and returns true if they are equal,
* otherwise false.
*
* A substring of <code>str1</code> is compared to a substring of
@@ -586,9 +590,9 @@
* @param str2 Null-terminated string to compare
* @param offset2 Starting offset of str2
* @param charsCount The number of characters to compare
- * @return true if the specified subregion of <code>str1</code> exactly
- * matches the specified subregion of <code>str2></code>; false
- * otherwise.
+ * @return true if the specified subregion of <code>str1</code> exactly
+ * matches the specified subregion of <code>str2></code>; false
+ * otherwise.
*/
static bool regionIMatches
(
@@ -828,7 +832,7 @@
/** @name Substring function */
//@{
/** Create a substring of a givend string. The substring begins at the
- * specified beginIndex and extends to the character at index
+ * specified beginIndex and extends to the character at index
* endIndex - 1.
* @param targetStr The string to copy the chars to
* @param srcStr The string to copy the chars from
@@ -840,11 +844,11 @@
char* const targetStr
, const char* const srcStr
, const int startIndex
- , const int endIndex
+ , const int endIndex
);
/** Create a substring of a givend string. The substring begins at the
- * specified beginIndex and extends to the character at index
+ * specified beginIndex and extends to the character at index
* endIndex - 1.
* @param targetStr The string to copy the chars to
* @param srcStr The string to copy the chars from
@@ -856,7 +860,7 @@
XMLCh* const targetStr
, const XMLCh* const srcStr
, const int startIndex
- , const int endIndex
+ , const int endIndex
);
//@}
@@ -985,7 +989,7 @@
/** Transcodes a string to native code-page
*
- * NOTE: The returned buffer is dynamically allocated and is the
+ * NOTE: The returned buffer is dynamically allocated and is the
* responsibility of the caller to delete it when not longer needed.
*
* @param toTranscode The string to be transcoded
@@ -1021,7 +1025,7 @@
/** Transcodes a string to native code-page
*
- * NOTE: The returned buffer is dynamically allocated and is the
+ * NOTE: The returned buffer is dynamically allocated and is the
* responsibility of the caller to delete it when not longer needed.
*
* @param toTranscode The string to be transcoded
@@ -1063,6 +1067,15 @@
* the trimmed string
*/
static void trim(XMLCh* const toTrim);
+
+ /** Break a string into tokens with space as delimiter, and
+ * stored in a string vector. The caller owns the string vector
+ * that is returned, and is responsible for deleting it.
+ * @param tokenizeStr String to be tokenized
+ * @return a vector of all the tokenized string
+ */
+ static RefVectorOf<XMLCh>* tokenizeString(const XMLCh* const tokenizeSrc);
+
//@}
/** @name Formatting functions */
@@ -1121,7 +1134,7 @@
private :
-
+
/** @name Constructors and Destructor */
//@{
/** Unimplemented default constructor */
@@ -1216,7 +1229,7 @@
const unsigned int charsCount)
{
- if (offset1 < 0 || offset2 < 0 ||
+ if (offset1 < 0 || offset2 < 0 ||
(offset1 + charsCount) > XMLString::stringLen(str1) ||
(offset2 + charsCount) > XMLString::stringLen(str2) )
return false;
1.1 xml-xerces/c/src/util/RefHash3KeysIdPool.c
Index: RefHash3KeysIdPool.c
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/**
* $Log: RefHash3KeysIdPool.c,v $
* Revision 1.1 2001/03/21 21:56:12 tng
* Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
*
*/
// ---------------------------------------------------------------------------
// Include
// ---------------------------------------------------------------------------
#if defined(XERCES_TMPLSINC)
#include <util/RefHash3KeysIdPool.hpp>
#endif
// ---------------------------------------------------------------------------
// RefHash3KeysIdPool: Constructors and Destructor
// ---------------------------------------------------------------------------
template <class TVal> RefHash3KeysIdPool<TVal>::RefHash3KeysIdPool(
const unsigned int modulus
, const bool adoptElems
, const unsigned int initSize) :
fAdoptedElems(adoptElems)
, fBucketList(0)
, fHashModulus(modulus)
, fIdPtrs(0)
, fIdPtrsCount(initSize)
, fIdCounter(0)
{
initialize(modulus);
// create default hasher
fHash = new HashXMLCh();
//
// Allocate the initial id pointers array. We don't have to zero them
// out since the fIdCounter value tells us which ones are valid. The
// zeroth element is never used (and represents an invalid pool id.)
//
if (!fIdPtrsCount)
fIdPtrsCount = 256;
fIdPtrs = new TVal*[fIdPtrsCount];
fIdPtrs[0] = 0;
}
template <class TVal> RefHash3KeysIdPool<TVal>::RefHash3KeysIdPool(
const unsigned int modulus
, const bool adoptElems
, HashBase* hash
, const unsigned int initSize) :
fAdoptedElems(adoptElems)
, fBucketList(0)
, fHashModulus(modulus)
, fIdPtrs(0)
, fIdPtrsCount(initSize)
, fIdCounter(0)
{
initialize(modulus);
// set hasher
fHash = hash;
//
// Allocate the initial id pointers array. We don't have to zero them
// out since the fIdCounter value tells us which ones are valid. The
// zeroth element is never used (and represents an invalid pool id.)
//
if (!fIdPtrsCount)
fIdPtrsCount = 256;
fIdPtrs = new TVal*[fIdPtrsCount];
fIdPtrs[0] = 0;
}
template <class TVal> RefHash3KeysIdPool<TVal>::RefHash3KeysIdPool(const unsigned int modulus
, const unsigned int initSize) :
fAdoptedElems(true)
, fBucketList(0)
, fHashModulus(modulus)
, fIdPtrs(0)
, fIdPtrsCount(initSize)
, fIdCounter(0)
{
initialize(modulus);
// create default hasher
fHash = new HashXMLCh();
//
// Allocate the initial id pointers array. We don't have to zero them
// out since the fIdCounter value tells us which ones are valid. The
// zeroth element is never used (and represents an invalid pool id.)
//
if (!fIdPtrsCount)
fIdPtrsCount = 256;
fIdPtrs = new TVal*[fIdPtrsCount];
fIdPtrs[0] = 0;
}
template <class TVal> void RefHash3KeysIdPool<TVal>::initialize(const unsigned int modulus)
{
if (modulus == 0)
ThrowXML(IllegalArgumentException, XMLExcepts::HshTbl_ZeroModulus);
// Allocate the bucket list and zero them
fBucketList = new RefHash3KeysTableBucketElem<TVal>*[fHashModulus];
for (unsigned int index = 0; index < fHashModulus; index++)
fBucketList[index] = 0;
}
template <class TVal> RefHash3KeysIdPool<TVal>::~RefHash3KeysIdPool()
{
removeAll();
// Then delete the bucket list & hasher & id pointers list
delete [] fIdPtrs;
delete [] fBucketList;
delete fHash;
}
// ---------------------------------------------------------------------------
// RefHash3KeysIdPool: Element management
// ---------------------------------------------------------------------------
template <class TVal> bool RefHash3KeysIdPool<TVal>::isEmpty() const
{
// Just check the bucket list for non-empty elements
for (unsigned int buckInd = 0; buckInd < fHashModulus; buckInd++)
{
if (fBucketList[buckInd] != 0)
return false;
}
return true;
}
template <class TVal> bool RefHash3KeysIdPool<TVal>::
containsKey(const void* const key1, const int key2, const int key3) const
{
unsigned int hashVal;
const RefHash3KeysTableBucketElem<TVal>* findIt = findBucketElem(key1, key2, key3, hashVal);
return (findIt != 0);
}
template <class TVal> void RefHash3KeysIdPool<TVal>::removeAll()
{
// Clean up the buckets first
for (unsigned int buckInd = 0; buckInd < fHashModulus; buckInd++)
{
// Get the bucket list head for this entry
RefHash3KeysTableBucketElem<TVal>* curElem = fBucketList[buckInd];
RefHash3KeysTableBucketElem<TVal>* nextElem;
while (curElem)
{
// Save the next element before we hose this one
nextElem = curElem->fNext;
// If we adopted the data, then delete it too
// (Note: the userdata hash table instance has data type of void *.
// This will generate compiler warnings here on some platforms, but they
// can be ignored since fAdoptedElements is false.
if (fAdoptedElems)
delete curElem->fData;
// Then delete the current element and move forward
delete curElem;
curElem = nextElem;
}
// Clean out this entry
fBucketList[buckInd] = 0;
}
// Reset the id counter
fIdCounter = 0;
}
// ---------------------------------------------------------------------------
// RefHash3KeysIdPool: Getters
// ---------------------------------------------------------------------------
template <class TVal> TVal*
RefHash3KeysIdPool<TVal>::getByKey(const void* const key1, const int key2, const int key3)
{
unsigned int hashVal;
RefHash3KeysTableBucketElem<TVal>* findIt = findBucketElem(key1, key2, key3, hashVal);
if (!findIt)
return 0;
return findIt->fData;
}
template <class TVal> const TVal*
RefHash3KeysIdPool<TVal>::getByKey(const void* const key1, const int key2, const int key3) const
{
unsigned int hashVal;
const RefHash3KeysTableBucketElem<TVal>* findIt = findBucketElem(key1, key2, key3, hashVal);
if (!findIt)
return 0;
return findIt->fData;
}
template <class TVal> TVal*
RefHash3KeysIdPool<TVal>::getById(const unsigned int elemId)
{
// If its either zero or beyond our current id, its an error
if (!elemId || (elemId > fIdCounter))
ThrowXML(IllegalArgumentException, XMLExcepts::Pool_InvalidId);
return fIdPtrs[elemId];
}
template <class TVal> const TVal*
RefHash3KeysIdPool<TVal>::getById(const unsigned int elemId) const
{
// If its either zero or beyond our current id, its an error
if (!elemId || (elemId > fIdCounter))
ThrowXML(IllegalArgumentException, XMLExcepts::Pool_InvalidId);
return fIdPtrs[elemId];
}
// ---------------------------------------------------------------------------
// RefHash3KeysIdPool: Putters
// ---------------------------------------------------------------------------
template <class TVal> unsigned int
RefHash3KeysIdPool<TVal>::put(void* key1, int key2, int key3, TVal* const valueToAdopt)
{
// First see if the key exists already
unsigned int hashVal;
RefHash3KeysTableBucketElem<TVal>* newBucket = findBucketElem(key1, key2, key3, hashVal);
//
// If so,then update its value. If not, then we need to add it to
// the right bucket
//
if (newBucket)
{
if (fAdoptedElems)
delete newBucket->fData;
newBucket->fData = valueToAdopt;
newBucket->fKey1 = key1;
newBucket->fKey2 = key2;
newBucket->fKey3 = key3;
}
else
{
newBucket = new RefHash3KeysTableBucketElem<TVal>(key1, key2, key3, valueToAdopt, fBucketList[hashVal]);
fBucketList[hashVal] = newBucket;
}
//
// Give this new one the next available id and add to the pointer list.
// Expand the list if that is now required.
//
if (fIdCounter + 1 == fIdPtrsCount)
{
// Create a new count 1.5 times larger and allocate a new array
unsigned int newCount = (unsigned int)(fIdPtrsCount * 1.5);
TVal** newArray = new TVal*[newCount];
// Copy over the old contents to the new array
memcpy(newArray, fIdPtrs, fIdPtrsCount * sizeof(TVal*));
// Ok, toss the old array and store the new data
delete [] fIdPtrs;
fIdPtrs = newArray;
fIdPtrsCount = newCount;
}
const unsigned int retId = ++fIdCounter;
fIdPtrs[retId] = valueToAdopt;
// Set the id on the passed element
valueToAdopt->setId(retId);
// Return the id that we gave to this element
return retId;
}
// ---------------------------------------------------------------------------
// RefHash3KeysIdPool: Private methods
// ---------------------------------------------------------------------------
template <class TVal> RefHash3KeysTableBucketElem<TVal>* RefHash3KeysIdPool<TVal>::
findBucketElem(const void* const key1, const int key2, const int key3, unsigned int& hashVal)
{
// Hash the key
hashVal = fHash->getHashVal(key1, fHashModulus);
if (hashVal > fHashModulus)
ThrowXML(RuntimeException, XMLExcepts::HshTbl_BadHashFromKey);
// Search that bucket for the key
RefHash3KeysTableBucketElem<TVal>* curElem = fBucketList[hashVal];
while (curElem)
{
if (fHash->equals(key1, curElem->fKey1) && (key2==curElem->fKey2) && (key3==curElem->fKey3))
return curElem;
curElem = curElem->fNext;
}
return 0;
}
template <class TVal> const RefHash3KeysTableBucketElem<TVal>* RefHash3KeysIdPool<TVal>::
findBucketElem(const void* const key1, const int key2, const int key3, unsigned int& hashVal) const
{
// Hash the key
hashVal = fHash->getHashVal(key1, fHashModulus);
if (hashVal > fHashModulus)
ThrowXML(RuntimeException, XMLExcepts::HshTbl_BadHashFromKey);
// Search that bucket for the key
const RefHash3KeysTableBucketElem<TVal>* curElem = fBucketList[hashVal];
while (curElem)
{
if (fHash->equals(key1, curElem->fKey1) && (key2==curElem->fKey2) && (key3==curElem->fKey3))
return curElem;
curElem = curElem->fNext;
}
return 0;
}
// ---------------------------------------------------------------------------
// RefHash3KeysIdPoolEnumerator: Constructors and Destructor
// ---------------------------------------------------------------------------
template <class TVal> RefHash3KeysIdPoolEnumerator<TVal>::
RefHash3KeysIdPoolEnumerator(RefHash3KeysIdPool<TVal>* const toEnum, const bool adopt)
: fAdoptedElems(adopt), fCurIndex(0), fToEnum(toEnum)
{
//
// Find the next available bucket element in the pool. We use the id
// array since its very easy to enumerator through by just maintaining
// an index. If the id counter is zero, then its empty and we leave the
// current index to zero.
//
if (toEnum->fIdCounter)
fCurIndex = 1;
}
template <class TVal> RefHash3KeysIdPoolEnumerator<TVal>::~RefHash3KeysIdPoolEnumerator()
{
if (fAdoptedElems)
delete fToEnum;
}
// ---------------------------------------------------------------------------
// RefHash3KeysIdPoolEnumerator: Enum interface
// ---------------------------------------------------------------------------
template <class TVal> bool RefHash3KeysIdPoolEnumerator<TVal>::hasMoreElements() const
{
// If our index is zero or past the end, then we are done
if (!fCurIndex || (fCurIndex > fToEnum->fIdCounter))
return false;
return true;
}
template <class TVal> TVal& RefHash3KeysIdPoolEnumerator<TVal>::nextElement()
{
// If our index is zero or past the end, then we are done
if (!fCurIndex || (fCurIndex > fToEnum->fIdCounter))
ThrowXML(NoSuchElementException, XMLExcepts::Enum_NoMoreElements);
// Return the current element and bump the index
return *fToEnum->fIdPtrs[fCurIndex++];
}
template <class TVal> void RefHash3KeysIdPoolEnumerator<TVal>::Reset()
{
fCurIndex = 0;
}
1.1 xml-xerces/c/src/util/RefHash3KeysIdPool.hpp
Index: RefHash3KeysIdPool.hpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Log: RefHash3KeysIdPool.hpp,v $
* Revision 1.1 2001/03/21 21:56:12 tng
* Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
*
*/
#if !defined(REFHASH3KEYSIDPOOL_HPP)
#define REFHASH3KEYSIDPOOL_HPP
#include <util/XercesDefs.hpp>
#include <util/KeyValuePair.hpp>
#include <util/HashBase.hpp>
#include <util/IllegalArgumentException.hpp>
#include <util/NoSuchElementException.hpp>
#include <util/RuntimeException.hpp>
#include <util/XMLExceptMsgs.hpp>
#include <util/XMLEnumerator.hpp>
#include <util/XMLString.hpp>
#include <util/HashBase.hpp>
#include <util/HashXMLCh.hpp>
// This hash table is a combination of RefHash2KeyTableOf (with an additional integer as key3)
// and NameIdPool with an id as index
//
// Forward declare the enumerator so he can be our friend. Can you say
// friend? Sure...
//
template <class TVal> class RefHash3KeysIdPoolEnumerator;
template <class TVal> struct RefHash3KeysTableBucketElem;
//
// This should really be a nested class, but some of the compilers we
// have to support cannot deal with that!
//
template <class TVal> struct RefHash3KeysTableBucketElem
{
RefHash3KeysTableBucketElem(
void* key1
, int key2
, int key3
, TVal* const value
, RefHash3KeysTableBucketElem<TVal>* next) :
fData(value)
, fNext(next)
, fKey1(key1)
, fKey2(key2)
, fKey3(key3)
{
}
TVal* fData;
RefHash3KeysTableBucketElem<TVal>* fNext;
void* fKey1;
int fKey2;
int fKey3;
};
template <class TVal> class RefHash3KeysIdPool
{
public:
// -----------------------------------------------------------------------
// Constructors and Destructor
// -----------------------------------------------------------------------
// backwards compatability - default hasher is HashXMLCh
RefHash3KeysIdPool
(
const unsigned int modulus
, const unsigned int initSize = 128
);
// backwards compatability - default hasher is HashXMLCh
RefHash3KeysIdPool
(
const unsigned int modulus
, const bool adoptElems
, const unsigned int initSize = 128
);
// if a hash function is passed in, it will be deleted when the hashtable is deleted.
// use a new instance of the hasher class for each hashtable, otherwise one hashtable
// may delete the hasher of a different hashtable if both use the same hasher.
RefHash3KeysIdPool
(
const unsigned int modulus
, const bool adoptElems, HashBase* hash
, const unsigned int initSize = 128
);
~RefHash3KeysIdPool();
// -----------------------------------------------------------------------
// Element management
// -----------------------------------------------------------------------
bool isEmpty() const;
bool containsKey(const void* const key1, const int key2, const int key3) const;
void removeAll();
// -----------------------------------------------------------------------
// Getters
// -----------------------------------------------------------------------
TVal* getByKey(const void* const key1, const int key2, const int key3);
const TVal* getByKey(const void* const key1, const int key2, const int key3) const;
TVal* getById(const unsigned elemId);
const TVal* getById(const unsigned elemId) const;
// -----------------------------------------------------------------------
// Putters
// -----------------------------------------------------------------------
unsigned int put(void* key1, int key2, int key3, TVal* const valueToAdopt);
private :
// -----------------------------------------------------------------------
// Declare our friends
// -----------------------------------------------------------------------
friend class RefHash3KeysIdPoolEnumerator<TVal>;
private:
// -----------------------------------------------------------------------
// Private methods
// -----------------------------------------------------------------------
RefHash3KeysTableBucketElem<TVal>* findBucketElem(const void* const key1, const int key2, const int key3, unsigned int& hashVal);
const RefHash3KeysTableBucketElem<TVal>* findBucketElem(const void* const key1, const int key2, const int key3, unsigned int& hashVal) const;
void initialize(const unsigned int modulus);
// -----------------------------------------------------------------------
// Data members
//
// fAdoptedElems
// Indicates whether the values added are adopted or just referenced.
// If adopted, then they are deleted when they are removed from the
// hash table.
//
// fBucketList
// This is the array that contains the heads of all of the list
// buckets, one for each possible hash value.
//
// fHashModulus
// The modulus used for this hash table, to hash the keys. This is
// also the number of elements in the bucket list.
//
// fHash
// The hasher for the key1 data type.
//
// fIdPtrs
// fIdPtrsCount
// This is the array of pointers to the bucket elements in order of
// their assigned ids. So taking id N and referencing this array
// gives you the element with that id. The count field indicates
// the current size of this list. When fIdCounter+1 reaches this
// value the list must be expanded.
//
// fIdCounter
// This is used to give out unique ids to added elements. It starts
// at zero (which means empty), and is bumped up for each newly added
// element. So the first element is 1, the next is 2, etc... This
// means that this value is set to the top index of the fIdPtrs array.
// -----------------------------------------------------------------------
bool fAdoptedElems;
RefHash3KeysTableBucketElem<TVal>** fBucketList;
unsigned int fHashModulus;
HashBase* fHash;
TVal** fIdPtrs;
unsigned int fIdPtrsCount;
unsigned int fIdCounter;
};
//
// An enumerator for a value array. It derives from the basic enumerator
// class, so that value vectors can be generically enumerated.
//
template <class TVal> class RefHash3KeysIdPoolEnumerator : public XMLEnumerator<TVal>
{
public :
// -----------------------------------------------------------------------
// Constructors and Destructor
// -----------------------------------------------------------------------
RefHash3KeysIdPoolEnumerator(RefHash3KeysIdPool<TVal>* const toEnum, const bool adopt = false);
~RefHash3KeysIdPoolEnumerator();
// -----------------------------------------------------------------------
// Enum interface
// -----------------------------------------------------------------------
bool hasMoreElements() const;
TVal& nextElement();
void Reset();
private :
// -----------------------------------------------------------------------
// Data Members
// fAdoptedElems
// Indicates whether the values added are adopted or just referenced.
// If adopted, then they are deleted when they are removed from the
// hash table
//
// fCurIndex
// This is the current index into the pool's id mapping array. This
// is now we enumerate it.
//
// fToEnum
// The name id pool that is being enumerated.
// -----------------------------------------------------------------------
bool fAdoptedElems;
unsigned int fCurIndex;
RefHash3KeysIdPool<TVal>* fToEnum;
};
#if !defined(XERCES_TMPLSINC)
#include <util/RefHash3KeysIdPool.c>
#endif
#endif
1.15 +8 -4 xml-xerces/c/src/util/MsgLoaders/InMemory/CppErrMsgs_EN_US.hpp
Index: CppErrMsgs_EN_US.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/util/MsgLoaders/InMemory/CppErrMsgs_EN_US.hpp,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- CppErrMsgs_EN_US.hpp 2001/03/02 20:53:21 1.14
+++ CppErrMsgs_EN_US.hpp 2001/03/21 21:56:15 1.15
@@ -154,12 +154,13 @@
, { 0x0056,0x0061,0x006C,0x0075,0x0065,0x0020,0x006F,0x0066,0x0020,0x007B,0x0030,0x007D,0x0020,0x0069,0x0073,0x0020,0x006E,0x006F,0x0074,0x0020,0x0061,0x006E,0x0020,0x0069,0x006E,0x0074,0x0065,0x0067,0x0065,0x0072,0x002E,0x00 }
, { 0x0044,0x0061,0x0074,0x0061,0x0074,0x0079,0x0070,0x0065,0x0020,0x0065,0x0072,0x0072,0x006F,0x0072,0x003A,0x0020,0x007B,0x0030,0x007D,0x002E,0x00 }
, { 0x0054,0x0068,0x0065,0x0020,0x0074,0x0079,0x0070,0x0065,0x0020,0x006F,0x0066,0x0020,0x0074,0x0068,0x0065,0x0020,0x0065,0x006C,0x0065,0x006D,0x0065,0x006E,0x0074,0x0020,0x0068,0x0061,0x0073,0x0020,0x0061,0x006C,0x0072,0x0065,0x0061,0x0064,0x0079,0x0020,0x0062,0x0065,0x0065,0x006E,0x0020,0x0064,0x0065,0x0063,0x006C,0x0061,0x0072,0x0065,0x0064,0x002E,0x00 }
- , { 0x0053,0x0063,0x0068,0x0065,0x006D,0x0061,0x0020,0x0065,0x0072,0x0072,0x006F,0x0072,0x003A,0x0020,0x007B,0x0030,0x007D,0x002E,0x00 }
+ , { 0x0053,0x0063,0x0068,0x0065,0x006D,0x0061,0x0020,0x0065,0x0072,0x0072,0x006F,0x0072,0x0020,0x0064,0x0075,0x0072,0x0069,0x006E,0x0067,0x0020,0x0070,0x0061,0x0072,0x0073,0x0069,0x006E,0x0067,0x00 }
, { 0x0055,0x006E,0x0065,0x0078,0x0070,0x0065,0x0063,0x0074,0x0065,0x0064,0x0045,0x0072,0x0072,0x006F,0x0072,0x00 }
+ , { 0x0054,0x0068,0x0065,0x0020,0x0073,0x0063,0x0068,0x0065,0x006D,0x0061,0x004C,0x006F,0x0063,0x0061,0x0074,0x0069,0x006F,0x006E,0x0020,0x0061,0x0074,0x0074,0x0072,0x0069,0x0062,0x0075,0x0074,0x0065,0x0020,0x0064,0x006F,0x0065,0x0073,0x0020,0x006E,0x006F,0x0074,0x0020,0x0063,0x006F,0x006E,0x0074,0x0061,0x0069,0x006E,0x0020,0x0070,0x0061,0x0069,0x0072,0x0073,0x0020,0x006F,0x0066,0x0020,0x0076,0x0061,0x006C,0x0075,0x0065,0x0073,0x002E,0x00 }
, { 0x0045,0x005F,0x0045,0x006E,0x0064,0x00 }
};
-const unsigned int gXMLErrArraySize = 155;
+const unsigned int gXMLErrArraySize = 156;
const XMLCh gXMLValidityArray[][128] =
{
@@ -206,10 +207,12 @@
, { 0x007B,0x0030,0x007D,0x0020,0x0068,0x0061,0x0073,0x0020,0x0065,0x0078,0x0063,0x0065,0x0065,0x0064,0x0065,0x0064,0x0020,0x0074,0x0068,0x0065,0x0020,0x0070,0x0072,0x0065,0x0063,0x0069,0x0073,0x0069,0x006F,0x006E,0x0020,0x0046,0x0061,0x0063,0x0065,0x0074,0x0020,0x007B,0x0031,0x007D,0x00 }
, { 0x007B,0x0030,0x007D,0x0020,0x0068,0x0061,0x0073,0x0020,0x0065,0x0078,0x0065,0x0063,0x0065,0x0065,0x0064,0x0020,0x0074,0x0068,0x0065,0x0020,0x0073,0x0063,0x0061,0x006C,0x0065,0x0020,0x0046,0x0061,0x0063,0x0065,0x0074,0x0020,0x007B,0x0031,0x007D,0x00 }
, { 0x007B,0x0030,0x007D,0x0020,0x0069,0x0073,0x0020,0x006E,0x006F,0x0074,0x0020,0x0061,0x0020,0x0066,0x006C,0x006F,0x0061,0x0074,0x002E,0x00 }
+ , { 0x0043,0x0061,0x006E,0x0027,0x0074,0x0020,0x0067,0x0065,0x0074,0x0020,0x0062,0x0061,0x0063,0x006B,0x0020,0x0053,0x0063,0x0068,0x0065,0x006D,0x0061,0x0020,0x0064,0x006F,0x0063,0x0075,0x006D,0x0065,0x006E,0x0074,0x0027,0x0073,0x0020,0x0072,0x006F,0x006F,0x0074,0x0020,0x0065,0x006C,0x0065,0x006D,0x0065,0x006E,0x0074,0x0020,0x007B,0x0030,0x007D,0x002E,0x00 }
+ , { 0x0053,0x0063,0x0068,0x0065,0x006D,0x0061,0x0020,0x0069,0x006E,0x0020,0x007B,0x0030,0x007D,0x0020,0x0068,0x0061,0x0073,0x0020,0x0061,0x0020,0x0064,0x0069,0x0066,0x0066,0x0065,0x0072,0x0065,0x006E,0x0074,0x0020,0x0074,0x0061,0x0072,0x0067,0x0065,0x0074,0x0020,0x006E,0x0061,0x006D,0x0065,0x0073,0x0070,0x0061,0x0063,0x0065,0x0020,0x0066,0x0072,0x006F,0x006D,0x0020,0x0074,0x0068,0x0065,0x0020,0x006F,0x006E,0x0065,0x0020,0x0073,0x0070,0x0065,0x0063,0x0069,0x0066,0x0069,0x0065,0x0064,0x0020,0x0069,0x006E,0x0020,0x0074,0x0068,0x0065,0x0020,0x0069,0x006E,0x0073,0x0074,0x0061,0x006E,0x0063,0x0065,0x0020,0x0064,0x006F,0x0063,0x0075,0x006D,0x0065,0x006E,0x0074,0x0020,0x007B,0x0031,0x007D,0x002E,0x00 }
, { 0x0056,0x005F,0x0045,0x006E,0x0064,0x00 }
};
-const unsigned int gXMLValidityArraySize = 49;
+const unsigned int gXMLValidityArraySize = 51;
const XMLCh gXMLExceptArray[][128] =
{
@@ -348,8 +351,9 @@
, { 0x0049,0x006E,0x0076,0x0061,0x006C,0x0069,0x0064,0x0020,0x0055,0x006E,0x0069,0x0063,0x006F,0x0064,0x0065,0x0020,0x0063,0x006F,0x0064,0x0065,0x0020,0x0070,0x006F,0x0069,0x006E,0x0074,0x00 }
, { 0x0041,0x006E,0x0020,0x0061,0x006E,0x0063,0x0068,0x006F,0x0072,0x0020,0x006D,0x0075,0x0073,0x0074,0x0020,0x006E,0x006F,0x0074,0x0020,0x0062,0x0065,0x0020,0x0068,0x0065,0x0072,0x0065,0x00 }
, { 0x0054,0x0068,0x0069,0x0073,0x0020,0x0065,0x0078,0x0070,0x0072,0x0065,0x0073,0x0073,0x0069,0x006F,0x006E,0x0020,0x0069,0x0073,0x0020,0x006E,0x006F,0x0074,0x0020,0x0073,0x0075,0x0070,0x0070,0x006F,0x0072,0x0074,0x0065,0x0064,0x0020,0x0069,0x006E,0x0020,0x0074,0x0068,0x0065,0x0020,0x0063,0x0075,0x0072,0x0072,0x0065,0x006E,0x0074,0x0020,0x006F,0x0070,0x0074,0x0069,0x006F,0x006E,0x0020,0x0073,0x0065,0x0074,0x0074,0x0069,0x006E,0x0067,0x00 }
+ , { 0x0041,0x0020,0x0073,0x0063,0x0068,0x0065,0x006D,0x0061,0x0020,0x0077,0x0061,0x0073,0x0020,0x0073,0x0065,0x0065,0x006E,0x0020,0x0062,0x0075,0x0074,0x0020,0x0074,0x0068,0x0065,0x0020,0x0069,0x006E,0x0073,0x0074,0x0061,0x006C,0x006C,0x0065,0x0064,0x0020,0x0076,0x0061,0x006C,0x0069,0x0064,0x0061,0x0074,0x006F,0x0072,0x0020,0x0064,0x006F,0x0065,0x0073,0x0020,0x006E,0x006F,0x0074,0x0020,0x0075,0x006E,0x0064,0x0065,0x0072,0x0073,0x0074,0x0061,0x006E,0x0064,0x0020,0x0073,0x0063,0x0068,0x0065,0x006D,0x0061,0x00 }
, { 0x0045,0x005F,0x0045,0x006E,0x0064,0x00 }
};
-const unsigned int gXMLExceptArraySize = 141;
+const unsigned int gXMLExceptArraySize = 142;
1.18 +5 -1 xml-xerces/c/src/util/MsgLoaders/MsgCatalog/XMLMsgCat_EN_US.Msg
Index: XMLMsgCat_EN_US.Msg
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/util/MsgLoaders/MsgCatalog/XMLMsgCat_EN_US.Msg,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- XMLMsgCat_EN_US.Msg 2001/03/02 20:53:24 1.17
+++ XMLMsgCat_EN_US.Msg 2001/03/21 21:56:16 1.18
@@ -146,8 +146,9 @@
147 Value of {0} is not an integer.
148 Datatype error: {0}.
149 The type of the element has already been declared.
-150 Schema error: {0}.
+150 Schema error during parsing
151 UnexpectedError
+152 The schemaLocation attribute does not contain pairs of values.
$set 2
@@ -193,6 +194,8 @@
41 {0} has exceeded the precision Facet {1}
42 {0} has execeed the scale Facet {1}
43 {0} is not a float.
+ 44 Can't get back Schema document's root element {0}.
+ 45 Schema in {0} has a different target namespace from the one specified in the instance document {1}.
$set 3
@@ -330,5 +333,6 @@
133 Invalid Unicode code point
134 An anchor must not be here
135 This expression is not supported in the current option setting
+136 A schema was seen but the installed validator does not understand schema
1.21 +7 -3 xml-xerces/c/src/util/Platforms/Win32/Version.rc
Index: Version.rc
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/util/Platforms/Win32/Version.rc,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- Version.rc 2001/03/02 20:53:28 1.20
+++ Version.rc 2001/03/21 21:56:17 1.21
@@ -101,8 +101,9 @@
//
// ----------------------------------------------------------------
// This data was generated from the XML error message source.
-// so do not edit this file directly!! Like you could anyway...
+// so do not edit this file directly!!
// ----------------------------------------------------------------
+
STRINGTABLE DISCARDABLE
BEGIN
2 L"\x004E\x006F\x0074\x0061\x0074\x0069\x006F\x006E\x0020\x0027\x007B\x0030\x007D\x0027\x0020\x0068\x0061\x0073\x0020\x0061\x006C\x0072\x0065\x0061\x0064\x0079\x0020\x0062\x0065\x0065\x006E\x0020\x0064\x0065\x0063\x006C\x0061\x0072\x0065\x0064\x00"
@@ -251,8 +252,9 @@
147 L"\x0056\x0061\x006C\x0075\x0065\x0020\x006F\x0066\x0020\x007B\x0030\x007D\x0020\x0069\x0073\x0020\x006E\x006F\x0074\x0020\x0061\x006E\x0020\x0069\x006E\x0074\x0065\x0067\x0065\x0072\x002E\x00"
148 L"\x0044\x0061\x0074\x0061\x0074\x0079\x0070\x0065\x0020\x0065\x0072\x0072\x006F\x0072\x003A\x0020\x007B\x0030\x007D\x002E\x00"
149 L"\x0054\x0068\x0065\x0020\x0074\x0079\x0070\x0065\x0020\x006F\x0066\x0020\x0074\x0068\x0065\x0020\x0065\x006C\x0065\x006D\x0065\x006E\x0074\x0020\x0068\x0061\x0073\x0020\x0061\x006C\x0072\x0065\x0061\x0064\x0079\x0020\x0062\x0065\x0065\x006E\x0020\x0064\x0065\x0063\x006C\x0061\x0072\x0065\x0064\x002E\x00"
- 150 L"\x0053\x0063\x0068\x0065\x006D\x0061\x0020\x0065\x0072\x0072\x006F\x0072\x003A\x0020\x007B\x0030\x007D\x002E\x00"
+ 150 L"\x0053\x0063\x0068\x0065\x006D\x0061\x0020\x0065\x0072\x0072\x006F\x0072\x0020\x0064\x0075\x0072\x0069\x006E\x0067\x0020\x0070\x0061\x0072\x0073\x0069\x006E\x0067\x00"
151 L"\x0055\x006E\x0065\x0078\x0070\x0065\x0063\x0074\x0065\x0064\x0045\x0072\x0072\x006F\x0072\x00"
+ 152 L"\x0054\x0068\x0065\x0020\x0073\x0063\x0068\x0065\x006D\x0061\x004C\x006F\x0063\x0061\x0074\x0069\x006F\x006E\x0020\x0061\x0074\x0074\x0072\x0069\x0062\x0075\x0074\x0065\x0020\x0064\x006F\x0065\x0073\x0020\x006E\x006F\x0074\x0020\x0063\x006F\x006E\x0074\x0061\x0069\x006E\x0020\x0070\x0061\x0069\x0072\x0073\x0020\x006F\x0066\x0020\x0076\x0061\x006C\x0075\x0065\x0073\x002E\x00"
END
STRINGTABLE DISCARDABLE
BEGIN
@@ -298,6 +300,8 @@
16425 L"\x007B\x0030\x007D\x0020\x0068\x0061\x0073\x0020\x0065\x0078\x0063\x0065\x0065\x0064\x0065\x0064\x0020\x0074\x0068\x0065\x0020\x0070\x0072\x0065\x0063\x0069\x0073\x0069\x006F\x006E\x0020\x0046\x0061\x0063\x0065\x0074\x0020\x007B\x0031\x007D\x00"
16426 L"\x007B\x0030\x007D\x0020\x0068\x0061\x0073\x0020\x0065\x0078\x0065\x0063\x0065\x0065\x0064\x0020\x0074\x0068\x0065\x0020\x0073\x0063\x0061\x006C\x0065\x0020\x0046\x0061\x0063\x0065\x0074\x0020\x007B\x0031\x007D\x00"
16427 L"\x007B\x0030\x007D\x0020\x0069\x0073\x0020\x006E\x006F\x0074\x0020\x0061\x0020\x0066\x006C\x006F\x0061\x0074\x002E\x00"
+ 16428 L"\x0043\x0061\x006E\x0027\x0074\x0020\x0067\x0065\x0074\x0020\x0062\x0061\x0063\x006B\x0020\x0053\x0063\x0068\x0065\x006D\x0061\x0020\x0064\x006F\x0063\x0075\x006D\x0065\x006E\x0074\x0027\x0073\x0020\x0072\x006F\x006F\x0074\x0020\x0065\x006C\x0065\x006D\x0065\x006E\x0074\x0020\x007B\x0030\x007D\x002E\x00"
+ 16429 L"\x0053\x0063\x0068\x0065\x006D\x0061\x0020\x0069\x006E\x0020\x007B\x0030\x007D\x0020\x0068\x0061\x0073\x0020\x0061\x0020\x0064\x0069\x0066\x0066\x0065\x0072\x0065\x006E\x0074\x0020\x0074\x0061\x0072\x0067\x0065\x0074\x0020\x006E\x0061\x006D\x0065\x0073\x0070\x0061\x0063\x0065\x0020\x0066\x0072\x006F\x006D\x0020\x0074\x0068\x0065\x0020\x006F\x006E\x0065\x0020\x0073\x0070\x0065\x0063\x0069\x0066\x0069\x0065\x0064\x0020\x0069\x006E\x0020\x0074\x0068\x0065\x0020\x0069\x006E\x0073\x0074\x0061\x006E\x0063\x0065\x0020\x0064\x006F\x0063\x0075\x006D\x0065\x006E\x0074\x0020\x007B\x0031\x007D\x002E\x00"
END
STRINGTABLE DISCARDABLE
BEGIN
@@ -435,8 +439,8 @@
8325 L"\x0049\x006E\x0076\x0061\x006C\x0069\x0064\x0020\x0055\x006E\x0069\x0063\x006F\x0064\x0065\x0020\x0063\x006F\x0064\x0065\x0020\x0070\x006F\x0069\x006E\x0074\x00"
8326 L"\x0041\x006E\x0020\x0061\x006E\x0063\x0068\x006F\x0072\x0020\x006D\x0075\x0073\x0074\x0020\x006E\x006F\x0074\x0020\x0062\x0065\x0020\x0068\x0065\x0072\x0065\x00"
8327 L"\x0054\x0068\x0069\x0073\x0020\x0065\x0078\x0070\x0072\x0065\x0073\x0073\x0069\x006F\x006E\x0020\x0069\x0073\x0020\x006E\x006F\x0074\x0020\x0073\x0075\x0070\x0070\x006F\x0072\x0074\x0065\x0064\x0020\x0069\x006E\x0020\x0074\x0068\x0065\x0020\x0063\x0075\x0072\x0072\x0065\x006E\x0074\x0020\x006F\x0070\x0074\x0069\x006F\x006E\x0020\x0073\x0065\x0074\x0074\x0069\x006E\x0067\x00"
+ 8328 L"\x0041\x0020\x0073\x0063\x0068\x0065\x006D\x0061\x0020\x0077\x0061\x0073\x0020\x0073\x0065\x0065\x006E\x0020\x0062\x0075\x0074\x0020\x0074\x0068\x0065\x0020\x0069\x006E\x0073\x0074\x0061\x006C\x006C\x0065\x0064\x0020\x0076\x0061\x006C\x0069\x0064\x0061\x0074\x006F\x0072\x0020\x0064\x006F\x0065\x0073\x0020\x006E\x006F\x0074\x0020\x0075\x006E\x0064\x0065\x0072\x0073\x0074\x0061\x006E\x0064\x0020\x0073\x0063\x0068\x0065\x006D\x0061\x00"
END
-
#endif // English (U.S.) resources
1.11 +27 -6 xml-xerces/c/src/validators/DTD/DTDElementDecl.cpp
Index: DTDElementDecl.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/validators/DTD/DTDElementDecl.cpp,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- DTDElementDecl.cpp 2001/03/21 19:29:40 1.10
+++ DTDElementDecl.cpp 2001/03/21 21:56:19 1.11
@@ -55,7 +55,7 @@
*/
/*
- * $Id: DTDElementDecl.cpp,v 1.10 2001/03/21 19:29:40 tng Exp $
+ * $Id: DTDElementDecl.cpp,v 1.11 2001/03/21 21:56:19 tng Exp $
*/
@@ -166,6 +166,27 @@
return fBaseName;
}
+XMLCh* DTDElementDecl::getBaseName()
+{
+ //
+ // If the base name nas not been extraced, then do it now. Since we are
+ // faulting it in from a const method, we have to cast off the constness.
+ //
+ if (!fBaseName)
+ {
+ //
+ // Search for the first colon in the name. Note that, if its not
+ // found, then it will be -1, which will still make the replicate
+ // logic work correctly.
+ //
+ int colonPos = XMLString::indexOf(fQName, chColon);
+ ((DTDElementDecl*)this)->fBaseName = XMLString::replicate(&fQName[colonPos + 1]);
+ }
+
+ // Just return our QName
+ return fBaseName;
+}
+
XMLElementDecl::CharDataOpts DTDElementDecl::getCharDataOpts() const
{
@@ -266,7 +287,7 @@
// DTDElementDecl: Implementation of the protected virtual interface
// ---------------------------------------------------------------------------
XMLCh*
-DTDElementDecl::formatContentModel(const XMLValidator& validator) const
+DTDElementDecl::formatContentModel(const Grammar& grammar) const
{
XMLCh* newValue = 0;
if (fModelType == Any)
@@ -285,13 +306,13 @@
// will expand to handle the more pathological ones.
//
XMLBuffer bufFmt;
- fContentSpec->formatSpec(validator, bufFmt);
+ fContentSpec->formatSpec(grammar, bufFmt);
newValue = XMLString::replicate(bufFmt.getRawBuffer());
}
return newValue;
}
-XMLContentModel* DTDElementDecl::makeContentModel(XMLValidator* pValidator) const
+XMLContentModel* DTDElementDecl::makeContentModel(const Grammar* grammar) const
{
XMLContentModel* cmRet = 0;
if (fModelType == Mixed)
@@ -311,7 +332,7 @@
// create a SimpleListContentModel object. If its complex, it
// will create a DFAContentModel object.
//
- cmRet = createChildModel(pValidator);
+ cmRet = createChildModel(grammar);
}
else
{
@@ -325,7 +346,7 @@
// ---------------------------------------------------------------------------
// DTDElementDecl: Private helper methods
// ---------------------------------------------------------------------------
-XMLContentModel* DTDElementDecl::createChildModel(XMLValidator* pValidator) const
+XMLContentModel* DTDElementDecl::createChildModel(const Grammar* grammar) const
{
// Get the content spec node of the element
const ContentSpecNode* specNode = getContentSpec();
1.8 +8 -4 xml-xerces/c/src/validators/DTD/DTDElementDecl.hpp
Index: DTDElementDecl.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/validators/DTD/DTDElementDecl.hpp,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- DTDElementDecl.hpp 2001/03/21 19:29:43 1.7
+++ DTDElementDecl.hpp 2001/03/21 21:56:19 1.8
@@ -56,6 +56,9 @@
/*
* $Log: DTDElementDecl.hpp,v $
+ * Revision 1.8 2001/03/21 21:56:19 tng
+ * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+ *
* Revision 1.7 2001/03/21 19:29:43 tng
* Schema: Content Model Updates, by Pei Yong Zhang.
*
@@ -150,6 +153,7 @@
) const;
virtual XMLAttDefList& getAttDefList() const;
virtual const XMLCh* getBaseName() const;
+ virtual XMLCh* getBaseName() ;
virtual const int getURI() const;
virtual CharDataOpts getCharDataOpts() const;
virtual const XMLCh* getFullName() const;
@@ -164,7 +168,7 @@
//
// This method allows objects of this type be placed into one of the
// standard keyed collections. This method will return the full name of
- // the element, which will vary depending upon the type of the validator.
+ // the element, which will vary depending upon the type of the grammar.
// -----------------------------------------------------------------------
const XMLCh* getKey() const;
@@ -188,10 +192,10 @@
// -----------------------------------------------------------------------
// Protected, virtual methods
// -----------------------------------------------------------------------
- virtual XMLContentModel* makeContentModel(XMLValidator* pValidator=0) const;
+ virtual XMLContentModel* makeContentModel(const Grammar* grammar=0) const;
virtual XMLCh* formatContentModel
(
- const XMLValidator& validator
+ const Grammar& grammar
) const;
@@ -199,7 +203,7 @@
// -----------------------------------------------------------------------
// Private helper methods
// -----------------------------------------------------------------------
- XMLContentModel* createChildModel(XMLValidator* pValidator=0) const;
+ XMLContentModel* createChildModel(const Grammar* grammar=0) const;
void faultInAttDefList() const;
1.15 +150 -415 xml-xerces/c/src/validators/DTD/DTDValidator.cpp
Index: DTDValidator.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/validators/DTD/DTDValidator.cpp,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- DTDValidator.cpp 2001/02/26 19:22:04 1.14
+++ DTDValidator.cpp 2001/03/21 21:56:20 1.15
@@ -55,7 +55,7 @@
*/
/*
- * $Id: DTDValidator.cpp,v 1.14 2001/02/26 19:22:04 tng Exp $
+ * $Id: DTDValidator.cpp,v 1.15 2001/03/21 21:56:20 tng Exp $
*/
@@ -68,7 +68,6 @@
#include <internal/ReaderMgr.hpp>
#include <internal/XMLScanner.hpp>
#include <validators/DTD/DTDValidator.hpp>
-#include <validators/DTD/DocTypeHandler.hpp>
// ---------------------------------------------------------------------------
@@ -151,71 +150,19 @@
DTDValidator::DTDValidator(XMLErrorReporter* const errReporter) :
XMLValidator(errReporter)
- , fDocTypeHandler(0)
- , fDumAttDef(0)
- , fDumElemDecl(0)
- , fDumEntityDecl(0)
- , fElemDeclPool(0)
- , fEntityDeclPool(0)
- , fInternalSubset(false)
- , fNextAttrId(1)
- , fNotationDeclPool(0)
- , fPEntityDeclPool(0)
- , fRootElemId(XMLElementDecl::fgInvalidElemId)
-{
- //
- // Init all the pool members.
- //
- // <TBD> Investigate what the optimum values would be for the various
- // pools.
- //
- fElemDeclPool = new NameIdPool<DTDElementDecl>(109);
- fEntityDeclPool = new NameIdPool<DTDEntityDecl>(109);
- fNotationDeclPool = new NameIdPool<XMLNotationDecl>(109);
- fPEntityDeclPool = new NameIdPool<DTDEntityDecl>(109);
-
- //
- // Call our own reset method. This lets us have the pool setup stuff
- // done in just one place (because this stame setup stuff has to be
- // done every time we are reset.)
- //
+ , fDTDGrammar(0)
+{
reset();
}
DTDValidator::~DTDValidator()
{
- delete fDumAttDef;
- delete fDumElemDecl;
- delete fDumEntityDecl;
- delete fElemDeclPool;
- delete fEntityDeclPool;
- delete fNotationDeclPool;
- delete fPEntityDeclPool;
-}
-
-
-// ---------------------------------------------------------------------------
-// DTDValidator: Pool manipulation methods
-// ---------------------------------------------------------------------------
-unsigned int DTDValidator::findElemId(const XMLCh* const qName) const
-{
- // Look up this name in the element decl pool
- const DTDElementDecl* decl = fElemDeclPool->getByKey(qName);
- if (!decl)
- return XMLElementDecl::fgInvalidElemId;
- return decl->getId();
}
// ---------------------------------------------------------------------------
// DTDValidator: Implementation of the XMLValidator interface
// ---------------------------------------------------------------------------
-int DTDValidator::addOrFindNSId(const XMLCh* const uriText)
-{
- return fURIStringPool.addOrFind(uriText);
-}
-
-
int DTDValidator::checkContent( const unsigned int elemId
, const unsigned int* childIds
, const unsigned int childCount)
@@ -224,7 +171,7 @@
// Look up the element id in our element decl pool. This will get us
// the element decl in our own way of looking at them.
//
- DTDElementDecl* elemDecl = fElemDeclPool->getById(elemId);
+ DTDElementDecl* elemDecl = (DTDElementDecl*) fDTDGrammar->getElemDecl(elemId);
if (!elemDecl)
ThrowXML(RuntimeException, XMLExcepts::Val_InvalidElemId);
@@ -262,7 +209,7 @@
}
// Went ok, so return success
- return XMLValidator::Success;
+ return -1;
}
@@ -272,6 +219,7 @@
// If the root element was never set, then there was never a DOCTYPE. So
// we just return false.
//
+ unsigned int fRootElemId = fDTDGrammar->getRootElemId();
if (fRootElemId == XMLElementDecl::fgInvalidElemId)
return false;
@@ -279,7 +227,6 @@
return (elemId == fRootElemId);
}
-
void DTDValidator::faultInAttr(XMLAttr& toFill, const XMLAttDef& attDef) const
{
//
@@ -329,219 +276,14 @@
}
}
-
-const XMLElementDecl*
-DTDValidator::findElemDecl( const unsigned int uriId
- , const XMLCh* const baseName
- , const XMLCh* const prefix
- , const XMLCh* const qName
- , const LookupOpts options
- , bool& wasAdded) const
-{
- // See it it exists
- DTDElementDecl* retVal = fElemDeclPool->getByKey(qName);
-
- // If not, and they want us to add it, then fault one in
- if (!retVal && (options == XMLValidator::AddIfNotFound))
- {
- retVal = new DTDElementDecl(qName, DTDElementDecl::Any);
- const unsigned int elemId = fElemDeclPool->put(retVal);
- retVal->setId(elemId);
- wasAdded = true;
- }
- else
- {
- wasAdded = false;
- }
- return retVal;
-}
-
-
-XMLElementDecl*
-DTDValidator::findElemDecl( const unsigned int uriId
- , const XMLCh* const baseName
- , const XMLCh* const prefix
- , const XMLCh* const qName
- , const LookupOpts options
- , bool& wasAdded)
-{
- // See it it exists
- DTDElementDecl* retVal = fElemDeclPool->getByKey(qName);
-
- // If not, and they want us to add it, then fault one in
- if (!retVal && (options == XMLValidator::AddIfNotFound))
- {
- retVal = new DTDElementDecl(qName, DTDElementDecl::Any);
- const unsigned int elemId = fElemDeclPool->put(retVal);
- retVal->setId(elemId);
- wasAdded = true;
- }
- else
- {
- wasAdded = false;
- }
- return retVal;
-}
-
-
-const XMLEntityDecl*
-DTDValidator::findEntityDecl(const XMLCh* const entName
- , const bool isPE) const
-{
- if (isPE)
- return fPEntityDeclPool->getByKey(entName);
- return fEntityDeclPool->getByKey(entName);
-}
-
-
-XMLEntityDecl* DTDValidator::findEntityDecl(const XMLCh* const entName
- , const bool isPE)
-{
- if (isPE)
- return fPEntityDeclPool->getByKey(entName);
- return fEntityDeclPool->getByKey(entName);
-}
-
-
-unsigned int
-DTDValidator::findElemId(const unsigned int uriId
- , const XMLCh* const baseName
- , const XMLCh* const prefix
- , const XMLCh* const qName) const
-{
- //
- // In this case, we don't return zero to mean 'not found', so we have to
- // map it to the official not found value if we don't find it.
- //
- const DTDElementDecl* decl = fElemDeclPool->getByKey(qName);
- if (!decl)
- return XMLElementDecl::fgInvalidElemId;
- return decl->getId();
-}
-
-
-const XMLNotationDecl*
-DTDValidator::findNotationDecl(const XMLCh* const notName) const
-{
- return fNotationDeclPool->getByKey(notName);
-}
-
-
-XMLNotationDecl* DTDValidator::findNotationDecl(const XMLCh* const notName)
-{
- return fNotationDeclPool->getByKey(notName);
-}
-
-
-unsigned int DTDValidator::findNSId(const XMLCh* const uriText) const
-{
- //
- // Look up the id for this one. It returns zero if not found, which is
- // what we want to return.
- //
- return fURIStringPool.getId(uriText);
-}
-
-
-const XMLElementDecl* DTDValidator::getElemDecl(const unsigned int elemId) const
-{
- // Look up this element decl by id
- return fElemDeclPool->getById(elemId);
-}
-
-
-XMLElementDecl* DTDValidator::getElemDecl(const unsigned int elemId)
-{
- // Look up this element decl by id
- return fElemDeclPool->getById(elemId);
-}
-
-
-bool DTDValidator::getURIText( const unsigned int uriId
- , XMLBuffer& uriBufToFill) const
-{
- // Look up the URI in the string pool and return its id
- const XMLCh* value = fURIStringPool.getValueForId(uriId);
- if (!value)
- return false;
-
- uriBufToFill.set(value);
- return true;
-}
-
-const XMLCh* DTDValidator::getURIText(const unsigned int uriId) const
-{
- // Look up the URI in the string pool and return its id
- const XMLCh* value = fURIStringPool.getValueForId(uriId);
- if (!value)
- return XMLUni::fgZeroLenString;
-
- return value;
-}
-
-void DTDValidator::postParseValidation()
-{
- //
- // At this time, there is nothing to do here. The scanner itself handles
- // ID/IDREF validation, since that is the same no matter what kind of
- // validator.
- //
-}
-
-
void DTDValidator::reset()
{
- //
- // We need to reset all of the pools and a couple of the other members.
- // The other stuff is not sensitive across uses of the validator.
- //
- fElemDeclPool->removeAll();
- fEntityDeclPool->removeAll();
- fInternalSubset = false;
- fNotationDeclPool->removeAll();
- fPEntityDeclPool->removeAll();
- fURIStringPool.flushAll();
- fRootElemId = XMLElementDecl::fgInvalidElemId;
-
- // If there is a doc type handler, reset it
- if (fDocTypeHandler)
- fDocTypeHandler->resetDocType();
-
- //
- // Add some special URIs to the URI string pool. These represent special
- // URIs that are predefined and don't come from the user data. We pass
- // the ids to our base class who will store them and make them available
- // to client code.
- //
- setBaseFields
- (
- fURIStringPool.addOrFind(XMLUni::fgZeroLenString)
- , fURIStringPool.addOrFind(XMLUni::fgGlobalNSURIName)
- , fURIStringPool.addOrFind(XMLUni::fgUnknownURIName)
- , fURIStringPool.addOrFind(XMLUni::fgXMLURIName)
- , fURIStringPool.addOrFind(XMLUni::fgXMLNSURIName)
- );
-
- //
- // Add the default entity entries for the character refs that must always
- // be present. We indicate that they are from the internal subset. They
- // aren't really, but they have to look that way so that they are still
- // valid for use within a standalone document.
- //
- // We also mark them as special char entities, which allows them to be
- // used in places whether other non-numeric general entities cannot.
- //
- fEntityDeclPool->put(new DTDEntityDecl(gAmp, chAmpersand, true, true));
- fEntityDeclPool->put(new DTDEntityDecl(gLT, chOpenAngle, true, true));
- fEntityDeclPool->put(new DTDEntityDecl(gGT, chCloseAngle, true, true));
- fEntityDeclPool->put(new DTDEntityDecl(gQuot, chDoubleQuote, true, true));
- fEntityDeclPool->put(new DTDEntityDecl(gApos, chSingleQuote, true, true));
}
bool DTDValidator::requiresNamespaces() const
{
- // Namespaces are optional for DTDs
+ // Namespaces are not supported for DTDs
return false;
}
@@ -733,7 +475,7 @@
// general entity pool. If not there, then its an error. If its
// not an external unparsed entity, then its an error.
//
- const XMLEntityDecl* decl = findEntityDecl(pszTmpVal, false);
+ const XMLEntityDecl* decl = fDTDGrammar->getEntityDecl(pszTmpVal);
if (decl)
{
if (!decl->isUnparsed())
@@ -779,190 +521,183 @@
}
}
-
-// ---------------------------------------------------------------------------
-// DTDValidator: DTD handler interface.
-// ---------------------------------------------------------------------------
-void DTDValidator::scanDTD(const bool reuseValidator)
+void DTDValidator::preContentValidation(bool reuseGrammar)
{
//
- // And now call out to the DTDValidator2.cpp file to do the actual
- // scanning. When we get back, we will be through the internal and
- // external subsets.
+ // Lets enumerate all of the elements in the element decl pool
+ // and put out an error for any that did not get declared.
+ // We also check all of the attributes as well.
//
- scanDocTypeDecl(reuseValidator);
-
- // If validating, then do the pre-content validation
- if (getScanner()->getDoValidation())
+ NameIdPoolEnumerator<DTDElementDecl> elemEnum = fDTDGrammar->getElemEnumerator();
+ while (elemEnum.hasMoreElements())
{
+ const DTDElementDecl& curElem = elemEnum.nextElement();
+ const DTDElementDecl::CreateReasons reason = curElem.getCreateReason();
+
//
- // Lets enumerate all of the elements in the element decl pool
- // and put out an error for any that did not get declared.
- // We also check all of the attributes as well.
+ // See if this element decl was ever marked as declared. If
+ // not, then put out an error. In some cases its just
+ // a warning, such as being referenced in a content model.
//
- NameIdPoolEnumerator<DTDElementDecl> elemEnum(fElemDeclPool);
- while (elemEnum.hasMoreElements())
+ if (reason != XMLElementDecl::Declared)
{
- const DTDElementDecl& curElem = elemEnum.nextElement();
- const DTDElementDecl::CreateReasons reason = curElem.getCreateReason();
+ if (reason == XMLElementDecl::AttList)
+ {
+ getScanner()->emitError
+ (
+ XMLErrs::UndeclaredElemInAttList
+ , curElem.getFullName()
+ );
+ }
+ else if (reason == XMLElementDecl::AsRootElem)
+ {
+ emitError
+ (
+ XMLValid::UndeclaredElemInDocType
+ , curElem.getFullName()
+ );
+ }
+ else if (reason == XMLElementDecl::InContentModel)
+ {
+ getScanner()->emitError
+ (
+ XMLErrs::UndeclaredElemInCM
+ , curElem.getFullName()
+ );
+ }
+ else
+ {
+ #if defined(XERCES_DEBUG)
+ if(reuseGrammar && reason == XMLElementDecl::JustFaultIn){
+ }
+ else
+ ThrowXML(RuntimeException, XMLExcepts::DTD_UnknownCreateReason);
+ #endif
+ }
+ }
- //
- // See if this element decl was ever marked as declared. If
- // not, then put out an error. In some cases its just
- // a warning, such as being referenced in a content model.
- //
- if (reason != XMLElementDecl::Declared)
+ //
+ // Check all of the attributes of the current element.
+ // We check for:
+ //
+ // 1) Multiple ID attributes
+ // 2) That all of the default values of attributes are
+ // valid for their type.
+ // 3) That for any notation types, that their lists
+ // of possible values refer to declared notations.
+ //
+ XMLAttDefList& attDefList = curElem.getAttDefList();
+ bool seenId = false;
+ while (attDefList.hasMoreElements())
+ {
+ const XMLAttDef& curAttDef = attDefList.nextElement();
+
+ if (curAttDef.getType() == XMLAttDef::ID)
{
- if (reason == XMLElementDecl::AttList)
- {
- getScanner()->emitError
- (
- XMLErrs::UndeclaredElemInAttList
- , curElem.getFullName()
- );
- }
- else if (reason == XMLElementDecl::AsRootElem)
+ if (seenId)
{
emitError
- (
- XMLValid::UndeclaredElemInDocType
- , curElem.getFullName()
- );
- }
- else if (reason == XMLElementDecl::InContentModel)
- {
- getScanner()->emitError
(
- XMLErrs::UndeclaredElemInCM
+ XMLValid::MultipleIdAttrs
, curElem.getFullName()
);
+ break;
}
- else
- {
- #if defined(XERCES_DEBUG)
- if(reuseValidator && reason == XMLElementDecl::JustFaultIn){
- }
- else
- ThrowXML(RuntimeException, XMLExcepts::DTD_UnknownCreateReason);
- #endif
- }
- }
- //
- // Check all of the attributes of the current element.
- // We check for:
- //
- // 1) Multiple ID attributes
- // 2) That all of the default values of attributes are
- // valid for their type.
- // 3) That for any notation types, that their lists
- // of possible values refer to declared notations.
- //
- XMLAttDefList& attDefList = curElem.getAttDefList();
- bool seenId = false;
- while (attDefList.hasMoreElements())
+ seenId = true;
+ }
+ else if (curAttDef.getType() == XMLAttDef::Notation)
{
- const XMLAttDef& curAttDef = attDefList.nextElement();
+ //
+ // We need to verify that all of its possible values
+ // (in the enum list) refer to valid notations.
+ //
+ XMLCh* list = XMLString::replicate(curAttDef.getEnumeration());
+ ArrayJanitor<XMLCh> janList(list);
- if (curAttDef.getType() == XMLAttDef::ID)
+ //
+ // Search forward for a space or a null. If a null,
+ // we are done. If a space, cap it and look it up.
+ //
+ bool breakFlag = false;
+ XMLCh* listPtr = list;
+ XMLCh* lastPtr = listPtr;
+ while (true)
{
- if (seenId)
- {
- emitError
- (
- XMLValid::MultipleIdAttrs
- , curElem.getFullName()
- );
- break;
- }
+ while (*listPtr && (*listPtr != chSpace))
+ listPtr++;
- seenId = true;
- }
- else if (curAttDef.getType() == XMLAttDef::Notation)
- {
//
- // We need to verify that all of its possible values
- // (in the enum list) refer to valid notations.
+ // If at the end, indicate we need to break after
+ // this one. Else, cap it off here.
//
- XMLCh* list = XMLString::replicate(curAttDef.getEnumeration());
- ArrayJanitor<XMLCh> janList(list);
+ if (!*listPtr)
+ breakFlag = true;
+ else
+ *listPtr = chNull;
- //
- // Search forward for a space or a null. If a null,
- // we are done. If a space, cap it and look it up.
- //
- bool breakFlag = false;
- XMLCh* listPtr = list;
- XMLCh* lastPtr = listPtr;
- while (true)
+ if (!fDTDGrammar->getNotationDecl(lastPtr))
{
- while (*listPtr && (*listPtr != chSpace))
- listPtr++;
-
- //
- // If at the end, indicate we need to break after
- // this one. Else, cap it off here.
- //
- if (!*listPtr)
- breakFlag = true;
- else
- *listPtr = chNull;
-
- if (!fNotationDeclPool->getByKey(lastPtr))
- {
- emitError
- (
- XMLValid::UnknownNotRefAttr
- , curAttDef.getFullName()
- , lastPtr
- );
- }
-
- // Break out if we hit the end last time
- if (breakFlag)
- break;
-
- // Else move upwards and try again
- listPtr++;
- lastPtr = listPtr;
+ emitError
+ (
+ XMLValid::UnknownNotRefAttr
+ , curAttDef.getFullName()
+ , lastPtr
+ );
}
- }
- // If it has a default/fixed value, then validate it
- if (curAttDef.getValue())
- {
- validateAttrValue
- (
- curAttDef
- , curAttDef.getValue()
- );
+ // Break out if we hit the end last time
+ if (breakFlag)
+ break;
+
+ // Else move upwards and try again
+ listPtr++;
+ lastPtr = listPtr;
}
}
- }
- //
- // And enumerate all of the general entities. If any of them
- // reference a notation, then make sure the notation exists.
- //
- NameIdPoolEnumerator<DTDEntityDecl> entEnum(fEntityDeclPool);
- while (entEnum.hasMoreElements())
- {
- const DTDEntityDecl& curEntity = entEnum.nextElement();
-
- if (!curEntity.getNotationName())
- continue;
-
- // It has a notation name, so look it up
- if (!fNotationDeclPool->getByKey(curEntity.getNotationName()))
+ // If it has a default/fixed value, then validate it
+ if (curAttDef.getValue())
{
- emitError
+ validateAttrValue
(
- XMLValid::NotationNotDeclared
- , curEntity.getNotationName()
+ curAttDef
+ , curAttDef.getValue()
);
}
}
}
+
+ //
+ // And enumerate all of the general entities. If any of them
+ // reference a notation, then make sure the notation exists.
+ //
+ NameIdPoolEnumerator<DTDEntityDecl> entEnum = fDTDGrammar->getEntityEnumerator();
+ while (entEnum.hasMoreElements())
+ {
+ const DTDEntityDecl& curEntity = entEnum.nextElement();
+
+ if (!curEntity.getNotationName())
+ continue;
+
+ // It has a notation name, so look it up
+ if (!fDTDGrammar->getNotationDecl(curEntity.getNotationName()))
+ {
+ emitError
+ (
+ XMLValid::NotationNotDeclared
+ , curEntity.getNotationName()
+ );
+ }
+ }
}
+void DTDValidator::postParseValidation()
+{
+ //
+ // At this time, there is nothing to do here. The scanner itself handles
+ // ID/IDREF validation, since that is the same no matter what kind of
+ // validator.
+ //
+}
1.8 +34 -329 xml-xerces/c/src/validators/DTD/DTDValidator.hpp
Index: DTDValidator.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/validators/DTD/DTDValidator.hpp,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- DTDValidator.hpp 2001/02/26 19:22:08 1.7
+++ DTDValidator.hpp 2001/03/21 21:56:21 1.8
@@ -56,6 +56,9 @@
/*
* $Log: DTDValidator.hpp,v $
+ * Revision 1.8 2001/03/21 21:56:21 tng
+ * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+ *
* Revision 1.7 2001/02/26 19:22:08 tng
* Schema: add parameter prefix in findElem and findAttr.
*
@@ -93,15 +96,10 @@
#if !defined(DTDVALIDATOR_HPP)
#define DTDVALIDATOR_HPP
-#include <util/RefHashTableOf.hpp>
#include <util/NameIdPool.hpp>
-#include <util/StringPool.hpp>
#include <framework/XMLValidator.hpp>
-#include <validators/DTD/DTDElementDecl.hpp>
-#include <validators/DTD/DTDEntityDecl.hpp>
+#include <validators/DTD/DTDGrammar.hpp>
-class ContentSpecNode;
-class DocTypeHandler;
class XMLMsgLoader;
@@ -112,68 +110,23 @@
// DTD, and provides the standard validation services against the DTD info
// it found.
//
-// NOTE: DTDs are not namespace aware, so we just use regular NameIdPool
-// data structures to store element and attribute decls. They are all set
-// to be in the global namespace and the full QName is used as the base name
-// of the decl. This means that all the URI parameters below are expected
-// to be null pointers (and anything else will cause an exception.)
-//
class VALIDATORS_EXPORT DTDValidator : public XMLValidator
{
public:
// -----------------------------------------------------------------------
- // Class specific types
- //
- // NOTE: This should really be private, but some of the compilers we
- // have to support cannot understand that.
- //
- // EntityExpRes
- // Returned from scanEntityRef() to indicate how the expanded text
- // was treated.
- // -----------------------------------------------------------------------
- enum EntityExpRes
- {
- EntityExp_Failed
- , EntityExp_Pushed
- , EntityExp_Returned
- };
-
-
- // -----------------------------------------------------------------------
// Constructors and Destructor
// -----------------------------------------------------------------------
DTDValidator(XMLErrorReporter* const errReporter = 0);
virtual ~DTDValidator();
-
// -----------------------------------------------------------------------
- // Getter methods
- // -----------------------------------------------------------------------
- NameIdPoolEnumerator<DTDElementDecl> getElemEnumerator() const;
- NameIdPoolEnumerator<DTDEntityDecl> getEntityEnumerator() const;
- NameIdPoolEnumerator<XMLNotationDecl> getNotationEnumerator() const;
- unsigned int getRootElemId() const;
- DocTypeHandler* getDocTypeHandler();
- const DocTypeHandler* getDocTypeHandler() const;
-
-
- // -----------------------------------------------------------------------
// Setter methods
// -----------------------------------------------------------------------
- void setDocTypeHandler
- (
- DocTypeHandler* const handlerToSet
- );
-
+ void setDTDGrammar(DTDGrammar* dtdGrammar);
// -----------------------------------------------------------------------
// Implementation of the XMLValidator interface
// -----------------------------------------------------------------------
- virtual int addOrFindNSId
- (
- const XMLCh* const uriText
- );
-
virtual int checkContent
(
const unsigned int elemId
@@ -191,84 +144,9 @@
XMLAttr& toFill
, const XMLAttDef& attDef
) const;
-
- virtual const XMLElementDecl* findElemDecl
- (
- const unsigned int uriId
- , const XMLCh* const baseName
- , const XMLCh* const prefix
- , const XMLCh* const qName
- , const LookupOpts options
- , bool& wasAdded
- ) const;
- virtual XMLElementDecl* findElemDecl
- (
- const unsigned int uriId
- , const XMLCh* const baseName
- , const XMLCh* const prefix
- , const XMLCh* const qName
- , const LookupOpts options
- , bool& wasAdded
- );
+ virtual void preContentValidation(bool reuseGrammar);
- virtual const XMLEntityDecl* findEntityDecl
- (
- const XMLCh* const entName
- , const bool isPE
- ) const;
-
- virtual XMLEntityDecl* findEntityDecl
- (
- const XMLCh* const entName
- , const bool isPE
- );
-
- virtual unsigned int findElemId
- (
- const unsigned int uriId
- , const XMLCh* const baseName
- , const XMLCh* const prefix
- , const XMLCh* const qName
- ) const;
-
- virtual const XMLNotationDecl* findNotationDecl
- (
- const XMLCh* const notName
- ) const;
-
- virtual XMLNotationDecl* findNotationDecl
- (
- const XMLCh* const notName
- );
-
- virtual unsigned int findNSId
- (
- const XMLCh* const nsName
- ) const;
-
- virtual const XMLElementDecl* getElemDecl
- (
- const unsigned int elemId
- ) const;
-
- virtual XMLElementDecl* getElemDecl
- (
- const unsigned int elemId
- );
-
- virtual bool getURIText
- (
- const unsigned int uriId
- , XMLBuffer& uriBufToFill
- ) const;
-
- virtual const XMLCh* getURIText
- (
- const unsigned int uriId
- ) const;
-
-
virtual void postParseValidation();
virtual void reset();
@@ -280,239 +158,66 @@
const XMLAttDef& attDef
, const XMLCh* const attrValue
);
+ virtual Grammar* getGrammar(const XMLCh* uri=0);
+ virtual Grammar* getGrammar(const char* uri);
// -----------------------------------------------------------------------
- // DTD specific pool methods. Many of the virtual interface methods
- // above just call this one, passing along the qName (which is all that
- // we deal with in this validator.
+ // Virtual DTD handler interface.
// -----------------------------------------------------------------------
- unsigned int findElemId
- (
- const XMLCh* const qName
- ) const;
-
-
-
- // -----------------------------------------------------------------------
- // Virtual DTD handler interface. If handlesDTD() returns true, then
- // scanDocTypeDecl() will be called when a DOCTYPE is seen. The passed
- // message loader and reader manager are really internal stuff but they
- // are required to process the DTD external and internal subset.
- // -----------------------------------------------------------------------
virtual bool handlesDTD() const;
- virtual void scanDTD(const bool reuseValidator);
-
-private:
// -----------------------------------------------------------------------
- // Unimplemented constructors and operators
+ // Virtual Schema handler interface. handlesSchema() always return false.
// -----------------------------------------------------------------------
- DTDValidator(const DTDValidator&);
- void operator=(const DTDValidator&);
+ virtual bool handlesSchema() const;
-
private:
- // -----------------------------------------------------------------------
- // Private class types
- // -----------------------------------------------------------------------
- enum IDTypes
- {
- IDType_Public
- , IDType_External
- , IDType_Either
- };
-
// -----------------------------------------------------------------------
- // Private DTD scanning methods. These are all in XMLValidator2.cpp
- // -----------------------------------------------------------------------
- bool checkForPERef
- (
- const bool spaceRequired
- , const bool inLiteral
- , const bool inMarkup
- , const bool throwEndOfExt = false
- );
- bool expandPERef
- (
- const bool scanExternal
- , const bool inLiteral
- , const bool inMarkup
- , const bool throwEndOfExt = false
- );
- bool getQuotedString(XMLBuffer& toFill);
- XMLAttDef* scanAttDef(DTDElementDecl& elemDecl, XMLBuffer& bufToUse);
- bool scanAttValue
- (
- const XMLCh* const attrName
- , XMLBuffer& toFill
- , const XMLAttDef::AttTypes type
- );
- void scanAttListDecl();
- ContentSpecNode* scanChildren
- (
- const DTDElementDecl& elemDecl
- , XMLBuffer& bufToUse
- );
- bool scanCharRef(XMLCh& toFill, XMLCh& second);
- void scanComment();
- bool scanContentSpec(DTDElementDecl& toFill);
- void scanDefaultDecl(DTDAttDef& toFill);
- void scanDocTypeDecl(const bool reuseValidator);
- void scanElementDecl();
- void scanEntityDecl();
- bool scanEntityDef();
- bool scanEntityLiteral(XMLBuffer& toFill, const bool isPE);
- bool scanEntityDef(DTDEntityDecl& decl, const bool isPEDecl);
- EntityExpRes scanEntityRef(XMLCh& firstCh, XMLCh& secondCh, bool& escaped);
- bool scanEnumeration
- (
- const DTDAttDef& attDef
- , XMLBuffer& toFill
- , const bool notation
- );
- bool scanEq();
- void scanExtSubsetDecl(const bool inIncludeSect);
- bool scanId
- (
- XMLBuffer& pubIdToFill
- , XMLBuffer& sysIdToFill
- , const IDTypes whatKind
- );
- void scanIgnoredSection();
- bool scanInternalSubset();
- void scanMarkupDecl(const bool parseTextDecl);
- bool scanMixed(DTDElementDecl& toFill);
- void scanNotationDecl();
- void scanPI();
- bool scanPublicLiteral(XMLBuffer& toFill);
- bool scanSystemLiteral(XMLBuffer& toFill);
- void scanTextDecl();
-
-
- // -----------------------------------------------------------------------
// Private data members
- //
- // fDocTypeHandler
- // This holds the optional doc type handler that can be installed
- // and used to call back for all markup events. It is DTD specific.
- //
- // fDumAttDef
- // fDumElemDecl
- // fDumEntityDecl
- // These are dummy objects into which mark decls are parsed when
- // they are just overrides of previously declared markup decls. In
- // such situations, the first one wins but we need to have somewhere
- // to parse them into. So these are lazily created and used as needed
- // when such markup decls are seen.
- //
- // fElemDeclPool
- // This is the element decl pool. It contains all of the elements
- // declared in the DTD (and their associated attributes.) When in
- // non-validating mode, its just populated as new elements are seen
- // and they are given default characteristics.
- //
- // fEntityDeclPool
- // This is a pool of EntityDecl objects, which contains all of the
- // general entities that are declared in the DTD subsets.
- //
- // fInternalSubset
- // This is used to track whether we are in the internal subset or not,
- // in which case we are in the external subset.
//
- // fNextAttrId
- // Since att defs are per-element, we don't have a validator wide
- // attribute def pool. So we use a simpler data structure in each
- // element decl to store its att defs, and we use this simple counter
- // to apply a unique id to each new attribute.
+ // fDTDGrammar
+ // The DTD information stored.
//
- // fNotationDeclPool
- // This is a pool of NotationDecl objects, which contains all of the
- // notations declared in the DTD subsets.
- //
- // fPEntityDeclPool
- // This is a pool of EntityDecl objects, which contains all of the
- // parameter entities that are declared in the DTD subsets.
- //
- // fRootElemId
- // The id of the root element that we found in the DOCTYPE statement.
- // Its initialized to ContentModel::fgInvalidElemId, so that its
- // invalid unless we have a DOCTYPE.
- //
- // fURIStringPool
- // Each validator is required to maintain a pool for URIs. It has
- // to be able to assign unique ids for URIs. We use a standard string
- // pool class.
- // -----------------------------------------------------------------------
- DocTypeHandler* fDocTypeHandler;
- DTDAttDef* fDumAttDef;
- DTDElementDecl* fDumElemDecl;
- DTDEntityDecl* fDumEntityDecl;
- NameIdPool<DTDElementDecl>* fElemDeclPool;
- NameIdPool<DTDEntityDecl>* fEntityDeclPool;
- bool fInternalSubset;
- unsigned int fNextAttrId;
- NameIdPool<XMLNotationDecl>* fNotationDeclPool;
- NameIdPool<DTDEntityDecl>* fPEntityDeclPool;
- unsigned int fRootElemId;
- XMLStringPool fURIStringPool;
+ // -----------------------------------------------------------------------
+ DTDGrammar* fDTDGrammar;
};
+// -----------------------------------------------------------------------
+// Setter methods
+// -----------------------------------------------------------------------
+inline void DTDValidator::setDTDGrammar(DTDGrammar* dtdGrammar) {
+ fDTDGrammar = dtdGrammar;
+}
// ---------------------------------------------------------------------------
-// DTDValidator: Getter methods
+// Virtual interface
// ---------------------------------------------------------------------------
-inline NameIdPoolEnumerator<DTDElementDecl>
-DTDValidator::getElemEnumerator() const
-{
- return NameIdPoolEnumerator<DTDElementDecl>(fElemDeclPool);
+inline Grammar* DTDValidator::getGrammar(const XMLCh* uri) {
+ return fDTDGrammar;
}
-inline NameIdPoolEnumerator<DTDEntityDecl>
-DTDValidator::getEntityEnumerator() const
-{
- return NameIdPoolEnumerator<DTDEntityDecl>(fEntityDeclPool);
+inline Grammar* DTDValidator::getGrammar(const char* uri) {
+ return fDTDGrammar;
}
-inline NameIdPoolEnumerator<XMLNotationDecl>
-DTDValidator::getNotationEnumerator() const
-{
- return NameIdPoolEnumerator<XMLNotationDecl>(fNotationDeclPool);
-}
-
-inline unsigned int DTDValidator::getRootElemId() const
-{
- return fRootElemId;
-}
-
-inline DocTypeHandler* DTDValidator::getDocTypeHandler()
-{
- return fDocTypeHandler;
-}
-
-inline const DocTypeHandler* DTDValidator::getDocTypeHandler() const
-{
- return fDocTypeHandler;
-}
-
-
// ---------------------------------------------------------------------------
-// DTDValidator: Setter methods
+// DTDValidator: DTD handler interface
// ---------------------------------------------------------------------------
-inline void DTDValidator::setDocTypeHandler(DocTypeHandler* const handlerToSet)
+inline bool DTDValidator::handlesDTD() const
{
- fDocTypeHandler = handlerToSet;
+ // We definitely want to handle DTD scanning
+ return true;
}
-
// ---------------------------------------------------------------------------
-// DTDValidator: DTD handler interface
+// DTDValidator: Schema handler interface
// ---------------------------------------------------------------------------
-inline bool DTDValidator::handlesDTD() const
+inline bool DTDValidator::handlesSchema() const
{
- // We definitely want to handle DTD scanning
- return true;
+ // No Schema scanning
+ return false;
}
#endif
1.8 +9 -2 xml-xerces/c/src/validators/DTD/Makefile.in
Index: Makefile.in
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/validators/DTD/Makefile.in,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- Makefile.in 2001/02/16 14:58:56 1.7
+++ Makefile.in 2001/03/21 21:56:22 1.8
@@ -55,6 +55,9 @@
#
#
# $Log: Makefile.in,v $
+# Revision 1.8 2001/03/21 21:56:22 tng
+# Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+#
# Revision 1.7 2001/02/16 14:58:56 tng
# Schema: Update Makefile, configure files, project files, and include path in
# certain cpp files because of the move of the common Content Model files. By Pei Yong Zhang.
@@ -112,6 +115,8 @@
DTDAttDefList.hpp \
DTDElementDecl.hpp \
DTDEntityDecl.hpp \
+ DTDGrammar.hpp \
+ DTDScanner.hpp \
DTDValidator.hpp \
DocTypeHandler.hpp
@@ -123,8 +128,9 @@
DTDAttDef.$(TO) \
DTDAttDefList.$(TO) \
DTDElementDecl.$(TO) \
- DTDValidator.$(TO) \
- DTDValidator2.$(TO)
+ DTDGrammar.$(TO) \
+ DTDScanner.$(TO) \
+ DTDValidator.$(TO)
all:: includes $(VALIDATORS_DTD_CPP_OBJECTS)
1.1 xml-xerces/c/src/validators/DTD/DTDGrammar.cpp
Index: DTDGrammar.cpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Log: DTDGrammar.cpp,v $
* Revision 1.1 2001/03/21 21:56:20 tng
* Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
*
*/
// ---------------------------------------------------------------------------
// Includes
// ---------------------------------------------------------------------------
#include <util/XMLUniDefs.hpp>
#include <util/XMLUni.hpp>
#include <validators/DTD/DTDGrammar.hpp>
//---------------------------------------------------------------------------
// DTDGrammar: Constructors and Destructor
// ---------------------------------------------------------------------------
DTDGrammar::DTDGrammar(NameIdPool<DTDEntityDecl>* entityDeclPool) :
fElemDeclPool(0)
, fEntityDeclPool(entityDeclPool)
, fNotationDeclPool(0)
{
//
// Init all the pool members.
//
// <TBD> Investigate what the optimum values would be for the various
// pools.
//
fElemDeclPool = new NameIdPool<DTDElementDecl>(109);
fNotationDeclPool = new NameIdPool<XMLNotationDecl>(109);
//
// Call our own reset method. This lets us have the pool setup stuff
// done in just one place (because this stame setup stuff has to be
// done every time we are reset.)
//
reset();
}
DTDGrammar::~DTDGrammar()
{
delete fElemDeclPool;
delete fNotationDeclPool;
}
// -----------------------------------------------------------------------
// Virtual methods
// -----------------------------------------------------------------------
XMLElementDecl* DTDGrammar::findOrAddElemDecl (const unsigned int uriId
, const XMLCh* const baseName
, const XMLCh* const prefixName
, const XMLCh* const qName
, unsigned int scope
, bool& wasAdded )
{
// See it it exists
DTDElementDecl* retVal = fElemDeclPool->getByKey(qName);
// if not, then add this in
if (!retVal)
{
retVal = new DTDElementDecl(qName, DTDElementDecl::Any);
const unsigned int elemId = fElemDeclPool->put(retVal);
retVal->setId(elemId);
wasAdded = true;
}
else
{
wasAdded = false;
}
return retVal;
}
void DTDGrammar::reset()
{
//
// We need to reset all of the pools.
//
fElemDeclPool->removeAll();
fNotationDeclPool->removeAll();
}
1.1 xml-xerces/c/src/validators/DTD/DTDGrammar.hpp
Index: DTDGrammar.hpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Log: DTDGrammar.hpp,v $
* Revision 1.1 2001/03/21 21:56:20 tng
* Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
*
*/
#if !defined(DTDGRAMMAR_HPP)
#define DTDGRAMMAR_HPP
#include <util/RefHashTableOf.hpp>
#include <util/NameIdPool.hpp>
#include <util/StringPool.hpp>
#include <validators/common/Grammar.hpp>
#include <validators/DTD/DTDElementDecl.hpp>
#include <validators/DTD/DTDEntityDecl.hpp>
//
// This class stores the DTD information
// NOTE: DTDs are not namespace aware, so we just use regular NameIdPool
// data structures to store element and attribute decls. They are all set
// to be in the global namespace and the full QName is used as the base name
// of the decl. This means that all the URI parameters below are expected
// to be null pointers (and anything else will cause an exception.)
//
class VALIDATORS_EXPORT DTDGrammar : public Grammar
{
public:
// -----------------------------------------------------------------------
// Constructors and Destructor
// -----------------------------------------------------------------------
DTDGrammar(NameIdPool<DTDEntityDecl>* entityDeclPool);
virtual ~DTDGrammar();
// -----------------------------------------------------------------------
// Implementation of Virtual Interface
// -----------------------------------------------------------------------
virtual Grammar::GrammarType getGrammarType();
virtual XMLElementDecl* findOrAddElemDecl
(
const unsigned int uriId
, const XMLCh* const baseName
, const XMLCh* const prefixName
, const XMLCh* const qName
, unsigned int scope
, bool& wasAdded
) ;
virtual unsigned int getElemId
(
const unsigned int uriId
, const XMLCh* const baseName
, const XMLCh* const qName
, unsigned int scope
) const ;
virtual const XMLElementDecl* getElemDecl
(
const unsigned int uriId
, const XMLCh* const baseName
, const XMLCh* const qName
, unsigned int scope
) const ;
virtual XMLElementDecl* getElemDecl
(
const unsigned int uriId
, const XMLCh* const baseName
, const XMLCh* const qName
, unsigned int scope
);
virtual const XMLElementDecl* getElemDecl
(
const unsigned int elemId
) const;
virtual XMLElementDecl* getElemDecl
(
const unsigned int elemId
);
virtual const XMLEntityDecl* getEntityDecl
(
const XMLCh* const entName
) const;
virtual XMLEntityDecl* getEntityDecl
(
const XMLCh* const entName
);
virtual const XMLNotationDecl* getNotationDecl
(
const XMLCh* const notName
) const;
virtual XMLNotationDecl* getNotationDecl
(
const XMLCh* const notName
);
virtual unsigned int putElemDecl
(
XMLElementDecl* const elemDecl
) const;
virtual unsigned int putEntityDecl
(
XMLEntityDecl* const entityDecl
) const;
virtual unsigned int putNotationDecl
(
XMLNotationDecl* const notationDecl
) const;
virtual void reset();
// -----------------------------------------------------------------------
// Getter methods
// -----------------------------------------------------------------------
unsigned int getRootElemId();
NameIdPoolEnumerator<DTDElementDecl> getElemEnumerator() const;
NameIdPoolEnumerator<DTDEntityDecl> getEntityEnumerator() const;
NameIdPoolEnumerator<XMLNotationDecl> getNotationEnumerator() const;
// -----------------------------------------------------------------------
// Setter methods
// -----------------------------------------------------------------------
void setRootElemId(unsigned int rootElemId);
private:
// -----------------------------------------------------------------------
// Private data members
//
// fElemDeclPool
// This is the element decl pool. It contains all of the elements
// declared in the DTD (and their associated attributes.) When in
// non-validating mode, its just populated as new elements are seen
// and they are given default characteristics.
//
// fEntityDeclPool
// This is a pool of EntityDecl objects, which contains all of the
// general entities that are declared in the DTD subsets. It is
// owned by the Scanner as Schema Grammar may also need access to
// this pool for entity reference.
//
// fNotationDeclPool
// This is a pool of NotationDecl objects, which contains all of the
// notations declared in the DTD subsets.
//
// fRootElemId
// The id of the root element that we found in the DOCTYPE statement.
// Its initialized to ContentModel::fgInvalidElemId, so that its
// invalid unless we have a DOCTYPE.
// -----------------------------------------------------------------------
NameIdPool<DTDElementDecl>* fElemDeclPool;
NameIdPool<DTDEntityDecl>* fEntityDeclPool;
NameIdPool<XMLNotationDecl>* fNotationDeclPool;
unsigned int fRootElemId;
};
// ---------------------------------------------------------------------------
// DTDGrammar: Getter methods
// ---------------------------------------------------------------------------
inline unsigned int DTDGrammar::getRootElemId()
{
return fRootElemId;
}
// ---------------------------------------------------------------------------
// DTDGrammar: Getter methods
// ---------------------------------------------------------------------------
inline NameIdPoolEnumerator<DTDElementDecl>
DTDGrammar::getElemEnumerator() const
{
return NameIdPoolEnumerator<DTDElementDecl>(fElemDeclPool);
}
inline NameIdPoolEnumerator<DTDEntityDecl>
DTDGrammar::getEntityEnumerator() const
{
return NameIdPoolEnumerator<DTDEntityDecl>(fEntityDeclPool);
}
inline NameIdPoolEnumerator<XMLNotationDecl>
DTDGrammar::getNotationEnumerator() const
{
return NameIdPoolEnumerator<XMLNotationDecl>(fNotationDeclPool);
}
// -----------------------------------------------------------------------
// Setter methods
// -----------------------------------------------------------------------
inline void DTDGrammar::setRootElemId(unsigned int rootElemId) {
fRootElemId = rootElemId;
}
// ---------------------------------------------------------------------------
// DTDGrammar: Virtual methods
// ---------------------------------------------------------------------------
inline Grammar::GrammarType DTDGrammar::getGrammarType() {
return Grammar::DTDGrammarType;
}
// Element Decl
inline unsigned int DTDGrammar::getElemId (const unsigned int uriId
, const XMLCh* const baseName
, const XMLCh* const qName
, unsigned int scope ) const
{
//
// In this case, we don't return zero to mean 'not found', so we have to
// map it to the official not found value if we don't find it.
//
const DTDElementDecl* decl = fElemDeclPool->getByKey(qName);
if (!decl)
return XMLElementDecl::fgInvalidElemId;
return decl->getId();
}
inline const XMLElementDecl* DTDGrammar::getElemDecl( const unsigned int uriId
, const XMLCh* const baseName
, const XMLCh* const qName
, unsigned int scope ) const
{
return fElemDeclPool->getByKey(qName);
}
inline XMLElementDecl* DTDGrammar::getElemDecl (const unsigned int uriId
, const XMLCh* const baseName
, const XMLCh* const qName
, unsigned int scope )
{
return fElemDeclPool->getByKey(qName);
}
inline const XMLElementDecl* DTDGrammar::getElemDecl(const unsigned int elemId) const
{
// Look up this element decl by id
return fElemDeclPool->getById(elemId);
}
inline XMLElementDecl* DTDGrammar::getElemDecl(const unsigned int elemId)
{
// Look up this element decl by id
return fElemDeclPool->getById(elemId);
}
inline unsigned int DTDGrammar::putElemDecl (XMLElementDecl* const elemDecl) const
{
return fElemDeclPool->put((DTDElementDecl*) elemDecl);
}
// Entity Decl
inline const XMLEntityDecl* DTDGrammar::getEntityDecl(const XMLCh* const entName) const
{
return fEntityDeclPool->getByKey(entName);
}
inline XMLEntityDecl* DTDGrammar::getEntityDecl(const XMLCh* const entName)
{
return fEntityDeclPool->getByKey(entName);
}
inline unsigned int DTDGrammar::putEntityDecl (XMLEntityDecl* const entityDecl) const
{
return fEntityDeclPool->put((DTDEntityDecl*) entityDecl);
}
// Notation Decl
inline const XMLNotationDecl* DTDGrammar::getNotationDecl(const XMLCh* const notName) const
{
return fNotationDeclPool->getByKey(notName);
}
inline XMLNotationDecl* DTDGrammar::getNotationDecl(const XMLCh* const notName)
{
return fNotationDeclPool->getByKey(notName);
}
inline unsigned int DTDGrammar::putNotationDecl(XMLNotationDecl* const notationDecl) const
{
return fNotationDeclPool->put(notationDecl);
}
#endif
1.1 xml-xerces/c/src/validators/DTD/DTDScanner.cpp
Index: DTDScanner.cpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Log: DTDScanner.cpp,v $
* Revision 1.1 2001/03/21 21:56:20 tng
* Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
*
*/
// ---------------------------------------------------------------------------
// Includes
// ---------------------------------------------------------------------------
#include <util/BinMemInputStream.hpp>
#include <util/FlagJanitor.hpp>
#include <util/Janitor.hpp>
#include <util/XMLUniDefs.hpp>
#include <util/UnexpectedEOFException.hpp>
#include <sax/InputSource.hpp>
#include <framework/XMLDocumentHandler.hpp>
#include <framework/XMLEntityHandler.hpp>
#include <internal/EndOfEntityException.hpp>
#include <internal/XMLScanner.hpp>
#include <validators/common/ContentSpecNode.hpp>
#include <validators/common/MixedContentModel.hpp>
#include <validators/DTD/DTDEntityDecl.hpp>
#include <validators/DTD/DocTypeHandler.hpp>
#include <validators/DTD/DTDScanner.hpp>
// ---------------------------------------------------------------------------
// Local methods
// ---------------------------------------------------------------------------
//
// This method automates the grunt work of looking at a char and see if its
// a repetition suffix. If so, it creates a new correct rep node and wraps
// the pass node in it. Otherwise, it returns the previous node.
//
static ContentSpecNode*
makeRepNode(const XMLCh testCh, ContentSpecNode* const prevNode)
{
if (testCh == chQuestion)
{
return new ContentSpecNode
(
ContentSpecNode::ZeroOrOne
, prevNode
, 0
);
}
else if (testCh == chPlus)
{
return new ContentSpecNode
(
ContentSpecNode::OneOrMore
, prevNode
, 0
);
}
else if (testCh == chAsterisk)
{
return new ContentSpecNode
(
ContentSpecNode::ZeroOrMore
, prevNode
, 0
);
}
// Just return the incoming node
return prevNode;
}
// ---------------------------------------------------------------------------
// DTDValidator: Constructors and Destructor
// ---------------------------------------------------------------------------
DTDScanner::DTDScanner(DTDGrammar* dtdGrammar, DocTypeHandler* const docTypeHandler) :
fDocTypeHandler(docTypeHandler)
, fDumAttDef(0)
, fDumElemDecl(0)
, fDumEntityDecl(0)
, fInternalSubset(false)
, fNextAttrId(1)
, fDTDGrammar(dtdGrammar)
, fPEntityDeclPool(0)
{
fPEntityDeclPool = new NameIdPool<DTDEntityDecl>(109);
}
DTDScanner::~DTDScanner()
{
delete fDumAttDef;
delete fDumElemDecl;
delete fDumEntityDecl;
delete fPEntityDeclPool;
}
// ---------------------------------------------------------------------------
// DTDScanner: Private scanning methods
// ---------------------------------------------------------------------------
bool DTDScanner::checkForPERef(const bool spaceRequired
, const bool inLiteral
, const bool inMarkup
, const bool throwAtEndExt)
{
bool gotSpace = false;
//
// See if we have any spaces up front. If so, then skip them and set
// the gotSpaces flag.
//
if (fReaderMgr->skippedSpace())
{
fReaderMgr->skipPastSpaces();
gotSpace = true;
}
// If the next char is a percent, then expand the PERef
if (!fReaderMgr->skippedChar(chPercent))
return gotSpace;
while (true)
{
if (!expandPERef(false, inLiteral, inMarkup, throwAtEndExt))
fScanner->emitError(XMLErrs::ExpectedEntityRefName);
// And skip any more spaces in the expanded value
if (fReaderMgr->skippedSpace())
{
fReaderMgr->skipPastSpaces();
gotSpace = true;
}
if (!fReaderMgr->skippedChar(chPercent))
break;
}
return gotSpace;
}
bool DTDScanner::expandPERef( const bool scanExternal
, const bool inLiteral
, const bool inMarkup
, const bool throwEndOfExt)
{
XMLBufBid bbName(fBufMgr);
//
// If we are in the internal subset and in markup, then this is
// an error but we go ahead and do it anyway.
//
if (fInternalSubset && inMarkup)
fScanner->emitError(XMLErrs::PERefInMarkupInIntSubset);
if (!fReaderMgr->getName(bbName.getBuffer()))
{
fScanner->emitError(XMLErrs::ExpectedPEName);
// Skip the semicolon if that's what we ended up on
fReaderMgr->skippedChar(chSemiColon);
return false;
}
// If no terminating semicolon, emit an error but try to keep going
if (!fReaderMgr->skippedChar(chSemiColon))
fScanner->emitError(XMLErrs::UnterminatedEntityRef, bbName.getRawBuffer());
//
// Look it up in the PE decl pool and see if it exists. If not, just
// emit an error and continue.
//
XMLEntityDecl* decl = fPEntityDeclPool->getByKey(bbName.getRawBuffer());
if (!decl)
{
fScanner->emitError(XMLErrs::EntityNotFound, bbName.getRawBuffer());
return false;
}
//
// If we are a standalone document, then it has to have been declared
// in the internal subset. Keep going though.
//
if (fScanner->getStandalone() && !decl->getDeclaredInIntSubset())
fScanner->emitError(XMLErrs::IllegalRefInStandalone, bbName.getRawBuffer());
//
// Okee dokee, we found it. So create either a memory stream with
// the entity value contents, or a file stream if its an external
// entity.
//
if (decl->isExternal())
{
// And now create a reader to read this entity
InputSource* srcUsed;
XMLReader* reader = fReaderMgr->createReader
(
decl->getSystemId()
, decl->getPublicId()
, false
, inLiteral ? XMLReader::RefFrom_Literal : XMLReader::RefFrom_NonLiteral
, XMLReader::Type_PE
, XMLReader::Source_External
, srcUsed
);
// Put a janitor on the source so its cleaned up on exit
Janitor<InputSource> janSrc(srcUsed);
// If the creation failed then throw an exception
if (!reader)
ThrowXML1(RuntimeException, XMLExcepts::Gen_CouldNotOpenExtEntity, srcUsed->getSystemId());
// Set the 'throw at end' flag, to the one we were given
reader->setThrowAtEnd(throwEndOfExt);
//
// Push the reader. If its a recursive expansion, then emit an error
// and return an failure.
//
if (!fReaderMgr->pushReader(reader, decl))
{
fScanner->emitError(XMLErrs::RecursiveEntity, decl->getName());
return false;
}
//
// If the caller wants us to scan the external entity, then lets
// do that now.
//
if (scanExternal)
{
XMLEntityHandler* entHandler = fScanner->getEntityHandler();
// If we have an entity handler, tell it we are starting this entity
if (entHandler)
entHandler->startInputSource(*srcUsed);
//
// Scan the external entity now. The parameter tells it that
// it is not in an include section. Get the current reader
// level so we can catch partial markup errors and be sure
// to get back to here if we get an exception out of the
// ext subset scan.
//
const unsigned int readerNum = fReaderMgr->getCurrentReaderNum();
try
{
scanExtSubsetDecl(false);
}
catch(...)
{
// Pop the reader back to the original level
fReaderMgr->cleanStackBackTo(readerNum);
// End the input source, even though its not happy
if (entHandler)
entHandler->endInputSource(*srcUsed);
throw;
}
// If we have an entity handler, tell it we are ending this entity
if (entHandler)
entHandler->endInputSource(*srcUsed);
}
}
else
{
// Create a reader over a memory stream over the entity value
XMLReader* valueReader = fReaderMgr->createIntEntReader
(
decl->getName()
, inLiteral ? XMLReader::RefFrom_Literal : XMLReader::RefFrom_NonLiteral
, XMLReader::Type_PE
, decl->getValue()
, decl->getValueLen()
, false
);
//
// Trt to push the entity reader onto the reader manager stack,
// where it will become the subsequent input. If it fails, that
// means the entity is recursive, so issue an error. The reader
// will have just been discarded, but we just keep going.
//
if (!fReaderMgr->pushReader(valueReader, decl))
fScanner->emitError(XMLErrs::RecursiveEntity, decl->getName());
}
return true;
}
bool DTDScanner::getQuotedString(XMLBuffer& toFill)
{
// Reset the target buffer
toFill.reset();
// Get the next char which must be a single or double quote
XMLCh quoteCh;
if (!fReaderMgr->skipIfQuote(quoteCh))
return false;
while (true)
{
// Get another char
const XMLCh nextCh = fReaderMgr->getNextChar();
// See if it matches the starting quote char
if (nextCh == quoteCh)
break;
//
// We should never get either an end of file null char here. If we
// do, just fail. It will be handled more gracefully in the higher
// level code that called us.
//
if (!nextCh)
return false;
// Else add it to the buffer
toFill.append(nextCh);
}
return true;
}
XMLAttDef*
DTDScanner::scanAttDef(DTDElementDecl& parentElem, XMLBuffer& bufToUse)
{
// Check for PE ref or optional whitespace
checkForPERef(false, false, true);
// Get the name of the attribute
if (!fReaderMgr->getName(bufToUse))
{
fScanner->emitError(XMLErrs::ExpectedAttrName);
return 0;
}
//
// Look up this attribute in the parent element's attribute list. If
// it already exists, then use the dummy.
//
DTDAttDef* decl = parentElem.getAttDef(bufToUse.getRawBuffer());
if (decl)
{
// It already exists, so put out a warning
fScanner->emitError
(
XMLErrs::AttListAlreadyExists
, bufToUse.getRawBuffer()
, parentElem.getFullName()
);
// Use the dummy decl to parse into and set its name to the name we got
if (!fDumAttDef)
{
fDumAttDef = new DTDAttDef;
fDumAttDef->setId(fNextAttrId++);
}
fDumAttDef->setName(bufToUse.getRawBuffer());
decl = fDumAttDef;
}
else
{
//
// It does not already exist so create a new one, give it the next
// available unique id, and add it
//
decl = new DTDAttDef(bufToUse.getRawBuffer());
decl->setId(fNextAttrId++);
parentElem.addAttDef(decl);
}
// Set a flag to indicate whether we are doing a dummy parse
const bool isIgnored = (decl == fDumAttDef);
// Space is required here, so check for PE ref, and require space
if (!checkForPERef(true, false, true))
fScanner->emitError(XMLErrs::ExpectedWhitespace);
//
// Next has to be one of the attribute type strings. This tells us what
// is to follow.
//
if (fReaderMgr->skippedString(XMLUni::fgCDATAString))
{
decl->setType(XMLAttDef::CData);
}
else if (fReaderMgr->skippedString(XMLUni::fgIDString))
{
if (!fReaderMgr->skippedString(XMLUni::fgRefString))
decl->setType(XMLAttDef::ID);
else if (!fReaderMgr->skippedChar(chLatin_S))
decl->setType(XMLAttDef::IDRef);
else
decl->setType(XMLAttDef::IDRefs);
}
else if (fReaderMgr->skippedString(XMLUni::fgEntitString))
{
if (fReaderMgr->skippedChar(chLatin_Y))
{
decl->setType(XMLAttDef::Entity);
}
else if (fReaderMgr->skippedString(XMLUni::fgIESString))
{
decl->setType(XMLAttDef::Entities);
}
else
{
fScanner->emitError
(
XMLErrs::ExpectedAttributeType
, decl->getFullName()
, parentElem.getFullName()
);
return 0;
}
}
else if (fReaderMgr->skippedString(XMLUni::fgNmTokenString))
{
if (fReaderMgr->skippedChar(chLatin_S))
decl->setType(XMLAttDef::NmTokens);
else
decl->setType(XMLAttDef::NmToken);
}
else if (fReaderMgr->skippedString(XMLUni::fgNotationString))
{
// Check for PE ref and require space
if (!checkForPERef(true, false, true))
fScanner->emitError(XMLErrs::ExpectedWhitespace);
decl->setType(XMLAttDef::Notation);
if (!scanEnumeration(*decl, bufToUse, true))
return 0;
// Set the value as the enumeration for this decl
decl->setEnumeration(bufToUse.getRawBuffer());
}
else if (fReaderMgr->skippedChar(chOpenParen))
{
decl->setType(XMLAttDef::Enumeration);
if (!scanEnumeration(*decl, bufToUse, false))
return 0;
// Set the value as the enumeration for this decl
decl->setEnumeration(bufToUse.getRawBuffer());
}
else
{
fScanner->emitError
(
XMLErrs::ExpectedAttributeType
, decl->getFullName()
, parentElem.getFullName()
);
return 0;
}
// Space is required here, so check for PE ref, and require space
if (!checkForPERef(true, false, true))
fScanner->emitError(XMLErrs::ExpectedWhitespace);
// And then scan for the optional default value declaration
scanDefaultDecl(*decl);
// If validating, then do a couple of validation constraints
if (fScanner->getDoValidation())
{
if (decl->getType() == XMLAttDef::ID)
{
if ((decl->getDefaultType() != XMLAttDef::Implied)
&& (decl->getDefaultType() != XMLAttDef::Required))
{
fScanner->getValidator()->emitError(XMLValid::BadIDAttrDefType, decl->getFullName());
}
}
}
// If we have a doc type handler, tell it about this attdef.
if (fDocTypeHandler)
fDocTypeHandler->attDef(parentElem, *decl, isIgnored);
return decl;
}
void DTDScanner::scanAttListDecl()
{
// Space is required here, so check for a PE ref
if (!checkForPERef(true, false, true))
{
fScanner->emitError(XMLErrs::ExpectedWhitespace);
fReaderMgr->skipPastChar(chCloseAngle);
return;
}
//
// Next should be the name of the element it belongs to, so get a buffer
// and get the name into it.
//
XMLBufBid bbName(fBufMgr);
if (!fReaderMgr->getName(bbName.getBuffer()))
{
fScanner->emitError(XMLErrs::ExpectedElementName);
fReaderMgr->skipPastChar(chCloseAngle);
return;
}
//
// Find this element's declaration. If it has not been declared yet,
// we will force one into the list, but not mark it as declared.
//
DTDElementDecl* elemDecl = (DTDElementDecl*) fDTDGrammar->getElemDecl(0, 0, bbName.getRawBuffer(), 0);
if (!elemDecl)
{
//
// Lets fault in a declaration and add it to the pool. We mark
// it having been created because of an attlist. Later, if its
// declared, this will be updated.
//
elemDecl = new DTDElementDecl(bbName.getRawBuffer());
elemDecl->setCreateReason(XMLElementDecl::AttList);
fDTDGrammar->putElemDecl((XMLElementDecl*) elemDecl);
}
// If we have a doc type handler, tell it the att list is starting
if (fDocTypeHandler)
fDocTypeHandler->startAttList(*elemDecl);
//
// Now we loop until we are done with all of the attributes in this
// list. We need a buffer to use for local processing.
//
XMLBufBid bbTmp(fBufMgr);
XMLBuffer& tmpBuf = bbTmp.getBuffer();
bool seenAnId = false;
while (true)
{
// Get the next char out and see what it tells us to do
const XMLCh nextCh = fReaderMgr->peekNextChar();
// Watch for EOF
if (!nextCh)
ThrowXML(UnexpectedEOFException, XMLExcepts::Gen_UnexpectedEOF);
if (nextCh == chCloseAngle)
{
// We are done with this attribute list
fReaderMgr->getNextChar();
break;
}
else if (XMLReader::isWhitespace(nextCh))
{
//
// If advanced callbacks are enabled and we have a doc
// type handler, then gather up the white space and call
// back on the doctype handler. Otherwise, just skip
// whitespace.
//
if (fDocTypeHandler)
{
fReaderMgr->getSpaces(tmpBuf);
fDocTypeHandler->doctypeWhitespace
(
tmpBuf.getRawBuffer()
, tmpBuf.getLen()
);
}
else
{
fReaderMgr->skipPastSpaces();
}
}
else if (nextCh == chPercent)
{
// Eat the percent and expand the ref
fReaderMgr->getNextChar();
expandPERef(false, false, true);
}
else
{
//
// It must be an attribute name, so scan it. We let
// it use our local buffer for its name scanning.
//
XMLAttDef* attDef = scanAttDef(*elemDecl, tmpBuf);
if (!attDef)
{
fReaderMgr->skipPastChar(chCloseAngle);
break;
}
//
// If we are validating and its an ID type, then we have to
// make sure that we have not seen an id attribute yet. Set
// the flag to say that we've seen one now also.
//
if (attDef->getType() == XMLAttDef::ID)
{
if (seenAnId)
fScanner->getValidator()->emitError(XMLValid::MultipleIdAttrs, elemDecl->getFullName());
seenAnId = true;
}
}
}
// If we have a doc type handler, tell it the att list is ending
if (fDocTypeHandler)
fDocTypeHandler->endAttList(*elemDecl);
}
//
// This method is called to scan the value of an attribute in content. This
// involves some normalization and replacement of general entity and
// character references.
//
// End of entity's must be dealt with here. During DTD scan, they can come
// from external entities. During content, they can come from any entity.
// We just eat the end of entity and continue with our scan until we come
// to the closing quote. If an unterminated value causes us to go through
// subsequent entities, that will cause errors back in the calling code,
// but there's little we can do about it here.
//
bool DTDScanner::scanAttValue(const XMLCh* const attrName
, XMLBuffer& toFill
, const XMLAttDef::AttTypes type)
{
enum States
{
InWhitespace
, InContent
};
// Reset the target buffer
toFill.reset();
// Get the next char which must be a single or double quote
XMLCh quoteCh;
if (!fReaderMgr->skipIfQuote(quoteCh))
return false;
//
// We have to get the current reader because we have to ignore closing
// quotes until we hit the same reader again.
//
const unsigned int curReader = fReaderMgr->getCurrentReaderNum();
//
// Loop until we get the attribute value. Note that we use a double
// loop here to avoid the setup/teardown overhead of the exception
// handler on every round.
//
XMLCh nextCh;
XMLCh secondCh = 0;
States curState = InContent;
bool firstNonWS = false;
bool gotLeadingSurrogate = false;
bool escaped;
while (true)
{
try
{
while(true)
{
// Get another char. Use second char from prevous is its there
if (secondCh)
{
nextCh = secondCh;
secondCh = 0;
}
else
{
nextCh = fReaderMgr->getNextChar();
}
if (!nextCh)
ThrowXML(UnexpectedEOFException, XMLExcepts::Gen_UnexpectedEOF);
// Check for our ending quote in the same entity
if (nextCh == quoteCh)
{
if (curReader == fReaderMgr->getCurrentReaderNum())
return true;
// Watch for spillover into a previous entity
if (curReader > fReaderMgr->getCurrentReaderNum())
{
fScanner->emitError(XMLErrs::PartialMarkupInEntity);
return false;
}
}
//
// Check for an entity ref now, before we let it affect our
// whitespace normalization logic below. We ignore the empty flag
// in this one.
//
escaped = false;
if (nextCh == chAmpersand)
{
if (scanEntityRef(nextCh, secondCh, escaped) != EntityExp_Returned)
{
gotLeadingSurrogate = false;
continue;
}
}
// Check for correct surrogate pairs
if ((nextCh >= 0xD800) && (nextCh <= 0xDBFF))
{
if (gotLeadingSurrogate)
fScanner->emitError(XMLErrs::Expected2ndSurrogateChar);
else
gotLeadingSurrogate = true;
}
else
{
if (gotLeadingSurrogate)
{
if ((nextCh < 0xDC00) && (nextCh > 0xDFFF))
fScanner->emitError(XMLErrs::Expected2ndSurrogateChar);
}
gotLeadingSurrogate = false;
// Its got to at least be a valid XML character
if (!XMLReader::isXMLChar(nextCh))
{
XMLCh tmpBuf[9];
XMLString::binToText
(
nextCh
, tmpBuf
, 8
, 16
);
fScanner->emitError
(
XMLErrs::InvalidCharacter
, attrName
, tmpBuf
);
}
}
//
// If its not escaped, then make sure its not a < character, which
// is not allowed in attribute values.
//
if (!escaped && (nextCh == chOpenAngle))
fScanner->emitError(XMLErrs::BracketInAttrValue, attrName);
//
// If the attribute is a CDATA type we do simple replacement of
// tabs and new lines with spaces, if the character is not escaped
// by way of a char ref.
//
// Otherwise, we do the standard non-CDATA normalization of
// compressing whitespace to single spaces and getting rid of
// leading and trailing whitespace.
//
if (type == XMLAttDef::CData)
{
if (!escaped)
{
if ((nextCh == 0x09) || (nextCh == 0x0A) || (nextCh == 0x0D))
nextCh = chSpace;
}
}
else
{
if (curState == InWhitespace)
{
if (!XMLReader::isWhitespace(nextCh))
{
if (firstNonWS)
toFill.append(chSpace);
curState = InContent;
firstNonWS = true;
}
else
{
continue;
}
}
else if (curState == InContent)
{
if (XMLReader::isWhitespace(nextCh))
{
curState = InWhitespace;
continue;
}
firstNonWS = true;
}
}
// Else add it to the buffer
toFill.append(nextCh);
}
}
catch(const EndOfEntityException&)
{
// Just eat it and continue.
gotLeadingSurrogate = false;
escaped = false;
}
}
return true;
}
bool DTDScanner::scanCharRef(XMLCh& first, XMLCh& second)
{
bool gotOne = false;
unsigned int value = 0;
//
// Set the radix. Its supposed to be a lower case x if hex. But, in
// order to recover well, we check for an upper and put out an error
// for that.
//
unsigned int radix = 10;
if (fReaderMgr->skippedChar(chLatin_x))
{
radix = 16;
}
else if (fReaderMgr->skippedChar(chLatin_X))
{
fScanner->emitError(XMLErrs::HexRadixMustBeLowerCase);
radix = 16;
}
while (true)
{
const XMLCh nextCh = fReaderMgr->peekNextChar();
// Watch for EOF
if (!nextCh)
ThrowXML(UnexpectedEOFException, XMLExcepts::Gen_UnexpectedEOF);
// Break out on the terminating semicolon
if (nextCh == chSemiColon)
{
fReaderMgr->getNextChar();
break;
}
//
// Convert this char to a binary value, or bail out if its not
// one.
//
unsigned int nextVal;
if ((nextCh >= chDigit_0) && (nextCh <= chDigit_9))
nextVal = (unsigned int)(nextCh - chDigit_0);
else if ((nextCh >= chLatin_A) && (nextCh <= chLatin_F))
nextVal= (unsigned int)(10 + (nextCh - chLatin_A));
else if ((nextCh >= chLatin_a) && (nextCh <= chLatin_f))
nextVal = (unsigned int)(10 + (nextCh - chLatin_a));
else
{
//
// If we got at least a sigit, then do an unterminated ref
// error. Else, do an expected a numerical ref thing.
//
if (gotOne)
fScanner->emitError(XMLErrs::UnterminatedCharRef);
else
fScanner->emitError(XMLErrs::ExpectedNumericalCharRef);
return false;
}
//
// Make sure its valid for the radix. If not, then just eat the
// digit and go on after issueing an error. Else, update the
// running value with this new digit.
//
if (nextVal >= radix)
{
XMLCh tmpStr[2];
tmpStr[0] = nextCh;
tmpStr[1] = chNull;
fScanner->emitError(XMLErrs::BadDigitForRadix, tmpStr);
}
else
{
value = (value * radix) + nextVal;
}
// Indicate that we got at least one good digit
gotOne = true;
// Eat the char we just processed
fReaderMgr->getNextChar();
}
// Return the char (or chars)
if (value >= 0x10000)
{
value -= 0x10000;
first = XMLCh((value >> 10) + 0xD800);
second = XMLCh((value & 0x3FF) + 0xDC00);
}
else
{
first = XMLCh(value);
second = 0;
}
return true;
}
ContentSpecNode*
DTDScanner::scanChildren(const DTDElementDecl& elemDecl, XMLBuffer& bufToUse)
{
// Check for a PE ref here, but don't require spaces
checkForPERef(false, false, true);
// We have to check entity nesting here
unsigned int curReader;
//
// We know that the caller just saw an opening parenthesis, so we need
// to parse until we hit the end of it, recursing for other nested
// parentheses we see.
//
// We have to check for one up front, since it could be something like
// (((a)*)) etc...
//
ContentSpecNode* curNode = 0;
if (fReaderMgr->skippedChar(chOpenParen))
{
curReader = fReaderMgr->getCurrentReaderNum();
// Lets call ourself and get back the resulting node
curNode = scanChildren(elemDecl, bufToUse);
// If that failed, no need to go further, return failure
if (!curNode)
return 0;
if (curReader != fReaderMgr->getCurrentReaderNum())
fScanner->emitError(XMLErrs::PartialMarkupInEntity);
}
else
{
// Not a nested paren, so it must be a leaf node
if (!fReaderMgr->getName(bufToUse))
{
fScanner->emitError(XMLErrs::ExpectedElementName);
return 0;
}
//
// Create a leaf node for it. If we can find the element id for
// this element, then use it. Else, we have to fault in an element
// decl, marked as created because of being in a content model.
//
unsigned int elemId = fDTDGrammar->getElemId(0, 0, bufToUse.getRawBuffer(), 0);
if (elemId == XMLElementDecl::fgInvalidElemId)
{
DTDElementDecl* decl = new DTDElementDecl(bufToUse.getRawBuffer());
decl->setCreateReason(XMLElementDecl::InContentModel);
elemId = fDTDGrammar->putElemDecl(decl);
}
curNode = new ContentSpecNode(elemId);
// Check for a PE ref here, but don't require spaces
const bool gotSpaces = checkForPERef(false, false, true);
// Check for a repetition character after the leaf
const XMLCh repCh = fReaderMgr->peekNextChar();
ContentSpecNode* tmpNode = makeRepNode(repCh, curNode);
if (tmpNode != curNode)
{
if (gotSpaces)
fScanner->emitError(XMLErrs::UnexpectedWhitespace);
fReaderMgr->getNextChar();
curNode = tmpNode;
}
}
// Check for a PE ref here, but don't require spaces
checkForPERef(false, false, true);
//
// Ok, the next character tells us what kind of content this particular
// model this particular parentesized section is. Its either a choice if
// we see ',', a sequence if we see '|', or a single leaf node if we see
// a closing paren.
//
const XMLCh opCh = fReaderMgr->peekNextChar();
if ((opCh != chComma)
&& (opCh != chPipe)
&& (opCh != chCloseParen))
{
// Not a legal char, so delete our node and return failure
fScanner->emitError(XMLErrs::ExpectedSeqChoiceLeaf);
delete curNode;
return 0;
}
//
// Create the head node of the correct type. We need this to remember
// the top of the local tree. If it was a single subexpr, then just
// set the head node to the current node. For the others, we'll build
// the tree off the second child as we move across.
//
ContentSpecNode* headNode = 0;
ContentSpecNode::NodeTypes curType;
if (opCh == chComma)
{
curType = ContentSpecNode::Sequence;
headNode = new ContentSpecNode(curType, curNode, 0);
curNode = headNode;
}
else if (opCh == chPipe)
{
curType = ContentSpecNode::Choice;
headNode = new ContentSpecNode(curType, curNode, 0);
curNode = headNode;
}
else
{
headNode = curNode;
fReaderMgr->getNextChar();
}
//
// If it was a sequence or choice, we just loop until we get to the
// end of our section, adding each new leaf or sub expression to the
// right child of the current node, and making that new node the current
// node.
//
if ((opCh == chComma) || (opCh == chPipe))
{
ContentSpecNode* lastNode = 0;
while (true)
{
//
// The next thing must either be another | or , character followed
// by another leaf or subexpression, or a closing parenthesis, or a
// PE ref.
//
if (fReaderMgr->lookingAtChar(chPercent))
{
checkForPERef(false, false, true);
}
else if (fReaderMgr->skippedSpace())
{
// Just skip whitespace
fReaderMgr->skipPastSpaces();
}
else if (fReaderMgr->skippedChar(chCloseParen))
{
//
// We've hit the end of this section, so break out. But, we
// need to see if we left a partial sequence of choice node
// without a second node. If so, we have to undo that and
// put its left child into the right node of the previous
// node.
//
if ((curNode->getType() == ContentSpecNode::Choice)
|| (curNode->getType() == ContentSpecNode::Sequence))
{
if (!curNode->getSecond())
{
ContentSpecNode* saveFirst = curNode->orphanFirst();
lastNode->setSecond(saveFirst);
curNode = lastNode;
}
}
break;
}
else if (fReaderMgr->skippedChar(opCh))
{
// Check for a PE ref here, but don't require spaces
checkForPERef(false, false, true);
if (fReaderMgr->skippedChar(chOpenParen))
{
curReader = fReaderMgr->getCurrentReaderNum();
// Recurse to handle this new guy
ContentSpecNode* subNode = scanChildren(elemDecl, bufToUse);
// If it failed, we are done, clean up here and return failure
if (!subNode)
{
delete headNode;
return 0;
}
if (curReader != fReaderMgr->getCurrentReaderNum())
fScanner->emitError(XMLErrs::PartialMarkupInEntity);
// Else patch it in and make it the new current
ContentSpecNode* newCur = new ContentSpecNode
(
curType
, subNode
, 0
);
curNode->setSecond(newCur);
lastNode = curNode;
curNode = newCur;
}
else
{
//
// Got to be a leaf node, so get a name. If we cannot get
// one, then clean up and get outa here.
//
if (!fReaderMgr->getName(bufToUse))
{
delete headNode;
fScanner->emitError(XMLErrs::ExpectedElementName);
return 0;
}
//
// Create a leaf node for it. If we can find the element
// id for this element, then use it. Else, we have to
// fault in an element decl, marked as created because
// of being in a content model.
//
unsigned int elemId = fDTDGrammar->getElemId(0, 0, bufToUse.getRawBuffer(), 0);
if (elemId == XMLElementDecl::fgInvalidElemId)
{
DTDElementDecl* decl = new DTDElementDecl(bufToUse.getRawBuffer());
decl->setCreateReason(XMLElementDecl::InContentModel);
elemId = fDTDGrammar->putElemDecl(decl);
}
ContentSpecNode* tmpLeaf = new ContentSpecNode(elemId);
// Check for a repetition character after the leaf
const XMLCh repCh = fReaderMgr->peekNextChar();
ContentSpecNode* tmpLeaf2 = makeRepNode(repCh, tmpLeaf);
if (tmpLeaf != tmpLeaf2)
fReaderMgr->getNextChar();
//
// Create a new sequence or choice node, with the leaf
// (or rep surrounding it) we just got as its first node.
// Make the new node the second node of the current node,
// and then make it the current node.
//
ContentSpecNode* newCur = new ContentSpecNode
(
curType
, tmpLeaf2
, 0
);
curNode->setSecond(newCur);
lastNode = curNode;
curNode = newCur;
}
}
else
{
// Cannot be valid
if (opCh == chComma)
{
fScanner->emitError(XMLErrs::ExpectedChoiceOrCloseParen);
}
else
{
fScanner->emitError
(
XMLErrs::ExpectedSeqOrCloseParen
, elemDecl.getFullName()
);
}
delete headNode;
return 0;
}
}
}
//
// We saw the terminating parenthesis so lets check for any repetition
// character, and create a node for that, making the head node the child
// of it.
//
XMLCh repCh = fReaderMgr->peekNextChar();
ContentSpecNode* retNode = makeRepNode(repCh, headNode);
if (retNode != headNode)
fReaderMgr->getNextChar();
return retNode;
}
//
// We get here after the '<!--' part of the comment. We scan past the
// terminating '-->' It will calls the appropriate handler with the comment
// text, if one is provided. A comment can be in either the document or
// the DTD, so the fInDocument flag is used to know which handler to send
// it to.
//
void DTDScanner::scanComment()
{
enum States
{
InText
, OneDash
, TwoDashes
};
// Get a buffer for this
XMLBufBid bbComment(fBufMgr);
//
// Get the comment text into a temp buffer. Be sure to use temp buffer
// two here, since its to be used for stuff that is potentially longer
// than just a name.
//
States curState = InText;
while (true)
{
// Get the next character
const XMLCh nextCh = fReaderMgr->getNextChar();
// Watch for an end of file
if (!nextCh)
{
fScanner->emitError(XMLErrs::UnterminatedComment);
ThrowXML(UnexpectedEOFException, XMLExcepts::Gen_UnexpectedEOF);
}
// Make sure its a valid XML character
if (!XMLReader::isXMLChar(nextCh))
{
XMLCh tmpBuf[9];
XMLString::binToText
(
nextCh
, tmpBuf
, 8
, 16
);
fScanner->emitError(XMLErrs::InvalidCharacter, tmpBuf);
}
if (curState == InText)
{
// If its a dash, go to OneDash state. Otherwise take as text
if (nextCh == chDash)
curState = OneDash;
else
bbComment.append(nextCh);
}
else if (curState == OneDash)
{
//
// If its another dash, then we change to the two dashes states.
// Otherwise, we have to put in the deficit dash and the new
// character and go back to InText.
//
if (nextCh == chDash)
{
curState = TwoDashes;
}
else
{
bbComment.append(chDash);
bbComment.append(nextCh);
curState = InText;
}
}
else if (curState == TwoDashes)
{
// The next character must be the closing bracket
if (nextCh != chCloseAngle)
{
fScanner->emitError(XMLErrs::IllegalSequenceInComment);
fReaderMgr->skipPastChar(chCloseAngle);
return;
}
break;
}
}
// If there is a doc type handler, then pass on the comment stuff
if (fDocTypeHandler)
fDocTypeHandler->doctypeComment(bbComment.getRawBuffer());
}
bool DTDScanner::scanContentSpec(DTDElementDecl& toFill)
{
//
// Check for for a couple of the predefined content type strings. If
// its not one of these, its got to be a parenthesized reg ex type
// expression.
//
if (fReaderMgr->skippedString(XMLUni::fgEmptyString))
{
toFill.setModelType(DTDElementDecl::Empty);
return true;
}
if (fReaderMgr->skippedString(XMLUni::fgAnyString))
{
toFill.setModelType(DTDElementDecl::Any);
return true;
}
// Its got to be a parenthesized regular expression
if (!fReaderMgr->skippedChar(chOpenParen))
{
fScanner->emitError
(
XMLErrs::ExpectedContentSpecExpr
, toFill.getFullName()
);
return false;
}
// Get the current reader id, so we can test for partial markup
const unsigned int curReader = fReaderMgr->getCurrentReaderNum();
// We could have a PE ref here, but don't require space
checkForPERef(false, false, true);
//
// Now we look for a PCDATA string. If its PCDATA, then it must be a
// MIXED model. Otherwise, it must be a regular list of children in
// a regular expression perhaps.
//
bool status;
if (fReaderMgr->skippedString(XMLUni::fgPCDATAString))
{
// Set the model to mixed
toFill.setModelType(DTDElementDecl::Mixed);
status = scanMixed(toFill);
//
// If we are validating we have to check that there are no multiple
// uses of any child elements.
//
if (fScanner->getDoValidation())
{
if (((const MixedContentModel*)toFill.getContentModel())->hasDups())
fScanner->getValidator()->emitError(XMLValid::RepElemInMixed);
}
}
else
{
//
// We have to do a recursive scan of the content model. Create a
// buffer for it to use, for efficiency. It returns the top ofthe
// content spec node tree, which we set if successful.
//
toFill.setModelType(DTDElementDecl::Children);
XMLBufBid bbTmp(fBufMgr);
ContentSpecNode* resNode = scanChildren(toFill, bbTmp.getBuffer());
status = (resNode != 0);
if (status)
toFill.setContentSpec(resNode);
}
// Make sure we are on the same reader as where we started
if (curReader != fReaderMgr->getCurrentReaderNum())
fScanner->emitError(XMLErrs::PartialMarkupInEntity);
return status;
}
void DTDScanner::scanDefaultDecl(DTDAttDef& toFill)
{
if (fReaderMgr->skippedString(XMLUni::fgRequiredString))
{
toFill.setDefaultType(XMLAttDef::Required);
return;
}
if (fReaderMgr->skippedString(XMLUni::fgImpliedString))
{
toFill.setDefaultType(XMLAttDef::Implied);
return;
}
if (fReaderMgr->skippedString(XMLUni::fgFixedString))
{
//
// There must be space before the fixed value. If there is not, then
// emit an error but keep going.
//
if (!fReaderMgr->skippedSpace())
fScanner->emitError(XMLErrs::ExpectedWhitespace);
else
fReaderMgr->skipPastSpaces();
toFill.setDefaultType(XMLAttDef::Fixed);
}
else
{
toFill.setDefaultType(XMLAttDef::Default);
}
//
// If we got here, its fixed or default, so we need to get a value.
// If we don't, then emit an error but just set the default value to
// an empty string and try to keep going.
//
XMLBufBid bbValue(fBufMgr);
if (!scanAttValue(toFill.getFullName(), bbValue.getBuffer(), toFill.getType()))
fScanner->emitError(XMLErrs::ExpectedDefAttrDecl);
toFill.setValue(bbValue.getRawBuffer());
}
//
// This method handles the high level logic of scanning the DOCType
// declaration. This kicks off both the scanning of the internal subset and
// the scanning of the external subset, if any.
//
// When we get here the '<!DOCTYPE' part has already been scanned, which is
// what told us that we had a doc type decl to parse.
//
void DTDScanner::scanDocTypeDecl(const bool reuseGrammar)
{
// There must be some space after DOCTYPE
if (!fReaderMgr->skipPastSpaces())
{
fScanner->emitError(XMLErrs::ExpectedWhitespace);
// Just skip the Doctype declaration and return
fReaderMgr->skipPastChar(chCloseAngle);
return;
}
// Get a buffer for the root element
XMLBufBid bbRootName(fBufMgr);
//
// Get a name from the input, which should be the name of the root
// element of the upcoming content.
//
fReaderMgr->getName(bbRootName.getBuffer());
if (bbRootName.isEmpty())
{
fScanner->emitError(XMLErrs::NoRootElemInDOCTYPE);
fReaderMgr->skipPastChar(chCloseAngle);
return;
}
//
// This element obviously is not going to exist in the element decl
// pool yet, but we need to store away an element id. So force it into
// the element decl pool, marked as being there because it was in
// the DOCTYPE. Later, when its declared, the status will be updated.
//
// Only do this if we are not reusing the validator! If we are reusing,
// then look it up instead. It has to exist!
//
DTDElementDecl* rootDecl;
if (reuseGrammar)
{
rootDecl = (DTDElementDecl*) fDTDGrammar->getElemDecl(0, 0, bbRootName.getRawBuffer(), 0);
if (!rootDecl)
{
fScanner->getValidator()->emitError(XMLValid::UndeclaredElemInDocType, bbRootName.getRawBuffer());
fReaderMgr->skipPastChar(chCloseAngle);
return;
}
}
else
{
rootDecl = new DTDElementDecl(bbRootName.getRawBuffer());
rootDecl->setCreateReason(DTDElementDecl::AsRootElem);
fDTDGrammar->setRootElemId(fDTDGrammar->putElemDecl(rootDecl));
}
// Skip any spaces after the name
fReaderMgr->skipPastSpaces();
//
// And now if we are looking at a >, then we are done. It is not
// required to have an internal or external subset, though why you
// would not escapes me.
//
if (fReaderMgr->skippedChar(chCloseAngle))
return;
bool hasIntSubset = false;
bool hasExtSubset = false;
XMLCh* sysId = 0;
XMLCh* pubId = 0;
//
// If the next character is '[' then we have no external subset cause
// there is no system id, just the opening character of the internal
// subset. Else, has to be an id.
//
if (fReaderMgr->skippedChar(chOpenSquare))
{
hasIntSubset = true;
}
else
{
// Indicate we have an external subset
hasExtSubset = true;
// Get buffers for the ids
XMLBufBid bbPubId(fBufMgr);
XMLBufBid bbSysId(fBufMgr);
// Get the external subset id
if (!scanId(bbPubId.getBuffer(), bbSysId.getBuffer(), IDType_External))
{
fScanner->emitError(XMLErrs::ExpectedSystemOrPublicId);
fReaderMgr->skipPastChar(chCloseAngle);
return;
}
// Get copies of the ids we got
pubId = XMLString::replicate(bbPubId.getRawBuffer());
sysId = XMLString::replicate(bbSysId.getRawBuffer());
// Skip spaces and check again for the opening of an internal subset
fReaderMgr->skipPastSpaces();
if (fReaderMgr->skippedChar(chOpenSquare))
hasIntSubset = true;
}
// Insure that the ids get cleaned up, if they got allocated
ArrayJanitor<XMLCh> janSysId(sysId);
ArrayJanitor<XMLCh> janPubId(pubId);
//
// If we have a doc type handler and advanced callbacks are enabled,
// call the doctype event.
//
if (fDocTypeHandler)
fDocTypeHandler->doctypeDecl(*rootDecl, pubId, sysId, hasIntSubset);
//
// Ok, if we had an internal subset, we are just past the [ character
// and need to parse that first.
//
if (hasIntSubset)
{
// We can't have any internal subset if we are reusing the validator
if (reuseGrammar)
ThrowXML(RuntimeException, XMLExcepts::Val_CantHaveIntSS);
// Indicate we are in the internal subset now
FlagJanitor<bool> janContentFlag(&fInternalSubset, true);
//
// And try to scan the internal subset. If we fail, try to recover
// by skipping forward tot he close angle and returning.
//
if (!scanInternalSubset())
{
fReaderMgr->skipPastChar(chCloseAngle);
return;
}
//
// Do a sanity check that some expanded PE did not propogate out of
// the doctype. This could happen if it was terminated early by bad
// syntax.
//
if (fReaderMgr->getReaderDepth() > 1)
{
fScanner->emitError(XMLErrs::PEPropogated);
// Ask the reader manager to pop back down to the main level
fReaderMgr->cleanStackBackTo(1);
}
fReaderMgr->skipPastSpaces();
}
// And that should leave us at the closing > of the DOCTYPE line
if (!fReaderMgr->skippedChar(chCloseAngle))
{
//
// Do a special check for the common scenario of an extra ] char at
// the end. This is easy to recover from.
//
if (fReaderMgr->skippedChar(chCloseSquare)
&& fReaderMgr->skippedChar(chCloseAngle))
{
fScanner->emitError(XMLErrs::ExtraCloseSquare);
}
else
{
fScanner->emitError(XMLErrs::UnterminatedDOCTYPE);
fReaderMgr->skipPastChar(chCloseAngle);
}
}
//
// If we had an external subset, then we need to deal with that one
// next. If we are reusing the validator, then don't scan it.
//
if (hasExtSubset && !reuseGrammar)
{
// Indicate we are in the external subset now
FlagJanitor<bool> janContentFlag(&fInternalSubset, false);
// And now create a reader to read this entity
InputSource* srcUsed;
XMLReader* reader = fReaderMgr->createReader
(
sysId
, pubId
, false
, XMLReader::RefFrom_NonLiteral
, XMLReader::Type_General
, XMLReader::Source_External
, srcUsed
);
// Put a janitor on the input source
Janitor<InputSource> janSrc(srcUsed);
//
// If it failed then throw an exception
//
if (!reader)
ThrowXML1(RuntimeException, XMLExcepts::Gen_CouldNotOpenDTD, srcUsed->getSystemId());
//
// In order to make the processing work consistently, we have to
// make this look like an external entity. So create an entity
// decl and fill it in and push it with the reader, as happens
// with an external entity. Put a janitor on it to insure it gets
// cleaned up. The reader manager does not adopt them.
//
const XMLCh gDTDStr[] = { chLatin_D, chLatin_T, chLatin_D , chNull };
DTDEntityDecl* declDTD = new DTDEntityDecl(gDTDStr);
declDTD->setSystemId(sysId);
Janitor<DTDEntityDecl> janDecl(declDTD);
// Mark this one as a throw at end
reader->setThrowAtEnd(true);
// And push it onto the stack, with its pseudo name
fReaderMgr->pushReader(reader, declDTD);
// Tell it its not in an include section
scanExtSubsetDecl(false);
}
}
//
// This is called after seeing '<!ELEMENT' which indicates that an element
// markup is starting. This guy scans the rest of it and adds it to the
// element decl pool if it has not already been declared.
//
void DTDScanner::scanElementDecl()
{
//
// Space is legal (required actually) here so check for a PE ref. If
// we don't get our whitespace, then issue and error, but try to keep
// going.
//
if (!checkForPERef(true, false, true))
fScanner->emitError(XMLErrs::ExpectedWhitespace);
// Get a buffer for the element name and scan in the name
XMLBufBid bbName(fBufMgr);
if (!fReaderMgr->getName(bbName.getBuffer()))
{
fScanner->emitError(XMLErrs::ExpectedElementName);
fReaderMgr->skipPastChar(chCloseAngle);
return;
}
// Look this guy up in the element decl pool
DTDElementDecl* decl = (DTDElementDecl*) fDTDGrammar->getElemDecl(0, 0, bbName.getRawBuffer(), 0);
//
// If it does not exist, then we need to create it. If it does and
// its marked as declared, then that's an error, but we still need to
// scan over the content model so use the dummy declaration that the
// parsing code can fill in.
//
if (decl)
{
if (decl->isDeclared())
{
if (fScanner->getDoValidation())
fScanner->getValidator()->emitError(XMLValid::ElementAlreadyExists, bbName.getRawBuffer());
if (!fDumElemDecl)
fDumElemDecl = new DTDElementDecl(bbName.getRawBuffer());
else
fDumElemDecl->setName(bbName.getRawBuffer());
}
}
else
{
//
// Create the new empty declaration to fill in and put it into
// the decl pool.
//
decl = new DTDElementDecl(bbName.getRawBuffer());
fDTDGrammar->putElemDecl(decl);
}
// Set a flag for whether we will ignore this one
const bool isIgnored = (decl == fDumElemDecl);
// Mark this one as being declared
decl->setCreateReason(XMLElementDecl::Declared);
// Another check for a PE ref, with at least required whitespace
if (!checkForPERef(true, false, true))
fScanner->emitError(XMLErrs::ExpectedWhitespace);
// And now scan the content model for this guy.
if (!scanContentSpec(*decl))
{
fReaderMgr->skipPastChar(chCloseAngle);
return;
}
// Another check for a PE ref, but we don't require whitespace here
checkForPERef(false, false, true);
// And we should have the ending angle bracket
if (!fReaderMgr->skippedChar(chCloseAngle))
{
fScanner->emitError(XMLErrs::UnterminatedElementDecl, bbName.getRawBuffer());
fReaderMgr->skipPastChar(chCloseAngle);
}
//
// If we have a DTD handler tell it about the new element decl. We
// tell it if its one that can be ignored, cause its an override of a
// previously existing decl. If it is being ignored, only call back
// if advanced callbacks are enabled.
//
if (fDocTypeHandler)
fDocTypeHandler->elementDecl(*decl, isIgnored);
}
//
// This method will process a general or parameter entity reference. The
// entity name and entity text will be stored in the entity pool. The value
// of the entity will be scanned for any other parameter entity or char
// references which will be expanded. So the stored value can only have
// general entity references when done.
//
void DTDScanner::scanEntityDecl()
{
//
// Space is required here, but we cannot check for a PE Ref since
// there could be a legal (no-ref) percent sign here. Since any
// entity that ended here would be illegal, we just skip spaces
// and then check for a percent.
//
if (!fReaderMgr->lookingAtSpace())
fScanner->emitError(XMLErrs::ExpectedWhitespace);
else
fReaderMgr->skipPastSpaces();
const bool isPEDecl = fReaderMgr->skippedChar(chPercent);
//
// If a PE decl, then eat the percent and check for spaces or a
// PE ref on the other side of it. At least spaces are required.
//
if (isPEDecl)
{
if (!checkForPERef(true, false, true))
fScanner->emitError(XMLErrs::ExpectedWhitespace);
}
//
// Now lets get a name, which should be the name of the entity. We
// have to get a buffer for this.
//
XMLBufBid bbName(fBufMgr);
if (!fReaderMgr->getName(bbName.getBuffer()))
{
fScanner->emitError(XMLErrs::ExpectedPEName);
fReaderMgr->skipPastChar(chCloseAngle);
return;
}
// If namespaces are enabled, then no colons allowed
if (fScanner->getDoNamespaces())
{
if (XMLString::indexOf(bbName.getRawBuffer(), chColon) != -1)
fScanner->emitError(XMLErrs::ColonNotLegalWithNS);
}
//
// See if this entity already exists. If so, then the existing one
// takes precendence. So we use the local dummy decl to parse into
// and just ignore the results.
//
DTDEntityDecl* entityDecl;
if (isPEDecl)
entityDecl = fPEntityDeclPool->getByKey(bbName.getRawBuffer());
else
entityDecl = (DTDEntityDecl*) fDTDGrammar->getEntityDecl(bbName.getRawBuffer());
if (entityDecl)
{
if (!fDumEntityDecl)
fDumEntityDecl = new DTDEntityDecl;
fDumEntityDecl->setName(bbName.getRawBuffer());
entityDecl = fDumEntityDecl;
}
else
{
// Its not in existence already, then create an entity decl for it
entityDecl = new DTDEntityDecl(bbName.getRawBuffer());
//
// Set the declaration location. The parameter indicates whether its
// declared in the content/internal subset, so we know whether or not
// its in the external subset.
//
entityDecl->setDeclaredInIntSubset(fInternalSubset);
// Add it to the appropriate entity decl pool
if (isPEDecl)
fPEntityDeclPool->put(entityDecl);
else
fDTDGrammar->putEntityDecl(entityDecl);
}
// Set a flag that indicates whether we are ignoring this one
const bool isIgnored = (entityDecl == fDumEntityDecl);
// Set the PE flag on it
entityDecl->setIsParameter(isPEDecl);
//
// Space is legal (required actually) here so check for a PE ref. If
// we don't get our whitespace, then issue an error, but try to keep
// going.
//
if (!checkForPERef(true, false, true))
fScanner->emitError(XMLErrs::ExpectedWhitespace);
// According to the type call the value scanning method
if (!scanEntityDef(*entityDecl, isPEDecl))
{
fReaderMgr->skipPastChar(chCloseAngle);
fScanner->emitError(XMLErrs::ExpectedEntityValue);
return;
}
// Space is legal (but not required) here so check for a PE ref
checkForPERef(false, false, true);
// And then we have to have the closing angle bracket
if (!fReaderMgr->skippedChar(chCloseAngle))
{
fScanner->emitError(XMLErrs::UnterminatedEntityDecl, entityDecl->getName());
fReaderMgr->skipPastChar(chCloseAngle);
}
//
// If we have a doc type handler, then call it. But only call it for
// ignored elements if advanced callbacks are enabled.
//
if (fDocTypeHandler)
fDocTypeHandler->entityDecl(*entityDecl, isPEDecl, isIgnored);
}
//
// This method will scan a general/character entity ref. It will either
// expand a char ref and return the value directly, or it will expand
// a general entity and a reader for it onto the reader stack.
//
// The return value indicates whether the value was returned directly or
// pushed as a reader or it failed.
//
// The escaped flag tells the caller whether the returnd parameter resulted
// from a character reference, which escapes the character in some cases. It
// only makes any difference if the return indicates the value was returned
// directly.
//
// NOTE: This is only called when scanning attribute values, so we always
// expand general entities.
//
DTDScanner::EntityExpRes
DTDScanner::scanEntityRef(XMLCh& firstCh, XMLCh& secondCh, bool& escaped)
{
// Assume no escape and no second char
escaped = false;
secondCh = 0;
// We have to insure its all done in a single entity
const unsigned int curReader = fReaderMgr->getCurrentReaderNum();
//
// If the next char is a pound, then its a character reference and we
// need to expand it always.
//
if (fReaderMgr->skippedChar(chPound))
{
//
// Its a character reference, so scan it and get back the numeric
// value it represents. If it fails, just return immediately.
//
if (!scanCharRef(firstCh, secondCh))
return EntityExp_Failed;
if (curReader != fReaderMgr->getCurrentReaderNum())
fScanner->emitError(XMLErrs::PartialMarkupInEntity);
// Its now escaped since it was a char ref
escaped = true;
return EntityExp_Returned;
}
// Get the name of the general entity
XMLBufBid bbName(fBufMgr);
if (!fReaderMgr->getName(bbName.getBuffer()))
{
fScanner->emitError(XMLErrs::ExpectedEntityRefName);
return EntityExp_Failed;
}
//
// Next char must be a semi-colon. But if its not, just emit
// an error and try to continue.
//
if (!fReaderMgr->skippedChar(chSemiColon))
fScanner->emitError(XMLErrs::UnterminatedEntityRef, bbName.getRawBuffer());
// Make sure it was all in one entity reader
if (curReader != fReaderMgr->getCurrentReaderNum())
fScanner->emitError(XMLErrs::PartialMarkupInEntity);
// Look it up the name the general entity pool
XMLEntityDecl* decl = fDTDGrammar->getEntityDecl(bbName.getRawBuffer());
// If it does not exist, then obviously an error
if (!decl)
{
fScanner->emitError(XMLErrs::EntityNotFound, bbName.getRawBuffer());
return EntityExp_Failed;
}
//
// If we are a standalone document, then it has to have been declared
// in the internal subset. Keep going though.
//
if (fScanner->getStandalone() && !decl->getDeclaredInIntSubset())
fScanner->emitError(XMLErrs::IllegalRefInStandalone, bbName.getRawBuffer());
//
// If its a special char reference, then its escaped and we can return
// it directly.
//
if (decl->getIsSpecialChar())
{
firstCh = decl->getValue()[0];
escaped = true;
return EntityExp_Returned;
}
if (decl->isExternal())
{
// If its unparsed, then its not valid here
if (decl->isUnparsed())
{
fScanner->emitError(XMLErrs::NoUnparsedEntityRefs, bbName.getRawBuffer());
return EntityExp_Failed;
}
// We are in an attribute value, so not valid. But keep going
fScanner->emitError(XMLErrs::NoExtRefsInAttValue);
// And now create a reader to read this entity
InputSource* srcUsed;
XMLReader* reader = fReaderMgr->createReader
(
decl->getSystemId()
, decl->getPublicId()
, false
, XMLReader::RefFrom_NonLiteral
, XMLReader::Type_General
, XMLReader::Source_External
, srcUsed
);
// Put a janitor on the source so it gets cleaned up on exit
Janitor<InputSource> janSrc(srcUsed);
//
// If the creation failed then throw an exception
//
if (!reader)
ThrowXML1(RuntimeException, XMLExcepts::Gen_CouldNotOpenExtEntity, srcUsed->getSystemId());
//
// Push the reader. If its a recursive expansion, then emit an error
// and return an failure.
//
if (!fReaderMgr->pushReader(reader, decl))
{
fScanner->emitError(XMLErrs::RecursiveEntity, decl->getName());
return EntityExp_Failed;
}
// If it starts with the XML string, then parse a text decl
if (fReaderMgr->skippedString(XMLUni::fgXMLDeclString))
scanTextDecl();
}
else
{
//
// Create a reader over a memory stream over the entity value
// We force it to assume UTF-16 by passing in an encoding
// string. This way it won't both trying to predecode the
// first line, looking for an XML/TextDecl.
//
XMLReader* valueReader = fReaderMgr->createIntEntReader
(
decl->getName()
, XMLReader::RefFrom_NonLiteral
, XMLReader::Type_General
, decl->getValue()
, decl->getValueLen()
, false
);
//
// Trt to push the entity reader onto the reader manager stack,
// where it will become the subsequent input. If it fails, that
// means the entity is recursive, so issue an error. The reader
// will have just been discarded, but we just keep going.
//
if (!fReaderMgr->pushReader(valueReader, decl))
fScanner->emitError(XMLErrs::RecursiveEntity, decl->getName());
}
return EntityExp_Pushed;
}
//
// This method will scan a quoted literal of an entity value. It has to
// deal with replacement of PE references; however, since this is a DTD
// scanner, all such entity literals are in entity decls and therefore
// general entities are not expanded.
//
bool DTDScanner::scanEntityLiteral(XMLBuffer& toFill, const bool isPE)
{
toFill.reset();
// Get the next char which must be a single or double quote
XMLCh quoteCh;
if (!fReaderMgr->skipIfQuote(quoteCh))
return false;
// Get a buffer for pulling in entity names when we see GE refs
XMLBufBid bbName(fBufMgr);
XMLBuffer& nameBuf = bbName.getBuffer();
// Remember the current reader
const unsigned int orgReader = fReaderMgr->getCurrentReaderNum();
//
// Loop until we see the ending quote character, handling any references
// in the process.
//
XMLCh nextCh;
XMLCh secondCh = 0;
bool gotLeadingSurrogate = false;
while (true)
{
// Get the second char if we have one, else get another
if (secondCh)
{
nextCh = secondCh;
secondCh = 0;
}
else
{
nextCh = fReaderMgr->getNextChar();
}
//
// Watch specifically for EOF and issue a more meaningful error
// if that occurs (since an unterminated quoted char can cause
// this easily.)
//
if (!nextCh)
{
fScanner->emitError(XMLErrs::UnterminatedEntityLiteral);
ThrowXML(UnexpectedEOFException, XMLExcepts::Gen_UnexpectedEOF);
}
//
// Break out on our terminating quote char when we are back in the
// same reader. Otherwise, we might trigger on a nested quote char
// in an expanded entity.
//
if ((nextCh == quoteCh)
&& (fReaderMgr->getCurrentReaderNum() == orgReader))
{
break;
}
if (nextCh == chPercent)
{
//
// Put the PE's value on the reader stack and then jump back
// to the top to start processing it. The parameter indicates
// that it should not scan the reference's content as an external
// subset.
//
expandPERef(false, true, true);
continue;
}
//
// Ok, now that all the other special stuff is checked, we can
// look for a general entity. In here, we cannot have a naked &
// and will only expand numerical char refs or the intrinsic char
// refs. Others will be left alone.
//
if (nextCh == chAmpersand)
{
//
// Here, we only expand numeric char refs, but not any general
// entities. However, the stupid XML spec requires that we check
// and make sure it does refer to a general entity if its not
// a char ref (i.e. no naked '&' chars.)
//
if (fReaderMgr->skippedChar(chPound))
{
// If it failed, then just jump back to the top and try to pick up
if (!scanCharRef(nextCh, secondCh))
{
gotLeadingSurrogate = false;
continue;
}
}
else
{
if (!fReaderMgr->getName(nameBuf))
{
fScanner->emitError(XMLErrs::ExpectedEntityRefName);
}
else
{
//
// Since we are not expanding any of this, we have to
// put the amp and name into the target buffer as data.
//
toFill.append(chAmpersand);
toFill.append(nameBuf.getRawBuffer());
// Make sure we skipped a trailing semicolon
if (!fReaderMgr->skippedChar(chSemiColon))
{
fScanner->emitError
(
XMLErrs::UnterminatedEntityRef
, nameBuf.getRawBuffer()
);
}
// And make the new character the semicolon
nextCh = chSemiColon;
}
// Either way here we reset the surrogate flag
gotLeadingSurrogate = false;
}
}
if ((nextCh >= 0xD800) && (nextCh <= 0xDBFF))
{
if (gotLeadingSurrogate)
fScanner->emitError(XMLErrs::Expected2ndSurrogateChar);
else
gotLeadingSurrogate = true;
}
else
{
if (gotLeadingSurrogate)
{
if ((nextCh < 0xDC00) && (nextCh > 0xDFFF))
fScanner->emitError(XMLErrs::Expected2ndSurrogateChar);
}
else if (!XMLReader::isXMLChar(nextCh))
{
XMLCh tmpBuf[9];
XMLString::binToText
(
nextCh
, tmpBuf
, 8
, 16
);
fScanner->emitError(XMLErrs::InvalidCharacter, tmpBuf);
fReaderMgr->skipPastChar(quoteCh);
return false;
}
gotLeadingSurrogate = false;
}
// Looks ok, so add it to the literal
toFill.append(nextCh);
}
//
// If we got here and did not get back to the original reader level,
// then we propogated some entity out of the literal, so issue an
// error, but don't fail.
//
if (fReaderMgr->getCurrentReaderNum() != orgReader)
fScanner->emitError(XMLErrs::PartialMarkupInEntity);
return true;
}
//
// This method is called after the entity name has been scanned, and any
// PE referenced following the name is handled. The passed decl will be
// filled in with the info scanned.
//
bool DTDScanner::scanEntityDef(DTDEntityDecl& decl, const bool isPEDecl)
{
// Its got to be an entity literal
if (fReaderMgr->lookingAtChar(chSingleQuote)
|| fReaderMgr->lookingAtChar(chDoubleQuote))
{
// Get a buffer for the literal
XMLBufBid bbValue(fBufMgr);
if (!scanEntityLiteral(bbValue.getBuffer(), isPEDecl))
return false;
// Set it on the entity decl
decl.setValue(bbValue.getRawBuffer());
return true;
}
//
// Its got to be an external entity, so there must be an external id.
// Get buffers for them and scan an external id into them.
//
XMLBufBid bbPubId(fBufMgr);
XMLBufBid bbSysId(fBufMgr);
if (!scanId(bbPubId.getBuffer(), bbSysId.getBuffer(), IDType_External))
return false;
// Fill in the id fields of the decl with the info we got
decl.setPublicId(bbPubId.getRawBuffer());
decl.setSystemId(bbSysId.getRawBuffer());
// If its a PE decl, we are done
bool gotSpaces = checkForPERef(false, false, true);
if (isPEDecl)
{
//
// Check for a common error here. NDATA is not allowed for PEs
// so check for the NDATA string. If found give a nice meaningful
// error and continue parsing to eat the NDATA text.
//
if (gotSpaces)
{
if (fReaderMgr->skippedString(XMLUni::fgNDATAString))
fScanner->emitError(XMLErrs::NDATANotValidForPE);
}
else
{
return true;
}
}
// If looking at close angle now, we are done
if (fReaderMgr->lookingAtChar(chCloseAngle))
return true;
// Else we had to have seem the whitespace
if (!gotSpaces)
fScanner->emitError(XMLErrs::ExpectedWhitespace);
// We now have to see a notation data string
if (!fReaderMgr->skippedString(XMLUni::fgNDATAString))
fScanner->emitError(XMLErrs::ExpectedNDATA);
// Space is required here, but try to go on if not
if (!checkForPERef(false, false, true))
fScanner->emitError(XMLErrs::ExpectedWhitespace);
// Get a name
XMLBufBid bbName(fBufMgr);
if (!fReaderMgr->getName(bbName.getBuffer()))
{
fScanner->emitError(XMLErrs::ExpectedNotationName);
return false;
}
// Set the decl's notation name
decl.setNotationName(bbName.getRawBuffer());
return true;
}
//
// This method is called after an attribute decl name or a notation decl has
// been scanned and then an opening parenthesis was see, indicating the list
// of values. It scans the enumeration values and creates a single string
// which has a single space between each value.
//
// The terminating close paren ends this scan.
//
bool DTDScanner::scanEnumeration( const DTDAttDef& attDef
, XMLBuffer& toFill
, const bool notation)
{
// Reset the passed buffer
toFill.reset();
// Check for PE ref but don't require space
checkForPERef(false, false, true);
// If this is a notation, we need an opening paren
if (notation)
{
if (!fReaderMgr->skippedChar(chOpenParen))
fScanner->emitError(XMLErrs::ExpectedOpenParen);
}
// We need a local buffer to use as well
XMLBufBid bbTmp(fBufMgr);
while (true)
{
// Space is allowed here for either type so check for PE ref
checkForPERef(false, false, true);
// And then get either a name or a name token
bool success;
if (notation)
success = fReaderMgr->getName(bbTmp.getBuffer());
else
success = fReaderMgr->getNameToken(bbTmp.getBuffer());
if (!success)
{
fScanner->emitError
(
XMLErrs::ExpectedEnumValue
, attDef.getFullName()
);
return false;
}
// Append this value to the target value
toFill.append(bbTmp.getRawBuffer(), bbTmp.getLen());
// Space is allowed here for either type so check for PE ref
checkForPERef(false, false, true);
// Check for the terminating paren
if (fReaderMgr->skippedChar(chCloseParen))
break;
// And append a space separator
toFill.append(chSpace);
// Check for the pipe character separator
if (!fReaderMgr->skippedChar(chPipe))
{
fScanner->emitError(XMLErrs::ExpectedEnumSepOrParen);
return false;
}
}
return true;
}
bool DTDScanner::scanEq()
{
fReaderMgr->skipPastSpaces();
if (fReaderMgr->skippedChar(chEqual))
{
fReaderMgr->skipPastSpaces();
return true;
}
return false;
}
//
// This method is called when an external entity reference is seen in the
// DTD or an external DTD subset is encountered, and their contents pushed
// onto the reader stack. This method will scan that contents.
//
void DTDScanner::scanExtSubsetDecl(const bool inIncludeSect)
{
bool bAcceptDecl = !inIncludeSect;
// Get a buffer for whitespace
XMLBufBid bbSpace(fBufMgr);
//
// If we have a doc type handler and we are not being called recursively
// to handle an include section, tell it the ext subset starts
//
if (fDocTypeHandler && !inIncludeSect)
fDocTypeHandler->startExtSubset();
//
// We have to play a trick here if the current entity we are parsing
// is a PE. Because the spooling code will put out a whitespace before
// and after an expanded PE if its being scanned outside the context of
// a literal entity, this will confuse this external subset code.
//
// So, we see if that is what is happening and, if so, eat the single
// space, a check for the <?xml string. If we find it, we parse that
// markup right now and put the space back.
//
if (fReaderMgr->isScanningPERefOutOfLiteral())
{
if (fReaderMgr->skippedSpace())
{
if (fReaderMgr->skippedString(XMLUni::fgXMLDeclStringSpace))
{
scanTextDecl();
bAcceptDecl = false;
// <TBD> Figure out how to do this
// fReaderMgr->unGet(chSpace);
}
}
}
// Get the current reader number
const unsigned int orgReader = fReaderMgr->getCurrentReaderNum();
//
// Loop until we hit the end of the external subset entity. Note that
// we use a double loop here in order to avoid the overhead of doing
// the exception setup/teardown work on every loop.
//
bool inMarkup = false;
bool inCharData = false;
while (true)
{
try
{
while (true)
{
const XMLCh nextCh = fReaderMgr->peekNextChar();
if (nextCh == chOpenAngle)
{
// Get the reader we started this on
const unsigned int orgReader = fReaderMgr->getCurrentReaderNum();
//
// Now scan the markup. Set the flag so that we will know that
// we were in markup if an end of entity exception occurs.
//
fReaderMgr->getNextChar();
inMarkup = true;
scanMarkupDecl(bAcceptDecl);
inMarkup = false;
//
// And see if we got back to the same level. If not, then its
// a partial markup error.
//
if (fReaderMgr->getCurrentReaderNum() != orgReader)
fScanner->emitError(XMLErrs::PartialMarkupInEntity);
}
else if (XMLReader::isWhitespace(nextCh))
{
//
// If we have a doc type handler, and advanced callbacks are
// enabled, then gather up whitespace and call back. Otherwise
// just skip whitespaces.
//
if (fDocTypeHandler)
{
inCharData = true;
fReaderMgr->getSpaces(bbSpace.getBuffer());
inCharData = false;
fDocTypeHandler->doctypeWhitespace
(
bbSpace.getRawBuffer()
, bbSpace.getLen()
);
}
else
{
//
// If we hit an end of entity in the middle of white
// space, that's fine. We'll just come back in here
// again on the next round and skip some more.
//
fReaderMgr->skipPastSpaces();
}
}
else if (nextCh == chPercent)
{
//
// Expand (and scan if external) the reference value. Tell
// it to throw an end of entity exception at the end of the
// entity.
//
fReaderMgr->getNextChar();
expandPERef(true, false, false, true);
}
else if (inIncludeSect && (nextCh == chCloseSquare))
{
//
// Its the end of a conditional include section. So scan it and
// decrement the include depth counter.
//
fReaderMgr->getNextChar();
if (!fReaderMgr->skippedChar(chCloseSquare))
{
fScanner->emitError(XMLErrs::ExpectedEndOfConditional);
fReaderMgr->skipPastChar(chCloseAngle);
}
else if (!fReaderMgr->skippedChar(chCloseAngle))
{
fScanner->emitError(XMLErrs::ExpectedEndOfConditional);
fReaderMgr->skipPastChar(chCloseAngle);
}
return;
}
else
{
fReaderMgr->getNextChar();
if (!XMLReader::isXMLChar(nextCh))
{
XMLCh tmpBuf[9];
XMLString::binToText
(
nextCh
, tmpBuf
, 8
, 16
);
fScanner->emitError(XMLErrs::InvalidCharacter, tmpBuf);
}
else
{
fScanner->emitError(XMLErrs::InvalidDocumentStructure);
}
// Try to get realigned
static const XMLCh toSkip[] =
{
chPercent, chCloseSquare, chOpenAngle, chNull
};
fReaderMgr->skipUntilInOrWS(toSkip);
}
bAcceptDecl = false;
}
}
catch(const EndOfEntityException& toCatch)
{
//
// If the external entity ended while we were in markup, then that's
// a partial markup error.
//
if (inMarkup)
{
fScanner->emitError(XMLErrs::PartialMarkupInEntity);
inMarkup = false;
}
// If we were in char data, then send what we got
if (inCharData)
{
// Send what we got, then rethrow
if (fDocTypeHandler)
{
fDocTypeHandler->doctypeWhitespace
(
bbSpace.getRawBuffer()
, bbSpace.getLen()
);
}
inCharData = false;
}
//
// If the entity that just ended was the entity that we started
// on, then this is the end of the external subset.
//
if (orgReader == toCatch.getReaderNum())
break;
}
}
// If we have a doc type handler, tell it the ext subset ends
if (fDocTypeHandler)
fDocTypeHandler->endExtSubset();
}
//
// This method will scan for an id, either public or external.
//
bool DTDScanner::scanId( XMLBuffer& pubIdToFill
, XMLBuffer& sysIdToFill
, const IDTypes whatKind)
{
// Clean out both return buffers
pubIdToFill.reset();
sysIdToFill.reset();
//
// Check first for the system id first. If we find it, and system id
// is one of the legal values, then lets try to scan it.
//
if (fReaderMgr->skippedString(XMLUni::fgSysIDString))
{
// If they were looking for a public id, then we failed
if (whatKind == IDType_Public)
{
fScanner->emitError(XMLErrs::ExpectedPublicId);
return false;
}
// We must skip spaces
if (!fReaderMgr->skipPastSpaces())
{
fScanner->emitError(XMLErrs::ExpectedWhitespace);
return false;
}
// Get the system literal value
return scanSystemLiteral(sysIdToFill);
}
// See if we have a public id string. If not, we are done and found nothing
if (!fReaderMgr->skippedString(XMLUni::fgPubIDString))
return false;
//
// So following this we must have whitespace, a public literal, whitespace,
// and a system literal.
//
if (!fReaderMgr->skipPastSpaces())
{
fScanner->emitError(XMLErrs::ExpectedWhitespace);
//
// Just in case, if they just forgot the whitespace but the next char
// is a single or double quote, then keep going.
//
const XMLCh chPeek = fReaderMgr->peekNextChar();
if ((chPeek != chDoubleQuote) && (chPeek != chSingleQuote))
return false;
}
if (!scanPublicLiteral(pubIdToFill))
{
fScanner->emitError(XMLErrs::ExpectedPublicId);
return false;
}
// If they wanted a public id, then this is all
if (whatKind == IDType_Public)
return true;
// Else lets get the system id
if (!fReaderMgr->skipPastSpaces())
{
//
// In order to recover best here we need to see if we don't have
// whitespace because the next thing is a quote or because the next
// thing is some non-quote character.
//
const XMLCh chPeek = fReaderMgr->peekNextChar();
const bool bIsQuote = ((chPeek == chDoubleQuote)
|| (chPeek == chSingleQuote));
if (whatKind == IDType_External)
{
//
// If its an external Id, then we need to see the system id.
// So, emit the error. But, if the next char is a quote, don't
// give up since its probably going to work. The user just
// missed the separating space. Otherwise, fail.
//
fScanner->emitError(XMLErrs::ExpectedWhitespace);
if (!bIsQuote)
return false;
}
else
{
//
// We can legally return here. But, if the next char is a quote,
// then that's probably not what was desired, since its probably
// just that space was forgotten and there really is a system
// id to follow.
//
// So treat it like missing whitespace if so and keep going.
// Else, just return success.
//
if (bIsQuote)
fScanner->emitError(XMLErrs::ExpectedWhitespace);
else
return true;
}
}
if (!scanSystemLiteral(sysIdToFill))
{
// Its only an error to not have it if we are doing an external
if (whatKind == IDType_External)
{
fScanner->emitError(XMLErrs::ExpectedSystemId);
return false;
}
}
return true;
}
//
// This method will scan the contents of an ignored section. It assumes that
// we already are in the body, i.e. we've seen <![IGNORE[ at this point. So
// we have to just scan until we see a matching ]]> closing markup.
//
void DTDScanner::scanIgnoredSection()
{
//
// Depth starts at one because we are already in one section and want
// to parse until we hit its end.
//
unsigned long depth = 1;
while (true)
{
const XMLCh nextCh = fReaderMgr->getNextChar();
if (!nextCh)
ThrowXML(UnexpectedEOFException, XMLExcepts::Gen_UnexpectedEOF);
if (nextCh == chOpenAngle)
{
if (fReaderMgr->skippedChar(chBang)
&& fReaderMgr->skippedChar(chOpenSquare))
{
depth++;
}
}
else if (nextCh == chCloseSquare)
{
if (fReaderMgr->skippedChar(chCloseSquare))
{
while (fReaderMgr->skippedChar(chCloseSquare))
{
// Do nothing, just skip them
}
if (fReaderMgr->skippedChar(chCloseAngle))
{
depth--;
if (!depth)
break;
}
}
}
else if (!XMLReader::isXMLChar(nextCh))
{
XMLCh tmpBuf[9];
XMLString::binToText
(
nextCh
, tmpBuf
, 8
, 16
);
fScanner->emitError(XMLErrs::InvalidCharacter, tmpBuf);
}
}
}
//
// This method scans the entire internal subset. All we can have here is
// decl markup, and PE references. The expanded PE references must contain
// whole markup, so we don't have to worry about their content at this
// level. We just scan them, expand them, push them, and parse their content
// right there, via the expandERef() method.
//
bool DTDScanner::scanInternalSubset()
{
// If we have a doc type handler, tell it the internal subset starts
if (fDocTypeHandler)
fDocTypeHandler->startIntSubset();
// Get a buffer for whitespace
XMLBufBid bbSpace(fBufMgr);
bool noErrors = true;
while (true)
{
const XMLCh nextCh = fReaderMgr->peekNextChar();
//
// If we get an end of file marker, just unget it and return a
// failure status. The caller will then see the end of file and
// faill out correctly.
//
if (!nextCh)
return false;
// Watch for the end of internal subset marker
if (nextCh == chCloseSquare)
{
fReaderMgr->getNextChar();
break;
}
if (nextCh == chPercent)
{
//
// Expand (and scan if external) the reference value. Tell
// it to set the reader to cause an end of entity exception
// when this reader dies, which is what the scanExtSubset
// method wants (who is called to scan this.)
//
fReaderMgr->getNextChar();
expandPERef(true, false, false, true);
}
else if (nextCh == chOpenAngle)
{
// Remember this reader before we start the scan
const unsigned int orgReader = fReaderMgr->getCurrentReaderNum();
// And scan this markup
fReaderMgr->getNextChar();
scanMarkupDecl(false);
// If we did not get back to entry level, then partial markup
if (fReaderMgr->getCurrentReaderNum() != orgReader)
fScanner->emitError(XMLErrs::PartialMarkupInEntity);
}
else if (XMLReader::isWhitespace(nextCh))
{
//
// IF we are doing advanced callbacks and have a doc type
// handler, then get the whitespace and call the doc type
// handler with it. Otherwise, just skip whitespace.
//
if (fDocTypeHandler)
{
fReaderMgr->getSpaces(bbSpace.getBuffer());
fDocTypeHandler->doctypeWhitespace
(
bbSpace.getRawBuffer()
, bbSpace.getLen()
);
}
else
{
fReaderMgr->skipPastSpaces();
}
}
else
{
// Not valid, so emit an error
XMLCh tmpBuf[9];
XMLString::binToText
(
fReaderMgr->getNextChar()
, tmpBuf
, 8
, 16
);
fScanner->emitError
(
XMLErrs::InvalidCharacterInIntSubset
, tmpBuf
);
//
// If an '>', then probably an abnormally terminated
// internal subset so just return.
//
if (nextCh == chCloseAngle)
{
noErrors = false;
break;
}
//
// Otherwise, try to sync back up by scanning forward for
// a reasonable start character.
//
static const XMLCh toSkip[] =
{
chPercent, chCloseSquare, chOpenAngle, chNull
};
fReaderMgr->skipUntilInOrWS(toSkip);
}
}
// If we have a doc type handler, tell it the internal subset ends
if (fDocTypeHandler)
fDocTypeHandler->endIntSubset();
return noErrors;
}
//
// This method is called once we see a < in the input of an int/ext subset,
// which indicates the start of some sort of markup.
//
void DTDScanner::scanMarkupDecl(const bool parseTextDecl)
{
//
// We only have two valid first characters here. One is a ! which opens
// some markup decl. The other is a ?, which could begin either a PI
// or a text decl. If parseTextDecl is false, we cannot accept a text
// decl.
//
const XMLCh nextCh = fReaderMgr->getNextChar();
if (nextCh == chBang)
{
if (fReaderMgr->skippedChar(chDash))
{
if (fReaderMgr->skippedChar(chDash))
{
scanComment();
}
else
{
fScanner->emitError(XMLErrs::CommentsMustStartWith);
fReaderMgr->skipPastChar(chCloseAngle);
}
}
else if (fReaderMgr->skippedChar(chOpenSquare))
{
//
// Its a conditional section. This is only valid in the external
// subset, so issue an error if we aren't there.
//
if (fInternalSubset)
{
fScanner->emitError(XMLErrs::ConditionalSectInIntSubset);
fReaderMgr->skipPastChar(chCloseAngle);
return;
}
// A PE ref can happen here, but space is not required
checkForPERef(false, false, true);
if (fReaderMgr->skippedString(XMLUni::fgIncludeString))
{
checkForPERef(false, false, true);
// Check for the following open square bracket
if (!fReaderMgr->skippedChar(chOpenSquare))
fScanner->emitError(XMLErrs::ExpectedINCLUDEBracket);
checkForPERef(false, false, true);
//
// Recurse back to the ext subset call again, telling it its
// in an include section.
//
scanExtSubsetDecl(true);
}
else if (fReaderMgr->skippedString(XMLUni::fgIgnoreString))
{
checkForPERef(false, false, true);
// Check for the following open square bracket
if (!fReaderMgr->skippedChar(chOpenSquare))
fScanner->emitError(XMLErrs::ExpectedINCLUDEBracket);
// And scan over the ignored part
scanIgnoredSection();
}
else
{
fScanner->emitError(XMLErrs::ExpectedIncOrIgn);
fReaderMgr->skipPastChar(chCloseAngle);
}
}
else if (fReaderMgr->skippedString(XMLUni::fgAttListString))
{
scanAttListDecl();
}
else if (fReaderMgr->skippedString(XMLUni::fgElemString))
{
scanElementDecl();
}
else if (fReaderMgr->skippedString(XMLUni::fgEntityString))
{
scanEntityDecl();
}
else if (fReaderMgr->skippedString(XMLUni::fgNotationString))
{
scanNotationDecl();
}
else
{
fScanner->emitError(XMLErrs::ExpectedMarkupDecl);
fReaderMgr->skipPastChar(chCloseAngle);
}
}
else if (nextCh == chQuestion)
{
// It could be a PI or the XML declaration. Check for Decl
bool gotDecl = fReaderMgr->skippedString(XMLUni::fgXMLStringSpace);
//
// Just in case, check for upper case. If found, issue
// an error, but keep going.
//
if (!gotDecl)
{
gotDecl = fReaderMgr->skippedString(XMLUni::fgXMLStringSpaceU);
if (gotDecl)
fScanner->emitError(XMLErrs::XMLDeclMustBeLowerCase);
}
if (gotDecl)
{
// If we are not accepting text decls, its an error
if (parseTextDecl)
{
scanTextDecl();
}
else
{
// Emit the error and skip past this markup
fScanner->emitError(XMLErrs::TextDeclNotLegalHere);
fReaderMgr->skipPastChar(chCloseAngle);
}
}
else
{
// It has to be a PI
scanPI();
}
}
else
{
// Can't be valid so emit error and try to skip past end of this decl
fScanner->emitError(XMLErrs::ExpectedMarkupDecl);
fReaderMgr->skipPastChar(chCloseAngle);
}
}
//
// This method is called for a mixed model element's content mode. We've
// already scanned past the '(PCDATA' part by the time we get here. So
// everything else is element names separated by | characters until we
// hit the end. The passed element decl's content model is filled in with
// the information found.
//
bool DTDScanner::scanMixed(DTDElementDecl& toFill)
{
//
// The terminating star is only required if there is something more
// than (PCDATA).
//
bool starRequired = false;
// Get a buffer to be used below to get element names
XMLBufBid bbName(fBufMgr);
XMLBuffer& nameBuf = bbName.getBuffer();
//
// Create an initial content spec node. Its just a leaf node with a
// PCDATA element id. This current node pointer will be pushed down the
// tree as we go.
//
ContentSpecNode* curNode = new ContentSpecNode(XMLElementDecl::fgPCDataElemId);
//
// Set the initial leaf as the temporary head. If we hit the first choice
// node, it will be set up here. When done, this is the node that's set
// as the content spec for the element.
//
ContentSpecNode* headNode = curNode;
// Remember the original node so we can sense the first choice node
ContentSpecNode* orgNode = curNode;
//
// We just loop around, getting the | character at the top and then
// looking for the next element name. We keep up with the last node
// and add each new one to its right node.
//
while (true)
{
//
// First of all we check for some grunt work details of skipping
// whitespace, expand PE refs, and catching invalid reps.
//
if (fReaderMgr->lookingAtChar(chPercent))
{
// Expand it and continue
checkForPERef(false, false, true);
}
else if (fReaderMgr->skippedChar(chAsterisk))
{
//
// Tell them they can't have reps in mixed model, but eat
// it and keep going if we are allowed to.
//
fScanner->emitError(XMLErrs::NoRepInMixed);
}
else if (fReaderMgr->skippedSpace())
{
// Spaces are ok at this point, just eat them and continue
fReaderMgr->skipPastSpaces();
}
else
{
if (!fReaderMgr->skippedChar(chPipe))
{
// Has to be the closing paren now.
if (!fReaderMgr->skippedChar(chCloseParen))
{
fScanner->emitError(XMLErrs::UnterminatedContentModel);
delete headNode;
return false;
}
if (!fReaderMgr->skippedChar(chAsterisk) && starRequired)
fScanner->emitError(XMLErrs::ExpectedAsterisk);
//
// Create a zero or more node and make the original head
// node its first child.
//
headNode = new ContentSpecNode
(
ContentSpecNode::ZeroOrMore
, headNode
, 0
);
// Store the head node as the content spec of the element.
toFill.setContentSpec(headNode);
break;
}
// Its more than just a PCDATA, so an ending star will be required now
starRequired = true;
// Space is legal here so check for a PE ref, but don't require space
checkForPERef(false, false, true);
// Get a name token
if (!fReaderMgr->getName(nameBuf))
{
fScanner->emitError(XMLErrs::ExpectedElementName);
delete headNode;
return false;
}
//
// Create a leaf node for it. If we can find the element id for
// this element, then use it. Else, we have to fault in an element
// decl, marked as created because of being in a content model.
//
unsigned int elemId = fDTDGrammar->getElemId(0, 0, nameBuf.getRawBuffer(), 0);
if (elemId == XMLElementDecl::fgInvalidElemId)
{
DTDElementDecl* decl = new DTDElementDecl(nameBuf.getRawBuffer());
decl->setCreateReason(XMLElementDecl::InContentModel);
elemId = fDTDGrammar->putElemDecl(decl);
}
//
// If the current node is the original node, this is the first choice
// node, so create an initial choice node with the current node and
// the new element id. Store this as the head node.
//
// Otherwise, we have to steal the right node of the previous choice
// and weave in another choice node there, which has the old choice
// as its left and the new leaf as its right.
//
if (curNode == orgNode)
{
curNode = new ContentSpecNode
(
ContentSpecNode::Choice
, curNode
, new ContentSpecNode(elemId)
);
// Remember the top node
headNode = curNode;
}
else
{
ContentSpecNode* oldRight = curNode->orphanSecond();
curNode->setSecond
(
new ContentSpecNode
(
ContentSpecNode::Choice
, oldRight
, new ContentSpecNode(elemId)
)
);
// Make the new right node the current node
curNode = curNode->getSecond();
}
}
}
return true;
}
//
// This method is called when we see a '<!NOTATION' string while scanning
// markup decl. It parses out the notation and its id and stores a new
// notation decl object in the notation decl pool.
//
void DTDScanner::scanNotationDecl()
{
// Space is required here so check for a PE ref, and require space
if (!checkForPERef(true, false, true))
{
fScanner->emitError(XMLErrs::ExpectedWhitespace);
fReaderMgr->skipPastChar(chCloseAngle);
return;
}
//
// And now we get a name, which is the name of the notation. Get a
// buffer for the name.
//
XMLBufBid bbName(fBufMgr);
if (!fReaderMgr->getName(bbName.getBuffer()))
{
fScanner->emitError(XMLErrs::ExpectedNotationName);
fReaderMgr->skipPastChar(chCloseAngle);
return;
}
// If namespaces are enabled, then no colons allowed
if (fScanner->getDoNamespaces())
{
if (XMLString::indexOf(bbName.getRawBuffer(), chColon) != -1)
fScanner->emitError(XMLErrs::ColonNotLegalWithNS);
}
// Space is required here so check for a PE ref, and require space
if (!checkForPERef(true, false, true))
{
fScanner->emitError(XMLErrs::ExpectedWhitespace);
fReaderMgr->skipPastChar(chCloseAngle);
return;
}
//
// And scan an external or public id. We need buffers to use for both
// of these.
//
XMLBufBid bbPubId(fBufMgr);
XMLBufBid bbSysId(fBufMgr);
if (!scanId(bbPubId.getBuffer(), bbSysId.getBuffer(), IDType_Either))
{
fReaderMgr->skipPastChar(chCloseAngle);
return;
}
// We can have an optional space or PE ref here
checkForPERef(false, false, true);
//
// See if it already exists. If so, add it to the notatino decl pool.
// Otherwise, if advanced callbacks are on, create a temp one and
// call out for that one.
//
XMLNotationDecl* decl = fDTDGrammar->getNotationDecl(bbName.getRawBuffer());
bool isIgnoring = (decl != 0);
if (isIgnoring)
{
fScanner->emitError(XMLErrs::NotationAlreadyExists, bbName.getRawBuffer());
}
else
{
// Fill in a new notation declaration and add it to the pool
decl = new XMLNotationDecl
(
bbName.getRawBuffer()
, bbPubId.getRawBuffer()
, bbSysId.getRawBuffer()
);
fDTDGrammar->putNotationDecl(decl);
}
//
// If we have a document type handler, then tell it about this. If we
// are ignoring it, only call out if advanced callbacks are enabled.
//
if (fDocTypeHandler)
{
fDocTypeHandler->notationDecl
(
*decl
, isIgnoring
);
}
// And one more optional space or PE ref
checkForPERef(false, false, true);
// And skip the terminating bracket
if (!fReaderMgr->skippedChar(chCloseAngle))
fScanner->emitError(XMLErrs::UnterminatedNotationDecl);
}
//
// Scans a PI and calls the appropriate callbacks. A PI can happen in either
// the document or the DTD, so it calls the appropriate handler according
// to the fInDocument flag.
//
// At entry we have just scanned the <? part, and need to now start on the
// PI target name.
//
void DTDScanner::scanPI()
{
const XMLCh* namePtr = 0;
const XMLCh* targetPtr = 0;
//
// If there are any spaces here, then warn about it. If we aren't in
// 'first error' mode, then we'll come back and can easily pick up
// again by just skipping them.
//
if (fReaderMgr->lookingAtSpace())
{
fScanner->emitError(XMLErrs::PINameExpected);
fReaderMgr->skipPastSpaces();
}
// Get a buffer for the PI name and scan it in
XMLBufBid bbName(fBufMgr);
if (!fReaderMgr->getNameToken(bbName.getBuffer()))
{
fScanner->emitError(XMLErrs::PINameExpected);
fReaderMgr->skipPastChar(chCloseAngle);
return;
}
// Point the name pointer at the raw data
namePtr = bbName.getRawBuffer();
// See if it issome form of 'xml' and emit a warning
if (!XMLString::compareIString(namePtr, XMLUni::fgXMLString))
fScanner->emitError(XMLErrs::NoPIStartsWithXML);
// If namespaces are enabled, then no colons allowed
if (fScanner->getDoNamespaces())
{
if (XMLString::indexOf(namePtr, chColon) != -1)
fScanner->emitError(XMLErrs::ColonNotLegalWithNS);
}
//
// If we don't hit a space next, then the PI has no target. If we do
// then get out the target. Get a buffer for it as well
//
XMLBufBid bbTarget(fBufMgr);
if (fReaderMgr->skippedSpace())
{
// Skip any leading spaces
fReaderMgr->skipPastSpaces();
// It does have a target, so lets move on to deal with that.
while (1)
{
const XMLCh nextCh = fReaderMgr->getNextChar();
// Watch for an end of file, which is always bad here
if (!nextCh)
{
fScanner->emitError(XMLErrs::UnterminatedPI);
ThrowXML(UnexpectedEOFException, XMLExcepts::Gen_UnexpectedEOF);
}
// Watch for potential terminating character
if (nextCh == chQuestion)
{
// It must be followed by '>' to be a termination of the target
if (fReaderMgr->skippedChar(chCloseAngle))
break;
}
// Watch for invalid chars but try to keep going
if (!XMLReader::isXMLChar(nextCh))
{
XMLCh tmpBuf[9];
XMLString::binToText
(
nextCh
, tmpBuf
, 8
, 16
);
fScanner->emitError(XMLErrs::InvalidCharacter, tmpBuf);
}
bbTarget.append(nextCh);
}
}
else
{
// No target, but make sure its terminated ok
if (!fReaderMgr->skippedChar(chQuestion))
{
fScanner->emitError(XMLErrs::UnterminatedPI);
fReaderMgr->skipPastChar(chCloseAngle);
return;
}
if (!fReaderMgr->skippedChar(chCloseAngle))
{
fScanner->emitError(XMLErrs::UnterminatedPI);
fReaderMgr->skipPastChar(chCloseAngle);
return;
}
}
// Point the target pointer at the raw data
targetPtr = bbTarget.getRawBuffer();
//
// If we have a handler, then call it.
//
if (fDocTypeHandler)
{
fDocTypeHandler->doctypePI
(
namePtr
, targetPtr
);
}
}
//
// This method scans a public literal. It must be quoted and all of its
// characters must be valid public id characters. The quotes are discarded
// and the results are returned.
//
bool DTDScanner::scanPublicLiteral(XMLBuffer& toFill)
{
toFill.reset();
// Get the next char which must be a single or double quote
XMLCh quoteCh;
if (!fReaderMgr->skipIfQuote(quoteCh))
return false;
while (true)
{
const XMLCh nextCh = fReaderMgr->getNextChar();
// Watch for EOF
if (!nextCh)
ThrowXML(UnexpectedEOFException, XMLExcepts::Gen_UnexpectedEOF);
if (nextCh == quoteCh)
break;
//
// If its not a valid public id char, then report it but keep going
// since that's the best recovery scheme.
//
if (!XMLReader::isPublicIdChar(nextCh))
{
XMLCh tmpBuf[9];
XMLString::binToText
(
nextCh
, tmpBuf
, 8
, 16
);
fScanner->emitError(XMLErrs::InvalidPublicIdChar, tmpBuf);
}
toFill.append(nextCh);
}
return true;
}
//
// This method handles scanning in a quoted system literal. It expects to
// start on the open quote and returns after eating the ending quote. There
// are not really any restrictions on the contents of system literals.
//
bool DTDScanner::scanSystemLiteral(XMLBuffer& toFill)
{
toFill.reset();
// Get the next char which must be a single or double quote
XMLCh quoteCh;
if (!fReaderMgr->skipIfQuote(quoteCh))
return false;
bool retVal = true;
while (retVal)
{
const XMLCh nextCh = fReaderMgr->getNextChar();
// Watch for EOF
if (!nextCh)
ThrowXML(UnexpectedEOFException, XMLExcepts::Gen_UnexpectedEOF);
// Break out on terminating quote
if (nextCh == quoteCh)
break;
toFill.append(nextCh);
}
return retVal;
}
//
// This method is called to scan a text decl line, which can be the first
// line in an external entity or external subset.
//
// On entry the <? has been scanned, and next should be 'xml' followed by
// some whitespace, version string, etc...
//
void DTDScanner::scanTextDecl()
{
// Skip any subsequent whitespace before the version string
fReaderMgr->skipPastSpaces();
// Next should be the version string
XMLBufBid bbVersion(fBufMgr);
if (fReaderMgr->skippedString(XMLUni::fgVersionString))
{
if (!scanEq())
{
fScanner->emitError(XMLErrs::ExpectedEqSign);
fReaderMgr->skipPastChar(chCloseAngle);
return;
}
//
// Followed by a single or double quoted version. Get a buffer for
// the string.
//
if (!getQuotedString(bbVersion.getBuffer()))
{
fScanner->emitError(XMLErrs::BadXMLVersion);
fReaderMgr->skipPastChar(chCloseAngle);
return;
}
// If its not our supported version, issue an error but continue
if (XMLString::compareString(bbVersion.getRawBuffer(), XMLUni::fgSupportedVersion))
fScanner->emitError(XMLErrs::UnsupportedXMLVersion, bbVersion.getRawBuffer());
}
// Ok, now we can have an encoding string, but we don't have to
XMLBufBid bbEncoding(fBufMgr);
fReaderMgr->skipPastSpaces();
bool gotEncoding = false;
if (fReaderMgr->skippedString(XMLUni::fgEncodingString))
{
// There must be a equal sign next
if (!scanEq())
{
fScanner->emitError(XMLErrs::ExpectedEqSign);
fReaderMgr->skipPastChar(chCloseAngle);
return;
}
// Followed by a single or double quoted version string
getQuotedString(bbEncoding.getBuffer());
if (bbEncoding.isEmpty())
{
fScanner->emitError(XMLErrs::BadXMLEncoding, bbEncoding.getRawBuffer());
fReaderMgr->skipPastChar(chCloseAngle);
return;
}
// Indicate that we got an encoding
gotEncoding = true;
}
//
// [78] Encoding declarations are required in the external entity
// if there is a text declaration present
//
if (!fInternalSubset && !gotEncoding)
{
fScanner->emitError(XMLErrs::BadXMLEncoding);
fReaderMgr->skipPastChar(chCloseAngle);
return;
}
fReaderMgr->skipPastSpaces();
if (!fReaderMgr->skippedChar(chQuestion))
{
fScanner->emitError(XMLErrs::UnterminatedXMLDecl);
fReaderMgr->skipPastChar(chCloseAngle);
}
else if (!fReaderMgr->skippedChar(chCloseAngle))
{
fScanner->emitError(XMLErrs::UnterminatedXMLDecl);
fReaderMgr->skipPastChar(chCloseAngle);
}
//
// If we have a document type handler and advanced callbacks are on,
// then call the TextDecl callback
//
if (fDocTypeHandler)
{
fDocTypeHandler->TextDecl
(
bbVersion.getRawBuffer()
, bbEncoding.getRawBuffer()
);
}
//
// If we got an encoding string, then we have to call back on the reader
// to tell it what the encoding is.
//
if (!bbEncoding.isEmpty())
{
if (!fReaderMgr->getCurrentReader()->setEncoding(bbEncoding.getRawBuffer()))
fScanner->emitError(XMLErrs::ContradictoryEncoding, bbEncoding.getRawBuffer());
}
}
1.1 xml-xerces/c/src/validators/DTD/DTDScanner.hpp
Index: DTDScanner.hpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Log: DTDScanner.hpp,v $
* Revision 1.1 2001/03/21 21:56:20 tng
* Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
*
*/
#if !defined(DTDSCANNER_HPP)
#define DTDSCANNER_HPP
#include <validators/DTD/DTDGrammar.hpp>
/*
* Default implementation of an XML DTD scanner.
*/
class DocTypeHandler;
class VALIDATORS_EXPORT DTDScanner
{
public:
// -----------------------------------------------------------------------
// Class specific types
//
// NOTE: This should really be private, but some of the compilers we
// have to support cannot understand that.
//
// EntityExpRes
// Returned from scanEntityRef() to indicate how the expanded text
// was treated.
// -----------------------------------------------------------------------
enum EntityExpRes
{
EntityExp_Failed
, EntityExp_Pushed
, EntityExp_Returned
};
// -----------------------------------------------------------------------
// Constructors and Destructor
// -----------------------------------------------------------------------
DTDScanner(DTDGrammar* dtdGrammar, DocTypeHandler* const docTypeHandler);
virtual ~DTDScanner();
// -----------------------------------------------------------------------
// Getter methods
// -----------------------------------------------------------------------
DocTypeHandler* getDocTypeHandler();
const DocTypeHandler* getDocTypeHandler() const;
// -----------------------------------------------------------------------
// Setter methods
//
// setScannerInfo() is called by the scanner to tell the DTDScanner
// about the stuff it needs to have access to.
// -----------------------------------------------------------------------
void setScannerInfo
(
XMLScanner* const owningScanner
, ReaderMgr* const readerMgr
, XMLBufferMgr* const bufMgr
);
void setDocTypeHandler
(
DocTypeHandler* const handlerToSet
);
void scanDocTypeDecl(const bool reuseGrammar);
private:
// -----------------------------------------------------------------------
// Private class types
// -----------------------------------------------------------------------
enum IDTypes
{
IDType_Public
, IDType_External
, IDType_Either
};
// -----------------------------------------------------------------------
// Private DTD scanning methods. These are all in XMLValidator2.cpp
// -----------------------------------------------------------------------
bool checkForPERef
(
const bool spaceRequired
, const bool inLiteral
, const bool inMarkup
, const bool throwEndOfExt = false
);
bool expandPERef
(
const bool scanExternal
, const bool inLiteral
, const bool inMarkup
, const bool throwEndOfExt = false
);
bool getQuotedString(XMLBuffer& toFill);
XMLAttDef* scanAttDef(DTDElementDecl& elemDecl, XMLBuffer& bufToUse);
bool scanAttValue
(
const XMLCh* const attrName
, XMLBuffer& toFill
, const XMLAttDef::AttTypes type
);
void scanAttListDecl();
ContentSpecNode* scanChildren
(
const DTDElementDecl& elemDecl
, XMLBuffer& bufToUse
);
bool scanCharRef(XMLCh& toFill, XMLCh& second);
void scanComment();
bool scanContentSpec(DTDElementDecl& toFill);
void scanDefaultDecl(DTDAttDef& toFill);
void scanElementDecl();
void scanEntityDecl();
bool scanEntityDef();
bool scanEntityLiteral(XMLBuffer& toFill, const bool isPE);
bool scanEntityDef(DTDEntityDecl& decl, const bool isPEDecl);
EntityExpRes scanEntityRef(XMLCh& firstCh, XMLCh& secondCh, bool& escaped);
bool scanEnumeration
(
const DTDAttDef& attDef
, XMLBuffer& toFill
, const bool notation
);
bool scanEq();
void scanExtSubsetDecl(const bool inIncludeSect);
bool scanId
(
XMLBuffer& pubIdToFill
, XMLBuffer& sysIdToFill
, const IDTypes whatKind
);
void scanIgnoredSection();
bool scanInternalSubset();
void scanMarkupDecl(const bool parseTextDecl);
bool scanMixed(DTDElementDecl& toFill);
void scanNotationDecl();
void scanPI();
bool scanPublicLiteral(XMLBuffer& toFill);
bool scanSystemLiteral(XMLBuffer& toFill);
void scanTextDecl();
// -----------------------------------------------------------------------
// Private data members
//
// fDocTypeHandler
// This holds the optional doc type handler that can be installed
// and used to call back for all markup events. It is DTD specific.
//
// fDumAttDef
// fDumElemDecl
// fDumEntityDecl
// These are dummy objects into which mark decls are parsed when
// they are just overrides of previously declared markup decls. In
// such situations, the first one wins but we need to have somewhere
// to parse them into. So these are lazily created and used as needed
// when such markup decls are seen.
//
// fInternalSubset
// This is used to track whether we are in the internal subset or not,
// in which case we are in the external subset.
//
// fNextAttrId
// Since att defs are per-element, we don't have a validator wide
// attribute def pool. So we use a simpler data structure in each
// element decl to store its att defs, and we use this simple counter
// to apply a unique id to each new attribute.
//
// fDTDGrammar
// The DTD information we scanned like element decl, attribute decl
// are stored in this Grammar.
//
// fBufMgr
// This is the buffer manager of the scanner. This is provided as a
// convenience so that the DTDScanner doesn't have to create its own
// buffer manager during the parse process.
//
// fReaderMgr
// This is a pointer to the reader manager that is being used by the scanner.
//
// fScanner
// The pointer to the scanner to which this DTDScanner belongs
//
// fPEntityDeclPool
// This is a pool of EntityDecl objects, which contains all of the
// parameter entities that are declared in the DTD subsets.
// -----------------------------------------------------------------------
DocTypeHandler* fDocTypeHandler;
DTDAttDef* fDumAttDef;
DTDElementDecl* fDumElemDecl;
DTDEntityDecl* fDumEntityDecl;
bool fInternalSubset;
unsigned int fNextAttrId;
DTDGrammar* fDTDGrammar;
XMLBufferMgr* fBufMgr;
ReaderMgr* fReaderMgr;
XMLScanner* fScanner;
NameIdPool<DTDEntityDecl>* fPEntityDeclPool;
};
// ---------------------------------------------------------------------------
// DTDScanner: Getter methods
// ---------------------------------------------------------------------------
inline DocTypeHandler* DTDScanner::getDocTypeHandler()
{
return fDocTypeHandler;
}
inline const DocTypeHandler* DTDScanner::getDocTypeHandler() const
{
return fDocTypeHandler;
}
// ---------------------------------------------------------------------------
// DTDScanner: Setter methods
// ---------------------------------------------------------------------------
inline void DTDScanner::setDocTypeHandler(DocTypeHandler* const handlerToSet)
{
fDocTypeHandler = handlerToSet;
}
// -----------------------------------------------------------------------
// Setter methods
// -----------------------------------------------------------------------
inline void DTDScanner::setScannerInfo(XMLScanner* const owningScanner
, ReaderMgr* const readerMgr
, XMLBufferMgr* const bufMgr)
{
// We don't own any of these, we just reference them
fScanner = owningScanner;
fReaderMgr = readerMgr;
fBufMgr = bufMgr;
}
#endif
1.3 +12 -12 xml-xerces/c/src/validators/common/ContentSpecNode.cpp
Index: ContentSpecNode.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/validators/common/ContentSpecNode.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ContentSpecNode.cpp 2001/02/16 14:58:57 1.2
+++ ContentSpecNode.cpp 2001/03/21 21:56:25 1.3
@@ -55,7 +55,7 @@
*/
/*
- * $Id: ContentSpecNode.cpp,v 1.2 2001/02/16 14:58:57 tng Exp $
+ * $Id: ContentSpecNode.cpp,v 1.3 2001/03/21 21:56:25 tng Exp $
*/
@@ -77,7 +77,7 @@
// ---------------------------------------------------------------------------
static void formatNode( const ContentSpecNode* const curNode
, const ContentSpecNode::NodeTypes parentType
- , const XMLValidator& validator
+ , const Grammar& grammar
, XMLBuffer& bufToFill)
{
const ContentSpecNode* first = curNode->getFirst();
@@ -108,13 +108,13 @@
if (tmpVal == XMLElementDecl::fgPCDataElemId)
bufToFill.append(XMLElementDecl::fgPCDataElemName);
else
- bufToFill.append(validator.getElemDecl(tmpVal)->getFullName());
+ bufToFill.append(grammar.getElemDecl(tmpVal)->getFullName());
break;
case ContentSpecNode::ZeroOrOne :
if (doRepParens)
bufToFill.append(chOpenParen);
- formatNode(first, curType, validator, bufToFill);
+ formatNode(first, curType, grammar, bufToFill);
if (doRepParens)
bufToFill.append(chCloseParen);
bufToFill.append(chQuestion);
@@ -123,7 +123,7 @@
case ContentSpecNode::ZeroOrMore :
if (doRepParens)
bufToFill.append(chOpenParen);
- formatNode(first, curType, validator, bufToFill);
+ formatNode(first, curType, grammar, bufToFill);
if (doRepParens)
bufToFill.append(chCloseParen);
bufToFill.append(chAsterisk);
@@ -132,7 +132,7 @@
case ContentSpecNode::OneOrMore :
if (doRepParens)
bufToFill.append(chOpenParen);
- formatNode(first, curType, validator, bufToFill);
+ formatNode(first, curType, grammar, bufToFill);
if (doRepParens)
bufToFill.append(chCloseParen);
bufToFill.append(chPlus);
@@ -141,9 +141,9 @@
case ContentSpecNode::Choice :
if (parentType != curType)
bufToFill.append(chOpenParen);
- formatNode(first, curType, validator, bufToFill);
+ formatNode(first, curType, grammar, bufToFill);
bufToFill.append(chPipe);
- formatNode(second, curType, validator, bufToFill);
+ formatNode(second, curType, grammar, bufToFill);
if (parentType != curType)
bufToFill.append(chCloseParen);
break;
@@ -151,9 +151,9 @@
case ContentSpecNode::Sequence :
if (parentType != curType)
bufToFill.append(chOpenParen);
- formatNode(first, curType, validator, bufToFill);
+ formatNode(first, curType, grammar, bufToFill);
bufToFill.append(chComma);
- formatNode(second, curType, validator, bufToFill);
+ formatNode(second, curType, grammar, bufToFill);
if (parentType != curType)
bufToFill.append(chCloseParen);
break;
@@ -164,7 +164,7 @@
// ---------------------------------------------------------------------------
// ContentSpecNode: Miscellaneous
// ---------------------------------------------------------------------------
-void ContentSpecNode::formatSpec(const XMLValidator& validator
+void ContentSpecNode::formatSpec(const Grammar& grammar
, XMLBuffer& bufToFill) const
{
// Clean out the buffer first
@@ -176,7 +176,7 @@
(
this
, UnknownType
- , validator
+ , grammar
, bufToFill
);
if (fType == ContentSpecNode::Leaf)
1.3 +35 -10 xml-xerces/c/src/validators/common/ContentSpecNode.hpp
Index: ContentSpecNode.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/validators/common/ContentSpecNode.hpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ContentSpecNode.hpp 2001/02/27 14:48:49 1.2
+++ ContentSpecNode.hpp 2001/03/21 21:56:26 1.3
@@ -56,6 +56,9 @@
/*
* $Log: ContentSpecNode.hpp,v $
+ * Revision 1.3 2001/03/21 21:56:26 tng
+ * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+ *
* Revision 1.2 2001/02/27 14:48:49 tng
* Schema: Add CMAny and ContentLeafNameTypeVector, by Pei Yong Zhang
*
@@ -90,7 +93,7 @@
#include <util/XercesDefs.hpp>
class XMLBuffer;
-class XMLValidator;
+class Grammar;
class ContentSpecNode
@@ -101,7 +104,7 @@
// -----------------------------------------------------------------------
enum NodeTypes
{
- Leaf
+ Leaf = 0
, ZeroOrOne
, ZeroOrMore
, OneOrMore
@@ -109,13 +112,13 @@
, Sequence
, Any
, Any_Other
- , Any_Local
- , Any_Lax
- , Any_Other_Lax
- , Any_Local_Lax
- , Any_Skip
- , Any_Other_Skip
- , Any_Local_Skip
+ , Any_Local = 8
+ , Any_Lax = 22
+ , Any_Other_Lax = 23
+ , Any_Local_Lax = 24
+ , Any_Skip = 38
+ , Any_Other_Skip = 39
+ , Any_Local_Skip = 40
, UnknownType = -1
};
@@ -150,6 +153,7 @@
bool isPCData() const;
ContentSpecNode* orphanFirst();
ContentSpecNode* orphanSecond();
+ int getURI() const;
// -----------------------------------------------------------------------
@@ -159,6 +163,7 @@
void setFirst(ContentSpecNode* const toAdopt);
void setSecond(ContentSpecNode* const toAdopt);
void setType(const NodeTypes type);
+ void setURI(const int URIId);
// -----------------------------------------------------------------------
@@ -166,7 +171,7 @@
// -----------------------------------------------------------------------
void formatSpec
(
- const XMLValidator& validator
+ const Grammar& grammar
, XMLBuffer& bufToFill
) const;
@@ -193,15 +198,20 @@
// Leaf = Neither valid
// ZeroOrOne, ZeroOrMore = First
// Choice, Sequence = First and Second
+ // Any* = Neither valid
//
// fType
// The type of node. This controls how many of the child node fields
// are used.
+ //
+ // fURI
+ // When type == Any* case, we need to store the URI id attribute
// -----------------------------------------------------------------------
unsigned int fElemId;
ContentSpecNode* fFirst;
ContentSpecNode* fSecond;
NodeTypes fType;
+ int fURI;
};
@@ -214,6 +224,7 @@
, fFirst(0)
, fSecond(0)
, fType(ContentSpecNode::Leaf)
+ , fURI(-1)
{
}
@@ -224,6 +235,7 @@
, fFirst(0)
, fSecond(0)
, fType(ContentSpecNode::Leaf)
+ , fURI(-1)
{
}
@@ -236,6 +248,7 @@
, fFirst(firstToAdopt)
, fSecond(secondToAdopt)
, fType(type)
+ , fURI(-1)
{
}
@@ -258,6 +271,7 @@
fSecond = 0;
fType = toCopy.getType();
+ fURI = toCopy.getURI();
}
inline ContentSpecNode::~ContentSpecNode()
@@ -293,6 +307,7 @@
fSecond = 0;
fType = toAssign.getType();
+ fURI = toAssign.getURI();
return *this;
}
@@ -383,6 +398,11 @@
return retNode;
}
+inline int ContentSpecNode::getURI() const
+{
+ return fURI;
+}
+
// ---------------------------------------------------------------------------
// ContentSpecType: Setter methods
@@ -407,6 +427,11 @@
inline void ContentSpecNode::setType(const NodeTypes type)
{
fType = type;
+}
+
+inline void ContentSpecNode::setURI(const int URIId)
+{
+ fURI = URIId;
}
#endif
1.6 +61 -49 xml-xerces/c/src/validators/common/DFAContentModel.cpp
Index: DFAContentModel.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/validators/common/DFAContentModel.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- DFAContentModel.cpp 2001/03/21 19:29:51 1.5
+++ DFAContentModel.cpp 2001/03/21 21:56:27 1.6
@@ -56,6 +56,9 @@
/*
* $Log: DFAContentModel.cpp,v $
+ * Revision 1.6 2001/03/21 21:56:27 tng
+ * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+ *
* Revision 1.5 2001/03/21 19:29:51 tng
* Schema: Content Model Updates, by Pei Yong Zhang.
*
@@ -103,7 +106,6 @@
// Includes
// ---------------------------------------------------------------------------
#include <util/RuntimeException.hpp>
-#include <framework/XMLValidator.hpp>
#include <framework/XMLElementDecl.hpp>
#include <validators/common/CMAny.hpp>
#include <validators/common/CMBinaryOp.hpp>
@@ -111,6 +113,7 @@
#include <validators/common/CMUnaryOp.hpp>
#include <validators/common/DFAContentModel.hpp>
#include <validators/common/ContentSpecNode.hpp>
+#include <validators/common/Grammar.hpp>
#include <util/RefHashTableOf.hpp>
// ---------------------------------------------------------------------------
@@ -135,13 +138,13 @@
// ---------------------------------------------------------------------------
// DFAContentModel: Constructors and Destructor
// ---------------------------------------------------------------------------
-DFAContentModel::DFAContentModel(const XMLElementDecl& elemDecl,
- XMLValidator *pValidator,
- bool dtd) :
+DFAContentModel::DFAContentModel(const XMLElementDecl& elemDecl
+ , Grammar* grammar
+ , bool dtd) :
fElemDecl(elemDecl)
, fElemMap(0)
- , fElemMapType(0)
+ , fElemMapType(0)
, fElemMapSize(0)
, fEmptyOk(false)
, fEOCPos(0)
@@ -153,9 +156,9 @@
, fSpecNode(0)
, fTransTable(0)
, fTransTableSize(0)
- , fDTD(dtd)
- , fLeafNameTypeVector(0)
- , fValidator(pValidator)
+ , fDTD(dtd)
+ , fLeafNameTypeVector(0)
+ , fGrammar(grammar)
{
//
// Store away our content spec node. This is used all over the place
@@ -191,7 +194,7 @@
int
DFAContentModel::validateContent( const unsigned int* childIds
, const unsigned int childCount
- , const XMLValidator *pValidator) const
+ , const Grammar* grammar) const
{
//
// If there are no children, then either we fail on the 0th element
@@ -200,8 +203,10 @@
//
if (!childCount)
{
- if (fEmptyOk)
- return XMLValidator::Success;
+ if (fEmptyOk) {
+ // success
+ return -1;
+ }
return 0;
}
@@ -223,49 +228,55 @@
for (; elemIndex < fElemMapSize; elemIndex++)
{
if (fDTD)
- {
- if (fElemMap[elemIndex] == curElem)
- break;
+ {
+ if (fElemMap[elemIndex] == curElem) {
+ nextState = fTransTable[curState][elemIndex];
+ if (nextState != gInvalidTrans)
+ break;
+ }
}
else
{
ContentSpecNode::NodeTypes type = fElemMapType[elemIndex];
- if (type == ContentSpecNode::Leaf)
+ if (type == ContentSpecNode::Leaf)
{
- if (fElemMap[elemIndex]==curElem)
- break;
+ if (fElemMap[elemIndex]==curElem) {
+ nextState = fTransTable[curState][elemIndex];
+ if (nextState != gInvalidTrans)
+ break;
+ }
}
else if (type == ContentSpecNode::Any)
{
- const XMLElementDecl* elemDecl = pValidator->getElemDecl(fElemMap[elemIndex]);
+ const XMLElementDecl* elemDecl = grammar->getElemDecl(fElemMap[elemIndex]);
const int uri = elemDecl->getURI();
- const XMLElementDecl* elemDecl2 = pValidator->getElemDecl(curElem);
+ const XMLElementDecl* elemDecl2 = grammar->getElemDecl(curElem);
if (uri == -1 || uri == elemDecl2->getURI())
{
nextState = fTransTable[curState][elemIndex];
- if (nextState != gInvalidTrans)
+ if (nextState != gInvalidTrans)
break;
}
}
else if (type == ContentSpecNode::Any_Local)
{
- const XMLElementDecl* elemDecl = pValidator->getElemDecl(fElemMap[elemIndex]);
+ const XMLElementDecl* elemDecl = grammar->getElemDecl(fElemMap[elemIndex]);
if (elemDecl->getURI() == -1)
{
nextState = fTransTable[curState][elemIndex];
- if (nextState != gInvalidTrans)
+ if (nextState != gInvalidTrans)
break;
}
}
- else if (type == ContentSpecNode::Any_Other)
+ else if (type == ContentSpecNode::Any_Other)
{
- const XMLElementDecl* elemDecl = pValidator->getElemDecl(fElemMap[elemIndex]);
- const XMLElementDecl* elemDecl2 = pValidator->getElemDecl(curElem);
+ const XMLElementDecl* elemDecl = grammar->getElemDecl(fElemMap[elemIndex]);
+ const XMLElementDecl* elemDecl2 = grammar->getElemDecl(curElem);
if ( elemDecl->getURI() != elemDecl2->getURI())
{
nextState = fTransTable[curState][elemIndex];
- if (nextState != gInvalidTrans)
+ if (nextState != gInvalidTrans)
break;
}
}
@@ -273,15 +284,15 @@
}
}//for elemIndex
- // If "nextState" is -1, we found a match, but the transition is invalid
- if (nextState == gInvalidTrans)
+ // If "nextState" is -1, we found a match, but the transition is invalid
+ if (nextState == gInvalidTrans)
return childIndex;
// If we didn't find it, then obviously not valid
if (elemIndex == fElemMapSize)
return childIndex;
- curState = nextState;
+ curState = nextState;
nextState = 0;
}//for childIndex
@@ -294,7 +305,8 @@
if (!fFinalStateFlags[curState])
return childIndex;
- return XMLValidator::Success;
+ //success
+ return -1;
}
@@ -409,8 +421,8 @@
for (unsigned int outIndex = 0; outIndex < fLeafCount; outIndex++)
{
- if ( (fLeafListType[outIndex] & 0x0f) != ContentSpecNode::Leaf )
- if (fLeafNameTypeVector == 0)
+ if ( (fLeafListType[outIndex] & 0x0f) != ContentSpecNode::Leaf )
+ if (fLeafNameTypeVector == 0)
fLeafNameTypeVector = new ContentLeafNameTypeVector();
// Get the current leaf's element index
@@ -443,9 +455,9 @@
fLeafNameTypeVector->setValues(fElemMap, fElemMapType, fElemMapSize);
}
- /***
- * Optimization(Jan, 2001); We sort fLeafList according to
- * elemIndex which is *uniquely* associated to each leaf.
+ /***
+ * Optimization(Jan, 2001); We sort fLeafList according to
+ * elemIndex which is *uniquely* associated to each leaf.
* We are *assuming* that each element appears in at least one leaf.
**/
// don't forget to delete it
@@ -456,13 +468,13 @@
for (unsigned int elemIndex = 0; elemIndex < fElemMapSize; elemIndex++)
{
element = fElemMap[elemIndex];
- for (unsigned int leafIndex = 0; leafIndex < fLeafCount; leafIndex++)
+ for (unsigned int leafIndex = 0; leafIndex < fLeafCount; leafIndex++)
{
if (element == fLeafList[leafIndex]->getId())
fLeafSorter[fSortCount++] = leafIndex;
}
fLeafSorter[fSortCount++] = -1;
- }
+ }
//
// Next lets create some arrays, some that that hold transient info
@@ -934,38 +946,38 @@
(curType == ContentSpecNode::Any_Other) )
{
- // The following discussion apply to node of type
+ // The following discussion apply to node of type
// Any, Any_Local, Any_Other only
//
// In buildSyntaxTree(), we convert a node from ContentSpecNode to
// a CMAny, and lost the ElementId (compared to CMLeaf).
//
- // Here, we need to create a CMLeaf node out of a CMAny node, we need
+ // Here, we need to create a CMLeaf node out of a CMAny node, we need
// the ElementId.
//
- // There are two twys to overcome this, one is to add an elementId
+ // There are two twys to overcome this, one is to add an elementId
// data member into CMAny and retain this info when we construct a
// CMAny out of ContentSpecNode.
// But when we create fElemMap from fLeafList, we will have
- // multiple entries for nodes who share the same URI. This is contradict
+ // multiple entries for nodes who share the same URI. This is contradict
// to XML4J.
//
- // The second way, is to create a common pseudo elementDecl for nodes of
+ // The second way, is to create a common pseudo elementDecl for nodes of
// the same URI, therefore, we won't have multiple entries problem.
// create a pseudo elementDecl if necessary
// obtain the elementId
bool wasAdded;
- XMLElementDecl* elemDecl = fValidator->findElemDecl
- ( static_cast<CMAny*>(nodeCur)->getURI()
+ XMLElementDecl* elemDecl = fGrammar->findOrAddElemDecl
+ ( ((CMAny*)nodeCur)->getURI()
+ , 0
, 0
, 0
, 0
- , XMLValidator::AddIfNotFound
, wasAdded
);
- fLeafList[newIndex] = new CMLeaf(elemDecl->getId(), static_cast<CMAny*>(nodeCur)->getPosition());
+ fLeafList[newIndex] = new CMLeaf(elemDecl->getId(), ((CMAny*)nodeCur)->getPosition());
fLeafListType[newIndex] = curType;
++newIndex;
}
@@ -975,8 +987,8 @@
newIndex = postTreeBuildInit(((CMBinaryOp*)nodeCur)->getLeft(), newIndex);
newIndex = postTreeBuildInit(((CMBinaryOp*)nodeCur)->getRight(), newIndex);
}
- else if (curType == ContentSpecNode::ZeroOrMore ||
- curType == ContentSpecNode::ZeroOrOne ||
+ else if (curType == ContentSpecNode::ZeroOrMore ||
+ curType == ContentSpecNode::ZeroOrOne ||
curType == ContentSpecNode::OneOrMore)
{
newIndex = postTreeBuildInit(((CMUnaryOp*)nodeCur)->getChild(), newIndex);
@@ -1004,7 +1016,7 @@
int
DFAContentModel::validateContentSpecial( const unsigned int* childIds
, const unsigned int childCount
- , const XMLValidator *pValidator) const
+ , const Grammar* grammar) const
{
return 0;
};
1.5 +18 -15 xml-xerces/c/src/validators/common/DFAContentModel.hpp
Index: DFAContentModel.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/validators/common/DFAContentModel.hpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- DFAContentModel.hpp 2001/03/21 19:29:55 1.4
+++ DFAContentModel.hpp 2001/03/21 21:56:27 1.5
@@ -56,6 +56,9 @@
/*
* $Log: DFAContentModel.hpp,v $
+ * Revision 1.5 2001/03/21 21:56:27 tng
+ * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+ *
* Revision 1.4 2001/03/21 19:29:55 tng
* Schema: Content Model Updates, by Pei Yong Zhang.
*
@@ -120,8 +123,8 @@
// Constructors and Destructor
// -----------------------------------------------------------------------
DFAContentModel(const XMLElementDecl& elemDecl
- , XMLValidator *pValidator = 0
- , bool dtd = true);
+ , Grammar* grammar =0
+ , bool dtd = true);
virtual ~DFAContentModel();
@@ -130,18 +133,18 @@
// -----------------------------------------------------------------------
virtual bool getIsAmbiguous() const;
- virtual int validateContent
+ virtual int validateContent
(
const unsigned int* childIds
, const unsigned int childCount
- , const XMLValidator *pValidator = 0
+ , const Grammar* grammar = 0
) const;
- virtual int validateContentSpecial
+ virtual int validateContentSpecial
(
const unsigned int* childIds
, const unsigned int childCount
- , const XMLValidator *pValidator = 0
+ , const Grammar* grammar = 0
) const;
virtual ContentLeafNameTypeVector* getContentLeafNameTypeVector() const ;
@@ -189,7 +192,7 @@
// actual validation.
//
// fElemMapType
- // This is a map of whether the element map contains information
+ // This is a map of whether the element map contains information
// related to ANY models.
//
// fEmptyOk
@@ -236,7 +239,7 @@
// the actually leaf list array itself needs cleanup.
//
// fLeafListType
- // Array mapping ANY types to the leaf list.
+ // Array mapping ANY types to the leaf list.
//
// fSpecNode
// The content spec node for the element that this object represents
@@ -262,13 +265,13 @@
// fDTD;
// Boolean to allow DTDs to validate even with namespace support.
//
- // fValidator
- // instead of passing the validator pointer round, we save it here
- //
+ // fGrammar
+ // A pointer to the Grammar
+ //
// -----------------------------------------------------------------------
const XMLElementDecl& fElemDecl;
unsigned int* fElemMap;
- ContentSpecNode::NodeTypes *fElemMapType;
+ ContentSpecNode::NodeTypes *fElemMapType;
unsigned int fElemMapSize;
bool fEmptyOk;
unsigned int fEOCPos;
@@ -278,13 +281,13 @@
bool fIsAmbiguous;
unsigned int fLeafCount;
CMLeaf** fLeafList;
- ContentSpecNode::NodeTypes *fLeafListType;
+ ContentSpecNode::NodeTypes *fLeafListType;
const ContentSpecNode* fSpecNode;
unsigned int** fTransTable;
unsigned int fTransTableSize;
bool fDTD;
- ContentLeafNameTypeVector *fLeafNameTypeVector;
- XMLValidator *fValidator;
+ ContentLeafNameTypeVector *fLeafNameTypeVector;
+ Grammar* fGrammar;
};
1.3 +6 -0 xml-xerces/c/src/validators/common/Makefile.in
Index: Makefile.in
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/validators/common/Makefile.in,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Makefile.in 2001/02/27 14:48:53 1.2
+++ Makefile.in 2001/03/21 21:56:28 1.3
@@ -54,6 +54,9 @@
# <http://www.apache.org/>.
#
# $Log: Makefile.in,v $
+# Revision 1.3 2001/03/21 21:56:28 tng
+# Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+#
# Revision 1.2 2001/02/27 14:48:53 tng
# Schema: Add CMAny and ContentLeafNameTypeVector, by Pei Yong Zhang
#
@@ -91,6 +94,8 @@
ContentLeafNameTypeVector.hpp \
ContentSpecNode.hpp \
DFAContentModel.hpp \
+ Grammar.hpp \
+ GrammarResolver.hpp \
MixedContentModel.hpp \
SimpleContentModel.hpp
@@ -105,6 +110,7 @@
ContentLeafNameTypeVector.$(TO) \
ContentSpecNode.$(TO) \
DFAContentModel.$(TO) \
+ GrammarResolver.$(TO) \
MixedContentModel.$(TO) \
SimpleContentModel.$(TO)
1.6 +26 -22 xml-xerces/c/src/validators/common/MixedContentModel.cpp
Index: MixedContentModel.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/validators/common/MixedContentModel.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- MixedContentModel.cpp 2001/03/21 19:29:57 1.5
+++ MixedContentModel.cpp 2001/03/21 21:56:28 1.6
@@ -56,6 +56,9 @@
/*
* $Log: MixedContentModel.cpp,v $
+ * Revision 1.6 2001/03/21 21:56:28 tng
+ * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+ *
* Revision 1.5 2001/03/21 19:29:57 tng
* Schema: Content Model Updates, by Pei Yong Zhang.
*
@@ -102,10 +105,10 @@
#include <string.h>
#include <util/RuntimeException.hpp>
#include <framework/XMLElementDecl.hpp>
-#include <framework/XMLValidator.hpp>
#include <validators/common/ContentSpecNode.hpp>
#include <validators/common/MixedContentModel.hpp>
#include <validators/common/CMStateSet.hpp>
+#include <validators/common/Grammar.hpp>
// ---------------------------------------------------------------------------
@@ -244,7 +247,7 @@
int
MixedContentModel::validateContent( const unsigned int* childIds
, const unsigned int childCount
- , const XMLValidator *pValidator) const
+ , const Grammar* grammar) const
{
// must match order
if (fOrdered) {
@@ -268,9 +271,9 @@
}
else if (type == ContentSpecNode::Any) {
- const XMLElementDecl* elemDecl = pValidator->getElemDecl(inChild);
+ const XMLElementDecl* elemDecl = grammar->getElemDecl(inChild);
const int uri = elemDecl->getURI();
- const XMLElementDecl* elemDecl2 = pValidator->getElemDecl(curChild);
+ const XMLElementDecl* elemDecl2 = grammar->getElemDecl(curChild);
if ((uri != -1 ) &&
(uri != elemDecl2->getURI()))
{
@@ -279,15 +282,15 @@
}
else if (type == ContentSpecNode::Any_Local) {
- const XMLElementDecl* elemDecl = pValidator->getElemDecl(inChild);
+ const XMLElementDecl* elemDecl = grammar->getElemDecl(inChild);
if (elemDecl->getURI() != -1) {
return outIndex;
}
}
else if (type == ContentSpecNode::Any_Other) {
- const XMLElementDecl* elemDecl = pValidator->getElemDecl(inChild);
- const XMLElementDecl* elemDecl2 = pValidator->getElemDecl(curChild);
+ const XMLElementDecl* elemDecl = grammar->getElemDecl(inChild);
+ const XMLElementDecl* elemDecl2 = grammar->getElemDecl(curChild);
if (elemDecl->getURI() == elemDecl2->getURI()) {
return outIndex;
}
@@ -327,9 +330,9 @@
}
else if (type == ContentSpecNode::Any) {
- const XMLElementDecl* elemDecl = pValidator->getElemDecl(fChildIds[inIndex]);
+ const XMLElementDecl* elemDecl = grammar->getElemDecl(fChildIds[inIndex]);
const int uri = elemDecl->getURI();
- const XMLElementDecl* elemDecl2 = pValidator->getElemDecl(curChild);
+ const XMLElementDecl* elemDecl2 = grammar->getElemDecl(curChild);
if (uri == -1 || uri == elemDecl2->getURI()) {
break;
@@ -337,32 +340,33 @@
}
else if (type == ContentSpecNode::Any_Local) {
- const XMLElementDecl* elemDecl = pValidator->getElemDecl(fChildIds[inIndex]);
+ const XMLElementDecl* elemDecl = grammar->getElemDecl(fChildIds[inIndex]);
if (elemDecl->getURI() == -1) {
break;
}
}
else if (type == ContentSpecNode::Any_Other) {
- const XMLElementDecl* elemDecl = pValidator->getElemDecl(fChildIds[inIndex]);
- const XMLElementDecl* elemDecl2 = pValidator->getElemDecl(curChild);
+ const XMLElementDecl* elemDecl = grammar->getElemDecl(fChildIds[inIndex]);
+ const XMLElementDecl* elemDecl2 = grammar->getElemDecl(curChild);
if ( elemDecl->getURI() != elemDecl2->getURI()) {
break;
}
- }
+ }
// REVISIT: What about checking for multiple ANY matches?
// The content model ambiguity *could* be checked
// by the caller before constructing the mixed
// content model.
- }
+ }
// We did not find this one, so the validation failed
- if (inIndex == fCount)
- return outIndex;
- }
- }
+ if (inIndex == fCount)
+ return outIndex;
+ }
+ }
- // Everything seems to be in order, so return success
- return XMLValidator::Success;
+ // Everything seems to be in order, so return success
+ // success
+ return -1;
}
@@ -415,9 +419,9 @@
int MixedContentModel::validateContentSpecial( const unsigned int* childIds
, const unsigned int childCount
- , const XMLValidator *pValidator) const
+ , const Grammar* grammar) const
{
- return validateContent(childIds, childCount, pValidator);
+ return validateContent(childIds, childCount, grammar);
};
ContentLeafNameTypeVector* MixedContentModel::getContentLeafNameTypeVector() const
1.5 +5 -2 xml-xerces/c/src/validators/common/MixedContentModel.hpp
Index: MixedContentModel.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/validators/common/MixedContentModel.hpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- MixedContentModel.hpp 2001/03/21 19:29:58 1.4
+++ MixedContentModel.hpp 2001/03/21 21:56:28 1.5
@@ -56,6 +56,9 @@
/*
* $Log: MixedContentModel.hpp,v $
+ * Revision 1.5 2001/03/21 21:56:28 tng
+ * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+ *
* Revision 1.4 2001/03/21 19:29:58 tng
* Schema: Content Model Updates, by Pei Yong Zhang.
*
@@ -139,14 +142,14 @@
(
const unsigned int* childIds
, const unsigned int childCount
- , const XMLValidator *pValidator = 0
+ , const Grammar* grammar = 0
) const;
virtual int validateContentSpecial
(
const unsigned int* childIds
, const unsigned int childCount
- , const XMLValidator *pValidator = 0
+ , const Grammar* grammar = 0
) const;
virtual ContentLeafNameTypeVector* getContentLeafNameTypeVector() const ;
1.5 +5 -3 xml-xerces/c/src/validators/common/SimpleContentModel.cpp
Index: SimpleContentModel.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/validators/common/SimpleContentModel.cpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- SimpleContentModel.cpp 2001/03/21 19:30:00 1.4
+++ SimpleContentModel.cpp 2001/03/21 21:56:29 1.5
@@ -55,8 +55,10 @@
*/
/*
-/*
* $Log: SimpleContentModel.cpp,v $
+ * Revision 1.5 2001/03/21 21:56:29 tng
+ * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+ *
* Revision 1.4 2001/03/21 19:30:00 tng
* Schema: Content Model Updates, by Pei Yong Zhang.
*
@@ -124,7 +126,7 @@
int
SimpleContentModel::validateContent( const unsigned int* childIds
, const unsigned int childCount
- , const XMLValidator *pValidator) const
+ , const Grammar* grammar) const
{
//
// According to the type of operation, we do the correct type of
@@ -246,7 +248,7 @@
int
SimpleContentModel::validateContentSpecial( const unsigned int* childIds
, const unsigned int childCount
- , const XMLValidator *pValidator) const
+ , const Grammar* grammar) const
{
return 0;
}
1.5 +5 -2 xml-xerces/c/src/validators/common/SimpleContentModel.hpp
Index: SimpleContentModel.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/validators/common/SimpleContentModel.hpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- SimpleContentModel.hpp 2001/03/21 19:30:02 1.4
+++ SimpleContentModel.hpp 2001/03/21 21:56:29 1.5
@@ -56,6 +56,9 @@
/*
* $Log: SimpleContentModel.hpp,v $
+ * Revision 1.5 2001/03/21 21:56:29 tng
+ * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+ *
* Revision 1.4 2001/03/21 19:30:02 tng
* Schema: Content Model Updates, by Pei Yong Zhang.
*
@@ -142,14 +145,14 @@
(
const unsigned int* childIds
, const unsigned int childCount
- , const XMLValidator *pValidator = 0
+ , const Grammar* grammar = 0
) const;
virtual int validateContentSpecial
(
const unsigned int* childIds
, const unsigned int childCount
- , const XMLValidator *pValidator = 0
+ , const Grammar* grammar = 0
) const;
virtual ContentLeafNameTypeVector *getContentLeafNameTypeVector() const;
1.1 xml-xerces/c/src/validators/common/Grammar.hpp
Index: Grammar.hpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Log: Grammar.hpp,v $
* Revision 1.1 2001/03/21 21:56:27 tng
* Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
*
*/
#if !defined(GRAMMAR_HPP)
#define GRAMMAR_HPP
#include <framework/XMLElementDecl.hpp>
#include <framework/XMLEntityDecl.hpp>
#include <framework/XMLNotationDecl.hpp>
//
// This abstract class specifies the interface for a Grammar
//
class VALIDATORS_EXPORT Grammar
{
public:
enum GrammarType {
DTDGrammarType
, SchemaGrammarType
};
// -----------------------------------------------------------------------
// Constructors and Destructor
// -----------------------------------------------------------------------
virtual ~Grammar(){};
// -----------------------------------------------------------------------
// Virtual Getter methods
// -----------------------------------------------------------------------
virtual GrammarType getGrammarType()=0;
// Element Decl
virtual XMLElementDecl* findOrAddElemDecl
(
const unsigned int uriId
, const XMLCh* const baseName
, const XMLCh* const prefixName
, const XMLCh* const qName
, unsigned int scope
, bool& wasAdded
) = 0;
virtual unsigned int getElemId
(
const unsigned int uriId
, const XMLCh* const baseName
, const XMLCh* const qName
, unsigned int scope
) const = 0;
virtual const XMLElementDecl* getElemDecl
(
const unsigned int uriId
, const XMLCh* const baseName
, const XMLCh* const qName
, unsigned int scope
) const = 0;
virtual XMLElementDecl* getElemDecl
(
const unsigned int uriId
, const XMLCh* const baseName
, const XMLCh* const qName
, unsigned int scope
) = 0;
virtual const XMLElementDecl* getElemDecl
(
const unsigned int elemId
) const = 0;
virtual XMLElementDecl* getElemDecl
(
const unsigned int elemId
) = 0;
// Entity Decl
virtual const XMLEntityDecl* getEntityDecl
(
const XMLCh* const entName
) const=0;
virtual XMLEntityDecl* getEntityDecl
(
const XMLCh* const entName
)=0;
// Notation
virtual const XMLNotationDecl* getNotationDecl
(
const XMLCh* const notName
) const=0;
virtual XMLNotationDecl* getNotationDecl
(
const XMLCh* const notName
)=0;
// -----------------------------------------------------------------------
// Virtual Setter methods
// -----------------------------------------------------------------------
virtual unsigned int putElemDecl
(
XMLElementDecl* const elemDecl
) const = 0;
virtual unsigned int putEntityDecl
(
XMLEntityDecl* const entityDecl
) const = 0;
virtual unsigned int putNotationDecl
(
XMLNotationDecl* const notationDecl
) const=0;
// -----------------------------------------------------------------------
// Virtual methods
// -----------------------------------------------------------------------
virtual void reset()=0;
protected :
// -----------------------------------------------------------------------
// Hidden constructors
// -----------------------------------------------------------------------
Grammar() {};
};
#endif
1.1 xml-xerces/c/src/validators/common/GrammarResolver.cpp
Index: GrammarResolver.cpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.apache.org. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Log: GrammarResolver.cpp,v $
* Revision 1.1 2001/03/21 21:56:28 tng
* Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
*
*/
#include <validators/common/GrammarResolver.hpp>
#include <validators/datatype/DatatypeValidatorFactory.hpp>
// ---------------------------------------------------------------------------
// GrammarResolver: Constructor and Destructor
// ---------------------------------------------------------------------------
GrammarResolver::GrammarResolver() :
fGrammarRegistry(0)
, fDataTypeReg(0)
{
fGrammarRegistry = new RefHashTableOf<Grammar>(29, true);
}
GrammarResolver::~GrammarResolver()
{
delete fGrammarRegistry;
if (fDataTypeReg)
delete fDataTypeReg;
}
// ---------------------------------------------------------------------------
// GrammarResolver: Getter methods
// ---------------------------------------------------------------------------
DatatypeValidatorFactory* GrammarResolver::getDatatypeRegistry()
{
if (!fDataTypeReg) {
fDataTypeReg = new DatatypeValidatorFactory();
}
return fDataTypeReg;
}
Grammar* GrammarResolver::getGrammar( const XMLCh* const nameSpaceKey )
{
return fGrammarRegistry->get( nameSpaceKey );
}
RefHashTableOfEnumerator<Grammar>
GrammarResolver::getGrammarEnumerator() const
{
return RefHashTableOfEnumerator<Grammar>(fGrammarRegistry);
}
bool GrammarResolver::containsNameSpace( const XMLCh* const nameSpaceKey )
{
return fGrammarRegistry->containsKey( nameSpaceKey );
}
void GrammarResolver::putGrammar( const XMLCh* const nameSpaceKey, Grammar* const grammarToAdopt ){
fGrammarRegistry->put( (void*) nameSpaceKey, grammarToAdopt );
}
void GrammarResolver::removeGrammar( const XMLCh* const nameSpaceKey ) {
if ( containsNameSpace( nameSpaceKey ) )
fGrammarRegistry->removeKey( nameSpaceKey );
}
void GrammarResolver::reset() {
fGrammarRegistry->removeAll();
if (fDataTypeReg) {
fDataTypeReg->resetRegistry();
}
}
1.1 xml-xerces/c/src/validators/common/GrammarResolver.hpp
Index: GrammarResolver.hpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.apache.org. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/**
* $Id: GrammarResolver.hpp,v 1.1 2001/03/21 21:56:28 tng Exp $
*/
#if !defined(GRAMMARRESOLVER_HPP)
#define GRAMMARRESOLVER_HPP
#include <util/RefHashTableOf.hpp>
#include <validators/common/Grammar.hpp>
class DatatypeValidator;
class DatatypeValidatorFactory;
/**
* This class embodies the representation of a Grammar pool Resolver.
* This class is called from the validator.
*
*/
class GrammarResolver {
public:
/** @name Constructor and Destructor */
//@{
/**
*
* Default Constructor
*/
GrammarResolver();
/**
* Destructor
*/
~GrammarResolver();
//@}
/** @name Getter methods */
//@{
/**
* Retrieve the DatatypeValidatorFactory Registry
* @return the DatatypeValidatorFactory Registry
*/
DatatypeValidatorFactory* getDatatypeRegistry();
/**
* Retrieve the grammar that is associated with the specified namespace key
*
* @param nameSpaceKey Namespace key into Grammar pool
* @return Grammar abstraction associated with the NameSpace key.
*/
Grammar* getGrammar( const XMLCh* const nameSpaceKey ) ;
/**
* Get an enumeration of Grammar in the Grammar pool
*
* @return enumeration of Grammar in Grammar pool
*/
RefHashTableOfEnumerator<Grammar> getGrammarEnumerator() const;
/**
* Is the specified Namespace key in Grammar pool?
*
* @param nameSpaceKey Namespace key
* @return True if Namespace key association is in the Grammar pool.
*/
bool containsNameSpace( const XMLCh* const nameSpaceKey );
//@}
/** @name GrammarResolver methods */
//@{
/**
* Add the Grammar with Namespace Key associated to the Grammar Pool.
* The Grammar will be owned by the Grammar Pool.
*
* @param nameSpaceKey Key to associate with Grammar abstraction
* @param grammarToAdopt Grammar abstraction used by validator.
*/
void putGrammar(const XMLCh* const nameSpaceKey, Grammar* const grammarToAdopt );
/**
* Remove the Grammar with Namespace Key associated from the Grammar Pool
*
* @param nameSpaceKey Key to associate with Grammar abstraction
*/
void removeGrammar( const XMLCh* const nameSpaceKey );
/**
* Reset internal Namespace/Grammar registry.
*/
void reset();
//@}
private:
// -----------------------------------------------------------------------
// Private data members
//
// fGrammarRegistry The Grammar Pool. It represents a mapping
// between Namespace and a Grammar
// fDataTypeReg DatatypeValidatorFactory register
//
// -----------------------------------------------------------------------
RefHashTableOf<Grammar>* fGrammarRegistry;
DatatypeValidatorFactory* fDataTypeReg;
};
#endif
1.3 +9 -2 xml-xerces/c/src/validators/schema/Makefile.in
Index: Makefile.in
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/validators/schema/Makefile.in,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Makefile.in 2001/03/21 21:39:19 1.2
+++ Makefile.in 2001/03/21 21:56:33 1.3
@@ -55,6 +55,9 @@
#
#
# $Log: Makefile.in,v $
+# Revision 1.3 2001/03/21 21:56:33 tng
+# Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+#
# Revision 1.2 2001/03/21 21:39:19 knoaman
# Schema symbols and Datatype validator part I
#
@@ -85,7 +88,9 @@
SchemaAttDef.hpp \
SchemaAttDefList.hpp \
SchemaElementDecl.hpp \
- SchemaSymbols.hpp
+ SchemaGrammar.hpp \
+ SchemaSymbols.hpp \
+ SchemaValidator.hpp
VALIDATORS_SCHEMA_CPP_PRIVHEADERS =
@@ -95,7 +100,9 @@
SchemaAttDef.$(TO) \
SchemaAttDefList.$(TO) \
SchemaElementDecl.$(TO) \
- SchemaSymbols.$(TO)
+ SchemaGrammar.$(TO) \
+ SchemaSymbols.$(TO) \
+ SchemaValidator.$(TO)
all:: includes $(VALIDATORS_SCHEMA_CPP_OBJECTS)
1.4 +13 -5 xml-xerces/c/src/validators/schema/SchemaElementDecl.cpp
Index: SchemaElementDecl.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/validators/schema/SchemaElementDecl.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- SchemaElementDecl.cpp 2001/03/21 19:30:15 1.3
+++ SchemaElementDecl.cpp 2001/03/21 21:56:33 1.4
@@ -56,6 +56,9 @@
/*
* $Log: SchemaElementDecl.cpp,v $
+ * Revision 1.4 2001/03/21 21:56:33 tng
+ * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+ *
* Revision 1.3 2001/03/21 19:30:15 tng
* Schema: Content Model Updates, by Pei Yong Zhang.
*
@@ -181,6 +184,11 @@
return fElementName->getLocalPart();
}
+XMLCh* SchemaElementDecl::getBaseName()
+{
+ return fElementName->getLocalPart();
+}
+
XMLElementDecl::CharDataOpts SchemaElementDecl::getCharDataOpts() const
{
@@ -279,7 +287,7 @@
// SchemaElementDecl: Implementation of the protected virtual interface
// ---------------------------------------------------------------------------
XMLCh*
-SchemaElementDecl::formatContentModel(const XMLValidator& validator) const
+SchemaElementDecl::formatContentModel(const Grammar& grammar) const
{
XMLCh* newValue = 0;
if (fModelType == Any)
@@ -298,13 +306,13 @@
// will expand to handle the more pathological ones.
//
XMLBuffer bufFmt;
- fContentSpec->formatSpec(validator, bufFmt);
+ fContentSpec->formatSpec(grammar, bufFmt);
newValue = XMLString::replicate(bufFmt.getRawBuffer());
}
return newValue;
}
-XMLContentModel* SchemaElementDecl::makeContentModel(XMLValidator* pValidator) const
+XMLContentModel* SchemaElementDecl::makeContentModel(const Grammar* grammar) const
{
XMLContentModel* cmRet = 0;
if (fModelType == Simple) {
@@ -327,7 +335,7 @@
// create a SimpleListContentModel object. If its complex, it
// will create a DFAContentModel object.
//
- cmRet = createChildModel(pValidator);
+ cmRet = createChildModel(grammar);
}
else
{
@@ -341,7 +349,7 @@
// ---------------------------------------------------------------------------
// SchemaElementDecl: Private helper methods
// ---------------------------------------------------------------------------
-XMLContentModel* SchemaElementDecl::createChildModel(XMLValidator* pValidator) const
+XMLContentModel* SchemaElementDecl::createChildModel(const Grammar* grammar) const
{
// Get the content spec node of the element
const ContentSpecNode* specNode = getContentSpec();
1.3 +23 -3 xml-xerces/c/src/validators/schema/SchemaElementDecl.hpp
Index: SchemaElementDecl.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/validators/schema/SchemaElementDecl.hpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- SchemaElementDecl.hpp 2001/03/21 19:30:17 1.2
+++ SchemaElementDecl.hpp 2001/03/21 21:56:33 1.3
@@ -56,6 +56,9 @@
/*
* $Log: SchemaElementDecl.hpp,v $
+ * Revision 1.3 2001/03/21 21:56:33 tng
+ * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
+ *
* Revision 1.2 2001/03/21 19:30:17 tng
* Schema: Content Model Updates, by Pei Yong Zhang.
*
@@ -135,6 +138,7 @@
) const;
virtual XMLAttDefList& getAttDefList() const;
virtual const XMLCh* getBaseName() const;
+ virtual XMLCh* getBaseName() ;
virtual const int getURI() const;
virtual CharDataOpts getCharDataOpts() const;
virtual const XMLCh* getFullName() const;
@@ -154,6 +158,7 @@
ModelTypes getModelType() const;
DatatypeValidator* getDatatypeValidator() const;
int getEnclosingScope() const;
+ int getDefinedScope() const;
// -----------------------------------------------------------------------
@@ -166,16 +171,17 @@
void setModelType(const SchemaElementDecl::ModelTypes toSet);
void setDatatypeValidator(DatatypeValidator* newDatatypeValidator);
void setEnclosingScope(const int enclosingScope);
+ void setDefinedScope(const int definedScope);
protected :
// -----------------------------------------------------------------------
// Protected, virtual methods
// -----------------------------------------------------------------------
- virtual XMLContentModel* makeContentModel(XMLValidator* pValidator=0) const;
+ virtual XMLContentModel* makeContentModel(const Grammar* grammar=0) const;
virtual XMLCh* formatContentModel
(
- const XMLValidator& validator
+ const Grammar& grammar
) const;
@@ -183,7 +189,7 @@
// -----------------------------------------------------------------------
// Private helper methods
// -----------------------------------------------------------------------
- XMLContentModel* createChildModel(XMLValidator* pValidator=0) const;
+ XMLContentModel* createChildModel(const Grammar* grammar=0) const;
void faultInAttDefList() const;
@@ -219,6 +225,9 @@
//
// fEnclosingScope
// The enclosing scope where this element is declared.
+ //
+ // fDefinedScope
+ // The Complex Element that this element belongs to.
// -----------------------------------------------------------------------
RefHash2KeysTableOf<SchemaAttDef>* fAttDefs;
SchemaAttDefList* fAttList;
@@ -227,6 +236,7 @@
ModelTypes fModelType;
DatatypeValidator* fDatatypeValidator;
int fEnclosingScope;
+ int fDefinedScope;
};
// ---------------------------------------------------------------------------
@@ -275,6 +285,11 @@
return fEnclosingScope;
}
+inline int SchemaElementDecl::getDefinedScope() const
+{
+ return fDefinedScope;
+}
+
// ---------------------------------------------------------------------------
// SchemaElementDecl: Setter methods
// ---------------------------------------------------------------------------
@@ -299,6 +314,11 @@
inline void SchemaElementDecl::setEnclosingScope(const int newEnclosingScope)
{
fEnclosingScope = newEnclosingScope;
+}
+
+inline void SchemaElementDecl::setDefinedScope(const int newDefinedScope)
+{
+ fDefinedScope = newDefinedScope;
}
#endif
1.1 xml-xerces/c/src/validators/schema/SchemaGrammar.cpp
Index: SchemaGrammar.cpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Log: SchemaGrammar.cpp,v $
* Revision 1.1 2001/03/21 21:56:33 tng
* Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
*
*/
// ---------------------------------------------------------------------------
// Includes
// ---------------------------------------------------------------------------
#include <validators/schema/SchemaGrammar.hpp>
// ---------------------------------------------------------------------------
// SchemaGrammar: Constructors and Destructor
// ---------------------------------------------------------------------------
SchemaGrammar::SchemaGrammar() :
fElemDeclPool(0)
, fNotationDeclPool(0)
, fTargetNamespace(0)
{
//
// Init all the pool members.
//
// <TBD> Investigate what the optimum values would be for the various
// pools.
//
fElemDeclPool = new RefHash3KeysIdPool<SchemaElementDecl>(109);
fNotationDeclPool = new NameIdPool<XMLNotationDecl>(109);
//
// Call our own reset method. This lets us have the pool setup stuff
// done in just one place (because this stame setup stuff has to be
// done every time we are reset.)
//
reset();
}
SchemaGrammar::~SchemaGrammar()
{
delete fElemDeclPool;
delete fNotationDeclPool;
delete fTargetNamespace;
}
// -----------------------------------------------------------------------
// Virutal methods
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
// Virtual methods
// -----------------------------------------------------------------------
XMLElementDecl* SchemaGrammar::findOrAddElemDecl (const unsigned int uriId
, const XMLCh* const baseName
, const XMLCh* const prefixName
, const XMLCh* const qName
, unsigned int scope
, bool& wasAdded )
{
// See it it exists
SchemaElementDecl* retVal = fElemDeclPool->getByKey(baseName, uriId, scope);
// if not, then add this in
if (!retVal)
{
retVal = new SchemaElementDecl(prefixName, baseName, uriId, SchemaElementDecl::Any);
const unsigned int elemId = fElemDeclPool->put((void*)baseName, uriId, scope, retVal);
retVal->setId(elemId);
wasAdded = true;
}
else
{
wasAdded = false;
}
return retVal;
}
void SchemaGrammar::reset()
{
//
// We need to reset all of the pools.
//
fElemDeclPool->removeAll();
fNotationDeclPool->removeAll();
}
1.1 xml-xerces/c/src/validators/schema/SchemaGrammar.hpp
Index: SchemaGrammar.hpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Log: SchemaGrammar.hpp,v $
* Revision 1.1 2001/03/21 21:56:33 tng
* Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
*
*/
#if !defined(SCHEMAGRAMMAR_HPP)
#define SCHEMAGRAMMAR_HPP
#include <dom/DOM_Document.hpp>
#include <framework/XMLNotationDecl.hpp>
#include <framework/XMLEntityDecl.hpp>
#include <util/RefHash3KeysIdPool.hpp>
#include <util/NameIdPool.hpp>
#include <util/StringPool.hpp>
#include <validators/common/Grammar.hpp>
#include <validators/schema/SchemaElementDecl.hpp>
//
// This class stores the Schema information
// NOTE: Schemas are not namespace aware, so we just use regular NameIdPool
// data structures to store element and attribute decls. They are all set
// to be in the global namespace and the full QName is used as the base name
// of the decl. This means that all the URI parameters below are expected
// to be null pointers (and anything else will cause an exception.)
//
class VALIDATORS_EXPORT SchemaGrammar : public Grammar
{
public:
// -----------------------------------------------------------------------
// Constructors and Destructor
// -----------------------------------------------------------------------
SchemaGrammar();
virtual ~SchemaGrammar();
// -----------------------------------------------------------------------
// Implementation of Virtual Interface
// -----------------------------------------------------------------------
virtual Grammar::GrammarType getGrammarType();
virtual XMLElementDecl* findOrAddElemDecl
(
const unsigned int uriId
, const XMLCh* const baseName
, const XMLCh* const prefixName
, const XMLCh* const qName
, unsigned int scope
, bool& wasAdded
) ;
virtual unsigned int getElemId
(
const unsigned int uriId
, const XMLCh* const baseName
, const XMLCh* const qName
, unsigned int scope
) const ;
virtual const XMLElementDecl* getElemDecl
(
const unsigned int uriId
, const XMLCh* const baseName
, const XMLCh* const qName
, unsigned int scope
) const ;
virtual XMLElementDecl* getElemDecl
(
const unsigned int uriId
, const XMLCh* const baseName
, const XMLCh* const qName
, unsigned int scope
);
virtual const XMLElementDecl* getElemDecl
(
const unsigned int elemId
) const;
virtual XMLElementDecl* getElemDecl
(
const unsigned int elemId
);
virtual const XMLEntityDecl* getEntityDecl
(
const XMLCh* const entName
) const;
virtual XMLEntityDecl* getEntityDecl
(
const XMLCh* const entName
);
virtual const XMLNotationDecl* getNotationDecl
(
const XMLCh* const notName
) const;
virtual XMLNotationDecl* getNotationDecl
(
const XMLCh* const notName
);
virtual unsigned int putElemDecl
(
XMLElementDecl* const elemDecl
) const;
virtual unsigned int putEntityDecl
(
XMLEntityDecl* const entityDecl
) const;
virtual unsigned int putNotationDecl
(
XMLNotationDecl* const notationDecl
) const;
virtual void reset();
// -----------------------------------------------------------------------
// Getter methods
// -----------------------------------------------------------------------
DOM_Document getGrammarDocument() const;
const XMLCh* getTargetNamespace() const;
XMLCh* getTargetNamespace() ;
// -----------------------------------------------------------------------
// Setter methods
// -----------------------------------------------------------------------
void setGrammarDocument(const DOM_Document grammarDocument);
void setTargetNamespace(const XMLCh* const targetNamespace);
private:
// -----------------------------------------------------------------------
// Private data members
//
// fElemDeclPool
// This is the element decl pool. It contains all of the elements
// declared in the Schema (and their associated attributes.) When in
// non-validating mode, its just populated as new elements are seen
// and they are given default characteristics.
//
// fNotationDeclPool
// This is a pool of NotationDecl objects, which contains all of the
// notations declared in the Schema.
//
// fTargetNamespace
// Target name space for this grammar.
//
// fGrammarDocument
// Grammar stored as DOM Document.
// -----------------------------------------------------------------------
RefHash3KeysIdPool<SchemaElementDecl>* fElemDeclPool;
NameIdPool<XMLNotationDecl>* fNotationDeclPool;
XMLCh* fTargetNamespace;
DOM_Document fGrammarDocument;
};
// ---------------------------------------------------------------------------
// SchemaGrammar: Getter methods
// ---------------------------------------------------------------------------
inline DOM_Document SchemaGrammar::getGrammarDocument() const {
return fGrammarDocument;
}
inline XMLCh* SchemaGrammar::getTargetNamespace() {
return fTargetNamespace;
}
inline const XMLCh* SchemaGrammar::getTargetNamespace() const {
return fTargetNamespace;
}
// -----------------------------------------------------------------------
// Setter methods
// -----------------------------------------------------------------------
inline void SchemaGrammar::setGrammarDocument(const DOM_Document grammarDocument) {
fGrammarDocument = grammarDocument;
}
inline void SchemaGrammar::setTargetNamespace(const XMLCh* const targetNamespace) {
fTargetNamespace = XMLString::replicate(targetNamespace);
}
// ---------------------------------------------------------------------------
// SchemaGrammar: Virtual methods
// ---------------------------------------------------------------------------
inline Grammar::GrammarType SchemaGrammar::getGrammarType() {
return Grammar::SchemaGrammarType;
}
// Element Decl
inline unsigned int SchemaGrammar::getElemId (const unsigned int uriId
, const XMLCh* const baseName
, const XMLCh* const qName
, unsigned int scope ) const
{
//
// In this case, we don't return zero to mean 'not found', so we have to
// map it to the official not found value if we don't find it.
//
const SchemaElementDecl* decl = fElemDeclPool->getByKey(baseName, uriId, scope);
if (!decl)
return XMLElementDecl::fgInvalidElemId;
return decl->getId();
}
inline const XMLElementDecl* SchemaGrammar::getElemDecl( const unsigned int uriId
, const XMLCh* const baseName
, const XMLCh* const qName
, unsigned int scope ) const
{
return fElemDeclPool->getByKey(baseName, uriId, scope);
}
inline XMLElementDecl* SchemaGrammar::getElemDecl (const unsigned int uriId
, const XMLCh* const baseName
, const XMLCh* const qName
, unsigned int scope )
{
return fElemDeclPool->getByKey(baseName, uriId, scope);
}
inline const XMLElementDecl* SchemaGrammar::getElemDecl(const unsigned int elemId) const
{
// Look up this element decl by id
return fElemDeclPool->getById(elemId);
}
inline XMLElementDecl* SchemaGrammar::getElemDecl(const unsigned int elemId)
{
// Look up this element decl by id
return fElemDeclPool->getById(elemId);
}
inline unsigned int SchemaGrammar::putElemDecl (XMLElementDecl* const elemDecl) const
{
return fElemDeclPool->put(elemDecl->getBaseName(), elemDecl->getURI(), ((SchemaElementDecl* )elemDecl)->getEnclosingScope(), (SchemaElementDecl*) elemDecl);
}
// Entity Decl
inline const XMLEntityDecl* SchemaGrammar::getEntityDecl(const XMLCh* const entName) const
{
// No entity pool in Schema
return 0;
}
inline XMLEntityDecl* SchemaGrammar::getEntityDecl(const XMLCh* const entName)
{
// No entity pool in Schema
return 0;
}
inline unsigned int SchemaGrammar::putEntityDecl (XMLEntityDecl* const entityDecl) const
{
// No entity pool in Schema
return 0;
}
// Notation Decl
inline const XMLNotationDecl* SchemaGrammar::getNotationDecl(const XMLCh* const notName) const
{
return fNotationDeclPool->getByKey(notName);
}
inline XMLNotationDecl* SchemaGrammar::getNotationDecl(const XMLCh* const notName)
{
return fNotationDeclPool->getByKey(notName);
}
inline unsigned int SchemaGrammar::putNotationDecl(XMLNotationDecl* const notationDecl) const
{
return fNotationDeclPool->put(notationDecl);
}
#endif
1.1 xml-xerces/c/src/validators/schema/SchemaValidator.cpp
Index: SchemaValidator.cpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Log: SchemaValidator.cpp,v $
* Revision 1.1 2001/03/21 21:56:33 tng
* Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
*
*/
// ---------------------------------------------------------------------------
// Includes
// ---------------------------------------------------------------------------
#include <util/KVStringPair.hpp>
#include <validators/schema/SchemaValidator.hpp>
// ---------------------------------------------------------------------------
// SchemaValidator: Constructors and Destructor
// ---------------------------------------------------------------------------
SchemaValidator::SchemaValidator(XMLErrorReporter* const errReporter) :
XMLValidator(errReporter)
, fGrammarResolver(0)
{
}
SchemaValidator::~SchemaValidator()
{
}
// ---------------------------------------------------------------------------
// SchemaValidator: Implementation of the XMLValidator interface
// ---------------------------------------------------------------------------
int SchemaValidator::checkContent (const unsigned int elemId
, const unsigned int* childIds
, const unsigned int childCount)
{
return 0;
}
bool SchemaValidator::checkRootElement (const unsigned int elemId)
{
return false;
}
void SchemaValidator::faultInAttr (XMLAttr& toFill, const XMLAttDef& attDef) const
{
}
void SchemaValidator::preContentValidation(bool reuseGrammar)
{
}
void SchemaValidator::postParseValidation()
{
}
void SchemaValidator::reset()
{
}
bool SchemaValidator::requiresNamespaces() const
{
return true;
}
void SchemaValidator::validateAttrValue (const XMLAttDef& attDef
, const XMLCh* const attrValue)
{
}
1.1 xml-xerces/c/src/validators/schema/SchemaValidator.hpp
Index: SchemaValidator.hpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Log: SchemaValidator.hpp,v $
* Revision 1.1 2001/03/21 21:56:33 tng
* Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
*
*/
#if !defined(SCHEMAVALIDATOR_HPP)
#define SCHEMAVALIDATOR_HPP
#include <framework/XMLValidator.hpp>
#include <util/RefVectorOf.hpp>
#include <validators/schema/SchemaElementDecl.hpp>
#include <validators/common/GrammarResolver.hpp>
//
// This is a derivative of the abstract validator interface. This class
// implements a validator that supports standard XML Schema semantics.
// This class handles scanning the of the schema, and provides
// the standard validation services against the Schema info it found.
//
class VALIDATORS_EXPORT SchemaValidator : public XMLValidator
{
public:
// -----------------------------------------------------------------------
// Constructors and Destructor
// -----------------------------------------------------------------------
SchemaValidator(XMLErrorReporter* const errReporter = 0);
virtual ~SchemaValidator();
// -----------------------------------------------------------------------
// Setter methods
// -----------------------------------------------------------------------
void setXsiTypeAttValue(const XMLCh* const xsiTypeAttValue);
void setGrammarResolver(GrammarResolver* grammarResolver);
// -----------------------------------------------------------------------
// Implementation of the XMLValidator interface
// -----------------------------------------------------------------------
virtual int checkContent
(
const unsigned int elemId
, const unsigned int* childIds
, const unsigned int childCount
);
virtual bool checkRootElement
(
const unsigned int elemId
);
virtual void faultInAttr
(
XMLAttr& toFill
, const XMLAttDef& attDef
) const;
virtual void preContentValidation(bool reuseGrammar);
virtual void postParseValidation();
virtual void reset();
virtual bool requiresNamespaces() const;
virtual void validateAttrValue
(
const XMLAttDef& attDef
, const XMLCh* const attrValue
);
virtual Grammar* getGrammar(const XMLCh* uri=0);
virtual Grammar* getGrammar(const char* uri);
// -----------------------------------------------------------------------
// Virtual DTD handler interface.
// -----------------------------------------------------------------------
virtual bool handlesDTD() const;
// -----------------------------------------------------------------------
// Virtual Schema handler interface. handlesSchema() always return false.
// -----------------------------------------------------------------------
virtual bool handlesSchema() const;
private:
// -----------------------------------------------------------------------
// Private data members
//
// fXsiTypeAttValue
// Store the Schema Type Attribute Value if schema type is specified
//
// fGrammarResolver
// All the schema grammar stored
// -----------------------------------------------------------------------
const XMLCh* fXsiTypeAttValue;
GrammarResolver* fGrammarResolver;
};
// ---------------------------------------------------------------------------
// SchemaValidator: Setter methods
// ---------------------------------------------------------------------------
inline void SchemaValidator::setXsiTypeAttValue(const XMLCh* const xsiTypeAttValue) {
fXsiTypeAttValue = xsiTypeAttValue;
}
inline void SchemaValidator::setGrammarResolver(GrammarResolver* grammarResolver) {
fGrammarResolver = grammarResolver;
}
// ---------------------------------------------------------------------------
// Virtual interface
// ---------------------------------------------------------------------------
inline Grammar* SchemaValidator::getGrammar(const XMLCh* uri) {
return fGrammarResolver->getGrammar(uri);
}
inline Grammar* SchemaValidator::getGrammar(const char* uri) {
XMLCh* tempURI = XMLString::transcode(uri);
Grammar* tempGrammar = fGrammarResolver->getGrammar(tempURI);
delete tempURI;
return tempGrammar;
}
// ---------------------------------------------------------------------------
// SchemaValidator: DTD handler interface
// ---------------------------------------------------------------------------
inline bool SchemaValidator::handlesDTD() const
{
// No DTD scanning
return false;
}
// ---------------------------------------------------------------------------
// SchemaValidator: Schema handler interface
// ---------------------------------------------------------------------------
inline bool SchemaValidator::handlesSchema() const
{
return true;
}
#endif
---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-cvs-help@xml.apache.org