Xalan-C++ API Documentation

The Xalan C++ XSLT Processor Version 1.6

Main Page   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-2002 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 <xalanc/XPath/XPathDefinitions.hpp>
00064 
00065 
00066 
00067 #include <vector>
00068 
00069 #if defined(XALAN_CLASSIC_IOSTREAMS)
00070 #include <iostream.h>
00071 #else
00072 #include <iosfwd>
00073 #endif
00074 
00075 
00076 
00077 #include <xalanc/XalanDOM/XalanDOMString.hpp>
00078 
00079 
00080 
00081 #include <xalanc/PlatformSupport/DOMStringHelper.hpp>
00082 #include <xalanc/PlatformSupport/PrintWriter.hpp>
00083 
00084 
00085 
00086 #include <xalanc/XPath/XToken.hpp>
00087 #include <xalanc/XPath/XalanXPathException.hpp>
00088 
00089 
00090 
00091 XALAN_CPP_NAMESPACE_BEGIN
00092 
00093 
00094 
00095 class XALAN_XPATH_EXPORT XPathExpression
00096 {
00097 public:
00098 
00099 #if defined(XALAN_NO_STD_NAMESPACE)
00100     typedef ostream         OstreamType;
00101 #else
00102     typedef std::ostream    OstreamType;
00103 #endif
00104 
00123     enum eOpCodes
00124     {
00130         eELEMWILDCARD = -3,
00131 
00136         eEMPTY = -2,
00137 
00142         eENDOP = -1,
00143 
00157         eOP_XPATH = 1,
00158 
00168         eOP_OR = 2,
00169 
00179         eOP_AND = 3,
00180 
00190         eOP_NOTEQUALS = 4,
00191 
00201         eOP_EQUALS = 5,
00202 
00212         eOP_LTE = 6,
00213 
00223         eOP_LT = 7,
00224 
00234         eOP_GTE = 8,
00235 
00245         eOP_GT = 9,
00246 
00256         eOP_PLUS = 10,
00257 
00267         eOP_MINUS = 11,
00268 
00278         eOP_MULT = 12,
00279 
00289         eOP_DIV = 13,
00290 
00300         eOP_MOD = 14,
00301 
00310         eOP_NEG = 15,
00311 
00320         eOP_BOOL = 16,
00321 
00330         eOP_UNION = 17,
00331 
00340         eOP_LITERAL = 18,
00341 
00350         eOP_VARIABLE = 19,
00351 
00365         eOP_GROUP = 20,
00366 
00375         eOP_NUMBERLIT = 21,
00376 
00390         eOP_ARGUMENT = 22,
00391 
00407         eOP_EXTFUNCTION = 23,
00408 
00425         eOP_FUNCTION = 24,
00426 
00440         eOP_LOCATIONPATH = 25,
00441 
00451         eOP_PREDICATE = 26,
00452 
00460         eNODETYPE_COMMENT = 27,
00461         
00469         eNODETYPE_TEXT = 28,
00470         
00478         eNODETYPE_PI = 29,
00479         
00487         eNODETYPE_NODE = 30,
00488         
00497         eNODENAME = 31,
00498         
00506         eNODETYPE_ROOT = 32,
00507         
00515         eNODETYPE_ANYELEMENT = 33,
00516 
00527         eFROM_ANCESTORS = 34,
00528         eFROM_ANCESTORS_OR_SELF = 35,
00529         eFROM_ATTRIBUTES = 36,
00530         eFROM_CHILDREN = 37,
00531         eFROM_DESCENDANTS = 38,
00532         eFROM_DESCENDANTS_OR_SELF = 39,
00533         eFROM_FOLLOWING = 40,
00534         eFROM_FOLLOWING_SIBLINGS = 41,
00535         eFROM_PARENT = 42,
00536         eFROM_PRECEDING = 43,
00537         eFROM_PRECEDING_SIBLINGS = 44,
00538         eFROM_SELF = 45,
00539         eFROM_NAMESPACE = 46,
00540         eFROM_ROOT = 47,
00541 
00550         eOP_MATCHPATTERN = 48,
00551 
00560         eOP_LOCATIONPATHPATTERN = 49,
00561 
00562         // For match patterns
00563         eMATCH_ATTRIBUTE = 50,
00564         eMATCH_ANY_ANCESTOR = 51,
00565         eMATCH_IMMEDIATE_ANCESTOR = 52,
00566         eMATCH_ANY_ANCESTOR_WITH_PREDICATE = 53,
00567         eMATCH_ANY_ANCESTOR_WITH_FUNCTION_CALL = 54,
00568 
00578         eOP_PREDICATE_WITH_POSITION = 55,
00579   
00584         eOP_FUNCTION_POSITION = 56,
00585         eOP_FUNCTION_LAST = 57,
00586         eOP_FUNCTION_COUNT = 58,
00587         eOP_FUNCTION_NOT = 59,
00588         eOP_FUNCTION_TRUE = 60,
00589         eOP_FUNCTION_FALSE = 61,
00590         eOP_FUNCTION_BOOLEAN = 62,
00591         eOP_FUNCTION_NAME_0 = 63,
00592         eOP_FUNCTION_NAME_1 = 64,
00593         eOP_FUNCTION_LOCALNAME_0 = 65,
00594         eOP_FUNCTION_LOCALNAME_1 = 66,
00595         eOP_FUNCTION_FLOOR = 67,
00596         eOP_FUNCTION_CEILING = 68,
00597         eOP_FUNCTION_ROUND = 69,
00598         eOP_FUNCTION_NUMBER_0 = 70,
00599         eOP_FUNCTION_NUMBER_1 = 71,
00600         eOP_FUNCTION_STRING_0 = 72,
00601         eOP_FUNCTION_STRING_1 = 73,
00602         eOP_FUNCTION_STRINGLENGTH_0 = 74,
00603         eOP_FUNCTION_STRINGLENGTH_1 = 75,
00604         eOP_FUNCTION_NAMESPACEURI_0 = 76,
00605         eOP_FUNCTION_NAMESPACEURI_1 = 77,
00606         eOP_FUNCTION_SUM = 78,
00607         eOP_FUNCTION_CONCAT = 79,
00608 
00609         // Always add _before_ this one and update
00610         // s_opCodeLengthArray.
00611         eOpCodeNextAvailable
00612     };  // enum eOpCodes
00613 
00617     class XALAN_XPATH_EXPORT XPathExpressionException : public XalanXPathException
00618     {
00619     public:
00620 
00626         XPathExpressionException(const XalanDOMString&  theMessage);
00627 
00628         virtual~
00629         XPathExpressionException();
00630     };
00631 
00635     class XALAN_XPATH_EXPORT InvalidOpCodeException : public XPathExpressionException
00636     {
00637     public:
00638 
00644         InvalidOpCodeException(int  theOpCode);
00645 
00646         virtual~
00647         InvalidOpCodeException();
00648 
00649     private:
00650 
00651         static XalanDOMString
00652         FormatErrorMessage(int  theOpCode);
00653     };
00654 
00659     class XALAN_XPATH_EXPORT InvalidArgumentCountException : public XPathExpressionException
00660     {
00661     public:
00662 
00670         InvalidArgumentCountException(
00671             int     theOpCode,
00672             int     theExpectedCount,
00673             int     theSuppliedCount);
00674 
00675         virtual~
00676         InvalidArgumentCountException();
00677 
00678     private:
00679 
00680         static XalanDOMString
00681         FormatErrorMessage(
00682             int     theOpCode,
00683             int     theExpectedCount,
00684             int     theSuppliedCount);
00685     };
00686 
00690     class XALAN_XPATH_EXPORT InvalidArgumentException : public XPathExpressionException
00691     {
00692     public:
00693 
00700         InvalidArgumentException(
00701             int theOpCode,
00702             int theValue);
00703 
00704         virtual~
00705         InvalidArgumentException();
00706 
00707     private:
00708 
00709         static XalanDOMString
00710         FormatErrorMessage(
00711                 int     theOpCode,
00712                 int     theValue);
00713     };
00714 
00718     class XALAN_XPATH_EXPORT InvalidRelativeTokenPosition : public XPathExpressionException
00719     {
00720     public:
00721 
00727         InvalidRelativeTokenPosition(int    theOffset);
00728 
00729         virtual~
00730         InvalidRelativeTokenPosition();
00731 
00732     private:
00733 
00734         static XalanDOMString
00735         FormatErrorMessage(int  theOffset);
00736     };
00737 
00738 
00739 #if defined(XALAN_NO_STD_NAMESPACE)
00740 
00741     typedef vector<int>                     OpCodeMapType;
00742     typedef vector<XToken>                  TokenQueueType;
00743 
00744     typedef OpCodeMapType::value_type       OpCodeMapValueType;
00745     typedef OpCodeMapType::size_type        OpCodeMapSizeType;
00746 
00747     typedef vector<OpCodeMapValueType>      OpCodeMapValueVectorType;
00748 
00749     typedef vector<double>                  NumberLiteralValueVectorType;
00750 #else
00751 
00752     typedef std::vector<int>                OpCodeMapType;
00753     typedef std::vector<XToken>             TokenQueueType;
00754 
00755     typedef OpCodeMapType::value_type       OpCodeMapValueType;
00756     typedef OpCodeMapType::size_type        OpCodeMapSizeType;
00757 
00758     typedef std::vector<OpCodeMapValueType> OpCodeMapValueVectorType;
00759 
00760     typedef std::vector<double>             NumberLiteralValueVectorType;
00761 #endif
00762 
00763     typedef TokenQueueType::value_type      TokenQueueValueType;
00764     typedef TokenQueueType::size_type       TokenQueueSizeType;
00765 
00772 #if defined(XALAN_INLINE_INITIALIZATION)
00773     static const TokenQueueSizeType     s_opCodeMapLengthIndex = 1;
00774 #else
00775     enum eDummy
00776     {
00777         s_opCodeMapLengthIndex = 1
00778     };
00779 #endif
00780 
00781     explicit
00782     XPathExpression();
00783 
00784     ~XPathExpression();
00785 
00789     void
00790     reset();
00791 
00795     void
00796     shrink();
00797 
00803     OpCodeMapSizeType
00804     opCodeMapSize() const
00805     {
00806         return m_opMap.size();
00807     }
00808 
00820     OpCodeMapValueType
00821     opCodeMapLength() const
00822     {
00823         const OpCodeMapSizeType     theSize = opCodeMapSize();
00824 
00825         if (theSize > s_opCodeMapLengthIndex)
00826         {
00827             assert(theSize == OpCodeMapSizeType(m_opMap[s_opCodeMapLengthIndex]));
00828 
00829             return m_opMap[s_opCodeMapLengthIndex];
00830         }
00831         else
00832         {
00833             assert(theSize == OpCodeMapValueType(theSize));
00834 
00835             return OpCodeMapValueType(theSize);
00836         }
00837     }
00838 
00844     TokenQueueSizeType
00845     tokenQueueSize() const
00846     {
00847         return m_tokenQueue.size();
00848     }
00849 
00857     OpCodeMapValueType
00858     getOpCodeMapValue(OpCodeMapSizeType     opPos) const
00859     {
00860         return m_opMap[opPos];
00861     }
00862 
00863     OpCodeMapValueType
00864     getOpCodeArgumentLength(OpCodeMapSizeType   opPos) const
00865     {
00866         return getOpCodeMapValue(opPos + XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
00867     }
00868 
00876     OpCodeMapValueType
00877     getOpCodeLengthFromOpMap(OpCodeMapSizeType  opPos) const;
00878 
00886     OpCodeMapValueType
00887     getNextOpCodePosition(OpCodeMapSizeType     opPos) const
00888     {
00889         assert(opPos < opCodeMapSize());
00890 
00891         assert(opPos + m_opMap[opPos + s_opCodeMapLengthIndex] == OpCodeMapValueType(opPos + m_opMap[opPos + s_opCodeMapLengthIndex]));
00892 
00893         return OpCodeMapValueType(opPos + m_opMap[opPos + s_opCodeMapLengthIndex]);
00894     }
00895 
00905     void
00906     setOpCodeArgs(
00907             eOpCodes                            theOpCode,
00908             OpCodeMapSizeType                   theIndex,
00909             const OpCodeMapValueVectorType&     theArgs);
00910 
00917     OpCodeMapSizeType
00918     appendOpCode(eOpCodes   theOpCode);
00919 
00926     OpCodeMapSizeType
00927     appendOpCode(eOpCodes                           theOpCode,
00928                  const OpCodeMapValueVectorType&    theArgs)
00929     {
00930         const OpCodeMapSizeType     thePosition = appendOpCode(theOpCode);
00931 
00932         setOpCodeArgs(theOpCode,
00933                       thePosition,
00934                       theArgs);
00935 
00936         return thePosition;
00937     }
00938 
00946     void
00947     replaceOpCode(
00948             OpCodeMapSizeType   theIndex,
00949             eOpCodes            theOldOpCode,
00950             eOpCodes            theNewOpCode);
00951 
00958     OpCodeMapValueType
00959     insertOpCode(
00960             eOpCodes            theOpCode,
00961             OpCodeMapSizeType   theIndex);
00962 
00972     void
00973     updateOpCodeLength(OpCodeMapSizeType    theIndex)
00974     {
00975         assert(theIndex < opCodeMapSize());
00976 
00977         updateOpCodeLength(m_opMap[theIndex], theIndex);
00978     }
00979 
00988     void
00989     updateShiftedOpCodeLength(
00990             OpCodeMapValueType  theOpCode,
00991             OpCodeMapSizeType   theOriginalIndex,
00992             OpCodeMapSizeType   theNewIndex);
00993 
01004     void
01005     updateOpCodeLength(
01006             OpCodeMapValueType  theOpCode,
01007             OpCodeMapSizeType   theIndex);
01008 
01016     static bool
01017     isNodeTestOpCode(OpCodeMapValueType     theOpCode);
01018 
01024     void
01025     updateOpCodeLengthAfterNodeTest(OpCodeMapSizeType   theIndex);
01026 
01032     bool
01033     hasMoreTokens() const
01034     {
01035         return tokenQueueSize() - m_currentPosition > 0 ? true : false;
01036     }
01037 
01043     TokenQueueSizeType
01044     getTokenPosition() const
01045     {
01046         return m_currentPosition;
01047     }
01048 
01052     void
01053     resetTokenPosition()
01054     {
01055         m_currentPosition = 0;
01056     }
01057 
01063     void
01064     setTokenPosition(TokenQueueSizeType     thePosition)
01065     {
01066         const TokenQueueSizeType    theSize = tokenQueueSize();
01067 
01068         m_currentPosition = thePosition > theSize ? theSize : thePosition;
01069     }
01070 
01076     void
01077     setTokenPosition(int    thePosition)
01078     {
01079         setTokenPosition(thePosition > 0 ? TokenQueueSizeType(thePosition) : 0);
01080     }
01081 
01088     const XObject*
01089     getToken(TokenQueueSizeType     thePosition) const
01090     {
01091         assert(thePosition < tokenQueueSize());
01092 
01093         return &m_tokenQueue[thePosition];
01094     }
01095 
01101     const XObject*
01102     getNextToken()
01103     {
01104         if (hasMoreTokens() == true)
01105         {
01106             return getToken(m_currentPosition++);
01107         }
01108         else
01109         {
01110             return 0;
01111         }
01112     }
01113 
01119     const XObject*
01120     getPreviousToken()
01121     {
01122         if (m_currentPosition > 0)
01123         {
01124             return getToken(--m_currentPosition);
01125         }
01126         else
01127         {
01128             return 0;
01129         }
01130     }
01131 
01139     const XObject*
01140     getRelativeToken(int    theOffset) const
01141     {
01142         const int   thePosition = int(m_currentPosition) + theOffset;
01143 
01144         if (thePosition < 0 ||
01145             thePosition >= int(tokenQueueSize()))
01146         {
01147             return 0;
01148         }
01149         else
01150         {
01151             return getToken(thePosition);
01152         }
01153     }
01154 
01160     void
01161     pushToken(const XalanDOMString&     theToken)
01162     {
01163         m_tokenQueue.push_back(XToken(theToken));
01164     }
01165 
01172     void
01173     pushToken(
01174             double                  theNumber,
01175             const XalanDOMString&   theString)
01176     {
01177         m_tokenQueue.push_back(XToken(theNumber, theString));
01178     }
01179 
01186     void
01187     insertToken(const XalanDOMString&   theToken)
01188     {
01189         m_tokenQueue.insert(m_tokenQueue.begin() + (m_currentPosition - 1), XToken(theToken));
01190     }
01191 
01199     void
01200     insertToken(
01201             double                  theNumber,
01202             const XalanDOMString&   theString)
01203     {
01204         m_tokenQueue.insert(m_tokenQueue.begin() + (m_currentPosition - 1), XToken(theNumber, theString));
01205     }
01206 
01213     void
01214     replaceRelativeToken(
01215             int             theOffset,
01216             const XToken&   theToken)
01217     {
01218         const int   thePosition = int(m_currentPosition) + theOffset;
01219 
01220         if (thePosition < 0 ||
01221             thePosition >= int(tokenQueueSize()))
01222         {
01223             throw InvalidRelativeTokenPosition(theOffset);
01224         }
01225 
01226         m_tokenQueue[thePosition] = theToken;
01227     }
01228 
01235     void
01236     replaceRelativeToken(
01237             int                     theOffset,
01238             const XalanDOMString&   theString)
01239     {
01240         const int   thePosition = int(m_currentPosition) + theOffset;
01241 
01242         if (thePosition < 0 ||
01243             thePosition >= int(tokenQueueSize()))
01244         {
01245             throw InvalidRelativeTokenPosition(theOffset);
01246         }
01247 
01248         m_tokenQueue[thePosition].set(theString);
01249     }
01250 
01257     void
01258     dumpOpCodeMap(
01259             PrintWriter&        thePrintWriter,
01260             OpCodeMapSizeType   theStartPosition = 0) const;
01261 
01268     void
01269     dumpOpCodeMap(
01270             OstreamType&        theStream,
01271             OpCodeMapSizeType   theStartPosition = 0) const;
01272 
01279     void
01280     dumpTokenQueue(
01281             PrintWriter&        thePrintWriter,
01282             TokenQueueSizeType  theStartPosition = 0) const;
01283 
01290     void
01291     dumpTokenQueue(
01292             OstreamType&        theStream,
01293             TokenQueueSizeType  theStartPosition = 0) const;
01294 
01300     void
01301     dumpRemainingTokenQueue(PrintWriter&    thePrintWriter) const;
01302 
01308     void
01309     dumpRemainingTokenQueue(OstreamType&    theStream) const;
01310 
01317     void
01318     pushValueOnOpCodeMap(const OpCodeMapType::value_type&   theValue)
01319     {
01320         // Push the index onto the op map.
01321         m_opMap.push_back(theValue);
01322 
01323         // Update the op map length.
01324         m_opMap[s_opCodeMapLengthIndex]++;
01325     }
01326 
01333     void
01334     pushArgumentOnOpCodeMap(const XToken&   theXToken);
01335 
01342     void
01343     pushArgumentOnOpCodeMap(const XalanDOMString&   theString);
01344 
01352     void
01353     pushArgumentOnOpCodeMap(
01354             double                  theNumber,
01355             const XalanDOMString&   theString);
01356 
01363     void
01364     pushNumberLiteralOnOpCodeMap(double     theNumber);
01365 
01371     double
01372     getNumberLiteral(int    theIndex) const
01373     {
01374         assert(theIndex >= 0 &&
01375                NumberLiteralValueVectorType::size_type(theIndex) < m_numberLiteralValues.size());
01376 
01377         return m_numberLiteralValues[NumberLiteralValueVectorType::size_type(theIndex)];
01378     }
01379 
01384     void
01385     pushCurrentTokenOnOpCodeMap();
01386 
01392     void
01393     setCurrentPattern(const XalanDOMString&     thePattern)
01394     {
01395         m_currentPattern = &thePattern;
01396     }
01397 
01403     const XalanDOMString&
01404     getCurrentPattern() const
01405     {
01406         assert(m_currentPattern != 0);
01407 
01408         return *m_currentPattern;
01409     }
01410 
01417     OpCodeMapType           m_opMap;
01418 
01423     OpCodeMapSizeType       m_lastOpCodeIndex;
01424 
01430     TokenQueueType          m_tokenQueue;
01431 
01435     TokenQueueSizeType      m_currentPosition;
01436 
01440     const XalanDOMString*   m_currentPattern;
01441 
01442 private:
01443 
01444     // Default vector allocation sizes.
01445     enum
01446     {
01447         eDefaultOpMapSize = 100,
01448         eDefaultTokenQueueSize = 30
01449     };
01450 
01451     NumberLiteralValueVectorType    m_numberLiteralValues;
01452 };
01453 
01454 
01455 
01456 XALAN_CPP_NAMESPACE_END
01457 
01458 
01459 
01460 #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++ XSLT Processor Version 1.6
Copyright © 2000, 2001, 2002, 2003 The Apache Software Foundation. All Rights Reserved.