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 &gt; &lt; ...) 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 = &notationPoolEnum.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