Make RTF reader fall back to simple text if a correct RTF header is

not detected. This should fix some installers.
This commit is contained in:
Phil Krylov 2005-04-13 11:11:03 +00:00 committed by Alexandre Julliard
parent ad7f4daf35
commit 1e9c200f61
5 changed files with 109 additions and 67 deletions

View File

@ -233,36 +233,40 @@ ME_TextBuffer *ME_MakeText() {
return buf; return buf;
} }
#define STREAMIN_BUFFER_SIZE 4096 /* M$ compatibility */
static LRESULT ME_StreamInText(ME_TextEditor *editor, DWORD dwFormat, EDITSTREAM *stream, ME_Style *style) static LRESULT ME_StreamInText(ME_TextEditor *editor, DWORD dwFormat, ME_InStream *stream, ME_Style *style)
{ {
BYTE buffer[STREAMIN_BUFFER_SIZE+1];
WCHAR wszText[STREAMIN_BUFFER_SIZE+1]; WCHAR wszText[STREAMIN_BUFFER_SIZE+1];
WCHAR *pText;
TRACE("%08lx %p\n", dwFormat, stream); TRACE("%08lx %p\n", dwFormat, stream);
stream->dwError = 0;
do { do {
long nDataSize = 0, nWideChars = 0; long nWideChars = 0;
stream->dwError = stream->pfnCallback(stream->dwCookie,
(dwFormat & SF_UNICODE ? (BYTE *)wszText : buffer),
STREAMIN_BUFFER_SIZE, &nDataSize);
if (stream->dwError) if (!stream->dwSize)
{
ME_StreamInFill(stream);
if (stream->editstream->dwError)
break; break;
if (!nDataSize) if (!stream->dwSize)
break; break;
}
if (!(dwFormat & SF_UNICODE)) if (!(dwFormat & SF_UNICODE))
{ {
/* FIXME? this is doomed to fail on true MBCS like UTF-8, luckily they're unlikely to be used as CP_ACP */ /* FIXME? this is doomed to fail on true MBCS like UTF-8, luckily they're unlikely to be used as CP_ACP */
nWideChars = MultiByteToWideChar(CP_ACP, 0, buffer, nDataSize, wszText, STREAMIN_BUFFER_SIZE); nWideChars = MultiByteToWideChar(CP_ACP, 0, stream->buffer, stream->dwSize, wszText, STREAMIN_BUFFER_SIZE);
pText = wszText;
} }
else else
nWideChars = nDataSize>>1; {
ME_InsertTextFromCursor(editor, 0, wszText, nWideChars, style); nWideChars = stream->dwSize >> 1;
if (nDataSize<STREAMIN_BUFFER_SIZE) pText = (WCHAR *)stream->buffer;
}
ME_InsertTextFromCursor(editor, 0, pText, nWideChars, style);
if (stream->dwSize < STREAMIN_BUFFER_SIZE)
break; break;
} while(1); } while(1);
ME_CommitUndo(editor); ME_CommitUndo(editor);
@ -428,6 +432,16 @@ void ME_RTFReadHook(RTF_Info *info) {
} }
} }
void
ME_StreamInFill(ME_InStream *stream)
{
stream->editstream->dwError = stream->editstream->pfnCallback(stream->editstream->dwCookie,
stream->buffer,
sizeof(stream->buffer),
&stream->dwSize);
stream->dwUsed = 0;
}
static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stream) static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stream)
{ {
RTF_Info parser; RTF_Info parser;
@ -435,6 +449,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
int from, to, to2, nUndoMode; int from, to, to2, nUndoMode;
ME_UndoItem *pUI; ME_UndoItem *pUI;
int nEventMask = editor->nEventMask; int nEventMask = editor->nEventMask;
ME_InStream inStream;
TRACE("%p %p\n", stream, editor->hWnd); TRACE("%p %p\n", stream, editor->hWnd);
editor->nEventMask = 0; editor->nEventMask = 0;
@ -457,10 +472,32 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
nUndoMode = editor->nUndoMode; nUndoMode = editor->nUndoMode;
editor->nUndoMode = umIgnore; editor->nUndoMode = umIgnore;
inStream.editstream = stream;
inStream.editstream->dwError = 0;
inStream.dwSize = 0;
inStream.dwUsed = 0;
if (format & SF_RTF)
{
/* Check if it's really RTF, and if it is not, use plain text */
ME_StreamInFill(&inStream);
if (!inStream.editstream->dwError)
{
if (strncmp(inStream.buffer, "{\\rtf1", 6) && strncmp(inStream.buffer, "{\\urtf", 6))
{
format &= ~SF_RTF;
format |= SF_TEXT;
}
}
}
if (!inStream.editstream->dwError)
{
if (format & SF_RTF) { if (format & SF_RTF) {
/* setup the RTF parser */ /* setup the RTF parser */
memset(&parser, 0, sizeof parser); memset(&parser, 0, sizeof parser);
RTFSetEditStream(&parser, stream); RTFSetEditStream(&parser, &inStream);
parser.rtfFormat = format&(SF_TEXT|SF_RTF); parser.rtfFormat = format&(SF_TEXT|SF_RTF);
parser.hwndEdit = editor->hWnd; parser.hwndEdit = editor->hWnd;
parser.editor = editor; parser.editor = editor;
@ -478,7 +515,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
style = parser.style; style = parser.style;
} }
else if (format & SF_TEXT) else if (format & SF_TEXT)
ME_StreamInText(editor, format, stream, style); ME_StreamInText(editor, format, &inStream, style);
else else
ERR("EM_STREAMIN without SF_TEXT or SF_RTF\n"); ERR("EM_STREAMIN without SF_TEXT or SF_RTF\n");
ME_GetSelection(editor, &to, &to2); ME_GetSelection(editor, &to, &to2);
@ -489,6 +526,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
{ {
/* FIXME where to put cursor now ? */ /* FIXME where to put cursor now ? */
} }
}
editor->nUndoMode = nUndoMode; editor->nUndoMode = nUndoMode;
pUI = ME_AddUndoItem(editor, diUndoDeleteRun, NULL); pUI = ME_AddUndoItem(editor, diUndoDeleteRun, NULL);

View File

@ -213,6 +213,7 @@ void ME_Redo(ME_TextEditor *editor);
void ME_EmptyUndoStack(ME_TextEditor *editor); void ME_EmptyUndoStack(ME_TextEditor *editor);
int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int nStart, int nChars, BOOL bCRLF); int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int nStart, int nChars, BOOL bCRLF);
ME_DisplayItem *ME_FindItemAtOffset(ME_TextEditor *editor, ME_DIType nItemType, int nOffset, int *nItemOffset); ME_DisplayItem *ME_FindItemAtOffset(ME_TextEditor *editor, ME_DIType nItemType, int nOffset, int *nItemOffset);
void ME_StreamInFill(ME_InStream *stream);
extern int me_debug; extern int me_debug;
extern HANDLE me_heap; extern HANDLE me_heap;

View File

@ -197,6 +197,18 @@ typedef struct tagME_FontTableItem {
WCHAR *szFaceName; WCHAR *szFaceName;
} ME_FontTableItem; } ME_FontTableItem;
#define STREAMIN_BUFFER_SIZE 4096 /* M$ compatibility */
struct tagME_InStream {
EDITSTREAM *editstream;
DWORD dwSize;
DWORD dwUsed;
BYTE buffer[STREAMIN_BUFFER_SIZE];
};
typedef struct tagME_InStream ME_InStream;
#define STREAMOUT_BUFFER_SIZE 4096 #define STREAMOUT_BUFFER_SIZE 4096
#define STREAMOUT_FONTTBL_SIZE 8192 #define STREAMOUT_FONTTBL_SIZE 8192
#define STREAMOUT_COLORTBL_SIZE 1024 #define STREAMOUT_COLORTBL_SIZE 1024

View File

@ -123,41 +123,35 @@ static inline void RTFFree(void *p)
int _RTFGetChar(RTF_Info *info) int _RTFGetChar(RTF_Info *info)
{ {
int ch; int ch;
ME_InStream *stream = info->stream;
TRACE("\n"); TRACE("\n");
/* if the last buffer wasn't full, it's EOF */ /* if the last buffer wasn't full, it's EOF */
if (info->dwInputSize > 0 && if (stream->dwSize > 0 && stream->dwSize == stream->dwUsed
info->dwInputSize == info->dwInputUsed && && stream->dwSize < sizeof(stream->buffer))
info->dwInputSize < sizeof(info->InputBuffer))
return EOF; return EOF;
if (info->dwInputSize <= info->dwInputUsed) if (stream->dwSize <= stream->dwUsed)
{ {
long count = 0; ME_StreamInFill(stream);
info->editstream.dwError = info->editstream.pfnCallback(info->editstream.dwCookie,
info->InputBuffer, sizeof(info->InputBuffer), &count);
/* if error, it's EOF */ /* if error, it's EOF */
if (info->editstream.dwError) if (stream->editstream->dwError)
return EOF; return EOF;
/* if no bytes read, it's EOF */ /* if no bytes read, it's EOF */
if (count == 0) if (stream->dwSize == 0)
return EOF; return EOF;
info->dwInputSize = count;
info->dwInputUsed = 0;
} }
ch = info->InputBuffer[info->dwInputUsed++]; ch = stream->buffer[stream->dwUsed++];
if (!ch) if (!ch)
return EOF; return EOF;
return ch; return ch;
} }
void RTFSetEditStream(RTF_Info *info, EDITSTREAM *es) void RTFSetEditStream(RTF_Info *info, ME_InStream *stream)
{ {
TRACE("\n"); TRACE("\n");
info->editstream.dwCookie = es->dwCookie; info->stream = stream;
info->editstream.dwError = es->dwError;
info->editstream.pfnCallback = es->pfnCallback;
} }
static void static void

View File

@ -1078,10 +1078,7 @@ struct _RTF_Info {
char *inputName; char *inputName;
char *outputName; char *outputName;
EDITSTREAM editstream; ME_InStream *stream;
char InputBuffer[0x1000];
DWORD dwInputSize;
DWORD dwInputUsed;
/* edit window to output to */ /* edit window to output to */
HWND hwndEdit; HWND hwndEdit;
@ -1155,7 +1152,7 @@ void RTFMsg (RTF_Info *, const char *fmt, ...);
void RTFPanic (RTF_Info *, const char *fmt, ...); void RTFPanic (RTF_Info *, const char *fmt, ...);
void RTFFlushOutputBuffer( RTF_Info *info ); void RTFFlushOutputBuffer( RTF_Info *info );
void RTFSetEditStream(RTF_Info *, EDITSTREAM *es); void RTFSetEditStream(RTF_Info *info, ME_InStream *stream);
void WriterInit (RTF_Info *); void WriterInit (RTF_Info *);
int BeginFile (RTF_Info *); int BeginFile (RTF_Info *);