📄 hxurl.cpp
字号:
// host
if (*(m_pszHost = pszCursor) == '\0')
{
m_LastError = HXR_INVALID_URL_HOST;
goto cleanup;
}
// port
pszTemp = (char*) ::HXFindChar(pszCursor, '/');
if (pszTemp)
{
*pszTemp = '\0';
pszCursor = pszTemp+1;
}
else
{
// it's legal to have RTSP or HTTP URLs with no resource.
// The correct behavior for RTSP would be not to flag this as
// an error but the client core treats the lack of a resource
// as a failure. The correct change would be to have the client
// core check explicitly for a resource but legacy code rears its
// ugly head... so we flag the error (client core is happy) but
// go ahead and parse the rest of the headers (so you can still
// get the host:port if you need to). */
if (m_unProtocol != httpProtocol && m_unProtocol != rtspProtocol)
{
m_LastError = HXR_INVALID_URL_PATH;
}
pszCursor = NULL;
}
// port
pszTemp = (char*) ::HXFindChar(m_pszHost, ':');
if (pszTemp)
{
*pszTemp = '\0';
if (*(m_pszPort = pszTemp+1) == '\0')
{
m_LastError = HXR_INVALID_URL_HOST;
goto cleanup;
}
}
if (m_pszHost)
{
::SaveStringToHeader(m_pProperties, PROPERTY_HOST, m_pszHost);
}
if (m_pszPort)
{
m_pProperties->SetPropertyULONG32(PROPERTY_PORT, (ULONG32)atol(m_pszPort));
}
else if (m_unDefaultPort > 0)
{
m_pProperties->SetPropertyULONG32(PROPERTY_PORT, (ULONG32)m_unDefaultPort);
}
if (pszCursor && (*(m_pszResource = pszCursor) == '\0' && m_unProtocol != httpProtocol && m_unProtocol != rtspProtocol))
{
m_LastError = HXR_INVALID_URL_PATH;
goto cleanup;
}
}
//
// other options?
//
/*
// 1.0 player
if (pszTemp = (char*) ::HXFindChar(pszCursor, '$'))
{
*pszTemp = '\0';
pszCursor = pszTemp+1;
if (*(m_pszStartTime = pszCursor) == '\0')
{
m_LastError = HXR_FAILED;
goto cleanup;
}
}
*/
cleanup:
ParseResource();
return m_LastError;
}
void
CHXURL::TrimOffSpaces(char*& pszString)
{
if( NULL == pszString )
return;
char* pszValue = pszString;
char* pszCursor = pszString;
// trim off the leading spaces
while (*pszCursor == ' ')
{
pszCursor++;
}
pszValue = pszCursor;
// trim off the tailing spaces
if( strlen(pszCursor) != 0 )
{
pszCursor = pszCursor + strlen(pszCursor) - 1;
while (*pszCursor == ' ' )
{
pszCursor--;
}
++pszCursor;
if( *pszCursor != '\0' )
*pszCursor = '\0';
}
pszString = pszValue;
}
HX_RESULT
CHXURL::CollectOptions (char* pszOptions)
{
HX_RESULT hr = HXR_OK;
char* pszCursor = NULL;
char* pszKey = NULL;
char* pszValue = NULL;
char* pszTemp = NULL;
BOOL bValueQuoted = FALSE;
if (HXR_OK != m_LastError)
{
return m_LastError;
}
pszCursor = pszOptions;
char* pszEndOptions = pszOptions + strlen(pszOptions);
// let's start parsing
while (pszCursor < pszEndOptions)
{
//
// collect one value pair at a time
//
// <key>="<value>" or <key>=<value>
pszKey = pszCursor;
if (!(pszTemp = (char*) ::HXFindChar(pszCursor, '=')))
{
hr = HXR_FAILED;
goto cleanup;
}
*pszTemp = '\0';
pszCursor = pszTemp + 1;
// remove all the spaces between '=' and actual value
while (*pszCursor == ' ')
{
pszCursor++;
}
// "<value>"
if (*pszCursor == '"')
{
bValueQuoted = TRUE;
pszCursor += 1;
}
pszValue = pszCursor;
if (bValueQuoted)
{
if (!(pszTemp = (char*) ::HXFindChar(pszCursor, '"')))
{
hr = HXR_INCOMPLETE;
goto cleanup;
}
*pszTemp = '\0';
pszCursor = pszTemp + 1;
}
if ((pszTemp = (char*) ::HXFindChar(pszCursor, '&')) != 0)
{
*pszTemp = '\0';
// move cursor to the next pair
pszCursor = pszTemp + 1;
}
else
{
// move cursor to the end of this URL
pszCursor += strlen(pszValue);
}
// trim off leading/tailing spaces
TrimOffSpaces(pszKey);
TrimOffSpaces(pszValue);
// decode each value (option) since it may be URL-encoded.
CHXString strUnescapedOptionValue;
CHXURL::decodeURL(pszValue, strUnescapedOptionValue);
pszValue = (char *)(const char *)strUnescapedOptionValue;
// save to the header
if (!strcasecmp("Start", pszKey)
|| !strcasecmp("End", pszKey)
|| !strcasecmp("Delay", pszKey)
|| !strcasecmp("Duration", pszKey))
{
m_pOptions->SetPropertyULONG32(pszKey, (ULONG32) ::TimeParse(pszValue) * 100);
}
else if (bValueQuoted || !IsNumber(pszValue))
{
IHXBuffer* pBuffer = NULL;
if (m_pCCF)
{
m_pCCF->CreateInstance(CLSID_IHXBuffer, (void**)&pBuffer);
}
if (!pBuffer)
{
hr = HXR_OUTOFMEMORY;
goto cleanup;
}
pBuffer->Set((UCHAR*)pszValue, strlen(pszValue)+1);
m_pOptions->SetPropertyBuffer(pszKey, (IHXBuffer*) pBuffer);
pBuffer->Release();
}
else
{
m_pOptions->SetPropertyULONG32(pszKey, (ULONG32) atol(pszValue));
}
bValueQuoted = FALSE;
pszKey = NULL;
pszValue = NULL;
}
cleanup:
return hr;
}
BOOL
CHXURL::IsTimeValue (char* pszValue)
{
int i = 0;
char* pszData = NULL;
char* pszTemp = NULL;
// time value format: hh:mm:ss
if (isdigit(*pszValue) &&
isdigit(*(pszValue+1)) &&
*(pszValue+2) == ':' &&
isdigit(*(pszValue+3)) &&
isdigit(*(pszValue+4)) &&
*(pszValue+5) == ':' &&
isdigit(*(pszValue+6)) &&
isdigit(*(pszValue+7)))
{
for (i = 0; i < 3; i++)
{
pszData = pszValue;
if (i < 2)
{
pszTemp = (char*) ::HXFindChar(pszValue, ':');
pszTemp = '\0';
}
switch (i)
{
case 0: // hh
if (atoi(pszData) >= 24)
{
return FALSE;
}
break;
case 1: // mm
if (atoi(pszData) >= 60)
{
return FALSE;
}
break;
case 2: // ss
if (atoi(pszData) >= 60)
{
return FALSE;
}
break;
default:
break;
}
pszValue = pszTemp + 1;
}
return TRUE;
}
return FALSE;
}
BOOL
CHXURL::IsNumber(char* pszValue)
{
char* pszCursor = pszValue;
while (*pszCursor != '\0')
{
if (!isdigit(*pszCursor))
{
return FALSE;
}
pszCursor++;
}
return TRUE;
}
// case insensitive compare
int
CHXURL::StringNCompare (const char* pszStr1, const char* pszStr2, size_t nChars)
{
#ifdef _WINDOWS
return strnicmp (pszStr1, pszStr2, nChars);
#elif defined(_MACINTOSH)
return strnicmp (pszStr1, pszStr2, nChars);
#elif defined(_UNIX) || defined(_OPENWAVE)
return strncasecmp (pszStr1, pszStr2, nChars);
#elif defined(_SYMBIAN)
return strnicmp(pszStr1, pszStr2, nChars);
#elif
# error "undefined platform....."
#else
return -1;
#endif
}
void
CHXURL::AddOption(char* pKey, char* pValue)
{
// trim off leading/tailing spaces
TrimOffSpaces(pKey);
TrimOffSpaces(pValue);
// save to the header
if (IsNumber(pValue))
{
m_pOptions->SetPropertyULONG32(pKey, (ULONG32) atol(pValue));
}
else
{
IHXBuffer* pBuffer = NULL;
if (m_pCCF)
{
m_pCCF->CreateInstance(CLSID_IHXBuffer, (void**)&pBuffer);
}
if (pBuffer)
{
pBuffer->Set((UCHAR*)pValue, strlen(pValue)+1);
m_pOptions->SetPropertyBuffer(pKey, (IHXBuffer*) pBuffer);
pBuffer->Release();
}
}
}
void
CHXURL::AddOption(char* pKey, UINT32 ulValue)
{
TrimOffSpaces(pKey);
m_pOptions->SetPropertyULONG32(pKey, ulValue);
}
IHXValues*
CHXURL::GetProperties(void)
{
if (m_pProperties)
{
m_pProperties->AddRef();
}
return m_pProperties;
}
IHXValues*
CHXURL::GetOptions(void)
{
if (m_pOptions)
{
m_pOptions->AddRef();
}
return m_pOptions;
}
char*
CHXURL::GetAltURL(BOOL& bDefault)
{
IHXBuffer* pValue = NULL;
char* pAltURL = NULL;
char* pURL = NULL;
char* pCursor1 = NULL;
char* pCursor2 = NULL;
bDefault = FALSE;
if (HXR_OK != m_LastError)
{
goto cleanup;
}
// retrieve Alt-URL if it exists in the option list
if (HXR_OK == m_pOptions->GetPropertyBuffer("altURL", pValue) && pValue)
{
// allocate mem. for m_pszAltURL
pAltURL = new char[pValue->GetSize()];
SafeStrCpy(pAltURL, (const char*)pValue->GetBuffer(), pValue->GetSize());
}
else if (HXR_OK == m_pProperties->GetPropertyBuffer("url", pValue) && pValue)
{
if (m_unProtocol == pnmProtocol ||
m_unProtocol == rtspProtocol)
{
bDefault = TRUE;
// The +1 is NOT for the NULL terminator since the size already has space for it. The +1 is actually because
// if the URL contains a pnm:// the code below will potentially add a http:// which is one more character than
// a pnm URL. A rtsp:// URL will work correctly
INT32 lSize = pValue->GetSize() + 1;
pAltURL = new char[lSize];
memset(pAltURL, 0, lSize);
pURL = (char*)pValue->GetBuffer();
switch (m_unProtocol)
{
case pnmProtocol:
SafeSprintf(pAltURL, lSize, "http:%s", pURL + 4);
break;
case rtspProtocol:
SafeSprintf(pAltURL, lSize, "http:%s", pURL + 5);
break;
default:
break;
}
// exclude the port from the URL
if (m_pszPort)
{
pCursor1 = strstr(pAltURL, m_pszPort);
pCursor2 = pCursor1 + strlen(m_pszPort);
pCursor1--; // back up over the ':'
while(*pCursor2)
{
*pCursor1++ = *pCursor2++;
}
*pCursor1 = '\0';
}
}
}
cleanup:
HX_RELEASE(pValue);
return pAltURL;
}
void
CHXURL::ParseResource(void)
{
char* pszTemp = NULL;
char* pResource = NULL;
char* pPath = NULL;
char* pFullPath = NULL;
if (m_pszResource && (*m_pszResource != '\0'))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -