Xalan-C++ API Documentation

The Xalan C++ XSL Transformer Version 1.1

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 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_NO_IOSFWD)
00070 #if defined(XALAN_OLD_STREAM_HEADERS)
00071 #include <iostream.h>
00072 #else
00073 #include <ostream>
00074 #endif
00075 #else
00076 #include <iosfwd>
00077 #endif
00078 
00079 
00080 
00081 #include <XalanDOM/XalanDOMString.hpp>
00082 
00083 
00084 
00085 #include <PlatformSupport/DOMStringHelper.hpp>
00086 #include <PlatformSupport/PrintWriter.hpp>
00087 
00088 
00089 
00090 #include <XPath/XToken.hpp>
00091 #include <XPath/XPathException.hpp>
00092 
00093 
00094 
00095 class XALAN_XPATH_EXPORT XPathExpression
00096 {
00097 public:
00098 
00117     enum eOpCodes
00118     {
00124         eELEMWILDCARD = -3,
00125 
00130         eEMPTY = -2,
00131 
00136         eENDOP = -1,
00137 
00151         eOP_XPATH = 1,
00152 
00162         eOP_OR = 2,
00163 
00173         eOP_AND = 3,
00174 
00184         eOP_NOTEQUALS = 4,
00185 
00195         eOP_EQUALS = 5,
00196 
00206         eOP_LTE = 6,
00207 
00217         eOP_LT = 7,
00218 
00228         eOP_GTE = 8,
00229 
00239         eOP_GT = 9,
00240 
00250         eOP_PLUS = 10,
00251 
00261         eOP_MINUS = 11,
00262 
00272         eOP_MULT = 12,
00273 
00283         eOP_DIV = 13,
00284 
00294         eOP_MOD = 14,
00295 
00304         eOP_NEG = 15,
00305 
00314         eOP_BOOL = 16,
00315 
00324         eOP_UNION = 17,
00325 
00334         eOP_LITERAL = 18,
00335 
00344         eOP_VARIABLE = 19,
00345 
00359         eOP_GROUP = 20,
00360 
00369         eOP_NUMBERLIT = 21,
00370 
00384         eOP_ARGUMENT = 22,
00385 
00401         eOP_EXTFUNCTION = 23,
00402 
00418         eOP_FUNCTION = 24,
00419 
00433         eOP_LOCATIONPATH = 25,
00434 
00444         eOP_PREDICATE = 26,
00445   
00453         eNODETYPE_COMMENT = 27,
00454         
00462         eNODETYPE_TEXT = 28,
00463         
00471         eNODETYPE_PI = 29,
00472         
00480         eNODETYPE_NODE = 30,
00481         
00490         eNODENAME = 31,
00491         
00499         eNODETYPE_ROOT = 32,
00500         
00508         eNODETYPE_ANYELEMENT = 33,
00509 
00520         eFROM_ANCESTORS = 34,
00521         eFROM_ANCESTORS_OR_SELF = 35,
00522         eFROM_ATTRIBUTES = 36,
00523         eFROM_CHILDREN = 37,
00524         eFROM_DESCENDANTS = 38,
00525         eFROM_DESCENDANTS_OR_SELF = 39,
00526         eFROM_FOLLOWING = 40,
00527         eFROM_FOLLOWING_SIBLINGS = 41,
00528         eFROM_PARENT = 42,
00529         eFROM_PRECEDING = 43,
00530         eFROM_PRECEDING_SIBLINGS = 44,
00531         eFROM_SELF = 45,
00532         eFROM_NAMESPACE = 46,
00533         eFROM_ROOT = 47,
00534 
00543         eOP_MATCHPATTERN = 48,
00544 
00553         eOP_LOCATIONPATHPATTERN = 49,
00554 
00555         // For match patterns
00556         eMATCH_ATTRIBUTE = 50,
00557         eMATCH_ANY_ANCESTOR = 51,
00558         eMATCH_IMMEDIATE_ANCESTOR = 52,
00559         eMATCH_ANY_ANCESTOR_WITH_PREDICATE = 53,
00560         eMATCH_ANY_ANCESTOR_WITH_FUNCTION_CALL = 54,
00561 
00562         // Always add _before_ this one and update
00563         // s_opCodeLengthArray.
00564         eOpCodeNextAvailable
00565     };  // enum eOpCodes
00566 
00573 #if defined(XALAN_INLINE_INITIALIZATION)
00574     static const int    s_opCodeMapLengthIndex = 1;
00575 #else
00576     enum eDummy
00577     {
00578         s_opCodeMapLengthIndex = 1
00579     };
00580 #endif
00581 
00585     class XALAN_XPATH_EXPORT XPathExpressionException : public XPathException
00586     {
00587     public:
00588 
00594         XPathExpressionException(const XalanDOMString&  theMessage);
00595 
00596         virtual~
00597         XPathExpressionException();
00598     };
00599 
00603     class XALAN_XPATH_EXPORT InvalidOpCodeException : public XPathExpressionException
00604     {
00605     public:
00606 
00612         InvalidOpCodeException(int  theOpCode);
00613 
00614         virtual~
00615         InvalidOpCodeException();
00616 
00617     private:
00618 
00619         static XalanDOMString
00620         FormatErrorMessage(int  theOpCode);
00621     };
00622 
00627     class XALAN_XPATH_EXPORT InvalidArgumentCountException : public XPathExpressionException
00628     {
00629     public:
00630 
00638         InvalidArgumentCountException(
00639             int     theOpCode,
00640             int     theExpectedCount,
00641             int     theSuppliedCount);
00642 
00643         virtual~
00644         InvalidArgumentCountException();
00645 
00646     private:
00647 
00648         static XalanDOMString
00649         FormatErrorMessage(
00650             int     theOpCode,
00651             int     theExpectedCount,
00652             int     theSuppliedCount);
00653     };
00654 
00658     class XALAN_XPATH_EXPORT InvalidArgumentException : public XPathExpressionException
00659     {
00660     public:
00661 
00668         InvalidArgumentException(
00669             int theOpCode,
00670             int theValue);
00671 
00672         virtual~
00673         InvalidArgumentException();
00674 
00675     private:
00676 
00677         static XalanDOMString
00678         FormatErrorMessage(
00679                 int     theOpCode,
00680                 int     theValue);
00681     };
00682 
00686     class XALAN_XPATH_EXPORT InvalidRelativeTokenPosition : public XPathExpressionException
00687     {
00688     public:
00689 
00695         InvalidRelativeTokenPosition(int    theOffset);
00696 
00697         virtual~
00698         InvalidRelativeTokenPosition();
00699 
00700     private:
00701 
00702         static XalanDOMString
00703         FormatErrorMessage(int  theOffset);
00704     };
00705 
00706 
00707 #if defined(XALAN_NO_NAMESPACES)
00708 
00709     typedef vector<int>                     OpCodeMapType;
00710     typedef vector<XToken>                  TokenQueueType;
00711     typedef vector<int>                     PatternMapType;
00712 
00713     typedef OpCodeMapType::value_type       OpCodeMapValueType;
00714     typedef OpCodeMapType::size_type        OpCodeMapSizeType;
00715 
00716     typedef vector<OpCodeMapValueType>      OpCodeMapValueVectorType;
00717 
00718     typedef vector<double>                  NumberLiteralValueVectorType;
00719 #else
00720 
00721     typedef std::vector<int>                OpCodeMapType;
00722     typedef std::vector<XToken>             TokenQueueType;
00723     typedef std::vector<int>                PatternMapType;
00724 
00725     typedef OpCodeMapType::value_type       OpCodeMapValueType;
00726     typedef OpCodeMapType::size_type        OpCodeMapSizeType;
00727 
00728     typedef std::vector<OpCodeMapValueType> OpCodeMapValueVectorType;
00729 
00730     typedef std::vector<double>             NumberLiteralValueVectorType;
00731 #endif
00732 
00733     typedef TokenQueueType::value_type      TokenQueueValueType;
00734     typedef TokenQueueType::size_type       TokenQueueSizeType;
00735     typedef PatternMapType::value_type      PatternMapValueType;
00736     typedef PatternMapType::size_type       PatternMapSizeType;
00737 
00738     explicit
00739     XPathExpression();
00740 
00741     ~XPathExpression();
00742 
00746     void
00747     reset();
00748 
00752     void
00753     shrink();
00754 
00760     OpCodeMapSizeType
00761     opCodeMapSize() const
00762     {
00763         return m_opMap.size();
00764     }
00765 
00777     OpCodeMapValueType
00778     opCodeMapLength() const
00779     {
00780         const OpCodeMapSizeType     theSize = opCodeMapSize();
00781 
00782         if (theSize > s_opCodeMapLengthIndex)
00783         {
00784             assert(theSize ==
00785                 OpCodeMapSizeType(m_opMap[s_opCodeMapLengthIndex]));
00786 
00787             return m_opMap[s_opCodeMapLengthIndex];
00788         }
00789         else
00790         {
00791             return theSize;
00792         }
00793     }
00794 
00800     TokenQueueSizeType
00801     tokenQueueSize() const
00802     {
00803         return m_tokenQueue.size();
00804     }
00805 
00811     PatternMapSizeType
00812     patternMapSize() const
00813     {
00814         return m_patternMap.size();
00815     }
00816 
00824     OpCodeMapValueType
00825     getOpCodeMapValue(OpCodeMapSizeType     opPos) const
00826     {
00827         return m_opMap[opPos];
00828     }
00829 
00830     OpCodeMapValueType
00831     getOpCodeArgumentLength(OpCodeMapSizeType   opPos) const
00832     {
00833         return getOpCodeMapValue(opPos + XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
00834     }
00835 
00843     OpCodeMapValueType
00844     getOpCodeLengthFromOpMap(OpCodeMapSizeType  opPos) const;
00845 
00853     OpCodeMapValueType
00854     getNextOpCodePosition(OpCodeMapSizeType     opPos) const
00855     {
00856         assert(opPos < opCodeMapSize());
00857 
00858         return opPos + m_opMap[opPos + s_opCodeMapLengthIndex];
00859     }
00860 
00870     void
00871     setOpCodeArgs(
00872             eOpCodes                            theOpCode,
00873             OpCodeMapSizeType                   theIndex,
00874             const OpCodeMapValueVectorType&     theArgs);
00875 
00881     void
00882     appendOpCode(eOpCodes   theOpCode);
00883 
00890     void
00891     appendOpCode(eOpCodes                           theOpCode,
00892                  const OpCodeMapValueVectorType&    theArgs)
00893     {
00894         appendOpCode(theOpCode);
00895 
00896         setOpCodeArgs(theOpCode,
00897                       m_lastOpCodeIndex,
00898                       theArgs);
00899     }
00900 
00907     OpCodeMapValueType
00908     insertOpCode(
00909             eOpCodes            theOpCode,
00910             OpCodeMapSizeType   theIndex);
00911 
00921     void
00922     updateOpCodeLength(OpCodeMapSizeType    theIndex)
00923     {
00924         assert(theIndex < opCodeMapSize());
00925 
00926         updateOpCodeLength(m_opMap[theIndex], theIndex);
00927     }
00928 
00937     void
00938     updateShiftedOpCodeLength(
00939             OpCodeMapValueType  theOpCode,
00940             OpCodeMapSizeType   theOriginalIndex,
00941             OpCodeMapSizeType   theNewIndex);
00942 
00953     void
00954     updateOpCodeLength(
00955             OpCodeMapValueType  theOpCode,
00956             OpCodeMapSizeType   theIndex);
00957 
00965     static bool
00966     isNodeTestOpCode(OpCodeMapValueType     theOpCode);
00967 
00973     void
00974     updateOpCodeLengthAfterNodeTest(OpCodeMapSizeType   theIndex);
00975 
00981     bool
00982     hasMoreTokens() const
00983     {
00984         return tokenQueueSize() - m_currentPosition > 0 ? true : false;
00985     }
00986 
00992     TokenQueueSizeType
00993     getTokenPosition() const
00994     {
00995         return m_currentPosition;
00996     }
00997 
01001     void
01002     resetTokenPosition()
01003     {
01004         m_currentPosition = 0;
01005     }
01006 
01012     void
01013     setTokenPosition(TokenQueueSizeType     thePosition)
01014     {
01015         const TokenQueueSizeType    theSize = tokenQueueSize();
01016 
01017         m_currentPosition = thePosition > theSize ? theSize : thePosition;
01018     }
01019 
01025     void
01026     setTokenPosition(int    thePosition)
01027     {
01028         setTokenPosition(thePosition > 0 ? TokenQueueSizeType(thePosition) : 0);
01029     }
01030 
01037     const XObject*
01038     getToken(TokenQueueSizeType     thePosition) const
01039     {
01040         assert(thePosition < tokenQueueSize());
01041 
01042         return &m_tokenQueue[thePosition];
01043     }
01044 
01050     const XObject*
01051     getNextToken()
01052     {
01053         if (hasMoreTokens() == true)
01054         {
01055             return getToken(m_currentPosition++);
01056         }
01057         else
01058         {
01059             return 0;
01060         }
01061     }
01062 
01068     const XObject*
01069     getPreviousToken()
01070     {
01071         if (m_currentPosition > 0)
01072         {
01073             return getToken(--m_currentPosition);
01074         }
01075         else
01076         {
01077             return 0;
01078         }
01079     }
01080 
01088     const XObject*
01089     getRelativeToken(int    theOffset) const
01090     {
01091         const int   thePosition = int(m_currentPosition) + theOffset;
01092 
01093         if (thePosition < 0 ||
01094             thePosition >= int(tokenQueueSize()))
01095         {
01096             return 0;
01097         }
01098         else
01099         {
01100             return getToken(thePosition);
01101         }
01102     }
01103 
01109     void
01110     pushToken(const XalanDOMString&     theToken)
01111     {
01112         m_tokenQueue.push_back(XToken(theToken));
01113     }
01114 
01120     void
01121     pushToken(double    theToken)
01122     {
01123         m_tokenQueue.push_back(XToken(theToken));
01124     }
01125 
01132     void
01133     insertToken(const XalanDOMString&   theToken)
01134     {
01135         m_tokenQueue.insert(m_tokenQueue.begin() + (m_currentPosition - 1), XToken(theToken));
01136     }
01137 
01144     void
01145     insertToken(double  theToken)
01146     {
01147         m_tokenQueue.insert(m_tokenQueue.begin() + (m_currentPosition - 1), XToken(theToken));
01148     }
01149 
01156     void
01157     replaceRelativeToken(
01158             int                     theOffset,
01159             const XalanDOMString&   theToken)
01160     {
01161         assert(c_wstr(theToken) != 0);
01162 
01163         const int   thePosition = int(m_currentPosition) + theOffset;
01164 
01165         if (thePosition < 0 ||
01166             thePosition >= int(tokenQueueSize()))
01167         {
01168             throw InvalidRelativeTokenPosition(theOffset);
01169         }
01170 
01171         m_tokenQueue[thePosition] = theToken;
01172     }
01173 
01180     void
01181     replaceRelativeToken(
01182             int     theOffset,
01183             double  theToken)
01184     {
01185         assert(theToken != 0);
01186 
01187         const int   thePosition = int(m_currentPosition) + theOffset;
01188 
01189         if (thePosition < 0 || thePosition >= int(tokenQueueSize()))
01190         {
01191             throw InvalidRelativeTokenPosition(theOffset);
01192         }
01193 
01194         m_tokenQueue[thePosition] = theToken;
01195     }
01196 
01203     void
01204     dumpOpCodeMap(PrintWriter&          thePrintWriter,
01205                   OpCodeMapSizeType     theStartPosition = 0) const;
01206 
01213     void
01214     dumpOpCodeMap(
01215 #if defined(XALAN_NO_NAMESPACES)
01216             ostream&            theStream,
01217 #else
01218             std::ostream&       theStream,
01219 #endif
01220             OpCodeMapSizeType   theStartPosition = 0) const;
01221 
01228     void
01229     dumpTokenQueue(PrintWriter&         thePrintWriter,
01230                    TokenQueueSizeType   theStartPosition = 0) const;
01231 
01238     void
01239     dumpTokenQueue(
01240 #if defined(XALAN_NO_NAMESPACES)
01241             ostream&            theStream,
01242 #else
01243             std::ostream&       theStream,
01244 #endif
01245             TokenQueueSizeType  theStartPosition = 0) const;
01246 
01252     void
01253     dumpRemainingTokenQueue(PrintWriter&    thePrintWriter) const;
01254 
01260     void
01261 #if defined(XALAN_NO_NAMESPACES)
01262     dumpRemainingTokenQueue(ostream&        theStream) const;
01263 #else
01264     dumpRemainingTokenQueue(std::ostream&   theStream) const;
01265 #endif
01266 
01273     void
01274     pushValueOnOpCodeMap(const OpCodeMapType::value_type&   theValue)
01275     {
01276         // Push the index onto the op map.
01277         m_opMap.push_back(theValue);
01278 
01279         // Update the op map length.
01280         m_opMap[s_opCodeMapLengthIndex]++;
01281     }
01282 
01289     void
01290     pushArgumentOnOpCodeMap(const XalanDOMString&   theToken);
01291 
01298     void
01299     pushArgumentOnOpCodeMap(double  theToken);
01300 
01307     void
01308     pushNumberLiteralOnOpCodeMap(double     theNumber);
01309 
01315     double
01316     getNumberLiteral(int    theIndex) const
01317     {
01318         assert(theIndex >= 0 &&
01319                NumberLiteralValueVectorType::size_type(theIndex) < m_numberLiteralValues.size());
01320 
01321         return m_numberLiteralValues[NumberLiteralValueVectorType::size_type(theIndex)];
01322     }
01323 
01328     void
01329     pushCurrentTokenOnOpCodeMap();
01330 
01338     PatternMapValueType
01339     getPattern(int  thePatternPosition) const
01340     {
01341         assert(int(patternMapSize()) > thePatternPosition);
01342 
01343         return m_patternMap[thePatternPosition];
01344     }
01345 
01353     PatternMapValueType
01354     getPattern(PatternMapSizeType   thePatternPosition) const
01355     {
01356         assert(patternMapSize() > thePatternPosition);
01357 
01358         return m_patternMap[thePatternPosition];
01359     }
01360 
01366     void
01367     pushPattern(PatternMapValueType thePattern)
01368     {
01369         m_patternMap.push_back(thePattern);
01370     }
01371 
01378     void
01379     adjustPattern(
01380             OpCodeMapSizeType   theIndex,
01381             PatternMapValueType theAdjustment)
01382     {
01383         m_patternMap[theIndex] += theAdjustment;
01384     }
01385 
01391     void
01392     setCurrentPattern(const XalanDOMString&     thePattern)
01393     {
01394         m_currentPattern = thePattern;
01395     }
01396 
01402     const XalanDOMString&
01403     getCurrentPattern() const
01404     {
01405         return m_currentPattern;
01406     }
01407 
01414     OpCodeMapType           m_opMap;
01415 
01420     OpCodeMapSizeType       m_lastOpCodeIndex;
01421 
01427     TokenQueueType          m_tokenQueue;
01428 
01432     TokenQueueSizeType      m_currentPosition;
01433 
01441      // Ignore this, it is going away.
01442     PatternMapType          m_patternMap;
01443 
01447     XalanDOMString          m_currentPattern;
01448 
01449 private:
01450 
01451     // Default vector allocation sizes.
01452     enum
01453     {
01454         eDefaultOpMapSize = 100,
01455         eDefaultPatternMapSize = 100
01456     };
01457 
01458     NumberLiteralValueVectorType    m_numberLiteralValues;
01459 };
01460 
01461 
01462 
01463 #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.1
Copyright © 2000, 2001 The Apache Software Foundation. All Rights Reserved.