Leaked source code of windows server 2003
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.

215 lines
6.2 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 >= '0' && ch <= '9' ) || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F');
  39. }
  40. //////////////////////////////////////////////////////////////////////////////
  41. bool isLetter(WCHAR ch)
  42. {
  43. return (ch >= 'a') && ::isCharAlphaW(ch);
  44. }
  45. //////////////////////////////////////////////////////////////////////////////
  46. int isStartNameChar(WCHAR ch)
  47. {
  48. return (ch < TABLE_SIZE) ? (g_anCharType[ch] & (FLETTER | FSTARTNAME))
  49. : (isLetter(ch) || (ch == '_' || ch == ':'));
  50. }
  51. //////////////////////////////////////////////////////////////////////////////
  52. bool isCombiningChar(WCHAR ch)
  53. {
  54. UNUSED(ch);
  55. return false;
  56. }
  57. //////////////////////////////////////////////////////////////////////////////
  58. bool isExtender(WCHAR ch)
  59. {
  60. return (ch == 0xb7);
  61. }
  62. //////////////////////////////////////////////////////////////////////////////
  63. bool isAlphaNumeric(WCHAR ch)
  64. {
  65. return (ch >= '0' && ch <= '9') || ((ch >= 'a') && isCharAlphaW(ch));
  66. }
  67. //////////////////////////////////////////////////////////////////////////////
  68. int isNameChar(WCHAR ch)
  69. {
  70. return (ch < TABLE_SIZE ? (g_anCharType[ch] & (FLETTER | FDIGIT | FMISCNAME | FSTARTNAME)) :
  71. ( isAlphaNumeric(ch) ||
  72. ch == '-' ||
  73. ch == '_' ||
  74. ch == '.' ||
  75. ch == ':' ||
  76. isCombiningChar(ch) ||
  77. isExtender(ch)));
  78. }
  79. //////////////////////////////////////////////////////////////////////////////
  80. int isCharData(WCHAR ch)
  81. {
  82. // it is in the valid range if it is greater than or equal to
  83. // 0x20, or it is white space.
  84. return (ch < TABLE_SIZE) ? (g_anCharType[ch] & FCHARDATA)
  85. : ((ch < 0xD800 && ch >= 0x20) || // Section 2.2 of spec.
  86. (ch >= 0xE000 && ch < 0xfffe));
  87. }
  88. //==============================================================================
  89. WCHAR BuiltinEntity(const WCHAR* text, ULONG len)
  90. {
  91. ULONG ulength = len * sizeof(WCHAR); // Length in chars
  92. switch (len)
  93. {
  94. case 4:
  95. if (::memcmp(L"quot", text, ulength) == 0)
  96. {
  97. return '\"';
  98. }
  99. else if (::memcmp(L"apos", text, ulength) == 0)
  100. {
  101. return '\'';
  102. }
  103. break;
  104. case 3:
  105. if (::memcmp(L"amp", text, ulength) == 0)
  106. {
  107. return '&';
  108. }
  109. break;
  110. case 2:
  111. if (::memcmp(L"lt", text, ulength) == 0)
  112. {
  113. return '<';
  114. }
  115. else if (::memcmp(L"gt", text, ulength) == 0)
  116. {
  117. return '>';
  118. }
  119. break;
  120. }
  121. return 0;
  122. }
  123. // Since we cannot use the SHLWAPI wnsprintfA function...
  124. int DecimalToBuffer(long value, char* buffer, int j, long maxdigits)
  125. {
  126. long max = 1;
  127. for (int k = 0; k < maxdigits; k++)
  128. max = max * 10;
  129. if (value > (max*10)-1)
  130. value = (max*10)-1;
  131. max = max/10;
  132. for (int i = 0; i < maxdigits; i++)
  133. {
  134. long digit = (value / max);
  135. value -= (digit * max);
  136. max /= 10;
  137. buffer[i+j] = char('0' + (char)digit);
  138. }
  139. buffer[i+j]=0;
  140. return i+j;
  141. }
  142. /////////////////////////////////////////////////////////////////////
  143. int StrToBuffer(const WCHAR* str, WCHAR* buffer, int j)
  144. {
  145. while (*str != UNICODE_NULL)
  146. {
  147. buffer[j++] = *str++;
  148. }
  149. return j;
  150. }
  151. //==============================================================================
  152. const ULONG MAXWCHAR = 0xFFFF;
  153. HRESULT DecimalToUnicode(const WCHAR* text, ULONG len, WCHAR& ch)
  154. {
  155. ULONG result = 0;
  156. for (ULONG i = 0; i < len; i++)
  157. {
  158. ULONG digit = 0;
  159. if (text[i] >= L'0' && text[i] <= L'9')
  160. {
  161. digit = (text[i] - L'0');
  162. }
  163. else
  164. return XML_E_INVALID_DECIMAL;
  165. // Last unicode value (MAXWCHAR) is reserved as "invalid value"
  166. if (result >= (MAXWCHAR - digit) /10) // result is about to overflow
  167. return XML_E_INVALID_UNICODE; // the maximum 4 byte value.
  168. result = (result*10) + digit;
  169. }
  170. if (result == 0) // zero is also invalid.
  171. return XML_E_INVALID_UNICODE;
  172. ch = (WCHAR)result;
  173. return S_OK;
  174. }
  175. //==============================================================================
  176. HRESULT HexToUnicode(const WCHAR* text, ULONG len, WCHAR& ch)
  177. {
  178. ULONG result = 0;
  179. for (ULONG i = 0; i < len; i++)
  180. {
  181. ULONG digit = 0;
  182. if (text[i] >= L'a' && text[i] <= L'f')
  183. {
  184. digit = 10 + (text[i] - L'a');
  185. }
  186. else if (text[i] >= L'A' && text[i] <= L'F')
  187. {
  188. digit = 10 + (text[i] - L'A');
  189. }
  190. else if (text[i] >= L'0' && text[i] <= L'9')
  191. {
  192. digit = (text[i] - L'0');
  193. }
  194. else
  195. return XML_E_INVALID_HEXIDECIMAL;
  196. // Last unicode value (MAXWCHAR) is reserved as "invalid value"
  197. if (result >= (MAXWCHAR - digit)/16) // result is about to overflow
  198. return XML_E_INVALID_UNICODE; // the maximum 4 byte value.
  199. result = (result*16) + digit;
  200. }
  201. if (result == 0) // zero is also invalid.
  202. return XML_E_INVALID_UNICODE;
  203. ch = (WCHAR)result;
  204. return S_OK;
  205. }