Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:14:54

0001 /*
0002  * Licensed to the Apache Software Foundation (ASF) under one or more
0003  * contributor license agreements.  See the NOTICE file distributed with
0004  * this work for additional information regarding copyright ownership.
0005  * The ASF licenses this file to You under the Apache License, Version 2.0
0006  * (the "License"); you may not use this file except in compliance with
0007  * the License.  You may obtain a copy of the License at
0008  * 
0009  *      http://www.apache.org/licenses/LICENSE-2.0
0010  * 
0011  * Unless required by applicable law or agreed to in writing, software
0012  * distributed under the License is distributed on an "AS IS" BASIS,
0013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014  * See the License for the specific language governing permissions and
0015  * limitations under the License.
0016  */
0017 
0018 /*
0019  * $Id$
0020  */
0021 
0022 #if !defined(XERCESC_INCLUDE_GUARD_ELEMSTACK_HPP)
0023 #define XERCESC_INCLUDE_GUARD_ELEMSTACK_HPP
0024 
0025 #include <xercesc/util/StringPool.hpp>
0026 #include <xercesc/util/QName.hpp>
0027 #include <xercesc/util/ValueVectorOf.hpp>
0028 
0029 XERCES_CPP_NAMESPACE_BEGIN
0030 
0031 class XMLElementDecl;
0032 class Grammar;
0033 
0034 struct PrefMapElem : public XMemory
0035 {
0036     unsigned int        fPrefId;
0037     unsigned int        fURIId;
0038 };
0039 
0040 //
0041 //  During the scan of content, we have to keep up with the nesting of
0042 //  elements (for validation and wellformedness purposes) and we have to
0043 //  have places to remember namespace (prefix to URI) mappings.
0044 //
0045 //  We only have to keep a stack of the current path down through the tree
0046 //  that we are currently scanning, and keep track of any children of any
0047 //  elements along that path.
0048 //
0049 //  So, this data structure is a stack, which represents the current path
0050 //  through the tree that we've worked our way down to. For each node in
0051 //  the stack, there is an array of element ids that represent the ids of
0052 //  the child elements scanned so far. Upon exit from that element, its
0053 //  array of child elements is validated.
0054 //
0055 //  Since we have the actual XMLElementDecl in the stack nodes, when its time
0056 //  to validate, we just extract the content model from that element decl
0057 //  and validate. All the required data falls easily to hand. Note that we
0058 //  actually have some derivative of XMLElementDecl, which is specific to
0059 //  the validator used, but the abstract API is sufficient for the needs of
0060 //  the scanner.
0061 //
0062 //  Since the namespace support also requires the storage of information on
0063 //  a nested element basis, this structure also holds the namespace info. For
0064 //  each level, the prefixes defined at that level (and the namespaces that
0065 //  they map to) are stored.
0066 //
0067 class XMLPARSER_EXPORT ElemStack : public XMemory
0068 {
0069 public :
0070     // -----------------------------------------------------------------------
0071     //  Class specific data types
0072     //
0073     //  These really should be private, but some of the compilers we have to
0074     //  support are too dumb to deal with that.
0075     //
0076     //  PrefMapElem
0077     //      fURIId is the id of the URI from the validator's URI map. The
0078     //      fPrefId is the id of the prefix from our own prefix pool. The
0079     //      namespace stack consists of these elements.
0080     //
0081     //  StackElem
0082     //      fThisElement is the basic element decl for the current element.
0083     //      The fRowCapacity is how large fChildIds has grown so far.
0084     //      fChildCount is how many of them are valid right now.
0085     //
0086     //      The fMapCapacity is how large fMap has grown so far. fMapCount
0087     //      is how many of them are valid right now.
0088     //
0089     //      Note that we store the reader number we were in when we found the
0090     //      start tag. We'll use this at the end tag to test for unbalanced
0091     //      markup in entities.
0092     //
0093     //  MapModes
0094     //      When a prefix is mapped to a namespace id, it matters whether the
0095     //      QName being mapped is an attribute or name. Attributes are not
0096     //      affected by an sibling xmlns attributes, whereas elements are
0097     //      affected by its own xmlns attributes.
0098     // -----------------------------------------------------------------------
0099     struct StackElem : public XMemory
0100     {
0101         XMLElementDecl*     fThisElement;
0102         XMLSize_t           fReaderNum;
0103 
0104         XMLSize_t           fChildCapacity;
0105         XMLSize_t           fChildCount;
0106         QName**             fChildren;
0107 
0108         PrefMapElem*        fMap;
0109         XMLSize_t           fMapCapacity;
0110         XMLSize_t           fMapCount;
0111 
0112         bool                fValidationFlag;
0113         bool                fCommentOrPISeen;
0114         bool                fReferenceEscaped;
0115         unsigned int        fCurrentScope;
0116         Grammar*            fCurrentGrammar;
0117         unsigned int        fCurrentURI;
0118         XMLCh *             fSchemaElemName;
0119         XMLSize_t           fSchemaElemNameMaxLen;
0120         
0121         int                 fPrefixColonPos;
0122     };
0123 
0124     enum MapModes
0125     {
0126         Mode_Attribute
0127         , Mode_Element
0128     };
0129 
0130 
0131     // -----------------------------------------------------------------------
0132     //  Constructors and Destructor
0133     // -----------------------------------------------------------------------
0134     ElemStack(MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
0135     ~ElemStack();
0136 
0137 
0138     // -----------------------------------------------------------------------
0139     //  Stack access
0140     // -----------------------------------------------------------------------
0141     XMLSize_t addLevel();
0142     XMLSize_t addLevel(XMLElementDecl* const toSet, const XMLSize_t readerNum);
0143     const StackElem* popTop();
0144 
0145 
0146     // -----------------------------------------------------------------------
0147     //  Stack top access
0148     // -----------------------------------------------------------------------
0149     XMLSize_t addChild(QName* const child, const bool toParent);
0150     const StackElem* topElement() const;
0151     void setElement(XMLElementDecl* const toSet, const XMLSize_t readerNum);
0152 
0153     void setValidationFlag(bool validationFlag);
0154     bool getValidationFlag();
0155 
0156     inline void setCommentOrPISeen();
0157     inline bool getCommentOrPISeen() const;
0158 
0159     inline void setReferenceEscaped();
0160     inline bool getReferenceEscaped() const;
0161 
0162     void setCurrentScope(int currentScope);
0163     int getCurrentScope();
0164 
0165     void setCurrentGrammar(Grammar* currentGrammar);
0166     Grammar* getCurrentGrammar();
0167 
0168     void setCurrentURI(unsigned int uri);
0169     unsigned int getCurrentURI();
0170 
0171     inline void setCurrentSchemaElemName(const XMLCh * const schemaElemName);
0172     inline XMLCh *getCurrentSchemaElemName();
0173 
0174     void setPrefixColonPos(int colonPos);
0175     int getPrefixColonPos() const;
0176 
0177     // -----------------------------------------------------------------------
0178     //  Prefix map methods
0179     // -----------------------------------------------------------------------
0180     void addGlobalPrefix
0181     (
0182         const   XMLCh* const    prefixToAdd
0183         , const unsigned int    uriId
0184     );
0185     void addPrefix
0186     (
0187         const   XMLCh* const    prefixToAdd
0188         , const unsigned int    uriId
0189     );
0190     unsigned int mapPrefixToURI
0191     (
0192         const   XMLCh* const    prefixToMap
0193         ,       bool&           unknown
0194     )   const;
0195     ValueVectorOf<PrefMapElem*>* getNamespaceMap() const;
0196     unsigned int getPrefixId(const XMLCh* const prefix) const;
0197     const XMLCh* getPrefixForId(unsigned int prefId) const;
0198 
0199     // -----------------------------------------------------------------------
0200     //  Miscellaneous methods
0201     // -----------------------------------------------------------------------
0202     bool isEmpty() const;
0203     void reset
0204     (
0205         const   unsigned int    emptyId
0206         , const unsigned int    unknownId
0207         , const unsigned int    xmlId
0208         , const unsigned int    xmlNSId
0209     );
0210 
0211     unsigned int getEmptyNamespaceId();
0212 
0213 private :
0214     // -----------------------------------------------------------------------
0215     //  Unimplemented constructors and operators
0216     // -----------------------------------------------------------------------
0217     ElemStack(const ElemStack&);
0218     ElemStack& operator=(const ElemStack&);
0219 
0220 
0221     // -----------------------------------------------------------------------
0222     //  Private helper methods
0223     // -----------------------------------------------------------------------
0224     void expandMap(StackElem* const toExpand);
0225     void expandStack();
0226 
0227 
0228     // -----------------------------------------------------------------------
0229     //  Data members
0230     //
0231     //  fEmptyNamespaceId
0232     //      This is the special URI id for the "" namespace, which is magic
0233     //      because of the xmlns="" operation.
0234     //
0235     //  fGlobalPoolId
0236     //      This is a special URI id that is returned when the namespace
0237     //      prefix is "" and no one has explicitly mapped that prefix to an
0238     //      explicit URI (or when they explicitly clear any such mapping,
0239     //      which they can also do.) And also its prefix pool id, which is
0240     //      stored here for fast access.
0241     //
0242     //  fPrefixPool
0243     //      This is the prefix pool where prefixes are hashed and given unique
0244     //      ids. These ids are used to track prefixes in the element stack.
0245     //
0246     //  fGlobalNamespaces
0247     //      This object contains the namespace bindings that are globally valid 
0248     //
0249     //  fStack
0250     //  fStackCapacity
0251     //  fStackTop
0252     //      This the stack array. Its an array of pointers to StackElem
0253     //      structures. The capacity is the current high water mark of the
0254     //      stack. The top is the current top of stack (i.e. the part of it
0255     //      being used.)
0256     //
0257     //  fUnknownNamespaceId
0258     //      This is the URI id for the special URI that is assigned to any
0259     //      prefix which has not been mapped. This lets us keep going after
0260     //      issuing the error.
0261     //
0262     //  fXMLNamespaceId
0263     //  fXMLPoolId
0264     //  fXMLNSNamespaceId
0265     //  fXMLNSPoolId
0266     //      These are the URI ids for the special URIs that are assigned to
0267     //      the 'xml' and 'xmlns' namespaces. And also its prefix pool id,
0268     //      which is stored here for fast access.
0269     // -----------------------------------------------------------------------
0270     unsigned int                 fEmptyNamespaceId;
0271     unsigned int                 fGlobalPoolId;
0272     XMLStringPool                fPrefixPool;
0273     StackElem*                   fGlobalNamespaces;
0274     StackElem**                  fStack;
0275     XMLSize_t                    fStackCapacity;
0276     XMLSize_t                    fStackTop;
0277     unsigned int                 fUnknownNamespaceId;
0278     unsigned int                 fXMLNamespaceId;
0279     unsigned int                 fXMLPoolId;
0280     unsigned int                 fXMLNSNamespaceId;
0281     unsigned int                 fXMLNSPoolId;
0282     ValueVectorOf<PrefMapElem*>* fNamespaceMap;
0283     MemoryManager*               fMemoryManager;
0284 };
0285 
0286 
0287 class XMLPARSER_EXPORT WFElemStack : public XMemory
0288 {
0289 public :
0290     // -----------------------------------------------------------------------
0291     //  Class specific data types
0292     //
0293     //  These really should be private, but some of the compilers we have to
0294     //  support are too dumb to deal with that.
0295     //
0296     //  PrefMapElem
0297     //      fURIId is the id of the URI from the validator's URI map. The
0298     //      fPrefId is the id of the prefix from our own prefix pool. The
0299     //      namespace stack consists of these elements.
0300     //
0301     //  StackElem
0302     //      fThisElement is the basic element decl for the current element.
0303     //      The fRowCapacity is how large fChildIds has grown so far.
0304     //      fChildCount is how many of them are valid right now.
0305     //
0306     //      The fMapCapacity is how large fMap has grown so far. fMapCount
0307     //      is how many of them are valid right now.
0308     //
0309     //      Note that we store the reader number we were in when we found the
0310     //      start tag. We'll use this at the end tag to test for unbalanced
0311     //      markup in entities.
0312     //
0313     //  MapModes
0314     //      When a prefix is mapped to a namespace id, it matters whether the
0315     //      QName being mapped is an attribute or name. Attributes are not
0316     //      affected by an sibling xmlns attributes, whereas elements are
0317     //      affected by its own xmlns attributes.
0318     // -----------------------------------------------------------------------
0319     struct StackElem : public XMemory
0320     {
0321         int                 fTopPrefix;        
0322         unsigned int        fCurrentURI;
0323         unsigned int        fReaderNum;
0324         unsigned int        fElemMaxLength;
0325         XMLCh*              fThisElement;
0326     };
0327 
0328     enum MapModes
0329     {
0330         Mode_Attribute
0331         , Mode_Element
0332     };
0333 
0334 
0335     // -----------------------------------------------------------------------
0336     //  Constructors and Destructor
0337     // -----------------------------------------------------------------------
0338     WFElemStack(MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
0339     ~WFElemStack();
0340 
0341 
0342     // -----------------------------------------------------------------------
0343     //  Stack access
0344     // -----------------------------------------------------------------------
0345     XMLSize_t addLevel();
0346     XMLSize_t addLevel(const XMLCh* const toSet, const unsigned int toSetLen,
0347                           const unsigned int readerNum);
0348     const StackElem* popTop();
0349 
0350 
0351     // -----------------------------------------------------------------------
0352     //  Stack top access
0353     // -----------------------------------------------------------------------
0354     const StackElem* topElement() const;
0355     void setElement(const XMLCh* const toSet, const unsigned int toSetLen,
0356                     const unsigned int readerNum);
0357 
0358     void setCurrentURI(unsigned int uri);
0359     unsigned int getCurrentURI();
0360 
0361     // -----------------------------------------------------------------------
0362     //  Prefix map methods
0363     // -----------------------------------------------------------------------
0364     void addPrefix
0365     (
0366         const   XMLCh* const    prefixToAdd
0367         , const unsigned int    uriId
0368     );
0369     unsigned int mapPrefixToURI
0370     (
0371         const   XMLCh* const    prefixToMap
0372         ,       bool&           unknown
0373     )   const;
0374 
0375 
0376     // -----------------------------------------------------------------------
0377     //  Miscellaneous methods
0378     // -----------------------------------------------------------------------
0379     bool isEmpty() const;
0380     void reset
0381     (
0382         const   unsigned int    emptyId
0383         , const unsigned int    unknownId
0384         , const unsigned int    xmlId
0385         , const unsigned int    xmlNSId
0386     );
0387 
0388 
0389 private :
0390     // -----------------------------------------------------------------------
0391     //  Unimplemented constructors and operators
0392     // -----------------------------------------------------------------------
0393     WFElemStack(const WFElemStack&);
0394     WFElemStack& operator=(const WFElemStack&);
0395 
0396 
0397     // -----------------------------------------------------------------------
0398     //  Private helper methods
0399     // -----------------------------------------------------------------------
0400     void expandMap();
0401     void expandStack();
0402 
0403 
0404     // -----------------------------------------------------------------------
0405     //  Data members
0406     //
0407     //  fEmptyNamespaceId
0408     //      This is the special URI id for the "" namespace, which is magic
0409     //      because of the xmlns="" operation.
0410     //
0411     //  fGlobalPoolId
0412     //      This is a special URI id that is returned when the namespace
0413     //      prefix is "" and no one has explicitly mapped that prefix to an
0414     //      explicit URI (or when they explicitly clear any such mapping,
0415     //      which they can also do.) And also its prefix pool id, which is
0416     //      stored here for fast access.
0417     //
0418     //  fPrefixPool
0419     //      This is the prefix pool where prefixes are hashed and given unique
0420     //      ids. These ids are used to track prefixes in the element stack.
0421     //
0422     //  fStack
0423     //  fStackCapacity
0424     //  fStackTop
0425     //      This the stack array. Its an array of pointers to StackElem
0426     //      structures. The capacity is the current high water mark of the
0427     //      stack. The top is the current top of stack (i.e. the part of it
0428     //      being used.)
0429     //
0430     //  fUnknownNamespaceId
0431     //      This is the URI id for the special URI that is assigned to any
0432     //      prefix which has not been mapped. This lets us keep going after
0433     //      issuing the error.
0434     //
0435     //  fXMLNamespaceId
0436     //  fXMLPoolId
0437     //  fXMLNSNamespaceId
0438     //  fXMLNSPoolId
0439     //      These are the URI ids for the special URIs that are assigned to
0440     //      the 'xml' and 'xmlns' namespaces. And also its prefix pool id,
0441     //      which is stored here for fast access.
0442     // -----------------------------------------------------------------------
0443     unsigned int    fEmptyNamespaceId;
0444     unsigned int    fGlobalPoolId;
0445     XMLSize_t       fStackCapacity;
0446     XMLSize_t       fStackTop;
0447     unsigned int    fUnknownNamespaceId;
0448     unsigned int    fXMLNamespaceId;
0449     unsigned int    fXMLPoolId;
0450     unsigned int    fXMLNSNamespaceId;
0451     unsigned int    fXMLNSPoolId;
0452     XMLSize_t       fMapCapacity;
0453     PrefMapElem*    fMap;
0454     StackElem**     fStack;
0455     XMLStringPool   fPrefixPool;
0456     MemoryManager*  fMemoryManager;
0457 };
0458 
0459 
0460 // ---------------------------------------------------------------------------
0461 //  ElemStack: Miscellaneous methods
0462 // ---------------------------------------------------------------------------
0463 inline bool ElemStack::isEmpty() const
0464 {
0465     return (fStackTop == 0);
0466 }
0467 
0468 inline bool ElemStack::getValidationFlag()
0469 {
0470     return fStack[fStackTop-1]->fValidationFlag;
0471 }
0472 
0473 inline void ElemStack::setValidationFlag(bool validationFlag)
0474 {
0475     fStack[fStackTop-1]->fValidationFlag = validationFlag;
0476 }
0477 
0478 inline bool ElemStack::getCommentOrPISeen() const
0479 {
0480     return fStack[fStackTop-1]->fCommentOrPISeen;
0481 }
0482 
0483 inline void ElemStack::setCommentOrPISeen()
0484 {
0485     fStack[fStackTop-1]->fCommentOrPISeen = true;
0486 }
0487 
0488 inline bool ElemStack::getReferenceEscaped() const
0489 {
0490     return fStack[fStackTop-1]->fReferenceEscaped;
0491 }
0492 
0493 inline void ElemStack::setReferenceEscaped()
0494 {
0495     fStack[fStackTop-1]->fReferenceEscaped = true;
0496 }
0497 
0498 inline void ElemStack::setCurrentSchemaElemName(const XMLCh * const schemaElemName)
0499 {
0500     XMLSize_t schemaElemNameLen = XMLString::stringLen(schemaElemName);
0501     XMLSize_t stackPos = fStackTop-1;
0502     
0503     if(fStack[stackPos]->fSchemaElemNameMaxLen <= schemaElemNameLen)
0504     {
0505         XMLCh *tempStr = fStack[stackPos]->fSchemaElemName;
0506         fStack[stackPos]->fSchemaElemNameMaxLen = schemaElemNameLen << 1;
0507         fStack[stackPos]->fSchemaElemName = (XMLCh *)fMemoryManager->allocate((fStack[stackPos]->fSchemaElemNameMaxLen)*sizeof(XMLCh));
0508         fMemoryManager->deallocate(tempStr);
0509     }
0510     XMLString::copyString(fStack[stackPos]->fSchemaElemName, schemaElemName);
0511 }
0512 
0513 inline XMLCh *ElemStack::getCurrentSchemaElemName()
0514 {
0515     return fStack[fStackTop-1]->fSchemaElemName;
0516 }
0517 
0518 inline int ElemStack::getCurrentScope()
0519 {
0520     return fStack[fStackTop-1]->fCurrentScope;
0521 }
0522 
0523 inline void ElemStack::setCurrentScope(int currentScope)
0524 {
0525     fStack[fStackTop-1]->fCurrentScope = currentScope;
0526 }
0527 
0528 inline Grammar* ElemStack::getCurrentGrammar()
0529 {
0530     return fStack[fStackTop-1]->fCurrentGrammar;
0531 }
0532 
0533 inline void ElemStack::setCurrentGrammar(Grammar* currentGrammar)
0534 {
0535     fStack[fStackTop-1]->fCurrentGrammar = currentGrammar;
0536 }
0537 
0538 inline unsigned int ElemStack::getCurrentURI()
0539 {
0540     return fStack[fStackTop-1]->fCurrentURI;
0541 }
0542 
0543 inline void ElemStack::setCurrentURI(unsigned int uri)
0544 {
0545     fStack[fStackTop-1]->fCurrentURI = uri;
0546 }
0547 
0548 inline unsigned int ElemStack::getPrefixId(const XMLCh* const prefix) const
0549 {
0550     return fPrefixPool.getId(prefix);
0551 }
0552 
0553 inline const XMLCh* ElemStack::getPrefixForId(unsigned int prefId) const
0554 {
0555     return fPrefixPool.getValueForId(prefId);
0556 }
0557 
0558 inline void ElemStack::setPrefixColonPos(int colonPos)
0559 {
0560     fStack[fStackTop-1]->fPrefixColonPos = colonPos;
0561 }
0562  
0563 inline int ElemStack::getPrefixColonPos() const {
0564     return fStack[fStackTop-1]->fPrefixColonPos;
0565 }
0566 
0567 inline unsigned int ElemStack::getEmptyNamespaceId() {
0568     return fEmptyNamespaceId;
0569 }
0570 
0571 // ---------------------------------------------------------------------------
0572 //  WFElemStack: Miscellaneous methods
0573 // ---------------------------------------------------------------------------
0574 inline bool WFElemStack::isEmpty() const
0575 {
0576     return (fStackTop == 0);
0577 }
0578 
0579 inline unsigned int WFElemStack::getCurrentURI()
0580 {
0581     return fStack[fStackTop-1]->fCurrentURI;
0582 }
0583 
0584 inline void WFElemStack::setCurrentURI(unsigned int uri)
0585 {
0586     fStack[fStackTop-1]->fCurrentURI = uri;
0587 }
0588 
0589 
0590 XERCES_CPP_NAMESPACE_END
0591 
0592 #endif