chxavescapedstring.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:6k
- /************************************************************************
- * 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
- ' '
- };
- // 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)
- ' '
- };
- // 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
- ' '
- };
- 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, ' ');
- }
- m_escaped = EscapeStr(unescapedPath, strPathChars);
- }
- void CHXAvEscapedString::EscapeQueryStr(const CHXString& unescapedQuery)
- {
- m_unEscaped = unescapedQuery;
- m_escaped = EscapeStr(unescapedQuery,
- k_queryChars);
- }