PageRenderTime 27ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/ATF2/control-software/epics-3.14.8/extensions/src/ChannelArchiver/ThirdParty/xerces-c-src2_4_0/src/xercesc/validators/schema/identity/XercesXPath.cpp

http://atf2flightsim.googlecode.com/
C++ | 1490 lines | 993 code | 224 blank | 273 comment | 300 complexity | 10cc27c5922052677c647dcb1dba478b MD5 | raw file
Possible License(s): BSD-2-Clause, LGPL-2.0, IPL-1.0, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. * Copyright (c) 2001 The Apache Software Foundation. All rights
  5. * reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. *
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in
  16. * the documentation and/or other materials provided with the
  17. * distribution.
  18. *
  19. * 3. The end-user documentation included with the redistribution,
  20. * if any, must include the following acknowledgment:
  21. * "This product includes software developed by the
  22. * Apache Software Foundation (http://www.apache.org/)."
  23. * Alternately, this acknowledgment may appear in the software itself,
  24. * if and wherever such third-party acknowledgments normally appear.
  25. *
  26. * 4. The names "Xerces" and "Apache Software Foundation" must
  27. * not be used to endorse or promote products derived from this
  28. * software without prior written permission. For written
  29. * permission, please contact apache\@apache.org.
  30. *
  31. * 5. Products derived from this software may not be called "Apache",
  32. * nor may "Apache" appear in their name, without prior written
  33. * permission of the Apache Software Foundation.
  34. *
  35. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46. * SUCH DAMAGE.
  47. * ====================================================================
  48. *
  49. * This software consists of voluntary contributions made by many
  50. * individuals on behalf of the Apache Software Foundation, and was
  51. * originally based on software copyright (c) 1999, International
  52. * Business Machines, Inc., http://www.ibm.com . For more information
  53. * on the Apache Software Foundation, please see
  54. * <http://www.apache.org/>.
  55. */
  56. /*
  57. * $Log: XercesXPath.cpp,v $
  58. * Revision 1.1.1.1 2009/03/14 06:43:14 whitegr
  59. * epics channel archiver
  60. *
  61. * Revision 1.11 2003/10/17 21:18:04 peiyongz
  62. * using XTemplateSerializer
  63. *
  64. * Revision 1.10 2003/10/14 15:24:23 peiyongz
  65. * Implementation of Serialization/Deserialization
  66. *
  67. * Revision 1.9 2003/10/01 16:32:42 neilg
  68. * improve handling of out of memory conditions, bug #23415. Thanks to David Cargill.
  69. *
  70. * Revision 1.8 2003/05/18 14:02:09 knoaman
  71. * Memory manager implementation: pass per instance manager.
  72. *
  73. * Revision 1.7 2003/05/16 21:43:22 knoaman
  74. * Memory manager implementation: Modify constructors to pass in the memory manager.
  75. *
  76. * Revision 1.6 2003/05/15 18:59:34 knoaman
  77. * Partial implementation of the configurable memory manager.
  78. *
  79. * Revision 1.5 2002/12/20 22:10:48 tng
  80. * XML 1.1
  81. *
  82. * Revision 1.4 2002/12/04 18:21:23 knoaman
  83. * Identity constraint fix.
  84. *
  85. * Revision 1.3 2002/11/04 14:47:42 tng
  86. * C++ Namespace Support.
  87. *
  88. * Revision 1.2 2002/10/30 21:52:01 tng
  89. * [Bug 13641] compiler-generated copy-constructor for QName doesn't do the right thing.
  90. *
  91. * Revision 1.1.1.1 2002/02/01 22:22:51 peiyongz
  92. * sane_include
  93. *
  94. * Revision 1.3 2001/11/15 17:10:19 knoaman
  95. * Particle derivation checking support.
  96. *
  97. * Revision 1.2 2001/11/07 14:25:36 knoaman
  98. * Fix compliation error on Unix.
  99. *
  100. * Revision 1.1 2001/11/02 14:08:40 knoaman
  101. * Add support for identity constraints.
  102. *
  103. */
  104. // ---------------------------------------------------------------------------
  105. // Includes
  106. // ---------------------------------------------------------------------------
  107. #include <xercesc/validators/schema/identity/XercesXPath.hpp>
  108. #include <xercesc/validators/schema/identity/XPathSymbols.hpp>
  109. #include <xercesc/validators/schema/identity/XPathException.hpp>
  110. #include <xercesc/validators/schema/NamespaceScope.hpp>
  111. #include <xercesc/util/StringPool.hpp>
  112. #include <xercesc/util/Janitor.hpp>
  113. #include <xercesc/framework/XMLBuffer.hpp>
  114. #include <xercesc/internal/XMLReader.hpp>
  115. #include <xercesc/util/RuntimeException.hpp>
  116. #include <xercesc/util/OutOfMemoryException.hpp>
  117. #include <xercesc/internal/XTemplateSerializer.hpp>
  118. XERCES_CPP_NAMESPACE_BEGIN
  119. // ---------------------------------------------------------------------------
  120. // Static data
  121. // ---------------------------------------------------------------------------
  122. const XMLByte XPathScanner::fASCIICharMap[128] =
  123. {
  124. 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 2, 0, 0,
  125. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  126. 2, 3, 4, 1, 5, 1, 1, 4, 6, 7, 8, 9, 10, 11, 12, 13,
  127. 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 1, 16, 17, 18, 1,
  128. 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
  129. 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 1, 22, 1, 23,
  130. 1, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
  131. 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 1, 24, 1, 1, 1
  132. };
  133. // ---------------------------------------------------------------------------
  134. // XercesNodeTest: Constructors and Destructor
  135. // ---------------------------------------------------------------------------
  136. XercesNodeTest::XercesNodeTest(const short aType,
  137. MemoryManager* const manager)
  138. : fType(aType)
  139. , fName(new (manager) QName(manager))
  140. {
  141. }
  142. XercesNodeTest::XercesNodeTest(const QName* const qName)
  143. : fType(QNAME)
  144. , fName(new (qName->getMemoryManager()) QName(*qName))
  145. {
  146. }
  147. XercesNodeTest::XercesNodeTest(const XMLCh* const prefix,
  148. const unsigned int uriId,
  149. MemoryManager* const manager)
  150. : fType(NAMESPACE)
  151. , fName(new (manager) QName(manager))
  152. {
  153. fName->setURI(uriId);
  154. fName->setPrefix(prefix);
  155. }
  156. XercesNodeTest::XercesNodeTest(const XercesNodeTest& other)
  157. : fType(other.fType)
  158. , fName(new ((other.fName)->getMemoryManager())QName(*other.fName))
  159. {
  160. }
  161. /***
  162. * Support for Serialization/De-serialization
  163. ***/
  164. IMPL_XSERIALIZABLE_TOCREATE(XercesNodeTest)
  165. void XercesNodeTest::serialize(XSerializeEngine& serEng)
  166. {
  167. if (serEng.isStoring())
  168. {
  169. serEng<<fType;
  170. serEng<<fName;
  171. }
  172. else
  173. {
  174. serEng>>fType;
  175. serEng>>fName;
  176. }
  177. }
  178. XercesNodeTest::XercesNodeTest(MemoryManager* const manager)
  179. :fType(UNKNOWN)
  180. ,fName(0)
  181. {
  182. }
  183. // ---------------------------------------------------------------------------
  184. // XercesNodeTest: Operators
  185. // ---------------------------------------------------------------------------
  186. XercesNodeTest& XercesNodeTest::operator=(const XercesNodeTest& other)
  187. {
  188. if (this == &other)
  189. return *this;
  190. fType = other.fType;
  191. fName->setValues(*(other.fName));
  192. return *this;
  193. }
  194. bool XercesNodeTest::operator ==(const XercesNodeTest& other) const {
  195. if (this == &other)
  196. return true;
  197. if (fType != other.fType)
  198. return false;
  199. return (*fName == *(other.fName));
  200. }
  201. bool XercesNodeTest::operator !=(const XercesNodeTest& other) const {
  202. return !operator==(other);
  203. }
  204. // ---------------------------------------------------------------------------
  205. // XercesStep: Constructors and Destructor
  206. // ---------------------------------------------------------------------------
  207. XercesStep::XercesStep(const unsigned short axisType, XercesNodeTest* const nodeTest)
  208. : fAxisType(axisType)
  209. , fNodeTest(nodeTest)
  210. {
  211. }
  212. XercesStep::XercesStep(const XercesStep& other)
  213. : fAxisType(other.fAxisType)
  214. , fNodeTest(0)
  215. {
  216. fNodeTest = new (other.fNodeTest->getName()->getMemoryManager()) XercesNodeTest(*(other.fNodeTest));
  217. }
  218. // ---------------------------------------------------------------------------
  219. // XercesStep: Operators
  220. // ---------------------------------------------------------------------------
  221. XercesStep& XercesStep::operator=(const XercesStep& other)
  222. {
  223. if (this == &other)
  224. return *this;
  225. fAxisType = other.fAxisType;
  226. *fNodeTest = *(other.fNodeTest);
  227. return *this;
  228. }
  229. bool XercesStep::operator==(const XercesStep& other) const {
  230. if (this == &other)
  231. return true;
  232. if (fAxisType != other.fAxisType)
  233. return false;
  234. if (fAxisType == XercesStep::CHILD ||
  235. fAxisType == XercesStep::ATTRIBUTE) {
  236. return (*fNodeTest == *(other.fNodeTest));
  237. }
  238. return true;
  239. }
  240. bool XercesStep::operator!=(const XercesStep& other) const {
  241. return !operator==(other);
  242. }
  243. /***
  244. * Support for Serialization/De-serialization
  245. ***/
  246. IMPL_XSERIALIZABLE_TOCREATE(XercesStep)
  247. void XercesStep::serialize(XSerializeEngine& serEng)
  248. {
  249. if (serEng.isStoring())
  250. {
  251. serEng<<fAxisType;
  252. serEng<<fNodeTest;
  253. }
  254. else
  255. {
  256. serEng>>fAxisType;
  257. serEng>>fNodeTest;
  258. }
  259. }
  260. XercesStep::XercesStep(MemoryManager* const manager)
  261. :fAxisType(UNKNOWN)
  262. ,fNodeTest(0)
  263. {
  264. }
  265. // ---------------------------------------------------------------------------
  266. // XercesLocationPath: Constructors and Destructor
  267. // ---------------------------------------------------------------------------
  268. XercesLocationPath::XercesLocationPath(RefVectorOf<XercesStep>* const steps)
  269. : fSteps(steps)
  270. {
  271. }
  272. // ---------------------------------------------------------------------------
  273. // XercesLocationPath: Operators
  274. // ---------------------------------------------------------------------------
  275. bool XercesLocationPath::operator==(const XercesLocationPath& other) const {
  276. unsigned int stepsSize = fSteps->size();
  277. if (stepsSize != other.fSteps->size())
  278. return false;
  279. for (unsigned int i=0; i < stepsSize; i++) {
  280. if (*(fSteps->elementAt(i)) != *(other.fSteps->elementAt(i)))
  281. return false;
  282. }
  283. return true;
  284. }
  285. bool XercesLocationPath::operator!=(const XercesLocationPath& other) const {
  286. return !operator==(other);
  287. }
  288. /***
  289. * Support for Serialization/De-serialization
  290. ***/
  291. IMPL_XSERIALIZABLE_TOCREATE(XercesLocationPath)
  292. void XercesLocationPath::serialize(XSerializeEngine& serEng)
  293. {
  294. if (serEng.isStoring())
  295. {
  296. /***
  297. * Serialize RefVectorOf<XercesStep>* fSteps;
  298. ***/
  299. XTemplateSerializer::storeObject(fSteps, serEng);
  300. }
  301. else
  302. {
  303. /***
  304. * Deserialize RefVectorOf<XercesStep>* fSteps;
  305. ***/
  306. XTemplateSerializer::loadObject(&fSteps, 8, true, serEng);
  307. }
  308. }
  309. XercesLocationPath::XercesLocationPath(MemoryManager* const manager)
  310. :fSteps(0)
  311. {
  312. }
  313. // ---------------------------------------------------------------------------
  314. // XercesPath: Constructors and Destructor
  315. // ---------------------------------------------------------------------------
  316. XercesXPath::XercesXPath(const XMLCh* const xpathExpr,
  317. XMLStringPool* const stringPool,
  318. NamespaceScope* const scopeContext,
  319. const unsigned int emptyNamespaceId,
  320. const bool isSelector,
  321. MemoryManager* const manager)
  322. : fEmptyNamespaceId(emptyNamespaceId)
  323. , fExpression(0)
  324. , fLocationPaths(0)
  325. , fMemoryManager(manager)
  326. {
  327. try
  328. {
  329. fExpression = XMLString::replicate(xpathExpr, fMemoryManager);
  330. parseExpression(stringPool, scopeContext);
  331. if (isSelector) {
  332. checkForSelectedAttributes();
  333. }
  334. }
  335. catch(const OutOfMemoryException&)
  336. {
  337. throw;
  338. }
  339. catch(...) {
  340. cleanUp();
  341. throw;
  342. }
  343. }
  344. XercesXPath::~XercesXPath() {
  345. cleanUp();
  346. }
  347. // ---------------------------------------------------------------------------
  348. // XercesXPath: Operators
  349. // ---------------------------------------------------------------------------
  350. bool XercesXPath::operator==(const XercesXPath& other) const {
  351. unsigned int locPathSize = fLocationPaths->size();
  352. if (locPathSize != other.fLocationPaths->size())
  353. return false;
  354. for (unsigned int i=0; i < locPathSize; i++) {
  355. if (*(fLocationPaths->elementAt(i)) != *(other.fLocationPaths->elementAt(i)))
  356. return false;
  357. }
  358. return true;
  359. }
  360. bool XercesXPath::operator!=(const XercesXPath& other) const {
  361. return !operator==(other);
  362. }
  363. // ---------------------------------------------------------------------------
  364. // XercesPath: Helper methods
  365. // ---------------------------------------------------------------------------
  366. void XercesXPath::cleanUp() {
  367. fMemoryManager->deallocate(fExpression);//delete [] fExpression;
  368. delete fLocationPaths;
  369. }
  370. void XercesXPath::checkForSelectedAttributes() {
  371. // verify that an attribute is not selected
  372. unsigned int locSize = (fLocationPaths) ? fLocationPaths->size() : 0;
  373. for (unsigned int i = 0; i < locSize; i++) {
  374. XercesLocationPath* locPath = fLocationPaths->elementAt(i);
  375. unsigned int stepSize = locPath->getStepSize();
  376. if (stepSize) {
  377. if (locPath->getStep(stepSize - 1)->getAxisType() == XercesStep::ATTRIBUTE) {
  378. ThrowXML(XPathException, XMLExcepts::XPath_NoAttrSelector);
  379. }
  380. }
  381. }
  382. }
  383. void XercesXPath::parseExpression(XMLStringPool* const stringPool,
  384. NamespaceScope* const scopeContext) {
  385. unsigned int length = XMLString::stringLen(fExpression);
  386. if (!length) {
  387. return;
  388. }
  389. ValueVectorOf<int> tokens(16, fMemoryManager);
  390. XPathScannerForSchema scanner(stringPool);
  391. bool success = scanner.scanExpression(fExpression, 0, length, &tokens);
  392. bool firstTokenOfLocationPath=true;
  393. unsigned int tokenCount = tokens.size();
  394. RefVectorOf<XercesStep>* stepsVector = new (fMemoryManager) RefVectorOf<XercesStep>(16, true, fMemoryManager);
  395. Janitor<RefVectorOf<XercesStep> > janSteps(stepsVector);
  396. if (tokenCount) {
  397. fLocationPaths = new (fMemoryManager) RefVectorOf<XercesLocationPath>(8, true, fMemoryManager);
  398. }
  399. for (unsigned int i = 0; i < tokenCount; i++) {
  400. int aToken = tokens.elementAt(i);
  401. bool isNamespace=false;
  402. switch (aToken) {
  403. case XercesXPath::EXPRTOKEN_OPERATOR_UNION:
  404. {
  405. if (i == 0) {
  406. ThrowXML(XPathException, XMLExcepts::XPath_NoUnionAtStart);
  407. }
  408. int stepsSize = stepsVector->size();
  409. if (stepsSize == 0) {
  410. ThrowXML(XPathException, XMLExcepts::XPath_NoMultipleUnion);
  411. }
  412. fLocationPaths->addElement(new (fMemoryManager) XercesLocationPath(stepsVector));
  413. janSteps.orphan();
  414. stepsVector = new (fMemoryManager) RefVectorOf<XercesStep>(16, true, fMemoryManager);
  415. janSteps.reset(stepsVector);
  416. firstTokenOfLocationPath = true;
  417. }
  418. break;
  419. case XercesXPath::EXPRTOKEN_AXISNAME_ATTRIBUTE:
  420. {
  421. // consume "::" token and drop through
  422. i++;
  423. }
  424. case XercesXPath::EXPRTOKEN_ATSIGN:
  425. {
  426. // consume QName token
  427. if (i == tokenCount - 1) {
  428. ThrowXML(XPathException, XMLExcepts::XPath_MissingAttr);
  429. }
  430. aToken = tokens.elementAt(++i);
  431. if (aToken != XercesXPath::EXPRTOKEN_NAMETEST_QNAME
  432. && aToken!= XercesXPath::EXPRTOKEN_NAMETEST_ANY
  433. && aToken!= XercesXPath::EXPRTOKEN_NAMETEST_NAMESPACE) {
  434. ThrowXML(XPathException, XMLExcepts::XPath_ExpectedToken1);
  435. }
  436. bool isNamespaceAtt=false;
  437. switch (aToken) {
  438. case XercesXPath::EXPRTOKEN_NAMETEST_ANY:
  439. {
  440. XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(XercesNodeTest::WILDCARD, fMemoryManager);
  441. XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::ATTRIBUTE, nodeTest);
  442. stepsVector->addElement(step);
  443. break;
  444. }
  445. case XercesXPath::EXPRTOKEN_NAMETEST_NAMESPACE:
  446. {
  447. isNamespaceAtt = true;
  448. }
  449. case XercesXPath::EXPRTOKEN_NAMETEST_QNAME:
  450. {
  451. aToken = tokens.elementAt(++i);
  452. const XMLCh* prefix = XMLUni::fgZeroLenString;
  453. unsigned int uri = fEmptyNamespaceId;
  454. if (scopeContext && aToken != -1) {
  455. prefix = stringPool->getValueForId(aToken);
  456. uri = scopeContext->getNamespaceForPrefix(prefix);
  457. }
  458. if (aToken != -1 && scopeContext && uri == fEmptyNamespaceId) {
  459. ThrowXML1(XPathException, XMLExcepts::XPath_PrefixNoURI, prefix);
  460. }
  461. if (isNamespaceAtt) {
  462. // build step
  463. XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(prefix, uri, fMemoryManager);
  464. XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::ATTRIBUTE, nodeTest);
  465. stepsVector->addElement(step);
  466. break;
  467. }
  468. aToken = tokens.elementAt(++i);
  469. const XMLCh* localPart = stringPool->getValueForId(aToken);
  470. QName aQName(prefix, localPart, uri, fMemoryManager);
  471. // build step
  472. XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(&aQName);
  473. XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::ATTRIBUTE, nodeTest);
  474. stepsVector->addElement(step);
  475. break;
  476. }
  477. }
  478. firstTokenOfLocationPath=false;
  479. break;
  480. }
  481. case XercesXPath::EXPRTOKEN_DOUBLE_COLON:
  482. {
  483. // should never have a bare double colon
  484. ThrowXML(XPathException, XMLExcepts::XPath_NoDoubleColon);
  485. }
  486. case XercesXPath::EXPRTOKEN_AXISNAME_CHILD:
  487. {
  488. // consume "::" token and drop through
  489. i++;
  490. if (i == tokenCount - 1) {
  491. ThrowXML(XPathException, XMLExcepts::XPath_ExpectedStep1);
  492. }
  493. firstTokenOfLocationPath=false;
  494. break;
  495. }
  496. case XercesXPath::EXPRTOKEN_NAMETEST_ANY:
  497. {
  498. XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(XercesNodeTest::WILDCARD, fMemoryManager);
  499. XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::CHILD, nodeTest);
  500. stepsVector->addElement(step);
  501. firstTokenOfLocationPath = false;
  502. break;
  503. }
  504. case XercesXPath::EXPRTOKEN_NAMETEST_NAMESPACE:
  505. {
  506. isNamespace=true;
  507. }
  508. case XercesXPath::EXPRTOKEN_NAMETEST_QNAME:
  509. {
  510. // consume QName token
  511. aToken = tokens.elementAt(++i);
  512. const XMLCh* prefix = XMLUni::fgZeroLenString;
  513. unsigned int uri = fEmptyNamespaceId;
  514. if (scopeContext && aToken != -1) {
  515. prefix = stringPool->getValueForId(aToken);
  516. uri = scopeContext->getNamespaceForPrefix(prefix);
  517. }
  518. if (aToken != -1 && scopeContext && uri == fEmptyNamespaceId) {
  519. ThrowXML1(XPathException, XMLExcepts::XPath_PrefixNoURI, prefix);
  520. }
  521. if (isNamespace) {
  522. // build step
  523. XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(prefix, uri, fMemoryManager);
  524. XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::CHILD, nodeTest);
  525. stepsVector->addElement(step);
  526. break;
  527. }
  528. aToken = tokens.elementAt(++i);
  529. const XMLCh* localPart = stringPool->getValueForId(aToken);
  530. QName aQName(prefix, localPart, uri, fMemoryManager);
  531. // build step
  532. XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(&aQName);
  533. XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::CHILD, nodeTest);
  534. stepsVector->addElement(step);
  535. firstTokenOfLocationPath = false;
  536. break;
  537. }
  538. case XercesXPath::EXPRTOKEN_PERIOD:
  539. {
  540. // build step
  541. XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(XercesNodeTest::NODE, fMemoryManager);
  542. XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::SELF, nodeTest);
  543. stepsVector->addElement(step);
  544. if (firstTokenOfLocationPath && i+1 < tokenCount) {
  545. aToken = tokens.elementAt(i+1);
  546. if (aToken == XercesXPath::EXPRTOKEN_OPERATOR_DOUBLE_SLASH){
  547. if (++i == tokenCount - 1) {
  548. ThrowXML(XPathException, XMLExcepts::XPath_ExpectedStep2);
  549. }
  550. if (i+1 < tokenCount) {
  551. aToken = tokens.elementAt(i+1);
  552. if (aToken == XercesXPath::EXPRTOKEN_OPERATOR_SLASH) {
  553. ThrowXML(XPathException, XMLExcepts::XPath_NoForwardSlash);
  554. }
  555. }
  556. // build step
  557. nodeTest = new (fMemoryManager) XercesNodeTest(XercesNodeTest::NODE, fMemoryManager);
  558. step = new (fMemoryManager) XercesStep(XercesStep::DESCENDANT, nodeTest);
  559. stepsVector->addElement(step);
  560. }
  561. }
  562. firstTokenOfLocationPath=false;
  563. break;
  564. }
  565. case XercesXPath::EXPRTOKEN_OPERATOR_DOUBLE_SLASH:
  566. {
  567. ThrowXML(XPathException, XMLExcepts::XPath_NoDoubleForwardSlash);
  568. }
  569. case XercesXPath::EXPRTOKEN_OPERATOR_SLASH:
  570. {
  571. if (i == 0) {
  572. ThrowXML(XPathException, XMLExcepts::XPath_NoForwardSlashAtStart);
  573. }
  574. // keep on truckin'
  575. if (firstTokenOfLocationPath) {
  576. ThrowXML(XPathException, XMLExcepts::XPath_NoSelectionOfRoot);
  577. }
  578. if (i == tokenCount - 1) {
  579. ThrowXML(XPathException, XMLExcepts::XPath_ExpectedStep3);
  580. }
  581. firstTokenOfLocationPath=false;
  582. break;
  583. }
  584. default:
  585. firstTokenOfLocationPath=false;
  586. }
  587. }
  588. int stepsSize = stepsVector->size();
  589. if (stepsSize == 0) {
  590. if (!fLocationPaths || fLocationPaths->size() == 0) {
  591. ThrowXML(XPathException, XMLExcepts::XPath_EmptyExpr);
  592. }
  593. else {
  594. ThrowXML(XPathException, XMLExcepts::XPath_NoUnionAtEnd);
  595. }
  596. }
  597. fLocationPaths->addElement(new (fMemoryManager) XercesLocationPath(stepsVector));
  598. janSteps.orphan();
  599. }
  600. /***
  601. * Support for Serialization/De-serialization
  602. ***/
  603. IMPL_XSERIALIZABLE_TOCREATE(XercesXPath)
  604. void XercesXPath::serialize(XSerializeEngine& serEng)
  605. {
  606. if (serEng.isStoring())
  607. {
  608. serEng<<fEmptyNamespaceId;
  609. serEng.writeString(fExpression);
  610. /***
  611. * Serialize RefVectorOf<XercesLocationPath>* fLocationPaths;
  612. ***/
  613. XTemplateSerializer::storeObject(fLocationPaths, serEng);
  614. }
  615. else
  616. {
  617. serEng>>fEmptyNamespaceId;
  618. serEng.readString(fExpression);
  619. /***
  620. * Deserialize RefVectorOf<XercesLocationPath>* fLocationPaths;
  621. ***/
  622. XTemplateSerializer::loadObject(&fLocationPaths, 8, true, serEng);
  623. }
  624. }
  625. XercesXPath::XercesXPath(MemoryManager* const manager)
  626. :fEmptyNamespaceId(0)
  627. ,fExpression(0)
  628. ,fLocationPaths(0)
  629. ,fMemoryManager(manager)
  630. {
  631. }
  632. // ---------------------------------------------------------------------------
  633. // XPathScanner: Constructors and Destructor
  634. // ---------------------------------------------------------------------------
  635. XPathScanner::XPathScanner(XMLStringPool* const stringPool)
  636. : fAndSymbol (0)
  637. , fOrSymbol(0)
  638. , fModSymbol(0)
  639. , fDivSymbol(0)
  640. , fCommentSymbol(0)
  641. , fTextSymbol(0)
  642. , fPISymbol(0)
  643. , fNodeSymbol(0)
  644. , fAncestorSymbol(0)
  645. , fAncestorOrSelfSymbol(0)
  646. , fAttributeSymbol(0)
  647. , fChildSymbol(0)
  648. , fDescendantSymbol(0)
  649. , fDescendantOrSelfSymbol(0)
  650. , fFollowingSymbol(0)
  651. , fFollowingSiblingSymbol(0)
  652. , fNamespaceSymbol(0)
  653. , fParentSymbol(0)
  654. , fPrecedingSymbol(0)
  655. , fPrecedingSiblingSymbol(0)
  656. , fSelfSymbol(0)
  657. , fStringPool(stringPool)
  658. {
  659. init();
  660. }
  661. // ---------------------------------------------------------------------------
  662. // XPathScanner: Helper methods
  663. // ---------------------------------------------------------------------------
  664. void XPathScanner::init() {
  665. fAndSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_AND);
  666. fOrSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_OR);
  667. fModSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_MOD);
  668. fDivSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_DIV);
  669. fCommentSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_COMMENT);
  670. fTextSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_TEXT);
  671. fPISymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_PI);
  672. fNodeSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_NODE);
  673. fAncestorSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_ANCESTOR);
  674. fAncestorOrSelfSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_ANCESTOR_OR_SELF);
  675. fAttributeSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_ATTRIBUTE);
  676. fChildSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_CHILD);
  677. fDescendantSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_DESCENDANT);
  678. fDescendantOrSelfSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_DESCENDANT_OR_SELF);
  679. fFollowingSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_FOLLOWING);
  680. fFollowingSiblingSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_FOLLOWING_SIBLING);
  681. fNamespaceSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_NAMESPACE);
  682. fParentSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_PARENT);
  683. fPrecedingSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_PRECEDING);
  684. fPrecedingSiblingSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_PRECEDING_SIBLING);
  685. fSelfSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_SELF);
  686. }
  687. // ---------------------------------------------------------------------------
  688. // XPathScanner: Scan methods
  689. // ---------------------------------------------------------------------------
  690. bool XPathScanner::scanExpression(const XMLCh* const data,
  691. int currentOffset,
  692. const int endOffset,
  693. ValueVectorOf<int>* const tokens) {
  694. bool starIsMultiplyOperator = false;
  695. int nameOffset = -1;
  696. int nameHandle = -1;
  697. int prefixHandle = -1;
  698. XMLCh ch;
  699. XMLBuffer dataBuffer(128, tokens->getMemoryManager());
  700. while (true) {
  701. if (currentOffset == endOffset) {
  702. break;
  703. }
  704. ch = data[currentOffset];
  705. while (XMLChar1_0::isWhitespace(ch)) {
  706. if (++currentOffset == endOffset) {
  707. break;
  708. }
  709. ch = data[currentOffset];
  710. }
  711. if (currentOffset == endOffset) {
  712. break;
  713. }
  714. //
  715. // [28] ExprToken ::= '(' | ')' | '[' | ']' | '.' | '..' | '@' | ',' | '::'
  716. // | NameTest | NodeType | Operator | FunctionName
  717. // | AxisName | Literal | Number | VariableReference
  718. //
  719. XMLByte chartype = (ch >= 0x80) ? CHARTYPE_NONASCII : fASCIICharMap[ch];
  720. switch (chartype) {
  721. case CHARTYPE_OPEN_PAREN: // '('
  722. addToken(tokens, XercesXPath::EXPRTOKEN_OPEN_PAREN);
  723. starIsMultiplyOperator = false;
  724. ++currentOffset;
  725. break;
  726. case CHARTYPE_CLOSE_PAREN: // ')'
  727. addToken(tokens, XercesXPath::EXPRTOKEN_CLOSE_PAREN);
  728. starIsMultiplyOperator = true;
  729. ++currentOffset;
  730. break;
  731. case CHARTYPE_OPEN_BRACKET: // '['
  732. addToken(tokens, XercesXPath::EXPRTOKEN_OPEN_BRACKET);
  733. starIsMultiplyOperator = false;
  734. ++currentOffset;
  735. break;
  736. case CHARTYPE_CLOSE_BRACKET: // ']'
  737. addToken(tokens, XercesXPath::EXPRTOKEN_CLOSE_BRACKET);
  738. starIsMultiplyOperator = true;
  739. ++currentOffset;
  740. break;
  741. //
  742. // [30] Number ::= Digits ('.' Digits?)? | '.' Digits
  743. // ^^^^^^^^^^
  744. //
  745. case CHARTYPE_PERIOD: // '.', '..' or '.' Digits
  746. if (currentOffset + 1 == endOffset) {
  747. addToken(tokens, XercesXPath::EXPRTOKEN_PERIOD);
  748. starIsMultiplyOperator = true;
  749. currentOffset++;
  750. break;
  751. }
  752. ch = data[currentOffset + 1];
  753. if (ch == chPeriod) { // '..'
  754. addToken(tokens, XercesXPath::EXPRTOKEN_DOUBLE_PERIOD);
  755. starIsMultiplyOperator = true;
  756. currentOffset += 2;
  757. } else if (ch >= chDigit_0 && ch <= chDigit_9) {
  758. addToken(tokens, XercesXPath::EXPRTOKEN_NUMBER);
  759. starIsMultiplyOperator = true;
  760. currentOffset = scanNumber(data, endOffset, currentOffset, tokens);
  761. } else if (ch == chForwardSlash) {
  762. addToken(tokens, XercesXPath::EXPRTOKEN_PERIOD);
  763. starIsMultiplyOperator = true;
  764. currentOffset++;
  765. } else if (ch == chPipe) { // '|'
  766. addToken(tokens, XercesXPath::EXPRTOKEN_PERIOD);
  767. starIsMultiplyOperator = true;
  768. currentOffset++;
  769. } else if (XMLChar1_0::isWhitespace(ch)) {
  770. do {
  771. if (++currentOffset == endOffset)
  772. break;
  773. ch = data[currentOffset];
  774. } while (XMLChar1_0::isWhitespace(ch));
  775. if (currentOffset == endOffset || ch == chPipe) {
  776. addToken(tokens, XercesXPath::EXPRTOKEN_PERIOD);
  777. starIsMultiplyOperator = true;
  778. break;
  779. }
  780. } else {
  781. ThrowXML(XPathException, XMLExcepts::XPath_InvalidChar);
  782. }
  783. break;
  784. case CHARTYPE_ATSIGN: // '@'
  785. addToken(tokens, XercesXPath::EXPRTOKEN_ATSIGN);
  786. starIsMultiplyOperator = false;
  787. ++currentOffset;
  788. break;
  789. case CHARTYPE_COMMA: // ','
  790. addToken(tokens, XercesXPath::EXPRTOKEN_COMMA);
  791. starIsMultiplyOperator = false;
  792. ++currentOffset;
  793. break;
  794. case CHARTYPE_COLON: // '::'
  795. if (++currentOffset == endOffset) {
  796. return false; // REVISIT
  797. }
  798. ch = data[currentOffset];
  799. if (ch != chColon) {
  800. return false; // REVISIT
  801. }
  802. addToken(tokens, XercesXPath::EXPRTOKEN_DOUBLE_COLON);
  803. starIsMultiplyOperator = false;
  804. ++currentOffset;
  805. break;
  806. case CHARTYPE_SLASH: // '/' and '//'
  807. if (++currentOffset == endOffset) {
  808. addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_SLASH);
  809. starIsMultiplyOperator = false;
  810. break;
  811. }
  812. ch = data[currentOffset];
  813. if (ch == chForwardSlash) { // '//'
  814. addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_DOUBLE_SLASH);
  815. starIsMultiplyOperator = false;
  816. ++currentOffset;
  817. } else {
  818. addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_SLASH);
  819. starIsMultiplyOperator = false;
  820. }
  821. break;
  822. case CHARTYPE_UNION: // '|'
  823. addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_UNION);
  824. starIsMultiplyOperator = false;
  825. ++currentOffset;
  826. break;
  827. case CHARTYPE_PLUS: // '+'
  828. addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_PLUS);
  829. starIsMultiplyOperator = false;
  830. ++currentOffset;
  831. break;
  832. case CHARTYPE_MINUS: // '-'
  833. addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_MINUS);
  834. starIsMultiplyOperator = false;
  835. ++currentOffset;
  836. break;
  837. case CHARTYPE_EQUAL: // '='
  838. addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_EQUAL);
  839. starIsMultiplyOperator = false;
  840. ++currentOffset;
  841. break;
  842. case CHARTYPE_EXCLAMATION: // '!='
  843. if (++currentOffset == endOffset) {
  844. return false; // REVISIT
  845. }
  846. ch = data[currentOffset];
  847. if (ch != chEqual) {
  848. return false; // REVISIT
  849. }
  850. addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_NOT_EQUAL);
  851. starIsMultiplyOperator = false;
  852. ++currentOffset;
  853. break;
  854. case CHARTYPE_LESS: // '<' and '<='
  855. if (++currentOffset == endOffset) {
  856. addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_LESS);
  857. starIsMultiplyOperator = false;
  858. break;
  859. }
  860. ch = data[currentOffset];
  861. if (ch == chEqual) { // '<='
  862. addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_LESS_EQUAL);
  863. starIsMultiplyOperator = false;
  864. ++currentOffset;
  865. } else {
  866. addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_LESS);
  867. starIsMultiplyOperator = false;
  868. }
  869. break;
  870. case CHARTYPE_GREATER: // '>' and '>='
  871. if (++currentOffset == endOffset) {
  872. addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_GREATER);
  873. starIsMultiplyOperator = false;
  874. break;
  875. }
  876. ch = data[currentOffset];
  877. if (ch == chEqual) { // '>='
  878. addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_GREATER_EQUAL);
  879. starIsMultiplyOperator = false;
  880. ++currentOffset;
  881. } else {
  882. addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_GREATER);
  883. starIsMultiplyOperator = false;
  884. }
  885. break;
  886. //
  887. // [29] Literal ::= '"' [^"]* '"' | "'" [^']* "'"
  888. //
  889. case CHARTYPE_QUOTE: // '\"' or '\''
  890. {
  891. XMLCh qchar = ch;
  892. if (++currentOffset == endOffset) {
  893. return false; // REVISIT
  894. }
  895. ch = data[currentOffset];
  896. int litOffset = currentOffset;
  897. while (ch != qchar) {
  898. if (++currentOffset == endOffset) {
  899. return false; // REVISIT
  900. }
  901. ch = data[currentOffset];
  902. }
  903. addToken(tokens, XercesXPath::EXPRTOKEN_LITERAL);
  904. starIsMultiplyOperator = true;
  905. dataBuffer.set(data + litOffset, currentOffset - litOffset);
  906. tokens->addElement(fStringPool->addOrFind(dataBuffer.getRawBuffer()));
  907. ++currentOffset;
  908. break;
  909. }
  910. //
  911. // [30] Number ::= Digits ('.' Digits?)? | '.' Digits
  912. // [31] Digits ::= [0-9]+
  913. //
  914. case CHARTYPE_DIGIT:
  915. addToken(tokens, XercesXPath::EXPRTOKEN_NUMBER);
  916. starIsMultiplyOperator = true;
  917. currentOffset = scanNumber(data, endOffset, currentOffset, tokens);
  918. break;
  919. //
  920. // [36] VariableReference ::= '$' QName
  921. //
  922. case CHARTYPE_DOLLAR:
  923. if (++currentOffset == endOffset) {
  924. return false; // REVISIT
  925. }
  926. nameOffset = currentOffset;
  927. currentOffset = scanNCName(data, endOffset, currentOffset);
  928. if (currentOffset == nameOffset) {
  929. return false; // REVISIT
  930. }
  931. if (currentOffset < endOffset) {
  932. ch = data[currentOffset];
  933. }
  934. else {
  935. ch = 0;
  936. }
  937. dataBuffer.set(data + nameOffset, currentOffset - nameOffset);
  938. nameHandle = fStringPool->addOrFind(dataBuffer.getRawBuffer());
  939. prefixHandle = -1;
  940. if (ch == chColon) {
  941. prefixHandle = nameHandle;
  942. if (++currentOffset == endOffset) {
  943. return false; // REVISIT
  944. }
  945. nameOffset = currentOffset;
  946. currentOffset = scanNCName(data, endOffset, currentOffset);
  947. if (currentOffset == nameOffset) {
  948. return false; // REVISIT
  949. }
  950. dataBuffer.set(data + nameOffset, currentOffset - nameOffset);
  951. nameHandle = fStringPool->addOrFind(dataBuffer.getRawBuffer());
  952. }
  953. addToken(tokens, XercesXPath::EXPRTOKEN_VARIABLE_REFERENCE);
  954. starIsMultiplyOperator = true;
  955. tokens->addElement(prefixHandle);
  956. tokens->addElement(nameHandle);
  957. break;
  958. //
  959. // [37] NameTest ::= '*' | NCName ':' '*' | QName
  960. // [34] MultiplyOperator ::= '*'
  961. //
  962. case CHARTYPE_STAR: // '*'
  963. //
  964. // 3.7 Lexical Structure
  965. //
  966. // If there is a preceding token and the preceding token is not one of @, ::, (, [, , or
  967. // an Operator, then a * must be recognized as a MultiplyOperator.
  968. //
  969. // Otherwise, the token must not be recognized as a MultiplyOperator.
  970. //
  971. if (starIsMultiplyOperator) {
  972. addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_MULT);
  973. starIsMultiplyOperator = false;
  974. } else {
  975. addToken(tokens, XercesXPath::EXPRTOKEN_NAMETEST_ANY);
  976. starIsMultiplyOperator = true;
  977. }
  978. ++currentOffset;
  979. break;
  980. //
  981. // NCName, QName and non-terminals
  982. //
  983. case CHARTYPE_NONASCII: // possibly a valid non-ascii 'Letter' (BaseChar | Ideographic)
  984. case CHARTYPE_LETTER:
  985. case CHARTYPE_UNDERSCORE:
  986. //
  987. // 3.7 Lexical Structure
  988. //
  989. // If there is a preceding token and the preceding token is not one of @, ::, (, [, , or
  990. // an Operator, then an NCName must be recognized as an OperatorName.
  991. //
  992. // If the character following an NCName (possibly after intervening ExprWhitespace) is (,
  993. // then the token must be recognized as a NodeType or a FunctionName.
  994. //
  995. // If the two characters following an NCName (possibly after intervening ExprWhitespace)
  996. // are ::, then the token must be recognized as an AxisName.
  997. //
  998. // Otherwise, the token must not be recognized as an OperatorName, a NodeType, a
  999. // FunctionName, or an AxisName.
  1000. //
  1001. // [33] OperatorName ::= 'and' | 'or' | 'mod' | 'div'
  1002. // [38] NodeType ::= 'comment' | 'text' | 'processing-instruction' | 'node'
  1003. // [35] FunctionName ::= QName - NodeType
  1004. // [6] AxisName ::= (see above)
  1005. //
  1006. // [37] NameTest ::= '*' | NCName ':' '*' | QName
  1007. // [5] NCName ::= (Letter | '_') (NCNameChar)*
  1008. // [?] NCNameChar ::= Letter | Digit | '.' | '-' | '_' (ascii subset of 'NCNameChar')
  1009. // [?] QName ::= (NCName ':')? NCName
  1010. // [?] Letter ::= [A-Za-z] (ascii subset of 'Letter')
  1011. // [?] Digit ::= [0-9] (ascii subset of 'Digit')
  1012. //
  1013. nameOffset = currentOffset;
  1014. currentOffset = scanNCName(data, endOffset, currentOffset);
  1015. if (currentOffset == nameOffset) {
  1016. return false; // REVISIT
  1017. }
  1018. if (currentOffset < endOffset) {
  1019. ch = data[currentOffset];
  1020. }
  1021. else {
  1022. ch = 0;
  1023. }
  1024. dataBuffer.set(data + nameOffset, currentOffset - nameOffset);
  1025. nameHandle = fStringPool->addOrFind(dataBuffer.getRawBuffer());
  1026. bool isNameTestNCName = false;
  1027. bool isAxisName = false;
  1028. prefixHandle = -1;
  1029. if (ch == chColon) {
  1030. if (++currentOffset == endOffset) {
  1031. return false; // REVISIT
  1032. }
  1033. ch = data[currentOffset];
  1034. if (ch == chAsterisk) {
  1035. if (++currentOffset < endOffset) {
  1036. ch = data[currentOffset];
  1037. }
  1038. isNameTestNCName = true;
  1039. } else if (ch == chColon) {
  1040. if (++currentOffset < endOffset) {
  1041. ch = data[currentOffset];
  1042. }
  1043. isAxisName = true;
  1044. } else {
  1045. prefixHandle = nameHandle;
  1046. nameOffset = currentOffset;
  1047. currentOffset = scanNCName(data, endOffset, currentOffset);
  1048. if (currentOffset == nameOffset) {
  1049. return false; // REVISIT
  1050. }
  1051. if (currentOffset < endOffset) {
  1052. ch = data[currentOffset];
  1053. }
  1054. else {
  1055. ch = 0;
  1056. }
  1057. dataBuffer.set(data + nameOffset, currentOffset - nameOffset);
  1058. nameHandle = fStringPool->addOrFind(dataBuffer.getRawBuffer());
  1059. }
  1060. }
  1061. //
  1062. // [39] ExprWhitespace ::= S
  1063. //
  1064. while (XMLChar1_0::isWhitespace(ch)) {
  1065. if (++currentOffset == endOffset) {
  1066. break;
  1067. }
  1068. ch = data[currentOffset];
  1069. }
  1070. //
  1071. // If there is a preceding token and the preceding token is not one of @, ::, (, [, , or
  1072. // an Operator, then an NCName must be recognized as an OperatorName.
  1073. //
  1074. if (starIsMultiplyOperator) {
  1075. if (nameHandle == fAndSymbol) {
  1076. addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_AND);
  1077. starIsMultiplyOperator = false;
  1078. } else if (nameHandle == fOrSymbol) {
  1079. addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_OR);
  1080. starIsMultiplyOperator = false;
  1081. } else if (nameHandle == fModSymbol) {
  1082. addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_MOD);
  1083. starIsMultiplyOperator = false;
  1084. } else if (nameHandle == fDivSymbol) {
  1085. addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_DIV);
  1086. starIsMultiplyOperator = false;
  1087. } else {
  1088. return false; // REVISIT
  1089. }
  1090. if (isNameTestNCName) {
  1091. return false; // REVISIT - NCName:* where an OperatorName is required
  1092. } else if (isAxisName) {
  1093. return false; // REVISIT - AxisName:: where an OperatorName is required
  1094. }
  1095. break;
  1096. }
  1097. //
  1098. // If the character following an NCName (possibly after intervening ExprWhitespace) is (,
  1099. // then the token must be recognized as a NodeType or a FunctionName.
  1100. //
  1101. if (ch == chOpenParen && !isNameTestNCName && !isAxisName) {
  1102. if (nameHandle == fCommentSymbol) {
  1103. addToken(tokens, XercesXPath::EXPRTOKEN_NODETYPE_COMMENT);
  1104. } else if (nameHandle == fTextSymbol) {
  1105. addToken(tokens, XercesXPath::EXPRTOKEN_NODETYPE_TEXT);
  1106. } else if (nameHandle == fPISymbol) {
  1107. addToken(tokens, XercesXPath::EXPRTOKEN_NODETYPE_PI);
  1108. } else if (nameHandle == fNodeSymbol) {
  1109. addToken(tokens, XercesXPath::EXPRTOKEN_NODETYPE_NODE);
  1110. } else {
  1111. addToken(tokens, XercesXPath::EXPRTOKEN_FUNCTION_NAME);
  1112. tokens->addElement(prefixHandle);
  1113. tokens->addElement(nameHandle);
  1114. }
  1115. addToken(tokens, XercesXPath::EXPRTOKEN_OPEN_PAREN);
  1116. starIsMultiplyOperator = false;
  1117. ++currentOffset;
  1118. break;
  1119. }
  1120. //
  1121. // If the two characters following an NCName (possibly after intervening ExprWhitespace)
  1122. // are ::, then the token must be recognized as an AxisName.
  1123. //
  1124. if (isAxisName ||
  1125. (ch == chColon && currentOffset + 1 < endOffset &&
  1126. data[currentOffset + 1] == chColon)) {
  1127. if (nameHandle == fAncestorSymbol) {
  1128. addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_ANCESTOR);
  1129. } else if (nameHandle == fAncestorOrSelfSymbol) {
  1130. addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_ANCESTOR_OR_SELF);
  1131. } else if (nameHandle == fAttributeSymbol) {
  1132. addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_ATTRIBUTE);
  1133. } else if (nameHandle == fChildSymbol) {
  1134. addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_CHILD);
  1135. } else if (nameHandle == fDescendantSymbol) {
  1136. addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_DESCENDANT);
  1137. } else if (nameHandle == fDescendantOrSelfSymbol) {
  1138. addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_DESCENDANT_OR_SELF);
  1139. } else if (nameHandle == fFollowingSymbol) {
  1140. addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_FOLLOWING);
  1141. } else if (nameHandle == fFollowingSiblingSymbol) {
  1142. addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_FOLLOWING_SIBLING);
  1143. } else if (nameHandle == fNamespaceSymbol) {
  1144. addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_NAMESPACE);
  1145. } else if (nameHandle == fParentSymbol) {
  1146. addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_PARENT);
  1147. } else if (nameHandle == fPrecedingSymbol) {
  1148. addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_PRECEDING);
  1149. } else if (nameHandle == fPrecedingSiblingSymbol) {
  1150. addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_PRECEDING_SIBLING);
  1151. } else if (nameHandle == fSelfSymbol) {
  1152. addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_SELF);
  1153. } else {
  1154. return false; // REVISIT
  1155. }
  1156. if (isNameTestNCName) {
  1157. return false; // REVISIT - "NCName:* ::" where "AxisName ::" is required
  1158. }
  1159. addToken(tokens, XercesXPath::EXPRTOKEN_DOUBLE_COLON);
  1160. starIsMultiplyOperator = false;
  1161. if (!isAxisName) {
  1162. currentOffset += 2;
  1163. }
  1164. break;
  1165. }
  1166. //
  1167. // Otherwise, the token must not be recognized as an OperatorName, a NodeType, a
  1168. // FunctionName, or an AxisName.
  1169. //
  1170. if (isNameTestNCName) {
  1171. addToken(tokens, XercesXPath::EXPRTOKEN_NAMETEST_NAMESPACE);
  1172. tokens->addElement(nameHandle);
  1173. } else {
  1174. addToken(tokens, XercesXPath::EXPRTOKEN_NAMETEST_QNAME);
  1175. tokens->addElement(prefixHandle);
  1176. tokens->addElement(nameHandle);
  1177. }
  1178. starIsMultiplyOperator = true;
  1179. break;
  1180. }
  1181. }
  1182. return tr

Large files files are truncated, but you can click here to view the full file