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("<");
pObj->state = IN_COMMENT;
}
else if ( uPositionOffset + 2 <= ulLen &&
!strncmp((char*)pPositionPointer, "<?", 2) )
{
pQueue->EnQueue(m_pEscapeStrings[BeginTagMarkup]);
pQueue->EnQueue("<");
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("<");
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("<");
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("&");
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(">");
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("-->");
pPositionPointer += 2;
uPositionOffset += 2;
pQueue->EnQueue(m_pEscapeStrings[EndCommentMarkup]);
}
}
else if ( !strncmp((char*)pPositionPointer, "<!--", 4) )
{
pQueue->EnQueue(m_pEscapeStrings[BeginCommentMarkup]);
pQueue->EnQueue("<");
pObj->bPushChar = FALSE;
pObj->bInInternalComment = TRUE;
}
else if ( *pPositionPointer == ']' )
{
pObj->bInDataSection = FALSE;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?