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.

315 lines
10 KiB

  1. // --------------------------------------------------------------------------------
  2. // Enriched.cpp
  3. // Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  4. // --------------------------------------------------------------------------------
  5. #include "pch.hxx"
  6. #include "bookbody.h"
  7. #include "internat.h"
  8. #include "mimeapi.h"
  9. #include "demand.h"
  10. // --------------------------------------------------------------------------------
  11. // Charcter Strings used in this code
  12. // --------------------------------------------------------------------------------
  13. static const CHAR c_szAmpersandLT[] = "<";
  14. static const CHAR c_szAmpersandGT[] = ">";
  15. static const CHAR c_szGreaterThan[] = ">";
  16. static const CHAR c_szLessThan[] = "<";
  17. // --------------------------------------------------------------------------------
  18. // Number of characters in a globally defined string
  19. // --------------------------------------------------------------------------------
  20. #define CCHGLOBAL(_szGlobal) (sizeof(_szGlobal) - 1)
  21. // --------------------------------------------------------------------------------
  22. // FReadChar
  23. // --------------------------------------------------------------------------------
  24. inline BOOL FReadChar(IStream *pIn, HRESULT *phr, CHAR *pch)
  25. {
  26. ULONG cb;
  27. *phr = pIn->Read(pch, sizeof(CHAR), &cb);
  28. if (FAILED(*phr) || 0 == cb)
  29. return FALSE;
  30. return TRUE;
  31. }
  32. // --------------------------------------------------------------------------------
  33. // MimeOleConvertEnrichedToHTMLEx
  34. // --------------------------------------------------------------------------------
  35. HRESULT MimeOleConvertEnrichedToHTMLEx(IMimeBody *pBody, ENCODINGTYPE ietEncoding,
  36. IStream **ppStream)
  37. {
  38. // Locals
  39. HRESULT hr=S_OK;
  40. HCHARSET hCharset;
  41. LPSTREAM pStmEnriched=NULL;
  42. LPSTREAM pStmHtml=NULL;
  43. LPMESSAGEBODY pEnriched=NULL;
  44. // Invalid Args
  45. Assert(pBody && ppStream);
  46. // Get Data
  47. CHECKHR(hr = pBody->GetData(IET_DECODED, &pStmEnriched));
  48. // Get the Charset
  49. if (FAILED(pBody->GetCharset(&hCharset)))
  50. hCharset = CIntlGlobals::GetDefBodyCset() ? CIntlGlobals::GetDefBodyCset()->hCharset : NULL;
  51. // Create new virtual stream
  52. CHECKHR(hr = MimeOleCreateVirtualStream(&pStmHtml));
  53. // Make sure rewound
  54. CHECKHR(hr = HrRewindStream(pStmEnriched));
  55. // Convert
  56. CHECKHR(hr = MimeOleConvertEnrichedToHTML(MimeOleGetWindowsCP(hCharset), pStmEnriched, pStmHtml));
  57. // Make sure rewound
  58. CHECKHR(hr = HrRewindStream(pStmHtml));
  59. // Allocate pEnriched
  60. CHECKALLOC(pEnriched = new CMessageBody(NULL, NULL));
  61. // Init
  62. CHECKHR(hr = pEnriched->InitNew());
  63. // Put pstmHtml into pEnriched
  64. CHECKHR(hr = pEnriched->SetData(IET_DECODED, STR_CNT_TEXT, STR_SUB_HTML, IID_IStream, (LPVOID)pStmHtml));
  65. // Get and set the charset
  66. if (hCharset)
  67. pEnriched->SetCharset(hCharset, CSET_APPLY_ALL);
  68. // Get Data
  69. CHECKHR(hr = pEnriched->GetData(ietEncoding, ppStream));
  70. exit:
  71. // Cleanup
  72. SafeRelease(pStmHtml);
  73. SafeRelease(pStmEnriched);
  74. SafeRelease(pEnriched);
  75. // Done
  76. return hr;
  77. }
  78. // --------------------------------------------------------------------------------
  79. // MimeOleConvertEnrichedToHTML
  80. // --------------------------------------------------------------------------------
  81. MIMEOLEAPI MimeOleConvertEnrichedToHTML(CODEPAGEID codepage, IStream *pIn, IStream *pOut)
  82. {
  83. // Locals
  84. HRESULT hr=S_OK;
  85. CHAR ch;
  86. INT i;
  87. INT paramct=0;
  88. INT nofill=0;
  89. CHAR token[62];
  90. LPSTR p;
  91. BOOL fDone;
  92. CHAR szTemp[2];
  93. // Main loop
  94. while(FReadChar(pIn, &hr, &ch))
  95. {
  96. // LeadByte
  97. if (IsDBCSLeadByteEx(codepage, ch))
  98. {
  99. // Write This Character
  100. CHECKHR(hr = pOut->Write(&ch, 1, NULL));
  101. // Read Next
  102. if (!FReadChar(pIn, &hr, &ch))
  103. break;
  104. // Write This Character
  105. CHECKHR(hr = pOut->Write(&ch, 1, NULL));
  106. }
  107. // Token Start
  108. else if (ch == '<')
  109. {
  110. // Read Next
  111. if (!FReadChar(pIn, &hr, &ch))
  112. break;
  113. // Escaped
  114. if (ch == '<')
  115. {
  116. // Write
  117. CHECKHR(hr = pOut->Write(c_szAmpersandLT, CCHGLOBAL(c_szAmpersandLT), NULL));
  118. }
  119. else
  120. {
  121. // Backup One Character
  122. CHECKHR(hr = HrStreamSeekCur(pIn, -1));
  123. // Setup szTemp
  124. szTemp[1] = '\0';
  125. // Token Scanner
  126. for (fDone=FALSE, i=0, p=token;;i++)
  127. {
  128. // Read Next Char
  129. if (!FReadChar(pIn, &hr, &ch))
  130. {
  131. fDone = TRUE;
  132. break;
  133. }
  134. // Finished with bracketed toeksn
  135. if (ch == '>')
  136. break;
  137. // Fill up the token buffer with lowercase chars
  138. if (i < sizeof(token) - 1)
  139. {
  140. szTemp[0] = ch;
  141. *p++ = IsUpper(szTemp) ? TOLOWERA(ch) : ch;
  142. }
  143. }
  144. // Nul-term
  145. *p = '\0';
  146. // End of file
  147. if (fDone)
  148. break;
  149. // /param
  150. if (lstrcmpi(token, "/param") == 0)
  151. {
  152. paramct--;
  153. CHECKHR(hr = pOut->Write(c_szGreaterThan, CCHGLOBAL(c_szGreaterThan), NULL));
  154. }
  155. else if (paramct > 0)
  156. {
  157. CHECKHR(hr = pOut->Write(c_szAmpersandLT, CCHGLOBAL(c_szAmpersandLT), NULL));
  158. CHECKHR(hr = pOut->Write(token, lstrlen(token), NULL));
  159. CHECKHR(hr = pOut->Write(c_szAmpersandGT, CCHGLOBAL(c_szAmpersandGT), NULL));
  160. }
  161. else
  162. {
  163. CHECKHR(hr = pOut->Write(c_szLessThan, CCHGLOBAL(c_szLessThan), NULL));
  164. if (lstrcmpi(token, "nofill") == 0)
  165. {
  166. nofill++;
  167. CHECKHR(hr = pOut->Write("pre", 3, NULL));
  168. }
  169. else if (lstrcmpi(token, "/nofill") == 0)
  170. {
  171. nofill--;
  172. CHECKHR(hr = pOut->Write("/pre", 4, NULL));
  173. }
  174. else if (lstrcmpi(token, "bold") == 0)
  175. {
  176. CHECKHR(hr = pOut->Write("b", 1, NULL));
  177. }
  178. else if (lstrcmpi(token, "/bold") == 0)
  179. {
  180. CHECKHR(hr = pOut->Write("/b", 2, NULL));
  181. }
  182. else if (lstrcmpi(token, "underline") == 0)
  183. {
  184. CHECKHR(hr = pOut->Write("u", 1, NULL));
  185. }
  186. else if (lstrcmpi(token, "/underline") == 0)
  187. {
  188. CHECKHR(hr = pOut->Write("/u", 2, NULL));
  189. }
  190. else if (lstrcmpi(token, "italic") == 0)
  191. {
  192. CHECKHR(hr = pOut->Write("i", 1, NULL));
  193. }
  194. else if (lstrcmpi(token, "/italic") == 0)
  195. {
  196. CHECKHR(hr = pOut->Write("/i", 2, NULL));
  197. }
  198. else if (lstrcmpi(token, "fixed") == 0)
  199. {
  200. CHECKHR(hr = pOut->Write("tt", 2, NULL));
  201. }
  202. else if (lstrcmpi(token, "/fixed") == 0)
  203. {
  204. CHECKHR(hr = pOut->Write("/tt", 3, NULL));
  205. }
  206. else if (lstrcmpi(token, "excerpt") == 0)
  207. {
  208. CHECKHR(hr = pOut->Write("blockquote", 10, NULL));
  209. }
  210. else if (lstrcmpi(token, "/excerpt") == 0)
  211. {
  212. CHECKHR(hr = pOut->Write("/blockquote", 11, NULL));
  213. }
  214. else
  215. {
  216. CHECKHR(hr = pOut->Write("?", 1, NULL));
  217. CHECKHR(hr = pOut->Write(token, lstrlen(token), NULL));
  218. if (lstrcmpi(token, "param") == 0)
  219. {
  220. paramct++;
  221. CHECKHR(hr = pOut->Write(" ", 1, NULL));
  222. continue;
  223. }
  224. }
  225. CHECKHR(hr = pOut->Write(c_szGreaterThan, CCHGLOBAL(c_szGreaterThan), NULL));
  226. }
  227. }
  228. }
  229. else if (ch == '>')
  230. {
  231. CHECKHR(hr = pOut->Write(c_szAmpersandGT, CCHGLOBAL(c_szAmpersandGT), NULL));
  232. }
  233. else if (ch == '&')
  234. {
  235. CHECKHR(hr = pOut->Write("&amp;", 5, NULL));
  236. }
  237. else
  238. {
  239. if ((chCR == ch || ch == chLF) && nofill <= 0 && paramct <= 0)
  240. {
  241. ULONG cCRLF=0;
  242. CHAR chTemp;
  243. while(1)
  244. {
  245. if (!FReadChar(pIn, &hr, &chTemp))
  246. break;
  247. if (chCR == chTemp)
  248. continue;
  249. if (chLF != chTemp)
  250. {
  251. CHECKHR(hr = HrStreamSeekCur(pIn, -1));
  252. break;
  253. }
  254. if (cCRLF > 0)
  255. {
  256. CHECKHR(hr = pOut->Write("<br>", 4, NULL));
  257. }
  258. cCRLF++;
  259. }
  260. if (1 == cCRLF)
  261. {
  262. CHECKHR(hr = pOut->Write(" ", 1, NULL));
  263. }
  264. }
  265. // Write the Character
  266. else
  267. {
  268. CHECKHR(hr = pOut->Write(&ch, 1, NULL));
  269. }
  270. }
  271. }
  272. exit:
  273. // Done
  274. return hr;
  275. }