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