Xalan-C++ API Documentation

The Xalan-C++ XSL Transformer Version 1.0

Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

XPathExpression.hpp

Go to the documentation of this file.
00001 /*
00002  * The Apache Software License, Version 1.1
00003  *
00004  *
00005  * Copyright (c) 1999 The Apache Software Foundation.  All rights 
00006  * reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions
00010  * are met:
00011  *
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer. 
00014  *
00015  * 2. Redistributions in binary form must reproduce the above copyright
00016  *    notice, this list of conditions and the following disclaimer in
00017  *    the documentation and/or other materials provided with the
00018  *    distribution.
00019  *
00020  * 3. The end-user documentation included with the redistribution,
00021  *    if any, must include the following acknowledgment:  
00022  *       "This product includes software developed by the
00023  *        Apache Software Foundation (http://www.apache.org/)."
00024  *    Alternately, this acknowledgment may appear in the software itself,
00025  *    if and wherever such third-party acknowledgments normally appear.
00026  *
00027  * 4. The names "Xalan" and "Apache Software Foundation" must
00028  *    not be used to endorse or promote products derived from this
00029  *    software without prior written permission. For written 
00030  *    permission, please contact apache@apache.org.
00031  *
00032  * 5. Products derived from this software may not be called "Apache",
00033  *    nor may "Apache" appear in their name, without prior written
00034  *    permission of the Apache Software Foundation.
00035  *
00036  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
00037  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00038  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00039  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
00040  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00041  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00042  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
00043  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00044  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00045  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00046  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00047  * SUCH DAMAGE.
00048  * ====================================================================
00049  *
00050  * This software consists of voluntary contributions made by many
00051  * individuals on behalf of the Apache Software Foundation and was
00052  * originally based on software copyright (c) 1999, International
00053  * Business Machines, Inc., http://www.ibm.com.  For more
00054  * information on the Apache Software Foundation, please see
00055  * <http://www.apache.org/>.
00056  */
00057 #if !defined(XPATHEXPRESSION_HEADER_GUARD_1357924680)
00058 #define XPATHEXPRESSION_HEADER_GUARD_1357924680
00059 
00060 
00061 
00062 // Base header file.  Must be first.
00063 #include <XPath/XPathDefinitions.hpp>
00064 
00065 
00066 
00067 #include <deque>
00068 #include <map>
00069 #include <set>
00070 #include <vector>
00071 
00072 
00073 
00074 #include <XalanDOM/XalanDOMString.hpp>
00075 
00076 
00077 
00078 #include <PlatformSupport/DOMStringHelper.hpp>
00079 #include <PlatformSupport/PrintWriter.hpp>
00080 
00081 
00082 
00083 #include <XPath/XObject.hpp>
00084 #include <XPath/XPathException.hpp>
00085 
00086 
00087 
00088 class XALAN_XPATH_EXPORT XPathExpression
00089 {
00090 public:
00091 
00110     enum eOpCodes
00111     {
00116         eENDOP = -1,
00117 
00122         eEMPTY = -2,
00123 
00129         eELEMWILDCARD = -3,
00130 
00144         eOP_XPATH = 1,
00145 
00155         eOP_OR = 2,
00156 
00166         eOP_AND = 3,
00167 
00177         eOP_NOTEQUALS = 4,
00178 
00188         eOP_EQUALS = 5,
00189 
00199         eOP_LTE = 6,
00200 
00210         eOP_LT = 7,
00211 
00221         eOP_GTE = 8,
00222 
00232         eOP_GT = 9,
00233 
00243         eOP_PLUS = 10,
00244 
00254         eOP_MINUS = 11,
00255 
00265         eOP_MULT = 12,
00266 
00276         eOP_DIV = 13,
00277 
00287         eOP_MOD = 14,
00288 
00298         eOP_QUO = 15,
00299 
00308         eOP_NEG = 16,
00309 
00318         eOP_STRING = 17,
00319 
00328         eOP_BOOL = 18,
00329 
00338         eOP_NUMBER = 19,
00339 
00348         eOP_UNION = 20,
00349 
00358         eOP_LITERAL = 21,
00359 
00368         eOP_VARIABLE = 22,
00369 
00383         eOP_GROUP = 23,
00384 
00393         eOP_NUMBERLIT = 24,
00394 
00408         eOP_ARGUMENT = 25,
00409 
00425         eOP_EXTFUNCTION = 26,
00426 
00442         eOP_FUNCTION = 27,
00443 
00457         eOP_LOCATIONPATH = 28,
00458 
00468         eOP_PREDICATE = 29,
00469   
00477         eNODETYPE_COMMENT = 1030,
00478         
00486         eNODETYPE_TEXT = 1031,
00487         
00495         eNODETYPE_PI = 1032,
00496         
00504         eNODETYPE_NODE = 1033,
00505         
00514         eNODENAME = 34,
00515         
00523         eNODETYPE_ROOT = 35,
00524         
00532         eNODETYPE_ANYELEMENT = 36,
00533 
00544         eFROM_ANCESTORS = 37,
00545         eFROM_ANCESTORS_OR_SELF = 38,
00546         eFROM_ATTRIBUTES = 39,
00547         eFROM_CHILDREN = 40,
00548         eFROM_DESCENDANTS = 41,
00549         eFROM_DESCENDANTS_OR_SELF = 42,
00550         eFROM_FOLLOWING = 43,
00551         eFROM_FOLLOWING_SIBLINGS = 44,
00552         eFROM_PARENT = 45,
00553         eFROM_PRECEDING = 46,
00554         eFROM_PRECEDING_SIBLINGS = 47,
00555         eFROM_SELF = 48,
00556         eFROM_NAMESPACE = 49,
00557         // eFROM_ATTRIBUTE = 50,
00558         // eFROM_DOC = 51,
00559         // eFROM_DOCREF = 52,
00560         // eFROM_ID = 53,
00561         // eFROM_IDREF = 54,
00562         eFROM_ROOT = 55,
00563 
00572         eOP_MATCHPATTERN = 92,
00573 
00582         eOP_LOCATIONPATHPATTERN = 93,
00583 
00584         // For match patterns
00585         eMATCH_ATTRIBUTE = 94,
00586         eMATCH_ANY_ANCESTOR = 95,
00587         eMATCH_IMMEDIATE_ANCESTOR = 96,
00588         eMATCH_ANY_ANCESTOR_WITH_PREDICATE = 97,
00589 
00590         // Always add _before_ this one.
00591         eOpCodeNextAvailable
00592     };  // enum eOpCodes
00593 
00600 #if defined(XALAN_INLINE_INITIALIZATION)
00601     const int   s__opCodeMapLengthIndex = 1;
00602 #else
00603     enum eDummy
00604     {
00605         s__opCodeMapLengthIndex = 1
00606     };
00607 #endif
00608 
00612     class XALAN_XPATH_EXPORT XPathExpressionException : public XPathException
00613     {
00614     public:
00615 
00621         XPathExpressionException(const XalanDOMString&  theMessage);
00622 
00623         virtual~
00624         XPathExpressionException();
00625     };
00626 
00630     class XALAN_XPATH_EXPORT InvalidOpCodeException : public XPathExpressionException
00631     {
00632     public:
00633 
00639         InvalidOpCodeException(int  theOpCode);
00640 
00641         virtual~
00642         InvalidOpCodeException();
00643 
00644     private:
00645 
00646         static XalanDOMString
00647         FormatErrorMessage(int  theOpCode);
00648     };
00649 
00654     class XALAN_XPATH_EXPORT InvalidArgumentCountException : public XPathExpressionException
00655     {
00656     public:
00657 
00665         InvalidArgumentCountException(
00666             int     theOpCode,
00667             int     theExpectedCount,
00668             int     theSuppliedCount);
00669 
00670         virtual~
00671         InvalidArgumentCountException();
00672 
00673     private:
00674 
00675         static XalanDOMString
00676         FormatErrorMessage(
00677             int     theOpCode,
00678             int     theExpectedCount,
00679             int     theSuppliedCount);
00680     };
00681 
00685     class XALAN_XPATH_EXPORT InvalidArgumentException : public XPathExpressionException
00686     {
00687     public:
00688 
00695         InvalidArgumentException(
00696             int theOpCode,
00697             int theValue);
00698 
00699         virtual~
00700         InvalidArgumentException();
00701 
00702     private:
00703 
00704         static XalanDOMString
00705         FormatErrorMessage(
00706                 int     theOpCode,
00707                 int     theValue);
00708     };
00709 
00713     class XALAN_XPATH_EXPORT InvalidRelativeTokenPosition : public XPathExpressionException
00714     {
00715     public:
00716 
00722         InvalidRelativeTokenPosition(int    theOffset);
00723 
00724         virtual~
00725         InvalidRelativeTokenPosition();
00726 
00727     private:
00728 
00729         static XalanDOMString
00730         FormatErrorMessage(int  theOffset);
00731     };
00732 
00733     class XToken : public XObject
00734     {
00735     public:
00736 
00737         explicit
00738         XToken();
00739 
00740         XToken(const XalanDOMString&    theString);
00741 
00742         XToken(double   theNumber);
00743 
00744         XToken(const XToken&    theSource);
00745 
00746         virtual
00747         ~XToken();
00748 
00749 #if defined(XALAN_NO_COVARIANT_RETURN_TYPE)
00750         virtual XObject*
00751 #else
00752         virtual XToken*
00753 #endif
00754         clone(void*     theAddress = 0) const;
00755 
00756         virtual XalanDOMString
00757         getTypeString() const;
00758 
00759         virtual double
00760         num() const;
00761 
00762         virtual const XalanDOMString&
00763         str() const;
00764 
00765         virtual void
00766         ProcessXObjectTypeCallback(XObjectTypeCallback&     theCallbackObject);
00767 
00768         virtual void
00769         ProcessXObjectTypeCallback(XObjectTypeCallback&     theCallbackObject) const;
00770 
00771         XToken&
00772         operator=(const XToken&     theRHS)
00773         {
00774             m_stringValue = theRHS.m_stringValue;
00775 
00776             m_numberValue = theRHS.m_numberValue;
00777 
00778             return *this;
00779         }
00780 
00781         XToken&
00782         operator=(const XalanDOMString&     theString);
00783 
00784         XToken&
00785         operator=(double    theNumber);
00786 
00787     private:
00788 
00789         // Not defined...
00790         bool
00791         operator==(const XToken&) const;
00792 
00793         // Data members...
00794         XalanDOMString  m_stringValue;
00795 
00796         double          m_numberValue;
00797     };
00798 
00799 
00800 #if defined(XALAN_NO_NAMESPACES)
00801 
00802     typedef vector<int>                     OpCodeMapType;
00803     typedef deque<XToken>                   TokenQueueType;
00804     typedef vector<int>                     PatternMapType;
00805 
00806     typedef map<int, int, less<int> >       OpCodeLengthMapType;
00807 
00808     typedef OpCodeMapType::value_type       OpCodeMapValueType;
00809     typedef OpCodeMapType::size_type        OpCodeMapSizeType;
00810 
00811     typedef set<OpCodeMapValueType, less<OpCodeMapValueType> >  NodeTestSetType;
00812 
00813     typedef vector<OpCodeMapValueType>      OpCodeMapValueVectorType;
00814 
00815 #else
00816 
00817     typedef std::vector<int>                OpCodeMapType;
00818     typedef std::deque<XToken>              TokenQueueType;
00819     typedef std::vector<int>                PatternMapType;
00820     typedef std::map<int, int>              OpCodeLengthMapType;
00821 
00822     typedef OpCodeMapType::value_type       OpCodeMapValueType;
00823     typedef OpCodeMapType::size_type        OpCodeMapSizeType;
00824 
00825     typedef std::set<OpCodeMapValueType>    NodeTestSetType;
00826     typedef std::vector<OpCodeMapValueType> OpCodeMapValueVectorType;
00827 
00828 #endif
00829 
00830     typedef TokenQueueType::value_type      TokenQueueValueType;
00831     typedef TokenQueueType::size_type       TokenQueueSizeType;
00832     typedef PatternMapType::value_type      PatternMapValueType;
00833     typedef PatternMapType::size_type       PatternMapSizeType;
00834 
00835     explicit
00836     XPathExpression();
00837 
00838     ~XPathExpression();
00839 
00843     void
00844     reset();
00845 
00849     void
00850     shrink();
00851 
00857     OpCodeMapSizeType
00858     opCodeMapSize() const
00859     {
00860         return m_opMap.size();
00861     }
00862 
00874     OpCodeMapValueType
00875     opCodeMapLength() const
00876     {
00877         const OpCodeMapSizeType     theSize = opCodeMapSize();
00878 
00879         if (theSize > s__opCodeMapLengthIndex)
00880         {
00881             assert(theSize ==
00882                 OpCodeMapSizeType(m_opMap[s__opCodeMapLengthIndex]));
00883 
00884             return m_opMap[s__opCodeMapLengthIndex];
00885         }
00886         else
00887         {
00888             return theSize;
00889         }
00890     }
00891 
00897     TokenQueueSizeType
00898     tokenQueueSize() const
00899     {
00900         return m_tokenQueue.size();
00901     }
00902 
00908     PatternMapSizeType
00909     patternMapSize() const
00910     {
00911         return m_patternMap.size();
00912     }
00913 
00921     OpCodeMapValueType
00922     getOpCodeMapValue(OpCodeMapSizeType     opPos) const
00923     {
00924         return m_opMap[opPos];
00925     }
00926 
00934     OpCodeMapValueType
00935     getOpCodeLength(OpCodeMapSizeType   opPos) const;
00936 
00944     OpCodeMapValueType
00945     getNextOpCodePosition(OpCodeMapSizeType     opPos) const
00946     {
00947         assert(opPos < opCodeMapSize());
00948 
00949         return opPos + m_opMap[opPos + s__opCodeMapLengthIndex];
00950     }
00951 
00961     void
00962     setOpCodeArgs(
00963             eOpCodes                            theOpCode,
00964             OpCodeMapSizeType                   theIndex,
00965             const OpCodeMapValueVectorType&     theArgs);
00966 
00972     void
00973     appendOpCode(eOpCodes   theOpCode);
00974 
00981     void
00982     appendOpCode(eOpCodes                           theOpCode,
00983                  const OpCodeMapValueVectorType&    theArgs)
00984     {
00985         appendOpCode(theOpCode);
00986 
00987         setOpCodeArgs(theOpCode,
00988                       m_lastOpCodeIndex,
00989                       theArgs);
00990     }
00991 
00998     OpCodeMapValueType
00999     insertOpCode(
01000             eOpCodes            theOpCode,
01001             OpCodeMapSizeType   theIndex);
01002 
01012     void
01013     updateOpCodeLength(OpCodeMapSizeType    theIndex)
01014     {
01015         assert(theIndex < opCodeMapSize());
01016 
01017         updateOpCodeLength(m_opMap[theIndex], theIndex);
01018     }
01019 
01028     void
01029     updateShiftedOpCodeLength(
01030             OpCodeMapValueType  theOpCode,
01031             OpCodeMapSizeType   theOriginalIndex,
01032             OpCodeMapSizeType   theNewIndex);
01033 
01044     void
01045     updateOpCodeLength(
01046             OpCodeMapValueType  theOpCode,
01047             OpCodeMapSizeType   theIndex);
01048 
01056     static bool
01057     isNodeTestOpCode(OpCodeMapValueType     theOpCode);
01058 
01064     void
01065     updateOpCodeLengthAfterNodeTest(OpCodeMapSizeType   theIndex);
01066 
01072     bool
01073     hasMoreTokens() const
01074     {
01075         return tokenQueueSize() - m_currentPosition > 0 ? true : false;
01076     }
01077 
01083     TokenQueueSizeType
01084     getTokenPosition() const
01085     {
01086         return m_currentPosition;
01087     }
01088 
01092     void
01093     resetTokenPosition()
01094     {
01095         m_currentPosition = 0;
01096     }
01097 
01103     void
01104     setTokenPosition(TokenQueueSizeType     thePosition)
01105     {
01106         const TokenQueueSizeType    theSize = tokenQueueSize();
01107 
01108         m_currentPosition = thePosition > theSize ? theSize : thePosition;
01109     }
01110 
01116     void
01117     setTokenPosition(int    thePosition)
01118     {
01119         setTokenPosition(thePosition > 0 ? TokenQueueSizeType(thePosition) : 0);
01120     }
01121 
01128     const XObject*
01129     getToken(TokenQueueSizeType     thePosition) const
01130     {
01131         assert(thePosition < tokenQueueSize());
01132 
01133         return &m_tokenQueue[thePosition];
01134     }
01135 
01141     const XObject*
01142     getNextToken()
01143     {
01144         if (hasMoreTokens() == true)
01145         {
01146             return getToken(m_currentPosition++);
01147         }
01148         else
01149         {
01150             return 0;
01151         }
01152     }
01153 
01159     const XObject*
01160     getPreviousToken()
01161     {
01162         if (m_currentPosition > 0)
01163         {
01164             return getToken(--m_currentPosition);
01165         }
01166         else
01167         {
01168             return 0;
01169         }
01170     }
01171 
01179     const XObject*
01180     getRelativeToken(int    theOffset) const
01181     {
01182         const int   thePosition = int(m_currentPosition) + theOffset;
01183 
01184         if (thePosition < 0 ||
01185             thePosition >= int(tokenQueueSize()))
01186         {
01187             return 0;
01188         }
01189         else
01190         {
01191             return getToken(thePosition);
01192         }
01193     }
01194 
01200     void
01201     pushToken(const XalanDOMString&     theToken)
01202     {
01203         m_tokenQueue.push_back(XToken(theToken));
01204     }
01205 
01211     void
01212     pushToken(double    theToken)
01213     {
01214         m_tokenQueue.push_back(XToken(theToken));
01215     }
01216 
01223     void
01224     insertToken(const XalanDOMString&   theToken)
01225     {
01226         m_tokenQueue.insert(m_tokenQueue.begin() + (m_currentPosition - 1), XToken(theToken));
01227     }
01228 
01235     void
01236     insertToken(double  theToken)
01237     {
01238         m_tokenQueue.insert(m_tokenQueue.begin() + (m_currentPosition - 1), XToken(theToken));
01239     }
01240 
01247     void
01248     replaceRelativeToken(
01249             int                     theOffset,
01250             const XalanDOMString&   theToken)
01251     {
01252         assert(theToken != 0);
01253 
01254         const int   thePosition = int(m_currentPosition) + theOffset;
01255 
01256         if (thePosition < 0 ||
01257             thePosition >= int(tokenQueueSize()))
01258         {
01259             throw InvalidRelativeTokenPosition(theOffset);
01260         }
01261 
01262         m_tokenQueue[thePosition] = theToken;
01263     }
01264 
01271     void
01272     replaceRelativeToken(
01273             int     theOffset,
01274             double  theToken)
01275     {
01276         assert(theToken != 0);
01277 
01278         const int   thePosition = int(m_currentPosition) + theOffset;
01279 
01280         if (thePosition < 0 || thePosition >= int(tokenQueueSize()))
01281         {
01282             throw InvalidRelativeTokenPosition(theOffset);
01283         }
01284 
01285         m_tokenQueue[thePosition] = theToken;
01286     }
01287 
01294     void
01295     dumpOpCodeMap(PrintWriter&          thePrintWriter,
01296                   OpCodeMapSizeType     theStartPosition = 0) const;
01297 
01304     void
01305     dumpTokenQueue(PrintWriter&         thePrintWriter,
01306                    TokenQueueSizeType   theStartPosition = 0) const;
01307 
01313     void
01314     dumpRemainingTokenQueue(PrintWriter&    thePrintWriter) const;
01315 
01322     void
01323     pushArgumentOnOpCodeMap(const XalanDOMString&   theToken);
01324 
01331     void
01332     pushArgumentOnOpCodeMap(double  theToken);
01333 
01338     void
01339     pushCurrentTokenOnOpCodeMap();
01340 
01348     PatternMapValueType
01349     getPattern(int  thePatternPosition) const
01350     {
01351         assert(int(patternMapSize()) > thePatternPosition);
01352 
01353         return m_patternMap[thePatternPosition];
01354     }
01355 
01363     PatternMapValueType
01364     getPattern(PatternMapSizeType   thePatternPosition) const
01365     {
01366         assert(patternMapSize() > thePatternPosition);
01367 
01368         return m_patternMap[thePatternPosition];
01369     }
01370 
01376     void
01377     pushPattern(PatternMapValueType thePattern)
01378     {
01379         m_patternMap.push_back(thePattern);
01380     }
01381 
01388     void
01389     adjustPattern(
01390             OpCodeMapSizeType   theIndex,
01391             PatternMapValueType theAdjustment)
01392     {
01393         m_patternMap[theIndex] += theAdjustment;
01394     }
01395 
01401     void
01402     setCurrentPattern(const XalanDOMString&     thePattern)
01403     {
01404         m_currentPattern = thePattern;
01405     }
01406 
01412     const XalanDOMString&
01413     getCurrentPattern() const
01414     {
01415         return m_currentPattern;
01416     }
01417 
01424     OpCodeMapType           m_opMap;
01425 
01430     OpCodeMapSizeType       m_lastOpCodeIndex;
01431 
01437     TokenQueueType          m_tokenQueue;
01438 
01442     TokenQueueSizeType      m_currentPosition;
01443 
01451      // Ignore this, it is going away.
01452     PatternMapType          m_patternMap;
01453 
01457     XalanDOMString          m_currentPattern;
01458 
01459 private:
01460 
01461     // Default vector allocation sizes.
01462     enum
01463     {
01464         eDefaultOpMapSize = 100,
01465         eDefaultPatternMapSize = 100
01466     };
01467 
01468     // A map of Op codes to op code lengths.
01469     const static OpCodeLengthMapType    s_opCodeLengths;
01470 
01471     static OpCodeLengthMapType
01472     IntializeOpCodeLengthMap();
01473 
01474     // A static set of Op codes that are node tests.
01475     const static NodeTestSetType        s_NodeTestOpCodes;
01476 
01477     static NodeTestSetType
01478     InitializeNodeTestSet();
01479 };
01480 
01481 
01482 
01483 #endif  // XPATHEXPRESSION_HEADER_GUARD_1357924680

Interpreting class diagrams

Doxygen and GraphViz are used to generate this API documentation from the Xalan-C header files.

Xalan-C++ XSL Transformer Version 1.0
Copyright © 2000 The Apache Software Foundation. All Rights Reserved.