You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by ne...@apache.org on 2003/06/03 00:22:29 UTC

cvs commit: xml-xerces/c/tests/MemHandlerTest Makefile.in MemoryMonitor.cpp MemoryMonitor.hpp SimpleHashPtr.cpp SimpleHashPtr.hpp SimpleValueHashTableOf.cpp SimpleValueHashTableOf.hpp

neilg       2003/06/02 15:22:27

  Modified:    c/tests  Makefile.in configure.in configure
  Added:       c/tests/MemHandlerTest Makefile.in MemoryMonitor.cpp
                        MemoryMonitor.hpp SimpleHashPtr.cpp
                        SimpleHashPtr.hpp SimpleValueHashTableOf.cpp
                        SimpleValueHashTableOf.hpp
  Log:
  new test for the pluggable memory management mechanism.  This tests all 4 common Xerces parsers (SAX, SAX2, DOMBuilder and DeprecatedDOM) and ensures all allocated memory is dallocated, and that the manager which created the memory is called to deallocate it.
  
  Revision  Changes    Path
  1.26      +12 -4     xml-xerces/c/tests/Makefile.in
  
  Index: Makefile.in
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/tests/Makefile.in,v
  retrieving revision 1.25
  retrieving revision 1.26
  diff -u -r1.25 -r1.26
  --- Makefile.in	29 Jan 2003 20:14:48 -0000	1.25
  +++ Makefile.in	2 Jun 2003 22:22:25 -0000	1.26
  @@ -63,6 +63,7 @@
   DOMTypeInfo_DIR=DOM/TypeInfo
   Traversal_DIR=DOM/Traversal
   ThreadTest_DIR=ThreadTest
  +MemHandlerTest_DIR=MemHandlerTest
   EncodingTest_DIR=EncodingTest
   DOMRange_DIR=DOM/RangeTest
   InitTermTest_DIR=InitTermTest
  @@ -82,12 +83,12 @@
   
   ifeq (${PLATFORM},HPUX)
     ifeq (${OSVER}, HPUX10)
  -      all::	bindir threadtest encodingtest traversal
  +      all::	bindir threadtest memhandlertest encodingtest traversal
     else
  -      all::	bindir dommemtest deprecateddomcount domtest domtypeinfo threadtest encodingtest traversal rangetest inittermtest
  +      all::	bindir dommemtest deprecateddomcount domtest domtypeinfo threadtest encodingtest traversal rangetest inittermtest memhandlertest  
     endif
   else
  -    all::	bindir dommemtest deprecateddomcount domtest domtypeinfo encodingtest traversal rangetest inittermtest
  +    all::	bindir dommemtest deprecateddomcount domtest domtypeinfo encodingtest traversal rangetest inittermtest memhandlertest 
     ifneq (${THREADS},none)
       all::	threadtest
     endif
  @@ -116,6 +117,11 @@
   	@echo Building "ThreadTest"
   	${MAKE} -C $(ThreadTest_DIR) $(MAKE_FLAGS)
   
  +memhandlertest::
  +	@echo Building "MemHandlerTest"
  +	${MAKE} -C $(MemHandlerTest_DIR) $(MAKE_FLAGS)
  +
  +
   encodingtest::
   	@echo Building "EncodingTest"
   	${MAKE} -C $(EncodingTest_DIR) $(MAKE_FLAGS)
  @@ -138,6 +144,7 @@
   	${MAKE} -C $(DOMTest_DIR) $@
   	${MAKE} -C $(DOMTypeInfo_DIR) $@
   	${MAKE} -C $(ThreadTest_DIR) $@
  +	${MAKE} -C $(MemHandlerTest_DIR) $@
   	${MAKE} -C $(EncodingTest_DIR) $@
   	${MAKE} -C $(Traversal_DIR) $@
   	${MAKE} -C $(DOMRange_DIR) $@
  @@ -149,6 +156,7 @@
   	${MAKE} -C $(DOMTest_DIR) $@
   	${MAKE} -C $(DOMTypeInfo_DIR) $@
   	${MAKE} -C $(ThreadTest_DIR) $@
  +	${MAKE} -C $(MemHandlerTest_DIR) $@
   	${MAKE} -C $(EncodingTest_DIR) $@
   	${MAKE} -C $(Traversal_DIR) $@
   	${MAKE} -C $(DOMRange_DIR) $@
  
  
  
  1.31      +2 -1      xml-xerces/c/tests/configure.in
  
  Index: configure.in
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/tests/configure.in,v
  retrieving revision 1.30
  retrieving revision 1.31
  diff -u -r1.30 -r1.31
  --- configure.in	14 May 2003 19:26:20 -0000	1.30
  +++ configure.in	2 Jun 2003 22:22:25 -0000	1.31
  @@ -96,7 +96,8 @@
   EncodingTest/Makefile \
   DOM/RangeTest/Makefile \
   InitTermTest/Makefile \
  -ThreadTest/Makefile])
  +ThreadTest/Makefile \
  +MemHandlerTest/Makefile])
   
   echo
   echo Having build problems? Read instructions at http://xml.apache.org/xerces-c/build.html
  
  
  
  1.29      +4 -2      xml-xerces/c/tests/configure
  
  Index: configure
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/tests/configure,v
  retrieving revision 1.28
  retrieving revision 1.29
  diff -u -r1.28 -r1.29
  --- configure	30 May 2003 13:08:24 -0000	1.28
  +++ configure	2 Jun 2003 22:22:25 -0000	1.29
  @@ -1531,7 +1531,8 @@
   EncodingTest/Makefile \
   DOM/RangeTest/Makefile \
   InitTermTest/Makefile \
  -ThreadTest/Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
  +ThreadTest/Makefile \
  +MemHandlerTest/Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
   EOF
   cat >> $CONFIG_STATUS <<EOF
   
  @@ -1637,7 +1638,8 @@
   EncodingTest/Makefile \
   DOM/RangeTest/Makefile \
   InitTermTest/Makefile \
  -ThreadTest/Makefile"}
  +ThreadTest/Makefile \
  +MemHandlerTest/Makefile"}
   EOF
   cat >> $CONFIG_STATUS <<\EOF
   for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
  
  
  
  1.1                  xml-xerces/c/tests/MemHandlerTest/Makefile.in
  
  Index: Makefile.in
  ===================================================================
  #
  # The Apache Software License, Version 1.1
  #
  # Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
  # reserved.
  #
  # Redistribution and use in source and binary forms, with or without
  # modification, are permitted provided that the following conditions
  # are met:
  #
  # 1. Redistributions of source code must retain the above copyright
  #    notice, this list of conditions and the following disclaimer.
  #
  # 2. Redistributions in binary form must reproduce the above copyright
  #    notice, this list of conditions and the following disclaimer in
  #    the documentation and/or other materials provided with the
  #    distribution.
  #
  # 3. The end-user documentation included with the redistribution,
  #    if any, must include the following acknowledgment:
  #       "This product includes software developed by the
  #        Apache Software Foundation (http://www.apache.org/)."
  #    Alternately, this acknowledgment may appear in the software itself,
  #    if and wherever such third-party acknowledgments normally appear.
  #
  # 4. The names "Xerces" and "Apache Software Foundation" must
  #    not be used to endorse or promote products derived from this
  #    software without prior written permission. For written
  #    permission, please contact apache\@apache.org.
  #
  # 5. Products derived from this software may not be called "Apache",
  #    nor may "Apache" appear in their name, without prior written
  #    permission of the Apache Software Foundation.
  #
  # THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  # DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  # ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  # SUCH DAMAGE.
  # ====================================================================
  #
  # This software consists of voluntary contributions made by many
  # individuals on behalf of the Apache Software Foundation, and was
  # originally based on software copyright (c) 1999, International
  # Business Machines, Inc., http://www.ibm.com .  For more information
  # on the Apache Software Foundation, please see
  # <http://www.apache.org/>.
  #
  #
  # $Id: Makefile.in,v 1.1 2003/06/02 22:22:26 neilg Exp $
  #
  
  ###################################################################
  #                    IMPORTANT NOTE                               #
  ###################################################################
  # If you are going to do the OS390BATCH build, make sure you have #
  # the OS390BATCH environment variable set.                        #
  #                                                                 #
  #   export OS390BATCH=1                                           #
  #                                                                 #
  ###################################################################
  
  PLATFORM = @platform@
  COMPILER = @compiler@
  GCC = @GCC@
  GXX = @GXX@
  CXXFLAGS = @cxxflags@
  CFLAGS = @cflags@
  LDFLAGS = @ldflags@
  PREFIX = @prefix@
  THREADS = @threads@
  EXTRA_LIBS = @extra_libs@
  
  include ../../version.incl
  include ../Makefile.incl
  
  APP_NAME=MemoryMonitor
  APP_DIR=MemHandlerTest
  
  OUTDIR= ${XERCESCROOT}/tests/${APP_DIR}
  EXEC=	${XERCESCROOT}/bin
  OBJS=	${OUTDIR}/MemoryMonitor.o ${OUTDIR}/SimpleHashPtr.o 
  SRC=	${XERCESCROOT}/tests/${APP_DIR}
  HEADER_FILES=
  
  ## OS390BATCH
  ifeq (${OS390BATCH},1)
  BATCH_TARGET= "//'${LOADMOD}(THREDTST)'"
  all:: makedir ${BATCH_TARGET}
  else
  all:: makedir ${EXEC}/${APP_NAME}
  endif
  
  makedir::
  	-mkdir -p $(OUTDIR)
  
  ${EXEC}/${APP_NAME}:: ${OBJS}
  	${LINK} ${PLATFORM_LIB_LINK_OPTIONS} ${OBJS} -o $@ ${LIBRARY_SEARCH_PATHS} ${LIBRARY_NAMES} ${EXTRA_LINK_OPTIONS} ${LIBS}
  
  ${BATCH_TARGET}:: ${OBJS}
  	${LINK} ${PLATFORM_LIB_LINK_OPTIONS} ${OBJS} -o $@ ${LIBRARY_SEARCH_PATHS} ${LIBRARY_NAMES} ${EXTRA_LINK_OPTIONS}
  
  $(OUTDIR)/SimpleHashPtr.o:: ${SRC}/SimpleHashPtr.cpp ${HEADER_FILES}
  	${CC} ${INCLUDES} ${CMP} -o $(OUTDIR)/SimpleHashPtr.o ${SRC}/SimpleHashPtr.cpp
  
  $(OUTDIR)/MemoryMonitor.o:: ${SRC}/MemoryMonitor.cpp ${OUTDIR}/SimpleValueHashTableOf.cpp ${SRC}/SimpleHashPtr.cpp ${HEADER_FILES}
  	${CC} ${INCLUDES} ${CMP} -o $(OUTDIR)/MemoryMonitor.o ${SRC}/MemoryMonitor.cpp
  
  clean::
  	rm -f ${OBJS} ${EXEC}/${APP_NAME}
  
  distclean::	clean
  	rm -f Makefile
  
  
  
  1.1                  xml-xerces/c/tests/MemHandlerTest/MemoryMonitor.cpp
  
  Index: MemoryMonitor.cpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xerces" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache\@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation, and was
   * originally based on software copyright (c) 1999, International
   * Business Machines, Inc., http://www.ibm.com .  For more information
   * on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /*
   * $Log: MemoryMonitor.cpp,v $
   * Revision 1.1  2003/06/02 22:22:26  neilg
   * new test for the pluggable memory management mechanism.  This tests all 4 common Xerces parsers (SAX, SAX2, DOMBuilder and DeprecatedDOM) and ensures all allocated memory is dallocated, and that the manager which created the memory is called to deallocate it.
   *
   */
  
  
  // ---------------------------------------------------------------------------
  //  Includes
  // ---------------------------------------------------------------------------
  #include <MemoryMonitor.hpp>
  #if defined(XERCES_NEW_IOSTREAMS)
  #include <iostream>
  #include <fstream>
  #else
  #include <iostream.h>
  #include <fstream.h>
  #endif
  #include <assert.h>
  #include <xercesc/util/XercesDefs.hpp>
  
  
  void* MemoryMonitor::allocate(size_t size)
  {
      void *key = ::operator new(size);
      fHashTable->put(key, (unsigned int)size);
      return key;
  }
  
  void MemoryMonitor::deallocate(void* p)
  {
      // if fHashTable doesn't contain p, then this memory manager
      // didn't allocate that memory--a segfault waiting to happen...
      assert(p == 0 || fHashTable->get(p) != 0);
      if (p != 0)
          fHashTable->removeKey(p);
      ::operator delete(p);
  }
  
  unsigned int MemoryMonitor::getTotalMemory() 
  {
      unsigned int total = 0;
      ValueHashTableOfEnumerator<unsigned int> *memEnum = 
              new ValueHashTableOfEnumerator<unsigned int>(fHashTable);
      while(memEnum->hasMoreElements()) {
          total += memEnum->nextElement();
      }
      delete memEnum;
      return total;
  }
  
  static void usage()
  {
      XERCES_STD_QUALIFIER cout << "\nUsage:\n"
              "    MemoryMonitor [options] <XML file | List file>\n\n"
              "This program invokes the XercesDOMParser, DOMBuilder, SAXParser ,\n"
              "and the SAX2XMLReader, and ensures that MemoryManagers set on these\n"
              "domBuilders are called to delete just as many bytes as they allocate.\n"
              "This is done for each XML file, and each file is processed\n"
              "as many times as indicated.\n"
              "Options:\n"
              "    -l          Indicate the input file is a List File that has a list of xml files.\n"
              "                Default to off (Input file is an XML file).\n"
              "    -v=xxx      Validation scheme [always | never | auto*].\n"
              "    -n          Enable namespace processing. Defaults to off.\n"
              "    -s          Enable schema processing. Defaults to off.\n"
              "    -f          Enable full schema constraint checking. Defaults to off.\n"
              "    -r=n        Run file through domBuilders n times.\n" 
  		    "    -?          Show this help.\n\n"
              "  * = Default if not provided explicitly.\n"
           << XERCES_STD_QUALIFIER endl;
  }
  
  class DOMBuilderHandler : public DOMErrorHandler 
  {
  public:
      DOMBuilderHandler() {};
      ~DOMBuilderHandler() {};
      bool handleError(const DOMError &error) 
      {
          char *message = 0;
          XERCES_STD_QUALIFIER cerr << "Error occurred in DOMBuilder!  Message:  " << 
              (message = XMLString::transcode(error.getMessage())) << " of severity " << error.getSeverity() << "." << XERCES_STD_QUALIFIER endl;
          XMLString::release(&message);
      }
  };
  
  class SAXErrorHandler : public ErrorHandler 
  {
  public:
      SAXErrorHandler() {};
      ~SAXErrorHandler() {};
      void warning(const SAXParseException &exception )
      {
          char *message = 0;
          XERCES_STD_QUALIFIER cerr << "SAX warning received!  Text:  " <<
              (message = XMLString::transcode(exception.getMessage())) << "." << XERCES_STD_QUALIFIER endl;
          XMLString::release(&message);
      }
      void error(const SAXParseException &exception )
      {
          char *message = 0;
          XERCES_STD_QUALIFIER cerr << "SAX error received!  Text:  " <<
              (message = XMLString::transcode(exception.getMessage())) << "." << XERCES_STD_QUALIFIER endl;
          XMLString::release(&message);
      }
      void fatalError(const SAXParseException &exception )
      {
          char *message = 0;
          XERCES_STD_QUALIFIER cerr << "SAX fatalError received!  Text:  " <<
              (message = XMLString::transcode(exception.getMessage())) << "." << XERCES_STD_QUALIFIER endl;
          XMLString::release(&message);
      }
  
      // no state so no body
      void resetErrors() {};
  };
  
  /**
   * This utility takes similar parameters as DOMCount,
   * with similar meanings.  The only difference is that it runs
   * the file(s) in question through a DOMParser, a DOMBuilder, a SAXParser and
   * a SAX2XMLReader, setting options as appropriate.  It does this
   * sequentially, n times per file with a single domBuilder
   * object, and reports what it finds in terms of memory
   * allocations/deallocations.
   */
  
  int main (int argC,  char *argV[]) 
  {
  
      MemoryMonitor *staticMemMonitor = new MemoryMonitor();
  
      // Initialize the XML4C system
      try
      {
          XMLPlatformUtils::Initialize(XMLUni::fgXercescDefaultLocale, 0, 0, staticMemMonitor);
      }
      catch (const XMLException& toCatch)
      {
           char *msg = XMLString::transcode(toCatch.getMessage());
           XERCES_STD_QUALIFIER cerr << "Error during initialization! :\n"
                << msg << XERCES_STD_QUALIFIER endl;
           XMLString::release(&msg);
           return 1;
      }
  
      // Check command line and extract arguments.
      if (argC < 2)
      {
          usage();
          return 1;
      }
  
      const char*                xmlFile = 0;
      AbstractDOMParser::ValSchemes domBuilderValScheme = AbstractDOMParser::Val_Auto;
      bool                       doNamespaces       = false;
      bool                       doSchema           = false;
      bool                       schemaFullChecking = false;
      bool                       doList = false;
      bool                       errorOccurred = false;
      int                        numReps =1;
  
      int argInd;
      for (argInd = 1; argInd < argC; argInd++)
      {
          // Break out on first parm not starting with a dash
          if (argV[argInd][0] != '-')
              break;
  
          // Watch for special case help request
          if (!strcmp(argV[argInd], "-?"))
          {
              usage();
              return 2;
          }
           else if (!strncmp(argV[argInd], "-v=", 3)
                ||  !strncmp(argV[argInd], "-V=", 3))
          {
              const char* const parm = &argV[argInd][3];
  
              if (!strcmp(parm, "never"))
                  domBuilderValScheme = AbstractDOMParser::Val_Never;
              else if (!strcmp(parm, "auto"))
                  domBuilderValScheme = AbstractDOMParser::Val_Auto;
              else if (!strcmp(parm, "always"))
                  domBuilderValScheme = AbstractDOMParser::Val_Always;
              else
              {
                  XERCES_STD_QUALIFIER cerr << "Unknown -v= value: " << parm << XERCES_STD_QUALIFIER endl;
                  return 2;
              }
          }
           else if (!strcmp(argV[argInd], "-n")
                ||  !strcmp(argV[argInd], "-N"))
          {
              doNamespaces = true;
          }
           else if (!strcmp(argV[argInd], "-s")
                ||  !strcmp(argV[argInd], "-S"))
          {
              doSchema = true;
          }
           else if (!strcmp(argV[argInd], "-f")
                ||  !strcmp(argV[argInd], "-F"))
          {
              schemaFullChecking = true;
          }
           else if (!strcmp(argV[argInd], "-l")
                ||  !strcmp(argV[argInd], "-L"))
          {
              doList = true;
          }
           else if (!strncmp(argV[argInd], "-r=", 3)
                ||  !strncmp(argV[argInd], "-R=", 3))
          {
              const char* const numStr = &argV[argInd][3];
              XMLCh* numXStr = XMLString::transcode(numStr);
              numReps = XMLString::parseInt(numXStr);
              XMLString::release(&numXStr);
          }
           else
          {
              XERCES_STD_QUALIFIER cerr << "Unknown option '" << argV[argInd]
                   << "', ignoring it\n" << XERCES_STD_QUALIFIER endl;
          }
      }
  
      //
      //  There should be only one and only one parameter left, and that
      //  should be the file name.
      //
      if (argInd != argC - 1)
      {
          usage();
          return 1;
      }
  
      // Instantiate the DOM domBuilder with its memory manager.
      MemoryMonitor *domBuilderMemMonitor = new MemoryMonitor();
      static const XMLCh gLS[] = { chLatin_L, chLatin_S, chNull };
      DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(gLS);
      DOMBuilder        *domBuilder = ((DOMImplementationLS*)impl)->createDOMBuilder(DOMImplementationLS::MODE_SYNCHRONOUS, 0, domBuilderMemMonitor);
      DOMBuilderHandler domBuilderHandler;
      domBuilder->setErrorHandler(&domBuilderHandler);
  
      // Instantiate the SAX2 domBuilder with its memory manager.
      MemoryMonitor *sax2MemMonitor = new MemoryMonitor();
      SAX2XMLReader *sax2parser = XMLReaderFactory::createXMLReader(sax2MemMonitor);
      SAXErrorHandler saxErrorHandler;
      sax2parser->setErrorHandler(&saxErrorHandler);
  
      // Instantiate the deprecated DOM parser with its memory manager.
      MemoryMonitor *depDOMMemMonitor = new MemoryMonitor();
      DOMParser *depDOMParser = new (depDOMMemMonitor)DOMParser(0, depDOMMemMonitor);
      depDOMParser->setErrorHandler(&saxErrorHandler);
  
      // Instantiate the SAX 1 parser with its memory manager.
      MemoryMonitor *sax1MemMonitor = new MemoryMonitor();
      SAXParser *saxParser = new (sax1MemMonitor) SAXParser(0, sax1MemMonitor);
      saxParser->setErrorHandler(&saxErrorHandler);
  
      // set features 
      domBuilder->setFeature(XMLUni::fgDOMNamespaces, doNamespaces);
      sax2parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, doNamespaces);
      depDOMParser->setDoNamespaces(doNamespaces);
      saxParser->setDoNamespaces(doNamespaces);
  
      domBuilder->setFeature(XMLUni::fgXercesSchema, doSchema);
      sax2parser->setFeature(XMLUni::fgXercesSchema, doSchema);
      depDOMParser->setDoSchema(doSchema);
      saxParser->setDoSchema(doSchema);
  
      domBuilder->setFeature(XMLUni::fgXercesSchemaFullChecking, schemaFullChecking);
      sax2parser->setFeature(XMLUni::fgXercesSchemaFullChecking, schemaFullChecking);
      depDOMParser->setValidationSchemaFullChecking(schemaFullChecking);
      saxParser->setValidationSchemaFullChecking(schemaFullChecking);
  
      if (domBuilderValScheme == AbstractDOMParser::Val_Auto)
      {
          domBuilder->setFeature(XMLUni::fgDOMValidateIfSchema, true);
          sax2parser->setFeature(XMLUni::fgSAX2CoreValidation, true);
          sax2parser->setFeature(XMLUni::fgXercesDynamic, true);
          depDOMParser->setValidationScheme(DOMParser::Val_Auto);
          saxParser->setValidationScheme(SAXParser::Val_Auto);
      }
      else if (domBuilderValScheme == AbstractDOMParser::Val_Never)
      {
          domBuilder->setFeature(XMLUni::fgDOMValidation, false);
          sax2parser->setFeature(XMLUni::fgSAX2CoreValidation, false);
          depDOMParser->setValidationScheme(DOMParser::Val_Never);
          saxParser->setValidationScheme(SAXParser::Val_Never);
      }
      else if (domBuilderValScheme == AbstractDOMParser::Val_Always)
      {
          domBuilder->setFeature(XMLUni::fgDOMValidation, true);
          sax2parser->setFeature(XMLUni::fgSAX2CoreValidation, true);
          sax2parser->setFeature(XMLUni::fgXercesDynamic, false);
          depDOMParser->setValidationScheme(DOMParser::Val_Always);
          saxParser->setValidationScheme(SAXParser::Val_Always);
      }
  
      // enable datatype normalization - default is off
      domBuilder->setFeature(XMLUni::fgDOMDatatypeNormalization, true);
  
      XERCES_STD_QUALIFIER ifstream fin;
      bool more = true;
  
      // the input is a list file
      if (doList)
          fin.open(argV[argInd]);
  
      if (fin.fail()) {
          XERCES_STD_QUALIFIER cerr <<"Cannot open the list file: " << argV[argInd] << XERCES_STD_QUALIFIER endl;
          return 2;
      }
  
      while (more)
      {
          char fURI[1000];
          //initialize the array to zeros
          memset(fURI,0,sizeof(fURI));
  
          if (doList) {
              if (! fin.eof() ) {
                  fin.getline (fURI, sizeof(fURI));
                  if (!*fURI)
                      continue;
                  else {
                      xmlFile = fURI;
                      XERCES_STD_QUALIFIER cerr << "==Parsing== " << xmlFile << XERCES_STD_QUALIFIER endl;
                  }
              }
              else
                  break;
          }
          else {
              xmlFile = argV[argInd];
              more = false;
          }
  
          // parse numReps times (in case we need it for some reason)
          for (int i=0; i<numReps; i++)
          {
  
              XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *doc = 0;
  
              try
              {
                  // reset document pool
                  domBuilder->resetDocumentPool();
  
                  doc = domBuilder->parseURI(xmlFile);
                  sax2parser->parse(xmlFile);
                  depDOMParser->parse(xmlFile);
                  saxParser->parse(xmlFile);
              }
  
              catch (const XMLException& toCatch)
              {
                  char *msg = XMLString::transcode(toCatch.getMessage()); 
                  XERCES_STD_QUALIFIER cerr << "\nError during parsing: '" << xmlFile << "'\n"
                      << "Exception message is:  \n"
                      << msg << "\n" << XERCES_STD_QUALIFIER endl;
                  XMLString::release(&msg);
                  continue;
              }
              catch (const DOMException& toCatch)
              {
                  const unsigned int maxChars = 2047;
                  XMLCh errText[maxChars + 1];
  
                  XERCES_STD_QUALIFIER cerr << "\nDOM Error during parsing: '" << xmlFile << "'\n"
                      << "DOMException code is:  " << toCatch.code << XERCES_STD_QUALIFIER endl;
  
                  if (DOMImplementation::loadDOMExceptionMsg(toCatch.code, errText, maxChars))
                  {
                      char * msg = XMLString::transcode(errText); 
                      XERCES_STD_QUALIFIER cerr << "Message is: " << msg << XERCES_STD_QUALIFIER endl;
  
                      continue;
                  }
              }
              catch (...)
              {
                  XERCES_STD_QUALIFIER cerr << "\nUnexpected exception during parsing: '" << xmlFile << "'\n";
                  continue;
              }
  
          }
      }
  
      //
      //  Delete the domBuilder itself.  Must be done prior to calling Terminate, below.
      //
      domBuilder->release();
      delete sax2parser;
      delete depDOMParser;
      delete saxParser;
  
      XERCES_STD_QUALIFIER cout << "At destruction, domBuilderMemMonitor has " << domBuilderMemMonitor->getTotalMemory() << " bytes." << XERCES_STD_QUALIFIER endl;
      XERCES_STD_QUALIFIER cout << "At destruction, sax2MemMonitor has " << sax2MemMonitor->getTotalMemory() << " bytes." << XERCES_STD_QUALIFIER endl;
      XERCES_STD_QUALIFIER cout << "At destruction, depDOMMemMonitor has " << depDOMMemMonitor->getTotalMemory() << " bytes." << XERCES_STD_QUALIFIER endl;
      XERCES_STD_QUALIFIER cout << "At destruction, sax1MemMonitor has " << sax1MemMonitor->getTotalMemory() << " bytes." << XERCES_STD_QUALIFIER endl;
      delete domBuilderMemMonitor;
      delete sax2MemMonitor;
      delete depDOMMemMonitor;
      delete sax1MemMonitor;
  
      XMLPlatformUtils::Terminate();
      XERCES_STD_QUALIFIER cout << "At destruction, staticMemMonitor has " << staticMemMonitor->getTotalMemory() << " bytes." << XERCES_STD_QUALIFIER endl;
      delete staticMemMonitor;
      return 0;
  }
  
  
  
  
  1.1                  xml-xerces/c/tests/MemHandlerTest/MemoryMonitor.hpp
  
  Index: MemoryMonitor.hpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xerces" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache\@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation, and was
   * originally based on software copyright (c) 1999, International
   * Business Machines, Inc., http://www.ibm.com .  For more information
   * on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /*
   * $Id: MemoryMonitor.hpp,v 1.1 2003/06/02 22:22:26 neilg Exp $
   */
  
  
  #include <xercesc/framework/MemoryManager.hpp>
  #include <xercesc/util/PlatformUtils.hpp>
  #include <SimpleHashPtr.hpp>
  #include <xercesc/dom/DOMBuilder.hpp>
  #include <xercesc/dom/DOMErrorHandler.hpp>
  #include <xercesc/dom/DOMError.hpp>
  #include <xercesc/dom/DOMImplementation.hpp>
  #include <xercesc/dom/DOMImplementationLS.hpp>
  #include <xercesc/dom/DOMImplementationRegistry.hpp>
  #include <xercesc/parsers/AbstractDOMParser.hpp>
  #include <xercesc/sax2/XMLReaderFactory.hpp>
  #include <xercesc/sax2/SAX2XMLReader.hpp>
  #include <xercesc/sax/ErrorHandler.hpp>
  #include <xercesc/sax/SAXParseException.hpp>
  #include <xercesc/dom/deprecated/DOMParser.hpp>
  #include <xercesc/parsers/SAXParser.hpp>
  #include "SimpleValueHashTableOf.hpp"
  
  XERCES_CPP_NAMESPACE_USE
  
  /**
    * Configurable memory manager
    *
    * <p>This class is a memory manager implementation that keeps track of all 
    * allocations/deallocations to ensure that all memory that it allocated is 
    * deallocated.
    * </p>
    */
  
  class MemoryMonitor : public MemoryManager
  {
  public:
  
      /** @name Constructor */
      //@{
  
      /**
        * Default constructor
        */
      MemoryMonitor()
      { 
          fHashType = new SimpleHashPtr();
          fHashTable = new SimpleValueHashTableOf<unsigned int>(1013, fHashType);
      }
      //@}
  
  
      /** @name Destructor */
      //@{
  
      /**
        * Default destructor
        */
      virtual ~MemoryMonitor()
      {
          delete fHashTable;
      }
      //@}
  
      /** @name The virtual methods in MemoryManager */
      //@{
  
      /**
        * This method allocates requested memory.
        *
        * @param size The requested memory size
        *
        * @return A pointer to the allocated memory
        */
      virtual void* allocate(size_t size);
  
      /**
        * This method deallocates memory
        *
        * @param p The pointer to the allocated memory to be deleted
        */
      virtual void deallocate(void* p);
  
      //@}
      
      // Print out amount of currently allocated memory
      unsigned int getTotalMemory();
  
  private:
      // -----------------------------------------------------------------------
      //  Unimplemented constructors and operators
      // -----------------------------------------------------------------------
      MemoryMonitor(const MemoryMonitor &);
      MemoryMonitor& operator=(const MemoryMonitor &);
      SimpleValueHashTableOf<unsigned int>* fHashTable;
      SimpleHashPtr* fHashType;
  
  };
  
  
  
  
  
  1.1                  xml-xerces/c/tests/MemHandlerTest/SimpleHashPtr.cpp
  
  Index: SimpleHashPtr.cpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xerces" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache\@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation, and was
   * originally based on software copyright (c) 1999, International
   * Business Machines, Inc., http://www.ibm.com .  For more information
   * on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  #include <SimpleHashPtr.hpp>
  
  // this is just a copy of HashPtr which is careful to rely on global new.
  
  
  SimpleHashPtr::SimpleHashPtr()
  {
  }
  
  SimpleHashPtr::~SimpleHashPtr()
  {
  }
  
  unsigned int SimpleHashPtr::getHashVal(const void *const key, unsigned int mod)
  {
   return ((long)key % (unsigned long)mod);
  }
  
  bool SimpleHashPtr::equals(const void *const key1, const void *const key2)
  {
  	return (key1 == key2);
  }
  
  
  
  
  1.1                  xml-xerces/c/tests/MemHandlerTest/SimpleHashPtr.hpp
  
  Index: SimpleHashPtr.hpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xerces" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache\@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation, and was
   * originally based on software copyright (c) 1999, International
   * Business Machines, Inc., http://www.ibm.com .  For more information
   * on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  #if !defined(SIMPLEHASHPTR_HPP)
  #define SIMPLEHASHPTR_HPP
  
  
  /**
   * this is just a copy of the HashPtr class that doesn't rely on the
   * pluggable memory mechanism.
   */
  
  class SimpleHashPtr 
  {
  public:
  	SimpleHashPtr();
  	virtual ~SimpleHashPtr();
  	virtual unsigned int getHashVal(const void *const key, unsigned int mod);
  	virtual bool equals(const void *const key1, const void *const key2);
  
  };
  
  #endif
  
  
  
  
  1.1                  xml-xerces/c/tests/MemHandlerTest/SimpleValueHashTableOf.cpp
  
  Index: SimpleValueHashTableOf.cpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xerces" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache\@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation, and was
   * originally based on software copyright (c) 1999, International
   * Business Machines, Inc., http://www.ibm.com .  For more information
   * on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /**
   * $Log: SimpleValueHashTableOf.cpp,v $
   * Revision 1.1  2003/06/02 22:22:26  neilg
   * new test for the pluggable memory management mechanism.  This tests all 4 common Xerces parsers (SAX, SAX2, DOMBuilder and DeprecatedDOM) and ensures all allocated memory is dallocated, and that the manager which created the memory is called to deallocate it.
   *
   */
  
  #if defined(XERCES_TMPLSINC)
  #include <SimpleValueHashTableOf.hpp>
  #endif
  
  // ---------------------------------------------------------------------------
  //  Include
  // ---------------------------------------------------------------------------
  
  #include <xercesc/util/NullPointerException.hpp>
  
  
  // This is just an old version of the ValueHashTableOf implementation
  // from xercesc/util; we need a new one here because this
  // cannot use the pluggalbe memory management facilities.
  
  // forward declarations
  
  // ---------------------------------------------------------------------------
  //  ValueHashTableOf: Constructors and Destructor
  // ---------------------------------------------------------------------------
  template <class TVal> SimpleValueHashTableOf<TVal>::SimpleValueHashTableOf(const unsigned int modulus
              , SimpleHashPtr* hashBase)
  	: fBucketList(0), fHashModulus(modulus)
  {
  	initialize(modulus);
  	// set hasher
  	fHash = hashBase;
  }
  
  template <class TVal> SimpleValueHashTableOf<TVal>::SimpleValueHashTableOf(const unsigned int modulus)
  	: fBucketList(0), fHashModulus(modulus)
  {
  	initialize(modulus);
  
  	// create default hasher
  	fHash = new HashXMLCh();
  }
  
  template <class TVal> void SimpleValueHashTableOf<TVal>::initialize(const unsigned int modulus)
  {
  	if (modulus == 0)
          ThrowXML(IllegalArgumentException, XMLExcepts::HshTbl_ZeroModulus);
  
      // Allocate the bucket list and zero them
      fBucketList = new ValueHashTableBucketElem<TVal>*[fHashModulus];
      for (unsigned int index = 0; index < fHashModulus; index++)
          fBucketList[index] = 0;
  }
  
  template <class TVal> SimpleValueHashTableOf<TVal>::~SimpleValueHashTableOf()
  {
      removeAll();
  
      // Then delete the bucket list & hasher
      delete [] fBucketList;
  	delete fHash;
  }
  
  
  // ---------------------------------------------------------------------------
  //  SimpleValueHashTableOf: Element management
  // ---------------------------------------------------------------------------
  template <class TVal> bool SimpleValueHashTableOf<TVal>::isEmpty() const
  {
      // Just check the bucket list for non-empty elements
      for (unsigned int buckInd = 0; buckInd < fHashModulus; buckInd++)
      {
          if (fBucketList[buckInd] != 0)
              return false;
      }
      return true;
  }
  
  template <class TVal> bool SimpleValueHashTableOf<TVal>::
  containsKey(const void* const key) const
  {
      unsigned int hashVal;
      const ValueHashTableBucketElem<TVal>* findIt = findBucketElem(key, hashVal);
      return (findIt != 0);
  }
  
  template <class TVal> void SimpleValueHashTableOf<TVal>::
  removeKey(const void* const key)
  {
      unsigned int hashVal;
      removeBucketElem(key, hashVal);
  }
  
  template <class TVal> void SimpleValueHashTableOf<TVal>::removeAll()
  {
      // Clean up the buckets first
      for (unsigned int buckInd = 0; buckInd < fHashModulus; buckInd++)
      {
          // Get the bucket list head for this entry
          ValueHashTableBucketElem<TVal>* curElem = fBucketList[buckInd];
          ValueHashTableBucketElem<TVal>* nextElem;
          while (curElem)
          {
              // Save the next element before we hose this one
              nextElem = curElem->fNext;
  
              // delete the current element and move forward
              delete curElem;
              curElem = nextElem;
          }
  
          // Clean out this entry
          fBucketList[buckInd] = 0;
      }
  }
  
  
  // ---------------------------------------------------------------------------
  //  SimpleValueHashTableOf: Getters
  // ---------------------------------------------------------------------------
  template <class TVal> TVal& SimpleValueHashTableOf<TVal>::get(const void* const key)
  {
      unsigned int hashVal;
      ValueHashTableBucketElem<TVal>* findIt = findBucketElem(key, hashVal);
      if (!findIt)
          ThrowXML(NoSuchElementException, XMLExcepts::HshTbl_NoSuchKeyExists);
  
      return findIt->fData;
  }
  
  template <class TVal> const TVal& SimpleValueHashTableOf<TVal>::
  get(const void* const key) const
  {
      unsigned int hashVal;
      const ValueHashTableBucketElem<TVal>* findIt = findBucketElem(key, hashVal);
      if (!findIt)
          ThrowXML(NoSuchElementException, XMLExcepts::HshTbl_NoSuchKeyExists);
  
      return findIt->fData;
  }
  
  
  // ---------------------------------------------------------------------------
  //  SimpleValueHashTableOf: Putters
  // ---------------------------------------------------------------------------
  template <class TVal> void SimpleValueHashTableOf<TVal>::put(void* key, const TVal& valueToAdopt)
  {
      // First see if the key exists already
      unsigned int hashVal;
      ValueHashTableBucketElem<TVal>* newBucket = findBucketElem(key, hashVal);
  
      //
      //  If so,then update its value. If not, then we need to add it to
      //  the right bucket
      //
      if (newBucket)
      {
          newBucket->fData = valueToAdopt;
  		newBucket->fKey = key;
      }
       else
      {
          newBucket = new ValueHashTableBucketElem<TVal>(key, valueToAdopt, fBucketList[hashVal]);
          fBucketList[hashVal] = newBucket;
      }
  }
  
  
  
  // ---------------------------------------------------------------------------
  //  SimpleValueHashTableOf: Private methods
  // ---------------------------------------------------------------------------
  template <class TVal> ValueHashTableBucketElem<TVal>* SimpleValueHashTableOf<TVal>::
  findBucketElem(const void* const key, unsigned int& hashVal)
  {
      // Hash the key
      hashVal = fHash->getHashVal(key, fHashModulus);
      if (hashVal > fHashModulus)
          ThrowXML(RuntimeException, XMLExcepts::HshTbl_BadHashFromKey);
  
      // Search that bucket for the key
      ValueHashTableBucketElem<TVal>* curElem = fBucketList[hashVal];
      while (curElem)
      {
  		if (fHash->equals(key, curElem->fKey))
              return curElem;
  
          curElem = curElem->fNext;
      }
      return 0;
  }
  
  template <class TVal> const ValueHashTableBucketElem<TVal>* SimpleValueHashTableOf<TVal>::
  findBucketElem(const void* const key, unsigned int& hashVal) const
  {
      // Hash the key
      hashVal = fHash->getHashVal(key, fHashModulus);
      if (hashVal > fHashModulus)
          ThrowXML(RuntimeException, XMLExcepts::HshTbl_BadHashFromKey);
  
      // Search that bucket for the key
      const ValueHashTableBucketElem<TVal>* curElem = fBucketList[hashVal];
      while (curElem)
      {
          if (fHash->equals(key, curElem->fKey))
              return curElem;
  
          curElem = curElem->fNext;
      }
      return 0;
  }
  
  
  template <class TVal> void SimpleValueHashTableOf<TVal>::
  removeBucketElem(const void* const key, unsigned int& hashVal)
  {
      // Hash the key
      hashVal = fHash->getHashVal(key, fHashModulus);
      if (hashVal > fHashModulus)
          ThrowXML(RuntimeException, XMLExcepts::HshTbl_BadHashFromKey);
  
      //
      //  Search the given bucket for this key. Keep up with the previous
      //  element so we can patch around it.
      //
      ValueHashTableBucketElem<TVal>* curElem = fBucketList[hashVal];
      ValueHashTableBucketElem<TVal>* lastElem = 0;
  
      while (curElem)
      {
          if (fHash->equals(key, curElem->fKey))
          {
              if (!lastElem)
              {
                  // It was the first in the bucket
                  fBucketList[hashVal] = curElem->fNext;
              }
               else
              {
                  // Patch around the current element
                  lastElem->fNext = curElem->fNext;
              }
  
              // Delete the current element
              delete curElem;
  
              return;
          }
  
          // Move both pointers upwards
          lastElem = curElem;
          curElem = curElem->fNext;
      }
  
      // We never found that key
      ThrowXML(NoSuchElementException, XMLExcepts::HshTbl_NoSuchKeyExists);
  }
  
  
  
  
  // ---------------------------------------------------------------------------
  //  ValueHashTableOfEnumerator: Constructors and Destructor
  // ---------------------------------------------------------------------------
  template <class TVal> ValueHashTableOfEnumerator<TVal>::
  ValueHashTableOfEnumerator(SimpleValueHashTableOf<TVal>* const toEnum, const bool adopt)
  	: fAdopted(adopt), fCurElem(0), fCurHash((unsigned int)-1), fToEnum(toEnum)
  {
      if (!toEnum)
          ThrowXML(NullPointerException, XMLExcepts::CPtr_PointerIsZero);
  
      //
      //  Find the next available bucket element in the hash table. If it
      //  comes back zero, that just means the table is empty.
      //
      //  Note that the -1 in the current hash tells it to start from the
      //  beginning.
      //
      findNext();
  }
  
  template <class TVal> ValueHashTableOfEnumerator<TVal>::~ValueHashTableOfEnumerator()
  {
      if (fAdopted)
          delete fToEnum;
  }
  
  
  // ---------------------------------------------------------------------------
  //  ValueHashTableOfEnumerator: Enum interface
  // ---------------------------------------------------------------------------
  template <class TVal> bool ValueHashTableOfEnumerator<TVal>::hasMoreElements() const
  {
      //
      //  If our current has is at the max and there are no more elements
      //  in the current bucket, then no more elements.
      //
      if (!fCurElem && (fCurHash == fToEnum->fHashModulus))
          return false;
      return true;
  }
  
  template <class TVal> TVal& ValueHashTableOfEnumerator<TVal>::nextElement()
  {
      // Make sure we have an element to return
      if (!hasMoreElements())
          ThrowXML(NoSuchElementException, XMLExcepts::Enum_NoMoreElements);
  
      //
      //  Save the current element, then move up to the next one for the
      //  next time around.
      //
      ValueHashTableBucketElem<TVal>* saveElem = fCurElem;
      findNext();
  
      return saveElem->fData;
  }
  
  
  template <class TVal> void ValueHashTableOfEnumerator<TVal>::Reset()
  {
      fCurHash = (unsigned int)-1;
      fCurElem = 0;
      findNext();
  }
  
  
  
  // ---------------------------------------------------------------------------
  //  ValueHashTableOfEnumerator: Private helper methods
  // ---------------------------------------------------------------------------
  template <class TVal> void ValueHashTableOfEnumerator<TVal>::findNext()
  {
      //
      //  If there is a current element, move to its next element. If this
      //  hits the end of the bucket, the next block will handle the rest.
      //
      if (fCurElem)
          fCurElem = fCurElem->fNext;
  
      //
      //  If the current element is null, then we have to move up to the
      //  next hash value. If that is the hash modulus, then we cannot
      //  go further.
      //
      if (!fCurElem)
      {
          fCurHash++;
          if (fCurHash == fToEnum->fHashModulus)
              return;
  
          // Else find the next non-empty bucket
          while (true)
          {
              if (fToEnum->fBucketList[fCurHash])
                  break;
  
              // Bump to the next hash value. If we max out return
              fCurHash++;
              if (fCurHash == fToEnum->fHashModulus)
                  return;
          }
          fCurElem = fToEnum->fBucketList[fCurHash];
      }
  }
  
  
  
  
  1.1                  xml-xerces/c/tests/MemHandlerTest/SimpleValueHashTableOf.hpp
  
  Index: SimpleValueHashTableOf.hpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xerces" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache\@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation, and was
   * originally based on software copyright (c) 1999, International
   * Business Machines, Inc., http://www.ibm.com .  For more information
   * on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /*
   * $Id: SimpleValueHashTableOf.hpp,v 1.1 2003/06/02 22:22:26 neilg Exp $
   */
  
  
  
  #include <xercesc/util/XercesDefs.hpp>
  #include <SimpleHashPtr.hpp>
  #include <xercesc/util/IllegalArgumentException.hpp>
  #include <xercesc/util/NoSuchElementException.hpp>
  #include <xercesc/util/RuntimeException.hpp>
  #include <xercesc/util/XMLExceptMsgs.hpp>
  #include <xercesc/util/XMLEnumerator.hpp>
  #include <xercesc/util/XMLString.hpp>
  
  XERCES_CPP_NAMESPACE_USE
  
  //
  //  Forward declare the enumerator so he can be our friend. Can you say
  //  friend, neighbour? Of course you can...
  //
  template <class TVal> class ValueHashTableOfEnumerator;
  template <class TVal> struct ValueHashTableBucketElem;
  
  
  //
  //  This should really be a nested class, but some of the compilers we
  //  have to support cannot deal with that!
  //
  template <class TVal> struct ValueHashTableBucketElem
  {
      ValueHashTableBucketElem(void* key, const TVal& value, ValueHashTableBucketElem<TVal>* next)
  		: fData(value), fNext(next), fKey(key)
          {
          }
  
      TVal                           fData;
      ValueHashTableBucketElem<TVal>* fNext;
  	void*                          fKey;
  };
  
  
  template <class TVal> class SimpleValueHashTableOf
  {
  public:
      // -----------------------------------------------------------------------
      //  Constructors and Destructor
      // -----------------------------------------------------------------------
  	// backwards compatability - default hasher is SimpleHasPtrh
      SimpleValueHashTableOf(const unsigned int modulus);
  	// if a hash function is passed in, it will be deleted when the hashtable is deleted.
  	// use a new instance of the hasher class for each hashtable, otherwise one hashtable
  	// may delete the hasher of a different hashtable if both use the same hasher.
      SimpleValueHashTableOf(const unsigned int modulus, SimpleHashPtr* hashBase);
      ~SimpleValueHashTableOf();
  
  
      // -----------------------------------------------------------------------
      //  Element management
      // -----------------------------------------------------------------------
      bool isEmpty() const;
      bool containsKey(const void* const key) const;
      void removeKey(const void* const key);
      void removeAll();
  
  
      // -----------------------------------------------------------------------
      //  Getters
      // -----------------------------------------------------------------------
      TVal& get(const void* const key);
      const TVal& get(const void* const key) const;
  
  
      // -----------------------------------------------------------------------
      //  Putters
      // -----------------------------------------------------------------------
  	void put(void* key, const TVal& valueToAdopt);
  
  
  private :
      // -----------------------------------------------------------------------
      //  Declare our friends
      // -----------------------------------------------------------------------
      friend class ValueHashTableOfEnumerator<TVal>;
  
  private:
  
      // -----------------------------------------------------------------------
      //  Private methods
      // -----------------------------------------------------------------------
      ValueHashTableBucketElem<TVal>* findBucketElem(const void* const key, unsigned int& hashVal);
      const ValueHashTableBucketElem<TVal>* findBucketElem(const void* const key, unsigned int& hashVal) const;
      void removeBucketElem(const void* const key, unsigned int& hashVal);
  	void initialize(const unsigned int modulus);
  
  
      // -----------------------------------------------------------------------
      //  Data members
      //
      //  fBucketList
      //      This is the array that contains the heads of all of the list
      //      buckets, one for each possible hash value.
      //
      //  fHashModulus
      //      The modulus used for this hash table, to hash the keys. This is
      //      also the number of elements in the bucket list.
  	//
  	//  fHash
  	//      The hasher for the key data type.
      // -----------------------------------------------------------------------
      ValueHashTableBucketElem<TVal>** fBucketList;
      unsigned int                    fHashModulus;
  	SimpleHashPtr*                       fHash;
  };
  
  
  
  //
  //  An enumerator for a value array. It derives from the basic enumerator
  //  class, so that value vectors can be generically enumerated.
  //
  template <class TVal> class ValueHashTableOfEnumerator : public XMLEnumerator<TVal>
  {
  public :
      // -----------------------------------------------------------------------
      //  Constructors and Destructor
      // -----------------------------------------------------------------------
      ValueHashTableOfEnumerator(SimpleValueHashTableOf<TVal>* const toEnum, const bool adopt = false);
      virtual ~ValueHashTableOfEnumerator();
  
  
      // -----------------------------------------------------------------------
      //  Enum interface
      // -----------------------------------------------------------------------
      bool hasMoreElements() const;
      TVal& nextElement();
      void Reset();
  
  
  private :
      // -----------------------------------------------------------------------
      //  Private methods
      // -----------------------------------------------------------------------
      void findNext();
  
  
      // -----------------------------------------------------------------------
      //  Data Members
      //
      //  fAdopted
      //      Indicates whether we have adopted the passed vector. If so then
      //      we delete the vector when we are destroyed.
      //
      //  fCurElem
      //      This is the current bucket bucket element that we are on.
      //
      //  fCurHash
      //      The is the current hash buck that we are working on. Once we hit
      //      the end of the bucket that fCurElem is in, then we have to start
      //      working this one up to the next non-empty bucket.
      //
      //  fToEnum
      //      The value array being enumerated.
      // -----------------------------------------------------------------------
      bool                            fAdopted;
      ValueHashTableBucketElem<TVal>* fCurElem;
      unsigned int                    fCurHash;
      SimpleValueHashTableOf<TVal>*         fToEnum;
  
  };
  
  #if !defined(XERCES_TMPLSINC)
  #include <SimpleValueHashTableOf.cpp>
  #endif
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-cvs-help@xml.apache.org