📄 xmlesc.cpp
字号:
* 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_XMLUINT32 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 *___________________________________________________________________________ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/voidCEscapeXMLtoHTML::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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -