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