PageRenderTime 54ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/ATF2/control-software/epics-3.14.8/extensions/src/ChannelArchiver/ThirdParty/xerces-c-src2_4_0/src/xercesc/internal/IGXMLScanner.cpp

http://atf2flightsim.googlecode.com/
C++ | 1841 lines | 1207 code | 205 blank | 429 comment | 255 complexity | 42283153e40584d3316858a19c1b51f1 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) 2002 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. * $Id: IGXMLScanner.cpp,v 1.1.1.1 2009/03/14 06:42:17 whitegr Exp $
  58. */
  59. // ---------------------------------------------------------------------------
  60. // Includes
  61. // ---------------------------------------------------------------------------
  62. #include <xercesc/internal/IGXMLScanner.hpp>
  63. #include <xercesc/util/RuntimeException.hpp>
  64. #include <xercesc/util/HashPtr.hpp>
  65. #include <xercesc/util/UnexpectedEOFException.hpp>
  66. #include <xercesc/sax/InputSource.hpp>
  67. #include <xercesc/framework/XMLDocumentHandler.hpp>
  68. #include <xercesc/framework/XMLEntityHandler.hpp>
  69. #include <xercesc/framework/XMLPScanToken.hpp>
  70. #include <xercesc/internal/EndOfEntityException.hpp>
  71. #include <xercesc/framework/MemoryManager.hpp>
  72. #include <xercesc/framework/XMLGrammarPool.hpp>
  73. #include <xercesc/framework/XMLDTDDescription.hpp>
  74. #include <xercesc/framework/psvi/PSVIHandler.hpp>
  75. #include <xercesc/framework/psvi/PSVIAttributeList.hpp>
  76. #include <xercesc/validators/common/GrammarResolver.hpp>
  77. #include <xercesc/validators/DTD/DocTypeHandler.hpp>
  78. #include <xercesc/validators/DTD/DTDScanner.hpp>
  79. #include <xercesc/validators/DTD/DTDValidator.hpp>
  80. #include <xercesc/validators/schema/SchemaValidator.hpp>
  81. #include <xercesc/validators/schema/identity/FieldActivator.hpp>
  82. #include <xercesc/validators/schema/identity/XPathMatcherStack.hpp>
  83. #include <xercesc/validators/schema/identity/ValueStoreCache.hpp>
  84. #include <xercesc/validators/schema/identity/IC_Selector.hpp>
  85. #include <xercesc/validators/schema/identity/ValueStore.hpp>
  86. #include <xercesc/util/OutOfMemoryException.hpp>
  87. XERCES_CPP_NAMESPACE_BEGIN
  88. // ---------------------------------------------------------------------------
  89. // IGXMLScanner: Constructors and Destructor
  90. // ---------------------------------------------------------------------------
  91. IGXMLScanner::IGXMLScanner( XMLValidator* const valToAdopt
  92. , GrammarResolver* const grammarResolver
  93. , MemoryManager* const manager) :
  94. XMLScanner(valToAdopt, grammarResolver, manager)
  95. , fSeeXsi(false)
  96. , fElemStateSize(16)
  97. , fElemState(0)
  98. , fContent(1023, manager)
  99. , fRawAttrList(0)
  100. , fDTDValidator(0)
  101. , fSchemaValidator(0)
  102. , fDTDGrammar(0)
  103. , fMatcherStack(0)
  104. , fValueStoreCache(0)
  105. , fFieldActivator(0)
  106. , fDTDElemNonDeclPool(0)
  107. , fSchemaElemNonDeclPool(0)
  108. , fElemCount(0)
  109. , fAttDefRegistry(0)
  110. , fUndeclaredAttrRegistry(0)
  111. , fUndeclaredAttrRegistryNS(0)
  112. , fPSVIAttrList(0)
  113. , fModel(0)
  114. , fPSVIElement(0)
  115. , fErrorStack(0)
  116. {
  117. try
  118. {
  119. commonInit();
  120. // use fDTDValidator as the default validator
  121. if (!valToAdopt)
  122. fValidator = fDTDValidator;
  123. }
  124. catch(const OutOfMemoryException&)
  125. {
  126. throw;
  127. }
  128. catch(...)
  129. {
  130. cleanUp();
  131. throw;
  132. }
  133. }
  134. IGXMLScanner::IGXMLScanner( XMLDocumentHandler* const docHandler
  135. , DocTypeHandler* const docTypeHandler
  136. , XMLEntityHandler* const entityHandler
  137. , XMLErrorReporter* const errHandler
  138. , XMLValidator* const valToAdopt
  139. , GrammarResolver* const grammarResolver
  140. , MemoryManager* const manager) :
  141. XMLScanner(docHandler, docTypeHandler, entityHandler, errHandler, valToAdopt, grammarResolver, manager)
  142. , fSeeXsi(false)
  143. , fElemStateSize(16)
  144. , fElemState(0)
  145. , fContent(1023, manager)
  146. , fRawAttrList(0)
  147. , fDTDValidator(0)
  148. , fSchemaValidator(0)
  149. , fDTDGrammar(0)
  150. , fMatcherStack(0)
  151. , fValueStoreCache(0)
  152. , fFieldActivator(0)
  153. , fDTDElemNonDeclPool(0)
  154. , fSchemaElemNonDeclPool(0)
  155. , fElemCount(0)
  156. , fAttDefRegistry(0)
  157. , fUndeclaredAttrRegistry(0)
  158. , fUndeclaredAttrRegistryNS(0)
  159. , fPSVIAttrList(0)
  160. , fModel(0)
  161. , fPSVIElement(0)
  162. , fErrorStack(0)
  163. {
  164. try
  165. {
  166. commonInit();
  167. //use fDTDValidator as the default validator
  168. if (!valToAdopt)
  169. fValidator = fDTDValidator;
  170. }
  171. catch(const OutOfMemoryException&)
  172. {
  173. throw;
  174. }
  175. catch(...)
  176. {
  177. cleanUp();
  178. throw;
  179. }
  180. }
  181. IGXMLScanner::~IGXMLScanner()
  182. {
  183. cleanUp();
  184. }
  185. // ---------------------------------------------------------------------------
  186. // XMLScanner: Getter methods
  187. // ---------------------------------------------------------------------------
  188. NameIdPool<DTDEntityDecl>* IGXMLScanner::getEntityDeclPool()
  189. {
  190. if(!fDTDGrammar)
  191. return 0;
  192. return fDTDGrammar->getEntityDeclPool();
  193. }
  194. const NameIdPool<DTDEntityDecl>* IGXMLScanner::getEntityDeclPool() const
  195. {
  196. if(!fDTDGrammar)
  197. return 0;
  198. return fDTDGrammar->getEntityDeclPool();
  199. }
  200. // ---------------------------------------------------------------------------
  201. // IGXMLScanner: Main entry point to scan a document
  202. // ---------------------------------------------------------------------------
  203. void IGXMLScanner::scanDocument(const InputSource& src)
  204. {
  205. // Bump up the sequence id for this parser instance. This will invalidate
  206. // any previous progressive scan tokens.
  207. fSequenceId++;
  208. try
  209. {
  210. // Reset the scanner and its plugged in stuff for a new run. This
  211. // resets all the data structures, creates the initial reader and
  212. // pushes it on the stack, and sets up the base document path.
  213. scanReset(src);
  214. // If we have a document handler, then call the start document
  215. if (fDocHandler)
  216. fDocHandler->startDocument();
  217. // Scan the prolog part, which is everything before the root element
  218. // including the DTD subsets.
  219. scanProlog();
  220. // If we got to the end of input, then its not a valid XML file.
  221. // Else, go on to scan the content.
  222. if (fReaderMgr.atEOF())
  223. {
  224. emitError(XMLErrs::EmptyMainEntity);
  225. }
  226. else
  227. {
  228. // Scan content, and tell it its not an external entity
  229. if (scanContent(false))
  230. {
  231. // Do post-parse validation if required
  232. if (fValidate)
  233. {
  234. // We handle ID reference semantics at this level since
  235. // its required by XML 1.0.
  236. checkIDRefs();
  237. // Then allow the validator to do any extra stuff it wants
  238. // fValidator->postParseValidation();
  239. }
  240. // That went ok, so scan for any miscellaneous stuff
  241. if (!fReaderMgr.atEOF())
  242. scanMiscellaneous();
  243. }
  244. }
  245. // If we have a document handler, then call the end document
  246. if (fDocHandler)
  247. fDocHandler->endDocument();
  248. // Reset the reader manager to close all files, sockets, etc...
  249. fReaderMgr.reset();
  250. }
  251. // NOTE:
  252. //
  253. // In all of the error processing below, the emitError() call MUST come
  254. // before the flush of the reader mgr, or it will fail because it tries
  255. // to find out the position in the XML source of the error.
  256. catch(const XMLErrs::Codes)
  257. {
  258. // This is a 'first fatal error' type exit, so reset and fall through
  259. fReaderMgr.reset();
  260. }
  261. catch(const XMLValid::Codes)
  262. {
  263. // This is a 'first fatal error' type exit, so reset and fall through
  264. fReaderMgr.reset();
  265. }
  266. catch(const XMLException& excToCatch)
  267. {
  268. // Emit the error and catch any user exception thrown from here. Make
  269. // sure in all cases we flush the reader manager.
  270. fInException = true;
  271. try
  272. {
  273. if (excToCatch.getErrorType() == XMLErrorReporter::ErrType_Warning)
  274. emitError
  275. (
  276. XMLErrs::XMLException_Warning
  277. , excToCatch.getType()
  278. , excToCatch.getMessage()
  279. );
  280. else if (excToCatch.getErrorType() >= XMLErrorReporter::ErrType_Fatal)
  281. emitError
  282. (
  283. XMLErrs::XMLException_Fatal
  284. , excToCatch.getType()
  285. , excToCatch.getMessage()
  286. );
  287. else
  288. emitError
  289. (
  290. XMLErrs::XMLException_Error
  291. , excToCatch.getType()
  292. , excToCatch.getMessage()
  293. );
  294. }
  295. catch(const OutOfMemoryException&)
  296. {
  297. throw;
  298. }
  299. catch(...)
  300. {
  301. // Flush the reader manager and rethrow user's error
  302. fReaderMgr.reset();
  303. throw;
  304. }
  305. // If it returned, then reset the reader manager and fall through
  306. fReaderMgr.reset();
  307. }
  308. catch(const OutOfMemoryException&)
  309. {
  310. throw;
  311. }
  312. catch(...)
  313. {
  314. // Reset and rethrow
  315. fReaderMgr.reset();
  316. throw;
  317. }
  318. }
  319. bool IGXMLScanner::scanNext(XMLPScanToken& token)
  320. {
  321. // Make sure this token is still legal
  322. if (!isLegalToken(token))
  323. ThrowXML(RuntimeException, XMLExcepts::Scan_BadPScanToken);
  324. // Find the next token and remember the reader id
  325. unsigned int orgReader;
  326. XMLTokens curToken;
  327. bool retVal = true;
  328. try
  329. {
  330. while (true)
  331. {
  332. // We have to handle any end of entity exceptions that happen here.
  333. // We could be at the end of X nested entities, each of which will
  334. // generate an end of entity exception as we try to move forward.
  335. try
  336. {
  337. curToken = senseNextToken(orgReader);
  338. break;
  339. }
  340. catch(const EndOfEntityException& toCatch)
  341. {
  342. // Send an end of entity reference event
  343. if (fDocHandler)
  344. fDocHandler->endEntityReference(toCatch.getEntity());
  345. }
  346. }
  347. if (curToken == Token_CharData)
  348. {
  349. scanCharData(fCDataBuf);
  350. }
  351. else if (curToken == Token_EOF)
  352. {
  353. if (!fElemStack.isEmpty())
  354. {
  355. const ElemStack::StackElem* topElem = fElemStack.popTop();
  356. emitError
  357. (
  358. XMLErrs::EndedWithTagsOnStack
  359. , topElem->fThisElement->getFullName()
  360. );
  361. }
  362. retVal = false;
  363. }
  364. else
  365. {
  366. // Its some sort of markup
  367. bool gotData = true;
  368. switch(curToken)
  369. {
  370. case Token_CData :
  371. // Make sure we are within content
  372. if (fElemStack.isEmpty())
  373. emitError(XMLErrs::CDATAOutsideOfContent);
  374. scanCDSection();
  375. break;
  376. case Token_Comment :
  377. scanComment();
  378. break;
  379. case Token_EndTag :
  380. scanEndTag(gotData);
  381. break;
  382. case Token_PI :
  383. scanPI();
  384. break;
  385. case Token_StartTag :
  386. if (fDoNamespaces)
  387. scanStartTagNS(gotData);
  388. else
  389. scanStartTag(gotData);
  390. break;
  391. default :
  392. fReaderMgr.skipToChar(chOpenAngle);
  393. break;
  394. }
  395. if (orgReader != fReaderMgr.getCurrentReaderNum())
  396. emitError(XMLErrs::PartialMarkupInEntity);
  397. // If we hit the end, then do the miscellaneous part
  398. if (!gotData)
  399. {
  400. // Do post-parse validation if required
  401. if (fValidate)
  402. {
  403. // We handle ID reference semantics at this level since
  404. // its required by XML 1.0.
  405. checkIDRefs();
  406. // Then allow the validator to do any extra stuff it wants
  407. // fValidator->postParseValidation();
  408. }
  409. // That went ok, so scan for any miscellaneous stuff
  410. scanMiscellaneous();
  411. if (fValidate)
  412. fValueStoreCache->endDocument();
  413. if (fDocHandler)
  414. fDocHandler->endDocument();
  415. }
  416. }
  417. }
  418. // NOTE:
  419. //
  420. // In all of the error processing below, the emitError() call MUST come
  421. // before the flush of the reader mgr, or it will fail because it tries
  422. // to find out the position in the XML source of the error.
  423. catch(const XMLErrs::Codes)
  424. {
  425. // This is a 'first failure' exception, so reset and return failure
  426. fReaderMgr.reset();
  427. return false;
  428. }
  429. catch(const XMLValid::Codes)
  430. {
  431. // This is a 'first fatal error' type exit, so reset and reuturn failure
  432. fReaderMgr.reset();
  433. return false;
  434. }
  435. catch(const XMLException& excToCatch)
  436. {
  437. // Emit the error and catch any user exception thrown from here. Make
  438. // sure in all cases we flush the reader manager.
  439. fInException = true;
  440. try
  441. {
  442. if (excToCatch.getErrorType() == XMLErrorReporter::ErrType_Warning)
  443. emitError
  444. (
  445. XMLErrs::XMLException_Warning
  446. , excToCatch.getType()
  447. , excToCatch.getMessage()
  448. );
  449. else if (excToCatch.getErrorType() >= XMLErrorReporter::ErrType_Fatal)
  450. emitError
  451. (
  452. XMLErrs::XMLException_Fatal
  453. , excToCatch.getType()
  454. , excToCatch.getMessage()
  455. );
  456. else
  457. emitError
  458. (
  459. XMLErrs::XMLException_Error
  460. , excToCatch.getType()
  461. , excToCatch.getMessage()
  462. );
  463. }
  464. catch(const OutOfMemoryException&)
  465. {
  466. throw;
  467. }
  468. catch(...)
  469. {
  470. // Reset and rethrow user error
  471. fReaderMgr.reset();
  472. throw;
  473. }
  474. // Reset and return failure
  475. fReaderMgr.reset();
  476. return false;
  477. }
  478. catch(const OutOfMemoryException&)
  479. {
  480. throw;
  481. }
  482. catch(...)
  483. {
  484. // Reset and rethrow original error
  485. fReaderMgr.reset();
  486. throw;
  487. }
  488. // If we hit the end, then flush the reader manager
  489. if (!retVal)
  490. fReaderMgr.reset();
  491. return retVal;
  492. }
  493. // ---------------------------------------------------------------------------
  494. // IGXMLScanner: Private helper methods. Most of these are implemented in
  495. // IGXMLScanner2.Cpp.
  496. // ---------------------------------------------------------------------------
  497. // This method handles the common initialization, to avoid having to do
  498. // it redundantly in multiple constructors.
  499. void IGXMLScanner::commonInit()
  500. {
  501. // Create the element state array
  502. fElemState = (unsigned int*) fMemoryManager->allocate
  503. (
  504. fElemStateSize * sizeof(unsigned int)
  505. ); //new unsigned int[fElemStateSize];
  506. // And we need one for the raw attribute scan. This just stores key/
  507. // value string pairs (prior to any processing.)
  508. fRawAttrList = new (fMemoryManager) RefVectorOf<KVStringPair>(32, true, fMemoryManager);
  509. // Create the Validator and init them
  510. fDTDValidator = new (fMemoryManager) DTDValidator();
  511. initValidator(fDTDValidator);
  512. fSchemaValidator = new (fMemoryManager) SchemaValidator(0, fMemoryManager);
  513. initValidator(fSchemaValidator);
  514. // Create IdentityConstraint info
  515. fMatcherStack = new (fMemoryManager) XPathMatcherStack(fMemoryManager);
  516. fValueStoreCache = new (fMemoryManager) ValueStoreCache(fMemoryManager);
  517. fFieldActivator = new (fMemoryManager) FieldActivator(fValueStoreCache, fMatcherStack, fMemoryManager);
  518. fValueStoreCache->setScanner(this);
  519. // Create schemaLocation pair info
  520. fLocationPairs = new (fMemoryManager) ValueVectorOf<XMLCh*>(8, fMemoryManager);
  521. // create pools for undeclared elements
  522. fDTDElemNonDeclPool = new (fMemoryManager) NameIdPool<DTDElementDecl>(29, 128, fMemoryManager);
  523. fSchemaElemNonDeclPool = new (fMemoryManager) RefHash3KeysIdPool<SchemaElementDecl>(29, true, 128, fMemoryManager);
  524. fAttDefRegistry = new (fMemoryManager) RefHashTableOf<unsigned int>
  525. (
  526. 509, false, new (fMemoryManager)HashPtr(), fMemoryManager
  527. );
  528. fUndeclaredAttrRegistry = new (fMemoryManager) RefHashTableOf<unsigned int>
  529. (
  530. 509, false, new (fMemoryManager)HashXMLCh(), fMemoryManager
  531. );
  532. fUndeclaredAttrRegistryNS = new (fMemoryManager) RefHash2KeysTableOf<unsigned int>
  533. (
  534. 509, false, new (fMemoryManager)HashXMLCh(), fMemoryManager
  535. );
  536. fPSVIAttrList = new (fMemoryManager) PSVIAttributeList(fMemoryManager);
  537. }
  538. void IGXMLScanner::cleanUp()
  539. {
  540. fMemoryManager->deallocate(fElemState); //delete [] fElemState;
  541. delete fRawAttrList;
  542. delete fDTDValidator;
  543. delete fSchemaValidator;
  544. delete fFieldActivator;
  545. delete fMatcherStack;
  546. delete fValueStoreCache;
  547. delete fLocationPairs;
  548. delete fDTDElemNonDeclPool;
  549. delete fSchemaElemNonDeclPool;
  550. delete fAttDefRegistry;
  551. delete fUndeclaredAttrRegistry;
  552. delete fUndeclaredAttrRegistryNS;
  553. delete fPSVIAttrList;
  554. delete fPSVIElement;
  555. delete fErrorStack;
  556. }
  557. // ---------------------------------------------------------------------------
  558. // IGXMLScanner: Private scanning methods
  559. // ---------------------------------------------------------------------------
  560. // This method is called from scanStartTag() to handle the very raw initial
  561. // scan of the attributes. It just fills in the passed collection with
  562. // key/value pairs for each attribute. No processing is done on them at all.
  563. unsigned int
  564. IGXMLScanner::rawAttrScan(const XMLCh* const elemName
  565. , RefVectorOf<KVStringPair>& toFill
  566. , bool& isEmpty)
  567. {
  568. // Keep up with how many attributes we've seen so far, and how many
  569. // elements are available in the vector. This way we can reuse old
  570. // elements until we run out and then expand it.
  571. unsigned int attCount = 0;
  572. unsigned int curVecSize = toFill.size();
  573. // Assume it is not empty
  574. isEmpty = false;
  575. // We loop until we either see a /> or >, handling key/value pairs util
  576. // we get there. We place them in the passed vector, which we will expand
  577. // as required to hold them.
  578. while (true)
  579. {
  580. // Get the next character, which should be non-space
  581. XMLCh nextCh = fReaderMgr.peekNextChar();
  582. // If the next character is not a slash or closed angle bracket,
  583. // then it must be whitespace, since whitespace is required
  584. // between the end of the last attribute and the name of the next
  585. // one.
  586. //
  587. if (attCount)
  588. {
  589. if ((nextCh != chForwardSlash) && (nextCh != chCloseAngle))
  590. {
  591. if (fReaderMgr.getCurrentReader()->isWhitespace(nextCh))
  592. {
  593. // Ok, skip by them and get another char
  594. fReaderMgr.getNextChar();
  595. fReaderMgr.skipPastSpaces();
  596. nextCh = fReaderMgr.peekNextChar();
  597. }
  598. else
  599. {
  600. // Emit the error but keep on going
  601. emitError(XMLErrs::ExpectedWhitespace);
  602. }
  603. }
  604. }
  605. // Ok, here we first check for any of the special case characters.
  606. // If its not one, then we do the normal case processing, which
  607. // assumes that we've hit an attribute value, Otherwise, we do all
  608. // the special case checks.
  609. if (!fReaderMgr.getCurrentReader()->isSpecialStartTagChar(nextCh))
  610. {
  611. // Assume its going to be an attribute, so get a name from
  612. // the input.
  613. if (!fReaderMgr.getName(fAttNameBuf))
  614. {
  615. emitError(XMLErrs::ExpectedAttrName);
  616. fReaderMgr.skipPastChar(chCloseAngle);
  617. return attCount;
  618. }
  619. // And next must be an equal sign
  620. if (!scanEq())
  621. {
  622. static const XMLCh tmpList[] =
  623. {
  624. chSingleQuote, chDoubleQuote, chCloseAngle
  625. , chOpenAngle, chForwardSlash, chNull
  626. };
  627. emitError(XMLErrs::ExpectedEqSign);
  628. // Try to sync back up by skipping forward until we either
  629. // hit something meaningful.
  630. const XMLCh chFound = fReaderMgr.skipUntilInOrWS(tmpList);
  631. if ((chFound == chCloseAngle) || (chFound == chForwardSlash))
  632. {
  633. // Jump back to top for normal processing of these
  634. continue;
  635. }
  636. else if ((chFound == chSingleQuote)
  637. || (chFound == chDoubleQuote)
  638. || fReaderMgr.getCurrentReader()->isWhitespace(chFound))
  639. {
  640. // Just fall through assuming that the value is to follow
  641. }
  642. else if (chFound == chOpenAngle)
  643. {
  644. // Assume a malformed tag and that new one is starting
  645. emitError(XMLErrs::UnterminatedStartTag, elemName);
  646. return attCount;
  647. }
  648. else
  649. {
  650. // Something went really wrong
  651. return attCount;
  652. }
  653. }
  654. // Next should be the quoted attribute value. We just do a simple
  655. // and stupid scan of this value. The only thing we do here
  656. // is to expand entity references.
  657. if (!basicAttrValueScan(fAttNameBuf.getRawBuffer(), fAttValueBuf))
  658. {
  659. static const XMLCh tmpList[] =
  660. {
  661. chCloseAngle, chOpenAngle, chForwardSlash, chNull
  662. };
  663. emitError(XMLErrs::ExpectedAttrValue);
  664. // It failed, so lets try to get synced back up. We skip
  665. // forward until we find some whitespace or one of the
  666. // chars in our list.
  667. const XMLCh chFound = fReaderMgr.skipUntilInOrWS(tmpList);
  668. if ((chFound == chCloseAngle)
  669. || (chFound == chForwardSlash)
  670. || fReaderMgr.getCurrentReader()->isWhitespace(chFound))
  671. {
  672. // Just fall through and process this attribute, though
  673. // the value will be "".
  674. }
  675. else if (chFound == chOpenAngle)
  676. {
  677. // Assume a malformed tag and that new one is starting
  678. emitError(XMLErrs::UnterminatedStartTag, elemName);
  679. return attCount;
  680. }
  681. else
  682. {
  683. // Something went really wrong
  684. return attCount;
  685. }
  686. }
  687. // Make sure that the name is basically well formed for namespace
  688. // enabled rules. It either has no colons, or it has one which
  689. // is neither the first or last char.
  690. const int colonFirst = XMLString::indexOf(fAttNameBuf.getRawBuffer(), chColon);
  691. if (colonFirst != -1)
  692. {
  693. const int colonLast = XMLString::lastIndexOf(fAttNameBuf.getRawBuffer(), chColon);
  694. if (colonFirst != colonLast)
  695. {
  696. emitError(XMLErrs::TooManyColonsInName);
  697. continue;
  698. }
  699. else if ((colonFirst == 0)
  700. || (colonLast == (int)fAttNameBuf.getLen() - 1))
  701. {
  702. emitError(XMLErrs::InvalidColonPos);
  703. continue;
  704. }
  705. }
  706. // And now lets add it to the passed collection. If we have not
  707. // filled it up yet, then we use the next element. Else we add
  708. // a new one.
  709. KVStringPair* curPair = 0;
  710. if (attCount >= curVecSize)
  711. {
  712. curPair = new (fMemoryManager) KVStringPair
  713. (
  714. fAttNameBuf.getRawBuffer()
  715. , fAttValueBuf.getRawBuffer()
  716. , fMemoryManager
  717. );
  718. toFill.addElement(curPair);
  719. }
  720. else
  721. {
  722. curPair = toFill.elementAt(attCount);
  723. curPair->set(fAttNameBuf.getRawBuffer(), fAttValueBuf.getRawBuffer());
  724. }
  725. // And bump the count of attributes we've gotten
  726. attCount++;
  727. // And go to the top again for another attribute
  728. continue;
  729. }
  730. // It was some special case character so do all of the checks and
  731. // deal with it.
  732. if (!nextCh)
  733. ThrowXML(UnexpectedEOFException, XMLExcepts::Gen_UnexpectedEOF);
  734. if (nextCh == chForwardSlash)
  735. {
  736. fReaderMgr.getNextChar();
  737. isEmpty = true;
  738. if (!fReaderMgr.skippedChar(chCloseAngle))
  739. emitError(XMLErrs::UnterminatedStartTag, elemName);
  740. break;
  741. }
  742. else if (nextCh == chCloseAngle)
  743. {
  744. fReaderMgr.getNextChar();
  745. break;
  746. }
  747. else if (nextCh == chOpenAngle)
  748. {
  749. // Check for this one specially, since its going to be common
  750. // and it is kind of auto-recovering since we've already hit the
  751. // next open bracket, which is what we would have seeked to (and
  752. // skipped this whole tag.)
  753. emitError(XMLErrs::UnterminatedStartTag, elemName);
  754. break;
  755. }
  756. else if ((nextCh == chSingleQuote) || (nextCh == chDoubleQuote))
  757. {
  758. // Check for this one specially, which is probably a missing
  759. // attribute name, e.g. ="value". Just issue expected name
  760. // error and eat the quoted string, then jump back to the
  761. // top again.
  762. emitError(XMLErrs::ExpectedAttrName);
  763. fReaderMgr.getNextChar();
  764. fReaderMgr.skipQuotedString(nextCh);
  765. fReaderMgr.skipPastSpaces();
  766. continue;
  767. }
  768. }
  769. return attCount;
  770. }
  771. // This method will kick off the scanning of the primary content of the
  772. // document, i.e. the elements.
  773. bool IGXMLScanner::scanContent(const bool extEntity)
  774. {
  775. // Go into a loop until we hit the end of the root element, or we fall
  776. // out because there is no root element.
  777. //
  778. // We have to do kind of a deeply nested double loop here in order to
  779. // avoid doing the setup/teardown of the exception handler on each
  780. // round. Doing it this way we only do it when an exception actually
  781. // occurs.
  782. bool gotData = true;
  783. bool inMarkup = false;
  784. while (gotData)
  785. {
  786. try
  787. {
  788. while (gotData)
  789. {
  790. // Sense what the next top level token is. According to what
  791. // this tells us, we will call something to handle that kind
  792. // of thing.
  793. unsigned int orgReader;
  794. const XMLTokens curToken = senseNextToken(orgReader);
  795. // Handle character data and end of file specially. Char data
  796. // is not markup so we don't want to handle it in the loop
  797. // below.
  798. if (curToken == Token_CharData)
  799. {
  800. // Scan the character data and call appropriate events. Let
  801. // him use our local character data buffer for efficiency.
  802. scanCharData(fCDataBuf);
  803. continue;
  804. }
  805. else if (curToken == Token_EOF)
  806. {
  807. // The element stack better be empty at this point or we
  808. // ended prematurely before all elements were closed.
  809. if (!fElemStack.isEmpty())
  810. {
  811. const ElemStack::StackElem* topElem = fElemStack.popTop();
  812. emitError
  813. (
  814. XMLErrs::EndedWithTagsOnStack
  815. , topElem->fThisElement->getFullName()
  816. );
  817. }
  818. // Its the end of file, so clear the got data flag
  819. gotData = false;
  820. continue;
  821. }
  822. // We are in some sort of markup now
  823. inMarkup = true;
  824. // According to the token we got, call the appropriate
  825. // scanning method.
  826. switch(curToken)
  827. {
  828. case Token_CData :
  829. // Make sure we are within content
  830. if (fElemStack.isEmpty())
  831. emitError(XMLErrs::CDATAOutsideOfContent);
  832. scanCDSection();
  833. break;
  834. case Token_Comment :
  835. scanComment();
  836. break;
  837. case Token_EndTag :
  838. scanEndTag(gotData);
  839. break;
  840. case Token_PI :
  841. scanPI();
  842. break;
  843. case Token_StartTag :
  844. if (fDoNamespaces)
  845. scanStartTagNS(gotData);
  846. else
  847. scanStartTag(gotData);
  848. break;
  849. default :
  850. fReaderMgr.skipToChar(chOpenAngle);
  851. break;
  852. }
  853. if (orgReader != fReaderMgr.getCurrentReaderNum())
  854. emitError(XMLErrs::PartialMarkupInEntity);
  855. // And we are back out of markup again
  856. inMarkup = false;
  857. }
  858. }
  859. catch(const EndOfEntityException& toCatch)
  860. {
  861. // If we were in some markup when this happened, then its a
  862. // partial markup error.
  863. if (inMarkup)
  864. emitError(XMLErrs::PartialMarkupInEntity);
  865. // Send an end of entity reference event
  866. if (fDocHandler)
  867. fDocHandler->endEntityReference(toCatch.getEntity());
  868. inMarkup = false;
  869. }
  870. }
  871. // It went ok, so return success
  872. return true;
  873. }
  874. void IGXMLScanner::scanEndTag(bool& gotData)
  875. {
  876. // Assume we will still have data until proven otherwise. It will only
  877. // ever be false if this is the end of the root element.
  878. gotData = true;
  879. // Check if the element stack is empty. If so, then this is an unbalanced
  880. // element (i.e. more ends than starts, perhaps because of bad text
  881. // causing one to be skipped.)
  882. if (fElemStack.isEmpty())
  883. {
  884. emitError(XMLErrs::MoreEndThanStartTags);
  885. fReaderMgr.skipPastChar(chCloseAngle);
  886. ThrowXML(RuntimeException, XMLExcepts::Scan_UnbalancedStartEnd);
  887. }
  888. // After the </ is the element QName, so get a name from the input
  889. if (!fReaderMgr.getName(fQNameBuf))
  890. {
  891. // It failed so we can't really do anything with it
  892. emitError(XMLErrs::ExpectedElementName);
  893. fReaderMgr.skipPastChar(chCloseAngle);
  894. //REVISIT: Do we restore PSVI information?
  895. return;
  896. }
  897. unsigned int uriId = fEmptyNamespaceId;
  898. int prefixColonPos = -1;
  899. if (fDoNamespaces)
  900. {
  901. uriId = resolveQName
  902. (
  903. fQNameBuf.getRawBuffer()
  904. , fPrefixBuf
  905. , ElemStack::Mode_Element
  906. , prefixColonPos
  907. );
  908. }
  909. // Pop the stack of the element we are supposed to be ending. Remember
  910. // that we don't own this. The stack just keeps them and reuses them.
  911. //
  912. // NOTE: We CANNOT do this until we've resolved the element name because
  913. // the element stack top contains the prefix to URI mappings for this
  914. // element.
  915. unsigned int topUri = fElemStack.getCurrentURI();
  916. const ElemStack::StackElem* topElem = fElemStack.popTop();
  917. // See if it was the root element, to avoid multiple calls below
  918. const bool isRoot = fElemStack.isEmpty();
  919. // Make sure that its the end of the element that we expect
  920. XMLElementDecl* tempElement = topElem->fThisElement;
  921. if (fDoNamespaces && fGrammarType == Grammar::SchemaGrammarType) {
  922. const XMLCh* rawNameBuf = fQNameBuf.getRawBuffer();
  923. if ((topUri != uriId) || (!XMLString::equals(tempElement->getBaseName(), &rawNameBuf[prefixColonPos + 1])))
  924. {
  925. emitError
  926. (
  927. XMLErrs::ExpectedEndOfTagX
  928. , topElem->fThisElement->getFullName()
  929. );
  930. }
  931. }
  932. else {
  933. if (!XMLString::equals(tempElement->getFullName(), fQNameBuf.getRawBuffer()))
  934. {
  935. emitError
  936. (
  937. XMLErrs::ExpectedEndOfTagX
  938. , topElem->fThisElement->getFullName()
  939. );
  940. }
  941. }
  942. // Make sure we are back on the same reader as where we started
  943. if (topElem->fReaderNum != fReaderMgr.getCurrentReaderNum())
  944. emitError(XMLErrs::PartialTagMarkupError);
  945. // Skip optional whitespace
  946. fReaderMgr.skipPastSpaces();
  947. // Make sure we find the closing bracket
  948. if (!fReaderMgr.skippedChar(chCloseAngle))
  949. {
  950. emitError
  951. (
  952. XMLErrs::UnterminatedEndTag
  953. , topElem->fThisElement->getFullName()
  954. );
  955. }
  956. if (fPSVIHandler && fGrammarType == Grammar::SchemaGrammarType)
  957. {
  958. if (fValidate && topElem->fThisElement->isDeclared())
  959. {
  960. fPSVIElemContext.fCurrentDV = ((SchemaValidator*) fValidator)->getCurrentDatatypeValidator();
  961. fPSVIElemContext.fCurrentTypeInfo = ((SchemaValidator*) fValidator)->getCurrentTypeInfo();
  962. fPSVIElemContext.fNormalizedValue = ((SchemaValidator*) fValidator)->getNormalizedValue();
  963. if (XMLString::equals(fPSVIElemContext.fNormalizedValue, XMLUni::fgZeroLenString))
  964. fPSVIElemContext.fNormalizedValue = 0;
  965. }
  966. else
  967. {
  968. fPSVIElemContext.fCurrentDV = 0;
  969. fPSVIElemContext.fCurrentTypeInfo = 0;
  970. fPSVIElemContext.fNormalizedValue = 0;
  971. }
  972. }
  973. // If validation is enabled, then lets pass him the list of children and
  974. // this element and let him validate it.
  975. DatatypeValidator* psviMemberType = 0;
  976. if (fValidate)
  977. {
  978. int res = fValidator->checkContent
  979. (
  980. topElem->fThisElement
  981. , topElem->fChildren
  982. , topElem->fChildCount
  983. );
  984. if (res >= 0)
  985. {
  986. // One of the elements is not valid for the content. NOTE that
  987. // if no children were provided but the content model requires
  988. // them, it comes back with a zero value. But we cannot use that
  989. // to index the child array in this case, and have to put out a
  990. // special message.
  991. if (!topElem->fChildCount)
  992. {
  993. fValidator->emitError
  994. (
  995. XMLValid::EmptyNotValidForContent
  996. , topElem->fThisElement->getFormattedContentModel()
  997. );
  998. }
  999. else if ((unsigned int)res >= topElem->fChildCount)
  1000. {
  1001. fValidator->emitError
  1002. (
  1003. XMLValid::NotEnoughElemsForCM
  1004. , topElem->fThisElement->getFormattedContentModel()
  1005. );
  1006. }
  1007. else
  1008. {
  1009. fValidator->emitError
  1010. (
  1011. XMLValid::ElementNotValidForContent
  1012. , topElem->fChildren[res]->getRawName()
  1013. , topElem->fThisElement->getFormattedContentModel()
  1014. );
  1015. }
  1016. }
  1017. if (fGrammarType == Grammar::SchemaGrammarType) {
  1018. if (fPSVIHandler)
  1019. {
  1020. fPSVIElemContext.fIsSpecified = ((SchemaValidator*) fValidator)->getIsElemSpecified();
  1021. if (((SchemaValidator*) fValidator)->getErrorOccurred())
  1022. fPSVIElemContext.fErrorOccurred = true;
  1023. else if (fPSVIElemContext.fCurrentDV->getType() == DatatypeValidator::Union)
  1024. psviMemberType = fValidationContext->getValidatingMemberType();
  1025. }
  1026. // call matchers and de-activate context
  1027. int oldCount = fMatcherStack->getMatcherCount();
  1028. if (oldCount ||
  1029. ((SchemaElementDecl*)topElem->fThisElement)->getIdentityConstraintCount()) {
  1030. for (int i = oldCount - 1; i >= 0; i--) {
  1031. XPathMatcher* matcher = fMatcherStack->getMatcherAt(i);
  1032. matcher->endElement(*(topElem->fThisElement), fContent.getRawBuffer());
  1033. }
  1034. if (fMatcherStack->size() > 0) {
  1035. fMatcherStack->popContext();
  1036. }
  1037. // handle everything *but* keyref's.
  1038. int newCount = fMatcherStack->getMatcherCount();
  1039. for (int j = oldCount - 1; j >= newCount; j--) {
  1040. XPathMatcher* matcher = fMatcherStack->getMatcherAt(j);
  1041. IdentityConstraint* ic = matcher->getIdentityConstraint();
  1042. if (ic && (ic->getType() != IdentityConstraint::KEYREF))
  1043. fValueStoreCache->transplant(ic, matcher->getInitialDepth());
  1044. }
  1045. // now handle keyref's...
  1046. for (int k = oldCount - 1; k >= newCount; k--) {
  1047. XPathMatcher* matcher = fMatcherStack->getMatcherAt(k);
  1048. IdentityConstraint* ic = matcher->getIdentityConstraint();
  1049. if (ic && (ic->getType() == IdentityConstraint::KEYREF)) {
  1050. ValueStore* values = fValueStoreCache->getValueStoreFor(ic, matcher->getInitialDepth());
  1051. if (values) { // nothing to do if nothing matched!
  1052. values->endDcocumentFragment(fValueStoreCache);
  1053. }
  1054. }
  1055. }
  1056. fValueStoreCache->endElement();
  1057. }
  1058. }
  1059. }
  1060. if (fGrammarType == Grammar::SchemaGrammarType)
  1061. {
  1062. if(!isRoot)
  1063. ((SchemaElementDecl *)fElemStack.topElement()->fThisElement)->updateValidityFromElement(topElem->fThisElement, fGrammarType);
  1064. if (fPSVIHandler)
  1065. {
  1066. endElementPSVI(
  1067. (SchemaElementDecl*)topElem->fThisElement, psviMemberType);
  1068. }
  1069. }
  1070. // If we have a doc handler, tell it about the end tag
  1071. if (fDocHandler)
  1072. {
  1073. fDocHandler->endElement
  1074. (
  1075. *topElem->fThisElement
  1076. , uriId
  1077. , isRoot
  1078. , fPrefixBuf.getRawBuffer()
  1079. );
  1080. }
  1081. // reset xsi:type ComplexTypeInfo
  1082. if (fGrammarType == Grammar::SchemaGrammarType) {
  1083. ((SchemaElementDecl*)topElem->fThisElement)->reset();
  1084. if (!isRoot)
  1085. ((SchemaElementDecl*)(fElemStack.topElement()->fThisElement))->
  1086. setXsiComplexTypeInfo(((SchemaValidator*)fValidator)->getCurrentTypeInfo());
  1087. }
  1088. // If this was the root, then done with content
  1089. gotData = !isRoot;
  1090. if (gotData) {
  1091. if (fDoNamespaces) {
  1092. // Restore the grammar
  1093. fGrammar = fElemStack.getCurrentGrammar();
  1094. fGrammarType = fGrammar->getGrammarType();
  1095. if (fGrammarType == Grammar::SchemaGrammarType && !fValidator->handlesSchema()) {
  1096. if (fValidatorFromUser)
  1097. ThrowXML(RuntimeException, XMLExcepts::Gen_NoSchemaValidator);
  1098. else {
  1099. fValidator = fSchemaValidator;
  1100. }
  1101. }
  1102. else if (fGrammarType == Grammar::DTDGrammarType && !fValidator->handlesDTD()) {
  1103. if (fValidatorFromUser)
  1104. ThrowXML(RuntimeException, XMLExcepts::Gen_NoDTDValidator);
  1105. else {
  1106. fValidator = fDTDValidator;
  1107. }
  1108. }
  1109. fValidator->setGrammar(fGrammar);
  1110. }
  1111. // Restore the validation flag
  1112. fValidate = fElemStack.getValidationFlag();
  1113. }
  1114. }
  1115. // This method handles the high level logic of scanning the DOCType
  1116. // declaration. This calls the DTDScanner and kicks off both the scanning of
  1117. // the internal subset and the scanning of the external subset, if any.
  1118. //
  1119. // When we get here the '<!DOCTYPE' part has already been scanned, which is
  1120. // what told us that we had a doc type decl to parse.
  1121. void IGXMLScanner::scanDocTypeDecl()
  1122. {
  1123. // We have a doc type. So, switch the Grammar.
  1124. switchGrammar(XMLUni::fgDTDEntityString);
  1125. if (fDocTypeHandler)
  1126. fDocTypeHandler->resetDocType();
  1127. // There must be some space after DOCTYPE
  1128. if (!fReaderMgr.skipPastSpaces())
  1129. {
  1130. emitError(XMLErrs::ExpectedWhitespace);
  1131. // Just skip the Doctype declaration and return
  1132. fReaderMgr.skipPastChar(chCloseAngle);
  1133. return;
  1134. }
  1135. // Get a buffer for the root element
  1136. XMLBufBid bbRootName(&fBufMgr);
  1137. // Get a name from the input, which should be the name of the root
  1138. // element of the upcoming content.
  1139. fReaderMgr.getName(bbRootName.getBuffer());
  1140. if (bbRootName.isEmpty())
  1141. {
  1142. emitError(XMLErrs::NoRootElemInDOCTYPE);
  1143. fReaderMgr.skipPastChar(chCloseAngle);
  1144. return;
  1145. }
  1146. // Store the root element name for later check
  1147. setRootElemName(bbRootName.getRawBuffer());
  1148. // This element obviously is not going to exist in the element decl
  1149. // pool yet, but we need to call docTypeDecl. So force it into
  1150. // the element decl pool, marked as being there because it was in
  1151. // the DOCTYPE. Later, when its declared, the status will be updated.
  1152. //
  1153. // Only do this if we are not reusing the validator! If we are reusing,
  1154. // then look it up instead. It has to exist!
  1155. DTDElementDecl* rootDecl = new (fGrammarPoolMemoryManager) DTDElementDecl
  1156. (
  1157. bbRootName.getRawBuffer()
  1158. , fEmptyNamespaceId
  1159. , DTDElementDecl::Any
  1160. , fGrammarPoolMemoryManager
  1161. );
  1162. rootDecl->setCreateReason(DTDElementDecl::AsRootElem);
  1163. rootDecl->setExternalElemDeclaration(true);
  1164. if(!fUseCachedGrammar)
  1165. {
  1166. // this will break getRootElemId on DTDGrammar when
  1167. // cached grammars are in use, but
  1168. // why would one use this anyway???
  1169. ((DTDGrammar*)fGrammar)->setRootElemId(fGrammar->putElemDecl(rootDecl));
  1170. } else
  1171. {
  1172. // attach this to the undeclared element pool so that it gets deleted
  1173. rootDecl->setId(fDTDElemNonDeclPool->put((DTDElementDecl*)rootDecl));
  1174. }
  1175. // Skip any spaces after the name
  1176. fReaderMgr.skipPastSpaces();
  1177. // And now if we are looking at a >, then we are done. It is not
  1178. // required to have an internal or external subset, though why you
  1179. // would not escapes me.
  1180. if (fReaderMgr.skippedChar(chCloseAngle)) {
  1181. // If we have a doc type handler and advanced callbacks are enabled,
  1182. // call the doctype event.
  1183. if (fDocTypeHandler)
  1184. fDocTypeHandler->doctypeDecl(*rootDecl, 0, 0, false);
  1185. return;
  1186. }
  1187. // either internal/external subset
  1188. if (fValScheme == Val_Auto && !fValidate)
  1189. fValidate = true;
  1190. bool hasIntSubset = false;
  1191. bool hasExtSubset = false;
  1192. XMLCh* sysId = 0;
  1193. XMLCh* pubId = 0;
  1194. DTDScanner dtdScanner
  1195. (
  1196. (DTDGrammar*) fGrammar
  1197. , fDocTypeHandler
  1198. , fGrammarPoolMemoryManager
  1199. , fMemoryManager
  1200. );
  1201. dtdScanner.setScannerInfo(this, &fReaderMgr, &fBufMgr);
  1202. // If the next character is '[' then we have no external subset cause
  1203. // there is no system id, just the opening character of the internal
  1204. // subset. Else, has to be an id.
  1205. //
  1206. // Just look at the next char, don't eat it.
  1207. if (fReaderMgr.peekNextChar() == chOpenSquare)
  1208. {
  1209. hasIntSubset = true;
  1210. }
  1211. else
  1212. {
  1213. // Indicate we have an external subset
  1214. hasExtSubset = true;
  1215. fHasNoDTD = false;
  1216. // Get buffers for the ids
  1217. XMLBufBid bbPubId(&fBufMgr);
  1218. XMLBufBid bbSysId(&fBufMgr);
  1219. // Get the external subset id
  1220. if (!dtdScanner.scanId(bbPubId.getBuffer(), bbSysId.getBuffer(), DTDScanner::IDType_External))
  1221. {
  1222. fReaderMgr.skipPastChar(chCloseAngle);
  1223. return;
  1224. }
  1225. // Get copies of the ids we got
  1226. pubId = XMLString::replicate(bbPubId.getRawBuffer(), fMemoryManager);
  1227. sysId = XMLString::replicate(bbSysId.getRawBuffer(), fMemoryManager);
  1228. // Skip spaces and check again for the opening of an internal subset
  1229. fReaderMgr.skipPastSpaces();
  1230. // Just look at the next char, don't eat it.
  1231. if (fReaderMgr.peekNextChar() == chOpenSquare) {
  1232. hasIntSubset = true;
  1233. }
  1234. }
  1235. // Insure that the ids get cleaned up, if they got allocated
  1236. ArrayJanitor<XMLCh> janSysId(sysId, fMemoryManager);
  1237. ArrayJanitor<XMLCh> janPubId(pubId, fMemoryManager);
  1238. // If we have a doc type handler and advanced callbacks are enabled,
  1239. // call the doctype event.
  1240. if (fDocTypeHandler)
  1241. fDocTypeHandler->doctypeDecl(*rootDecl, pubId, sysId, hasIntSubset, hasExtSubset);
  1242. // Ok, if we had an internal subset, we are just past the [ character
  1243. // and need to parse that first.
  1244. if (hasIntSubset)
  1245. {
  1246. // Eat the opening square bracket
  1247. fReaderMgr.getNextChar();
  1248. // We can't have any internal subset if we are reusing the validator
  1249. if (fUseCachedGrammar || fToCacheGrammar)
  1250. ThrowXML(RuntimeException, XMLExcepts::Val_CantHaveIntSS);
  1251. // And try to scan the internal subset. If we fail, try to recover
  1252. // by skipping forward tot he close angle and returning.
  1253. if (!dtdScanner.scanInternalSubset())
  1254. {
  1255. fReaderMgr.skipPastChar(chCloseAngle);
  1256. return;
  1257. }
  1258. // Do a sanity check that some expanded PE did not propogate out of
  1259. // the doctype. This could happen if it was terminated early by bad
  1260. // syntax.
  1261. if (fReaderMgr.getReaderDepth() > 1)
  1262. {
  1263. emitError(XMLErrs::PEPropogated);
  1264. // Ask the reader manager to pop backā€¦

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