Xalan-C++ API Documentation

The Xalan C++ XSLT Processor Version 1.10

XPathExpression.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #if !defined(XPATHEXPRESSION_HEADER_GUARD_1357924680)
17 #define XPATHEXPRESSION_HEADER_GUARD_1357924680
18 
19 
20 
21 // Base header file. Must be first.
23 
24 
25 
27 
28 
29 
30 #if defined(XALAN_CLASSIC_IOSTREAMS)
31 #include <iostream.h>
32 #else
33 #include <iosfwd>
34 #endif
35 
36 
37 
39 
40 
41 
44 
45 
46 
47 #include <xalanc/XPath/XToken.hpp>
49 
50 
51 
52 XALAN_CPP_NAMESPACE_BEGIN
53 
54 
55 
56 XALAN_USING_XERCES(MemoryManager)
57 
58 
59 
61 {
62 public:
63 
64  typedef XALAN_STD_QUALIFIER ostream OstreamType;
65 
68 
70  typedef OpCodeMapValueType OpCodeMapSizeType;
71 
73 
75 
76 #define XALAN_XPATH_EXPRESSION_USE_ITERATORS
77 
78 #if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS)
80 #else
81  typedef OpCodeMapSizeType OpCodeMapPositionType;
82 #endif
85  typedef int TokenQueueSizeType;
86  typedef TokenQueueSizeType TokenQueuePositionType;
87 
106  enum eOpCodes
107  {
113  eELEMWILDCARD = -3,
114 
119  eEMPTY = -2,
120 
125  eENDOP = -1,
126 
140  eOP_XPATH = 1,
141 
151  eOP_OR = 2,
152 
162  eOP_AND = 3,
163 
173  eOP_NOTEQUALS = 4,
174 
184  eOP_EQUALS = 5,
185 
195  eOP_LTE = 6,
196 
206  eOP_LT = 7,
207 
217  eOP_GTE = 8,
218 
228  eOP_GT = 9,
229 
239  eOP_PLUS = 10,
240 
250  eOP_MINUS = 11,
251 
261  eOP_MULT = 12,
262 
272  eOP_DIV = 13,
273 
283  eOP_MOD = 14,
284 
293  eOP_NEG = 15,
294 
303  eOP_BOOL = 16,
304 
313  eOP_UNION = 17,
314 
323  eOP_LITERAL = 18,
324 
333  eOP_VARIABLE = 19,
334 
348  eOP_GROUP = 20,
349 
358  eOP_NUMBERLIT = 21,
359 
373  eOP_ARGUMENT = 22,
374 
390  eOP_EXTFUNCTION = 23,
391 
408  eOP_FUNCTION = 24,
409 
423  eOP_LOCATIONPATH = 25,
424 
434  eOP_PREDICATE = 26,
435 
443  eNODETYPE_COMMENT = 27,
444 
452  eNODETYPE_TEXT = 28,
453 
461  eNODETYPE_PI = 29,
462 
470  eNODETYPE_NODE = 30,
471 
480  eNODENAME = 31,
481 
489  eNODETYPE_ROOT = 32,
490 
498  eNODETYPE_ANYELEMENT = 33,
499 
510  eFROM_ANCESTORS = 34,
511  eFROM_ANCESTORS_OR_SELF = 35,
512  eFROM_ATTRIBUTES = 36,
513  eFROM_CHILDREN = 37,
514  eFROM_DESCENDANTS = 38,
515  eFROM_DESCENDANTS_OR_SELF = 39,
516  eFROM_FOLLOWING = 40,
517  eFROM_FOLLOWING_SIBLINGS = 41,
518  eFROM_PARENT = 42,
519  eFROM_PRECEDING = 43,
520  eFROM_PRECEDING_SIBLINGS = 44,
521  eFROM_SELF = 45,
522  eFROM_NAMESPACE = 46,
523  eFROM_ROOT = 47,
524 
533  eOP_MATCHPATTERN = 48,
534 
543  eOP_LOCATIONPATHPATTERN = 49,
544 
545  // For match patterns
546  eMATCH_ATTRIBUTE = 50,
547  eMATCH_ANY_ANCESTOR = 51,
548  eMATCH_IMMEDIATE_ANCESTOR = 52,
549  eMATCH_ANY_ANCESTOR_WITH_PREDICATE = 53,
550  eMATCH_ANY_ANCESTOR_WITH_FUNCTION_CALL = 54,
551 
561  eOP_PREDICATE_WITH_POSITION = 55,
562 
567  eOP_FUNCTION_POSITION = 56,
568  eOP_FUNCTION_LAST = 57,
569  eOP_FUNCTION_COUNT = 58,
570  eOP_FUNCTION_NOT = 59,
571  eOP_FUNCTION_TRUE = 60,
572  eOP_FUNCTION_FALSE = 61,
573  eOP_FUNCTION_BOOLEAN = 62,
574  eOP_FUNCTION_NAME_0 = 63,
575  eOP_FUNCTION_NAME_1 = 64,
576  eOP_FUNCTION_LOCALNAME_0 = 65,
577  eOP_FUNCTION_LOCALNAME_1 = 66,
578  eOP_FUNCTION_FLOOR = 67,
579  eOP_FUNCTION_CEILING = 68,
580  eOP_FUNCTION_ROUND = 69,
581  eOP_FUNCTION_NUMBER_0 = 70,
582  eOP_FUNCTION_NUMBER_1 = 71,
583  eOP_FUNCTION_STRING_0 = 72,
584  eOP_FUNCTION_STRING_1 = 73,
585  eOP_FUNCTION_STRINGLENGTH_0 = 74,
586  eOP_FUNCTION_STRINGLENGTH_1 = 75,
587  eOP_FUNCTION_NAMESPACEURI_0 = 76,
588  eOP_FUNCTION_NAMESPACEURI_1 = 77,
589  eOP_FUNCTION_SUM = 78,
590  eOP_FUNCTION_CONCAT = 79,
591 
592  // Always add _before_ this one and update
593  // s_opCodeLengthArray.
594  eOpCodeNextAvailable
595  }; // enum eOpCodes
596 
601  {
602  public:
603 
609  XPathExpressionException(const XalanDOMString& theMessage,
610  MemoryManagerType& theManager);
611 
612  virtual~
614  };
615 
620  {
621  public:
622 
628  InvalidOpCodeException(OpCodeMapValueType theOpCode,
629  XalanDOMString& theResult);
630 
631  virtual~
633 
634  private:
635 
636  static XalanDOMString&
637  FormatErrorMessage(OpCodeMapValueType theOpCode,
638  XalanDOMString& theResult);
639  };
640 
646  {
647  public:
648 
657  OpCodeMapValueType theOpCode,
658  OpCodeMapValueType theExpectedCount,
659  OpCodeMapValueType theSuppliedCount,
660  XalanDOMString& theResult);
661 
662  virtual~
664 
665  private:
666 
667  static XalanDOMString&
668  FormatErrorMessage(
669  OpCodeMapValueType theOpCode,
670  OpCodeMapValueType theExpectedCount,
671  OpCodeMapValueType theSuppliedCount,
672  XalanDOMString& theResult);
673  };
674 
679  {
680  public:
681 
689  OpCodeMapValueType theOpCode,
690  OpCodeMapValueType theValue,
691  XalanDOMString& theResult);
692 
693  virtual~
695 
696  private:
697 
698  static XalanDOMString&
699  FormatErrorMessage(
700  OpCodeMapValueType theOpCode,
701  OpCodeMapValueType theValue,
702  XalanDOMString& theResult);
703  };
704 
705 
712 #if defined(XALAN_INLINE_INITIALIZATION)
713  static const TokenQueueSizeType s_opCodeMapLengthIndex = 1;
714 #else
715  enum eDummy
716  {
717  s_opCodeMapLengthIndex = 1
718  };
719 #endif
720 
721  explicit
722  XPathExpression(MemoryManagerType& theManager);
723 
724  ~XPathExpression();
725 
728  {
729  return m_opMap.getMemoryManager();
730  }
734  void
735  reset();
736 
740  void
741  shrink();
742 
748  OpCodeMapSizeType
750  {
751  return OpCodeMapSizeType(m_opMap.size());
752  }
753 
765  OpCodeMapValueType
767  {
768  const OpCodeMapSizeType theSize = opCodeMapSize();
769 
770  if (theSize > s_opCodeMapLengthIndex)
771  {
772  assert(theSize == OpCodeMapSizeType(m_opMap[s_opCodeMapLengthIndex]));
773 
774  return m_opMap[s_opCodeMapLengthIndex];
775  }
776  else
777  {
778  assert(theSize == OpCodeMapValueType(theSize));
779 
780  return OpCodeMapValueType(theSize);
781  }
782  }
783 
784  OpCodeMapPositionType
786  {
787 #if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS)
788  return m_opMap.begin();
789 #else
790  return 0;
791 #endif
792  }
793 
794  bool
795  isValidOpCodePosition(OpCodeMapPositionType opPos) const
796  {
797  const OpCodeMapDifferenceType theDifference =
798  OpCodeMapDifferenceType(opPos - getInitialOpCodePosition());
799 
800  return theDifference >= 0 &&
801  theDifference < opCodeMapSize();
802  }
803 
804 #if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS)
805  bool
806  isValidOpCodePosition(OpCodeMapSizeType theIndex) const
807  {
808  return theIndex >= 0 && theIndex < opCodeMapSize();
809  }
810 
818  OpCodeMapValueType
819  getOpCodeMapValue(OpCodeMapSizeType theIndex) const
820  {
821  assert(theIndex < opCodeMapLength());
822 
823  return m_opMap[theIndex];
824  }
825 #endif
826 
834  OpCodeMapValueType
835  getOpCodeMapValue(OpCodeMapPositionType opPos) const
836  {
837  assert(opPos < getInitialOpCodePosition() + opCodeMapLength());
838 
839 #if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS)
840  return *opPos;
841 #else
842 
843  return m_opMap[opPos];
844 #endif
845  }
846 
854  void
856  OpCodeMapSizeType theOpCodeMapIndex,
857  const OpCodeMapValueType& theValue)
858  {
859  assert(theOpCodeMapIndex < opCodeMapLength());
860 
861  m_opMap[theOpCodeMapIndex] = theValue;
862  }
863 
864  OpCodeMapValueType
865  getOpCodeArgumentLength(OpCodeMapPositionType opPos) const
866  {
867  return getOpCodeMapValue(opPos + XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
868  }
869 
877  OpCodeMapValueType
878  getOpCodeLengthFromOpMap(OpCodeMapPositionType opPos,
879  MemoryManagerType& theManager) const;
880 
881 #if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS)
882 
889  OpCodeMapValueType
890  getOpCodeLengthFromOpMap(OpCodeMapSizeType theIndex,
891  MemoryManagerType& theManager) const;
892 #endif
893 
894 #if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS)
895 
902  OpCodeMapPositionType
903  getNextOpCodePosition(OpCodeMapPositionType opPos) const
904  {
905  assert(opPos < getInitialOpCodePosition() + opCodeMapLength());
906 
907  return opPos + *(opPos + s_opCodeMapLengthIndex);
908  }
909 #endif
910 
918  OpCodeMapSizeType
919 #if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS)
920  getNextOpCodePosition(OpCodeMapSizeType theIndex) const
921 #else
922  getNextOpCodePosition(OpCodeMapPositionType theIndex) const
923 #endif
924  {
925  assert(theIndex < opCodeMapLength());
926 
927  assert(theIndex + m_opMap[theIndex + s_opCodeMapLengthIndex] ==
928  OpCodeMapSizeType(theIndex + m_opMap[theIndex + s_opCodeMapLengthIndex]));
929 
930  return OpCodeMapSizeType(theIndex + m_opMap[theIndex + s_opCodeMapLengthIndex]);
931  }
932 
942  void
943  setOpCodeArgs(
944  eOpCodes theOpCode,
945  OpCodeMapSizeType theIndex,
946  const OpCodeMapValueVectorType& theArgs);
947 
954  OpCodeMapSizeType
955  appendOpCode(eOpCodes theOpCode);
956 
963  OpCodeMapSizeType
965  eOpCodes theOpCode,
966  const OpCodeMapValueVectorType& theArgs)
967  {
968  const OpCodeMapSizeType thePosition = appendOpCode(theOpCode);
969 
970  setOpCodeArgs(theOpCode,
971  thePosition,
972  theArgs);
973 
974  return thePosition;
975  }
976 
984  void
985  replaceOpCode(
986  OpCodeMapSizeType theIndex,
987  eOpCodes theOldOpCode,
988  eOpCodes theNewOpCode);
989 
996  OpCodeMapValueType
997  insertOpCode(
998  eOpCodes theOpCode,
999  OpCodeMapSizeType theIndex);
1000 
1010  void
1011  updateOpCodeLength(OpCodeMapSizeType theIndex)
1012  {
1013  assert(theIndex < opCodeMapSize());
1014 
1015  updateOpCodeLength(m_opMap[theIndex], theIndex);
1016  }
1017 
1026  void
1027  updateShiftedOpCodeLength(
1028  OpCodeMapValueType theOpCode,
1029  OpCodeMapSizeType theOriginalIndex,
1030  OpCodeMapSizeType theNewIndex);
1031 
1042  void
1043  updateOpCodeLength(
1044  OpCodeMapValueType theOpCode,
1045  OpCodeMapSizeType theIndex);
1046 
1054  static bool
1055  isNodeTestOpCode(OpCodeMapValueType theOpCode);
1056 
1062  void
1063  updateOpCodeLengthAfterNodeTest(OpCodeMapSizeType theIndex);
1064 
1070  bool
1072  {
1073  return tokenQueueSize() > m_currentPosition ? true : false;
1074  }
1075 
1081  TokenQueueSizeType
1083  {
1084  return TokenQueueSizeType(m_tokenQueue.size());
1085  }
1086 
1087  bool
1088  isValidTokenQueuePosition(TokenQueueSizeType thePosition) const
1089  {
1090  return thePosition < tokenQueueSize();
1091  }
1092 
1098  TokenQueueSizeType
1100  {
1101  return m_currentPosition;
1102  }
1103 
1107  void
1109  {
1110  m_currentPosition = 0;
1111  }
1112 
1119  const XToken*
1120  getToken(TokenQueuePositionType thePosition) const
1121  {
1122  assert(thePosition < tokenQueueSize());
1123 
1124  return &m_tokenQueue[thePosition];
1125  }
1126 
1132  const XToken*
1134  {
1135  if (hasMoreTokens() == true)
1136  {
1137  return getToken(m_currentPosition++);
1138  }
1139  else
1140  {
1141  return 0;
1142  }
1143  }
1144 
1150  const XToken*
1152  {
1153  if (m_currentPosition > 0)
1154  {
1155  return getToken(--m_currentPosition);
1156  }
1157  else
1158  {
1159  return 0;
1160  }
1161  }
1162 
1164  {
1166  eRelativeForward
1167  };
1168 
1177  const XToken*
1179  TokenQueuePositionType theOffset,
1180  eRelativeDirection theDirection) const
1181  {
1182  const TokenQueuePositionType thePosition =
1183  calculateRelativePosition(theOffset, theDirection);
1184 
1185  if (thePosition == tokenQueueSize())
1186  {
1187  return 0;
1188  }
1189  else
1190  {
1191  return getToken(thePosition);
1192  }
1193  }
1194 
1200  void
1201  pushToken(const XalanDOMString& theToken)
1202  {
1203  m_tokenQueue.push_back(XToken(theToken, getMemoryManager()));
1204  }
1205 
1212  void
1214  double theNumber,
1215  const XalanDOMString& theString)
1216  {
1217  m_tokenQueue.push_back(XToken(theNumber, theString));
1218  }
1219 
1226  void
1227  insertToken(const XalanDOMString& theToken)
1228  {
1229  m_tokenQueue.insert(m_tokenQueue.begin() + (m_currentPosition - 1), XToken(theToken, getMemoryManager()));
1230  }
1231 
1239  void
1241  double theNumber,
1242  const XalanDOMString& theString)
1243  {
1244  m_tokenQueue.insert(m_tokenQueue.begin() + (m_currentPosition - 1), XToken(theNumber, theString));
1245  }
1246 
1253  void
1255  TokenQueuePositionType theOffset,
1256  eRelativeDirection theDirection,
1257  const XalanDOMString& theString)
1258  {
1259  const TokenQueuePositionType thePosition =
1260  calculateRelativePosition(theOffset, theDirection);
1261  assert(thePosition < tokenQueueSize());
1262 
1263  m_tokenQueue[thePosition].set(theString, getMemoryManager());
1264  }
1265 
1272  void
1273  dumpOpCodeMap(
1274  PrintWriter& thePrintWriter,
1275  OpCodeMapSizeType theStartPosition = 0) const;
1276 
1283  void
1284  dumpOpCodeMap(
1285  OstreamType& theStream,
1286  OpCodeMapSizeType theStartPosition = 0) const;
1287 
1294  void
1295  dumpTokenQueue(
1296  PrintWriter& thePrintWriter,
1297  TokenQueueSizeType theStartPosition = 0) const;
1298 
1305  void
1306  dumpTokenQueue(
1307  OstreamType& theStream,
1308  TokenQueueSizeType theStartPosition = 0) const;
1309 
1315  void
1316  dumpRemainingTokenQueue(PrintWriter& thePrintWriter) const;
1317 
1324  void
1325  dumpRemainingTokenQueue(
1326  OstreamType& theStream,
1327  MemoryManager& theMemoryManager) const;
1328 
1335  void
1337  {
1338  // Push the index onto the op map.
1339  m_opMap.push_back(theValue);
1340 
1341  // Update the op map length.
1342  ++m_opMap[s_opCodeMapLengthIndex];
1343  }
1344 
1351  void
1352  pushArgumentOnOpCodeMap(const XToken& theXToken);
1353 
1360  void
1361  pushArgumentOnOpCodeMap(const XalanDOMString& theString);
1362 
1370  void
1371  pushArgumentOnOpCodeMap(
1372  double theNumber,
1373  const XalanDOMString& theString);
1374 
1381  void
1382  pushNumberLiteralOnOpCodeMap(double theNumber);
1383 
1389  double
1390  getNumberLiteral(int theIndex) const
1391  {
1392  assert(theIndex >= 0 &&
1393  NumberLiteralValueVectorType::size_type(theIndex) < m_numberLiteralValues.size());
1394 
1395  return m_numberLiteralValues[NumberLiteralValueVectorType::size_type(theIndex)];
1396  }
1397 
1402  void
1403  pushCurrentTokenOnOpCodeMap();
1404 
1410  void
1412  {
1413  m_currentPattern = &thePattern;
1414  }
1415 
1421  const XalanDOMString&
1423  {
1424  assert(m_currentPattern != 0);
1425 
1426  return *m_currentPattern;
1427  }
1428 
1429 private:
1430 
1440  TokenQueuePositionType
1441  calculateRelativePosition(
1442  TokenQueuePositionType theOffset,
1443  eRelativeDirection theDirection) const
1444  {
1445  if (theDirection == eRelativeBackward &&
1446  theOffset <= m_currentPosition)
1447  {
1448  return m_currentPosition - theOffset;
1449  }
1450  else if (theDirection == eRelativeForward &&
1451  m_currentPosition + theOffset < tokenQueueSize())
1452  {
1453  return m_currentPosition + theOffset;
1454  }
1455  else
1456  {
1457  return tokenQueueSize();
1458  }
1459  }
1460 
1467  OpCodeMapType m_opMap;
1468 
1473  OpCodeMapSizeType m_lastOpCodeIndex;
1474 
1480  TokenQueueType m_tokenQueue;
1481 
1485  TokenQueueSizeType m_currentPosition;
1486 
1490  const XalanDOMString* m_currentPattern;
1491 
1492  // Default vector allocation sizes.
1493  enum
1494  {
1495  eDefaultOpMapSize = 100,
1496  eDefaultTokenQueueSize = 30
1497  };
1498 
1499  NumberLiteralValueVectorType m_numberLiteralValues;
1500 };
1501 
1502 
1503 
1504 XALAN_CPP_NAMESPACE_END
1505 
1506 
1507 
1508 #endif // XPATHEXPRESSION_HEADER_GUARD_1357924680

Interpreting class diagrams

Doxygen and GraphViz are used to generate this API documentation from the Xalan-C header files.

dot

Xalan-C++ XSLT Processor Version 1.10
Copyright © 1999-2004 The Apache Software Foundation. All Rights Reserved.

Apache Logo