Resend: RICHED20: fall back to simple test

Phil Krylov phil at newstar.rinet.ru
Wed Apr 13 02:30:03 CDT 2005


Hi,

this version of patch is made against current CVS.

ChangeLog:

Make RTF reader fall back to simple text if a correct RTF header is not
detected. This should fix some installers.

Patch:

Index: dlls/riched20/editor.c
===================================================================
RCS file: /home/wine/wine/dlls/riched20/editor.c,v
retrieving revision 1.22
diff -p -u -r1.22 editor.c
--- dlls/riched20/editor.c	11 Apr 2005 14:22:21 -0000	1.22
+++ dlls/riched20/editor.c	13 Apr 2005 07:13:21 -0000
@@ -233,36 +233,40 @@ ME_TextBuffer *ME_MakeText() {
   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 *pText;
   
   TRACE("%08lx %p\n", dwFormat, stream);
-  stream->dwError = 0;
   
   do {
-    long nDataSize = 0, nWideChars = 0;
-    stream->dwError = stream->pfnCallback(stream->dwCookie, 
-      (dwFormat & SF_UNICODE ? (BYTE *)wszText : buffer), 
-      STREAMIN_BUFFER_SIZE, &nDataSize);
-    
-    if (stream->dwError)
-      break;
-    if (!nDataSize)
-      break;
+    long nWideChars = 0;
+
+    if (!stream->dwSize)
+    {
+      ME_StreamInFill(stream);
+      if (stream->editstream->dwError)
+        break;
+      if (!stream->dwSize)
+        break;
+    }
       
     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 */
-      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
-      nWideChars = nDataSize>>1;
-    ME_InsertTextFromCursor(editor, 0, wszText, nWideChars, style);
-    if (nDataSize<STREAMIN_BUFFER_SIZE)
+    {
+      nWideChars = stream->dwSize >> 1;
+      pText = (WCHAR *)stream->buffer;
+    }
+    
+    ME_InsertTextFromCursor(editor, 0, pText, nWideChars, style);
+    if (stream->dwSize < STREAMIN_BUFFER_SIZE)
       break;
   } while(1);
   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)
 {
   RTF_Info parser;
@@ -435,6 +449,7 @@ static LRESULT ME_StreamIn(ME_TextEditor
   int from, to, to2, nUndoMode;
   ME_UndoItem *pUI;
   int nEventMask = editor->nEventMask;
+  ME_InStream inStream;
 
   TRACE("%p %p\n", stream, editor->hWnd);
   editor->nEventMask = 0;
@@ -457,37 +472,60 @@ static LRESULT ME_StreamIn(ME_TextEditor
   
   nUndoMode = editor->nUndoMode;
   editor->nUndoMode = umIgnore;
-  if (format & SF_RTF) {
-    /* setup the RTF parser */
-    memset(&parser, 0, sizeof parser);
-    RTFSetEditStream(&parser, stream);
-    parser.rtfFormat = format&(SF_TEXT|SF_RTF);
-    parser.hwndEdit = editor->hWnd;
-    parser.editor = editor;
-    parser.style = style;
-    WriterInit(&parser);
-    RTFInit(&parser);
-    RTFSetReadHook(&parser, ME_RTFReadHook);
-    BeginFile(&parser);
-  
-    /* do the parsing */
-    RTFRead(&parser);
-    RTFFlushOutputBuffer(&parser);
-    RTFDestroy(&parser);
-
-    style = parser.style;
-  }
-  else if (format & SF_TEXT)
-    ME_StreamInText(editor, format, stream, style);
-  else
-    ERR("EM_STREAMIN without SF_TEXT or SF_RTF\n");
-  ME_GetSelection(editor, &to, &to2);
-  /* put the cursor at the top */
-  if (!(format & SFF_SELECTION))
-    SendMessageA(editor->hWnd, EM_SETSEL, 0, 0);
-  else
+
+  inStream.editstream = stream;
+  inStream.editstream->dwError = 0;
+  inStream.dwSize = 0;
+  inStream.dwUsed = 0;
+
+  if (format & SF_RTF)
   {
-    /* FIXME where to put cursor now ? */
+    /* 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) {
+      /* setup the RTF parser */
+      memset(&parser, 0, sizeof parser);
+      RTFSetEditStream(&parser, &inStream);
+      parser.rtfFormat = format&(SF_TEXT|SF_RTF);
+      parser.hwndEdit = editor->hWnd;
+      parser.editor = editor;
+      parser.style = style;
+      WriterInit(&parser);
+      RTFInit(&parser);
+      RTFSetReadHook(&parser, ME_RTFReadHook);
+      BeginFile(&parser);
+  
+      /* do the parsing */
+      RTFRead(&parser);
+      RTFFlushOutputBuffer(&parser);
+      RTFDestroy(&parser);
+
+      style = parser.style;
+    }
+    else if (format & SF_TEXT)
+      ME_StreamInText(editor, format, &inStream, style);
+    else
+      ERR("EM_STREAMIN without SF_TEXT or SF_RTF\n");
+    ME_GetSelection(editor, &to, &to2);
+    /* put the cursor at the top */
+    if (!(format & SFF_SELECTION))
+      SendMessageA(editor->hWnd, EM_SETSEL, 0, 0);
+    else
+    {
+      /* FIXME where to put cursor now ? */
+    }
   }
   
   editor->nUndoMode = nUndoMode;
Index: dlls/riched20/editor.h
===================================================================
RCS file: /home/wine/wine/dlls/riched20/editor.h,v
retrieving revision 1.12
diff -p -u -r1.12 editor.h
--- dlls/riched20/editor.h	24 Mar 2005 21:01:37 -0000	1.12
+++ dlls/riched20/editor.h	13 Apr 2005 07:13:21 -0000
@@ -213,6 +213,7 @@ void ME_Redo(ME_TextEditor *editor);
 void ME_EmptyUndoStack(ME_TextEditor *editor);
 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);
+void ME_StreamInFill(ME_InStream *stream);
 
 extern int me_debug;
 extern HANDLE me_heap;
Index: dlls/riched20/editstr.h
===================================================================
RCS file: /home/wine/wine/dlls/riched20/editstr.h,v
retrieving revision 1.8
diff -p -u -r1.8 editstr.h
--- dlls/riched20/editstr.h	22 Mar 2005 16:41:36 -0000	1.8
+++ dlls/riched20/editstr.h	13 Apr 2005 07:13:21 -0000
@@ -197,6 +197,18 @@ typedef struct tagME_FontTableItem {
   WCHAR *szFaceName;
 } 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_FONTTBL_SIZE 8192
 #define STREAMOUT_COLORTBL_SIZE 1024
Index: dlls/riched20/reader.c
===================================================================
RCS file: /home/wine/wine/dlls/riched20/reader.c,v
retrieving revision 1.11
diff -p -u -r1.11 reader.c
--- dlls/riched20/reader.c	22 Mar 2005 16:41:36 -0000	1.11
+++ dlls/riched20/reader.c	13 Apr 2005 07:13:21 -0000
@@ -123,41 +123,35 @@ static inline void RTFFree(void *p)
 int _RTFGetChar(RTF_Info *info)
 {
 	int ch;
+        ME_InStream *stream = info->stream;
 
 	TRACE("\n");
 
 	/* if the last buffer wasn't full, it's EOF */
-	if (info->dwInputSize > 0 &&
-		info->dwInputSize == info->dwInputUsed &&
-		info->dwInputSize < sizeof(info->InputBuffer))
+	if (stream->dwSize > 0 && stream->dwSize == stream->dwUsed
+            && stream->dwSize < sizeof(stream->buffer))
 		return EOF;
-	if (info->dwInputSize <= info->dwInputUsed)
+	if (stream->dwSize <= stream->dwUsed)
 	{
-		long count = 0;
-		info->editstream.dwError = info->editstream.pfnCallback(info->editstream.dwCookie, 
-		info->InputBuffer, sizeof(info->InputBuffer), &count);
+                ME_StreamInFill(stream);
 		/* if error, it's EOF */
-		if (info->editstream.dwError)
+		if (stream->editstream->dwError)
 			return EOF;
 		/* if no bytes read, it's EOF */
-		if (count == 0)
+		if (stream->dwSize == 0)
 			return EOF;
-		info->dwInputSize = count;
-		info->dwInputUsed = 0;
 	}
-	ch = info->InputBuffer[info->dwInputUsed++];
+	ch = stream->buffer[stream->dwUsed++];
 	if (!ch)
 		 return EOF;
 	return ch;
 }
 
-void RTFSetEditStream(RTF_Info *info, EDITSTREAM *es)
+void RTFSetEditStream(RTF_Info *info, ME_InStream *stream)
 {
 	TRACE("\n");
 
-	info->editstream.dwCookie = es->dwCookie;
-	info->editstream.dwError  = es->dwError;
-	info->editstream.pfnCallback = es->pfnCallback;
+        info->stream = stream;
 }
 
 static void
Index: dlls/riched20/rtf.h
===================================================================
RCS file: /home/wine/wine/dlls/riched20/rtf.h,v
retrieving revision 1.9
diff -p -u -r1.9 rtf.h
--- dlls/riched20/rtf.h	22 Mar 2005 16:41:36 -0000	1.9
+++ dlls/riched20/rtf.h	13 Apr 2005 07:13:21 -0000
@@ -1078,10 +1078,7 @@ struct _RTF_Info {
     char *inputName;
     char *outputName;
 
-    EDITSTREAM editstream;
-    char InputBuffer[0x1000];
-    DWORD dwInputSize;
-    DWORD dwInputUsed;
+    ME_InStream *stream;
 
     /* edit window to output to */
     HWND hwndEdit;
@@ -1155,7 +1152,7 @@ void	RTFMsg (RTF_Info *, const char *fmt
 void	RTFPanic (RTF_Info *, const char *fmt, ...);
 
 void	RTFFlushOutputBuffer( RTF_Info *info );
-void	RTFSetEditStream(RTF_Info *, EDITSTREAM *es);
+void	RTFSetEditStream(RTF_Info *info, ME_InStream *stream);
 
 void	WriterInit (RTF_Info *);
 int	BeginFile (RTF_Info *);



More information about the wine-patches mailing list