Skip to content
Snippets Groups Projects
XMLScanner.cpp 75 KiB
Newer Older
Khaled Noaman's avatar
Khaled Noaman committed
        toFill = XMLCh(value);
        second = 0;
        if (!fReaderMgr.getCurrentReader()->isXMLChar(toFill) && !fReaderMgr.getCurrentReader()->isControlChar(toFill)) {
            // Character reference was not in the valid range
            emitError(XMLErrs::InvalidCharacterRef);
            return false;
        }
    }
    else {
        // Character reference was not in the valid range
        emitError(XMLErrs::InvalidCharacterRef);
        return false;
Khaled Noaman's avatar
Khaled Noaman committed
    return true;
}


//  We get here after the '<!--' part of the comment. We scan past the
//  terminating '-->' It will calls the appropriate handler with the comment
//  text, if one is provided. A comment can be in either the document or
//  the DTD, so the fInDocument flag is used to know which handler to send
//  it to.
void XMLScanner::scanComment()
{
Khaled Noaman's avatar
Khaled Noaman committed
    enum States
    {
        InText
        , OneDash
        , TwoDashes
    };

    // Get a buffer for this
    XMLBufBid bbComment(&fBufMgr);

    //  Get the comment text into a temp buffer. Be sure to use temp buffer
    //  two here, since its to be used for stuff that is potentially longer
    //  than just a name.
    States curState = InText;
    bool gotLeadingSurrogate = false;
    while (true)
    {
        // Get the next character
        const XMLCh nextCh = fReaderMgr.getNextChar();

        //  Watch for an end of file
        if (!nextCh)
        {
            emitError(XMLErrs::UnterminatedComment);
            ThrowXMLwithMemMgr(UnexpectedEOFException, XMLExcepts::Gen_UnexpectedEOF, fMemoryManager);
Khaled Noaman's avatar
Khaled Noaman committed
        }

        // Check for correct surrogate pairs
        if ((nextCh >= 0xD800) && (nextCh <= 0xDBFF))
        {
            if (gotLeadingSurrogate)
                emitError(XMLErrs::Expected2ndSurrogateChar);
            else
                gotLeadingSurrogate = true;
        }
        else
        {
            if (gotLeadingSurrogate)
            {
                if ((nextCh < 0xDC00) || (nextCh > 0xDFFF))
                    emitError(XMLErrs::Expected2ndSurrogateChar);
            }
            // Its got to at least be a valid XML character
Tinny Ng's avatar
Tinny Ng committed
            else if (!fReaderMgr.getCurrentReader()->isXMLChar(nextCh)) {
Khaled Noaman's avatar
Khaled Noaman committed

                XMLCh tmpBuf[9];
                XMLString::binToText
                (
                    nextCh
                    , tmpBuf
                    , 8
                    , 16
Khaled Noaman's avatar
Khaled Noaman committed
                );
                emitError(XMLErrs::InvalidCharacter, tmpBuf);
            }

            gotLeadingSurrogate = false;
        }
Khaled Noaman's avatar
Khaled Noaman committed
        if (curState == InText)
        {
            // If its a dash, go to OneDash state. Otherwise take as text
            if (nextCh == chDash)
                curState = OneDash;
            else
                bbComment.append(nextCh);
        }
        else if (curState == OneDash)
        {
            //  If its another dash, then we change to the two dashes states.
            //  Otherwise, we have to put in the deficit dash and the new
            //  character and go back to InText.
            if (nextCh == chDash)
            {
                curState = TwoDashes;
            }
            else
            {
                bbComment.append(chDash);
                bbComment.append(nextCh);
                curState = InText;
            }
        }
        else if (curState == TwoDashes)
        {
            // The next character must be the closing bracket
            if (nextCh != chCloseAngle)
            {
                emitError(XMLErrs::IllegalSequenceInComment);
                fReaderMgr.skipPastChar(chCloseAngle);
                return;
            }
            break;
        }
    }
Khaled Noaman's avatar
Khaled Noaman committed
    // If we have an available handler, call back with the comment.
    if (fDocHandler)
    {
        fDocHandler->docComment
        (
            bbComment.getRawBuffer()
        );

    //mark comment is seen within the current element
    if (! fElemStack.isEmpty())
        fElemStack.setCommentOrPISeen();

Khaled Noaman's avatar
Khaled Noaman committed
//  Most equal signs can have white space around them, so this little guy
//  just makes the calling code cleaner by eating whitespace.
bool XMLScanner::scanEq(bool inDecl)
    fReaderMgr.skipPastSpaces(inDecl);
Khaled Noaman's avatar
Khaled Noaman committed
    if (fReaderMgr.skippedChar(chEqual))
    {
        fReaderMgr.skipPastSpaces(inDecl);
Khaled Noaman's avatar
Khaled Noaman committed
        return true;
    }
    return false;
Khaled Noaman's avatar
Khaled Noaman committed

unsigned int
XMLScanner::scanUpToWSOr(XMLBuffer& toFill, const XMLCh chEndChar)
Khaled Noaman's avatar
Khaled Noaman committed
    fReaderMgr.getUpToCharOrWS(toFill, chEndChar);
    return toFill.getLen();
unsigned int *XMLScanner::getNewUIntPtr()
{
    // this method hands back a new pointer initialized to 0
    unsigned int *retVal;
    if(fUIntPoolCol < 64)
    {
        retVal = fUIntPool[fUIntPoolRow]+fUIntPoolCol;
        fUIntPoolCol++;
        return retVal;
    }
    // time to grow the pool...
    if(fUIntPoolRow+1 == fUIntPoolRowTotal)
    {
        // and time to add some space for new rows:
        fUIntPoolRowTotal <<= 1;
        unsigned int **newArray = (unsigned int **)fMemoryManager->allocate(sizeof(unsigned int *) * fUIntPoolRowTotal );
        memcpy(newArray, fUIntPool, (fUIntPoolRow+1) * sizeof(unsigned int *));
        fMemoryManager->deallocate(fUIntPool);
        fUIntPool = newArray;
        // need to 0 out new elements we won't need:
        for (unsigned int i=fUIntPoolRow+2; i<fUIntPoolRowTotal; i++)
            fUIntPool[i] = 0;
    }
    // now to add a new row; we just made sure we have space
    fUIntPoolRow++;
    fUIntPool[fUIntPoolRow] = (unsigned int *)fMemoryManager->allocate(sizeof(unsigned int) << 6);
    memset(fUIntPool[fUIntPoolRow], 0, sizeof(unsigned int) << 6);
    // point to next element
    fUIntPoolCol = 1; 
    return fUIntPool[fUIntPoolRow];
}

void XMLScanner::resetUIntPool()
{
    // to reuse the unsigned int pool--and the hashtables that use it--
    // simply reinitialize everything to 0's
    for(unsigned int i = 0; i<= fUIntPoolRow; i++)
        memset(fUIntPool[i], 0, sizeof(unsigned int) << 6);
}

void XMLScanner::recreateUIntPool()
{
    // this allows a bloated unsigned int pool to be dispensed with

    // first, delete old fUIntPool
    for (unsigned int i=0; i<=fUIntPoolRow; i++)
    {
        fMemoryManager->deallocate(fUIntPool[i]);
    }
    fMemoryManager->deallocate(fUIntPool);

    fUIntPoolRow = fUIntPoolCol = 0;
    fUIntPoolRowTotal = 2;
    fUIntPool = (unsigned int **)fMemoryManager->allocate(sizeof(unsigned int *) * fUIntPoolRowTotal);
    fUIntPool[0] = (unsigned int *)fMemoryManager->allocate(sizeof(unsigned int) << 6);
    memset(fUIntPool[fUIntPoolRow], 0, sizeof(unsigned int) << 6);
    fUIntPool[1] = 0;
}

Tinny Ng's avatar
Tinny Ng committed
XERCES_CPP_NAMESPACE_END