//
// 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;
}
//------------------------------------------------------------------------
//
//  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;
}