Initial import
git-svn-id: http://moon:8086/svn/software/trunk/libsrc/xerces-c-3.0.0@1 b431acfa-c32f-4a4a-93f1-934dc6c82436
This commit is contained in:
Executable
+439
@@ -0,0 +1,439 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: MemoryMonitor.cpp 674434 2008-07-07 09:39:20Z amassari $
|
||||
*/
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 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>
|
||||
#include <xercesc/util/OutOfMemoryException.hpp>
|
||||
#include <xercesc/dom/DOM.hpp>
|
||||
|
||||
MemoryManager* MemoryMonitor::getExceptionMemoryManager()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
void* MemoryMonitor::allocate(XMLSize_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->containsKey(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"
|
||||
" MemHandlerTest [options] <XML file | List file>\n\n"
|
||||
"This program invokes the XercesDOMParser, DOMLSParser, 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 DOMLSParserHandler : public DOMErrorHandler
|
||||
{
|
||||
public:
|
||||
DOMLSParserHandler() {};
|
||||
~DOMLSParserHandler() {};
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class SAXErrorHandler : public ErrorHandler
|
||||
{
|
||||
public:
|
||||
SAXErrorHandler() {};
|
||||
~SAXErrorHandler() {};
|
||||
void warning(const SAXParseException &exc )
|
||||
{
|
||||
char *message = 0;
|
||||
XERCES_STD_QUALIFIER cerr << "SAX warning received! Text: " <<
|
||||
(message = XMLString::transcode(exc.getMessage())) << "." << XERCES_STD_QUALIFIER endl;
|
||||
XMLString::release(&message);
|
||||
}
|
||||
void error(const SAXParseException &exc )
|
||||
{
|
||||
char *message = 0;
|
||||
XERCES_STD_QUALIFIER cerr << "SAX error received! Text: " <<
|
||||
(message = XMLString::transcode(exc.getMessage())) << "." << XERCES_STD_QUALIFIER endl;
|
||||
XMLString::release(&message);
|
||||
}
|
||||
void fatalError(const SAXParseException &exc )
|
||||
{
|
||||
char *message = 0;
|
||||
XERCES_STD_QUALIFIER cerr << "SAX fatalError received! Text: " <<
|
||||
(message = XMLString::transcode(exc.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;
|
||||
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);
|
||||
DOMLSParser *domBuilder = ((DOMImplementationLS*)impl)->createLSParser(DOMImplementationLS::MODE_SYNCHRONOUS, 0, domBuilderMemMonitor);
|
||||
DOMLSParserHandler domBuilderHandler;
|
||||
domBuilder->getDomConfig()->setParameter(XMLUni::fgDOMErrorHandler, &domBuilderHandler);
|
||||
|
||||
// Instantiate the SAX2 parser with its memory manager.
|
||||
MemoryMonitor *sax2MemMonitor = new MemoryMonitor();
|
||||
SAX2XMLReader *sax2parser = XMLReaderFactory::createXMLReader(sax2MemMonitor);
|
||||
SAXErrorHandler saxErrorHandler;
|
||||
sax2parser->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->getDomConfig()->setParameter(XMLUni::fgDOMNamespaces, doNamespaces);
|
||||
sax2parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, doNamespaces);
|
||||
saxParser->setDoNamespaces(doNamespaces);
|
||||
|
||||
domBuilder->getDomConfig()->setParameter(XMLUni::fgXercesSchema, doSchema);
|
||||
sax2parser->setFeature(XMLUni::fgXercesSchema, doSchema);
|
||||
saxParser->setDoSchema(doSchema);
|
||||
|
||||
domBuilder->getDomConfig()->setParameter(XMLUni::fgXercesSchemaFullChecking, schemaFullChecking);
|
||||
sax2parser->setFeature(XMLUni::fgXercesSchemaFullChecking, schemaFullChecking);
|
||||
saxParser->setValidationSchemaFullChecking(schemaFullChecking);
|
||||
|
||||
if (domBuilderValScheme == AbstractDOMParser::Val_Auto)
|
||||
{
|
||||
domBuilder->getDomConfig()->setParameter(XMLUni::fgDOMValidateIfSchema, true);
|
||||
sax2parser->setFeature(XMLUni::fgSAX2CoreValidation, true);
|
||||
sax2parser->setFeature(XMLUni::fgXercesDynamic, true);
|
||||
saxParser->setValidationScheme(SAXParser::Val_Auto);
|
||||
}
|
||||
else if (domBuilderValScheme == AbstractDOMParser::Val_Never)
|
||||
{
|
||||
domBuilder->getDomConfig()->setParameter(XMLUni::fgDOMValidate, false);
|
||||
sax2parser->setFeature(XMLUni::fgSAX2CoreValidation, false);
|
||||
saxParser->setValidationScheme(SAXParser::Val_Never);
|
||||
}
|
||||
else if (domBuilderValScheme == AbstractDOMParser::Val_Always)
|
||||
{
|
||||
domBuilder->getDomConfig()->setParameter(XMLUni::fgDOMValidate, true);
|
||||
sax2parser->setFeature(XMLUni::fgSAX2CoreValidation, true);
|
||||
sax2parser->setFeature(XMLUni::fgXercesDynamic, false);
|
||||
saxParser->setValidationScheme(SAXParser::Val_Always);
|
||||
}
|
||||
|
||||
// enable datatype normalization - default is off
|
||||
domBuilder->getDomConfig()->setParameter(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);
|
||||
if(doc && doc->getDocumentElement())
|
||||
{
|
||||
XERCES_CPP_NAMESPACE_QUALIFIER DOMNodeList *list=NULL;
|
||||
if(doNamespaces)
|
||||
list=doc->getElementsByTagNameNS(doc->getDocumentElement()->getNamespaceURI(), doc->getDocumentElement()->getLocalName());
|
||||
else
|
||||
list=doc->getElementsByTagName(doc->getDocumentElement()->getNodeName());
|
||||
if(list==NULL)
|
||||
XERCES_STD_QUALIFIER cout << "getElementsByTagName didn't return a valid DOMNodeList." << XERCES_STD_QUALIFIER endl;
|
||||
else if(list->item(0)!=doc->getDocumentElement())
|
||||
XERCES_STD_QUALIFIER cout << "getElementsByTagName didn't find the root element." << XERCES_STD_QUALIFIER endl;
|
||||
}
|
||||
sax2parser->parse(xmlFile);
|
||||
saxParser->parse(xmlFile);
|
||||
}
|
||||
catch (const OutOfMemoryException&)
|
||||
{
|
||||
XERCES_STD_QUALIFIER cerr << "OutOfMemoryException during parsing: '" << xmlFile << "'\n" << XERCES_STD_QUALIFIER endl;;
|
||||
continue;
|
||||
}
|
||||
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 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, sax1MemMonitor has " << sax1MemMonitor->getTotalMemory() << " bytes." << XERCES_STD_QUALIFIER endl;
|
||||
delete domBuilderMemMonitor;
|
||||
delete sax2MemMonitor;
|
||||
delete sax1MemMonitor;
|
||||
|
||||
XMLPlatformUtils::Terminate();
|
||||
XERCES_STD_QUALIFIER cout << "At destruction, staticMemMonitor has " << staticMemMonitor->getTotalMemory() << " bytes." << XERCES_STD_QUALIFIER endl;
|
||||
delete staticMemMonitor;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user