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 [EMAIL PROTECTED] # # 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 [EMAIL PROTECTED] * * 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 [EMAIL PROTECTED] * * 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 [EMAIL PROTECTED] * * 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 [EMAIL PROTECTED] * * 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 [EMAIL PROTECTED] * * 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 [EMAIL PROTECTED] * * 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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]