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.

389 lines
17 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1996, Microsoft Corporation.
  4. //
  5. // File: htmlchar.cxx
  6. //
  7. // Contents: Contains a translate table from WCHAR to HTML WCHAR
  8. // Translates an WCHAR string to its HTML equivalent
  9. //
  10. // History: 96/Jan/3 DwightKr Created
  11. // 19 Nov 1997 AlanW Added missing named entities. Allow
  12. // for outputing numeric entities if
  13. // codepage translation fails.
  14. //
  15. //----------------------------------------------------------------------------
  16. #include <pch.cxx>
  17. #pragma hdrstop
  18. #include <htmlchar.hxx>
  19. struct WCHAR_TO_HTML
  20. {
  21. WCHAR * wszTranslated;
  22. ULONG cchTranslated;
  23. };
  24. //+---------------------------------------------------------------------------
  25. //----------------------------------------------------------------------------
  26. static const struct WCHAR_TO_HTML WCHAR_TO_HTML[] =
  27. {
  28. L"never", 0xffffffff, // 0 end-of-string
  29. 0, 0, // 1
  30. 0, 0, // 2
  31. 0, 0, // 3
  32. 0, 0, // 4
  33. 0, 0, // 5
  34. 0, 0, // 6
  35. 0, 0, // 7
  36. 0, 0, // 8
  37. L"\t", 1, // 9 tab
  38. L"\n", 1, // 10 newline
  39. 0, 0, // 11
  40. 0, 0, // 12
  41. L"\r", 1, // 13 carriage return
  42. 0, 0, // 14
  43. 0, 0, // 15
  44. 0, 0, // 16
  45. 0, 0, // 17
  46. 0, 0, // 18
  47. 0, 0, // 19
  48. 0, 0, // 20
  49. 0, 0, // 21
  50. 0, 0, // 22
  51. 0, 0, // 23
  52. 0, 0, // 24
  53. 0, 0, // 25
  54. 0, 0, // 26
  55. 0, 0, // 27
  56. 0, 0, // 28
  57. 0, 0, // 29
  58. 0, 0, // 30
  59. 0, 0, // 31
  60. L" ", 1, // 32
  61. L"!", 1, // 33
  62. L"&quot;", 6, // 34
  63. L"#", 1, // 35
  64. L"$", 1, // 36
  65. L"%", 1, // 37
  66. L"&amp;", 5, // 38
  67. L"'", 1, // 39
  68. L"(", 1, // 40
  69. L")", 1, // 41
  70. L"*", 1, // 42
  71. L"+", 1, // 43
  72. L",", 1, // 44
  73. L"-", 1, // 45
  74. L".", 1, // 46
  75. L"/", 1, // 47
  76. L"0", 1, // 48
  77. L"1", 1, // 49
  78. L"2", 1, // 50
  79. L"3", 1, // 51
  80. L"4", 1, // 52
  81. L"5", 1, // 53
  82. L"6", 1, // 54
  83. L"7", 1, // 55
  84. L"8", 1, // 56
  85. L"9", 1, // 57
  86. L":", 1, // 58
  87. L";", 1, // 59
  88. L"&lt;", 4, // 60
  89. L"=", 1, // 61
  90. L"&gt;", 4, // 62
  91. L"?", 1, // 63
  92. L"@", 1, // 64
  93. L"A", 1, // 65
  94. L"B", 1, // 66
  95. L"C", 1, // 67
  96. L"D", 1, // 68
  97. L"E", 1, // 69
  98. L"F", 1, // 70
  99. L"G", 1, // 71
  100. L"H", 1, // 72
  101. L"I", 1, // 73
  102. L"J", 1, // 74
  103. L"K", 1, // 75
  104. L"L", 1, // 76
  105. L"M", 1, // 77
  106. L"N", 1, // 78
  107. L"O", 1, // 79
  108. L"P", 1, // 80
  109. L"Q", 1, // 81
  110. L"R", 1, // 82
  111. L"S", 1, // 83
  112. L"T", 1, // 84
  113. L"U", 1, // 85
  114. L"V", 1, // 86
  115. L"W", 1, // 87
  116. L"X", 1, // 88
  117. L"Y", 1, // 89
  118. L"Z", 1, // 90
  119. L"[", 1, // 91
  120. L"\\", 1, // 92
  121. L"]", 1, // 93
  122. L"^", 1, // 94
  123. L"_", 1, // 95
  124. L"`", 1, // 96
  125. L"a", 1, // 97
  126. L"b", 1, // 98
  127. L"c", 1, // 99
  128. L"d", 1, // 100
  129. L"e", 1, // 101
  130. L"f", 1, // 102
  131. L"g", 1, // 103
  132. L"h", 1, // 104
  133. L"i", 1, // 105
  134. L"j", 1, // 106
  135. L"k", 1, // 107
  136. L"l", 1, // 108
  137. L"m", 1, // 109
  138. L"n", 1, // 110
  139. L"o", 1, // 111
  140. L"p", 1, // 112
  141. L"q", 1, // 113
  142. L"r", 1, // 114
  143. L"s", 1, // 115
  144. L"t", 1, // 116
  145. L"u", 1, // 117
  146. L"v", 1, // 118
  147. L"w", 1, // 119
  148. L"x", 1, // 120
  149. L"y", 1, // 121
  150. L"z", 1, // 122
  151. L"{", 1, // 123
  152. L"|", 1, // 124
  153. L"}", 1, // 125
  154. L"~", 1, // 126
  155. 0, 0, // 127
  156. 0, 0, // 128
  157. 0, 0, // 129
  158. 0, 0, // 130
  159. 0, 0, // 131
  160. 0, 0, // 132
  161. 0, 0, // 133
  162. 0, 0, // 134
  163. 0, 0, // 135
  164. 0, 0, // 136
  165. 0, 0, // 137
  166. 0, 0, // 138
  167. 0, 0, // 139
  168. 0, 0, // 140
  169. 0, 0, // 141
  170. 0, 0, // 142
  171. 0, 0, // 143
  172. 0, 0, // 144
  173. 0, 0, // 145
  174. 0, 0, // 146
  175. 0, 0, // 147
  176. 0, 0, // 148
  177. 0, 0, // 149
  178. 0, 0, // 150
  179. 0, 0, // 151
  180. 0, 0, // 152
  181. 0, 0, // 153
  182. 0, 0, // 154
  183. 0, 0, // 155
  184. 0, 0, // 156
  185. 0, 0, // 157
  186. 0, 0, // 158
  187. 0, 0, // 159
  188. L"&nbsp;", 6, // 160
  189. L"&iexcl;", 7, // 161
  190. L"&cent;", 6, // 162
  191. L"&pound;", 7, // 163
  192. L"&curren;", 8, // 164
  193. L"&yen;", 5, // 165
  194. L"&brvbar;", 8, // 166
  195. L"&sect;", 6, // 167
  196. L"&uml;", 5, // 168
  197. L"&copy;", 6, // 169
  198. L"&ordf;", 6, // 170 - feminine ordinal indicator
  199. L"&laquo;", 7, // 171
  200. L"&not;", 5, // 172 - not sign
  201. L"&shy;", 5, // 173 - soft hyphen
  202. L"&reg;", 5, // 174
  203. L"&macr;", 6, // 175
  204. L"&deg;", 5, // 176
  205. L"&plusmn;", 8, // 177
  206. L"&sup2;", 6, // 178
  207. L"&sup3;", 6, // 179
  208. L"&acute;", 7, // 180
  209. L"&micro;", 7, // 181
  210. L"&para;", 6, // 182
  211. L"&middot;", 8, // 183
  212. L"&cedil;", 7, // 184
  213. L"&sup1;", 6, // 185
  214. L"&ordm;", 6, // 186 - masculine ordinal indicator
  215. L"&raquo;", 7, // 187
  216. L"&frac14;", 8, // 188
  217. L"&frac12;", 8, // 189
  218. L"&frac34;", 8, // 190
  219. L"&iquest;", 8, // 191
  220. L"&Agrave;", 8, // 192
  221. L"&Aacute;", 8, // 193
  222. L"&Acirc;", 7, // 194
  223. L"&Atilde;", 8, // 195
  224. L"&Auml;", 6, // 196
  225. L"&Aring;", 7, // 197
  226. L"&AElig;", 7, // 198
  227. L"&Ccedil;", 8, // 199
  228. L"&Egrave;", 8, // 200
  229. L"&Eacute;", 8, // 201
  230. L"&Ecirc;", 7, // 202
  231. L"&Euml;", 6, // 203
  232. L"&Igrave;", 8, // 204
  233. L"&Iacute;", 8, // 205
  234. L"&Icirc;", 7, // 206
  235. L"&Iuml;", 6, // 207
  236. L"&ETH;", 5, // 208
  237. L"&Ntilde;", 8, // 209
  238. L"&Ograve;", 8, // 210
  239. L"&Oacute;", 8, // 211
  240. L"&Ocirc;", 7, // 212
  241. L"&Otilde;", 8, // 213
  242. L"&Ouml;", 6, // 214
  243. L"&times;", 7, // 215
  244. L"&Oslash;", 8, // 216
  245. L"&Ugrave;", 8, // 217
  246. L"&Uacute;", 8, // 218
  247. L"&Ucirc;", 7, // 219
  248. L"&Uuml;", 6, // 220
  249. L"&Yacute;", 8, // 221
  250. L"&THORN;", 7, // 222
  251. L"&szlig;", 7, // 223
  252. L"&agrave;", 8, // 224
  253. L"&aacute;", 8, // 225
  254. L"&acirc;", 7, // 226
  255. L"&atilde;", 8, // 227
  256. L"&auml;", 6, // 228
  257. L"&aring;", 7, // 229
  258. L"&aelig;", 7, // 230
  259. L"&ccedil;", 8, // 231
  260. L"&egrave;", 8, // 232
  261. L"&eacute;", 8, // 233
  262. L"&ecirc;", 7, // 234
  263. L"&euml;", 6, // 235
  264. L"&igrave;", 8, // 236
  265. L"&iacute;", 8, // 237
  266. L"&icirc;", 7, // 238
  267. L"&iuml;", 6, // 239
  268. L"&eth;", 5, // 240
  269. L"&ntilde;", 8, // 241
  270. L"&ograve;", 8, // 242
  271. L"&oacute;", 8, // 243
  272. L"&ocirc;", 7, // 244
  273. L"&otilde;", 8, // 245
  274. L"&ouml;", 6, // 246
  275. L"&divide;", 8, // 247
  276. L"&oslash;", 8, // 248
  277. L"&ugrave;", 8, // 249
  278. L"&uacute;", 8, // 250
  279. L"&ucirc;", 7, // 251
  280. L"&uuml;", 6, // 252
  281. L"&yacute;", 8, // 253
  282. L"&thorn;", 7, // 254
  283. L"&yuml;", 6, // 255
  284. };
  285. //+---------------------------------------------------------------------------
  286. //
  287. // Function: HTMLEscapeW, public
  288. //
  289. // Synopsis: Appends an escaped version of a string to a virtual string.
  290. //
  291. // Arguments: [wcsString] - string to be translated
  292. // [StrResult] - CVirtualString to which result will be appended
  293. // [ulCodePage] - output codepage
  294. //
  295. // History: 96/Apr/03 dlee Created.
  296. //
  297. //----------------------------------------------------------------------------
  298. void HTMLEscapeW( WCHAR const * wcsString,
  299. CVirtualString & StrResult,
  300. ULONG ulCodePage )
  301. {
  302. unsigned iUnicodeOutputMethod = 0;
  303. do
  304. {
  305. if ( *wcsString < 256 )
  306. {
  307. const struct WCHAR_TO_HTML &Entry = WCHAR_TO_HTML[*wcsString];
  308. if ( 1 == Entry.cchTranslated )
  309. {
  310. StrResult.CharCat( *Entry.wszTranslated );
  311. wcsString++;
  312. continue;
  313. }
  314. // Do the check for end-of-string here, as this is an
  315. // unusual code-path. This saves a compare per loop.
  316. if ( 0 == *wcsString )
  317. break;
  318. // it's ok to pass 0 to StrCat
  319. StrResult.StrCat( Entry.wszTranslated,
  320. Entry.cchTranslated );
  321. }
  322. else
  323. {
  324. //
  325. // A unicode character >= 256 has been found. Either leave it
  326. // as-is in the output string, or convert to the numeric HTML
  327. // entity, depending on whether all unicode characters in the
  328. // string can be translated using the codepage.
  329. //
  330. if ( 0 == iUnicodeOutputMethod )
  331. {
  332. iUnicodeOutputMethod++;
  333. BOOL fUsedDefaultChar = FALSE;
  334. int cchOut = WideCharToMultiByte( ulCodePage,
  335. #if (WINVER >= 0x0500)
  336. WC_NO_BEST_FIT_CHARS |
  337. #endif // (WINVER >= 0x0500)
  338. WC_COMPOSITECHECK |
  339. WC_DEFAULTCHAR,
  340. wcsString,
  341. -1,
  342. 0,
  343. 0,
  344. 0,
  345. &fUsedDefaultChar );
  346. Win4Assert( cchOut != 0 ||
  347. ERROR_INVALID_PARAMETER == GetLastError() );
  348. if ( fUsedDefaultChar ||
  349. cchOut == 0 && ERROR_INVALID_PARAMETER == GetLastError() )
  350. iUnicodeOutputMethod++;
  351. }
  352. if ( 1 == iUnicodeOutputMethod )
  353. {
  354. StrResult.CharCat( *wcsString );
  355. }
  356. else
  357. {
  358. Win4Assert( 2 == iUnicodeOutputMethod );
  359. // Output the numeric html entity
  360. USHORT wch = *wcsString;
  361. WCHAR achNum[6];
  362. _itow( wch, achNum, 10 );
  363. StrResult.CharCat( L'&' );
  364. StrResult.CharCat( L'#' );
  365. StrResult.StrCat( achNum );
  366. StrResult.CharCat( L';' );
  367. }
  368. }
  369. wcsString++;
  370. } while( TRUE );
  371. }