source: NonGTP/Xerces/xerces-c_2_8_0/include/xercesc/internal/ElemStack.hpp @ 2674

Revision 2674, 20.1 KB checked in by mattausch, 16 years ago (diff)
Line 
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18/*
19 * $Id: ElemStack.hpp 568078 2007-08-21 11:43:25Z amassari $
20 */
21
22#if !defined(ELEMSTACK_HPP)
23#define ELEMSTACK_HPP
24
25#include <xercesc/util/StringPool.hpp>
26#include <xercesc/util/QName.hpp>
27#include <xercesc/util/ValueVectorOf.hpp>
28
29XERCES_CPP_NAMESPACE_BEGIN
30
31class XMLElementDecl;
32class Grammar;
33
34struct PrefMapElem : public XMemory
35{
36    unsigned int        fPrefId;
37    unsigned int        fURIId;
38};
39
40//
41//  During the scan of content, we have to keep up with the nesting of
42//  elements (for validation and wellformedness purposes) and we have to
43//  have places to remember namespace (prefix to URI) mappings.
44//
45//  We only have to keep a stack of the current path down through the tree
46//  that we are currently scanning, and keep track of any children of any
47//  elements along that path.
48//
49//  So, this data structure is a stack, which represents the current path
50//  through the tree that we've worked our way down to. For each node in
51//  the stack, there is an array of element ids that represent the ids of
52//  the child elements scanned so far. Upon exit from that element, its
53//  array of child elements is validated.
54//
55//  Since we have the actual XMLElementDecl in the stack nodes, when its time
56//  to validate, we just extract the content model from that element decl
57//  and validate. All the required data falls easily to hand. Note that we
58//  actually have some derivative of XMLElementDecl, which is specific to
59//  the validator used, but the abstract API is sufficient for the needs of
60//  the scanner.
61//
62//  Since the namespace support also requires the storage of information on
63//  a nested element basis, this structure also holds the namespace info. For
64//  each level, the prefixes defined at that level (and the namespaces that
65//  they map to) are stored.
66//
67class XMLPARSER_EXPORT ElemStack : public XMemory
68{
69public :
70    // -----------------------------------------------------------------------
71    //  Class specific data types
72    //
73    //  These really should be private, but some of the compilers we have to
74    //  support are too dumb to deal with that.
75    //
76    //  PrefMapElem
77    //      fURIId is the id of the URI from the validator's URI map. The
78    //      fPrefId is the id of the prefix from our own prefix pool. The
79    //      namespace stack consists of these elements.
80    //
81    //  StackElem
82    //      fThisElement is the basic element decl for the current element.
83    //      The fRowCapacity is how large fChildIds has grown so far.
84    //      fChildCount is how many of them are valid right now.
85    //
86    //      The fMapCapacity is how large fMap has grown so far. fMapCount
87    //      is how many of them are valid right now.
88    //
89    //      Note that we store the reader number we were in when we found the
90    //      start tag. We'll use this at the end tag to test for unbalanced
91    //      markup in entities.
92    //
93    //  MapModes
94    //      When a prefix is mapped to a namespace id, it matters whether the
95    //      QName being mapped is an attribute or name. Attributes are not
96    //      affected by an sibling xmlns attributes, whereas elements are
97    //      affected by its own xmlns attributes.
98    // -----------------------------------------------------------------------
99    struct StackElem : public XMemory
100    {
101        XMLElementDecl*     fThisElement;
102        unsigned int        fReaderNum;
103
104        unsigned int        fChildCapacity;
105        unsigned int        fChildCount;
106        QName**             fChildren;
107
108        PrefMapElem*        fMap;
109        unsigned int        fMapCapacity;
110        unsigned int        fMapCount;
111
112        bool                fValidationFlag;
113        bool                fCommentOrPISeen;
114        bool                fReferenceEscaped;
115        int                 fCurrentScope;
116        Grammar*            fCurrentGrammar;
117        unsigned int        fCurrentURI;
118        XMLCh *             fSchemaElemName;
119        unsigned int        fSchemaElemNameMaxLen;
120       
121        int                 fPrefixColonPos;
122    };
123
124    enum MapModes
125    {
126        Mode_Attribute
127        , Mode_Element
128    };
129
130
131    // -----------------------------------------------------------------------
132    //  Constructors and Destructor
133    // -----------------------------------------------------------------------
134    ElemStack(MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
135    ~ElemStack();
136
137
138    // -----------------------------------------------------------------------
139    //  Stack access
140    // -----------------------------------------------------------------------
141    unsigned int addLevel();
142    unsigned int addLevel(XMLElementDecl* const toSet, const unsigned int readerNum);
143    const StackElem* popTop();
144
145
146    // -----------------------------------------------------------------------
147    //  Stack top access
148    // -----------------------------------------------------------------------
149    unsigned int addChild(QName* const child, const bool toParent);
150    const StackElem* topElement() const;
151    void setElement(XMLElementDecl* const toSet, const unsigned int readerNum);
152
153    void setValidationFlag(bool validationFlag);
154    bool getValidationFlag();
155
156    inline void setCommentOrPISeen();
157    inline bool getCommentOrPISeen() const;
158
159    inline void setReferenceEscaped();
160    inline bool getReferenceEscaped() const;
161
162    void setCurrentScope(int currentScope);
163    int getCurrentScope();
164
165    void setCurrentGrammar(Grammar* currentGrammar);
166    Grammar* getCurrentGrammar();
167
168    void setCurrentURI(unsigned int uri);
169    unsigned int getCurrentURI();
170
171    inline void setCurrentSchemaElemName(const XMLCh * const schemaElemName);
172    inline XMLCh *getCurrentSchemaElemName();
173
174    void setPrefixColonPos(int colonPos);
175    int getPrefixColonPos() const;
176
177    // -----------------------------------------------------------------------
178    //  Prefix map methods
179    // -----------------------------------------------------------------------
180    void addPrefix
181    (
182        const   XMLCh* const    prefixToAdd
183        , const unsigned int    uriId
184    );
185    unsigned int mapPrefixToURI
186    (
187        const   XMLCh* const    prefixToMap
188        , const MapModes        mode
189        ,       bool&           unknown
190    )   const;
191    ValueVectorOf<PrefMapElem*>* getNamespaceMap() const;
192    unsigned int getPrefixId(const XMLCh* const prefix) const;
193    const XMLCh* getPrefixForId(unsigned int prefId) const;
194
195    // -----------------------------------------------------------------------
196    //  Miscellaneous methods
197    // -----------------------------------------------------------------------
198    bool isEmpty() const;
199    void reset
200    (
201        const   unsigned int    emptyId
202        , const unsigned int    unknownId
203        , const unsigned int    xmlId
204        , const unsigned int    xmlNSId
205    );
206
207
208private :
209    // -----------------------------------------------------------------------
210    //  Unimplemented constructors and operators
211    // -----------------------------------------------------------------------
212    ElemStack(const ElemStack&);
213    ElemStack& operator=(const ElemStack&);
214
215
216    // -----------------------------------------------------------------------
217    //  Private helper methods
218    // -----------------------------------------------------------------------
219    void expandMap(StackElem* const toExpand);
220    void expandStack();
221
222
223    // -----------------------------------------------------------------------
224    //  Data members
225    //
226    //  fEmptyNamespaceId
227    //      This is the special URI id for the "" namespace, which is magic
228    //      because of the xmlns="" operation.
229    //
230    //  fGlobalPoolId
231    //      This is a special URI id that is returned when the namespace
232    //      prefix is "" and no one has explicitly mapped that prefix to an
233    //      explicit URI (or when they explicitly clear any such mapping,
234    //      which they can also do.) And also its prefix pool id, which is
235    //      stored here for fast access.
236    //
237    //  fPrefixPool
238    //      This is the prefix pool where prefixes are hashed and given unique
239    //      ids. These ids are used to track prefixes in the element stack.
240    //
241    //  fStack
242    //  fStackCapacity
243    //  fStackTop
244    //      This the stack array. Its an array of pointers to StackElem
245    //      structures. The capacity is the current high water mark of the
246    //      stack. The top is the current top of stack (i.e. the part of it
247    //      being used.)
248    //
249    //  fUnknownNamespaceId
250    //      This is the URI id for the special URI that is assigned to any
251    //      prefix which has not been mapped. This lets us keep going after
252    //      issuing the error.
253    //
254    //  fXMLNamespaceId
255    //  fXMLPoolId
256    //  fXMLNSNamespaceId
257    //  fXMLNSPoolId
258    //      These are the URI ids for the special URIs that are assigned to
259    //      the 'xml' and 'xmlns' namespaces. And also its prefix pool id,
260    //      which is stored here for fast access.
261    // -----------------------------------------------------------------------
262    unsigned int                 fEmptyNamespaceId;
263    unsigned int                 fGlobalPoolId;
264    XMLStringPool                fPrefixPool;
265    StackElem**                  fStack;
266    unsigned int                 fStackCapacity;
267    unsigned int                 fStackTop;
268    unsigned int                 fUnknownNamespaceId;
269    unsigned int                 fXMLNamespaceId;
270    unsigned int                 fXMLPoolId;
271    unsigned int                 fXMLNSNamespaceId;
272    unsigned int                 fXMLNSPoolId;
273    ValueVectorOf<PrefMapElem*>* fNamespaceMap;
274    MemoryManager*               fMemoryManager;
275};
276
277
278class XMLPARSER_EXPORT WFElemStack : public XMemory
279{
280public :
281    // -----------------------------------------------------------------------
282    //  Class specific data types
283    //
284    //  These really should be private, but some of the compilers we have to
285    //  support are too dumb to deal with that.
286    //
287    //  PrefMapElem
288    //      fURIId is the id of the URI from the validator's URI map. The
289    //      fPrefId is the id of the prefix from our own prefix pool. The
290    //      namespace stack consists of these elements.
291    //
292    //  StackElem
293    //      fThisElement is the basic element decl for the current element.
294    //      The fRowCapacity is how large fChildIds has grown so far.
295    //      fChildCount is how many of them are valid right now.
296    //
297    //      The fMapCapacity is how large fMap has grown so far. fMapCount
298    //      is how many of them are valid right now.
299    //
300    //      Note that we store the reader number we were in when we found the
301    //      start tag. We'll use this at the end tag to test for unbalanced
302    //      markup in entities.
303    //
304    //  MapModes
305    //      When a prefix is mapped to a namespace id, it matters whether the
306    //      QName being mapped is an attribute or name. Attributes are not
307    //      affected by an sibling xmlns attributes, whereas elements are
308    //      affected by its own xmlns attributes.
309    // -----------------------------------------------------------------------
310    struct StackElem : public XMemory
311    {
312        int                 fTopPrefix;       
313        unsigned int        fCurrentURI;
314        unsigned int        fReaderNum;
315        unsigned int        fElemMaxLength;
316        XMLCh*              fThisElement;
317    };
318
319    enum MapModes
320    {
321        Mode_Attribute
322        , Mode_Element
323    };
324
325
326    // -----------------------------------------------------------------------
327    //  Constructors and Destructor
328    // -----------------------------------------------------------------------
329    WFElemStack(MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
330    ~WFElemStack();
331
332
333    // -----------------------------------------------------------------------
334    //  Stack access
335    // -----------------------------------------------------------------------
336    unsigned int addLevel();
337    unsigned int addLevel(const XMLCh* const toSet, const unsigned int toSetLen,
338                          const unsigned int readerNum);
339    const StackElem* popTop();
340
341
342    // -----------------------------------------------------------------------
343    //  Stack top access
344    // -----------------------------------------------------------------------
345    const StackElem* topElement() const;
346    void setElement(const XMLCh* const toSet, const unsigned int toSetLen,
347                    const unsigned int readerNum);
348
349    void setCurrentURI(unsigned int uri);
350    unsigned int getCurrentURI();
351
352    // -----------------------------------------------------------------------
353    //  Prefix map methods
354    // -----------------------------------------------------------------------
355    void addPrefix
356    (
357        const   XMLCh* const    prefixToAdd
358        , const unsigned int    uriId
359    );
360    unsigned int mapPrefixToURI
361    (
362        const   XMLCh* const    prefixToMap
363        , const MapModes        mode
364        ,       bool&           unknown
365    )   const;
366
367
368    // -----------------------------------------------------------------------
369    //  Miscellaneous methods
370    // -----------------------------------------------------------------------
371    bool isEmpty() const;
372    void reset
373    (
374        const   unsigned int    emptyId
375        , const unsigned int    unknownId
376        , const unsigned int    xmlId
377        , const unsigned int    xmlNSId
378    );
379
380
381private :
382    // -----------------------------------------------------------------------
383    //  Unimplemented constructors and operators
384    // -----------------------------------------------------------------------
385    WFElemStack(const WFElemStack&);
386    WFElemStack& operator=(const WFElemStack&);
387
388
389    // -----------------------------------------------------------------------
390    //  Private helper methods
391    // -----------------------------------------------------------------------
392    void expandMap();
393    void expandStack();
394
395
396    // -----------------------------------------------------------------------
397    //  Data members
398    //
399    //  fEmptyNamespaceId
400    //      This is the special URI id for the "" namespace, which is magic
401    //      because of the xmlns="" operation.
402    //
403    //  fGlobalPoolId
404    //      This is a special URI id that is returned when the namespace
405    //      prefix is "" and no one has explicitly mapped that prefix to an
406    //      explicit URI (or when they explicitly clear any such mapping,
407    //      which they can also do.) And also its prefix pool id, which is
408    //      stored here for fast access.
409    //
410    //  fPrefixPool
411    //      This is the prefix pool where prefixes are hashed and given unique
412    //      ids. These ids are used to track prefixes in the element stack.
413    //
414    //  fStack
415    //  fStackCapacity
416    //  fStackTop
417    //      This the stack array. Its an array of pointers to StackElem
418    //      structures. The capacity is the current high water mark of the
419    //      stack. The top is the current top of stack (i.e. the part of it
420    //      being used.)
421    //
422    //  fUnknownNamespaceId
423    //      This is the URI id for the special URI that is assigned to any
424    //      prefix which has not been mapped. This lets us keep going after
425    //      issuing the error.
426    //
427    //  fXMLNamespaceId
428    //  fXMLPoolId
429    //  fXMLNSNamespaceId
430    //  fXMLNSPoolId
431    //      These are the URI ids for the special URIs that are assigned to
432    //      the 'xml' and 'xmlns' namespaces. And also its prefix pool id,
433    //      which is stored here for fast access.
434    // -----------------------------------------------------------------------
435    unsigned int    fEmptyNamespaceId;
436    unsigned int    fGlobalPoolId;
437    unsigned int    fStackCapacity;
438    unsigned int    fStackTop;
439    unsigned int    fUnknownNamespaceId;
440    unsigned int    fXMLNamespaceId;
441    unsigned int    fXMLPoolId;
442    unsigned int    fXMLNSNamespaceId;
443    unsigned int    fXMLNSPoolId;
444    unsigned int    fMapCapacity;
445    PrefMapElem*    fMap;
446    StackElem**     fStack;
447    XMLStringPool   fPrefixPool;
448    MemoryManager*  fMemoryManager;
449};
450
451
452// ---------------------------------------------------------------------------
453//  ElemStack: Miscellaneous methods
454// ---------------------------------------------------------------------------
455inline bool ElemStack::isEmpty() const
456{
457    return (fStackTop == 0);
458}
459
460inline bool ElemStack::getValidationFlag()
461{
462    return fStack[fStackTop-1]->fValidationFlag;
463}
464
465inline void ElemStack::setValidationFlag(bool validationFlag)
466{
467    fStack[fStackTop-1]->fValidationFlag = validationFlag;
468    return;
469}
470
471inline bool ElemStack::getCommentOrPISeen() const
472{
473    return fStack[fStackTop-1]->fCommentOrPISeen;
474}
475
476inline void ElemStack::setCommentOrPISeen()
477{
478    fStack[fStackTop-1]->fCommentOrPISeen = true;
479    return;
480}
481
482inline bool ElemStack::getReferenceEscaped() const
483{
484    return fStack[fStackTop-1]->fReferenceEscaped;
485}
486
487inline void ElemStack::setReferenceEscaped()
488{
489    fStack[fStackTop-1]->fReferenceEscaped = true;
490    return;
491}
492
493inline void ElemStack::setCurrentSchemaElemName(const XMLCh * const schemaElemName)
494{
495    unsigned int schemaElemNameLen = XMLString::stringLen(schemaElemName);
496    unsigned int stackPos = fStackTop-1;
497   
498    if(fStack[stackPos]->fSchemaElemNameMaxLen <= schemaElemNameLen)
499    {
500        XMLCh *tempStr = fStack[stackPos]->fSchemaElemName;
501        fStack[stackPos]->fSchemaElemNameMaxLen = schemaElemNameLen << 1;
502        fStack[stackPos]->fSchemaElemName = (XMLCh *)fMemoryManager->allocate((fStack[stackPos]->fSchemaElemNameMaxLen)*sizeof(XMLCh));
503        fMemoryManager->deallocate(tempStr);
504    }
505    XMLString::copyString(fStack[stackPos]->fSchemaElemName, schemaElemName);
506}
507
508inline XMLCh *ElemStack::getCurrentSchemaElemName()
509{
510    return fStack[fStackTop-1]->fSchemaElemName;
511}
512
513inline int ElemStack::getCurrentScope()
514{
515    return fStack[fStackTop-1]->fCurrentScope;
516}
517
518inline void ElemStack::setCurrentScope(int currentScope)
519{
520    fStack[fStackTop-1]->fCurrentScope = currentScope;
521    return;
522}
523
524inline Grammar* ElemStack::getCurrentGrammar()
525{
526    return fStack[fStackTop-1]->fCurrentGrammar;
527}
528
529inline void ElemStack::setCurrentGrammar(Grammar* currentGrammar)
530{
531    fStack[fStackTop-1]->fCurrentGrammar = currentGrammar;
532    return;
533}
534
535inline unsigned int ElemStack::getCurrentURI()
536{
537    return fStack[fStackTop-1]->fCurrentURI;
538}
539
540inline void ElemStack::setCurrentURI(unsigned int uri)
541{
542    fStack[fStackTop-1]->fCurrentURI = uri;
543    return;
544}
545
546inline unsigned int ElemStack::getPrefixId(const XMLCh* const prefix) const
547{
548    return fPrefixPool.getId(prefix);
549}
550
551inline const XMLCh* ElemStack::getPrefixForId(unsigned int prefId) const
552{
553    return fPrefixPool.getValueForId(prefId);
554}
555
556inline void ElemStack::setPrefixColonPos(int colonPos)
557{
558    fStack[fStackTop-1]->fPrefixColonPos = colonPos;
559}
560 
561inline int ElemStack::getPrefixColonPos() const {
562    return fStack[fStackTop-1]->fPrefixColonPos;
563}
564
565// ---------------------------------------------------------------------------
566//  WFElemStack: Miscellaneous methods
567// ---------------------------------------------------------------------------
568inline bool WFElemStack::isEmpty() const
569{
570    return (fStackTop == 0);
571}
572
573inline unsigned int WFElemStack::getCurrentURI()
574{
575    return fStack[fStackTop-1]->fCurrentURI;
576}
577
578inline void WFElemStack::setCurrentURI(unsigned int uri)
579{
580    fStack[fStackTop-1]->fCurrentURI = uri;
581    return;
582}
583
584
585XERCES_CPP_NAMESPACE_END
586
587#endif
Note: See TracBrowser for help on using the repository browser.