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

词法分析

开发平台:

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: SAX2XMLReaderImpl.cpp,v $
  58.  * Revision 1.21  2003/05/18 14:02:05  knoaman
  59.  * Memory manager implementation: pass per instance manager.
  60.  *
  61.  * Revision 1.20  2003/05/16 21:36:59  knoaman
  62.  * Memory manager implementation: Modify constructors to pass in the memory manager.
  63.  *
  64.  * Revision 1.19  2003/05/16 06:01:52  knoaman
  65.  * Partial implementation of the configurable memory manager.
  66.  *
  67.  * Revision 1.18  2003/05/15 18:26:50  knoaman
  68.  * Partial implementation of the configurable memory manager.
  69.  *
  70.  * Revision 1.17  2003/04/17 21:58:50  neilg
  71.  * Adding a new property,
  72.  * http://apache.org/xml/properties/security-manager, with
  73.  * appropriate getSecurityManager/setSecurityManager methods on DOM
  74.  * and SAX parsers.  Also adding a new SecurityManager class.
  75.  *
  76.  * The purpose of these modifications is to permit applications a
  77.  * means to have the parser reject documents whose processing would
  78.  * otherwise consume large amounts of system resources.  Malicious
  79.  * use of such documents could be used to launch a denial-of-service
  80.  * attack against a system running the parser.  Initially, the
  81.  * SecurityManager only knows about attacks that can result from
  82.  * exponential entity expansion; this is the only known attack that
  83.  * involves processing a single XML document.  Other, simlar attacks
  84.  * can be launched if arbitrary schemas may be parsed; there already
  85.  * exist means (via use of the EntityResolver interface) by which
  86.  * applications can deny processing of untrusted schemas.  In future,
  87.  * the SecurityManager will be expanded to take these other exploits
  88.  * into account.
  89.  *
  90.  * Adding SecurityManager support
  91.  * 
  92.  * Revision 1.16  2003/01/03 20:09:36  tng
  93.  * New feature StandardUriConformant to force strict standard uri conformance.
  94.  *
  95.  * Revision 1.15  2002/12/27 16:16:51  knoaman
  96.  * Set scanner options and handlers.
  97.  *
  98.  * Revision 1.14  2002/12/11 22:14:54  knoaman
  99.  * Performance: no need to use temporary buffer to hold namespace value.
  100.  *
  101.  * Revision 1.13  2002/12/04 01:57:09  knoaman
  102.  * Scanner re-organization.
  103.  *
  104.  * Revision 1.12  2002/11/04 14:57:03  tng
  105.  * C++ Namespace Support.
  106.  *
  107.  * Revision 1.11  2002/09/24 20:00:32  tng
  108.  * Performance: use XMLString::equals instead of XMLString::compareString
  109.  *
  110.  * Revision 1.10  2002/08/14 15:20:38  knoaman
  111.  * [Bug 3111] Problem with LexicalHandler::startDTD() and LexicalHandler::endDTD().
  112.  *
  113.  * Revision 1.9  2002/07/11 18:27:20  knoaman
  114.  * Grammar caching/preparsing - initial implementation.
  115.  *
  116.  * Revision 1.8  2002/06/17 15:41:15  tng
  117.  * To be consistent, SAX2 is updated with:
  118.  * 1. the progressive parse methods should use the fReuseGrammar flag set from setFeature instead of using parameter
  119.  * 2. add feature "http://apache.org/xml/features/continue-after-fatal-error", and users should use setFeature instead of setExitOnFirstFatalError
  120.  * 3. add feature "http://apache.org/xml/features/validation-error-as-fatal", and users should use setFeature instead of setValidationConstraintFatal
  121.  *
  122.  * Revision 1.7  2002/05/30 16:20:09  tng
  123.  * Add feature to optionally ignore external DTD.
  124.  *
  125.  * Revision 1.6  2002/05/29 21:37:47  knoaman
  126.  * Add baseURI to resolveEntity to support DOMInputSource.
  127.  *
  128.  * Revision 1.5  2002/05/28 20:44:14  tng
  129.  * [Bug 9104] prefixes dissapearing when schema validation turned on.
  130.  *
  131.  * Revision 1.4  2002/05/27 18:39:21  tng
  132.  * To get ready for 64 bit large file, use XMLSSize_t to represent line and column number.
  133.  *
  134.  * Revision 1.3  2002/05/22 20:53:41  knoaman
  135.  * Prepare for DOM L3 :
  136.  * - Make use of the XMLEntityHandler/XMLErrorReporter interfaces, instead of using
  137.  * EntityHandler/ErrorHandler directly.
  138.  * - Add 'AbstractDOMParser' class to provide common functionality for XercesDOMParser
  139.  * and DOMBuilder.
  140.  *
  141.  * Revision 1.2  2002/02/13 16:09:24  knoaman
  142.  * Move SAX2 features/properties names constants to XMLUni.
  143.  *
  144.  * Revision 1.1.1.1  2002/02/01 22:22:06  peiyongz
  145.  * sane_include
  146.  *
  147.  * Revision 1.25  2002/01/28 17:47:41  knoaman
  148.  * Some SAX calls were not passed to the LexicalHandler.
  149.  *
  150.  * Revision 1.24  2002/01/28 17:08:47  knoaman
  151.  * SAX2-ext's DeclHandler support.
  152.  *
  153.  * Revision 1.23  2002/01/28 16:29:21  knoaman
  154.  * The namespace-prefixes feature in SAX2 should be off by default.
  155.  *
  156.  * Revision 1.22  2002/01/24 16:30:34  tng
  157.  * [Bug 3111] Problem with LexicalHandler::startDTD() and LexicalHandler::endDTD() .
  158.  *
  159.  * Revision 1.21  2001/12/21 18:03:25  tng
  160.  * [Bug 1833] LexicalHandler::startDTD not called correctly.
  161.  *
  162.  * Revision 1.20  2001/11/20 18:51:44  tng
  163.  * 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).
  164.  *
  165.  * Revision 1.19  2001/10/25 19:46:15  tng
  166.  * Comment outside root element should also be reported.
  167.  *
  168.  * Revision 1.18  2001/09/12 13:03:43  tng
  169.  * [Bug 3155] SAX2 does not offer progressive parse.
  170.  *
  171.  * Revision 1.17  2001/08/02 19:00:46  tng
  172.  * [Bug 1329] SAX2XMLReaderImpl leaks XMLBuffers.
  173.  *
  174.  * Revision 1.16  2001/08/01 19:11:02  tng
  175.  * Add full schema constraint checking flag to the samples and the parser.
  176.  *
  177.  * Revision 1.15  2001/06/27 17:39:50  knoaman
  178.  * Fix for bug #2353.
  179.  *
  180.  * Revision 1.14  2001/06/19 16:45:08  tng
  181.  * Add installAdvDocHandler to SAX2XMLReader as the code is there already.
  182.  *
  183.  * Revision 1.13  2001/06/03 19:26:19  jberry
  184.  * Add support for querying error count following parse; enables simple parse without requiring error handler.
  185.  *
  186.  * Revision 1.12  2001/05/11 13:26:21  tng
  187.  * Copyright update.
  188.  *
  189.  * Revision 1.11  2001/05/03 20:34:33  tng
  190.  * Schema: SchemaValidator update
  191.  *
  192.  * Revision 1.10  2001/03/30 16:46:57  tng
  193.  * Schema: Use setDoSchema instead of setSchemaValidation which makes more sense.
  194.  *
  195.  * Revision 1.9  2001/03/21 21:56:08  tng
  196.  * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
  197.  *
  198.  * Revision 1.8  2001/02/15 15:56:29  tng
  199.  * Schema: Add setSchemaValidation and getSchemaValidation for DOMParser and SAXParser.
  200.  * Add feature "http://apache.org/xml/features/validation/schema" for SAX2XMLReader.
  201.  * New data field  fSchemaValidation in XMLScanner as the flag.
  202.  *
  203.  * Revision 1.7  2001/01/15 21:26:33  tng
  204.  * Performance Patches by David Bertoni.
  205.  *
  206.  * Details: (see xerces-c-dev mailing Jan 14)
  207.  * XMLRecognizer.cpp: the internal encoding string XMLUni::fgXMLChEncodingString
  208.  * was going through this function numerous times.  As a result, the top hot-spot
  209.  * for the parse was _wcsicmp().  The real problem is that the Microsofts wide string
  210.  * functions are unbelievably slow.  For things like encodings, it might be
  211.  * better to use a special comparison function that only considers a-z and
  212.  * A-Z as characters with case.  This works since the character set for
  213.  * encodings is limit to printable ASCII characters.
  214.  *
  215.  *  XMLScanner2.cpp: This also has some case-sensitive vs. insensitive compares.
  216.  * They are also much faster.  The other tweak is to only make a copy of an attribute
  217.  * string if it needs to be split.  And then, the strategy is to try to use a
  218.  * stack-based buffer, rather than a dynamically-allocated one.
  219.  *
  220.  * SAX2XMLReaderImpl.cpp: Again, more case-sensitive vs. insensitive comparisons.
  221.  *
  222.  * KVStringPair.cpp & hpp: By storing the size of the allocation, the storage can
  223.  * likely be re-used many times, cutting down on dynamic memory allocations.
  224.  *
  225.  * XMLString.hpp: a more efficient implementation of stringLen().
  226.  *
  227.  * DTDValidator.cpp: another case of using a stack-based buffer when possible
  228.  *
  229.  * These patches made a big difference in parse time in some of our test
  230.  * files, especially the ones are very attribute-heavy.
  231.  *
  232.  * Revision 1.6  2000/12/22 20:41:52  tng
  233.  * XMLUni::fgEmptyString which is defined as "EMPTY" is incorrectly used as an empty string; in fact XMLUni::fgZeroLenString should be used instead
  234.  *
  235.  * Revision 1.5  2000/12/22 15:16:51  tng
  236.  * SAX2-ext's LexicalHandler support added by David Bertoni.
  237.  *
  238.  * Revision 1.4  2000/08/09 23:39:58  jpolast
  239.  * should be namespace-prefixes; not namespaces-prefixes
  240.  *
  241.  * Revision 1.3  2000/08/09 22:16:12  jpolast
  242.  * many conformance & stability changes:
  243.  *   - ContentHandler::resetDocument() removed
  244.  *   - attrs param of ContentHandler::startDocument() made const
  245.  *   - SAXExceptions thrown now have msgs
  246.  *   - removed duplicate function signatures that had 'const'
  247.  *       [ eg: getContentHander() ]
  248.  *   - changed getFeature and getProperty to apply to const objs
  249.  *   - setProperty now takes a void* instead of const void*
  250.  *   - SAX2XMLReaderImpl does not inherit from SAXParser anymore
  251.  *   - Reuse Validator (http://apache.org/xml/features/reuse-validator) implemented
  252.  *   - Features & Properties now read-only during parse
  253.  *
  254.  * Revision 1.2  2000/08/07 22:53:44  jpolast
  255.  * fixes for when 'namespaces' feature is turned off:
  256.  *   * namespaces-prefixes only used when namespaces is on
  257.  *   * URIs not looked up when namespaces is off, blank string instead
  258.  *   * default validation scheme is validation on, auto-validation off.
  259.  *
  260.  * Revision 1.1  2000/08/02 18:04:41  jpolast
  261.  * initial checkin of sax2 implemenation
  262.  * submitted by Simon Fell (simon@fell.com)
  263.  * and Joe Polastre (jpolast@apache.org)
  264.  *
  265.  *
  266.  */
  267. #include <xercesc/util/IOException.hpp>
  268. #include <xercesc/util/XMLChTranscoder.hpp>
  269. #include <xercesc/util/RefStackOf.hpp>
  270. #include <xercesc/util/XMLUniDefs.hpp>
  271. #include <xercesc/util/Janitor.hpp>
  272. #include <xercesc/sax2/ContentHandler.hpp>
  273. #include <xercesc/sax2/LexicalHandler.hpp>
  274. #include <xercesc/sax2/DeclHandler.hpp>
  275. #include <xercesc/sax/DTDHandler.hpp>
  276. #include <xercesc/sax/ErrorHandler.hpp>
  277. #include <xercesc/sax/EntityResolver.hpp>
  278. #include <xercesc/sax/SAXParseException.hpp>
  279. #include <xercesc/sax/SAXException.hpp>
  280. #include <xercesc/internal/XMLScannerResolver.hpp>
  281. #include <xercesc/parsers/SAX2XMLReaderImpl.hpp>
  282. #include <xercesc/validators/common/GrammarResolver.hpp>
  283. #include <string.h>
  284. XERCES_CPP_NAMESPACE_BEGIN
  285. const XMLCh gDTDEntityStr[] =
  286. {
  287.     chOpenSquare, chLatin_d, chLatin_t, chLatin_d, chCloseSquare, chNull
  288. };
  289. SAX2XMLReaderImpl::SAX2XMLReaderImpl(MemoryManager* const manager) :
  290.     fNamespacePrefix(false)
  291.     , fAutoValidation(false)
  292.     , fValidation(true)
  293.     , fParseInProgress(false)
  294.     , fHasExternalSubset(false)
  295.     , fElemDepth(0)
  296.     , fAdvDHCount(0)
  297.     , fAdvDHListSize(32)
  298.     , fDocHandler(0)
  299.     , fTempAttrVec(0)
  300.     , fPrefixes(0)
  301.     , fPrefixCounts(0)
  302.     , fDTDHandler(0)
  303.     , fEntityResolver(0)
  304.     , fErrorHandler(0)
  305.     , fLexicalHandler(0)
  306.     , fDeclHandler(0)
  307.     , fAdvDHList(0)
  308.     , fScanner(0)
  309.     , fGrammarResolver(0)
  310.     , fURIStringPool(0)
  311.     , fValidator(0)
  312.     , fMemoryManager(manager)
  313.     , fStringBuffers(manager)
  314. {
  315.     try
  316.     {
  317.         initialize();
  318.     }
  319.     catch(...)
  320.     {
  321.         cleanUp();
  322.         throw;
  323.     }
  324. }
  325. SAX2XMLReaderImpl::~SAX2XMLReaderImpl()
  326. {
  327.     cleanUp();
  328. }
  329. // ---------------------------------------------------------------------------
  330. //  SAX2XMLReaderImpl: Initialize/Cleanup methods
  331. // ---------------------------------------------------------------------------
  332. void SAX2XMLReaderImpl::initialize()
  333. {
  334.     // Create grammar resolver and string pool that we pass to the scanner
  335.     fGrammarResolver = new (fMemoryManager) GrammarResolver(fMemoryManager);
  336.     fURIStringPool = new (fMemoryManager) XMLStringPool(109, fMemoryManager);
  337.     //  Create a scanner and tell it what validator to use. Then set us
  338.     //  as the document event handler so we can fill the DOM document.
  339.     fScanner = XMLScannerResolver::getDefaultScanner(0, fMemoryManager);
  340.     fScanner->setGrammarResolver(fGrammarResolver);
  341.     fScanner->setURIStringPool(fURIStringPool);
  342.     // Create the initial advanced handler list array and zero it out
  343.     fAdvDHList = (XMLDocumentHandler**) fMemoryManager->allocate
  344.     (
  345.         fAdvDHListSize * sizeof(XMLDocumentHandler*)
  346.     );//new XMLDocumentHandler*[fAdvDHListSize];
  347.     memset(fAdvDHList, 0, sizeof(void*) * fAdvDHListSize);
  348. // SAX2 default is for namespaces (feature http://xml.org/sax/features/namespaces) to be on
  349. setDoNamespaces(true) ;
  350. // default: schema is on
  351. setDoSchema(true);
  352. fPrefixes    = new (fMemoryManager) RefStackOf<XMLBuffer> (10, false, fMemoryManager) ;
  353. fTempAttrVec  = new (fMemoryManager) RefVectorOf<XMLAttr>  (10, false, fMemoryManager) ;
  354. fPrefixCounts = new (fMemoryManager) ValueStackOf<unsigned int>(10, fMemoryManager) ;
  355. }
  356. void SAX2XMLReaderImpl::cleanUp()
  357. {
  358.     fMemoryManager->deallocate(fAdvDHList);//delete [] fAdvDHList;
  359.     delete fScanner;
  360.     delete fPrefixes;
  361.     delete fTempAttrVec;
  362.     delete fPrefixCounts;
  363.     delete fGrammarResolver;
  364.     delete fURIStringPool;
  365. }
  366. // ---------------------------------------------------------------------------
  367. //  SAX2XMLReaderImpl: Advanced document handler list maintenance methods
  368. // ---------------------------------------------------------------------------
  369. void SAX2XMLReaderImpl::installAdvDocHandler(XMLDocumentHandler* const toInstall)
  370. {
  371.     // See if we need to expand and do so now if needed
  372.     if (fAdvDHCount == fAdvDHListSize)
  373.     {
  374.         // Calc a new size and allocate the new temp buffer
  375.         const unsigned int newSize = (unsigned int)(fAdvDHListSize * 1.5);
  376.         XMLDocumentHandler** newList = (XMLDocumentHandler**) fMemoryManager->allocate
  377.         (
  378.             newSize * sizeof(XMLDocumentHandler*)
  379.         );//new XMLDocumentHandler*[newSize];
  380.         // Copy over the old data to the new list and zero out the rest
  381.         memcpy(newList, fAdvDHList, sizeof(void*) * fAdvDHListSize);
  382.         memset
  383.         (
  384.             &newList[fAdvDHListSize]
  385.             , 0
  386.             , sizeof(void*) * (newSize - fAdvDHListSize)
  387.         );
  388.         // And now clean up the old array and store the new stuff
  389.         fMemoryManager->deallocate(fAdvDHList);//delete [] fAdvDHList;
  390.         fAdvDHList = newList;
  391.         fAdvDHListSize = newSize;
  392.     }
  393.     // Add this new guy into the empty slot
  394.     fAdvDHList[fAdvDHCount++] = toInstall;
  395.     //
  396.     //  Install ourself as the document handler with the scanner. We might
  397.     //  already be, but its not worth checking, just do it.
  398.     //
  399.     fScanner->setDocHandler(this);
  400. }
  401. bool SAX2XMLReaderImpl::removeAdvDocHandler(XMLDocumentHandler* const toRemove)
  402. {
  403.     // If our count is zero, can't be any installed
  404.     if (!fAdvDHCount)
  405.         return false;
  406.     //
  407.     //  Search the array until we find this handler. If we find a null entry
  408.     //  first, we can stop there before the list is kept contiguous.
  409.     //
  410.     unsigned int index;
  411.     for (index = 0; index < fAdvDHCount; index++)
  412.     {
  413.         //
  414.         //  We found it. We have to keep the list contiguous, so we have to
  415.         //  copy down any used elements after this one.
  416.         //
  417.         if (fAdvDHList[index] == toRemove)
  418.         {
  419.             //
  420.             //  Optimize if only one entry (pretty common). Otherwise, we
  421.             //  have to copy them down to compact them.
  422.             //
  423.             if (fAdvDHCount > 1)
  424.             {
  425.                 index++;
  426.                 while (index < fAdvDHCount)
  427.                     fAdvDHList[index - 1] = fAdvDHList[index];
  428.             }
  429.             // Bump down the count and zero out the last one
  430.             fAdvDHCount--;
  431.             fAdvDHList[fAdvDHCount] = 0;
  432.             //
  433.             //  If this leaves us with no advanced handlers and there is
  434.             //  no SAX doc handler installed on us, then remove us from the
  435.             //  scanner as the document handler.
  436.             //
  437.             if (!fAdvDHCount && !fDocHandler)
  438.                 fScanner->setDocHandler(0);
  439.             return true;
  440.         }
  441.     }
  442.     // Never found it
  443.     return false;
  444. }
  445. // ---------------------------------------------------------------------------
  446. //  SAX2XMLReaderImpl Validator functions
  447. // ---------------------------------------------------------------------------
  448. void SAX2XMLReaderImpl::setValidator(XMLValidator* valueToAdopt)
  449. {
  450.     fValidator = valueToAdopt;
  451. fScanner->setValidator(valueToAdopt);
  452. }
  453. XMLValidator* SAX2XMLReaderImpl::getValidator() const
  454. {
  455. return fScanner->getValidator();
  456. }
  457. // ---------------------------------------------------------------------------
  458. //  SAX2XMLReader Interface
  459. // ---------------------------------------------------------------------------
  460. int SAX2XMLReaderImpl::getErrorCount() const
  461. {
  462.     return fScanner->getErrorCount();
  463. }
  464. void SAX2XMLReaderImpl::setContentHandler(ContentHandler* const handler)
  465. {
  466. fDocHandler = handler;
  467.     if (fDocHandler)
  468.     {
  469.         //
  470.         //  Make sure we are set as the document handler with the scanner.
  471.         //  We may already be (if advanced handlers are installed), but its
  472.         //  not worthing checking, just do it.
  473.         //
  474.         fScanner->setDocHandler(this);
  475.     }
  476.      else
  477.     {
  478.         //
  479.         //  If we don't have any advanced handlers either, then deinstall us
  480.         //  from the scanner because we don't need document events anymore.
  481.         //
  482.         if (!fAdvDHCount)
  483.             fScanner->setDocHandler(0);
  484.     }
  485. }
  486. void SAX2XMLReaderImpl::setDTDHandler(DTDHandler* const handler)
  487. {
  488.     fDTDHandler = handler;
  489.     if (fDTDHandler)
  490.         fScanner->setDocTypeHandler(this);
  491.     else
  492.         fScanner->setDocTypeHandler(0);
  493. }
  494. void SAX2XMLReaderImpl::setErrorHandler(ErrorHandler* const handler)
  495. {
  496.     //
  497.     //  Store the handler. Then either install or deinstall us as the
  498.     //  error reporter on the scanner.
  499.     //
  500.     fErrorHandler = handler;
  501.     if (fErrorHandler) {
  502.         fScanner->setErrorReporter(this);
  503.         fScanner->setErrorHandler(fErrorHandler);
  504.     }
  505.     else {
  506.         fScanner->setErrorReporter(0);
  507.         fScanner->setErrorHandler(0);
  508.     }
  509. }
  510. void SAX2XMLReaderImpl::setLexicalHandler(LexicalHandler* const handler)
  511. {
  512.     fLexicalHandler = handler;
  513.     if (fLexicalHandler)
  514.         fScanner->setDocTypeHandler(this);
  515.     else
  516.         fScanner->setDocTypeHandler(0);
  517. }
  518. void SAX2XMLReaderImpl::setDeclarationHandler(DeclHandler* const handler)
  519. {
  520.     fDeclHandler = handler;
  521.     if (fDeclHandler)
  522.         fScanner->setDocTypeHandler(this);
  523.     else
  524.         fScanner->setDocTypeHandler(0);
  525. }
  526. void SAX2XMLReaderImpl::setEntityResolver(EntityResolver* const resolver)
  527. {
  528.     fEntityResolver = resolver;
  529.     if (fEntityResolver) {
  530.         fScanner->setEntityHandler(this);
  531.     }
  532.     else {
  533.         fScanner->setEntityHandler(0);
  534.     }
  535. }
  536. void SAX2XMLReaderImpl::setExitOnFirstFatalError(const bool newState)
  537. {
  538.     fScanner->setExitOnFirstFatal(newState);
  539. }
  540. void SAX2XMLReaderImpl::setValidationConstraintFatal(const bool newState)
  541. {
  542.     fScanner->setValidationConstraintFatal(newState);
  543. }
  544. void SAX2XMLReaderImpl::parse (const   InputSource&    source)
  545. {
  546.     // Avoid multiple entrance
  547.     if (fParseInProgress)
  548.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  549.     try
  550.     {
  551.         fParseInProgress = true;
  552.         fScanner->scanDocument(source);
  553.         fParseInProgress = false;
  554.     }
  555.     catch (...)
  556.     {
  557.         fParseInProgress = false;
  558.         throw;
  559.     }
  560. }
  561. void SAX2XMLReaderImpl::parse (const   XMLCh* const    systemId)
  562. {
  563.     // Avoid multiple entrance
  564.     if (fParseInProgress)
  565.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  566.     try
  567.     {
  568.         fParseInProgress = true;
  569.         fScanner->scanDocument(systemId);
  570.         fParseInProgress = false;
  571.     }
  572.     catch (...)
  573.     {
  574.         fParseInProgress = false;
  575.         throw;
  576.     }
  577. }
  578. void SAX2XMLReaderImpl::parse (const   char* const     systemId)
  579. {
  580.     // Avoid multiple entrance
  581.     if (fParseInProgress)
  582.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  583.     try
  584.     {
  585.         fParseInProgress = true;
  586.         fScanner->scanDocument(systemId);
  587.         fParseInProgress = false;
  588.     }
  589.     catch (...)
  590.     {
  591.         fParseInProgress = false;
  592.         throw;
  593.     }
  594. }
  595. // ---------------------------------------------------------------------------
  596. //  SAX2XMLReaderImpl: Progressive parse methods
  597. // ---------------------------------------------------------------------------
  598. bool SAX2XMLReaderImpl::parseFirst( const   XMLCh* const    systemId
  599.                             ,       XMLPScanToken&  toFill)
  600. {
  601.     //
  602.     //  Avoid multiple entrance. We cannot enter here while a regular parse
  603.     //  is in progress.
  604.     //
  605.     if (fParseInProgress)
  606.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  607.     return fScanner->scanFirst(systemId, toFill);
  608. }
  609. bool SAX2XMLReaderImpl::parseFirst( const   char* const     systemId
  610.                             ,       XMLPScanToken&  toFill)
  611. {
  612.     //
  613.     //  Avoid multiple entrance. We cannot enter here while a regular parse
  614.     //  is in progress.
  615.     //
  616.     if (fParseInProgress)
  617.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  618.     return fScanner->scanFirst(systemId, toFill);
  619. }
  620. bool SAX2XMLReaderImpl::parseFirst( const   InputSource&    source
  621.                             ,       XMLPScanToken&  toFill)
  622. {
  623.     //
  624.     //  Avoid multiple entrance. We cannot enter here while a regular parse
  625.     //  is in progress.
  626.     //
  627.     if (fParseInProgress)
  628.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  629.     return fScanner->scanFirst(source, toFill);
  630. }
  631. bool SAX2XMLReaderImpl::parseNext(XMLPScanToken& token)
  632. {
  633.     return fScanner->scanNext(token);
  634. }
  635. void SAX2XMLReaderImpl::parseReset(XMLPScanToken& token)
  636. {
  637.     // Reset the scanner
  638.     fScanner->scanReset(token);
  639. }
  640. // ---------------------------------------------------------------------------
  641. //  SAX2XMLReaderImpl: Overrides of the XMLDocumentHandler interface
  642. // ---------------------------------------------------------------------------
  643. void SAX2XMLReaderImpl::docCharacters(  const   XMLCh* const    chars
  644.                                 , const unsigned int    length
  645.                                 , const bool            cdataSection)
  646. {
  647.     // Suppress the chars before the root element.
  648.     if (!fElemDepth)
  649.         return;
  650.    // Call the installed LexicalHandler.
  651.    if (cdataSection && fLexicalHandler)
  652.         fLexicalHandler->startCDATA();
  653.     // Just map to the SAX document handler
  654.     if (fDocHandler)
  655.         fDocHandler->characters(chars, length);
  656.    // Call the installed LexicalHandler.
  657.    if (cdataSection && fLexicalHandler)
  658.         fLexicalHandler->endCDATA();
  659.     //
  660.     //  If there are any installed advanced handlers, then lets call them
  661.     //  with this info.
  662.     //
  663.     for (unsigned int index = 0; index < fAdvDHCount; index++)
  664.         fAdvDHList[index]->docCharacters(chars, length, cdataSection);
  665. }
  666. void SAX2XMLReaderImpl::docComment(const XMLCh* const commentText)
  667. {
  668.    // Call the installed LexicalHandler.
  669.    if (fLexicalHandler)
  670.    {
  671.         // SAX2 reports comment text like characters -- as an
  672.         // array with a length.
  673.         fLexicalHandler->comment(commentText, XMLString::stringLen(commentText));
  674.    }
  675.     //
  676.     //  OK, if there are any installed advanced handlers,
  677.    // then let's call them with this info.
  678.     //
  679.     for (unsigned int index = 0; index < fAdvDHCount; index++)
  680.         fAdvDHList[index]->docComment(commentText);
  681. }
  682. void SAX2XMLReaderImpl::XMLDecl( const  XMLCh* const    versionStr
  683.                         , const XMLCh* const    encodingStr
  684.                         , const XMLCh* const    standaloneStr
  685.                         , const XMLCh* const    actualEncodingStr
  686.                         )
  687. {
  688.     // SAX has no way to report this event. But, if there are any installed
  689.     //  advanced handlers, then lets call them with this info.
  690.     //
  691.     for (unsigned int index = 0; index < fAdvDHCount; index++)
  692.         fAdvDHList[index]->XMLDecl( versionStr,
  693.                                     encodingStr,
  694.                                     standaloneStr,
  695.                                     actualEncodingStr );
  696. }
  697. void SAX2XMLReaderImpl::docPI(  const   XMLCh* const    target
  698.                         , const XMLCh* const    data)
  699. {
  700.     // Just map to the SAX document handler
  701.     if (fDocHandler)
  702.         fDocHandler->processingInstruction(target, data);
  703.     //
  704.     //  If there are any installed advanced handlers, then lets call them
  705.     //  with this info.
  706.     //
  707.     for (unsigned int index = 0; index < fAdvDHCount; index++)
  708.         fAdvDHList[index]->docPI(target, data);
  709. }
  710. void SAX2XMLReaderImpl::endDocument()
  711. {
  712.     if (fDocHandler)
  713.         fDocHandler->endDocument();
  714.     //
  715.     //  If there are any installed advanced handlers, then lets call them
  716.     //  with this info.
  717.     //
  718.     for (unsigned int index = 0; index < fAdvDHCount; index++)
  719.         fAdvDHList[index]->endDocument();
  720. }
  721. void SAX2XMLReaderImpl::endEntityReference(const XMLEntityDecl& entityDecl)
  722. {
  723.    // Call the installed LexicalHandler.
  724.    if (fLexicalHandler)
  725.         fLexicalHandler->endEntity(entityDecl.getName());
  726.     //
  727.     //  SAX has no way to report this event. But, if there are any installed
  728.     //  advanced handlers, then lets call them with this info.
  729.     //
  730.     for (unsigned int index = 0; index < fAdvDHCount; index++)
  731.         fAdvDHList[index]->endEntityReference(entityDecl);
  732. }
  733. void SAX2XMLReaderImpl::ignorableWhitespace(const   XMLCh* const    chars
  734.                                     , const unsigned int    length
  735.                                     , const bool            cdataSection)
  736. {
  737.     // Do not report the whitespace before the root element.
  738.     if (!fElemDepth)
  739.         return;
  740.     // Just map to the SAX document handler
  741.     if (fDocHandler)
  742.         fDocHandler->ignorableWhitespace(chars, length);
  743.     //
  744.     //  If there are any installed advanced handlers, then lets call them
  745.     //  with this info.
  746.     //
  747.     for (unsigned int index = 0; index < fAdvDHCount; index++)
  748.         fAdvDHList[index]->ignorableWhitespace(chars, length, cdataSection);
  749. }
  750. void SAX2XMLReaderImpl::resetDocument()
  751. {
  752.     //
  753.     //  If there are any installed advanced handlers, then lets call them
  754.     //  with this info.
  755.     //
  756.     for (unsigned int index = 0; index < fAdvDHCount; index++)
  757.         fAdvDHList[index]->resetDocument();
  758.     // Make sure our element depth flag gets set back to zero
  759.     fElemDepth = 0;
  760.     // Pop any prefix buffers left over from previous uses
  761.     while (!fPrefixCounts->empty())
  762.     {
  763.         unsigned int numPrefix = fPrefixCounts->pop();
  764.         for (unsigned int i = 0; i < numPrefix; i++)
  765.         {
  766.             XMLBuffer * buf = fPrefixes->pop() ;
  767.             fStringBuffers.releaseBuffer(*buf) ;
  768.         }
  769.     }
  770. }
  771. void SAX2XMLReaderImpl::startDocument()
  772. {
  773.     // Just map to the SAX document handler
  774.     if (fDocHandler)
  775.     {
  776.         fDocHandler->setDocumentLocator(fScanner->getLocator());
  777.         fDocHandler->startDocument();
  778.     }
  779.     //
  780.     //  If there are any installed advanced handlers, then lets call them
  781.     //  with this info.
  782.     //
  783.     for (unsigned int index = 0; index < fAdvDHCount; index++)
  784.         fAdvDHList[index]->startDocument();
  785. }
  786. void SAX2XMLReaderImpl::
  787. startElement(   const   XMLElementDecl&         elemDecl
  788.                 , const unsigned int            elemURLId
  789.                 , const XMLCh* const            elemPrefix
  790.                 , const RefVectorOf<XMLAttr>&   attrList
  791.                 , const unsigned int            attrCount
  792.                 , const bool                    isEmpty
  793.                 , const bool                    isRoot)
  794. {
  795.     // Bump the element depth counter if not empty
  796.     if (!isEmpty)
  797.         fElemDepth++;
  798.     if (fDocHandler)
  799.     {
  800.         XMLBufBid elemQName( &fStringBuffers ) ;
  801.         if (elemPrefix && *elemPrefix) {
  802.             elemQName.set(elemPrefix);
  803.             elemQName.append(chColon);
  804.         }
  805.         elemQName.append(elemDecl.getBaseName());
  806.         if (getDoNamespaces())
  807.         {
  808.             unsigned int numPrefix = 0;
  809.             const XMLCh*   nsString = XMLUni::fgXMLNSString;
  810.             const XMLCh*   nsPrefix = 0;
  811.             const XMLCh*   nsURI    = 0;
  812.             const XMLAttr* tempAttr = 0;
  813.             if (!fNamespacePrefix)
  814.             {
  815.                 fTempAttrVec->removeAllElements();
  816.             }
  817.             for (unsigned int i = 0; i < attrCount; i++)
  818.             {
  819.                 tempAttr = attrList.elementAt(i);
  820.                 if (XMLString::equals(tempAttr->getQName(), nsString))
  821.                     nsURI = tempAttr->getValue();
  822.                 if (XMLString::equals(tempAttr->getPrefix(), nsString))
  823.                 {
  824.                     nsPrefix = tempAttr->getName();
  825.                     nsURI = tempAttr->getValue();
  826.                 }
  827.                 if (!fNamespacePrefix)
  828.                 {
  829.                     if (nsURI == 0)
  830.                         fTempAttrVec->addElement((XMLAttr* const)tempAttr);
  831.                 }
  832.                 if (nsURI != 0)
  833.                 {
  834.                     if (nsPrefix == 0)
  835.                         nsPrefix = XMLUni::fgZeroLenString;
  836.                     fDocHandler->startPrefixMapping(nsPrefix, nsURI);
  837.                     XMLBuffer &buf = fStringBuffers.bidOnBuffer();
  838.                     buf.set ( nsPrefix ) ;
  839.                     fPrefixes->push(&buf) ;
  840.                     numPrefix++;
  841.                 }
  842.                 nsURI = 0;
  843.                 nsPrefix = 0;
  844.             }
  845.             fPrefixCounts->push(numPrefix) ;
  846.             if (!fNamespacePrefix)
  847.                 fAttrList.setVector(fTempAttrVec, fTempAttrVec->size(), fScanner);
  848.             else
  849.                 fAttrList.setVector(&attrList, attrCount, fScanner);
  850.             // call startElement() with namespace declarations
  851.             fDocHandler->startElement
  852.             (
  853.                 fScanner->getURIText(elemURLId)
  854.                 , elemDecl.getBaseName()
  855.                 , elemQName.getRawBuffer()
  856.                 , fAttrList
  857.             );
  858.         }
  859.         else // no namespace
  860.         {
  861.             fAttrList.setVector(&attrList, attrCount, fScanner);
  862.             fDocHandler->startElement(XMLUni::fgZeroLenString,
  863. elemDecl.getBaseName(),
  864. elemDecl.getFullName(),
  865. fAttrList);
  866.         }
  867.         // If its empty, send the end tag event now
  868.         if (isEmpty)
  869.         {
  870.             // call endPrefixMapping appropriately.
  871.             if (getDoNamespaces())
  872.             {
  873.                 fDocHandler->endElement
  874.                 (
  875.                     fScanner->getURIText(elemURLId)
  876.                     , elemDecl.getBaseName()
  877.                     , elemQName.getRawBuffer()
  878.                 );
  879.                 unsigned int numPrefix = fPrefixCounts->pop();
  880.                 for (unsigned int i = 0; i < numPrefix; ++i)
  881.                 {
  882.                     XMLBuffer * buf = fPrefixes->pop() ;
  883.                     fDocHandler->endPrefixMapping( buf->getRawBuffer() );
  884.                     fStringBuffers.releaseBuffer(*buf) ;
  885.                 }
  886.             }
  887.             else
  888.             {
  889.                 fDocHandler->endElement(XMLUni::fgZeroLenString,
  890.                                 elemDecl.getBaseName(),
  891.                                 elemDecl.getFullName());
  892.             }
  893.         }
  894.     }
  895.     //
  896.     //  If there are any installed advanced handlers, then lets call them
  897.     //  with this info.
  898.     //
  899.     for (unsigned int index = 0; index < fAdvDHCount; index++)
  900.     {
  901.         fAdvDHList[index]->startElement
  902.         (
  903.             elemDecl
  904.             , elemURLId
  905.             , elemPrefix
  906.             , attrList
  907.             , attrCount
  908.             , isEmpty
  909.             , isRoot
  910.         );
  911.     }
  912. }
  913. void SAX2XMLReaderImpl::endElement( const   XMLElementDecl& elemDecl
  914.                             , const unsigned int    uriId
  915.                             , const bool            isRoot
  916.                             , const XMLCh* const    elemPrefix)
  917. {
  918.     // Just map to the SAX document handler
  919.     if (fDocHandler)
  920.     {
  921.         // get the prefixes back so that we can call endPrefixMapping()
  922.         if (getDoNamespaces())
  923.         {
  924.             XMLBufBid elemQName( &fStringBuffers ) ;
  925.             if (elemPrefix && *elemPrefix) {
  926.                 elemQName.set(elemPrefix);
  927.                 elemQName.append(chColon);
  928.             }
  929.             elemQName.append(elemDecl.getBaseName());
  930.             fDocHandler->endElement
  931.             (
  932.                 fScanner->getURIText(uriId)
  933.                 , elemDecl.getBaseName()
  934.                 , elemQName.getRawBuffer()
  935.             );
  936.             unsigned int numPrefix = fPrefixCounts->pop();
  937.             for (unsigned int i = 0; i < numPrefix; i++)
  938.             {
  939.                 XMLBuffer * buf = fPrefixes->pop() ;
  940.                 fDocHandler->endPrefixMapping( buf->getRawBuffer() );
  941.                 fStringBuffers.releaseBuffer(*buf) ;
  942.             }
  943.         }
  944.         else
  945.         {
  946.             fDocHandler->endElement(XMLUni::fgZeroLenString,
  947.             elemDecl.getBaseName(),
  948.             elemDecl.getFullName() );
  949.         }
  950.     }
  951.     //
  952.     //  If there are any installed advanced handlers, then lets call them
  953.     //  with this info.
  954.     //
  955.     for (unsigned int index = 0; index < fAdvDHCount; index++)
  956.         fAdvDHList[index]->endElement(elemDecl, uriId, isRoot, elemPrefix);
  957.     //
  958.     //  Dump the element depth down again. Don't let it underflow in case
  959.     //  of malformed XML.
  960.     //
  961.     if (fElemDepth)
  962.         fElemDepth--;
  963. }
  964. void SAX2XMLReaderImpl::startEntityReference(const XMLEntityDecl& entityDecl)
  965. {
  966.    // Call the installed LexicalHandler.
  967.    if (fLexicalHandler)
  968.         fLexicalHandler->startEntity(entityDecl.getName());
  969.     //
  970.     //  SAX has no way to report this. But, If there are any installed
  971.     //  advanced handlers, then lets call them with this info.
  972.     //
  973.     for (unsigned int index = 0; index < fAdvDHCount; index++)
  974.         fAdvDHList[index]->startEntityReference(entityDecl);
  975. }
  976. // ---------------------------------------------------------------------------
  977. //  SAX2XMLReaderImpl: Overrides of the DocTypeHandler interface
  978. // ---------------------------------------------------------------------------
  979. void SAX2XMLReaderImpl::attDef( const   DTDElementDecl& elemDecl
  980.                         , const DTDAttDef&      attDef
  981.                         , const bool            ignoring)
  982. {
  983.     if (fDeclHandler && !ignoring) {
  984.         XMLAttDef::AttTypes attType = attDef.getType();
  985.         XMLAttDef::DefAttTypes defAttType = attDef.getDefaultType();
  986.         const XMLCh* defAttTypeStr = XMLUni::fgNullString;
  987.         bool isEnumeration = (attType == XMLAttDef::Notation || attType == XMLAttDef::Enumeration);
  988.         XMLBuffer enumBuf(128, fMemoryManager);
  989.         if (defAttType == XMLAttDef::Fixed ||
  990.             defAttType == XMLAttDef::Implied ||
  991.             defAttType == XMLAttDef::Required) {
  992.             defAttTypeStr = attDef.getDefAttTypeString(defAttType);
  993.         }
  994.         if (isEnumeration) {
  995.             const XMLCh* enumString = attDef.getEnumeration();
  996.             unsigned int enumLen = XMLString::stringLen(enumString);
  997.             if (attType == XMLAttDef::Notation) {
  998.                 enumBuf.set(XMLUni::fgNotationString);
  999.                 enumBuf.append(chSpace);
  1000.             }
  1001.             enumBuf.append(chOpenParen);
  1002.             for (unsigned int i=0; i<enumLen; i++) {
  1003.                 if (enumString[i] == chSpace)
  1004.                     enumBuf.append(chPipe);
  1005.                 else
  1006.                     enumBuf.append(enumString[i]);
  1007.             }
  1008.             enumBuf.append(chCloseParen);
  1009.         }
  1010.         fDeclHandler->attributeDecl(elemDecl.getFullName(),
  1011.                                     attDef.getFullName(),
  1012.                                     (isEnumeration) ? enumBuf.getRawBuffer()
  1013.                                                     : attDef.getAttTypeString(attDef.getType()),
  1014.                                     defAttTypeStr,
  1015.                                     attDef.getValue());
  1016.     }
  1017. }
  1018. void SAX2XMLReaderImpl::doctypeComment(const XMLCh* const commentText)
  1019. {
  1020.    if (fLexicalHandler)
  1021.    {
  1022.         // SAX2 reports comment text like characters -- as an
  1023.         // array with a length.
  1024.         fLexicalHandler->comment(commentText, XMLString::stringLen(commentText));
  1025.    }
  1026. }
  1027. void SAX2XMLReaderImpl::doctypeDecl(const   DTDElementDecl& elemDecl
  1028.                             , const XMLCh* const    publicId
  1029.                             , const XMLCh* const    systemId
  1030.                             , const bool            hasIntSubset
  1031.                             , const bool            hasExtSubset)
  1032. {
  1033.     // Call the installed LexicalHandler.
  1034.     if (fLexicalHandler && (hasIntSubset || hasExtSubset))
  1035.         fLexicalHandler->startDTD(elemDecl.getFullName(), publicId, systemId);
  1036.     fHasExternalSubset = hasExtSubset;
  1037.     // Unused by SAX DTDHandler interface at this time
  1038. }
  1039. void SAX2XMLReaderImpl::doctypePI(  const   XMLCh* const
  1040.                             , const XMLCh* const)
  1041. {
  1042.     // Unused by SAX DTDHandler interface at this time
  1043. }
  1044. void SAX2XMLReaderImpl::doctypeWhitespace(  const   XMLCh* const    chars
  1045.                                     , const unsigned int    length)
  1046. {
  1047.     // Unused by SAX DTDHandler interface at this time
  1048. }
  1049. void SAX2XMLReaderImpl::elementDecl(const DTDElementDecl& elemDecl,
  1050.                                     const bool isIgnored)
  1051. {
  1052.     if (fDeclHandler && !isIgnored)
  1053.         fDeclHandler->elementDecl(elemDecl.getFullName(),
  1054.                                   elemDecl.getFormattedContentModel());
  1055. }
  1056. void SAX2XMLReaderImpl::endAttList(const DTDElementDecl&)
  1057. {
  1058.     // Unused by SAX DTDHandler interface at this time
  1059. }
  1060. void SAX2XMLReaderImpl::endIntSubset()
  1061. {
  1062.    // Call the installed LexicalHandler.
  1063.    if (!fHasExternalSubset && fLexicalHandler)
  1064.         fLexicalHandler->endDTD();
  1065.     // Unused by SAX DTDHandler interface at this time
  1066. }
  1067. void SAX2XMLReaderImpl::endExtSubset()
  1068. {
  1069.     // Call the installed LexicalHandler.
  1070.     if (fLexicalHandler) {
  1071.         fLexicalHandler->endEntity(gDTDEntityStr);
  1072.         fLexicalHandler->endDTD();
  1073.     }
  1074.     // Unused by SAX DTDHandler interface at this time
  1075. }
  1076. void SAX2XMLReaderImpl::entityDecl( const   DTDEntityDecl&  entityDecl
  1077.                             , const bool            isPEDecl
  1078.                             , const bool            isIgnored)
  1079. {
  1080.     //
  1081.     //  If we have a DTD handler, and this entity is not ignored, and
  1082.     //  its an unparsed entity, then send this one, else if we have a Decl
  1083.     //  handler then send this one.
  1084.     //
  1085.     if (!isIgnored) {
  1086.         if (entityDecl.isUnparsed()) {
  1087.             if (fDTDHandler) {
  1088.                 fDTDHandler->unparsedEntityDecl
  1089.                 (
  1090.                     entityDecl.getName()
  1091.                     , entityDecl.getPublicId()
  1092.                     , entityDecl.getSystemId()
  1093.                     , entityDecl.getNotationName()
  1094.                 );
  1095.             }
  1096.         }
  1097.         else if (fDeclHandler) {
  1098.             const XMLCh* entityName = entityDecl.getName();
  1099.             ArrayJanitor<XMLCh> tmpNameJan(0);
  1100.             if (isPEDecl) {
  1101.                 unsigned int nameLen = XMLString::stringLen(entityName);
  1102.                 XMLCh* tmpName = (XMLCh*) fMemoryManager->allocate
  1103.                 (
  1104.                     (nameLen + 2) * sizeof(XMLCh)
  1105.                 );//new XMLCh[nameLen + 2];
  1106.                 tmpNameJan.reset(tmpName, fMemoryManager);
  1107.                 tmpName[0] = chPercent;
  1108.                 XMLString::copyString(tmpName + 1, entityName);
  1109.                 entityName = tmpName;
  1110.             }
  1111.             if (entityDecl.isExternal()) {
  1112.                 fDeclHandler->externalEntityDecl
  1113.                 (
  1114.                     entityName
  1115.                     , entityDecl.getPublicId()
  1116.                     , entityDecl.getSystemId()
  1117.                 );
  1118.             }
  1119.             else {
  1120.                 fDeclHandler->internalEntityDecl
  1121.                 (
  1122.                     entityName
  1123.                     , entityDecl.getValue()
  1124.                 );
  1125.             }
  1126.         }
  1127.     }
  1128. }
  1129. void SAX2XMLReaderImpl::resetDocType()
  1130. {
  1131.     fHasExternalSubset = false;
  1132.     // Just map to the DTD handler
  1133.     if (fDTDHandler)
  1134.         fDTDHandler->resetDocType();
  1135. }
  1136. void SAX2XMLReaderImpl::notationDecl(   const   XMLNotationDecl&    notDecl
  1137.                                 , const bool                isIgnored)
  1138. {
  1139.     if (fDTDHandler && !isIgnored)
  1140.     {
  1141.         fDTDHandler->notationDecl
  1142.         (
  1143.             notDecl.getName()
  1144.             , notDecl.getPublicId()
  1145.             , notDecl.getSystemId()
  1146.         );
  1147.     }
  1148. }
  1149. void SAX2XMLReaderImpl::startAttList(const DTDElementDecl&)
  1150. {
  1151.     // Unused by SAX DTDHandler interface at this time
  1152. }
  1153. void SAX2XMLReaderImpl::startIntSubset()
  1154. {
  1155.     // Unused by SAX DTDHandler interface at this time
  1156. }
  1157. void SAX2XMLReaderImpl::startExtSubset()
  1158. {
  1159.     if (fLexicalHandler)
  1160.         fLexicalHandler->startEntity(gDTDEntityStr);
  1161. }
  1162. void SAX2XMLReaderImpl::TextDecl(   const  XMLCh* const
  1163.                             , const XMLCh* const)
  1164. {
  1165.     // Unused by SAX DTDHandler interface at this time
  1166. }
  1167. // ---------------------------------------------------------------------------
  1168. //  SAX2XMLReaderImpl: Handlers for the XMLEntityHandler interface
  1169. // ---------------------------------------------------------------------------
  1170. void SAX2XMLReaderImpl::endInputSource(const InputSource&)
  1171. {
  1172. }
  1173. bool SAX2XMLReaderImpl::expandSystemId(const XMLCh* const, XMLBuffer&)
  1174. {
  1175.     return false;
  1176. }
  1177. void SAX2XMLReaderImpl::resetEntities()
  1178. {
  1179.     // Nothing to do for this one
  1180. }
  1181. InputSource* SAX2XMLReaderImpl::resolveEntity(   const   XMLCh* const    publicId
  1182.                                                , const   XMLCh* const    systemId
  1183.                                                , const   XMLCh* const    baseURI)
  1184. {
  1185.     // Just map to the SAX entity resolver handler
  1186.     if (fEntityResolver)
  1187.         return fEntityResolver->resolveEntity(publicId, systemId);
  1188.     return 0;
  1189. }
  1190. void SAX2XMLReaderImpl::startInputSource(const InputSource&)
  1191. {
  1192.     // Nothing to do for this one
  1193. }
  1194. // ---------------------------------------------------------------------------
  1195. //  SAX2XMLReaderImpl: Overrides of the XMLErrorReporter interface
  1196. // ---------------------------------------------------------------------------
  1197. void SAX2XMLReaderImpl::resetErrors()
  1198. {
  1199.     if (fErrorHandler)
  1200.         fErrorHandler->resetErrors();
  1201. }
  1202. void SAX2XMLReaderImpl::error(  const   unsigned int                code
  1203.                         , const XMLCh* const                msgDomain
  1204.                         , const XMLErrorReporter::ErrTypes  errType
  1205.                         , const XMLCh* const                errorText
  1206.                         , const XMLCh* const                systemId
  1207.                         , const XMLCh* const                publicId
  1208.                         , const XMLSSize_t                  lineNum
  1209.                         , const XMLSSize_t                  colNum)
  1210. {
  1211.     SAXParseException toThrow = SAXParseException
  1212.     (
  1213.         errorText
  1214.         , publicId
  1215.         , systemId
  1216.         , lineNum
  1217.         , colNum
  1218.     );
  1219.     if (!fErrorHandler)
  1220.     {
  1221.         if (errType == XMLErrorReporter::ErrType_Fatal)
  1222.             throw toThrow;
  1223.         else
  1224.             return;
  1225.     }
  1226.     if (errType == XMLErrorReporter::ErrType_Warning)
  1227.         fErrorHandler->warning(toThrow);
  1228.     else if (errType == XMLErrorReporter::ErrType_Fatal)
  1229.         fErrorHandler->fatalError(toThrow);
  1230.     else
  1231.         fErrorHandler->error(toThrow);
  1232. }
  1233. // ---------------------------------------------------------------------------
  1234. //  SAX2XMLReaderImpl: Features and Properties
  1235. // ---------------------------------------------------------------------------
  1236. void SAX2XMLReaderImpl::setFeature(const XMLCh* const name, const bool value)
  1237. {
  1238.     if (fParseInProgress)
  1239.         throw SAXNotSupportedException("Feature modification is not supported during parse.");
  1240.     if (XMLString::compareIString(name, XMLUni::fgSAX2CoreNameSpaces) == 0)
  1241.     {
  1242.         setDoNamespaces(value);
  1243.     }
  1244.     else if (XMLString::compareIString(name, XMLUni::fgSAX2CoreValidation) == 0)
  1245.     {
  1246.         fValidation = value;
  1247.         if (fValidation)
  1248.             if (fAutoValidation)
  1249.                 setValidationScheme(Val_Auto);
  1250.             else
  1251.                 setValidationScheme(Val_Always);
  1252.         else
  1253.             setValidationScheme(Val_Never);
  1254.     }
  1255.     else if (XMLString::compareIString(name, XMLUni::fgSAX2CoreNameSpacePrefixes) == 0)
  1256.     {
  1257.         fNamespacePrefix = value;
  1258.     }
  1259.     else if (XMLString::compareIString(name, XMLUni::fgXercesDynamic) == 0)
  1260.     {
  1261.         fAutoValidation = value;
  1262.         // for auto validation, the sax2 core validation feature must also be enabled.
  1263.         if (fValidation)
  1264.             if (fAutoValidation)
  1265.                 setValidationScheme(Val_Auto);
  1266.             else
  1267.                 setValidationScheme(Val_Always);
  1268.         else
  1269.             setValidationScheme(Val_Never);
  1270.     }
  1271.     else if (XMLString::compareIString(name, XMLUni::fgXercesSchema) == 0)
  1272.     {
  1273.         setDoSchema(value);
  1274.     }
  1275.     else if (XMLString::compareIString(name, XMLUni::fgXercesSchemaFullChecking) == 0)
  1276.     {
  1277.         fScanner->setValidationSchemaFullChecking(value);
  1278.     }
  1279.     else if (XMLString::compareIString(name, XMLUni::fgXercesLoadExternalDTD) == 0)
  1280.     {
  1281.         fScanner->setLoadExternalDTD(value);
  1282.     }
  1283.     else if (XMLString::compareIString(name, XMLUni::fgXercesContinueAfterFatalError) == 0)
  1284.     {
  1285.         fScanner->setExitOnFirstFatal(!value);
  1286.     }
  1287.     else if (XMLString::compareIString(name, XMLUni::fgXercesValidationErrorAsFatal) == 0)
  1288.     {
  1289.         fScanner->setValidationConstraintFatal(value);
  1290.     }
  1291.     else if (XMLString::compareIString(name, XMLUni::fgXercesCacheGrammarFromParse) == 0)
  1292.     {
  1293.         fScanner->cacheGrammarFromParse(value);
  1294.         if (value)
  1295.             fScanner->useCachedGrammarInParse(value);
  1296.     }
  1297.     else if (XMLString::compareIString(name, XMLUni::fgXercesUseCachedGrammarInParse) == 0)
  1298.     {
  1299.         if (value || !fScanner->isCachingGrammarFromParse())
  1300.             fScanner->useCachedGrammarInParse(value);
  1301.     }
  1302.     else if (XMLString::compareIString(name, XMLUni::fgXercesCalculateSrcOfs) == 0)
  1303.     {
  1304.         fScanner->setCalculateSrcOfs(value);
  1305.     }
  1306.     else if (XMLString::compareIString(name, XMLUni::fgXercesStandardUriConformant) == 0)
  1307.     {
  1308.         fScanner->setStandardUriConformant(value);
  1309.     }
  1310.     else
  1311.        throw SAXNotRecognizedException("Unknown Feature");
  1312. }
  1313. bool SAX2XMLReaderImpl::getFeature(const XMLCh* const name) const
  1314. {
  1315.     if (XMLString::compareIString(name, XMLUni::fgSAX2CoreNameSpaces) == 0)
  1316.         return getDoNamespaces();
  1317.     else if (XMLString::compareIString(name, XMLUni::fgSAX2CoreValidation) == 0)
  1318.         return fValidation;
  1319.     else if (XMLString::compareIString(name, XMLUni::fgSAX2CoreNameSpacePrefixes) == 0)
  1320.         return fNamespacePrefix;
  1321.     else if (XMLString::compareIString(name, XMLUni::fgXercesDynamic) == 0)
  1322.         return fAutoValidation;
  1323.     else if (XMLString::compareIString(name, XMLUni::fgXercesSchema) == 0)
  1324.         return getDoSchema();
  1325.     else if (XMLString::compareIString(name, XMLUni::fgXercesSchemaFullChecking) == 0)
  1326.         return fScanner->getValidationSchemaFullChecking();
  1327.     else if (XMLString::compareIString(name, XMLUni::fgXercesLoadExternalDTD) == 0)
  1328.         return fScanner->getLoadExternalDTD();
  1329.     else if (XMLString::compareIString(name, XMLUni::fgXercesContinueAfterFatalError) == 0)
  1330.         return !fScanner->getExitOnFirstFatal();
  1331.     else if (XMLString::compareIString(name, XMLUni::fgXercesValidationErrorAsFatal) == 0)
  1332.         return fScanner->getValidationConstraintFatal();
  1333.     else if (XMLString::compareIString(name, XMLUni::fgXercesCacheGrammarFromParse) == 0)
  1334.         return fScanner->isCachingGrammarFromParse();
  1335.     else if (XMLString::compareIString(name, XMLUni::fgXercesUseCachedGrammarInParse) == 0)
  1336.         return fScanner->isUsingCachedGrammarInParse();
  1337.     else if (XMLString::compareIString(name, XMLUni::fgXercesCalculateSrcOfs) == 0)
  1338.         return fScanner->getCalculateSrcOfs();
  1339.     else if (XMLString::compareIString(name, XMLUni::fgXercesStandardUriConformant) == 0)
  1340.         return fScanner->getStandardUriConformant();
  1341.     else
  1342.        throw SAXNotRecognizedException("Unknown Feature");
  1343.     return false;
  1344. }
  1345. void SAX2XMLReaderImpl::setProperty(const XMLCh* const name, void* value)
  1346. {
  1347. if (fParseInProgress)
  1348. throw SAXNotSupportedException("Property modification is not supported during parse.");
  1349. if (XMLString::compareIString(name, XMLUni::fgXercesSchemaExternalSchemaLocation) == 0)
  1350. {
  1351. fScanner->setExternalSchemaLocation((XMLCh*)value);
  1352. }
  1353. else if (XMLString::compareIString(name, XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation) == 0)
  1354. {
  1355. fScanner->setExternalNoNamespaceSchemaLocation((XMLCh*)value);
  1356. }
  1357. else if (XMLString::compareIString(name, XMLUni::fgXercesSecurityManager) == 0)
  1358. {
  1359. fScanner->setSecurityManager((SecurityManager*)value);
  1360. }
  1361.     else if (XMLString::equals(name, XMLUni::fgXercesScannerName))
  1362.     {
  1363.         XMLScanner* tempScanner = XMLScannerResolver::resolveScanner
  1364.         (
  1365.             (const XMLCh*) value
  1366.             , fValidator
  1367.             , fMemoryManager
  1368.         );
  1369.         if (tempScanner) {
  1370.             tempScanner->setParseSettings(fScanner);
  1371.             tempScanner->setGrammarResolver(fGrammarResolver);
  1372.             tempScanner->setURIStringPool(fURIStringPool);
  1373.             delete fScanner;
  1374.             fScanner = tempScanner;
  1375.         }
  1376.     }
  1377.     else
  1378.        throw SAXNotRecognizedException("Unknown Property");
  1379. }
  1380. void* SAX2XMLReaderImpl::getProperty(const XMLCh* const name) const
  1381. {
  1382.     if (XMLString::compareIString(name, XMLUni::fgXercesSchemaExternalSchemaLocation) == 0)
  1383.         return (void*)fScanner->getExternalSchemaLocation();
  1384.     else if (XMLString::compareIString(name, XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation) == 0)
  1385.         return (void*)fScanner->getExternalNoNamespaceSchemaLocation();
  1386.     else if (XMLString::compareIString(name, XMLUni::fgXercesSecurityManager) == 0)
  1387.         return (void*)fScanner->getSecurityManager();
  1388.     else if (XMLString::equals(name, XMLUni::fgXercesScannerName))
  1389.         return (void*)fScanner->getName();
  1390.     else
  1391.         throw SAXNotRecognizedException("Unknown Property");
  1392.     return 0;
  1393. }
  1394. // ---------------------------------------------------------------------------
  1395. //  SAX2XMLReaderImpl: Private getters and setters for conveniences
  1396. // ---------------------------------------------------------------------------
  1397. void SAX2XMLReaderImpl::setValidationScheme(const ValSchemes newScheme)
  1398. {
  1399.     if (newScheme == Val_Never)
  1400.         fScanner->setValidationScheme(XMLScanner::Val_Never);
  1401.     else if (newScheme == Val_Always)
  1402.         fScanner->setValidationScheme(XMLScanner::Val_Always);
  1403.     else
  1404.         fScanner->setValidationScheme(XMLScanner::Val_Auto);
  1405. }
  1406. void SAX2XMLReaderImpl::setDoNamespaces(const bool newState)
  1407. {
  1408.     fScanner->setDoNamespaces(newState);
  1409. }
  1410. bool SAX2XMLReaderImpl::getDoNamespaces() const
  1411. {
  1412.     return fScanner->getDoNamespaces();
  1413. }
  1414. void SAX2XMLReaderImpl::setDoSchema(const bool newState)
  1415. {
  1416.     fScanner->setDoSchema(newState);
  1417. }
  1418. bool SAX2XMLReaderImpl::getDoSchema() const
  1419. {
  1420.     return fScanner->getDoSchema();
  1421. }
  1422. // ---------------------------------------------------------------------------
  1423. //  SAX2XMLReaderImpl: Grammar preparsing
  1424. // ---------------------------------------------------------------------------
  1425. Grammar* SAX2XMLReaderImpl::loadGrammar(const char* const systemId,
  1426.                                         const short grammarType,
  1427.                                         const bool toCache)
  1428. {
  1429.     // Avoid multiple entrance
  1430.     if (fParseInProgress)
  1431.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  1432.     Grammar* grammar = 0;
  1433.     try
  1434.     {
  1435.         fParseInProgress = true;
  1436.         grammar = fScanner->loadGrammar(systemId, grammarType, toCache);
  1437.         fParseInProgress = false;
  1438.     }
  1439.     catch(...)
  1440.     {
  1441.         fParseInProgress = false;
  1442.         throw;
  1443.     }
  1444.     return grammar;
  1445. }
  1446. Grammar* SAX2XMLReaderImpl::loadGrammar(const XMLCh* const systemId,
  1447.                                         const short grammarType,
  1448.                                         const bool toCache)
  1449. {
  1450.     // Avoid multiple entrance
  1451.     if (fParseInProgress)
  1452.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  1453.     Grammar* grammar = 0;
  1454.     try
  1455.     {
  1456.         fParseInProgress = true;
  1457.         grammar = fScanner->loadGrammar(systemId, grammarType, toCache);
  1458.         fParseInProgress = false;
  1459.     }
  1460.     catch(...)
  1461.     {
  1462.         fParseInProgress = false;
  1463.         throw;
  1464.     }
  1465.     return grammar;
  1466. }
  1467. Grammar* SAX2XMLReaderImpl::loadGrammar(const InputSource& source,
  1468.                                         const short grammarType,
  1469.                                         const bool toCache)
  1470. {
  1471.     // Avoid multiple entrance
  1472.     if (fParseInProgress)
  1473.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  1474.     Grammar* grammar = 0;
  1475.     try
  1476.     {
  1477.         fParseInProgress = true;
  1478.         grammar = fScanner->loadGrammar(source, grammarType, toCache);
  1479.         fParseInProgress = false;
  1480.     }
  1481.     catch(...)
  1482.     {
  1483.         fParseInProgress = false;
  1484.         throw;
  1485.     }
  1486.     return grammar;
  1487. }
  1488. void SAX2XMLReaderImpl::resetCachedGrammarPool()
  1489. {
  1490.     fGrammarResolver->resetCachedGrammar();
  1491. }
  1492. Grammar* SAX2XMLReaderImpl::getGrammar(const XMLCh* const nameSpaceKey)
  1493. {
  1494.     return fGrammarResolver->getGrammar(nameSpaceKey);
  1495. }
  1496. XERCES_CPP_NAMESPACE_END