Xalan-C++ API Documentation

The Xalan C++ XSLT Processor Version 1.3

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 <XPath/XPathDefinitions.hpp>
00064 
00065 
00066 
00067 #include <vector>
00068 
00069 #if defined(XALAN_OLD_STREAMS)
00070 #include <iostream.h>
00071 #else
00072 #include <iosfwd>
00073 #endif
00074 
00075 
00076 
00077 #include <XalanDOM/XalanDOMString.hpp>
00078 
00079 
00080 
00081 #include <PlatformSupport/DOMStringHelper.hpp>
00082 #include <PlatformSupport/PrintWriter.hpp>
00083 
00084 
00085 
00086 #include <XPath/XToken.hpp>
00087 #include <XPath/XalanXPathException.hpp>
00088 
00089 
00090 
00091 class XALAN_XPATH_EXPORT XPathExpression
00092 {
00093 public:
00094 
00113     enum eOpCodes
00114     {
00120         eELEMWILDCARD = -3,
00121 
00126         eEMPTY = -2,
00127 
00132         eENDOP = -1,
00133 
00147         eOP_XPATH = 1,
00148 
00158         eOP_OR = 2,
00159 
00169         eOP_AND = 3,
00170 
00180         eOP_NOTEQUALS = 4,
00181 
00191         eOP_EQUALS = 5,
00192 
00202         eOP_LTE = 6,
00203 
00213         eOP_LT = 7,
00214 
00224         eOP_GTE = 8,
00225 
00235         eOP_GT = 9,
00236 
00246         eOP_PLUS = 10,
00247 
00257         eOP_MINUS = 11,
00258 
00268         eOP_MULT = 12,
00269 
00279         eOP_DIV = 13,
00280 
00290         eOP_MOD = 14,
00291 
00300         eOP_NEG = 15,
00301 
00310         eOP_BOOL = 16,
00311 
00320         eOP_UNION = 17,
00321 
00330         eOP_LITERAL = 18,
00331 
00340         eOP_VARIABLE = 19,
00341 
00355         eOP_GROUP = 20,
00356 
00365         eOP_NUMBERLIT = 21,
00366 
00380         eOP_ARGUMENT = 22,
00381 
00397         eOP_EXTFUNCTION = 23,
00398 
00414         eOP_FUNCTION = 24,
00415 
00429         eOP_LOCATIONPATH = 25,
00430 
00440         eOP_PREDICATE = 26,
00441   
00449         eNODETYPE_COMMENT = 27,
00450         
00458         eNODETYPE_TEXT = 28,
00459         
00467         eNODETYPE_PI = 29,
00468         
00476         eNODETYPE_NODE = 30,
00477         
00486         eNODENAME = 31,
00487         
00495         eNODETYPE_ROOT = 32,
00496         
00504         eNODETYPE_ANYELEMENT = 33,
00505 
00516         eFROM_ANCESTORS = 34,
00517         eFROM_ANCESTORS_OR_SELF = 35,
00518         eFROM_ATTRIBUTES = 36,
00519         eFROM_CHILDREN = 37,
00520         eFROM_DESCENDANTS = 38,
00521         eFROM_DESCENDANTS_OR_SELF = 39,
00522         eFROM_FOLLOWING = 40,
00523         eFROM_FOLLOWING_SIBLINGS = 41,
00524         eFROM_PARENT = 42,
00525         eFROM_PRECEDING = 43,
00526         eFROM_PRECEDING_SIBLINGS = 44,
00527         eFROM_SELF = 45,
00528         eFROM_NAMESPACE = 46,
00529         eFROM_ROOT = 47,
00530 
00539         eOP_MATCHPATTERN = 48,
00540 
00549         eOP_LOCATIONPATHPATTERN = 49,
00550 
00551         // For match patterns
00552         eMATCH_ATTRIBUTE = 50,
00553         eMATCH_ANY_ANCESTOR = 51,
00554         eMATCH_IMMEDIATE_ANCESTOR = 52,
00555         eMATCH_ANY_ANCESTOR_WITH_PREDICATE = 53,
00556         eMATCH_ANY_ANCESTOR_WITH_FUNCTION_CALL = 54,
00557 
00558         // Always add _before_ this one and update
00559         // s_opCodeLengthArray.
00560         eOpCodeNextAvailable
00561     };  // enum eOpCodes
00562 
00566     class XALAN_XPATH_EXPORT XPathExpressionException : public XalanXPathException
00567     {
00568     public:
00569 
00575         XPathExpressionException(const XalanDOMString&  theMessage);
00576 
00577         virtual~
00578         XPathExpressionException();
00579     };
00580 
00584     class XALAN_XPATH_EXPORT InvalidOpCodeException : public XPathExpressionException
00585     {
00586     public:
00587 
00593         InvalidOpCodeException(int  theOpCode);
00594 
00595         virtual~
00596         InvalidOpCodeException();
00597 
00598     private:
00599 
00600         static XalanDOMString
00601         FormatErrorMessage(int  theOpCode);
00602     };
00603 
00608     class XALAN_XPATH_EXPORT InvalidArgumentCountException : public XPathExpressionException
00609     {
00610     public:
00611 
00619         InvalidArgumentCountException(
00620             int     theOpCode,
00621             int     theExpectedCount,
00622             int     theSuppliedCount);
00623 
00624         virtual~
00625         InvalidArgumentCountException();
00626 
00627     private:
00628 
00629         static XalanDOMString
00630         FormatErrorMessage(
00631             int     theOpCode,
00632             int     theExpectedCount,
00633             int     theSuppliedCount);
00634     };
00635 
00639     class XALAN_XPATH_EXPORT InvalidArgumentException : public XPathExpressionException
00640     {
00641     public:
00642 
00649         InvalidArgumentException(
00650             int theOpCode,
00651             int theValue);
00652 
00653         virtual~
00654         InvalidArgumentException();
00655 
00656     private:
00657 
00658         static XalanDOMString
00659         FormatErrorMessage(
00660                 int     theOpCode,
00661                 int     theValue);
00662     };
00663 
00667     class XALAN_XPATH_EXPORT InvalidRelativeTokenPosition : public XPathExpressionException
00668     {
00669     public:
00670 
00676         InvalidRelativeTokenPosition(int    theOffset);
00677 
00678         virtual~
00679         InvalidRelativeTokenPosition();
00680 
00681     private:
00682 
00683         static XalanDOMString
00684         FormatErrorMessage(int  theOffset);
00685     };
00686 
00687 
00688 #if defined(XALAN_NO_NAMESPACES)
00689 
00690     typedef vector<int>                     OpCodeMapType;
00691     typedef vector<XToken>                  TokenQueueType;
00692     typedef vector<int>                     PatternMapType;
00693 
00694     typedef OpCodeMapType::value_type       OpCodeMapValueType;
00695     typedef OpCodeMapType::size_type        OpCodeMapSizeType;
00696 
00697     typedef vector<OpCodeMapValueType>      OpCodeMapValueVectorType;
00698 
00699     typedef vector<double>                  NumberLiteralValueVectorType;
00700 #else
00701 
00702     typedef std::vector<int>                OpCodeMapType;
00703     typedef std::vector<XToken>             TokenQueueType;
00704     typedef std::vector<int>                PatternMapType;
00705 
00706     typedef OpCodeMapType::value_type       OpCodeMapValueType;
00707     typedef OpCodeMapType::size_type        OpCodeMapSizeType;
00708 
00709     typedef std::vector<OpCodeMapValueType> OpCodeMapValueVectorType;
00710 
00711     typedef std::vector<double>             NumberLiteralValueVectorType;
00712 #endif
00713 
00714     typedef TokenQueueType::value_type      TokenQueueValueType;
00715     typedef TokenQueueType::size_type       TokenQueueSizeType;
00716     typedef PatternMapType::value_type      PatternMapValueType;
00717     typedef PatternMapType::size_type       PatternMapSizeType;
00718 
00725 #if defined(XALAN_INLINE_INITIALIZATION)
00726     static const TokenQueueSizeType     s_opCodeMapLengthIndex = 1;
00727 #else
00728     enum eDummy
00729     {
00730         s_opCodeMapLengthIndex = 1
00731     };
00732 #endif
00733 
00734     explicit
00735     XPathExpression();
00736 
00737     ~XPathExpression();
00738 
00742     void
00743     reset();
00744 
00748     void
00749     shrink();
00750 
00756     OpCodeMapSizeType
00757     opCodeMapSize() const
00758     {
00759         return m_opMap.size();
00760     }
00761 
00773     OpCodeMapValueType
00774     opCodeMapLength() const
00775     {
00776         const OpCodeMapSizeType     theSize = opCodeMapSize();
00777 
00778         if (theSize > s_opCodeMapLengthIndex)
00779         {
00780             assert(theSize == OpCodeMapSizeType(m_opMap[s_opCodeMapLengthIndex]));
00781 
00782             return m_opMap[s_opCodeMapLengthIndex];
00783         }
00784         else
00785         {
00786             assert(theSize == OpCodeMapValueType(theSize));
00787 
00788             return OpCodeMapValueType(theSize);
00789         }
00790     }
00791 
00797     TokenQueueSizeType
00798     tokenQueueSize() const
00799     {
00800         return m_tokenQueue.size();
00801     }
00802 
00808     PatternMapSizeType
00809     patternMapSize() const
00810     {
00811         return m_patternMap.size();
00812     }
00813 
00821     OpCodeMapValueType
00822     getOpCodeMapValue(OpCodeMapSizeType     opPos) const
00823     {
00824         return m_opMap[opPos];
00825     }
00826 
00827     OpCodeMapValueType
00828     getOpCodeArgumentLength(OpCodeMapSizeType   opPos) const
00829     {
00830         return getOpCodeMapValue(opPos + XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
00831     }
00832 
00840     OpCodeMapValueType
00841     getOpCodeLengthFromOpMap(OpCodeMapSizeType  opPos) const;
00842 
00850     OpCodeMapValueType
00851     getNextOpCodePosition(OpCodeMapSizeType     opPos) const
00852     {
00853         assert(opPos < opCodeMapSize());
00854 
00855         assert(opPos + m_opMap[opPos + s_opCodeMapLengthIndex] == OpCodeMapValueType(opPos + m_opMap[opPos + s_opCodeMapLengthIndex]));
00856 
00857         return OpCodeMapValueType(opPos + m_opMap[opPos + s_opCodeMapLengthIndex]);
00858     }
00859 
00869     void
00870     setOpCodeArgs(
00871             eOpCodes                            theOpCode,
00872             OpCodeMapSizeType                   theIndex,
00873             const OpCodeMapValueVectorType&     theArgs);
00874 
00880     void
00881     appendOpCode(eOpCodes   theOpCode);
00882 
00889     void
00890     appendOpCode(eOpCodes                           theOpCode,
00891                  const OpCodeMapValueVectorType&    theArgs)
00892     {
00893         appendOpCode(theOpCode);
00894 
00895         setOpCodeArgs(theOpCode,
00896                       m_lastOpCodeIndex,
00897                       theArgs);
00898     }
00899 
00906     OpCodeMapValueType
00907     insertOpCode(
00908             eOpCodes            theOpCode,
00909             OpCodeMapSizeType   theIndex);
00910 
00920     void
00921     updateOpCodeLength(OpCodeMapSizeType    theIndex)
00922     {
00923         assert(theIndex < opCodeMapSize());
00924 
00925         updateOpCodeLength(m_opMap[theIndex], theIndex);
00926     }
00927 
00936     void
00937     updateShiftedOpCodeLength(
00938             OpCodeMapValueType  theOpCode,
00939             OpCodeMapSizeType   theOriginalIndex,
00940             OpCodeMapSizeType   theNewIndex);
00941 
00952     void
00953     updateOpCodeLength(
00954             OpCodeMapValueType  theOpCode,
00955             OpCodeMapSizeType   theIndex);
00956 
00964     static bool
00965     isNodeTestOpCode(OpCodeMapValueType     theOpCode);
00966 
00972     void
00973     updateOpCodeLengthAfterNodeTest(OpCodeMapSizeType   theIndex);
00974 
00980     bool
00981     hasMoreTokens() const
00982     {
00983         return tokenQueueSize() - m_currentPosition > 0 ? true : false;
00984     }
00985 
00991     TokenQueueSizeType
00992     getTokenPosition() const
00993     {
00994         return m_currentPosition;
00995     }
00996 
01000     void
01001     resetTokenPosition()
01002     {
01003         m_currentPosition = 0;
01004     }
01005 
01011     void
01012     setTokenPosition(TokenQueueSizeType     thePosition)
01013     {
01014         const TokenQueueSizeType    theSize = tokenQueueSize();
01015 
01016         m_currentPosition = thePosition > theSize ? theSize : thePosition;
01017     }
01018 
01024     void
01025     setTokenPosition(int    thePosition)
01026     {
01027         setTokenPosition(thePosition > 0 ? TokenQueueSizeType(thePosition) : 0);
01028     }
01029 
01036     const XObject*
01037     getToken(TokenQueueSizeType     thePosition) const
01038     {
01039         assert(thePosition < tokenQueueSize());
01040 
01041         return &m_tokenQueue[thePosition];
01042     }
01043 
01049     const XObject*
01050     getNextToken()
01051     {
01052         if (hasMoreTokens() == true)
01053         {
01054             return getToken(m_currentPosition++);
01055         }
01056         else
01057         {
01058             return 0;
01059         }
01060     }
01061 
01067     const XObject*
01068     getPreviousToken()
01069     {
01070         if (m_currentPosition > 0)
01071         {
01072             return getToken(--m_currentPosition);
01073         }
01074         else
01075         {
01076             return 0;
01077         }
01078     }
01079 
01087     const XObject*
01088     getRelativeToken(int    theOffset) const
01089     {
01090         const int   thePosition = int(m_currentPosition) + theOffset;
01091 
01092         if (thePosition < 0 ||
01093             thePosition >= int(tokenQueueSize()))
01094         {
01095             return 0;
01096         }
01097         else
01098         {
01099             return getToken(thePosition);
01100         }
01101     }
01102 
01108     void
01109     pushToken(const XalanDOMString&     theToken)
01110     {
01111         m_tokenQueue.push_back(XToken(theToken));
01112     }
01113 
01119     void
01120     pushToken(double    theToken)
01121     {
01122         m_tokenQueue.push_back(XToken(theToken));
01123     }
01124 
01131     void
01132     insertToken(const XalanDOMString&   theToken)
01133     {
01134         m_tokenQueue.insert(m_tokenQueue.begin() + (m_currentPosition - 1), XToken(theToken));
01135     }
01136 
01143     void
01144     insertToken(double  theToken)
01145     {
01146         m_tokenQueue.insert(m_tokenQueue.begin() + (m_currentPosition - 1), XToken(theToken));
01147     }
01148 
01155     void
01156     replaceRelativeToken(
01157             int                     theOffset,
01158             const XalanDOMString&   theToken)
01159     {
01160         assert(c_wstr(theToken) != 0);
01161 
01162         const int   thePosition = int(m_currentPosition) + theOffset;
01163 
01164         if (thePosition < 0 ||
01165             thePosition >= int(tokenQueueSize()))
01166         {
01167             throw InvalidRelativeTokenPosition(theOffset);
01168         }
01169 
01170         m_tokenQueue[thePosition] = theToken;
01171     }
01172 
01179     void
01180     replaceRelativeToken(
01181             int     theOffset,
01182             double  theToken)
01183     {
01184         assert(theToken != 0);
01185 
01186         const int   thePosition = int(m_currentPosition) + theOffset;
01187 
01188         if (thePosition < 0 || thePosition >= int(tokenQueueSize()))
01189         {
01190             throw InvalidRelativeTokenPosition(theOffset);
01191         }
01192 
01193         m_tokenQueue[thePosition] = theToken;
01194     }
01195 
01202     void
01203     dumpOpCodeMap(PrintWriter&          thePrintWriter,
01204                   OpCodeMapSizeType     theStartPosition = 0) const;
01205 
01212     void
01213     dumpOpCodeMap(
01214 #if defined(XALAN_NO_NAMESPACES)
01215             ostream&            theStream,
01216 #else
01217             std::ostream&       theStream,
01218 #endif
01219             OpCodeMapSizeType   theStartPosition = 0) const;
01220 
01227     void
01228     dumpTokenQueue(PrintWriter&         thePrintWriter,
01229                    TokenQueueSizeType   theStartPosition = 0) const;
01230 
01237     void
01238     dumpTokenQueue(
01239 #if defined(XALAN_NO_NAMESPACES)
01240             ostream&            theStream,
01241 #else
01242             std::ostream&       theStream,
01243 #endif
01244             TokenQueueSizeType  theStartPosition = 0) const;
01245 
01251     void
01252     dumpRemainingTokenQueue(PrintWriter&    thePrintWriter) const;
01253 
01259     void
01260 #if defined(XALAN_NO_NAMESPACES)
01261     dumpRemainingTokenQueue(ostream&        theStream) const;
01262 #else
01263     dumpRemainingTokenQueue(std::ostream&   theStream) const;
01264 #endif
01265 
01272     void
01273     pushValueOnOpCodeMap(const OpCodeMapType::value_type&   theValue)
01274     {
01275         // Push the index onto the op map.
01276         m_opMap.push_back(theValue);
01277 
01278         // Update the op map length.
01279         m_opMap[s_opCodeMapLengthIndex]++;
01280     }
01281 
01288     void
01289     pushArgumentOnOpCodeMap(const XalanDOMString&   theToken);
01290 
01297     void
01298     pushArgumentOnOpCodeMap(double  theToken);
01299 
01306     void
01307     pushNumberLiteralOnOpCodeMap(double     theNumber);
01308 
01314     double
01315     getNumberLiteral(int    theIndex) const
01316     {
01317         assert(theIndex >= 0 &&
01318                NumberLiteralValueVectorType::size_type(theIndex) < m_numberLiteralValues.size());
01319 
01320         return m_numberLiteralValues[NumberLiteralValueVectorType::size_type(theIndex)];
01321     }
01322 
01327     void
01328     pushCurrentTokenOnOpCodeMap();
01329 
01337     PatternMapValueType
01338     getPattern(int  thePatternPosition) const
01339     {
01340         assert(int(patternMapSize()) > thePatternPosition);
01341 
01342         return m_patternMap[thePatternPosition];
01343     }
01344 
01352     PatternMapValueType
01353     getPattern(PatternMapSizeType   thePatternPosition) const
01354     {
01355         assert(patternMapSize() > thePatternPosition);
01356 
01357         return m_patternMap[thePatternPosition];
01358     }
01359 
01365     void
01366     pushPattern(PatternMapValueType thePattern)
01367     {
01368         m_patternMap.push_back(thePattern);
01369     }
01370 
01377     void
01378     adjustPattern(
01379             OpCodeMapSizeType   theIndex,
01380             PatternMapValueType theAdjustment)
01381     {
01382         m_patternMap[theIndex] += theAdjustment;
01383     }
01384 
01390     void
01391     setCurrentPattern(const XalanDOMString&     thePattern)
01392     {
01393         m_currentPattern = thePattern;
01394     }
01395 
01401     const XalanDOMString&
01402     getCurrentPattern() const
01403     {
01404         return m_currentPattern;
01405     }
01406 
01413     OpCodeMapType           m_opMap;
01414 
01419     OpCodeMapSizeType       m_lastOpCodeIndex;
01420 
01426     TokenQueueType          m_tokenQueue;
01427 
01431     TokenQueueSizeType      m_currentPosition;
01432 
01440      // Ignore this, it is going away.
01441     PatternMapType          m_patternMap;
01442 
01446     XalanDOMString          m_currentPattern;
01447 
01448 private:
01449 
01450     // Default vector allocation sizes.
01451     enum
01452     {
01453         eDefaultOpMapSize = 100,
01454         eDefaultPatternMapSize = 100
01455     };
01456 
01457     NumberLiteralValueVectorType    m_numberLiteralValues;
01458 };
01459 
01460 
01461 
01462 #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.3
Copyright © 2000, 2001 The Apache Software Foundation. All Rights Reserved.