source: NonGTP/Xerces/xercesc/internal/ElemStack.hpp @ 188

Revision 188, 22.3 KB checked in by mattausch, 19 years ago (diff)

added xercesc to support

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