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
Doxygen and GraphViz are used to generate this API documentation from the Xalan-C header files.
![]() |
Xalan-C++ XSL Transformer Version 1.1 |
|