|
||||
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
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |