tagparse.cpp

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

CPP
796
字号
			tag = NULL;
			return XMLPBadAttribute;
		}
	    }
	    else
	    {
		tag->new_attribute()->name = 0;
	    }

	    if(bUseNonQuotedValues)
	    {
		if(bHasDirectives)
		{
		    res = GetString(cur, close,
				    tag->m_cur_attribute->value,
				    AttributeValueDirective);
		}
		else
		{
		    res = GetString(cur, close,
				    tag->m_cur_attribute->value,
				    AttributeValueNoQuote);
		}
	    }
	    else
	    {
		res = GetString(cur, close,
				tag->m_cur_attribute->value,
				AttributeValue);
	    }
	    if(res == GSMissingQuote)
	    {
		delete tag;
		tag = NULL;
		return XMLPAttributeValueNotQuoted;
	    }
	    else if(res != GSFoundExpected)
	    {
		delete tag;
		tag = NULL;
		return XMLPBadAttribute;
	    }
	}
    }

    return XMLPTag;
}

GetStringResult
XMLTagParser::GetString(const char*& ptr, 
			const char* end, 
		        char*& val, 
			UINT32 type)
{
    GetStringResult retval = GSInvalid;

    CHXXMLEncode xmlStr(m_pEncoding, (BYTE*)ptr, end - ptr);
    UINT16 uLen = 0;
    ptr = (const char*)xmlStr.GetNextChar(uLen);
    while(isspace(*ptr) && ptr < end)
    {
	ptr = (const char*)xmlStr.GetNextChar(uLen);
    }
    if((const char*)ptr >= end)
    {
	return GSNoValue;
    }
    if(*ptr == '>')
    {
	ptr = (const char*)xmlStr.GetNextChar(uLen);
	return GSNoValue;
    }
    if(*ptr == '/' && *(ptr + 1) == '>')
    {
	xmlStr += 2;
	ptr = (const char*)xmlStr++;
	return GSNoValue;
    }

    // temp buffer to copy string value
    char* pVal = new char[end - ptr + 1];
    char* pValPtr = pVal;
    char* pValStartPtr = pVal;

    switch(type)
    {
	case TagType:
	{
	    // The main tag name, delimited by space
	    if(*ptr == '/')
	    {
		retval = GSEndTag;
		pValStartPtr++;
	    }
	    while(!isspace(*ptr) && *ptr != '>' && ptr < end)
	    {
		*pValPtr++ = *ptr;
		if(uLen == 2)
		{
		    *pValPtr++ = *(ptr + 1);
		}
		ptr = (const char*)xmlStr.GetNextChar(uLen);
	    }
	    break;
	}
	case AttributeName:
	{
	    // Delimited by whitespace or =
	    while(!isspace(*ptr) && *ptr != '=' && *ptr != '>' && ptr < end)
	    {
		*pValPtr++ = *ptr;
		if(uLen == 2)
		{
		    *pValPtr++ = *(ptr + 1);
		}
		ptr = (const char*)xmlStr.GetNextChar(uLen);
	    }
	    BOOL foundequals = FALSE;
	    if(ptr < end)
	    {
		// Set the ptr to past the =
		while((isspace(*ptr) || *ptr == '=') && ptr < end)
		{
		    if(*ptr == '=')
			foundequals=TRUE;
		    ptr = (const char*)xmlStr.GetNextChar(uLen);
		}
	    }
	    if(!foundequals)
	    {
		retval = GSValueOnly;
	    }
	    break;
	}
	case AttributeValue:
	case AttributeValueNoQuote:
	case AttributeValueDirective:
	{
	    if(*ptr == '"')
	    {
		ptr = (const char*)xmlStr.GetNextChar(uLen);
		while(*ptr != '"' && ptr < end)
		{
		    if(*ptr == '&')
		    {
			*pValPtr = GetEscapeMacro(ptr, end);
			pValPtr++;
			xmlStr.SetCurrent((BYTE*)ptr);
		    }
		    else
		    {
			*pValPtr++ = *ptr;
			if(uLen == 2)
			{
			    *pValPtr++ = *(ptr + 1);
			}
		    }
		    ptr = (const char*)xmlStr.GetNextChar(uLen);
		}
		if(*ptr != '"')
		{
		    return GSMissingQuote;
		}
		/* Skip the quote */
		ptr = (const char*)xmlStr.GetNextChar(uLen);
	    }
	    else if(*ptr == '\'')
	    {
		ptr = (const char*)xmlStr.GetNextChar(uLen);
		while(*ptr != '\'' && ptr < end)
		{
		    if(*ptr == '&')
		    {
			*pValPtr = GetEscapeMacro(ptr, end);
			pValPtr++;
			xmlStr.SetCurrent((BYTE*)ptr);
		    }
		    else
		    {
			*pValPtr++ = *ptr;
			if(uLen == 2)
			{
			    *pValPtr++ = *(ptr + 1);
			}
		    }
		    ptr = (const char*)xmlStr.GetNextChar(uLen);
		}
		if(*ptr != '\'')
		{
		    delete [] pVal;
		    return GSMissingQuote;
		}
		/* Skip the quote */
		ptr = (const char*)xmlStr.GetNextChar(uLen);
	    }
	    else if(*ptr == '[' && type == AttributeValueDirective)
	    {
		ptr = (const char*)xmlStr.GetNextChar(uLen);
		while(*ptr != ']' && ptr < end)
		{
		    *pValPtr++ = *ptr;
		    if(uLen == 2)
		    {
			*pValPtr++ = *(ptr + 1);
		    }
		    ptr = (const char*)xmlStr.GetNextChar(uLen);
		}
		if(*ptr != ']')
		{
		    delete[] pVal;
		    return GSMissingQuote;
		}
		/* skip the ']' */
		ptr = (const char*)xmlStr.GetNextChar(uLen);
	    }
	    else
	    {
		/* don't care!!! */
		while(!isspace(*ptr) && *ptr != '>' && ptr < end)
		{
		    *pValPtr++ = *ptr;
		    if(uLen == 2)
		    {
			*pValPtr++ = *(ptr + 1);
		    }
		    ptr = (const char*)xmlStr.GetNextChar(uLen);
		}
	    }
	    break;
	}
    }

    *pValPtr = '\0';

    val = new_string(pValStartPtr);
    delete [] pVal;

    if(retval == GSInvalid)
	return GSFoundExpected;
    else
	return retval;
}

void
XMLTagParser::FindCommentClose(const char*& buf, 
			       const char* start,
			       const char* end)
{
    UINT16 nCommentDepth = 1;

    CHXXMLEncode xmlStr(m_pEncoding, (BYTE*)start, end - start);
    UINT16 uLen = 0;

    const char* pos = (const char*)xmlStr.GetNextChar(uLen);
    while(pos < end && m_comment_state > 0)
    {
	switch(m_comment_state)
	{
	    case 1:
		if(*pos == '-')
		    m_comment_state = 2;
		else if (*pos == '<')
		    m_comment_state = 4;
		else if(m_comment_start)
		{
		    if(*pos == '#')
		    {
			if(end - pos < 8)
			{
			    buf = pos;
			    return;
			}
			pos = (const char*)xmlStr.GetNextChar(uLen);
			if(strncasecmp(pos, "include", 7) == 0)
			{
			    pos += 7;
			    m_comment_get_arg = 1;
			    m_comment_pos = 0;
			    strcpy(m_comment_command, "include"); /* Flawfinder: ignore */
			}
		    }
		}
		break;
	    case 2:
		if(*pos == '-')
		    m_comment_state = 3;
		else
		    m_comment_state = 1;
		break;
	    case 3:
		if(*pos == '>')
		{
		    nCommentDepth--;
		    if (nCommentDepth == 0)
		    {
			m_comment_state = 0;
			buf = (const char*)xmlStr.GetNextChar(uLen);
		    }
		    else
			m_comment_state = 1;
		}
		else
		    m_comment_state = 1;
		break;
	    case 4:
		// Ignore nested comments while looking for our end tag
		if (*pos == '!')
		    m_comment_state = 5;
		else
		    m_comment_state = 1;
		break;
	    case 5:
		if (*pos == '-')
		    m_comment_state = 6;
		else
		    m_comment_state = 1;
		break;
	    case 6:
		if (*pos == '-')
		{
		    nCommentDepth++;
		}
		m_comment_state = 1;
		break;
	}
	if(m_comment_state > 0)
	{
	    switch(m_comment_get_arg)
	    {
		case 1:
		    if(*pos != '"' && !isspace(*pos))
			m_comment_get_arg = 0;
		    else if(*pos == '"')
			m_comment_get_arg = 2;
		    break;
		case 2:
		    if(*pos != '"')
			if (m_comment_pos < 1023) m_comment_arg[m_comment_pos++] = *pos;
		    else
		    {
			if (m_comment_pos < 1024) m_comment_arg[m_comment_pos] = 0;
			m_comment_get_arg = 3;
		    }
		    break;
		default:
		    break;
	    }
	}
	pos = (const char*)xmlStr.GetNextChar(uLen);
    }
}

char
XMLTagParser::GetEscapeMacro(const char*& ptr, const char* end)
{
    char returnCh;
    if(*ptr != '&')
    {
	returnCh = *ptr;
    }
    else
    {
	int maxLen = end - ptr;
	if((maxLen > 5) && strncmp(ptr, "&apos;", 6) == 0)
	{
	    returnCh = '\'';
	    ptr += 6;
	}
	else if((maxLen > 5) && strncmp(ptr, "&quot;", 6) == 0)
	{
	    returnCh = '"';
	    ptr += 6;
	}
	else if((maxLen > 3) && strncmp(ptr, "&lt;", 4) == 0)
	{
	    returnCh = '<';
	    ptr += 4;
	}
	else if((maxLen > 3) && strncmp(ptr, "&gt;", 4) == 0)
	{
	    returnCh = '>';
	    ptr += 4;
	}
	else if((maxLen > 4) && strncmp(ptr, "&amp;", 5) == 0)
	{
	    returnCh = '&';
	    ptr += 5;
	}
	else
	{
	    returnCh = '&';
	    ptr++;
	}
    }
    return returnCh;
}

⌨️ 快捷键说明

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