chxavescapedstring.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 282 行
CPP
282 行
/************************************************************************
* chxavescapedstring.cpp
* ----------------------
*
* Synopsis:
* String manipulation. Remove escape chars.
*
* Target:
* Symbian OS
*
*
* (c) 1995-2003 RealNetworks, Inc. Patents pending. All rights reserved.
*
*****************************************************************************/
#include <ctype.h>
#include "hxstring.h"
#include "char_stack.h"
#include "chxavmisc.h"
#include "hxassert.h"
#include "chxavescapedstring.h"
namespace
{
// These are non-alphanumeric characters that are legal and do not
// have to be escaped
const char k_legalChars[] = {
'$', '-', '_', '.', // safe RFC2068 Sec 3.2.1
'!', '*', '\'', '(', ')', ',', // extra RFC2068 Sec 3.2.1
'\0'
};
// These are extra characters that are legal for path strings
// and should not be escaped
const char k_pathChars[] = {
':', '@', '&', '=', // pchar RFC2068 Sec 3.2.1
';', // params RFC2068 Sec 3.2.1
'/', // path RFC2068 Sec 3.2.1
'+', // pchar (must be last)
'\0'
};
// These are extra characters that are legal for query strings
// and should not be escaped
const char k_queryChars[] = {
';', '/', '?', ':', '@', '&', '=', '+', // reserved RFC2068 Sec 3.2.1
'\0'
};
inline
bool IsEscaped(const char* pBuf, int len)
{
bool ret = false;
if ((len >= 3) &&
(pBuf[0] == '%') &&
(isxdigit(pBuf[1])) &&
(isxdigit(pBuf[2])))
ret = true;
return ret;
}
inline
int Hex2Char(char ch)
{
int ret = 0;
if ((ch >= 'a') && (ch <= 'f'))
ret = 10 + ch - 'a';
else if ((ch >= 'A') && (ch <= 'F'))
ret = 10 + ch - 'A';
else
ret = ch - '0';
return ret;
}
inline
bool IsAlphaNum(unsigned char ch)
{
bool ret = false;
if (((ch >= 0x30) && (ch < 0x3a)) || // 0-9
((ch >= 0x41) && (ch < 0x5b)) || // A-Z
((ch >= 0x61) && (ch < 0x7b))) // a-z
ret = true;
return ret;
}
inline
bool IsSpecialChar(char ch, const char* pExtraLegal)
{
bool ret = true;
if ((IsAlphaNum(ch)) ||
(strchr(k_legalChars, ch))||
(strchr(pExtraLegal, ch)))
ret = false;
return ret;
}
inline
char MakeHex(unsigned char ch)
{
static const char z_hexBuf[] = "0123456789ABCDEF";
HX_ASSERT(ch >= 0 && ch < ARRAY_COUNT(z_hexBuf));
return z_hexBuf[ch];
}
CHXString UnEscapeStr(const CHXString& escapedStr)
{
int len = escapedStr.GetLength();
const char* pCur = escapedStr;
CharStack newStr;
while(len)
{
if (IsEscaped(pCur,len))
{
// Contruct the character from the escape sequence and
// copy it into the new string
*newStr = (Hex2Char(pCur[1]) << 4) | Hex2Char(pCur[2]);
newStr++;
pCur += 2;
len -= 2;
}
else
{
// Just copy the character
*newStr = *pCur;
newStr++;
}
pCur++;
len--;
}
return newStr.Finish();
}
CHXString EscapeStr(const CHXString& unescapedStr,
const char* pExtraLegal)
{
int len = unescapedStr.GetLength();
const char* pCur = unescapedStr;
CharStack newPath;
while (len)
{
if (IsSpecialChar(*pCur, pExtraLegal))
{
// Escape this character
*newPath = '%';
newPath++;
*newPath = MakeHex((*pCur >> 4) & 0x0f);
newPath++;
*newPath = MakeHex(*pCur & 0xf);
newPath++;
}
else
{
*newPath = *pCur;
newPath++;
}
pCur++;
len--;
}
return newPath.Finish();
}
bool ValidStr(const CHXString& escapedStr,
const char* pExtraLegal)
{
bool ret = true;
int len = escapedStr.GetLength();
const char* pCur = escapedStr;
CharStack newStr;
while(len)
{
if (IsSpecialChar(*pCur, pExtraLegal) &&
!IsEscaped(pCur,len))
{
// The escaped string has an illegal character in it
ret = false;
break;
}
pCur++;
len--;
}
return ret;
}
} // ns anon
CHXAvEscapedString::CHXAvEscapedString()
{}
CHXAvEscapedString::CHXAvEscapedString(const char* pEscapedStr) :
m_escaped(pEscapedStr),
m_unEscaped(UnEscapeStr(m_escaped))
{}
CHXAvEscapedString::CHXAvEscapedString(const CHXString& escapedStr) :
m_escaped(escapedStr),
m_unEscaped(UnEscapeStr(m_escaped))
{}
bool CHXAvEscapedString::operator == (const CHXAvEscapedString& rhs) const
{
return (bool)(m_escaped == rhs.m_escaped);
}
bool CHXAvEscapedString::operator != (const CHXAvEscapedString& rhs) const
{
return (bool)(m_escaped != rhs.m_escaped);
}
bool CHXAvEscapedString::ValidPath() const
{
return ValidStr(m_escaped, k_pathChars);
}
bool CHXAvEscapedString::ValidQuery() const
{
return ValidStr(m_escaped, k_queryChars);
}
void CHXAvEscapedString::EscapePathStr(const CHXString& unescapedPath, bool bForcePlusEscape)
{
m_unEscaped = unescapedPath;
CHXString strPathChars = k_pathChars;
if(bForcePlusEscape)
{
//
// RFC 1738 2.2: characters that are not required to be encoded
// (including alphanumerics) may be encoded within the scheme-specific
// part of a URL, as long as they are not being used for a reserved
// purpose.
//
// force '+' to be escaped so other unescaping logic doesn't mis-intepret it as a space
INT32 cchPathChars = strPathChars.GetLength();
HX_ASSERT(strPathChars.Find('+') == cchPathChars -1);
strPathChars.SetAt(cchPathChars - 1, '\0');
}
m_escaped = EscapeStr(unescapedPath, strPathChars);
}
void CHXAvEscapedString::EscapeQueryStr(const CHXString& unescapedQuery)
{
m_unEscaped = unescapedQuery;
m_escaped = EscapeStr(unescapedQuery,
k_queryChars);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?