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

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #include "hxresult.h"
  36. #include "hxassert.h"
  37. #include "hxheap.h"
  38. #include "hxstrutl.h"
  39. #include "xmlencod.h"
  40. #include "xmlvalid.h"
  41. #ifdef _DEBUG
  42. #undef HX_THIS_FILE
  43. static const char HX_THIS_FILE[] = __FILE__;
  44. #endif
  45. struct xmlEncodingInfo
  46. {
  47.     char*   m_pIANAName; // name of charset, case-insensitive
  48.     BOOL    m_bDoubleByte; // true if DBCS charset
  49.     BYTE    m_szLeadingByteRange[12]; // up to 5 zero-terminated
  50. // pairs of lead byte ranges
  51. } ;
  52. // Removed static here because it exercises a bug in gcc.  pgodman, 3/2/2000
  53. const xmlEncodingInfo XMLEncodingInfo[] =
  54. {
  55.     { "Default", TRUE,     // assume DBCS; any non-ASCII char is a lead byte
  56. 0x81, 0xFF, 0x00, 0x00, 0x00, 0x00,
  57. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
  58.     { "US-ASCII", FALSE, 
  59. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  60. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
  61.     { "Shift-JIS", TRUE, 
  62. 0x81, 0x9F, 0xE0, 0xFC, 0x00, 0x00, 
  63. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
  64.     { "Big5", TRUE,
  65. 0x81, 0xFE, 0x00, 0x00, 0x00, 0x00,
  66. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
  67.     { "GB2312", TRUE,
  68. 0xA1, 0xFE, 0x00, 0x00, 0x00, 0x00,
  69. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
  70.     { "EUC-KR", TRUE,
  71. 0x84, 0xD3, 0xD8, 0xD8, 0xD9, 0xDE,
  72. 0xE0, 0xF9, 0x00, 0x00, 0x00, 0x00 },
  73.     { "ISO-2022-KR", TRUE,
  74. 0x81, 0xFE, 0x00, 0x00, 0x00, 0x00,
  75. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
  76.     { "ISO-8859-1", FALSE,
  77. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  78. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
  79. };
  80. CHXXMLEncode::CHXXMLEncode(const char* pEncoding,
  81.    BYTE* pBuffer,
  82.    UINT32 ulLength):
  83.     m_ulBufferLength(ulLength),
  84.     m_pBuffer(pBuffer),
  85.     m_pCurrent(pBuffer)
  86. {
  87.     m_lEncodingIndex = GetEncodingIndex(pEncoding);
  88. }
  89. CHXXMLEncode::CHXXMLEncode(const char* pEncoding,
  90.    BYTE* pStr):
  91.     m_pBuffer(pStr),
  92.     m_pCurrent(pStr)
  93. {
  94.     m_ulBufferLength = strlen((char*)pStr) + 1;
  95.     m_lEncodingIndex = GetEncodingIndex(pEncoding);
  96. }
  97. CHXXMLEncode::CHXXMLEncode(const CHXXMLEncode& lhs)
  98. {
  99.     m_ulBufferLength = lhs.m_ulBufferLength;
  100.     m_pBuffer = lhs.m_pBuffer;
  101.     m_pCurrent = m_pBuffer;
  102.     m_lEncodingIndex = lhs.m_lEncodingIndex;
  103. }
  104. CHXXMLEncode::~CHXXMLEncode()
  105. {
  106. }
  107. const CHXXMLEncode&
  108. CHXXMLEncode::operator=(const CHXXMLEncode& lhs)
  109. {
  110.     m_ulBufferLength = lhs.m_ulBufferLength;
  111.     m_pBuffer = lhs.m_pBuffer;
  112.     m_pCurrent = m_pBuffer; // start at 0
  113.     m_lEncodingIndex = lhs.m_lEncodingIndex;
  114.     return *this;
  115. }
  116. CHXXMLEncode::operator const BYTE*() const
  117. {
  118.     return (const BYTE*)m_pBuffer;
  119. }
  120. BYTE*
  121. CHXXMLEncode::operator+(int offset)
  122. {
  123.     BYTE* pCh = m_pCurrent;
  124.     for(int nCount = 0; nCount < offset; ++nCount)
  125.     {
  126. UINT16 uLen = 0;
  127. GetNextChar(uLen);
  128.     }
  129.     BYTE* pOffset = m_pCurrent;
  130.     m_pCurrent = pCh;
  131.     return pOffset;
  132. }
  133. BYTE*
  134. CHXXMLEncode::operator+=(int offset)
  135. {
  136.     BYTE* pCh = m_pCurrent;
  137.     for(int nCount = 0; nCount < offset; ++nCount)
  138.     {
  139. UINT16 uLen = 0;
  140. pCh = GetNextChar(uLen);
  141.     }
  142.     return pCh;
  143. }
  144. BYTE*
  145. CHXXMLEncode::operator++(int)
  146. {
  147.     UINT16 uLen = 0;
  148.     return GetNextChar(uLen);
  149. }
  150. BYTE*
  151. CHXXMLEncode::operator--(int)
  152. {
  153.     UINT16 uLen = 0;
  154.     return GetPrevChar(uLen);
  155. }
  156. BOOL
  157. CHXXMLEncode::IsLeadByte(BYTE ch)
  158. {
  159.     int bRange = 0;
  160.     const xmlEncodingInfo* pEncInfo = &(XMLEncodingInfo[m_lEncodingIndex]);
  161.     if(pEncInfo->m_bDoubleByte)
  162.     {
  163. while((bRange < 12) &&
  164.       (pEncInfo->m_szLeadingByteRange[bRange] != 0))
  165. {
  166.     if(ch >= pEncInfo->m_szLeadingByteRange[bRange] &&
  167.        ch <= pEncInfo->m_szLeadingByteRange[bRange + 1])
  168.     {
  169. return TRUE;
  170.     }
  171.     bRange += 2;
  172. }
  173.     }
  174.     return FALSE;
  175. }
  176. BYTE*
  177. CHXXMLEncode::GetNextChar(UINT16& uLen)
  178. {
  179.     BYTE* pCh = m_pCurrent;
  180.     if(IsLeadByte(*m_pCurrent))
  181.     {
  182. m_pCurrent += 2;    // skip 2 bytes
  183. uLen = 2;
  184. return pCh;
  185.     }
  186.     m_pCurrent++;   // skip 1 byte
  187.     uLen = 1;
  188.     return pCh;
  189. }
  190. BYTE*
  191. CHXXMLEncode::GetPrevChar(UINT16& uLen)
  192. {
  193.     BYTE* pCh = m_pCurrent;
  194.     // assumes the m_pCurrent is on a boundary, i.e. it doesn't
  195.     // point to the middle of a DBCS character
  196.     // if current is at beginning or the previous byte is
  197.     // at the beginning, return current
  198.     if(m_pCurrent - 1 <= m_pBuffer)
  199.     {
  200. return pCh;
  201.     }
  202.     // point to the previous byte
  203.     BYTE* pTemp = m_pCurrent - 1;
  204.     // if pTemp points to a lead byte, then it must be a trail byte;
  205.     // decrement current 2 bytes to lead byte
  206.     if(IsLeadByte(*pTemp))
  207.     {
  208. m_pCurrent -= 2;
  209. pCh = m_pCurrent;
  210. uLen = 2;
  211. return pCh;
  212.     }
  213.     // otherwise, step back unil a non-lead byte is found
  214.     while(m_pCurrent <= --pTemp && IsLeadByte(*pTemp))
  215.     {
  216. ;
  217.     }
  218.     // now pTemp + 1 must point to the beginning of a character,
  219.     // so figure out whether we went back to an even or an odd
  220.     // number of bytes and go back 1 or 2 bytes, respectively.
  221.     m_pCurrent = m_pCurrent - 1 - ((m_pCurrent - pTemp) & 1);
  222.     pCh = m_pCurrent;
  223.     if(IsLeadByte(*pCh))
  224.     {
  225. uLen = 2;
  226.     }
  227.     else
  228.     {
  229. uLen = 1;
  230.     }
  231.     return pCh;
  232. }
  233. BYTE*
  234. CHXXMLEncode::SetCurrent(BYTE* pCh)
  235. {
  236.     // no checking other than boundary;
  237.     // if it is set on the trail byte
  238.     // of a DBCS character, bad things
  239.     // will happen...
  240.     HX_ASSERT(pCh >= m_pBuffer &&
  241.       pCh <= m_pBuffer + m_ulBufferLength);
  242.     m_pCurrent = pCh;
  243.     return m_pCurrent;
  244. }
  245. UINT32
  246. CHXXMLEncode::CharCount()
  247. {
  248.     UINT32 ulLength = 0;
  249.     BYTE* pCh = m_pBuffer;
  250.     if(XMLEncodingInfo[m_lEncodingIndex].m_bDoubleByte)
  251.     {
  252. UINT16 uLen = 0;
  253. for(; *pCh; pCh = GetNextChar(uLen))
  254. {
  255.     ++ulLength;
  256. }
  257.     }
  258.     else
  259.     {
  260. for(; *pCh; pCh++)
  261. {
  262.     ++ulLength;
  263. }
  264.     }
  265.     return ulLength;
  266. }
  267. INT32
  268. CHXXMLEncode::GetEncodingIndex(const char* pEncoding)
  269. {
  270.     INT32 lIndex = 0; // default
  271.     for(INT32 lCount = 0; 
  272. lCount < sizeof(XMLEncodingInfo) / sizeof(XMLEncodingInfo[0]);
  273. ++lCount)
  274.     {
  275. if(strcasecmp(pEncoding, XMLEncodingInfo[lCount].m_pIANAName) == 0)
  276. {
  277.     lIndex = lCount;
  278.     break;
  279. }
  280.     }
  281.     return lIndex;
  282. }
  283. BOOL
  284. CHXXMLEncode::IsRefValid(const BYTE* p, UINT32 len)
  285. {
  286.     if (!XMLEncodingInfo[m_lEncodingIndex].m_bDoubleByte)
  287.     {
  288. return ISO8859Valid::IsRefValid(p, len);
  289.     }
  290.     else
  291.     {
  292. // TODO: Double byte Validation
  293. return TRUE;
  294.     }
  295. }
  296. BOOL
  297. CHXXMLEncode::IsNameValid(const BYTE* p, UINT32 len)
  298. {
  299.     if (!XMLEncodingInfo[m_lEncodingIndex].m_bDoubleByte)
  300.     {
  301. return ISO8859Valid::IsNameValid(p, len);
  302.     }
  303.     else
  304.     {
  305. // TODO: Double byte Validation.
  306. return TRUE;
  307.     }
  308. }
  309. BOOL
  310. CHXXMLEncode::IsNmtokenValid(const BYTE*p, UINT32 len)
  311. {
  312.     if (!XMLEncodingInfo[m_lEncodingIndex].m_bDoubleByte)
  313.     {
  314. return ISO8859Valid::IsNmtokenValid(p, len);
  315.     }
  316.     else
  317.     {
  318. // TODO: Double byte Validation.
  319. return TRUE;
  320.     }
  321. }
  322. BOOL
  323. CHXXMLEncode::IsEntityValueValid(const BYTE* p, UINT32 len)
  324. {
  325.     if (!XMLEncodingInfo[m_lEncodingIndex].m_bDoubleByte)
  326.     {
  327. return ISO8859Valid::IsEntityValueValid(p, len);
  328.     }
  329.     else
  330.     {
  331. return TRUE;
  332.     }
  333. }
  334. BOOL 
  335. CHXXMLEncode::IsAttValueValid(const BYTE* p, UINT32 len)
  336. {
  337.     if (!XMLEncodingInfo[m_lEncodingIndex].m_bDoubleByte)
  338.     {
  339. return ISO8859Valid::IsAttValueValid(p, len);
  340.     }
  341.     else
  342.     {
  343. // TODO: Double byte Validation.
  344. return TRUE;
  345.     }
  346. }
  347. BOOL 
  348. CHXXMLEncode::IsSystemLiteralValid(const BYTE* p, UINT32 len)
  349. {
  350.     if (!XMLEncodingInfo[m_lEncodingIndex].m_bDoubleByte)
  351.     {
  352. return ISO8859Valid::IsSystemLiteralValid(p, len);
  353.     }
  354.     else
  355.     {
  356. // TODO: Double byte Validation.
  357. return TRUE;
  358.     }
  359. }
  360. BOOL
  361. CHXXMLEncode::IsPubidLiteralValid(const BYTE* p, UINT32 len)
  362. {
  363.     if (!XMLEncodingInfo[m_lEncodingIndex].m_bDoubleByte)
  364.     {
  365. return ISO8859Valid::IsPubidLiteralValid(p, len);
  366.     }
  367.     else
  368.     {
  369. // TODO: Double byte Validation.
  370. return TRUE;
  371.     }
  372. }