/*
 * 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: ThreadTest.cpp 568078 2007-08-21 11:43:25Z amassari $
 *
 * @author Andy Heninger, IBM
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <xercesc/parsers/SAXParser.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/sax/HandlerBase.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>

#include <xercesc/sax2/SAX2XMLReader.hpp>
#include <xercesc/sax2/XMLReaderFactory.hpp>
#include <xercesc/sax2/Attributes.hpp>
#include <xercesc/sax2/DefaultHandler.hpp>

#include <xercesc/dom/DOM.hpp>

#include <xercesc/framework/StdOutFormatTarget.hpp>
#include <xercesc/internal/XMLGrammarPoolImpl.hpp>
#include <xercesc/internal/MemoryManagerImpl.hpp>
#include <xercesc/util/OutOfMemoryException.hpp>

void clearFileInfoMemory();

//------------------------------------------------------------------------------
//
//   Windows specific code for starting threads
//
//------------------------------------------------------------------------------
#ifdef PLATFORM_WIN32

#include "Windows.h"
#include "process.h"

typedef DWORD (WINAPI *ThreadFunc)(void *);

class ThreadFuncs           // This class isolates OS dependent threading
{                           //   functions from the rest of ThreadTest program.
public:
    static void Sleep(int millis) {::Sleep(millis);};
    static void startThread(ThreadFunc, void *param);
};

void ThreadFuncs::startThread(ThreadFunc func, void *param)
{
    HANDLE  tHandle;
    DWORD   threadID;

    tHandle = CreateThread(0,          // Security Attributes,
                           0x10000,    // Stack Size,
                           func,       // Starting Address.
                           param,      // Parmeters
                           0,          // Creation Flags,
                           &threadID); // Thread ID (Can not be null on 95/98)

    if (tHandle == 0)
    {
        fprintf(stderr, "Error starting thread.  Errno = %d\n", errno);
        clearFileInfoMemory();
        exit(-1);
    }

    // Set the priority of the working threads low, so that the UI of the running system will
    //   remain responsive.
    SetThreadPriority(tHandle, THREAD_PRIORITY_IDLE);
}


#elif defined (AIX) || defined(SOLARIS) || defined(LINUX) || defined(HPUX) || defined (OS390) || defined(MACOSX) || defined(FREEBSD) || defined(__CYGWIN__) || defined(__QNXNTO__) || defined(INTERIX) || defined(IRIX)
#include <pthread.h>
#include <unistd.h>
#include <errno.h>


//------------------------------------------------------------------------------
//
//   UNIX specific code for starting threads
//
//------------------------------------------------------------------------------

extern "C" {

typedef void (*ThreadFunc)(void *);
typedef void *(*pthreadfunc)(void *);

class ThreadFuncs           // This class isolates OS dependent threading
{                           //   functions from the rest of ThreadTest program.
public:
    static void Sleep(int millis);
    static void startThread(ThreadFunc, void *param);
};

void ThreadFuncs::Sleep(int millis)
{
   int seconds = millis/1000;
   if (seconds <= 0) seconds = 1;
#if defined(SOLARIS)
   // somehow the sleep hangs on Solaris
   // so ignore the call
#else
   ::sleep(seconds);
#endif
}


void ThreadFuncs::startThread(ThreadFunc func, void *param)
{
    unsigned long x;

    pthread_t tId;
    //thread_t tId;
#if defined(_HP_UX) && defined(XML_USE_DCE)
    x = pthread_create( &tId, pthread_attr_default,  (pthreadfunc)func,  param);
#else
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    x = pthread_create( &tId, &attr,  (pthreadfunc)func,  param);
#endif
    if (x == -1)
    {
        fprintf(stderr, "Error starting thread.  Errno = %d\n", errno);
        clearFileInfoMemory();
        exit(-1);
    }

}

} // end of extern "C"
#else
#error This platform is not supported
#endif


//------------------------------------------------------------------------------
//
//  struct InFileInfo   One of these structs will be set up for each file listed
//                      on the command line.  Once set, the data is unchanging
//                      and can safely be referenced by the test threads without
//                      use of synchronization.
//
//------------------------------------------------------------------------------
struct InFileInfo
{
    char    *fileName;
    XMLCh   *uFileName;      // When doing an in-memory parse, avoid transcoding file name
                             //    each time through.
    char    *fileContent;    // If doing an in-memory parse, this field points
                             //   to an allocated string containing the entire file
                             //   contents.  Otherwise it's 0.
    size_t  fileSize;        // The file length.  Only initialized when doing
                             //   an in-memory test.
    int     checkSum;        // The XML checksum.  Set up by the main thread for
                             //   each file before the worker threads are started.
};


//------------------------------------------------------------------------------
//
//  struct threadInfo  Holds information specific to an individual thread.
//                     One of these is set up for each thread in the test.
//                     The main program monitors the threads by looking
//                     at the status stored in these structs.
//
//------------------------------------------------------------------------------
struct ThreadInfo
{
    bool            fHeartBeat;   // Set true by the thread each time it finishes
                                  //   parsing a file.
    bool            fInProgress;  // Set to false by the thread when parse in progress
    unsigned int    fParses;      // Number of parses completed.
    int             fThreadNum;   // Identifying number for this thread.
    ThreadInfo() {
        fHeartBeat = false;
        fInProgress = false;
        fParses = 0;
        fThreadNum = -1;
    }
};


XERCES_CPP_NAMESPACE_USE
//------------------------------------------------------------------------------
//
//  struct runInfo     Holds the info extracted from the command line.
//                     There is only one of these, and it is static, and
//                     unchanging once the command line has been parsed.
//                     During the test, the threads will access this info without
//                     any synchronization.
//
//------------------------------------------------------------------------------
const int MAXINFILES = 25;
struct RunInfo
{    
    bool                            doGrammarCaching;    
    bool                            quiet;
    bool                            verbose;
    bool                            stopNow;        
    bool                            dom;    
    bool                            sax;    
    bool                            reuseParser;
    bool                            inMemory;
    bool                            dumpOnErr;
    bool                            doSchema;
    bool                            schemaFullChecking;
    bool                            doNamespaces;
    bool                            doInitialParse;    
    bool                            doNamespacePrefixes;  // SAX2    
    SAXParser::ValSchemes           valScheme;
    int                             numThreads;
    int                             totalTime;
    int                             numInputFiles;
    unsigned int                    numParses;
    InFileInfo                      files[MAXINFILES];
};

//
//------------------------------------------------------------------------------
//
//  Global Data
//
//------------------------------------------------------------------------------
RunInfo         gRunInfo;
ThreadInfo      *gThreadInfo;

/** Grammar caching thread testing */
MemoryManager*  gpMemMgr = 0;
XMLGrammarPool* gp = 0;

// Routines which maybe helpful for debugging
static void printString(const XMLCh *str)
{
    char *s = XMLString::transcode(str);
    printf("%s", s);
    delete s;
}

#define CHARS_PER_LINE           40
#define BYTES_PER_LINE           16

/*
 * DumpLine: Dump out a buffer (address and length) to stderr.
 */
static void DumpLine(char* address, int length) {
    int i, c, charCount=0;
    if (length % 4) length += 4;
    fprintf(stderr, "%8.8p: ", address);
    for (i=0; i < length/4; ++i) {
        fprintf(stderr, "%8.8X ", ((int*)address)[i]);
        charCount += 9;
    }
    for (i=charCount; i < CHARS_PER_LINE; ++i) {
        putc(' ', stderr);
    }
    fprintf(stderr, "| ");
    for (i=0; i < length; ++i) {
        c = address[i];
        c = (isprint(c) ? c : '.');
        fprintf(stderr, "%c", c);
    }
    fprintf(stderr, "\n");
}

/*
 * dump: dump out a buffer (address and length) to stderr by dumping out
 *       a line at a time (DumpLine), until the buffer is written out.
 */

static void dump(void* generalAddress, int length) {
    int curr = 0;
    char* address = (char*) generalAddress;
    while (&address[curr] < &address[length-BYTES_PER_LINE]) {
        DumpLine(&address[curr], BYTES_PER_LINE);
        curr += BYTES_PER_LINE;
    }
    if (curr < length) {
        DumpLine(&address[curr], length-curr);
    }
    fflush(stderr);
}

//------------------------------------------------------------------------------
//
//  class ThreadParser   Bundles together a SAX parser and the SAX handlers
//                       and contains the API that the rest of this test
//                       program uses for creating parsers and doing parsing.
//
//                       Multiple instances of this class can operate concurrently
//                       in different threads.
//
//-------------------------------------------------------------------------------

class ThreadParser
{
public:
    class SAXHandler;
    class SAX2Handler;
    SAXHandler*     fSAXHandler;
    SAX2Handler*    fSAX2Handler;
    ErrorHandler*   fDOMErrorHandler;
    
    //  This is the API used by the rest of the test program
    ThreadParser();
    ~ThreadParser();

    int parse(int fileNum);           // Parse the specified file.  fileNum is an index
                                      //   into the gRunInfo.files array.
                                      //  return the XML checksum, or
                                      //  0 if a parse error occurred.

    int getCheckSum() {
        return fCheckSum;
    };

    int reCheck();                    // Try to compute the checksum again.
                                      //  for DOM, re-walk the tree.
                                      //  for SAX, can't do, just return previous value.

    void domPrint();                  //   including any children.  Default (no param)
                                       //   version dumps the entire document.
    void  addToCheckSum(const XMLCh *chars, int len=-1);
    
    //  These are the SAX call-back functions that this class implements. Can be used
    //  for SAX and SAX2.
    void characters(const XMLCh* const chars, const unsigned int length) {
        addToCheckSum(chars, length);
    };
    
    void ignorableWhitespace(const XMLCh* const chars, const unsigned int length) {
        addToCheckSum(chars, length);
    };
    
    void resetDocument() {
    };

    void warning(const SAXParseException& exc)     {
        fprintf(stderr, "*** Warning ");
        fflush(stderr);
        throw exc;
    };

    void error(const SAXParseException& exc)       {
        fprintf(stderr, "*** Error ");
        fflush(stderr);
        throw exc;
    };

    void fatalError(const SAXParseException& exc)  {
        fprintf(stderr, "***** Fatal error ");
        fflush(stderr);
        throw exc;
    };

    // Create a nested class that can inherit from HandlerBase
    // for SAX startElement callbacks.
    class SAXHandler :  public HandlerBase
    {
    public:
        ThreadParser* SAXInstance;

        void startElement(const XMLCh* const name, AttributeList& attributes);
    };

    // Create a nested class that can inherit from DefaultHandler
    // for SAX2 startElement callbacks.
    class SAX2Handler :  public DefaultHandler
    {
    public:
        ThreadParser* SAX2Instance;

        void startElement(const XMLCh* const uri,
                          const XMLCh* const localname,
                          const XMLCh* const qname,
                          const Attributes& attributes);
    };

private:
    int                                             fCheckSum;
    SAXParser*                                      fSAXParser;
    SAX2XMLReader*                                  fSAX2Parser;
    XercesDOMParser*                                fXercesDOMParser;
    XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *    fDoc;


    ThreadParser(const ThreadParser &); // No copy constructor
    const ThreadParser & operator =(const ThreadParser &); // No assignment.

    void  domCheckSum(const DOMNode *);
};

//
//  ThreadParser constructor.  Invoked by the threads of the test program
//                              to create parsers.
//
ThreadParser::ThreadParser()
{   
    fSAXParser       = 0;
    fSAX2Parser      = 0;
    fXercesDOMParser = 0;
    fSAXHandler      = 0;
    fSAX2Handler     = 0;
    fDOMErrorHandler = 0;    
    fDoc             = 0;
    fCheckSum        = 0;

    if (gRunInfo.dom) {
        // Set up to use a DOM parser
        /** Grammar caching thread testing */
        if (gp) {
            fXercesDOMParser = new XercesDOMParser(0, XMLPlatformUtils::fgMemoryManager, gp);
            fXercesDOMParser->cacheGrammarFromParse(true);
            fXercesDOMParser->useCachedGrammarInParse(true);
        }        
        else {
            fXercesDOMParser = new XercesDOMParser;
        }
        switch (gRunInfo.valScheme) {
            case SAXParser::Val_Never:
                fXercesDOMParser->setValidationScheme(XercesDOMParser::Val_Never);
                break;
            case SAXParser::Val_Auto:
                fXercesDOMParser->setValidationScheme(XercesDOMParser::Val_Auto);
                break;
            default: //SAXParser::Val_Always:
                fXercesDOMParser->setValidationScheme(XercesDOMParser::Val_Always);
                break;
        }        
        fXercesDOMParser->setDoSchema(gRunInfo.doSchema);
        fXercesDOMParser->setValidationSchemaFullChecking(gRunInfo.schemaFullChecking);
        fXercesDOMParser->setDoNamespaces(gRunInfo.doNamespaces);
        fDOMErrorHandler = (ErrorHandler*) new HandlerBase();
        fXercesDOMParser->setErrorHandler(fDOMErrorHandler);
    }

    else if (gRunInfo.sax) {
        // Set up to use a SAX1 parser.
        /** Grammar caching thread testing */
        if (gp) {
            fSAXParser = new SAXParser(0, XMLPlatformUtils::fgMemoryManager, gp);
            fSAXParser->cacheGrammarFromParse(true);
            fSAXParser->useCachedGrammarInParse(true);
        }        
        else {
            fSAXParser = new SAXParser();
        }
        fSAXParser->setValidationScheme(gRunInfo.valScheme);
        fSAXParser->setDoSchema(gRunInfo.doSchema);
        fSAXParser->setValidationSchemaFullChecking(gRunInfo.schemaFullChecking);
        fSAXParser->setDoNamespaces(gRunInfo.doNamespaces);
        fSAXHandler = new ThreadParser::SAXHandler();
        fSAXHandler->SAXInstance = this;
        fSAXParser->setDocumentHandler(fSAXHandler);
        fSAXParser->setErrorHandler(fSAXHandler);
    }

    else { 
        // Set up to use a SAX2 parser.
        /** Grammar caching thread testing */
        if (gp) {            
            fSAX2Parser = XMLReaderFactory::createXMLReader(gpMemMgr, gp);
            fSAX2Parser->setFeature(XMLUni::fgXercesCacheGrammarFromParse,true);
            fSAX2Parser->setFeature(XMLUni::fgXercesUseCachedGrammarInParse,true);
        }
        else {
            fSAX2Parser = XMLReaderFactory::createXMLReader();
        }

        fSAX2Parser->setFeature(XMLUni::fgSAX2CoreNameSpaces,(gRunInfo.doNamespaces));
        fSAX2Parser->setFeature(XMLUni::fgXercesSchema,(gRunInfo.doSchema));
        fSAX2Parser->setFeature(XMLUni::fgXercesSchemaFullChecking,(gRunInfo.schemaFullChecking));

        switch (gRunInfo.valScheme) {
            case SAXParser::Val_Never:
                fSAX2Parser->setFeature(XMLUni::fgSAX2CoreValidation, false);
                break;
            case SAXParser::Val_Auto:
                fSAX2Parser->setFeature(XMLUni::fgSAX2CoreValidation, true);
                fSAX2Parser->setFeature(XMLUni::fgXercesDynamic, true);
                break;
            default: //SAXParser::Val_Always:
                fSAX2Parser->setFeature(XMLUni::fgSAX2CoreValidation, true);
                fSAX2Parser->setFeature(XMLUni::fgXercesDynamic, false);
                break;
        }            
        
        fSAX2Parser->setFeature(XMLUni::fgSAX2CoreNameSpacePrefixes,(gRunInfo.doNamespacePrefixes));        
        fSAX2Handler = new ThreadParser::SAX2Handler();
        fSAX2Handler->SAX2Instance = this;
        fSAX2Parser->setContentHandler(fSAX2Handler);
        fSAX2Parser->setErrorHandler(fSAX2Handler);
    }
}

ThreadParser::~ThreadParser()
{
     delete fSAXParser;          
     delete fSAX2Parser;
     delete fXercesDOMParser;
     delete fSAXHandler;
     delete fSAX2Handler;     
     delete fDOMErrorHandler;
}

//------------------------------------------------------------------------
//
//  parse   - This is the method that is invoked by the rest of
//            the test program to actually parse an XML file.
//
//------------------------------------------------------------------------
int ThreadParser::parse(int fileNum)
{
    MemBufInputSource *mbis = 0;
    InFileInfo        *fInfo = &gRunInfo.files[fileNum];
    bool              errors = false;

    fCheckSum = 0;

    if (gRunInfo.inMemory) {
        mbis = new  MemBufInputSource((const XMLByte *) fInfo->fileContent,
                                       fInfo->fileSize,
                                       fInfo->uFileName,
                                       false);
    }

    try
    {
        if (gRunInfo.dom) {
            // Do a DOM parse
            fXercesDOMParser->resetDocumentPool();
            if (gRunInfo.inMemory)
                fXercesDOMParser->parse(*mbis);
            else
                fXercesDOMParser->parse(fInfo->fileName);
            fDoc = fXercesDOMParser->getDocument();
            domCheckSum(fDoc);
        }
        else if (gRunInfo.sax) {
            // Do a SAX1 parse
            if (gRunInfo.inMemory)
                fSAXParser->parse(*mbis);
            else
                fSAXParser->parse(fInfo->fileName);
        }
        else {
            // Do a SAX2 parse
            if (gRunInfo.inMemory)
                fSAX2Parser->parse(*mbis);
            else
                fSAX2Parser->parse(fInfo->fileName);
        }
    }
    catch (const OutOfMemoryException&)
    {
	    fprintf(stderr, " during parsing: %s\n OutOfMemoryException.\n", fInfo->fileName);        
	    errors = true;
    }
    catch (const XMLException& e)
    {
        char *exceptionMessage = XMLString::transcode(e.getMessage());
        fprintf(stderr, " during parsing: %s\n Exception message is: %s\n",
            fInfo->fileName, exceptionMessage);
        XMLString::release(&exceptionMessage);
        errors = true;
    }
    catch (const DOMException& toCatch)
    {
        fprintf(stderr, " during parsing: %s\n DOMException code is: %i\n",
            fInfo->fileName, toCatch.code);
        errors = true;
    }
    catch (const SAXParseException& e)
    {
        char *exceptionMessage = XMLString::transcode(e.getMessage());
        fprintf(stderr, " during parsing: %s\n Exception message is: %s\n",
            fInfo->fileName, exceptionMessage);
        XMLString::release(&exceptionMessage);
        errors = true;
    }
    catch (...)
    {
        fprintf(stderr, "Unexpected exception during parsing\n");
        errors = true;
    }

    delete mbis;
    if (errors) {
        fflush(stderr);
        return 0;  // if errors occurred, return zero as if checksum = 0;
    }
    return fCheckSum;
}


//
//  addToCheckSum - private function, used within ThreadParser in
//                  computing the checksum of the XML file.
//
//                  Unichar Strings to be added to the checksum
//                  can either be null terminated (omit len param, which
//                  will then default to -1), or provide an explicit
//                  length.
//
void ThreadParser::addToCheckSum(const XMLCh *chars, int len)
{
    if (len == -1)
    {
        // Null terminated string.
        while (*chars != 0)
        {
            fCheckSum = fCheckSum*5 + *chars;
            chars++;
        }
    }
    else
    {
        // String with character count.
        int i;
        for (i=0; i<len; i++)
            fCheckSum = fCheckSum*5 + chars[i];
    }
}


//
// startElement - our SAX handler callback function for startElement.
//                Update the document checksum with the element name
//                and any attribute names and values.
//
 void ThreadParser::SAXHandler::startElement(const XMLCh *const name, AttributeList &attributes)
{
    SAXInstance->addToCheckSum(name);
    int n = attributes.getLength();
    int i;
    for (i=0; i<n; i++)
    {
        const XMLCh *attNam = attributes.getName(i);
        SAXInstance->addToCheckSum(attNam);
        const XMLCh *attVal = attributes.getValue(i);
        SAXInstance->addToCheckSum(attVal);
    }
}

//
// startElement - our SAX2 handler callback function for startElement.
//                Update the document checksum with the element name
//                and any attribute names and values.
//

void ThreadParser::SAX2Handler::startElement(const XMLCh *const uri,
                              const XMLCh *const localname,
                              const XMLCh *const qname,
                              const Attributes& attributes)
{
    SAX2Instance->addToCheckSum(localname);

    int n = attributes.getLength();
    int i;
    for (i=0; i<n; i++)
    {
        const XMLCh *attNam = attributes.getQName(i);
        SAX2Instance->addToCheckSum(attNam);
        const XMLCh *attVal = attributes.getValue(i);
        SAX2Instance->addToCheckSum(attVal);
    }
}

//
// domCheckSum  -  Compute the check sum for a DOM node.
//                 Works recursively - initially called with a document node.
//
void ThreadParser::domCheckSum(const DOMNode *node)
{
    const XMLCh        *s;
    DOMNode          *child;
    DOMNamedNodeMap  *attributes;

    switch (node->getNodeType() )
    {
    case DOMNode::ELEMENT_NODE:
        {
            s = node->getNodeName();   // the element name

            attributes = node->getAttributes();  // Element's attributes
            int numAttributes = attributes->getLength();
            int i;
            for (i=0; i<numAttributes; i++)
                domCheckSum(attributes->item(i));

            addToCheckSum(s);          // Content and Children
            for (child=node->getFirstChild(); child!=0; child=child->getNextSibling())
                domCheckSum(child);

            break;
        }

    case DOMNode::ATTRIBUTE_NODE:
        {
            s = node->getNodeName();  // The attribute name
            addToCheckSum(s);
            s = node->getNodeValue();  // The attribute value
            if (s != 0)
                addToCheckSum(s);
            break;
        }

    case DOMNode::TEXT_NODE:
    case DOMNode::CDATA_SECTION_NODE:
        {
            s = node->getNodeValue();
            addToCheckSum(s);
            break;
        }

    case DOMNode::ENTITY_REFERENCE_NODE:
    case DOMNode::DOCUMENT_NODE:
        {
            // For entity references and the document, nothing is dirctly
            //  added to the checksum, but we do want to process the chidren nodes.
            //
            for (child=node->getFirstChild(); child!=0; child=child->getNextSibling())
                domCheckSum(child);
            break;
        }
    }
}


//
// Recompute the checksum.  Meaningful only for DOM, will tell us whether
//  a failure is transient, or whether the DOM data is permanently corrupted.
//
int ThreadParser::reCheck()
{
    if (gRunInfo.dom) {
        fCheckSum = 0;
        domCheckSum(fDoc);
    }
    return fCheckSum;
}

//
// domPrint  -  Dump the contents of a DOM node.
//              For debugging failures, when all else fails.
//                 Works recursively - initially called with a document node.
//
void ThreadParser::domPrint()
{
    printf("Begin DOMPrint ...\n");
    if (gRunInfo.dom)
    {
        try
        {
            XMLCh tempStr[100];
            XMLString::transcode("LS", tempStr, 99);
            DOMImplementation *impl          = DOMImplementationRegistry::getDOMImplementation(tempStr);
            DOMWriter         *theSerializer = ((DOMImplementationLS*)impl)->createDOMWriter();
            XMLFormatTarget   *myFormTarget  = new StdOutFormatTarget();
            DOMNode           *doc           = fXercesDOMParser->getDocument();
            theSerializer->writeNode(myFormTarget, *doc);
            delete theSerializer;
        }
        catch (...)
        {
            // do nothing
        }
    }
    printf("End DOMPrint\n");
}

//----------------------------------------------------------------------
//
//   parseCommandLine   Read through the command line, and save all
//                      of the options in the gRunInfo struct.
//
//                      Display the usage message if the command line
//                      is no good.
//
//                      Probably ought to be a member function of RunInfo.
//
//----------------------------------------------------------------------

void parseCommandLine(int argc, char **argv)
{
    gRunInfo.doGrammarCaching = false;     
    gRunInfo.quiet = false;               // Set up defaults for run.
    gRunInfo.verbose = false;
    gRunInfo.stopNow = false;            
    gRunInfo.dom = false;
    gRunInfo.sax = true;    
    gRunInfo.reuseParser = false;
    gRunInfo.inMemory = false;
    gRunInfo.dumpOnErr = false;
    gRunInfo.doSchema = false;
    gRunInfo.schemaFullChecking = false;
    gRunInfo.doNamespaces = false;
    gRunInfo.doInitialParse = false;
    gRunInfo.doNamespacePrefixes = false;    
    
    gRunInfo.valScheme = SAXParser::Val_Auto;
    gRunInfo.numThreads = 2;
    gRunInfo.totalTime = 0;
    gRunInfo.numInputFiles = 0;
    gRunInfo.numParses = 0;

    try             // Use exceptions for command line syntax errors.
    {
        int argnum = 1;
        while (argnum < argc) {
            if (strcmp(argv[argnum], "-quiet") == 0)
                gRunInfo.quiet = true;
            else if (strcmp(argv[argnum], "-verbose") == 0)
                gRunInfo.verbose = true;
            else if (strncmp(argv[argnum], "-v=", 3) == 0) {
                const char* const parm = &argv[argnum][3];
                if (!strcmp(parm, "never"))
                    gRunInfo.valScheme = SAXParser::Val_Never;
                else if (!strcmp(parm, "auto"))
                    gRunInfo.valScheme = SAXParser::Val_Auto;
                else if (!strcmp(parm, "always"))
                    gRunInfo.valScheme = SAXParser::Val_Always;
                else {
                    fprintf(stderr, "Unrecognized -v option \"%s\"\n", parm);                     
                    throw 1;
                }
            }
            else if (strcmp(argv[argnum], "-v") == 0) {
                fprintf(stderr, "Please note the -v option has been changed to -v=[always | never | auto]\n");
                fprintf(stderr, "ThreadTest will continue with -v=always\n");
                gRunInfo.valScheme = SAXParser::Val_Always;
            }
            else if (strcmp(argv[argnum], "-s") == 0)
                gRunInfo.doSchema = true;
            else if (strcmp(argv[argnum], "-f") == 0)
                gRunInfo.schemaFullChecking = true;
            else if (strcmp(argv[argnum], "-n") == 0)
                gRunInfo.doNamespaces = true;            
            else if (strcmp(argv[argnum], "-p") == 0)
                gRunInfo.doNamespacePrefixes = true;         
            else if (!strncmp(argv[argnum], "-parser=", 8)) {
                const char* const parm = &argv[argnum][8];                
                if (!strcmp(parm, "dom")) {
                    gRunInfo.dom = true;
                    gRunInfo.sax = false;
                }
                else if (!strcmp(parm, "sax")) {
                    gRunInfo.dom = false;
                    gRunInfo.sax = true;                    
                }
                else if (!strcmp(parm, "sax2")) {
                    gRunInfo.dom = false;
                    gRunInfo.sax = false;
                }                
                else {
                    fprintf(stderr, "Unrecognized -parser option \"%s\"\n", parm);                    
                    throw 1;
                }
            }
            else if (strcmp(argv[argnum], "-init") == 0)
                gRunInfo.doInitialParse = true;
            else if (strcmp(argv[argnum], "-reuse") == 0)
                gRunInfo.reuseParser = true;
            else if (strcmp(argv[argnum], "-dump") == 0)
                gRunInfo.dumpOnErr = true;
            else if (strcmp(argv[argnum], "-mem") == 0)
                gRunInfo.inMemory = true;
            else if (strcmp(argv[argnum], "-threads") == 0) {
                ++argnum;
                if (argnum >= argc) {
                    fprintf(stderr, "Invalid -threads option (missing # of threads)\n");
                    throw 1;
                }
                gRunInfo.numThreads = atoi(argv[argnum]);
                if (gRunInfo.numThreads < 0) {
                    fprintf(stderr, "Invalid -threads option (negative # of threads)\n");
                    throw 1;
                }
            }
            else if (strcmp(argv[argnum], "-time") == 0) {
                ++argnum;
                if (argnum >= argc) {
                    fprintf(stderr, "Invalid -time option (missing time value)\n");
                    throw 1;
                }
                gRunInfo.totalTime = atoi(argv[argnum]);
                if (gRunInfo.totalTime < 1) {
                    fprintf(stderr, "Invalid -time option (time value < 1)\n");
                    throw 1;
                }
            }            
            else if (strcmp(argv[argnum], "-gc") == 0)
                gRunInfo.doGrammarCaching = true;            
            else if (strcmp(argv[argnum], "-parses") == 0) {
                ++argnum;
                if (argnum >= argc) {
                    fprintf(stderr, "Invalid -parses option (missing # of parses)\n");
                    throw 1;
                }
                int temp = atoi(argv[argnum]);
                if (temp < 0) {
                    fprintf(stderr, "Invalid -parses option (negative # of parses)\n");
                    throw 1;
                }
                gRunInfo.numParses = temp;
            }
            else  if (argv[argnum][0] == '-') {
                fprintf(stderr, "Unrecognized command line option.  Scanning \"%s\"\n",
                    argv[argnum]);
                throw 1;
            }
            else {
                gRunInfo.numInputFiles++;
                if (gRunInfo.numInputFiles >= MAXINFILES) {
                    fprintf(stderr, "Too many input files.  Limit is %d\n", MAXINFILES);
                    throw 1;
                }
                gRunInfo.files[gRunInfo.numInputFiles-1].fileName = argv[argnum];
            }
            argnum++;
        }

        // We've made it through the command line.
        // Verify that at least one input file to be parsed was specified.
        if (gRunInfo.numInputFiles == 0) {
            fprintf(stderr, "No input XML file specified on command line.\n");
            throw 1;
        };

        if (gRunInfo.numParses && gRunInfo.totalTime) {
            fprintf(stderr, "Both -parses nnn and -time nnn were specified. Ignoring -time nnn.\n");
        }
    }
    catch (int)
    {
        fprintf(stderr, "usage:  ThreadTest [-v] [-threads nnn] [-time nnn] [-quiet] [-verbose] xmlfile...\n"            
            "     -v=xxx         Validation scheme [always | never | auto].  Default is 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"
            "     -parser=xxx    Parser Type [dom | sax | sax2].  Default is SAX (SAX1).\n"
            "     -p             Enable namespace prefixes. Defaults to off.\n"
            "                    (Only used with -parser=sax2, ignored otherwise.)\n"
            "     -quiet         Suppress periodic status display.\n"
            "     -verbose       Display extra messages.\n"
            "     -reuse         Retain and reuse parser.  Default creates new for each parse.\n"
            "     -threads nnn   Number of threads.  Default is 2.\n"
            "     -time nnn      Total time to run, in seconds.  Default is forever.\n"
            "     -parses nnn    Run for nnn parses instead of time.  Default is to use time\n"
            "     -dump          Dump DOM tree on error.\n"
            "     -mem           Read files into memory once only, and parse them from there.\n"
            "     -gc            Enable grammar caching (i.e. grammar cached and used in subsequent parses). Defaults to off.\n"
            "     -init          Perform an initial parse of the file(s) before starting up the individual threads.\n\n"
            );
        exit(1);
    }
}


//---------------------------------------------------------------------------
//
//   ReadFilesIntoMemory   For use when parsing from memory rather than
//                          reading the files each time, here is the code that
//                          reads the files into local memory buffers.
//
//                          This function is only called once, from the main
//                          thread, before all of the worker threads are started.
//
//---------------------------------------------------------------------------
void ReadFilesIntoMemory()
{
    int     fileNum;
    FILE    *fileF;
    size_t  t;

    if (gRunInfo.inMemory)
    {
        for (fileNum = 0; fileNum <gRunInfo.numInputFiles; fileNum++)
        {
            InFileInfo *fInfo = &gRunInfo.files[fileNum];
            fInfo->uFileName = XMLString::transcode(fInfo->fileName);
            fileF = fopen( fInfo->fileName, "rb" );
            if (fileF == 0) {
                fprintf(stderr, "Can not open file \"%s\".\n", fInfo->fileName);
                clearFileInfoMemory();
                exit(-1);
            }
            fseek(fileF, 0, SEEK_END);
            fInfo->fileSize = ftell(fileF);
            fseek(fileF, 0, SEEK_SET);
            fInfo->fileContent = new char[fInfo->fileSize + 1];
            t = fread(fInfo->fileContent, 1, fInfo->fileSize, fileF);
            if (t != fInfo->fileSize) {
                fprintf(stderr, "Error reading file \"%s\".\n", fInfo->fileName);
                clearFileInfoMemory();
                exit(-1);
            }
            fclose(fileF);
            fInfo->fileContent[fInfo->fileSize] = 0;
        }
    }
}

void clearFileInfoMemory()
{
    int     fileNum;

    if (gRunInfo.inMemory)
    {
        for (fileNum = 0; fileNum <gRunInfo.numInputFiles; fileNum++)
        {
            InFileInfo *fInfo = &gRunInfo.files[fileNum];
            XMLString::release(&fInfo->uFileName);
            delete [] fInfo->fileContent;
        }
    }
}



//----------------------------------------------------------------------
//
//  threadMain   The main function for each of the swarm of test threads.
//               Run in an infinite loop, parsing each of the documents
//               given on the command line in turn.
//
//----------------------------------------------------------------------

#ifdef PLATFORM_WIN32
unsigned long WINAPI threadMain (void *param)
#else
extern "C" {
void threadMain (void *param)
#endif
{
    ThreadInfo   *thInfo = (ThreadInfo *)param;
    ThreadParser *thParser = 0;

    if (gRunInfo.verbose)
        printf("Thread #%d: starting\n", thInfo->fThreadNum);

    int docNum = gRunInfo.numInputFiles;

    //
    // Each time through this loop, one file will be parsed and its checksum
    // computed and compared with the precomputed value for that file.
    //
    while (gRunInfo.stopNow == false) {
        if (gRunInfo.numParses == 0 || thInfo->fParses < gRunInfo.numParses) {
            thInfo->fInProgress = true;

            if (thParser == 0)
                thParser = new ThreadParser;

            docNum++;

            if (docNum >= gRunInfo.numInputFiles)
                docNum = 0;

            InFileInfo *fInfo = &gRunInfo.files[docNum];

            if (gRunInfo.verbose )
                printf("Thread #%d: parse %d starting file %s\n", thInfo->fThreadNum, thInfo->fParses, fInfo->fileName);

            int checkSum = 0;
                           
            checkSum = thParser->parse(docNum);

            // For the case where we skip the preparse we will have nothing to
            // compare the first parse's results to ... so if this looks like first
            // parse move the checkSum back into the gRunInfo data for this file.

            if (gRunInfo.files[docNum].checkSum == 0) {
                gRunInfo.files[docNum].checkSum = checkSum;
            }
            else if (checkSum != gRunInfo.files[docNum].checkSum) {
                if (checkSum == 0) {
                    // parse returns 0 if there was an error so do this to get the real
                    // checksum value
                    checkSum = thParser->getCheckSum();
                }
                fprintf(stderr, "\nThread %d: Parse Check sum error on file  \"%s\" for parse # %d.  Expected %x,  got %x\n",
                    thInfo->fThreadNum, thInfo->fParses, fInfo->fileName, fInfo->checkSum, checkSum);

	            double totalParsesCompleted = 0;
                for (int threadNum=0; threadNum < gRunInfo.numThreads; threadNum++) {
                    totalParsesCompleted += gThreadInfo[threadNum].fParses;                
                }
                fprintf(stderr, "Total number of parses completed is %f.\n", totalParsesCompleted);
            
                // Revisit - let the loop continue to run?
                int secondTryCheckSum = thParser->reCheck();
                fprintf(stderr, "   Retry checksum is %x\n", secondTryCheckSum);
                if (gRunInfo.dumpOnErr && gRunInfo.dom) {
                    thParser->domPrint();
                }
                fflush(stdout);
                fflush(stderr);
                clearFileInfoMemory();
                exit(-1);
            }

            if (gRunInfo.reuseParser == false) {
                delete thParser;
                thParser = 0;
            }

            thInfo->fHeartBeat = true;
            thInfo->fParses++;
            thInfo->fInProgress = false;
        }
        else {
            ThreadFuncs::Sleep(1000); 
        }
    }
    delete thParser;
#ifdef PLATFORM_WIN32
    return 0;
#else
    return;
}
#endif
}


//----------------------------------------------------------------------
//
//   main
//
//----------------------------------------------------------------------

int main (int argc, char **argv)
{


    parseCommandLine(argc, argv);

    //
    // Initialize the XML system.
    //
    try
    {
         XMLPlatformUtils::Initialize();
    }
    catch (...)
    {
        fprintf(stderr, "Exception from XMLPlatfromUtils::Initialize.\n");
        return 1;
    }


    /** Grammar caching thread testing */
    // Initialize memory manger and grammar pool
    // set doInitialParse to true so that the first parse will cache the
    // grammar and it'll be used in subsequent parses
    
    if (gRunInfo.doSchema == true && gRunInfo.doNamespaces == true && gRunInfo.doGrammarCaching == true) {
        gpMemMgr = new MemoryManagerImpl();
        gp = new XMLGrammarPoolImpl(gpMemMgr);
        gRunInfo.doInitialParse = true;
    }    

    //
    // If we will be parsing from memory, read each of the input files
    //  into memory now.
    //
    ReadFilesIntoMemory();

    // Initialize checksums to zero so we can check first parse and if
    // zero then we need to move first parse's checksum into array. This
    // is for the cse where we skip the initial parse.
    for (int n = 0; n < gRunInfo.numInputFiles; n++)
    {
        gRunInfo.files[n].checkSum = 0;
    }

    if (gRunInfo.doInitialParse)
    {
    //
    // While we are still single threaded, parse each of the documents
    // once, to check for errors, and to note the checksum.
    // Blow off the rest of the test if there are errors.
    //
        ThreadParser *mainParser = new ThreadParser;
        int     n;
        bool    errors = false;
        int     cksum;

        for (n = 0; n < gRunInfo.numInputFiles; n++)
        {
            char *fileName = gRunInfo.files[n].fileName;
            if (gRunInfo.verbose)
                printf("%s checksum is ", fileName);

            cksum = mainParser->parse(n);

            if (cksum == 0) {
                fprintf(stderr, "An error occurred while initially parsing %s\n",
                    fileName);
                errors = true;
            };

            gRunInfo.files[n].checkSum = cksum;
            if (gRunInfo.verbose )
                printf("%x\n", cksum);
            if (gRunInfo.dumpOnErr && errors && gRunInfo.dom) {
                mainParser->domPrint();
            }

        }
        delete mainParser;

        if (errors) {
            fprintf(stderr, "Quitting due to error incurred during initial parse\n");
            clearFileInfoMemory();
            return 1;
        }
    }

    //
    //  Fire off the requested number of parallel threads
    //

    if (gRunInfo.numThreads == 0) {
        clearFileInfoMemory();
        exit(0);
    }

    gThreadInfo = new ThreadInfo[gRunInfo.numThreads];

    int threadNum;
    for (threadNum=0; threadNum < gRunInfo.numThreads; threadNum++)
    {
        gThreadInfo[threadNum].fThreadNum = threadNum;
        ThreadFuncs::startThread(threadMain, &gThreadInfo[threadNum]);
    }
        
    if (gRunInfo.numParses)
    {
        bool notDone;
        while (true)
        {
            ThreadFuncs::Sleep(1000);            
            notDone = false;
           
            for (threadNum = 0; threadNum < gRunInfo.numThreads; threadNum++) {
                if (gThreadInfo[threadNum].fParses < gRunInfo.numParses)                                    
                    notDone = true;
            }
            if (notDone == false) {                
                break;
            }
        }
    }
    else
    {
        //
        //  Loop, watching the heartbeat of the worker threads.
        //    Each second, display "+" when all threads have completed a parse
        //                 display "." if some thread hasn't since previous "+"
        //

        unsigned long startTime = XMLPlatformUtils::getCurrentMillis();
        int elapsedSeconds = 0;
        while (gRunInfo.totalTime == 0 || gRunInfo.totalTime > elapsedSeconds) {
            ThreadFuncs::Sleep(1000);
            if (gRunInfo.quiet == false && gRunInfo.verbose == false) {
                char c = '+';                
                for (threadNum=0; threadNum < gRunInfo.numThreads; threadNum++) {
                    if (gThreadInfo[threadNum].fHeartBeat == false) {
                        c = '.';
                        break;
                    }
                }
                fputc(c, stdout);
                fflush(stdout);
                if (c == '+')
                    for (threadNum=0; threadNum < gRunInfo.numThreads; threadNum++)
                        gThreadInfo[threadNum].fHeartBeat = false;
            }
            elapsedSeconds = (XMLPlatformUtils::getCurrentMillis() - startTime) / 1000;
        }
    }

    //
    //  Time's up, we are done.  (We only get here if this was a timed run)
    //  Tally up the total number of parses completed by each of the threads.
    //
    gRunInfo.stopNow = true;      // set flag, which will cause worker threads to stop.

    //
    //  Make sure all threads are done before terminate
    //
    for (threadNum=0; threadNum < gRunInfo.numThreads; threadNum++) {
        while (gThreadInfo[threadNum].fInProgress == true) {
            ThreadFuncs::Sleep(1000);
        }
        if (gRunInfo.verbose)
            printf("Thread #%d: is finished.\n", threadNum);
    }

    //
    //  We are done!   Count the number of parse and terminate the program
    //
    double totalParsesCompleted = 0;
    for (threadNum=0; threadNum < gRunInfo.numThreads; threadNum++)
    {
        totalParsesCompleted += gThreadInfo[threadNum].fParses;
        // printf("%f   ", totalParsesCompleted);
    }

    if (gRunInfo.quiet == false) {
        if (gRunInfo.numParses) {
            printf("\n%8.0f total parses were completed.\n", totalParsesCompleted);
        }
        else {
            double parsesPerMinute = totalParsesCompleted / (double(gRunInfo.totalTime) / double(60));
            printf("\n%8.2f parses per minute.\n", parsesPerMinute);
        }
    }
    
    // delete grammar pool and memory manager
    if (gp) {
        delete gp;    
        delete gpMemMgr;    
    }

    XMLPlatformUtils::Terminate();

    clearFileInfoMemory();

    delete [] gThreadInfo;

    printf("Test Run Successfully\n");

    return 0;
}


