SAXParser.cpp
上传用户:zhuqijet
上传日期:2013-06-25
资源大小:10074k
文件大小:43k
源码类别:

词法分析

开发平台:

Visual C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 1999-2003 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: SAXParser.cpp,v $
  58.  * Revision 1.19  2003/05/18 14:02:05  knoaman
  59.  * Memory manager implementation: pass per instance manager.
  60.  *
  61.  * Revision 1.18  2003/05/16 21:36:59  knoaman
  62.  * Memory manager implementation: Modify constructors to pass in the memory manager.
  63.  *
  64.  * Revision 1.17  2003/05/15 18:26:50  knoaman
  65.  * Partial implementation of the configurable memory manager.
  66.  *
  67.  * Revision 1.16  2003/04/17 21:58:50  neilg
  68.  * Adding a new property,
  69.  * http://apache.org/xml/properties/security-manager, with
  70.  * appropriate getSecurityManager/setSecurityManager methods on DOM
  71.  * and SAX parsers.  Also adding a new SecurityManager class.
  72.  *
  73.  * The purpose of these modifications is to permit applications a
  74.  * means to have the parser reject documents whose processing would
  75.  * otherwise consume large amounts of system resources.  Malicious
  76.  * use of such documents could be used to launch a denial-of-service
  77.  * attack against a system running the parser.  Initially, the
  78.  * SecurityManager only knows about attacks that can result from
  79.  * exponential entity expansion; this is the only known attack that
  80.  * involves processing a single XML document.  Other, simlar attacks
  81.  * can be launched if arbitrary schemas may be parsed; there already
  82.  * exist means (via use of the EntityResolver interface) by which
  83.  * applications can deny processing of untrusted schemas.  In future,
  84.  * the SecurityManager will be expanded to take these other exploits
  85.  * into account.
  86.  *
  87.  * add security manager
  88.  * 
  89.  * Revision 1.15  2003/02/04 19:27:43  knoaman
  90.  * Performance: use global buffer to eliminate repetitive memory creation/deletion.
  91.  *
  92.  * Revision 1.14  2003/01/09 19:07:08  tng
  93.  * [Bug 15802] Add "const" qualifier to getURIText.
  94.  *
  95.  * Revision 1.13  2003/01/03 20:09:36  tng
  96.  * New feature StandardUriConformant to force strict standard uri conformance.
  97.  *
  98.  * Revision 1.12  2002/12/27 16:16:51  knoaman
  99.  * Set scanner options and handlers.
  100.  *
  101.  * Revision 1.11  2002/12/23 15:23:18  knoaman
  102.  * Added a public api to various parsers to return the src offset within the input
  103.  * source.
  104.  *
  105.  * Revision 1.10  2002/12/04 01:57:09  knoaman
  106.  * Scanner re-organization.
  107.  *
  108.  * Revision 1.9  2002/11/04 14:57:03  tng
  109.  * C++ Namespace Support.
  110.  *
  111.  * Revision 1.8  2002/08/14 15:20:38  knoaman
  112.  * [Bug 3111] Problem with LexicalHandler::startDTD() and LexicalHandler::endDTD().
  113.  *
  114.  * Revision 1.7  2002/07/11 18:27:04  knoaman
  115.  * Grammar caching/preparsing - initial implementation.
  116.  *
  117.  * Revision 1.6  2002/05/30 16:20:09  tng
  118.  * Add feature to optionally ignore external DTD.
  119.  *
  120.  * Revision 1.5  2002/05/29 21:37:47  knoaman
  121.  * Add baseURI to resolveEntity to support DOMInputSource.
  122.  *
  123.  * Revision 1.4  2002/05/28 20:44:14  tng
  124.  * [Bug 9104] prefixes dissapearing when schema validation turned on.
  125.  *
  126.  * Revision 1.3  2002/05/27 18:39:21  tng
  127.  * To get ready for 64 bit large file, use XMLSSize_t to represent line and column number.
  128.  *
  129.  * Revision 1.2  2002/05/22 20:53:41  knoaman
  130.  * Prepare for DOM L3 :
  131.  * - Make use of the XMLEntityHandler/XMLErrorReporter interfaces, instead of using
  132.  * EntityHandler/ErrorHandler directly.
  133.  * - Add 'AbstractDOMParser' class to provide common functionality for XercesDOMParser
  134.  * and DOMBuilder.
  135.  *
  136.  * Revision 1.1.1.1  2002/02/01 22:22:07  peiyongz
  137.  * sane_include
  138.  *
  139.  * Revision 1.23  2001/11/20 18:51:44  tng
  140.  * Schema: schemaLocation and noNamespaceSchemaLocation to be specified outside the instance document.  New methods setExternalSchemaLocation and setExternalNoNamespaceSchemaLocation are added (for SAX2, two new properties are added).
  141.  *
  142.  * Revision 1.22  2001/10/25 19:46:15  tng
  143.  * Comment outside root element should also be reported.
  144.  *
  145.  * Revision 1.21  2001/08/01 19:11:02  tng
  146.  * Add full schema constraint checking flag to the samples and the parser.
  147.  *
  148.  * Revision 1.20  2001/06/03 19:26:20  jberry
  149.  * Add support for querying error count following parse; enables simple parse without requiring error handler.
  150.  *
  151.  * Revision 1.19  2001/05/11 13:26:22  tng
  152.  * Copyright update.
  153.  *
  154.  * Revision 1.18  2001/05/03 19:09:23  knoaman
  155.  * Support Warning/Error/FatalError messaging.
  156.  * Validity constraints errors are treated as errors, with the ability by user to set
  157.  * validity constraints as fatal errors.
  158.  *
  159.  * Revision 1.17  2001/03/30 16:46:57  tng
  160.  * Schema: Use setDoSchema instead of setSchemaValidation which makes more sense.
  161.  *
  162.  * Revision 1.16  2001/03/21 21:56:08  tng
  163.  * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
  164.  *
  165.  * Revision 1.15  2001/02/15 15:56:29  tng
  166.  * Schema: Add setSchemaValidation and getSchemaValidation for DOMParser and SAXParser.
  167.  * Add feature "http://apache.org/xml/features/validation/schema" for SAX2XMLReader.
  168.  * New data field  fSchemaValidation in XMLScanner as the flag.
  169.  *
  170.  * Revision 1.14  2000/09/05 23:38:26  andyh
  171.  * Added advanced callback support for XMLDecl()
  172.  *
  173.  * Revision 1.13  2000/06/19 18:12:56  rahulj
  174.  * Suppress the comments, characters, ignoreableWhitespaces before
  175.  * root element. Only allow the PI's to get through. Still need to come
  176.  * to a consensus on this.
  177.  *
  178.  * Revision 1.12  2000/06/17 02:00:55  rahulj
  179.  * Also pass any PI's, comment's, character's occuring before root
  180.  * element to the registered document Handler. Defect identified
  181.  * by John Smirl and Rich Taylor.
  182.  *
  183.  * Revision 1.11  2000/05/15 22:31:18  andyh
  184.  * Replace #include<memory.h> with <string.h> everywhere.
  185.  *
  186.  * Revision 1.10  2000/04/12 22:58:30  roddey
  187.  * Added support for 'auto validate' mode.
  188.  *
  189.  * Revision 1.9  2000/04/11 19:17:58  roddey
  190.  * If a SAX error handler is installed, then the resetErrors() event handler
  191.  * should call the one on the installed SAX error handler.
  192.  *
  193.  * Revision 1.8  2000/04/05 18:56:17  roddey
  194.  * Init the fDTDHandler member. Enable installation of DTDHandler
  195.  * on SAX parser.
  196.  *
  197.  * Revision 1.7  2000/03/03 01:29:34  roddey
  198.  * Added a scanReset()/parseReset() method to the scanner and
  199.  * parsers, to allow for reset after early exit from a progressive parse.
  200.  * Added calls to new Terminate() call to all of the samples. Improved
  201.  * documentation in SAX and DOM parsers.
  202.  *
  203.  * Revision 1.6  2000/03/02 19:54:33  roddey
  204.  * This checkin includes many changes done while waiting for the
  205.  * 1.1.0 code to be finished. I can't list them all here, but a list is
  206.  * available elsewhere.
  207.  *
  208.  * Revision 1.5  2000/02/17 03:54:26  rahulj
  209.  * Added some new getters to query the parser state and
  210.  * clarified the documentation.
  211.  *
  212.  * Revision 1.4  2000/02/06 07:47:56  rahulj
  213.  * Year 2K copyright swat.
  214.  *
  215.  * Revision 1.3  2000/01/12 00:15:22  roddey
  216.  * Changes to deal with multiply nested, relative pathed, entities and to deal
  217.  * with the new URL class changes.
  218.  *
  219.  * Revision 1.2  1999/12/15 19:57:48  roddey
  220.  * Got rid of redundant 'const' on boolean return value. Some compilers choke
  221.  * on this and its useless.
  222.  *
  223.  * Revision 1.1.1.1  1999/11/09 01:07:50  twl
  224.  * Initial checkin
  225.  *
  226.  * Revision 1.6  1999/11/08 20:44:53  rahul
  227.  * Swat for adding in Product name and CVS comment log variable.
  228.  *
  229.  */
  230. // ---------------------------------------------------------------------------
  231. //  Includes
  232. // ---------------------------------------------------------------------------
  233. #include <xercesc/parsers/SAXParser.hpp>
  234. #include <xercesc/internal/XMLScannerResolver.hpp>
  235. #include <xercesc/framework/XMLValidator.hpp>
  236. #include <xercesc/util/IOException.hpp>
  237. #include <xercesc/sax/DocumentHandler.hpp>
  238. #include <xercesc/sax/DTDHandler.hpp>
  239. #include <xercesc/sax/ErrorHandler.hpp>
  240. #include <xercesc/sax/EntityResolver.hpp>
  241. #include <xercesc/sax/SAXParseException.hpp>
  242. #include <xercesc/validators/common/GrammarResolver.hpp>
  243. #include <string.h>
  244. XERCES_CPP_NAMESPACE_BEGIN
  245. // ---------------------------------------------------------------------------
  246. //  SAXParser: Constructors and Destructor
  247. // ---------------------------------------------------------------------------
  248. SAXParser::SAXParser( XMLValidator* const  valToAdopt
  249.                     , MemoryManager* const manager) :
  250.     fParseInProgress(false)
  251.     , fElemDepth(0)
  252.     , fAdvDHCount(0)
  253.     , fAdvDHListSize(32)
  254.     , fDocHandler(0)
  255.     , fDTDHandler(0)
  256.     , fEntityResolver(0)
  257.     , fErrorHandler(0)
  258.     , fAdvDHList(0)
  259.     , fScanner(0)
  260.     , fGrammarResolver(0)
  261.     , fURIStringPool(0)
  262.     , fValidator(valToAdopt)
  263.     , fMemoryManager(manager)
  264.     , fElemQNameBuf(1023, manager)
  265. {
  266.     try
  267.     {
  268.         initialize();
  269.     }
  270.     catch(...)
  271.     {
  272.         cleanUp();
  273.         throw;
  274.     }
  275. }
  276. SAXParser::~SAXParser()
  277. {
  278.     cleanUp();
  279. }
  280. // ---------------------------------------------------------------------------
  281. //  SAXParser: Initialize/CleanUp methods
  282. // ---------------------------------------------------------------------------
  283. void SAXParser::initialize()
  284. {
  285.     // Create grammar resolver and string pool to pass to scanner
  286.     fGrammarResolver = new (fMemoryManager) GrammarResolver(fMemoryManager);
  287.     fURIStringPool = new (fMemoryManager) XMLStringPool(109, fMemoryManager);
  288.     // Create our scanner and tell it what validator to use
  289.     fScanner = XMLScannerResolver::getDefaultScanner(fValidator,fMemoryManager);
  290.     fScanner->setGrammarResolver(fGrammarResolver);
  291.     fScanner->setURIStringPool(fURIStringPool);
  292.     // Create the initial advanced handler list array and zero it out
  293.     fAdvDHList = (XMLDocumentHandler**) fMemoryManager->allocate
  294.     (
  295.         fAdvDHListSize * sizeof(XMLDocumentHandler*)
  296.     );//new XMLDocumentHandler*[fAdvDHListSize];
  297.     memset(fAdvDHList, 0, sizeof(void*) * fAdvDHListSize);
  298. }
  299. void SAXParser::cleanUp()
  300. {
  301.     fMemoryManager->deallocate(fAdvDHList);//delete [] fAdvDHList;
  302.     delete fScanner;
  303.     delete fGrammarResolver;
  304.     delete fURIStringPool;
  305.     if (fValidator)
  306.         delete fValidator;
  307. }
  308. // ---------------------------------------------------------------------------
  309. //  SAXParser: Advanced document handler list maintenance methods
  310. // ---------------------------------------------------------------------------
  311. void SAXParser::installAdvDocHandler(XMLDocumentHandler* const toInstall)
  312. {
  313.     // See if we need to expand and do so now if needed
  314.     if (fAdvDHCount == fAdvDHListSize)
  315.     {
  316.         // Calc a new size and allocate the new temp buffer
  317.         const unsigned int newSize = (unsigned int)(fAdvDHListSize * 1.5);
  318.         XMLDocumentHandler** newList = (XMLDocumentHandler**) fMemoryManager->allocate
  319.         (
  320.             newSize * sizeof(XMLDocumentHandler*)
  321.         );//new XMLDocumentHandler*[newSize];
  322.         // Copy over the old data to the new list and zero out the rest
  323.         memcpy(newList, fAdvDHList, sizeof(void*) * fAdvDHListSize);
  324.         memset
  325.         (
  326.             &newList[fAdvDHListSize]
  327.             , 0
  328.             , sizeof(void*) * (newSize - fAdvDHListSize)
  329.         );
  330.         // And now clean up the old array and store the new stuff
  331.         fMemoryManager->deallocate(fAdvDHList);//delete [] fAdvDHList;
  332.         fAdvDHList = newList;
  333.         fAdvDHListSize = newSize;
  334.     }
  335.     // Add this new guy into the empty slot
  336.     fAdvDHList[fAdvDHCount++] = toInstall;
  337.     //
  338.     //  Install ourself as the document handler with the scanner. We might
  339.     //  already be, but its not worth checking, just do it.
  340.     //
  341.     fScanner->setDocHandler(this);
  342. }
  343. bool SAXParser::removeAdvDocHandler(XMLDocumentHandler* const toRemove)
  344. {
  345.     // If our count is zero, can't be any installed
  346.     if (!fAdvDHCount)
  347.         return false;
  348.     //
  349.     //  Search the array until we find this handler. If we find a null entry
  350.     //  first, we can stop there before the list is kept contiguous.
  351.     //
  352.     unsigned int index;
  353.     for (index = 0; index < fAdvDHCount; index++)
  354.     {
  355.         //
  356.         //  We found it. We have to keep the list contiguous, so we have to
  357.         //  copy down any used elements after this one.
  358.         //
  359.         if (fAdvDHList[index] == toRemove)
  360.         {
  361.             //
  362.             //  Optimize if only one entry (pretty common). Otherwise, we
  363.             //  have to copy them down to compact them.
  364.             //
  365.             if (fAdvDHCount > 1)
  366.             {
  367.                 index++;
  368.                 while (index < fAdvDHCount)
  369.                     fAdvDHList[index - 1] = fAdvDHList[index];
  370.             }
  371.             // Bump down the count and zero out the last one
  372.             fAdvDHCount--;
  373.             fAdvDHList[fAdvDHCount] = 0;
  374.             //
  375.             //  If this leaves us with no advanced handlers and there is
  376.             //  no SAX doc handler installed on us, then remove us from the
  377.             //  scanner as the document handler.
  378.             //
  379.             if (!fAdvDHCount && !fDocHandler)
  380.                 fScanner->setDocHandler(0);
  381.             return true;
  382.         }
  383.     }
  384.     // Never found it
  385.     return false;
  386. }
  387. // ---------------------------------------------------------------------------
  388. //  SAXParser: Getter methods
  389. // ---------------------------------------------------------------------------
  390. const XMLValidator& SAXParser::getValidator() const
  391. {
  392.     return *fScanner->getValidator();
  393. }
  394. bool SAXParser::getDoNamespaces() const
  395. {
  396.     return fScanner->getDoNamespaces();
  397. }
  398. bool SAXParser::getExitOnFirstFatalError() const
  399. {
  400.     return fScanner->getExitOnFirstFatal();
  401. }
  402. bool SAXParser::getValidationConstraintFatal() const
  403. {
  404.     return fScanner->getValidationConstraintFatal();
  405. }
  406. SAXParser::ValSchemes SAXParser::getValidationScheme() const
  407. {
  408.     const XMLScanner::ValSchemes scheme = fScanner->getValidationScheme();
  409.     if (scheme == XMLScanner::Val_Always)
  410.         return Val_Always;
  411.     else if (scheme == XMLScanner::Val_Never)
  412.         return Val_Never;
  413.     return Val_Auto;
  414. }
  415. bool SAXParser::getDoSchema() const
  416. {
  417.     return fScanner->getDoSchema();
  418. }
  419. bool SAXParser::getValidationSchemaFullChecking() const
  420. {
  421.     return fScanner->getValidationSchemaFullChecking();
  422. }
  423. int SAXParser::getErrorCount() const
  424. {
  425.     return fScanner->getErrorCount();
  426. }
  427. XMLCh* SAXParser::getExternalSchemaLocation() const
  428. {
  429.     return fScanner->getExternalSchemaLocation();
  430. }
  431. XMLCh* SAXParser::getExternalNoNamespaceSchemaLocation() const
  432. {
  433.     return fScanner->getExternalNoNamespaceSchemaLocation();
  434. }
  435. SecurityManager* SAXParser::getSecurityManager() const
  436. {
  437.     return fScanner->getSecurityManager();
  438. }
  439. bool SAXParser::getLoadExternalDTD() const
  440. {
  441.     return fScanner->getLoadExternalDTD();
  442. }
  443. bool SAXParser::isCachingGrammarFromParse() const
  444. {
  445.     return fScanner->isCachingGrammarFromParse();
  446. }
  447. bool SAXParser::isUsingCachedGrammarInParse() const
  448. {
  449.     return fScanner->isUsingCachedGrammarInParse();
  450. }
  451. bool SAXParser::getCalculateSrcOfs() const
  452. {
  453.     return fScanner->getCalculateSrcOfs();
  454. }
  455. bool SAXParser::getStandardUriConformant() const
  456. {
  457.     return fScanner->getStandardUriConformant();
  458. }
  459. Grammar* SAXParser::getGrammar(const XMLCh* const nameSpaceKey)
  460. {
  461.     return fGrammarResolver->getGrammar(nameSpaceKey);
  462. }
  463. Grammar* SAXParser::getRootGrammar()
  464. {
  465.     return fScanner->getRootGrammar();
  466. }
  467. const XMLCh* SAXParser::getURIText(unsigned int uriId) const
  468. {
  469.     return fScanner->getURIText(uriId);
  470. }
  471. unsigned int SAXParser::getSrcOffset() const
  472. {
  473.     return fScanner->getSrcOffset();
  474. }
  475. // ---------------------------------------------------------------------------
  476. //  SAXParser: Setter methods
  477. // ---------------------------------------------------------------------------
  478. void SAXParser::setDoNamespaces(const bool newState)
  479. {
  480.     fScanner->setDoNamespaces(newState);
  481. }
  482. void SAXParser::setExitOnFirstFatalError(const bool newState)
  483. {
  484.     fScanner->setExitOnFirstFatal(newState);
  485. }
  486. void SAXParser::setValidationConstraintFatal(const bool newState)
  487. {
  488.     fScanner->setValidationConstraintFatal(newState);
  489. }
  490. void SAXParser::setValidationScheme(const ValSchemes newScheme)
  491. {
  492.     if (newScheme == Val_Never)
  493.         fScanner->setValidationScheme(XMLScanner::Val_Never);
  494.     else if (newScheme == Val_Always)
  495.         fScanner->setValidationScheme(XMLScanner::Val_Always);
  496.     else
  497.         fScanner->setValidationScheme(XMLScanner::Val_Auto);
  498. }
  499. void SAXParser::setDoSchema(const bool newState)
  500. {
  501.     fScanner->setDoSchema(newState);
  502. }
  503. void SAXParser::setValidationSchemaFullChecking(const bool schemaFullChecking)
  504. {
  505.     fScanner->setValidationSchemaFullChecking(schemaFullChecking);
  506. }
  507. void SAXParser::setExternalSchemaLocation(const XMLCh* const schemaLocation)
  508. {
  509.     fScanner->setExternalSchemaLocation(schemaLocation);
  510. }
  511. void SAXParser::setExternalNoNamespaceSchemaLocation(const XMLCh* const noNamespaceSchemaLocation)
  512. {
  513.     fScanner->setExternalNoNamespaceSchemaLocation(noNamespaceSchemaLocation);
  514. }
  515. void SAXParser::setExternalSchemaLocation(const char* const schemaLocation)
  516. {
  517.     fScanner->setExternalSchemaLocation(schemaLocation);
  518. }
  519. void SAXParser::setExternalNoNamespaceSchemaLocation(const char* const noNamespaceSchemaLocation)
  520. {
  521.     fScanner->setExternalNoNamespaceSchemaLocation(noNamespaceSchemaLocation);
  522. }
  523. void SAXParser::setSecurityManager(SecurityManager* const securityManager)
  524. {
  525.     // since this could impact various components, don't permit it to change
  526.     // during a parse
  527.     if (fParseInProgress)
  528.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  529.     fScanner->setSecurityManager(securityManager);
  530. }
  531. void SAXParser::setLoadExternalDTD(const bool newState)
  532. {
  533.     fScanner->setLoadExternalDTD(newState);
  534. }
  535. void SAXParser::cacheGrammarFromParse(const bool newState)
  536. {
  537.     fScanner->cacheGrammarFromParse(newState);
  538.     if (newState)
  539.         fScanner->useCachedGrammarInParse(newState);
  540. }
  541. void SAXParser::useCachedGrammarInParse(const bool newState)
  542. {
  543.     if (newState || !fScanner->isCachingGrammarFromParse())
  544.         fScanner->useCachedGrammarInParse(newState);
  545. }
  546. void SAXParser::setCalculateSrcOfs(const bool newState)
  547. {
  548.     fScanner->setCalculateSrcOfs(newState);
  549. }
  550. void SAXParser::setStandardUriConformant(const bool newState)
  551. {
  552.     fScanner->setStandardUriConformant(newState);
  553. }
  554. void SAXParser::useScanner(const XMLCh* const scannerName)
  555. {
  556.     XMLScanner* tempScanner = XMLScannerResolver::resolveScanner
  557.     (
  558.         scannerName
  559.         , fValidator
  560.         , fMemoryManager
  561.     );
  562.     if (tempScanner) {
  563.         tempScanner->setParseSettings(fScanner);
  564.         tempScanner->setGrammarResolver(fGrammarResolver);
  565.         tempScanner->setURIStringPool(fURIStringPool);
  566.         delete fScanner;
  567.         fScanner = tempScanner;
  568.     }
  569. }
  570. // ---------------------------------------------------------------------------
  571. //  SAXParser: Overrides of the SAX Parser interface
  572. // ---------------------------------------------------------------------------
  573. void SAXParser::parse(const InputSource& source)
  574. {
  575.     // Avoid multiple entrance
  576.     if (fParseInProgress)
  577.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  578.     try
  579.     {
  580.         fParseInProgress = true;
  581.         fScanner->scanDocument(source);
  582.         fParseInProgress = false;
  583.     }
  584.     catch (...)
  585.     {
  586.         fParseInProgress = false;
  587.         throw;
  588.     }
  589. }
  590. void SAXParser::parse(const XMLCh* const systemId)
  591. {
  592.     // Avoid multiple entrance
  593.     if (fParseInProgress)
  594.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  595.     try
  596.     {
  597.         fParseInProgress = true;
  598.         fScanner->scanDocument(systemId);
  599.         fParseInProgress = false;
  600.     }
  601.     catch (...)
  602.     {
  603.         fParseInProgress = false;
  604.         throw;
  605.     }
  606. }
  607. void SAXParser::parse(const char* const systemId)
  608. {
  609.     // Avoid multiple entrance
  610.     if (fParseInProgress)
  611.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  612.     try
  613.     {
  614.         fParseInProgress = true;
  615.         fScanner->scanDocument(systemId);
  616.         fParseInProgress = false;
  617.     }
  618.     catch (...)
  619.     {
  620.         fParseInProgress = false;
  621.         throw;
  622.     }
  623. }
  624. void SAXParser::setDocumentHandler(DocumentHandler* const handler)
  625. {
  626.     fDocHandler = handler;
  627.     if (fDocHandler)
  628.     {
  629.         //
  630.         //  Make sure we are set as the document handler with the scanner.
  631.         //  We may already be (if advanced handlers are installed), but its
  632.         //  not worthing checking, just do it.
  633.         //
  634.         fScanner->setDocHandler(this);
  635.     }
  636.      else
  637.     {
  638.         //
  639.         //  If we don't have any advanced handlers either, then deinstall us
  640.         //  from the scanner because we don't need document events anymore.
  641.         //
  642.         if (!fAdvDHCount)
  643.             fScanner->setDocHandler(0);
  644.     }
  645. }
  646. void SAXParser::setDTDHandler(DTDHandler* const handler)
  647. {
  648.     fDTDHandler = handler;
  649.     if (fDTDHandler)
  650.         fScanner->setDocTypeHandler(this);
  651.     else
  652.         fScanner->setDocTypeHandler(0);
  653. }
  654. void SAXParser::setErrorHandler(ErrorHandler* const handler)
  655. {
  656.     //
  657.     //  Store the handler. Then either install or deinstall us as the
  658.     //  error reporter on the scanner.
  659.     //
  660.     fErrorHandler = handler;
  661.     if (fErrorHandler) {
  662.         fScanner->setErrorReporter(this);
  663.         fScanner->setErrorHandler(fErrorHandler);
  664.     }
  665.     else {
  666.         fScanner->setErrorReporter(0);
  667.         fScanner->setErrorHandler(0);
  668.     }
  669. }
  670. void SAXParser::setEntityResolver(EntityResolver* const resolver)
  671. {
  672.     fEntityResolver = resolver;
  673.     if (fEntityResolver) {
  674.         fScanner->setEntityHandler(this);
  675.     }
  676.     else {
  677.         fScanner->setEntityHandler(0);
  678.     }
  679. }
  680. // ---------------------------------------------------------------------------
  681. //  SAXParser: Progressive parse methods
  682. // ---------------------------------------------------------------------------
  683. bool SAXParser::parseFirst( const   XMLCh* const    systemId
  684.                             ,       XMLPScanToken&  toFill)
  685. {
  686.     //
  687.     //  Avoid multiple entrance. We cannot enter here while a regular parse
  688.     //  is in progress.
  689.     //
  690.     if (fParseInProgress)
  691.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  692.     return fScanner->scanFirst(systemId, toFill);
  693. }
  694. bool SAXParser::parseFirst( const   char* const     systemId
  695.                             ,       XMLPScanToken&  toFill)
  696. {
  697.     //
  698.     //  Avoid multiple entrance. We cannot enter here while a regular parse
  699.     //  is in progress.
  700.     //
  701.     if (fParseInProgress)
  702.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  703.     return fScanner->scanFirst(systemId, toFill);
  704. }
  705. bool SAXParser::parseFirst( const   InputSource&    source
  706.                             ,       XMLPScanToken&  toFill)
  707. {
  708.     //
  709.     //  Avoid multiple entrance. We cannot enter here while a regular parse
  710.     //  is in progress.
  711.     //
  712.     if (fParseInProgress)
  713.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  714.     return fScanner->scanFirst(source, toFill);
  715. }
  716. bool SAXParser::parseNext(XMLPScanToken& token)
  717. {
  718.     return fScanner->scanNext(token);
  719. }
  720. void SAXParser::parseReset(XMLPScanToken& token)
  721. {
  722.     // Reset the scanner
  723.     fScanner->scanReset(token);
  724. }
  725. // ---------------------------------------------------------------------------
  726. //  SAXParser: Overrides of the XMLDocumentHandler interface
  727. // ---------------------------------------------------------------------------
  728. void SAXParser::docCharacters(  const   XMLCh* const    chars
  729.                                 , const unsigned int    length
  730.                                 , const bool            cdataSection)
  731. {
  732.     // Suppress the chars before the root element.
  733.     if (!fElemDepth)
  734.         return;
  735.     // Just map to the SAX document handler
  736.     if (fDocHandler)
  737.         fDocHandler->characters(chars, length);
  738.     //
  739.     //  If there are any installed advanced handlers, then lets call them
  740.     //  with this info.
  741.     //
  742.     for (unsigned int index = 0; index < fAdvDHCount; index++)
  743.         fAdvDHList[index]->docCharacters(chars, length, cdataSection);
  744. }
  745. void SAXParser::docComment(const XMLCh* const commentText)
  746. {
  747.     //
  748.     //  SAX has no way to report this. But, if there are any installed
  749.     //  advanced handlers, then lets call them with this info.
  750.     //
  751.     for (unsigned int index = 0; index < fAdvDHCount; index++)
  752.         fAdvDHList[index]->docComment(commentText);
  753. }
  754. void SAXParser::XMLDecl( const  XMLCh* const    versionStr
  755.                         , const XMLCh* const    encodingStr
  756.                         , const XMLCh* const    standaloneStr
  757.                         , const XMLCh* const    actualEncodingStr
  758.                         )
  759. {
  760.     //
  761.     //  SAX has no way to report this. But, if there are any installed
  762.     //  advanced handlers, then lets call them with this info.
  763.     //
  764.     for (unsigned int index = 0; index < fAdvDHCount; index++)
  765.         fAdvDHList[index]->XMLDecl( versionStr,
  766.                                     encodingStr,
  767.                                     standaloneStr,
  768.                                     actualEncodingStr );
  769. }
  770. void SAXParser::docPI(  const   XMLCh* const    target
  771.                         , const XMLCh* const    data)
  772. {
  773.     // Just map to the SAX document handler
  774.     if (fDocHandler)
  775.         fDocHandler->processingInstruction(target, data);
  776.     //
  777.     //  If there are any installed advanced handlers, then lets call them
  778.     //  with this info.
  779.     //
  780.     for (unsigned int index = 0; index < fAdvDHCount; index++)
  781.         fAdvDHList[index]->docPI(target, data);
  782. }
  783. void SAXParser::endDocument()
  784. {
  785.     if (fDocHandler)
  786.         fDocHandler->endDocument();
  787.     //
  788.     //  If there are any installed advanced handlers, then lets call them
  789.     //  with this info.
  790.     //
  791.     for (unsigned int index = 0; index < fAdvDHCount; index++)
  792.         fAdvDHList[index]->endDocument();
  793. }
  794. void SAXParser::endElement( const   XMLElementDecl& elemDecl
  795.                             , const unsigned int    uriId
  796.                             , const bool            isRoot
  797.                             , const XMLCh* const    elemPrefix)
  798. {
  799.     // Just map to the SAX document handler
  800.     if (fDocHandler) {
  801.         if (fScanner->getDoNamespaces()) {
  802.             if (elemPrefix && *elemPrefix) {
  803.                 fElemQNameBuf.set(elemPrefix);
  804.                 fElemQNameBuf.append(chColon);
  805.                 fElemQNameBuf.append(elemDecl.getBaseName());
  806.                 fDocHandler->endElement(fElemQNameBuf.getRawBuffer());
  807.             }
  808.             else {
  809.                 fDocHandler->endElement(elemDecl.getBaseName());
  810.             }
  811.         }
  812.         else
  813.             fDocHandler->endElement(elemDecl.getFullName());
  814.     }
  815.     //
  816.     //  If there are any installed advanced handlers, then lets call them
  817.     //  with this info.
  818.     //
  819.     for (unsigned int index = 0; index < fAdvDHCount; index++)
  820.         fAdvDHList[index]->endElement(elemDecl, uriId, isRoot, elemPrefix);
  821.     //
  822.     //  Dump the element depth down again. Don't let it underflow in case
  823.     //  of malformed XML.
  824.     //
  825.     if (fElemDepth)
  826.         fElemDepth--;
  827. }
  828. void SAXParser::endEntityReference(const XMLEntityDecl& entityDecl)
  829. {
  830.     //
  831.     //  SAX has no way to report this event. But, if there are any installed
  832.     //  advanced handlers, then lets call them with this info.
  833.     //
  834.     for (unsigned int index = 0; index < fAdvDHCount; index++)
  835.         fAdvDHList[index]->endEntityReference(entityDecl);
  836. }
  837. void SAXParser::ignorableWhitespace(const   XMLCh* const    chars
  838.                                     , const unsigned int    length
  839.                                     , const bool            cdataSection)
  840. {
  841.     // Do not report the whitespace before the root element.
  842.     if (!fElemDepth)
  843.         return;
  844.     // Just map to the SAX document handler
  845.     if (fDocHandler)
  846.         fDocHandler->ignorableWhitespace(chars, length);
  847.     //
  848.     //  If there are any installed advanced handlers, then lets call them
  849.     //  with this info.
  850.     //
  851.     for (unsigned int index = 0; index < fAdvDHCount; index++)
  852.         fAdvDHList[index]->ignorableWhitespace(chars, length, cdataSection);
  853. }
  854. void SAXParser::resetDocument()
  855. {
  856.     // Just map to the SAX document handler
  857.     if (fDocHandler)
  858.         fDocHandler->resetDocument();
  859.     //
  860.     //  If there are any installed advanced handlers, then lets call them
  861.     //  with this info.
  862.     //
  863.     for (unsigned int index = 0; index < fAdvDHCount; index++)
  864.         fAdvDHList[index]->resetDocument();
  865.     // Make sure our element depth flag gets set back to zero
  866.     fElemDepth = 0;
  867. }
  868. void SAXParser::startDocument()
  869. {
  870.     // Just map to the SAX document handler
  871.     if (fDocHandler)
  872.     {
  873.         fDocHandler->setDocumentLocator(fScanner->getLocator());
  874.         fDocHandler->startDocument();
  875.     }
  876.     //
  877.     //  If there are any installed advanced handlers, then lets call them
  878.     //  with this info.
  879.     //
  880.     for (unsigned int index = 0; index < fAdvDHCount; index++)
  881.         fAdvDHList[index]->startDocument();
  882. }
  883. void SAXParser::
  884. startElement(   const   XMLElementDecl&         elemDecl
  885.                 , const unsigned int            elemURLId
  886.                 , const XMLCh* const            elemPrefix
  887.                 , const RefVectorOf<XMLAttr>&   attrList
  888.                 , const unsigned int            attrCount
  889.                 , const bool                    isEmpty
  890.                 , const bool                    isRoot)
  891. {
  892.     // Bump the element depth counter if not empty
  893.     if (!isEmpty)
  894.         fElemDepth++;
  895.     if (fDocHandler)
  896.     {
  897.         fAttrList.setVector(&attrList, attrCount);
  898.         if (fScanner->getDoNamespaces()) {
  899.             if (elemPrefix && *elemPrefix) {
  900.                 fElemQNameBuf.set(elemPrefix);
  901.                 fElemQNameBuf.append(chColon);
  902.                 fElemQNameBuf.append(elemDecl.getBaseName());
  903.                 fDocHandler->startElement(fElemQNameBuf.getRawBuffer(), fAttrList);
  904.                 // If its empty, send the end tag event now
  905.                 if (isEmpty)
  906.                     fDocHandler->endElement(fElemQNameBuf.getRawBuffer());
  907.             }
  908.             else {
  909.                 fDocHandler->startElement(elemDecl.getBaseName(), fAttrList);
  910.                 // If its empty, send the end tag event now
  911.                 if (isEmpty)
  912.                     fDocHandler->endElement(elemDecl.getBaseName());
  913.             }
  914.         }
  915.         else {
  916.             fDocHandler->startElement(elemDecl.getFullName(), fAttrList);
  917.             // If its empty, send the end tag event now
  918.             if (isEmpty)
  919.                 fDocHandler->endElement(elemDecl.getFullName());
  920.         }
  921.     }
  922.     //
  923.     //  If there are any installed advanced handlers, then lets call them
  924.     //  with this info.
  925.     //
  926.     for (unsigned int index = 0; index < fAdvDHCount; index++)
  927.     {
  928.         fAdvDHList[index]->startElement
  929.         (
  930.             elemDecl
  931.             , elemURLId
  932.             , elemPrefix
  933.             , attrList
  934.             , attrCount
  935.             , isEmpty
  936.             , isRoot
  937.         );
  938.     }
  939. }
  940. void SAXParser::startEntityReference(const XMLEntityDecl& entityDecl)
  941. {
  942.     //
  943.     //  SAX has no way to report this. But, If there are any installed
  944.     //  advanced handlers, then lets call them with this info.
  945.     //
  946.     for (unsigned int index = 0; index < fAdvDHCount; index++)
  947.         fAdvDHList[index]->startEntityReference(entityDecl);
  948. }
  949. // ---------------------------------------------------------------------------
  950. //  SAXParser: Overrides of the DocTypeHandler interface
  951. // ---------------------------------------------------------------------------
  952. void SAXParser::attDef( const   DTDElementDecl& elemDecl
  953.                         , const DTDAttDef&      attDef
  954.                         , const bool            ignoring)
  955. {
  956.     // Unused by SAX DTDHandler interface at this time
  957. }
  958. void SAXParser::doctypeComment(const XMLCh* const)
  959. {
  960.     // Unused by SAX DTDHandler interface at this time
  961. }
  962. void SAXParser::doctypeDecl(const   DTDElementDecl& elemDecl
  963.                             , const XMLCh* const    publicId
  964.                             , const XMLCh* const    systemId
  965.                             , const bool            hasIntSubset
  966.                             , const bool            hasExtSubset)
  967. {
  968.     // Unused by SAX DTDHandler interface at this time
  969. }
  970. void SAXParser::doctypePI(  const   XMLCh* const
  971.                             , const XMLCh* const)
  972. {
  973.     // Unused by SAX DTDHandler interface at this time
  974. }
  975. void SAXParser::doctypeWhitespace(  const   XMLCh* const    chars
  976.                                     , const unsigned int    length)
  977. {
  978.     // Unused by SAX DTDHandler interface at this time
  979. }
  980. void SAXParser::elementDecl(const DTDElementDecl&, const bool)
  981. {
  982.     // Unused by SAX DTDHandler interface at this time
  983. }
  984. void SAXParser::endAttList(const DTDElementDecl&)
  985. {
  986.     // Unused by SAX DTDHandler interface at this time
  987. }
  988. void SAXParser::endIntSubset()
  989. {
  990.     // Unused by SAX DTDHandler interface at this time
  991. }
  992. void SAXParser::endExtSubset()
  993. {
  994.     // Unused by SAX DTDHandler interface at this time
  995. }
  996. void SAXParser::entityDecl( const   DTDEntityDecl&  entityDecl
  997.                             , const bool            isPEDecl
  998.                             , const bool            isIgnored)
  999. {
  1000.     //
  1001.     //  If we have a DTD handler, and this entity is not ignored, and
  1002.     //  its an unparsed entity, then send this one.
  1003.     //
  1004.     if (fDTDHandler && !isIgnored)
  1005.     {
  1006.         if (entityDecl.isUnparsed())
  1007.         {
  1008.             fDTDHandler->unparsedEntityDecl
  1009.             (
  1010.                 entityDecl.getName()
  1011.                 , entityDecl.getPublicId()
  1012.                 , entityDecl.getSystemId()
  1013.                 , entityDecl.getNotationName()
  1014.             );
  1015.         }
  1016.     }
  1017. }
  1018. void SAXParser::resetDocType()
  1019. {
  1020.     // Just map to the DTD handler
  1021.     if (fDTDHandler)
  1022.         fDTDHandler->resetDocType();
  1023. }
  1024. void SAXParser::notationDecl(   const   XMLNotationDecl&    notDecl
  1025.                                 , const bool                isIgnored)
  1026. {
  1027.     if (fDTDHandler && !isIgnored)
  1028.     {
  1029.         fDTDHandler->notationDecl
  1030.         (
  1031.             notDecl.getName()
  1032.             , notDecl.getPublicId()
  1033.             , notDecl.getSystemId()
  1034.         );
  1035.     }
  1036. }
  1037. void SAXParser::startAttList(const DTDElementDecl&)
  1038. {
  1039.     // Unused by SAX DTDHandler interface at this time
  1040. }
  1041. void SAXParser::startIntSubset()
  1042. {
  1043.     // Unused by SAX DTDHandler interface at this time
  1044. }
  1045. void SAXParser::startExtSubset()
  1046. {
  1047.     // Unused by SAX DTDHandler interface at this time
  1048. }
  1049. void SAXParser::TextDecl(   const  XMLCh* const
  1050.                             , const XMLCh* const)
  1051. {
  1052.     // Unused by SAX DTDHandler interface at this time
  1053. }
  1054. // ---------------------------------------------------------------------------
  1055. //  SAXParser: Overrides of the XMLErrorReporter interface
  1056. // ---------------------------------------------------------------------------
  1057. void SAXParser::resetErrors()
  1058. {
  1059.     if (fErrorHandler)
  1060.         fErrorHandler->resetErrors();
  1061. }
  1062. void SAXParser::error(  const   unsigned int                code
  1063.                         , const XMLCh* const                msgDomain
  1064.                         , const XMLErrorReporter::ErrTypes  errType
  1065.                         , const XMLCh* const                errorText
  1066.                         , const XMLCh* const                systemId
  1067.                         , const XMLCh* const                publicId
  1068.                         , const XMLSSize_t                  lineNum
  1069.                         , const XMLSSize_t                  colNum)
  1070. {
  1071.     SAXParseException toThrow = SAXParseException
  1072.     (
  1073.         errorText
  1074.         , publicId
  1075.         , systemId
  1076.         , lineNum
  1077.         , colNum
  1078.     );
  1079.     if (!fErrorHandler)
  1080.     {
  1081.         if (errType == XMLErrorReporter::ErrType_Fatal)
  1082.             throw toThrow;
  1083.         else
  1084.             return;
  1085.     }
  1086.     if (errType == XMLErrorReporter::ErrType_Warning)
  1087.         fErrorHandler->warning(toThrow);
  1088.     else if (errType == XMLErrorReporter::ErrType_Fatal)
  1089.         fErrorHandler->fatalError(toThrow);
  1090.     else
  1091.         fErrorHandler->error(toThrow);
  1092. }
  1093. // ---------------------------------------------------------------------------
  1094. //  SAXParser: Handlers for the XMLEntityHandler interface
  1095. // ---------------------------------------------------------------------------
  1096. void SAXParser::endInputSource(const InputSource&)
  1097. {
  1098. }
  1099. bool SAXParser::expandSystemId(const XMLCh* const, XMLBuffer&)
  1100. {
  1101.     return false;
  1102. }
  1103. void SAXParser::resetEntities()
  1104. {
  1105.     // Nothing to do for this one
  1106. }
  1107. InputSource*
  1108. SAXParser::resolveEntity(   const   XMLCh* const    publicId
  1109.                             , const XMLCh* const    systemId
  1110.                             , const XMLCh* const    baseURI)
  1111. {
  1112.     // Just map to the SAX entity resolver handler
  1113.     if (fEntityResolver)
  1114.         return fEntityResolver->resolveEntity(publicId, systemId);
  1115.     return 0;
  1116. }
  1117. void SAXParser::startInputSource(const InputSource&)
  1118. {
  1119.     // Nothing to do for this one
  1120. }
  1121. // ---------------------------------------------------------------------------
  1122. //  SAXParser: Deprecated methods
  1123. // ---------------------------------------------------------------------------
  1124. bool SAXParser::getDoValidation() const
  1125. {
  1126.     //
  1127.     //  We don't want to tie the public parser classes to the enum used
  1128.     //  by the scanner, so we use a separate one and map.
  1129.     //
  1130.     //  DON'T mix the new and old methods!!
  1131.     //
  1132.     const XMLScanner::ValSchemes scheme = fScanner->getValidationScheme();
  1133.     if (scheme == XMLScanner::Val_Always)
  1134.         return true;
  1135.     return false;
  1136. }
  1137. void SAXParser::setDoValidation(const bool newState)
  1138. {
  1139.     fScanner->setDoValidation
  1140.     (
  1141.         newState ? XMLScanner::Val_Always : XMLScanner::Val_Never
  1142.     );
  1143. }
  1144. // ---------------------------------------------------------------------------
  1145. //  SAXParser: Grammar preparsing methods
  1146. // ---------------------------------------------------------------------------
  1147. Grammar* SAXParser::loadGrammar(const char* const systemId,
  1148.                                 const short grammarType,
  1149.                                 const bool toCache)
  1150. {
  1151.     // Avoid multiple entrance
  1152.     if (fParseInProgress)
  1153.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  1154.     Grammar* grammar = 0;
  1155.     try
  1156.     {
  1157.         fParseInProgress = true;
  1158.         grammar = fScanner->loadGrammar(systemId, grammarType, toCache);
  1159.         fParseInProgress = false;
  1160.     }
  1161.     catch(...)
  1162.     {
  1163.         fParseInProgress = false;
  1164.         throw;
  1165.     }
  1166.     return grammar;
  1167. }
  1168. Grammar* SAXParser::loadGrammar(const XMLCh* const systemId,
  1169.                                 const short grammarType,
  1170.                                 const bool toCache)
  1171. {
  1172.     // Avoid multiple entrance
  1173.     if (fParseInProgress)
  1174.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  1175.     Grammar* grammar = 0;
  1176.     try
  1177.     {
  1178.         fParseInProgress = true;
  1179.         grammar = fScanner->loadGrammar(systemId, grammarType, toCache);
  1180.         fParseInProgress = false;
  1181.     }
  1182.     catch(...)
  1183.     {
  1184.         fParseInProgress = false;
  1185.         throw;
  1186.     }
  1187.     return grammar;
  1188. }
  1189. Grammar* SAXParser::loadGrammar(const InputSource& source,
  1190.                                 const short grammarType,
  1191.                                 const bool toCache)
  1192. {
  1193.     // Avoid multiple entrance
  1194.     if (fParseInProgress)
  1195.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  1196.     Grammar* grammar = 0;
  1197.     try
  1198.     {
  1199.         fParseInProgress = true;
  1200.         grammar = fScanner->loadGrammar(source, grammarType, toCache);
  1201.         fParseInProgress = false;
  1202.     }
  1203.     catch(...)
  1204.     {
  1205.         fParseInProgress = false;
  1206.         throw;
  1207.     }
  1208.     return grammar;
  1209. }
  1210. void SAXParser::resetCachedGrammarPool()
  1211. {
  1212.     fGrammarResolver->resetCachedGrammar();
  1213. }
  1214. XERCES_CPP_NAMESPACE_END