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