⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chxavurlrep.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
字号:
/*============================================================================*
 *
 * (c) 1995-2002 RealNetworks, Inc. Patents pending. All rights reserved.
 *
 *============================================================================*/
 

#include "chxavurlrep.h"
#include "char_stack.h"
#include "chxavconvertutil.h"
#include "chxavvector.h"

inline
static bool IsURLAlpha(char ch)
{
    return (((ch >= 'a') && (ch <= 'z')) ||
	    ((ch >= 'A') && (ch <= 'Z')));
}

inline
static bool IsURLDigit(char ch)
{
    return ((ch >= '0') && (ch <= '9'));
}

inline
static bool IsURLAlnum(char ch)
{
    return (IsURLAlpha(ch) || IsURLDigit(ch));
}

inline
static bool IsURLSchemeChar(char ch)
{
    return (IsURLAlnum(ch) || strchr("+-.", ch));
}

CHXAvURLRep::CHXAvURLRep(const CHXString& url_string)
    : m_String(""),
      m_Protocol(""),
      m_Host(""),
      m_Port(0),
      m_parseSuccess(false),
      m_hasNetPath(false),
      m_hasAbsPath(false),
      m_hasQuery(false)
{
    m_parseSuccess =ParseURL(url_string, m_Protocol, m_Host, m_Port, 
			     m_Path, m_Query, m_Fragment,
			     m_hasNetPath, m_hasAbsPath, m_hasQuery, 
			     m_hasFragment);

    BuildURL(m_String, m_Protocol, m_Host, m_Port, 
	     m_Path, m_Query, m_Fragment,
	     m_hasNetPath, m_hasAbsPath, m_hasQuery, m_hasFragment);
}

CHXAvURLRep::~CHXAvURLRep()
{}

int CHXAvURLRep::operator==(const CHXAvURLRep& url) const
{
    return
	(stricmp(url.m_Protocol, m_Protocol) == 0) &&
	(stricmp(url.m_Host, m_Host) == 0) &&
	url.m_Port     == m_Port &&
	url.m_Path     == m_Path &&
	url.m_Query    == m_Query &&
	url.m_Fragment == m_Fragment &&
	url.m_hasNetPath == m_hasNetPath &&
	url.m_hasAbsPath == m_hasAbsPath &&
	url.m_hasQuery   == m_hasQuery &&
	url.m_hasFragment   == m_hasFragment;
}
int CHXAvURLRep::operator!=(const CHXAvURLRep& url) const
{
    return ! operator==(url);
}

CHXAvURLRep::CHXAvURLRep(const CHXString& protocol, const CHXString& host,
		   int port,
		   const CHXString& path,
		   const CHXString& query)
    : m_String(""),
      m_Protocol(protocol),
      m_Host(host),
      m_Port(port),
      m_parseSuccess(true),
      m_hasNetPath(false),
      m_hasAbsPath(false),
      m_hasQuery(false),
      m_hasFragment(false)
{
    m_Path.EscapePathStr(path);
    m_Query.EscapeQueryStr(query);

    if (protocol.GetLength() ||
	host.GetLength())
	m_hasNetPath = true;

    if (m_hasNetPath && path.GetLength())
	m_hasAbsPath = true;

    if (query.GetLength())
	m_hasQuery = true;

    BuildURL(m_String, m_Protocol, m_Host, m_Port, 
	     m_Path, m_Query, m_Fragment,
	     m_hasNetPath, m_hasAbsPath, m_hasQuery, m_hasFragment);
}

CHXAvURLRep::CHXAvURLRep(const CHXString& protocol, const CHXString& host,
		   int port,
		   const CHXAvEscapedString& path,
		   const CHXAvEscapedString& query)
    : m_String(""),
      m_Protocol(protocol),
      m_Host(host),
      m_Port(port),
      m_Path(path),
      m_Query(query),
      m_parseSuccess(true),
      m_hasNetPath(false),
      m_hasAbsPath(false),
      m_hasQuery(false),
      m_hasFragment(false)
{
    if (protocol.GetLength() ||
	host.GetLength())
	m_hasNetPath = true;

    if (m_hasNetPath && path.GetEscapedStr().GetLength())
	m_hasAbsPath = true;

    if (query.GetEscapedStr().GetLength())
	m_hasQuery = true;

    BuildURL(m_String, m_Protocol, m_Host, m_Port, 
	     m_Path, m_Query, m_Fragment,
	     m_hasNetPath, m_hasAbsPath, m_hasQuery, m_hasFragment);
}

const CHXString& CHXAvURLRep::String() const
{
    return m_String;
}

const CHXString& CHXAvURLRep::Protocol() const
{
    return m_Protocol;
}

const CHXString& CHXAvURLRep::Host() const
{
    return m_Host;
}

int CHXAvURLRep::Port() const
{
    return m_Port;
}

const CHXString& CHXAvURLRep::Path() const
{
    return m_Path.GetUnEscapedStr();
}
 
const CHXAvEscapedString& CHXAvURLRep::EscapedPath() const
{
    return m_Path;
}

const CHXString& CHXAvURLRep::Query() const
{
    return m_Query.GetUnEscapedStr();
}
 
const CHXAvEscapedString& CHXAvURLRep::EscapedQuery() const
{
    return m_Query;
}

const CHXAvEscapedString& CHXAvURLRep::EscapedFragment() const
{
    return m_Fragment;
}

bool CHXAvURLRep::IsAbsoluteURL() const
{
    return (m_Protocol.GetLength() &&
	    (m_Path.GetEscapedStr().GetLength() ||
	     m_hasNetPath || m_hasAbsPath || m_hasQuery || m_hasFragment));
}

bool CHXAvURLRep::HasNetPath() const
{
    return m_hasNetPath;
}

bool CHXAvURLRep::HasAbsolutePath() const
{
    return m_hasAbsPath;
}

bool CHXAvURLRep::HasQuery() const
{
    return m_hasQuery;
}

bool CHXAvURLRep::HasFragment() const
{
    return m_hasFragment;
}
  
void CHXAvURLRep::BuildURL(CHXString& url,
			const CHXString& protocol, const CHXString& host,
			int port, const CHXAvEscapedString& path, 
			const CHXAvEscapedString& query,
			const CHXAvEscapedString& fragment,
			bool hasNetPath,
			bool hasAbsPath,
			bool hasQuery,
			bool hasFragment)
{
    url = "";

    if (protocol.GetLength())
    {
	url += protocol;
	url += ":";
    }

    if (hasNetPath)
    {
	url += "//";
	url += host;

	if (port > 0)
	{
	    char buf[32];
	    ::sprintf(buf, ":%d", port);
	    url += buf;
	}
    }
    
    if (hasAbsPath)
	url += "/";

    if (path.GetEscapedStr().GetLength())
    {
	url += path.GetEscapedStr();
    }

    if (hasQuery)
    {
	url += "?";
	url += query.GetEscapedStr();
    }

    if (hasFragment)
    {
	url += "#";
	url += fragment.GetEscapedStr();
    }
}


bool CHXAvURLRep::ParseURL(const CHXString& url,
			CHXString& protocol, CHXString& host,
			int& port, CHXAvEscapedString& path,  
			CHXAvEscapedString& query,
			CHXAvEscapedString& fragment,
			bool& hasNetPath,
			bool& hasAbsPath,
			bool& hasQuery,
			bool& hasFragment)
{
    bool ret = true;

    const char* pu = url;
    CharStack pf;

    pf.Reset();
                           // protocol: scan to first ':', '/', '?', '#' or EOS
    CollectChars(pu, ":/?#", pf);

				// protocol found
    if (*pu == ':')
    {
	protocol = pf.Finish();
	pu++; // skip ':'

	pf.Reset();  // Clear consumed characters

	if (!*pu)
	{
	    // <scheme>: form is not a valid URL
	    ret = false;
	}
    }
    else			// no protocol
	protocol = "";

    // Check for a net path
    if ((strlen(pf.Finish()) == 0) &&
	(pu[0] == '/') && (pu[1] == '/'))
    {
	// This is a net path
	
	hasNetPath = true;

	pu += 2; // Skip "//"

	// Collect the host name
	CollectChars(pu, ":/?#", pf);
	
	host = pf.Finish();
	pf.Reset(); // Clear consumed characters

					// maybe port: scan to '/' or EOS
	if (*pu == ':')
	{
	    ++pu; // Skip ':'

	                               // Collect port number
	    CollectChars(pu, "/?#", pf);

	    if (strlen(pf.Finish()) != 0)
	    {
		if (!CHXAvConvertUtil::StringToInt(pf.Finish(), port))
		{
		    // Port number conversion failed
		    ret = false;
		}

		pf.Reset(); // Clear consumed characters
	    }
	    else
	    {
		port = 0;

		// No port number present
		ret = false;
	    }
	}
	else
	    port = 0;

	if ((*pu == '?') || (*pu == '#'))
	{
	    // Query or fragment delimiter before the path
	    ret = false;
	}
    }
    else
    {
	// No net path is present

	hasNetPath = false;

	host = "";
	port = 0;
    }

    // Check for absolute path
    if ((strlen(pf.Finish()) == 0) &&
	(*pu == '/'))
    {
	// This is an absolute path.
	hasAbsPath = true;

	pu++; // Skip the '/' since we don't
	      // want it appearing in our path
    }
    else
	hasAbsPath = false;

    // NOTE : pf may contain data at this point in the
    //        case of a relative URL

    // Collect the rest of the path
    CollectChars(pu, "?#", pf);

    path = CHXAvEscapedString(pf.Finish());
    pf.Reset(); // Clear consumed characters
    
    				// query scan to EOS
    if (*pu == '?')
    {
	++pu; // Skip '?'

	hasQuery = true;

	// Collect the rest the query part
	CollectChars(pu, "#", pf);

	query = CHXAvEscapedString(pf.Finish());
	pf.Reset(); // Clear consumed characters
    }
    else
    {
	query = CHXAvEscapedString("");
	hasQuery = false;
    }

    if (*pu == '#')
    {
	++pu; // Skip '#'

	hasFragment = true;

	// Put the rest of the string in the fragment
	fragment = CHXAvEscapedString(pu);
    }
    else
    {
	fragment = CHXAvEscapedString("");
	hasFragment = false;
    }

    return ret;
}

bool CHXAvURLRep::Valid() const
{
    return (m_parseSuccess &&
	    ValidProtocol() &&
	    ValidHostname() &&
	    m_Path.ValidPath() && 
	    m_Query.ValidQuery());
}

bool CHXAvURLRep::ValidProtocol() const
{
    bool ret = true;
    
    const char* pTmp = m_Protocol;

    for(; *pTmp && ret; pTmp++)
    {
	// RFC 2068 'scheme' production
	if (!IsURLSchemeChar(*pTmp))
	    ret = false;
    }

    return ret;
}

bool CHXAvURLRep::ValidHostname() const
{
    // Checks for valid hostname as specified by RFC 952 and RFC 1123
    bool ret = true;
    
    const char* pTmp = m_Host;

    if (*pTmp != '\0')
    {
	int len = 0;
	
	if (IsURLAlnum(*pTmp))
	{
	    for(; *pTmp && ret; pTmp++, len++)
	    {	    
		if (!IsURLAlnum(*pTmp) && (*pTmp != '.') && (*pTmp != '-'))
		    ret = false;
	    }
	}
	else
	{
	    // RFC 1123 Sec 2.1 specifies that it MUST start with a letter OR
	    // a number.
	    ret = false;
	}
	
	if (ret)
	{
	    if (len > 1)
	    {
		pTmp--; // move back to the last character
		
		if ((*pTmp == '-') || (*pTmp == '.'))
		{
		    // a hostname cannot end with a '-' or '.'
		    ret = false;
		}
	    }
	    else
	    {
		// a hostname MUST be more than 1 character long
		ret = false;
	    }
	}
    }

    return ret;
}

void CHXAvURLRep::CollectChars(const char*& pu, const char* pExtraDelim,
			    CharStack& token)
{
    for(; *pu && !strchr(pExtraDelim, *pu); token++)
	*token = *pu++;
}

⌨️ 快捷键说明

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