|
|
// --------------------------------------------------------------------------------
// Enriched.cpp
// Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
// --------------------------------------------------------------------------------
#include "pch.hxx"
#include "bookbody.h"
#include "internat.h"
#include "mimeapi.h"
#include "demand.h"
// --------------------------------------------------------------------------------
// Charcter Strings used in this code
// --------------------------------------------------------------------------------
static const CHAR c_szAmpersandLT[] = "<"; static const CHAR c_szAmpersandGT[] = ">"; static const CHAR c_szGreaterThan[] = ">"; static const CHAR c_szLessThan[] = "<";
// --------------------------------------------------------------------------------
// Number of characters in a globally defined string
// --------------------------------------------------------------------------------
#define CCHGLOBAL(_szGlobal) (sizeof(_szGlobal) - 1)
// --------------------------------------------------------------------------------
// FReadChar
// --------------------------------------------------------------------------------
inline BOOL FReadChar(IStream *pIn, HRESULT *phr, CHAR *pch) { ULONG cb; *phr = pIn->Read(pch, sizeof(CHAR), &cb); if (FAILED(*phr) || 0 == cb) return FALSE; return TRUE; }
// --------------------------------------------------------------------------------
// MimeOleConvertEnrichedToHTMLEx
// --------------------------------------------------------------------------------
HRESULT MimeOleConvertEnrichedToHTMLEx(IMimeBody *pBody, ENCODINGTYPE ietEncoding, IStream **ppStream) { // Locals
HRESULT hr=S_OK; HCHARSET hCharset; LPSTREAM pStmEnriched=NULL; LPSTREAM pStmHtml=NULL; LPMESSAGEBODY pEnriched=NULL;
// Invalid Args
Assert(pBody && ppStream);
// Get Data
CHECKHR(hr = pBody->GetData(IET_DECODED, &pStmEnriched));
// Get the Charset
if (FAILED(pBody->GetCharset(&hCharset))) hCharset = CIntlGlobals::GetDefBodyCset() ? CIntlGlobals::GetDefBodyCset()->hCharset : NULL;
// Create new virtual stream
CHECKHR(hr = MimeOleCreateVirtualStream(&pStmHtml));
// Make sure rewound
CHECKHR(hr = HrRewindStream(pStmEnriched));
// Convert
CHECKHR(hr = MimeOleConvertEnrichedToHTML(MimeOleGetWindowsCP(hCharset), pStmEnriched, pStmHtml));
// Make sure rewound
CHECKHR(hr = HrRewindStream(pStmHtml));
// Allocate pEnriched
CHECKALLOC(pEnriched = new CMessageBody(NULL, NULL));
// Init
CHECKHR(hr = pEnriched->InitNew());
// Put pstmHtml into pEnriched
CHECKHR(hr = pEnriched->SetData(IET_DECODED, STR_CNT_TEXT, STR_SUB_HTML, IID_IStream, (LPVOID)pStmHtml));
// Get and set the charset
if (hCharset) pEnriched->SetCharset(hCharset, CSET_APPLY_ALL);
// Get Data
CHECKHR(hr = pEnriched->GetData(ietEncoding, ppStream));
exit: // Cleanup
SafeRelease(pStmHtml); SafeRelease(pStmEnriched); SafeRelease(pEnriched);
// Done
return hr; }
// --------------------------------------------------------------------------------
// MimeOleConvertEnrichedToHTML
// --------------------------------------------------------------------------------
MIMEOLEAPI MimeOleConvertEnrichedToHTML(CODEPAGEID codepage, IStream *pIn, IStream *pOut) { // Locals
HRESULT hr=S_OK; CHAR ch; INT i; INT paramct=0; INT nofill=0; CHAR token[62]; LPSTR p; BOOL fDone; CHAR szTemp[2]; // Main loop
while(FReadChar(pIn, &hr, &ch)) { // LeadByte
if (IsDBCSLeadByteEx(codepage, ch)) { // Write This Character
CHECKHR(hr = pOut->Write(&ch, 1, NULL));
// Read Next
if (!FReadChar(pIn, &hr, &ch)) break;
// Write This Character
CHECKHR(hr = pOut->Write(&ch, 1, NULL)); }
// Token Start
else if (ch == '<') { // Read Next
if (!FReadChar(pIn, &hr, &ch)) break;
// Escaped
if (ch == '<') { // Write
CHECKHR(hr = pOut->Write(c_szAmpersandLT, CCHGLOBAL(c_szAmpersandLT), NULL)); } else { // Backup One Character
CHECKHR(hr = HrStreamSeekCur(pIn, -1));
// Setup szTemp
szTemp[1] = '\0';
// Token Scanner
for (fDone=FALSE, i=0, p=token;;i++) { // Read Next Char
if (!FReadChar(pIn, &hr, &ch)) { fDone = TRUE; break; }
// Finished with bracketed toeksn
if (ch == '>') break;
// Fill up the token buffer with lowercase chars
if (i < sizeof(token) - 1) { szTemp[0] = ch; *p++ = IsUpper(szTemp) ? TOLOWERA(ch) : ch; } }
// Nul-term
*p = '\0';
// End of file
if (fDone) break;
// /param
if (lstrcmpi(token, "/param") == 0) { paramct--; CHECKHR(hr = pOut->Write(c_szGreaterThan, CCHGLOBAL(c_szGreaterThan), NULL)); } else if (paramct > 0) { CHECKHR(hr = pOut->Write(c_szAmpersandLT, CCHGLOBAL(c_szAmpersandLT), NULL)); CHECKHR(hr = pOut->Write(token, lstrlen(token), NULL)); CHECKHR(hr = pOut->Write(c_szAmpersandGT, CCHGLOBAL(c_szAmpersandGT), NULL)); } else { CHECKHR(hr = pOut->Write(c_szLessThan, CCHGLOBAL(c_szLessThan), NULL)); if (lstrcmpi(token, "nofill") == 0) { nofill++; CHECKHR(hr = pOut->Write("pre", 3, NULL)); } else if (lstrcmpi(token, "/nofill") == 0) { nofill--; CHECKHR(hr = pOut->Write("/pre", 4, NULL)); } else if (lstrcmpi(token, "bold") == 0) { CHECKHR(hr = pOut->Write("b", 1, NULL)); } else if (lstrcmpi(token, "/bold") == 0) { CHECKHR(hr = pOut->Write("/b", 2, NULL)); } else if (lstrcmpi(token, "underline") == 0) { CHECKHR(hr = pOut->Write("u", 1, NULL)); } else if (lstrcmpi(token, "/underline") == 0) { CHECKHR(hr = pOut->Write("/u", 2, NULL)); } else if (lstrcmpi(token, "italic") == 0) { CHECKHR(hr = pOut->Write("i", 1, NULL)); } else if (lstrcmpi(token, "/italic") == 0) { CHECKHR(hr = pOut->Write("/i", 2, NULL)); } else if (lstrcmpi(token, "fixed") == 0) { CHECKHR(hr = pOut->Write("tt", 2, NULL)); } else if (lstrcmpi(token, "/fixed") == 0) { CHECKHR(hr = pOut->Write("/tt", 3, NULL)); } else if (lstrcmpi(token, "excerpt") == 0) { CHECKHR(hr = pOut->Write("blockquote", 10, NULL)); } else if (lstrcmpi(token, "/excerpt") == 0) { CHECKHR(hr = pOut->Write("/blockquote", 11, NULL)); } else { CHECKHR(hr = pOut->Write("?", 1, NULL)); CHECKHR(hr = pOut->Write(token, lstrlen(token), NULL)); if (lstrcmpi(token, "param") == 0) { paramct++; CHECKHR(hr = pOut->Write(" ", 1, NULL)); continue; } }
CHECKHR(hr = pOut->Write(c_szGreaterThan, CCHGLOBAL(c_szGreaterThan), NULL)); } } } else if (ch == '>') { CHECKHR(hr = pOut->Write(c_szAmpersandGT, CCHGLOBAL(c_szAmpersandGT), NULL)); } else if (ch == '&') { CHECKHR(hr = pOut->Write("&", 5, NULL)); } else { if ((chCR == ch || ch == chLF) && nofill <= 0 && paramct <= 0) { ULONG cCRLF=0; CHAR chTemp;
while(1) { if (!FReadChar(pIn, &hr, &chTemp)) break;
if (chCR == chTemp) continue;
if (chLF != chTemp) { CHECKHR(hr = HrStreamSeekCur(pIn, -1)); break; }
if (cCRLF > 0) { CHECKHR(hr = pOut->Write("<br>", 4, NULL)); }
cCRLF++; }
if (1 == cCRLF) { CHECKHR(hr = pOut->Write(" ", 1, NULL)); } }
// Write the Character
else { CHECKHR(hr = pOut->Write(&ch, 1, NULL)); } } }
exit: // Done
return hr; }
|