chxavescapedstring.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:6k
源码类别:

Symbian

开发平台:

C/C++

  1. /************************************************************************
  2.  * chxavescapedstring.cpp
  3.  * ----------------------
  4.  *
  5.  * Synopsis:
  6.  * String manipulation.  Remove escape chars.
  7.  *
  8.  * Target:
  9.  * Symbian OS
  10.  *
  11.  *
  12.  * (c) 1995-2003 RealNetworks, Inc. Patents pending. All rights reserved.
  13.  *
  14.  *****************************************************************************/
  15.  
  16. #include <ctype.h>
  17. #include "hxstring.h"
  18. #include "char_stack.h"
  19. #include "chxavmisc.h"
  20. #include "hxassert.h"
  21. #include "chxavescapedstring.h"
  22. namespace
  23. {
  24. // These are non-alphanumeric characters that are legal and do not
  25. // have to be escaped
  26. const char k_legalChars[] = { 
  27.     '$', '-', '_', '.',            // safe  RFC2068 Sec 3.2.1
  28.     '!', '*', ''', '(', ')', ',', // extra RFC2068 Sec 3.2.1
  29.     ''
  30. };
  31. // These are extra characters that are legal for path strings
  32. // and should not be escaped
  33. const char k_pathChars[] = {
  34.     ':', '@', '&', '=',       // pchar  RFC2068 Sec 3.2.1
  35.     ';',                      // params RFC2068 Sec 3.2.1
  36.     '/',                      // path   RFC2068 Sec 3.2.1
  37.     '+',                      // pchar (must be last)
  38.     ''
  39. };
  40. // These are extra characters that are legal for query strings
  41. // and should not be escaped
  42. const char k_queryChars[] = {
  43.     ';', '/', '?', ':', '@', '&', '=', '+', // reserved RFC2068 Sec 3.2.1
  44.     ''
  45. };
  46. inline
  47. bool IsEscaped(const char* pBuf, int len)
  48. {
  49.     bool ret = false;
  50.     if ((len >= 3) &&
  51. (pBuf[0] == '%') &&
  52. (isxdigit(pBuf[1])) &&
  53. (isxdigit(pBuf[2])))
  54. ret = true;
  55.     return ret;
  56. }
  57. inline 
  58. int Hex2Char(char ch)
  59. {
  60.     int ret = 0;
  61.     if ((ch >= 'a') && (ch <= 'f'))
  62. ret =  10 + ch - 'a';
  63.     else if ((ch >= 'A') && (ch <= 'F'))
  64. ret =  10 + ch - 'A';
  65.     else
  66. ret = ch - '0';
  67.     
  68.     return ret;
  69. }
  70. inline
  71. bool IsAlphaNum(unsigned char ch)
  72. {
  73.     bool ret = false;
  74.     
  75.     if (((ch >= 0x30) && (ch < 0x3a)) ||  // 0-9
  76. ((ch >= 0x41) && (ch < 0x5b)) ||  // A-Z
  77. ((ch >= 0x61) && (ch < 0x7b)))    // a-z
  78. ret = true;
  79.     
  80.     return ret;
  81. }
  82. inline
  83. bool IsSpecialChar(char ch, const char* pExtraLegal)
  84. {
  85.     bool ret = true;
  86.     if ((IsAlphaNum(ch)) ||
  87. (strchr(k_legalChars, ch))||
  88. (strchr(pExtraLegal, ch)))
  89. ret = false;
  90.        
  91.     return ret;
  92. }
  93. inline
  94. char MakeHex(unsigned char ch)
  95. {
  96.     static const char z_hexBuf[] = "0123456789ABCDEF";
  97.     HX_ASSERT(ch >= 0 && ch < ARRAY_COUNT(z_hexBuf));
  98.     return z_hexBuf[ch];
  99. }
  100. CHXString UnEscapeStr(const CHXString& escapedStr)
  101. {
  102.     int len = escapedStr.GetLength();
  103.     const char* pCur = escapedStr;
  104.     CharStack newStr;
  105.     while(len)
  106.     {
  107. if (IsEscaped(pCur,len))
  108. {
  109.     // Contruct the character from the escape sequence and
  110.     // copy it into the new string
  111.     *newStr = (Hex2Char(pCur[1]) << 4) | Hex2Char(pCur[2]);
  112.     newStr++;
  113.     pCur += 2;
  114.     len -= 2;
  115. }
  116. else
  117. {
  118.     // Just copy the character
  119.     *newStr = *pCur;
  120.     newStr++;
  121. }
  122. pCur++;
  123. len--;
  124.     }
  125.     return newStr.Finish();
  126. }
  127. CHXString EscapeStr(const CHXString& unescapedStr,
  128.     const char* pExtraLegal)
  129. {
  130.     int len = unescapedStr.GetLength();
  131.     const char* pCur = unescapedStr;
  132.     
  133.     CharStack newPath;
  134.     while (len)
  135.     {
  136. if (IsSpecialChar(*pCur, pExtraLegal))
  137. {
  138.     // Escape this character
  139.     *newPath = '%';
  140.     newPath++;
  141.     
  142.     *newPath = MakeHex((*pCur >> 4) & 0x0f);
  143.     newPath++;
  144.     
  145.     *newPath = MakeHex(*pCur & 0xf);
  146.     newPath++;
  147. }
  148. else
  149. {
  150.     *newPath = *pCur;
  151.     newPath++;
  152. }
  153. pCur++;
  154. len--; 
  155.     }
  156.     return newPath.Finish();
  157. }
  158. bool ValidStr(const CHXString& escapedStr,
  159.        const char* pExtraLegal)
  160. {
  161.     bool ret = true;
  162.     int len = escapedStr.GetLength();
  163.     const char* pCur = escapedStr;
  164.     CharStack newStr;
  165.     while(len)
  166.     {
  167. if (IsSpecialChar(*pCur, pExtraLegal) &&
  168.     !IsEscaped(pCur,len))
  169. {
  170.     // The escaped string has an illegal character in it
  171.     ret = false;
  172.     break;
  173. }
  174. pCur++;
  175. len--;
  176.     }
  177.     return ret;
  178. }
  179. } // ns anon
  180. CHXAvEscapedString::CHXAvEscapedString()
  181. {}
  182. CHXAvEscapedString::CHXAvEscapedString(const char* pEscapedStr) :
  183.     m_escaped(pEscapedStr),
  184.     m_unEscaped(UnEscapeStr(m_escaped))
  185. {}
  186. CHXAvEscapedString::CHXAvEscapedString(const CHXString& escapedStr) :
  187.     m_escaped(escapedStr),
  188.     m_unEscaped(UnEscapeStr(m_escaped))
  189. {}
  190. bool CHXAvEscapedString::operator == (const CHXAvEscapedString& rhs) const
  191. {
  192.     return (bool)(m_escaped == rhs.m_escaped);
  193. }
  194. bool CHXAvEscapedString::operator != (const CHXAvEscapedString& rhs) const
  195. {
  196.     return (bool)(m_escaped != rhs.m_escaped);
  197. }
  198. bool CHXAvEscapedString::ValidPath() const
  199. {
  200.     return ValidStr(m_escaped, k_pathChars);
  201. }
  202. bool CHXAvEscapedString::ValidQuery() const
  203. {
  204.     return ValidStr(m_escaped, k_queryChars);
  205. }
  206. void CHXAvEscapedString::EscapePathStr(const CHXString& unescapedPath, bool bForcePlusEscape)
  207. {
  208.     m_unEscaped = unescapedPath;
  209.     CHXString strPathChars = k_pathChars;
  210.     if(bForcePlusEscape)
  211.     {
  212.         //
  213.         // RFC 1738 2.2: characters that are not required to be encoded
  214.         // (including alphanumerics) may be encoded within the scheme-specific
  215.         // part of a URL, as long as they are not being used for a reserved
  216.         // purpose.
  217.         //
  218.         // force '+' to be escaped so other unescaping logic doesn't mis-intepret it as a space
  219.         INT32 cchPathChars = strPathChars.GetLength();
  220.         HX_ASSERT(strPathChars.Find('+') == cchPathChars -1);
  221.         strPathChars.SetAt(cchPathChars - 1, '');
  222.     }
  223.     m_escaped = EscapeStr(unescapedPath, strPathChars);
  224. }
  225. void CHXAvEscapedString::EscapeQueryStr(const CHXString& unescapedQuery)
  226. {
  227.     m_unEscaped = unescapedQuery;
  228.     m_escaped = EscapeStr(unescapedQuery,
  229.   k_queryChars);
  230. }