Main Page   Class Hierarchy   Compound List   File List   Compound Members  

ElemStack.hpp

00001 /*
00002  * The Apache Software License, Version 1.1
00003  *
00004  * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
00005  * reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions
00009  * are met:
00010  *
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  *
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in
00016  *    the documentation and/or other materials provided with the
00017  *    distribution.
00018  *
00019  * 3. The end-user documentation included with the redistribution,
00020  *    if any, must include the following acknowledgment:
00021  *       "This product includes software developed by the
00022  *        Apache Software Foundation (http://www.apache.org/)."
00023  *    Alternately, this acknowledgment may appear in the software itself,
00024  *    if and wherever such third-party acknowledgments normally appear.
00025  *
00026  * 4. The names "Xerces" and "Apache Software Foundation" must
00027  *    not be used to endorse or promote products derived from this
00028  *    software without prior written permission. For written
00029  *    permission, please contact apache\@apache.org.
00030  *
00031  * 5. Products derived from this software may not be called "Apache",
00032  *    nor may "Apache" appear in their name, without prior written
00033  *    permission of the Apache Software Foundation.
00034  *
00035  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
00036  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00037  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00038  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
00039  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00040  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00041  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
00042  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00043  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00044  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00045  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00046  * SUCH DAMAGE.
00047  * ====================================================================
00048  *
00049  * This software consists of voluntary contributions made by many
00050  * individuals on behalf of the Apache Software Foundation, and was
00051  * originally based on software copyright (c) 1999, International
00052  * Business Machines, Inc., http://www.ibm.com .  For more information
00053  * on the Apache Software Foundation, please see
00054  * <http://www.apache.org/>.
00055  */
00056 
00057 /*
00058  * $Log: ElemStack.hpp,v $
00059  * Revision 1.1  2002/05/11 20:17:49  bhavani
00060  * CR#CR062582# adding xercesc 1.7 file
00061  *
00062  * Revision 1.1.1.1  2002/02/01 22:21:58  peiyongz
00063  * sane_include
00064  *
00065  * Revision 1.11  2001/12/12 14:29:50  tng
00066  * Remove obsolete code in ElemStack which can help performance.
00067  *
00068  * Revision 1.10  2001/08/07 13:47:47  tng
00069  * Schema: Fix unmatched end tag for qualified/unqualifed start tag.
00070  *
00071  * Revision 1.9  2001/05/28 20:55:19  tng
00072  * Schema: Store Grammar in ElemStack as well.
00073  *
00074  * Revision 1.8  2001/05/11 13:26:16  tng
00075  * Copyright update.
00076  *
00077  * Revision 1.7  2001/05/03 20:34:28  tng
00078  * Schema: SchemaValidator update
00079  *
00080  * Revision 1.6  2001/04/19 18:16:58  tng
00081  * Schema: SchemaValidator update, and use QName in Content Model
00082  *
00083  * Revision 1.5  2000/04/18 23:54:29  roddey
00084  * Got rid of some foward references to no longer used classes.
00085  *
00086  * Revision 1.4  2000/03/02 19:54:28  roddey
00087  * This checkin includes many changes done while waiting for the
00088  * 1.1.0 code to be finished. I can't list them all here, but a list is
00089  * available elsewhere.
00090  *
00091  * Revision 1.3  2000/02/24 20:18:07  abagchi
00092  * Swat for removing Log from API docs
00093  *
00094  * Revision 1.2  2000/02/06 07:47:52  rahulj
00095  * Year 2K copyright swat.
00096  *
00097  * Revision 1.1.1.1  1999/11/09 01:08:06  twl
00098  * Initial checkin
00099  *
00100  * Revision 1.2  1999/11/08 20:44:42  rahul
00101  * Swat for adding in Product name and CVS comment log variable.
00102  *
00103  */
00104 
00105 #if !defined(ELEMSTACK_HPP)
00106 #define ELEMSTACK_HPP
00107 
00108 #include <xercesc/util/XercesDefs.hpp>
00109 #include <xercesc/util/StringPool.hpp>
00110 #include <xercesc/util/QName.hpp>
00111 class XMLElementDecl;
00112 class Grammar;
00113 
00114 //
00115 //  During the scan of content, we have to keep up with the nesting of
00116 //  elements (for validation and wellformedness purposes) and we have to
00117 //  have places to remember namespace (prefix to URI) mappings.
00118 //
00119 //  We only have to keep a stack of the current path down through the tree
00120 //  that we are currently scanning, and keep track of any children of any
00121 //  elements along that path.
00122 //
00123 //  So, this data structure is a stack, which represents the current path
00124 //  through the tree that we've worked our way down to. For each node in
00125 //  the stack, there is an array of element ids that represent the ids of
00126 //  the child elements scanned so far. Upon exit from that element, its
00127 //  array of child elements is validated.
00128 //
00129 //  Since we have the actual XMLElementDecl in the stack nodes, when its time
00130 //  to validate, we just extract the content model from that element decl
00131 //  and validate. All the required data falls easily to hand. Note that we
00132 //  actually have some derivative of XMLElementDecl, which is specific to
00133 //  the validator used, but the abstract API is sufficient for the needs of
00134 //  the scanner.
00135 //
00136 //  Since the namespace support also requires the storage of information on
00137 //  a nested element basis, this structure also holds the namespace info. For
00138 //  each level, the prefixes defined at that level (and the namespaces that
00139 //  they map to) are stored.
00140 //
00141 class XMLPARSER_EXPORT ElemStack
00142 {
00143 public :
00144     // -----------------------------------------------------------------------
00145     //  Class specific data types
00146     //
00147     //  These really should be private, but some of the compilers we have to
00148     //  support are too dumb to deal with that.
00149     //
00150     //  PrefMapElem
00151     //      fURIId is the id of the URI from the validator's URI map. The
00152     //      fPrefId is the id of the prefix from our own prefix pool. The
00153     //      namespace stack consists of these elements.
00154     //
00155     //  StackElem
00156     //      fThisElement is the basic element decl for the current element.
00157     //      The fRowCapacity is how large fChildIds has grown so far.
00158     //      fChildCount is how many of them are valid right now.
00159     //
00160     //      The fMapCapacity is how large fMap has grown so far. fMapCount
00161     //      is how many of them are valid right now.
00162     //
00163     //      Note that we store the reader number we were in when we found the
00164     //      start tag. We'll use this at the end tag to test for unbalanced
00165     //      markup in entities.
00166     //
00167     //  MapModes
00168     //      When a prefix is mapped to a namespace id, it matters whether the
00169     //      QName being mapped is an attribute or name. Attributes are not
00170     //      affected by an sibling xmlns attributes, whereas elements are
00171     //      affected by its own xmlns attributes.
00172     // -----------------------------------------------------------------------
00173     struct PrefMapElem
00174     {
00175         unsigned int        fPrefId;
00176         unsigned int        fURIId;
00177     };
00178 
00179     struct StackElem
00180     {
00181         XMLElementDecl*     fThisElement;
00182         unsigned int        fReaderNum;
00183 
00184         unsigned int        fChildCapacity;
00185         unsigned int        fChildCount;
00186         QName**             fChildren;
00187 
00188         PrefMapElem*        fMap;
00189         unsigned int        fMapCapacity;
00190         unsigned int        fMapCount;
00191 
00192         bool                fValidationFlag;
00193         int                 fCurrentScope;
00194         Grammar*            fCurrentGrammar;
00195         unsigned int        fCurrentURI;
00196     };
00197 
00198     enum MapModes
00199     {
00200         Mode_Attribute
00201         , Mode_Element
00202     };
00203 
00204 
00205     // -----------------------------------------------------------------------
00206     //  Constructors and Destructor
00207     // -----------------------------------------------------------------------
00208     ElemStack();
00209     ~ElemStack();
00210 
00211 
00212     // -----------------------------------------------------------------------
00213     //  Stack access
00214     // -----------------------------------------------------------------------
00215     unsigned int addLevel();
00216     unsigned int addLevel(XMLElementDecl* const toSet, const unsigned int readerNum);
00217     const StackElem* popTop();
00218 
00219 
00220     // -----------------------------------------------------------------------
00221     //  Stack top access
00222     // -----------------------------------------------------------------------
00223     unsigned int addChild(QName* const child, const bool toParent);
00224     const StackElem* topElement() const;
00225     void setElement(XMLElementDecl* const toSet, const unsigned int readerNum);
00226 
00227     void setValidationFlag(bool validationFlag);
00228     bool getValidationFlag();
00229 
00230     void setCurrentScope(int currentScope);
00231     int getCurrentScope();
00232 
00233     void setCurrentGrammar(Grammar* currentGrammar);
00234     Grammar* getCurrentGrammar();
00235 
00236     void setCurrentURI(unsigned int uri);
00237     unsigned int getCurrentURI();
00238 
00239     // -----------------------------------------------------------------------
00240     //  Prefix map methods
00241     // -----------------------------------------------------------------------
00242     void addPrefix
00243     (
00244         const   XMLCh* const    prefixToAdd
00245         , const unsigned int    uriId
00246     );
00247     unsigned int mapPrefixToURI
00248     (
00249         const   XMLCh* const    prefixToMap
00250         , const MapModes        mode
00251         ,       bool&           unknown
00252     )   const;
00253 
00254 
00255     // -----------------------------------------------------------------------
00256     //  Miscellaneous methods
00257     // -----------------------------------------------------------------------
00258     bool isEmpty() const;
00259     void reset
00260     (
00261         const   unsigned int    emptyId
00262         , const unsigned int    unknownId
00263         , const unsigned int    xmlId
00264         , const unsigned int    xmlNSId
00265     );
00266 
00267 
00268 private :
00269     // -----------------------------------------------------------------------
00270     //  Unimplemented constructors and operators
00271     // -----------------------------------------------------------------------
00272     ElemStack(const ElemStack&);
00273     void operator=(const ElemStack&);
00274 
00275 
00276     // -----------------------------------------------------------------------
00277     //  Private helper methods
00278     // -----------------------------------------------------------------------
00279     void expandMap(StackElem* const toExpand);
00280     void expandStack();
00281 
00282 
00283     // -----------------------------------------------------------------------
00284     //  Data members
00285     //
00286     //  fEmptyNamespaceId
00287     //      This is the special URI id for the "" namespace, which is magic
00288     //      because of the xmlns="" operation.
00289     //
00290     //  fGlobalPoolId
00291     //      This is a special URI id that is returned when the namespace
00292     //      prefix is "" and no one has explicitly mapped that prefix to an
00293     //      explicit URI (or when they explicitly clear any such mapping,
00294     //      which they can also do.) And also its prefix pool id, which is
00295     //      stored here for fast access.
00296     //
00297     //  fPrefixPool
00298     //      This is the prefix pool where prefixes are hashed and given unique
00299     //      ids. These ids are used to track prefixes in the element stack.
00300     //
00301     //  fStack
00302     //  fStackCapacity
00303     //  fStackTop
00304     //      This the stack array. Its an array of pointers to StackElem
00305     //      structures. The capacity is the current high water mark of the
00306     //      stack. The top is the current top of stack (i.e. the part of it
00307     //      being used.)
00308     //
00309     //  fUnknownNamespaceId
00310     //      This is the URI id for the special URI that is assigned to any
00311     //      prefix which has not been mapped. This lets us keep going after
00312     //      issuing the error.
00313     //
00314     //  fXMLNamespaceId
00315     //  fXMLPoolId
00316     //  fXMLNSNamespaceId
00317     //  fXMLNSPoolId
00318     //      These are the URI ids for the special URIs that are assigned to
00319     //      the 'xml' and 'xmlns' namespaces. And also its prefix pool id,
00320     //      which is stored here for fast access.
00321     // -----------------------------------------------------------------------
00322     unsigned int    fEmptyNamespaceId;
00323     unsigned int    fGlobalPoolId;
00324     XMLStringPool   fPrefixPool;
00325     StackElem**     fStack;
00326     unsigned int    fStackCapacity;
00327     unsigned int    fStackTop;
00328     unsigned int    fUnknownNamespaceId;
00329     unsigned int    fXMLNamespaceId;
00330     unsigned int    fXMLPoolId;
00331     unsigned int    fXMLNSNamespaceId;
00332     unsigned int    fXMLNSPoolId;
00333 };
00334 
00335 
00336 // ---------------------------------------------------------------------------
00337 //  ElemStack: Miscellaneous methods
00338 // ---------------------------------------------------------------------------
00339 inline bool ElemStack::isEmpty() const
00340 {
00341     return (fStackTop == 0);
00342 }
00343 
00344 inline bool ElemStack::getValidationFlag()
00345 {
00346     return fStack[fStackTop-1]->fValidationFlag;
00347 }
00348 
00349 inline void ElemStack::setValidationFlag(bool validationFlag)
00350 {
00351     fStack[fStackTop-1]->fValidationFlag = validationFlag;
00352     return;
00353 }
00354 
00355 inline int ElemStack::getCurrentScope()
00356 {
00357     return fStack[fStackTop-1]->fCurrentScope;
00358 }
00359 
00360 inline void ElemStack::setCurrentScope(int currentScope)
00361 {
00362     fStack[fStackTop-1]->fCurrentScope = currentScope;
00363     return;
00364 }
00365 
00366 inline Grammar* ElemStack::getCurrentGrammar()
00367 {
00368     return fStack[fStackTop-1]->fCurrentGrammar;
00369 }
00370 
00371 inline void ElemStack::setCurrentGrammar(Grammar* currentGrammar)
00372 {
00373     fStack[fStackTop-1]->fCurrentGrammar = currentGrammar;
00374     return;
00375 }
00376 
00377 inline unsigned int ElemStack::getCurrentURI()
00378 {
00379     return fStack[fStackTop-1]->fCurrentURI;
00380 }
00381 
00382 inline void ElemStack::setCurrentURI(unsigned int uri)
00383 {
00384     fStack[fStackTop-1]->fCurrentURI = uri;
00385     return;
00386 }
00387 
00388 #endif

Generated on Tue Nov 19 09:36:28 2002 by doxygen1.3-rc1