Xalan-C++ API Documentation

The Xalan C++ XSLT Processor Version 1.4

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-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 
00567         eOP_PREDICATE_WITH_POSITION = 55,
00568   
00569         // Always add _before_ this one and update
00570         // s_opCodeLengthArray.
00571         eOpCodeNextAvailable
00572     };  // enum eOpCodes
00573 
00577     class XALAN_XPATH_EXPORT XPathExpressionException : public XalanXPathException
00578     {
00579     public:
00580 
00586         XPathExpressionException(const XalanDOMString&  theMessage);
00587 
00588         virtual~
00589         XPathExpressionException();
00590     };
00591 
00595     class XALAN_XPATH_EXPORT InvalidOpCodeException : public XPathExpressionException
00596     {
00597     public:
00598 
00604         InvalidOpCodeException(int  theOpCode);
00605 
00606         virtual~
00607         InvalidOpCodeException();
00608 
00609     private:
00610 
00611         static XalanDOMString
00612         FormatErrorMessage(int  theOpCode);
00613     };
00614 
00619     class XALAN_XPATH_EXPORT InvalidArgumentCountException : public XPathExpressionException
00620     {
00621     public:
00622 
00630         InvalidArgumentCountException(
00631             int     theOpCode,
00632             int     theExpectedCount,
00633             int     theSuppliedCount);
00634 
00635         virtual~
00636         InvalidArgumentCountException();
00637 
00638     private:
00639 
00640         static XalanDOMString
00641         FormatErrorMessage(
00642             int     theOpCode,
00643             int     theExpectedCount,
00644             int     theSuppliedCount);
00645     };
00646 
00650     class XALAN_XPATH_EXPORT InvalidArgumentException : public XPathExpressionException
00651     {
00652     public:
00653 
00660         InvalidArgumentException(
00661             int theOpCode,
00662             int theValue);
00663 
00664         virtual~
00665         InvalidArgumentException();
00666 
00667     private:
00668 
00669         static XalanDOMString
00670         FormatErrorMessage(
00671                 int     theOpCode,
00672                 int     theValue);
00673     };
00674 
00678     class XALAN_XPATH_EXPORT InvalidRelativeTokenPosition : public XPathExpressionException
00679     {
00680     public:
00681 
00687         InvalidRelativeTokenPosition(int    theOffset);
00688 
00689         virtual~
00690         InvalidRelativeTokenPosition();
00691 
00692     private:
00693 
00694         static XalanDOMString
00695         FormatErrorMessage(int  theOffset);
00696     };
00697 
00698 
00699 #if defined(XALAN_NO_NAMESPACES)
00700 
00701     typedef vector<int>                     OpCodeMapType;
00702     typedef vector<XToken>                  TokenQueueType;
00703     typedef vector<int>                     PatternMapType;
00704 
00705     typedef OpCodeMapType::value_type       OpCodeMapValueType;
00706     typedef OpCodeMapType::size_type        OpCodeMapSizeType;
00707 
00708     typedef vector<OpCodeMapValueType>      OpCodeMapValueVectorType;
00709 
00710     typedef vector<double>                  NumberLiteralValueVectorType;
00711 #else
00712 
00713     typedef std::vector<int>                OpCodeMapType;
00714     typedef std::vector<XToken>             TokenQueueType;
00715     typedef std::vector<int>                PatternMapType;
00716 
00717     typedef OpCodeMapType::value_type       OpCodeMapValueType;
00718     typedef OpCodeMapType::size_type        OpCodeMapSizeType;
00719 
00720     typedef std::vector<OpCodeMapValueType> OpCodeMapValueVectorType;
00721 
00722     typedef std::vector<double>             NumberLiteralValueVectorType;
00723 #endif
00724 
00725     typedef TokenQueueType::value_type      TokenQueueValueType;
00726     typedef TokenQueueType::size_type       TokenQueueSizeType;
00727     typedef PatternMapType::value_type      PatternMapValueType;
00728     typedef PatternMapType::size_type       PatternMapSizeType;
00729 
00736 #if defined(XALAN_INLINE_INITIALIZATION)
00737     static const TokenQueueSizeType     s_opCodeMapLengthIndex = 1;
00738 #else
00739     enum eDummy
00740     {
00741         s_opCodeMapLengthIndex = 1
00742     };
00743 #endif
00744 
00745     explicit
00746     XPathExpression();
00747 
00748     ~XPathExpression();
00749 
00753     void
00754     reset();
00755 
00759     void
00760     shrink();
00761 
00767     OpCodeMapSizeType
00768     opCodeMapSize() const
00769     {
00770         return m_opMap.size();
00771     }
00772 
00784     OpCodeMapValueType
00785     opCodeMapLength() const
00786     {
00787         const OpCodeMapSizeType     theSize = opCodeMapSize();
00788 
00789         if (theSize > s_opCodeMapLengthIndex)
00790         {
00791             assert(theSize == OpCodeMapSizeType(m_opMap[s_opCodeMapLengthIndex]));
00792 
00793             return m_opMap[s_opCodeMapLengthIndex];
00794         }
00795         else
00796         {
00797             assert(theSize == OpCodeMapValueType(theSize));
00798 
00799             return OpCodeMapValueType(theSize);
00800         }
00801     }
00802 
00808     TokenQueueSizeType
00809     tokenQueueSize() const
00810     {
00811         return m_tokenQueue.size();
00812     }
00813 
00819     PatternMapSizeType
00820     patternMapSize() const
00821     {
00822         return m_patternMap.size();
00823     }
00824 
00832     OpCodeMapValueType
00833     getOpCodeMapValue(OpCodeMapSizeType     opPos) const
00834     {
00835         return m_opMap[opPos];
00836     }
00837 
00838     OpCodeMapValueType
00839     getOpCodeArgumentLength(OpCodeMapSizeType   opPos) const
00840     {
00841         return getOpCodeMapValue(opPos + XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
00842     }
00843 
00851     OpCodeMapValueType
00852     getOpCodeLengthFromOpMap(OpCodeMapSizeType  opPos) const;
00853 
00861     OpCodeMapValueType
00862     getNextOpCodePosition(OpCodeMapSizeType     opPos) const
00863     {
00864         assert(opPos < opCodeMapSize());
00865 
00866         assert(opPos + m_opMap[opPos + s_opCodeMapLengthIndex] == OpCodeMapValueType(opPos + m_opMap[opPos + s_opCodeMapLengthIndex]));
00867 
00868         return OpCodeMapValueType(opPos + m_opMap[opPos + s_opCodeMapLengthIndex]);
00869     }
00870 
00880     void
00881     setOpCodeArgs(
00882             eOpCodes                            theOpCode,
00883             OpCodeMapSizeType                   theIndex,
00884             const OpCodeMapValueVectorType&     theArgs);
00885 
00892     OpCodeMapSizeType
00893     appendOpCode(eOpCodes   theOpCode);
00894 
00901     OpCodeMapSizeType
00902     appendOpCode(eOpCodes                           theOpCode,
00903                  const OpCodeMapValueVectorType&    theArgs)
00904     {
00905         const OpCodeMapSizeType     thePosition = appendOpCode(theOpCode);
00906 
00907         setOpCodeArgs(theOpCode,
00908                       thePosition,
00909                       theArgs);
00910 
00911         return thePosition;
00912     }
00913 
00921     void
00922     replaceOpCode(
00923             OpCodeMapSizeType   theIndex,
00924             eOpCodes            theOldOpCode,
00925             eOpCodes            theNewOpCode);
00926 
00933     OpCodeMapValueType
00934     insertOpCode(
00935             eOpCodes            theOpCode,
00936             OpCodeMapSizeType   theIndex);
00937 
00947     void
00948     updateOpCodeLength(OpCodeMapSizeType    theIndex)
00949     {
00950         assert(theIndex < opCodeMapSize());
00951 
00952         updateOpCodeLength(m_opMap[theIndex], theIndex);
00953     }
00954 
00963     void
00964     updateShiftedOpCodeLength(
00965             OpCodeMapValueType  theOpCode,
00966             OpCodeMapSizeType   theOriginalIndex,
00967             OpCodeMapSizeType   theNewIndex);
00968 
00979     void
00980     updateOpCodeLength(
00981             OpCodeMapValueType  theOpCode,
00982             OpCodeMapSizeType   theIndex);
00983 
00991     static bool
00992     isNodeTestOpCode(OpCodeMapValueType     theOpCode);
00993 
00999     void
01000     updateOpCodeLengthAfterNodeTest(OpCodeMapSizeType   theIndex);
01001 
01007     bool
01008     hasMoreTokens() const
01009     {
01010         return tokenQueueSize() - m_currentPosition > 0 ? true : false;
01011     }
01012 
01018     TokenQueueSizeType
01019     getTokenPosition() const
01020     {
01021         return m_currentPosition;
01022     }
01023 
01027     void
01028     resetTokenPosition()
01029     {
01030         m_currentPosition = 0;
01031     }
01032 
01038     void
01039     setTokenPosition(TokenQueueSizeType     thePosition)
01040     {
01041         const TokenQueueSizeType    theSize = tokenQueueSize();
01042 
01043         m_currentPosition = thePosition > theSize ? theSize : thePosition;
01044     }
01045 
01051     void
01052     setTokenPosition(int    thePosition)
01053     {
01054         setTokenPosition(thePosition > 0 ? TokenQueueSizeType(thePosition) : 0);
01055     }
01056 
01063     const XObject*
01064     getToken(TokenQueueSizeType     thePosition) const
01065     {
01066         assert(thePosition < tokenQueueSize());
01067 
01068         return &m_tokenQueue[thePosition];
01069     }
01070 
01076     const XObject*
01077     getNextToken()
01078     {
01079         if (hasMoreTokens() == true)
01080         {
01081             return getToken(m_currentPosition++);
01082         }
01083         else
01084         {
01085             return 0;
01086         }
01087     }
01088 
01094     const XObject*
01095     getPreviousToken()
01096     {
01097         if (m_currentPosition > 0)
01098         {
01099             return getToken(--m_currentPosition);
01100         }
01101         else
01102         {
01103             return 0;
01104         }
01105     }
01106 
01114     const XObject*
01115     getRelativeToken(int    theOffset) const
01116     {
01117         const int   thePosition = int(m_currentPosition) + theOffset;
01118 
01119         if (thePosition < 0 ||
01120             thePosition >= int(tokenQueueSize()))
01121         {
01122             return 0;
01123         }
01124         else
01125         {
01126             return getToken(thePosition);
01127         }
01128     }
01129 
01135     void
01136     pushToken(const XalanDOMString&     theToken)
01137     {
01138         m_tokenQueue.push_back(XToken(theToken));
01139     }
01140 
01146     void
01147     pushToken(double    theToken)
01148     {
01149         m_tokenQueue.push_back(XToken(theToken));
01150     }
01151 
01158     void
01159     insertToken(const XalanDOMString&   theToken)
01160     {
01161         m_tokenQueue.insert(m_tokenQueue.begin() + (m_currentPosition - 1), XToken(theToken));
01162     }
01163 
01170     void
01171     insertToken(double  theToken)
01172     {
01173         m_tokenQueue.insert(m_tokenQueue.begin() + (m_currentPosition - 1), XToken(theToken));
01174     }
01175 
01182     void
01183     replaceRelativeToken(
01184             int                     theOffset,
01185             const XalanDOMString&   theToken)
01186     {
01187         assert(c_wstr(theToken) != 0);
01188 
01189         const int   thePosition = int(m_currentPosition) + theOffset;
01190 
01191         if (thePosition < 0 ||
01192             thePosition >= int(tokenQueueSize()))
01193         {
01194             throw InvalidRelativeTokenPosition(theOffset);
01195         }
01196 
01197         m_tokenQueue[thePosition] = theToken;
01198     }
01199 
01206     void
01207     replaceRelativeToken(
01208             int     theOffset,
01209             double  theToken)
01210     {
01211         assert(theToken != 0);
01212 
01213         const int   thePosition = int(m_currentPosition) + theOffset;
01214 
01215         if (thePosition < 0 || thePosition >= int(tokenQueueSize()))
01216         {
01217             throw InvalidRelativeTokenPosition(theOffset);
01218         }
01219 
01220         m_tokenQueue[thePosition] = theToken;
01221     }
01222 
01229     void
01230     dumpOpCodeMap(PrintWriter&          thePrintWriter,
01231                   OpCodeMapSizeType     theStartPosition = 0) const;
01232 
01239     void
01240     dumpOpCodeMap(
01241 #if defined(XALAN_NO_NAMESPACES)
01242             ostream&            theStream,
01243 #else
01244             std::ostream&       theStream,
01245 #endif
01246             OpCodeMapSizeType   theStartPosition = 0) const;
01247 
01254     void
01255     dumpTokenQueue(PrintWriter&         thePrintWriter,
01256                    TokenQueueSizeType   theStartPosition = 0) const;
01257 
01264     void
01265     dumpTokenQueue(
01266 #if defined(XALAN_NO_NAMESPACES)
01267             ostream&            theStream,
01268 #else
01269             std::ostream&       theStream,
01270 #endif
01271             TokenQueueSizeType  theStartPosition = 0) const;
01272 
01278     void
01279     dumpRemainingTokenQueue(PrintWriter&    thePrintWriter) const;
01280 
01286     void
01287 #if defined(XALAN_NO_NAMESPACES)
01288     dumpRemainingTokenQueue(ostream&        theStream) const;
01289 #else
01290     dumpRemainingTokenQueue(std::ostream&   theStream) const;
01291 #endif
01292 
01299     void
01300     pushValueOnOpCodeMap(const OpCodeMapType::value_type&   theValue)
01301     {
01302         // Push the index onto the op map.
01303         m_opMap.push_back(theValue);
01304 
01305         // Update the op map length.
01306         m_opMap[s_opCodeMapLengthIndex]++;
01307     }
01308 
01315     void
01316     pushArgumentOnOpCodeMap(const XalanDOMString&   theToken);
01317 
01324     void
01325     pushArgumentOnOpCodeMap(double  theToken);
01326 
01333     void
01334     pushNumberLiteralOnOpCodeMap(double     theNumber);
01335 
01341     double
01342     getNumberLiteral(int    theIndex) const
01343     {
01344         assert(theIndex >= 0 &&
01345                NumberLiteralValueVectorType::size_type(theIndex) < m_numberLiteralValues.size());
01346 
01347         return m_numberLiteralValues[NumberLiteralValueVectorType::size_type(theIndex)];
01348     }
01349 
01354     void
01355     pushCurrentTokenOnOpCodeMap();
01356 
01364     PatternMapValueType
01365     getPattern(int  thePatternPosition) const
01366     {
01367         assert(int(patternMapSize()) > thePatternPosition);
01368 
01369         return m_patternMap[thePatternPosition];
01370     }
01371 
01379     PatternMapValueType
01380     getPattern(PatternMapSizeType   thePatternPosition) const
01381     {
01382         assert(patternMapSize() > thePatternPosition);
01383 
01384         return m_patternMap[thePatternPosition];
01385     }
01386 
01392     void
01393     pushPattern(PatternMapValueType thePattern)
01394     {
01395         m_patternMap.push_back(thePattern);
01396     }
01397 
01404     void
01405     adjustPattern(
01406             OpCodeMapSizeType   theIndex,
01407             PatternMapValueType theAdjustment)
01408     {
01409         m_patternMap[theIndex] += theAdjustment;
01410     }
01411 
01417     void
01418     setCurrentPattern(const XalanDOMString&     thePattern)
01419     {
01420         m_currentPattern = thePattern;
01421     }
01422 
01428     const XalanDOMString&
01429     getCurrentPattern() const
01430     {
01431         return m_currentPattern;
01432     }
01433 
01440     OpCodeMapType           m_opMap;
01441 
01446     OpCodeMapSizeType       m_lastOpCodeIndex;
01447 
01453     TokenQueueType          m_tokenQueue;
01454 
01458     TokenQueueSizeType      m_currentPosition;
01459 
01467      // Ignore this, it is going away.
01468     PatternMapType          m_patternMap;
01469 
01473     XalanDOMString          m_currentPattern;
01474 
01475 private:
01476 
01477     // Default vector allocation sizes.
01478     enum
01479     {
01480         eDefaultOpMapSize = 100,
01481         eDefaultPatternMapSize = 100
01482     };
01483 
01484     NumberLiteralValueVectorType    m_numberLiteralValues;
01485 };
01486 
01487 
01488 
01489 #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.4
Copyright © 2000, 2001, 2002 The Apache Software Foundation. All Rights Reserved.