Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

219 lines
6.1 KiB

  1. #include "stdinc.h"
  2. #include <windows.h>
  3. #include <shlwapi.h>
  4. #include <wchar.h>
  5. #include <string.h>
  6. #include <stdio.h>
  7. #include <ole2.h>
  8. #include <xmlparser.h>
  9. #include "xmlhelper.hxx"
  10. bool isCharAlphaW(WCHAR wChar)
  11. {
  12. FN_TRACE();
  13. WORD ctype1info;
  14. if (!GetStringTypeW(CT_CTYPE1, &wChar, 1, &ctype1info)) {
  15. //
  16. // GetStringTypeW returned an error! IsCharAlphaW has no
  17. // provision for returning an error... The best we can do
  18. // is to return FALSE
  19. //
  20. //UserAssert(FALSE);
  21. ASSERT(FALSE);
  22. return FALSE;
  23. }
  24. if (ctype1info & C1_ALPHA) {
  25. return TRUE;
  26. } else {
  27. return FALSE;
  28. }
  29. }
  30. //////////////////////////////////////////////////////////////////////////////
  31. bool isDigit(WCHAR ch)
  32. {
  33. return (ch >= 0x30 && ch <= 0x39);
  34. }
  35. //////////////////////////////////////////////////////////////////////////////
  36. bool isHexDigit(WCHAR ch)
  37. {
  38. return (ch >= 0x30 && ch <= 0x39) || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F');
  39. }
  40. //////////////////////////////////////////////////////////////////////////////
  41. bool isLetter(WCHAR ch)
  42. {
  43. //return (ch >= 0X41);
  44. return (ch >= 0x41) && ::isCharAlphaW(ch);
  45. // isBaseChar(ch) || isIdeographic(ch);
  46. }
  47. //////////////////////////////////////////////////////////////////////////////
  48. int isStartNameChar(WCHAR ch)
  49. {
  50. return (ch < TABLE_SIZE) ? (g_anCharType[ch] & (FLETTER | FSTARTNAME))
  51. : (isLetter(ch) || (ch == '_' || ch == ':'));
  52. }
  53. //////////////////////////////////////////////////////////////////////////////
  54. bool isCombiningChar(WCHAR ch)
  55. {
  56. UNUSED(ch);
  57. return false;
  58. }
  59. //////////////////////////////////////////////////////////////////////////////
  60. bool isExtender(WCHAR ch)
  61. {
  62. return (ch == 0xb7);
  63. }
  64. //////////////////////////////////////////////////////////////////////////////
  65. bool isAlphaNumeric(WCHAR ch)
  66. {
  67. //return (ch >= 0x30 && ch <= 0x39) ;
  68. return (ch >= 0x30 && ch <= 0x39) || ((ch >= 0x41) && isCharAlphaW(ch));
  69. // isBaseChar(ch) || isIdeographic(ch);
  70. }
  71. //////////////////////////////////////////////////////////////////////////////
  72. int isNameChar(WCHAR ch)
  73. {
  74. return (ch < TABLE_SIZE ? (g_anCharType[ch] & (FLETTER | FDIGIT | FMISCNAME | FSTARTNAME)) :
  75. ( isAlphaNumeric(ch) ||
  76. ch == '-' ||
  77. ch == '_' ||
  78. ch == '.' ||
  79. ch == ':' ||
  80. isCombiningChar(ch) ||
  81. isExtender(ch)));
  82. }
  83. //////////////////////////////////////////////////////////////////////////////
  84. int isCharData(WCHAR ch)
  85. {
  86. // it is in the valid range if it is greater than or equal to
  87. // 0x20, or it is white space.
  88. return (ch < TABLE_SIZE) ? (g_anCharType[ch] & FCHARDATA)
  89. : ((ch < 0xD800 && ch >= 0x20) || // Section 2.2 of spec.
  90. (ch >= 0xE000 && ch < 0xfffe));
  91. }
  92. //==============================================================================
  93. WCHAR BuiltinEntity(const WCHAR* text, ULONG len)
  94. {
  95. ULONG ulength = len * sizeof(WCHAR); // Length in chars
  96. switch (len)
  97. {
  98. case 4:
  99. if (::memcmp(L"quot", text, ulength) == 0)
  100. {
  101. return 34;
  102. }
  103. else if (::memcmp(L"apos", text, ulength) == 0)
  104. {
  105. return 39;
  106. }
  107. break;
  108. case 3:
  109. if (::memcmp(L"amp", text, ulength) == 0)
  110. {
  111. return 38;
  112. }
  113. break;
  114. case 2:
  115. if (::memcmp(L"lt", text, ulength) == 0)
  116. {
  117. return 60;
  118. }
  119. else if (::memcmp(L"gt", text, ulength) == 0)
  120. {
  121. return 62;
  122. }
  123. break;
  124. }
  125. return 0;
  126. }
  127. // Since we cannot use the SHLWAPI wnsprintfA function...
  128. int DecimalToBuffer(long value, char* buffer, int j, long maxdigits)
  129. {
  130. long max = 1;
  131. for (int k = 0; k < maxdigits; k++)
  132. max = max * 10;
  133. if (value > (max*10)-1)
  134. value = (max*10)-1;
  135. max = max/10;
  136. for (int i = 0; i < maxdigits; i++)
  137. {
  138. long digit = (value / max);
  139. value -= (digit * max);
  140. max /= 10;
  141. buffer[i+j] = char('0' + (char)digit);
  142. }
  143. buffer[i+j]=0;
  144. return i+j;
  145. }
  146. /////////////////////////////////////////////////////////////////////
  147. int StrToBuffer(const WCHAR* str, WCHAR* buffer, int j)
  148. {
  149. while (*str != NULL)
  150. {
  151. buffer[j++] = *str++;
  152. }
  153. return j;
  154. }
  155. //==============================================================================
  156. const ULONG MAXWCHAR = 0xFFFF;
  157. HRESULT DecimalToUnicode(const WCHAR* text, ULONG len, WCHAR& ch)
  158. {
  159. ULONG result = 0;
  160. for (ULONG i = 0; i < len; i++)
  161. {
  162. ULONG digit = 0;
  163. if (text[i] >= L'0' && text[i] <= L'9')
  164. {
  165. digit = (text[i] - L'0');
  166. }
  167. else
  168. return XML_E_INVALID_DECIMAL;
  169. // Last unicode value (MAXWCHAR) is reserved as "invalid value"
  170. if (result >= (MAXWCHAR - digit) /10) // result is about to overflow
  171. return XML_E_INVALID_UNICODE; // the maximum 4 byte value.
  172. result = (result*10) + digit;
  173. }
  174. if (result == 0) // zero is also invalid.
  175. return XML_E_INVALID_UNICODE;
  176. ch = (WCHAR)result;
  177. return S_OK;
  178. }
  179. //==============================================================================
  180. HRESULT HexToUnicode(const WCHAR* text, ULONG len, WCHAR& ch)
  181. {
  182. ULONG result = 0;
  183. for (ULONG i = 0; i < len; i++)
  184. {
  185. ULONG digit = 0;
  186. if (text[i] >= L'a' && text[i] <= L'f')
  187. {
  188. digit = 10 + (text[i] - L'a');
  189. }
  190. else if (text[i] >= L'A' && text[i] <= L'F')
  191. {
  192. digit = 10 + (text[i] - L'A');
  193. }
  194. else if (text[i] >= L'0' && text[i] <= L'9')
  195. {
  196. digit = (text[i] - L'0');
  197. }
  198. else
  199. return XML_E_INVALID_HEXIDECIMAL;
  200. // Last unicode value (MAXWCHAR) is reserved as "invalid value"
  201. if (result >= (MAXWCHAR - digit)/16) // result is about to overflow
  202. return XML_E_INVALID_UNICODE; // the maximum 4 byte value.
  203. result = (result*16) + digit;
  204. }
  205. if (result == 0) // zero is also invalid.
  206. return XML_E_INVALID_UNICODE;
  207. ch = (WCHAR)result;
  208. return S_OK;
  209. }