xmlesc.cpp

来自「symbian 下的helix player源代码」· C++ 代码 · 共 1,586 行 · 第 1/4 页

CPP
1,586
字号
 *	This method will take the given pPositionPointer and wrap the given attribute
 *	with an HREF
 *
 *  RETURNS
 *	UINT32
 *	    number of characters used off pPositionPointer, thus the position can be
 *	    adjusted after the function returns
 *___________________________________________________________________________
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
UINT32 CEscapeXMLtoHTML::WrapAttributeWithHREF(const UCHAR* pPositionPointer, 
					UINT32 ulLen,
					DataObject* pObj,
					CBigByteGrowingQueue* pQueue, 
					const char* pAttribute)
{
    // we need to find two things
    // 1 - the end of the tag
    // 2 - the beggining of the attribute
    const UCHAR* pBeginAttribute = NULL;
    const UCHAR* pEndTag = NULL;
    const char* walker = (const char*)pPositionPointer;
    BOOL bInComment = FALSE;
    UINT32 ulEscLen = 0;
    UINT16 uAttribLen = strlen(pAttribute);
    while ( (!pEndTag || bInComment) && ulEscLen < ulLen)
    {
	if ( !bInComment )
	{
	    if ( *walker == '>')
	    {
		pEndTag = (const UCHAR*)walker;
		++pEndTag;
	    }
	    else if ( ulEscLen + uAttribLen < ulLen &&
		isspace(*(walker-1)) &&
		!strncmp(walker, pAttribute, uAttribLen) )
	    {
		walker += uAttribLen;
		ulEscLen += uAttribLen;
		// eat ws.
		while ( isspace(*walker) && ulEscLen < ulLen )
		{
		    ++walker;
		    ++ulEscLen;
		}
		// assert for =
		HX_ASSERT(*walker == '=');
		if ( *walker == '=' )
		{
		    ++walker;
		    ++ulEscLen;
		    while ( isspace(*walker) && ulEscLen < ulLen )
		    {
			++walker;
			++ulEscLen;
		    }
		    // eat ws assert for " '
		    HX_ASSERT(*walker == '\"' || *walker == '\'');
		    if ( *walker == '\"' || *walker == '\'' )
		    {
			++walker;
			++ulEscLen;
			pBeginAttribute = (const UCHAR*)walker;
		    }
		}
	    }
	    else if ( ulEscLen + 4 < ulLen && !strncmp(walker, "<!--", 4) )
	    {
		bInComment = TRUE;
		walker += 3;
		ulEscLen += 3;
	    }
	}
	else
	{
	    if ( ulEscLen + 3 < ulLen && !strncmp(walker, "-->", 3) )
	    {
		bInComment = FALSE;
		walker += 2;
		ulEscLen += 2;
	    }
	}
	++walker;
	++ulEscLen;
    }

    UINT32 pos = 0;
    if ( pBeginAttribute ) {
	// parse until the end of the attribute tag.
	pos = pBeginAttribute - pPositionPointer;
	Parse(pPositionPointer, pos, pQueue, pObj);
	// advance the character pointer by how much we parsed.
	pPositionPointer += pos;
	// push our wrapper on
	BOOL bPushed = PushOpenningHREF(pPositionPointer, pQueue, pObj->cQuote);
	// push mangled filename on
	UINT32 ulPathLen = PushMangledDisplayedPath(pPositionPointer, pQueue, pObj->cQuote);
	// advancd pPositionPointer by path length
	pPositionPointer += ulPathLen;
	pos += ulPathLen;
	// push ending HREF
	if ( bPushed )
	{
	    PushEndingHREF(pQueue);
	}
	// parse to end of tag
	Parse(pPositionPointer, ulEscLen - pos, pQueue, pObj);
	pObj->bPushChar = FALSE;
	// We want to return pointing to the last '>', therefore we can
	// catch anything that is imediatly following our tag.
	return ulEscLen - 1;
    }

    pObj->bPushChar = TRUE;
    return 0;

}

/*___________________________________________________________________________
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *  WrapHREF (pPositionPointer, ulLen, pObj, pQueue)
 *
 *  PARAMETERS:
 *
 *  pPositionPointer		Pointer to a character string.  It points to the first
 *		whitespace after the tagname
 *  ulLen	Length to end of pPositionPointer so we don't overrun the buffer
 *  pObj	The current state of the Parse Function, this can be used
 *		to continue parsing.
 *  queue	The queue to push the output to.
 *  pAttribute	The attribute we want to wrap.
 *
 *  DESCRIPTION:
 *	This method will take the given pPositionPointer and wrap an HREF=
 *  With a link to itself.
 *
 *  RETURNS
 *	UINT32
 *	    number of characters used off pPositionPointer, thus the position can be
 *	    adjusted after the function returns
 *___________________________________________________________________________
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

#ifdef HYPER_LINKING_HREFS_XML

UINT32 CEscapeXMLtoHTML::LinkHREF(const UCHAR* pPositionPointer, 
					UINT32 ulLen,
					DataObject* pObj,
					CBigByteGrowingQueue* pQueue)
{
    const UCHAR* pBeginHREF = NULL;
    const UCHAR* pEndHREF = NULL;
    const UCHAR* pEndTag = NULL;
    const char* walker = (const char*)pPositionPointer;
    BOOL bInComment = FALSE;
    BOOL bInString = FALSE;
    UINT32 ulEscLen = 0;
    while ( (!pEndTag) && ulEscLen < ulLen)
    {
	if ( bInString )
	{
	    if ( *walker == '\"' || *walker == '\'')
	    {
		bInString = FALSE;
		pEndHREF = (const UCHAR*)walker;
	    }
	}
	else if ( !bInComment )
	{
	    if ( *walker == '>')
	    {
		pEndTag = (const UCHAR*)walker;
		++pEndTag;
	    }
	    else if ( ulEscLen + 6 < ulLen && 
		isspace(*(walker-1)) && 
		!strncmp(walker, "href", 4) &&
		(*(walker+4) == '=' || isspace(*(walker+4))) )
	    {
		walker += 4;
		ulEscLen += 4;
		while ( *walker != '\"' && *walker != '\'' && ulEscLen < ulLen &&
			(isspace(*walker) || *walker == '='))
		{
		    ++walker;
		    ++ulEscLen;
		}
		HX_ASSERT(*walker == '\"' || *walker == '\'');
		if ( *walker == '\"' || *walker == '\'')
		{
		    pBeginHREF = (const UCHAR*)walker + 1;
		    bInString = TRUE;
		}
	    }
	    else if ( ulEscLen + 4 < ulLen && 
		!strncmp(walker, "<!--", 4) )
	    {
		bInComment = TRUE;
		walker += 3;
		ulEscLen += 3;
	    }
	}
	else
	{
	    if ( ulEscLen + 3 < ulLen && !strncmp(walker, "-->", 3) )
	    {
		bInComment = FALSE;
		walker += 2;
		ulEscLen += 2;
	    }
	}
	++walker;
	++ulEscLen;
    }

    if ( pEndTag == NULL || pBeginHREF == NULL || pEndHREF == NULL )
    {
	return 0;
    }
    else
    {
	const UCHAR* cp = pPositionPointer;
	Parse(pPositionPointer, pBeginHREF - cp, pQueue, pObj);
	cp += pBeginHREF - cp;
	pQueue->EnQueue(m_pEscapeStrings[BeginHREF]);
	pQueue->EnQueue((void*)pBeginHREF, pEndHREF - pBeginHREF);
	pQueue->EnQueue("\">");
	Parse(cp, pEndHREF - pBeginHREF, pQueue, pObj);
	cp += pEndHREF - pBeginHREF;
	pQueue->EnQueue(m_pEscapeStrings[EndHREF]);

	// parse to end of tag
	Parse(cp, pEndTag - cp, pQueue, pObj);
	pObj->bPushChar = FALSE;
	// We want to return pointing to the last '>', therefore we can
	// catch anything that is imediatly following our tag.
	return pEndTag - pPositionPointer - 1;
    }
}

#endif //HYPER_LINKING_HREFS_XML

/*___________________________________________________________________________
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *  Parse(pIn, ulLen, pQueue, pObj)
 *
 *  PARAMETERS:
 *	pIn	The string to be parsed.
 *	ulLen	How far to parse through pIn
 *	pQueue	The output Queue to push onto
 *	pObj	The state object.  This is used to start the queue from a
 *		given state.
 *
 *  DESCRIPTION:
 *	This function walks through the string one character at a time.  
 *	Every tag is checked with the CheckTag(...) function to see if it 
 *	needs special attention.  If so the OnTag(...) function is called.  
 *	This function will be implemented in a child class that will replace 
 *	the tag with parsed imput returning how far along pIn it made it.
 *	This function is designed such that Inherited classes can recusivly 
 *	call it to parse thier stream from the given state.
 *
 *  RETURNS
 *	void
 *___________________________________________________________________________
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void
CEscapeXMLtoHTML::Parse(const UCHAR* pIn, UINT32 ulLen, 
			CBigByteGrowingQueue* pQueue,
			DataObject* pObj)
{
    HX_ASSERT(pIn);
    
    const UCHAR* pPositionPointer;

    UINT32 uPositionOffset;
    for ( uPositionOffset = 0, pPositionPointer = pIn;
	uPositionOffset < ulLen; uPositionOffset++, pPositionPointer++ )
    {
        switch(pObj->state)
        {
            case IN_CONTENT:
	    {
                /* do nothing until you find a '<' "<!--" or '&' */
                if ( *pPositionPointer == '<' )
                {
                    /* XXX we can miss a comment spanning a block boundary */
		    pObj->bPushChar = FALSE;
                    if ( uPositionOffset + 4 <= ulLen && 
			!strncmp((char*)pPositionPointer, "<!--", 4) )
                    {
                        pQueue->EnQueue(m_pEscapeStrings[BeginCommentMarkup]);
                        pQueue->EnQueue("&lt;");
                        pObj->state = IN_COMMENT;
                    }
                   else if ( uPositionOffset + 2 <= ulLen && 
		       !strncmp((char*)pPositionPointer, "<?", 2) )
                   {
                       pQueue->EnQueue(m_pEscapeStrings[BeginTagMarkup]);
		       pQueue->EnQueue("&lt;");
		       pQueue->EnQueue(m_pEscapeStrings[EndTagMarkup]);
                       pQueue->EnQueue(m_pEscapeStrings[BeginProcessingInstructions]);
                       pQueue->EnQueue("?");
                       pQueue->EnQueue(m_pEscapeStrings[BeginTagNameMarkup]);
                       // increment pPositionPointer & uPositionOffset one because of ?
                       ++pPositionPointer;
                       ++uPositionOffset;
                       pObj->bInProcessingInstructions = TRUE;
                       pObj->bPushChar = FALSE;
                       pObj->state = ABOUT_TO_BEGIN_TAG;
                   }
                   else if ( uPositionOffset + 9 <= ulLen && 
		       !strncmp((char*)pPositionPointer, "<![CDATA[", 9) )
                   {
		       pQueue->EnQueue(m_pEscapeStrings[BeginTagMarkup]);
                       pQueue->EnQueue("&lt;");
                       pQueue->EnQueue(m_pEscapeStrings[BeginTagNameMarkup]);
                       pQueue->EnQueue("![CDATA[");
                       pQueue->EnQueue(m_pEscapeStrings[EndTagNameMarkup]);
		       pQueue->EnQueue(m_pEscapeStrings[EndTagMarkup]);
                       pQueue->EnQueue(m_pEscapeStrings[BeginCDATA]);
                       pObj->bPushChar = FALSE;
                       pPositionPointer += 8;
                       uPositionOffset += 8;
                       pObj->state = IN_CDATA;
                   }
                   else if ( uPositionOffset + 2 <= ulLen && 
		       !strncmp((char*)pPositionPointer, "<!", 2) )
                   {
		       pQueue->EnQueue(m_pEscapeStrings[BeginTagMarkup]);
                       pQueue->EnQueue("&lt;");
                       pQueue->EnQueue(m_pEscapeStrings[BeginTagNameMarkup]);
                       pObj->state = IN_DOC_TYPE_DEC_TAG;
                   }
                    else
                    {
                        BeginColorTag(pQueue, pObj);
                    }
                }
                else if ( *pPositionPointer == '&' )
                {
                    pObj->bPushChar = FALSE;
		    pQueue->EnQueue(m_pEscapeStrings[BeginAmpersandThingyMarkup]);
                    pQueue->EnQueue("&amp;");
                    pObj->state = IN_AMPERSAND_THINGY;
                }
	    }
            break;
           case IN_DOC_TYPE_DEC_TAG:
           {
                if ( IS_SPACE(*pPositionPointer) )
                {
                    pQueue->EnQueue(m_pEscapeStrings[EndTagNameMarkup]);
		    pQueue->EnQueue(m_pEscapeStrings[EndTagMarkup]);
		    pQueue->EnQueue(m_pEscapeStrings[BeginDTD]);
		    pObj->bPushChar = TRUE; // we want to still push it
                    pObj->state = IN_DOC_TYPE_DEC;
                }
                else if ( *pPositionPointer == '>' )
                {
                    pQueue->EnQueue(m_pEscapeStrings[EndTagNameMarkup]);
                    pQueue->EnQueue(m_pEscapeStrings[EndDTD]);
                    pQueue->EnQueue("&gt;");
                    pObj->bPushChar = FALSE;
		    pObj->state = IN_CONTENT;
                }
           }
           break;
           case IN_DOC_TYPE_DEC:
           {
               if ( pObj->bInDataSection )
               {
                   if ( pObj->bInInternalComment )
                   {
                       /* do nothing until you find a closing '-->' */
                       if ( !strncmp((char*)pPositionPointer, "-->", 3) )
                       {
                           pObj->bPushChar = FALSE;
                           pObj->bInInternalComment = FALSE;
                           pQueue->EnQueue("--&gt;");
                           pPositionPointer += 2;
                           uPositionOffset += 2;
                           pQueue->EnQueue(m_pEscapeStrings[EndCommentMarkup]);
                       }
                   }
                   else if ( !strncmp((char*)pPositionPointer, "<!--", 4) )
                   {
                        pQueue->EnQueue(m_pEscapeStrings[BeginCommentMarkup]);
                        pQueue->EnQueue("&lt;");
                        pObj->bPushChar = FALSE;
                        pObj->bInInternalComment = TRUE;
                   }
                   else if ( *pPositionPointer == ']' )
                   {
                       pObj->bInDataSection = FALSE;
                   }
               }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?