source: NonGTP/Xerces/xerces/include/xercesc/internal/ElemStack.hpp @ 358

Revision 358, 22.6 KB checked in by bittner, 19 years ago (diff)

xerces added

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