RICHEDIT: use buffers rather than linked lists for input and out buffers (take 3)

Mike McCormack mike at codeweavers.com
Fri Aug 27 06:44:33 CDT 2004


[rev 3] - fix a crash due to not resetting the output buffer after 
writing it out in PutLitChar

[rev 2] - increased the buffer to 4096 bytes suggested by Ge van Geldorp

This patch writes the output of the RTF parser into the edit control in 
1024 byte chunks, and reads the input via a char[1024] buffer, rather 
than a linked list of single characters.

It also corrects a bug in the richedit code; the parser should stop 
reading input once it sees a nul byte.

After applying this patch, you can remove dlls/richedit/charlist.[ch] 
from CVS.

Mike


ChangeLog:

* Use buffers rather than linked lists for input and out buffers.
   Stop reading input at a nul byte.
-------------- next part --------------
Index: dlls/richedit/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/richedit/Makefile.in,v
retrieving revision 1.13
diff -u -r1.13 Makefile.in
--- dlls/richedit/Makefile.in	11 Oct 2003 01:09:17 -0000	1.13
+++ dlls/richedit/Makefile.in	27 Aug 2004 10:13:40 -0000
@@ -6,7 +6,6 @@
 IMPORTS   = user32 kernel32
 
 C_SRCS = \
-	charlist.c \
 	reader.c \
 	text-writer.c \
 	richedit.c
Index: dlls/richedit/reader.c
===================================================================
RCS file: /home/wine/wine/dlls/richedit/reader.c,v
retrieving revision 1.14
diff -u -r1.14 reader.c
--- dlls/richedit/reader.c	16 Apr 2004 23:29:57 -0000	1.14
+++ dlls/richedit/reader.c	27 Aug 2004 10:13:41 -0000
@@ -80,8 +80,6 @@
 
 #include <stdlib.h>
 
-#include "charlist.h"
-
 #include "windef.h"
 #include "winbase.h"
 #include "wine/debug.h"
@@ -118,28 +116,23 @@
 
 int _RTFGetChar(RTF_Info *info)
 {
-    char myChar;
+    int ch;
 
     TRACE("\n");
 
-    if(CHARLIST_GetNbItems(&info->inputCharList) == 0)
+    if( info->dwInputSize <= info->dwInputUsed )
     {
-        char buff[4096];
-        long pcb;
-        info->editstream.pfnCallback(info->editstream.dwCookie, buff, sizeof(buff), &pcb);
-        if(pcb == 0)
-           return EOF;
-        else
-        {
-           int i;
-           for (i = 0; i < pcb; i++)
-           {
-               CHARLIST_Enqueue(&info->inputCharList, buff[i]);
-           }
-        }
+        long count = 0;
+        info->editstream.pfnCallback(info->editstream.dwCookie, 
+                   info->InputBuffer, sizeof(info->InputBuffer), &count);
+        if(count == 0)
+            return EOF;
+        info->dwInputSize = count;
+        info->dwInputUsed = 0;
     }
-    myChar = CHARLIST_Dequeue(&info->inputCharList);
-    return (int) myChar;
+    ch = info->InputBuffer[info->dwInputUsed++];
+    if( !ch ) return EOF;
+    return ch;
 }
 
 void RTFSetEditStream(RTF_Info *info, EDITSTREAM *es)
Index: dlls/richedit/richedit.c
===================================================================
RCS file: /home/wine/wine/dlls/richedit/richedit.c,v
retrieving revision 1.36
diff -u -r1.36 richedit.c
--- dlls/richedit/richedit.c	30 Jul 2004 04:19:56 -0000	1.36
+++ dlls/richedit/richedit.c	27 Aug 2004 10:13:41 -0000
@@ -31,7 +31,6 @@
 #include "winerror.h"
 #include "riched32.h"
 #include "richedit.h"
-#include "charlist.h"
 #define NO_SHLWAPI_STREAM
 #include "shlwapi.h"
 
@@ -115,11 +114,9 @@
 static LRESULT WINAPI RICHED32_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
                                    LPARAM lParam)
 {
-    int RTFToBuffer(RTF_Info *parser, char* pBuffer, int nBufferSize);
     LONG newstyle = 0;
     LONG style = 0;
     RTFControl_Info *info;
-    int rtfBufferSize;
     CHARRANGE *cr;
 
     info = (RTFControl_Info *) GetWindowLongW( hwnd, RTFInfoOffset );
@@ -187,23 +184,17 @@
 	    /* setup the RTF parser */
 	    RTFSetEditStream(info->parser,( EDITSTREAM*)lParam);
 	    info->parser->rtfFormat = wParam&(SF_TEXT|SF_RTF);
+	    info->parser->hwndEdit = hwnd;
 	    WriterInit(info->parser);
 	    RTFInit (info->parser);
 	    BeginFile(info->parser);
 
 	    /* do the parsing */
 	    RTFRead (info->parser);
+            RTFFlushOutputBuffer( info->parser );
 
-	    rtfBufferSize = RTFToBuffer(info->parser,NULL, 0);
-	    info->rtfBuffer = HeapAlloc(RICHED32_hHeap, 0,rtfBufferSize*sizeof(char));
-	    if(info->rtfBuffer)
-	    {
-	    	RTFToBuffer(info->parser,info->rtfBuffer, rtfBufferSize);
-                CallWindowProcA(lpfnEditWndProc, hwnd, WM_SETTEXT, 0, (LPARAM)info->rtfBuffer);
-	    	HeapFree(RICHED32_hHeap, 0,info->rtfBuffer);
-	    }
-	    else
-		WARN("Not enough memory for a allocating rtfBuffer\n");
+            /* put the cursor at the top */
+            SendMessageA( hwnd, EM_SETSEL, 0, 0 );
 
             return 0;
 
Index: dlls/richedit/rtf.h
===================================================================
RCS file: /home/wine/wine/dlls/richedit/rtf.h,v
retrieving revision 1.8
diff -u -r1.8 rtf.h
--- dlls/richedit/rtf.h	30 Jan 2004 22:56:33 -0000	1.8
+++ dlls/richedit/rtf.h	27 Aug 2004 10:13:41 -0000
@@ -1374,8 +1374,6 @@
 };
 
 
-#include "charlist.h"
-
 /*
  * Return pointer to new element of type t, or NULL
  * if no memory available.
@@ -1444,7 +1442,12 @@
     char *outputName;
 
     EDITSTREAM editstream;
-    CHARLIST inputCharList ;
+    char InputBuffer[0x1000];
+    DWORD dwInputSize;
+    DWORD dwInputUsed;
+
+    /* edit window to output to */
+    HWND hwndEdit;
 
     /*
      * These arrays are used to map RTF input character values onto the standard
@@ -1493,8 +1496,8 @@
 
     char     *outMap[rtfSC_MaxChar];
 
-    CHARLIST charlist;
-
+    DWORD    dwOutputCount;
+    char     OutputBuffer[0x1000];
 };
 
 
@@ -1559,6 +1562,7 @@
 void	RTFSetOpenLibFileProc ( RTF_Info *, FILE *(*)());
 FILE	*RTFOpenLibFile ( RTF_Info *, char *, char *);
 
+void RTFFlushOutputBuffer( RTF_Info *info );
 void RTFSetEditStream(RTF_Info *, EDITSTREAM *es);
 
 #endif
Index: dlls/richedit/text-writer.c
===================================================================
RCS file: /home/wine/wine/dlls/richedit/text-writer.c,v
retrieving revision 1.7
diff -u -r1.7 text-writer.c
--- dlls/richedit/text-writer.c	30 Jan 2004 22:56:33 -0000	1.7
+++ dlls/richedit/text-writer.c	27 Aug 2004 10:13:41 -0000
@@ -40,7 +40,6 @@
 
 #include "rtf.h"
 #include "rtf2text.h"
-#include "charlist.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(richedit);
@@ -53,42 +52,6 @@
 static void	PutLitChar (RTF_Info *info, int c);
 static void	PutLitStr (RTF_Info *info, char	*s);
 
-#if 0
-static char	*outMap[rtfSC_MaxChar];
-
-static CHARLIST charlist = {0, NULL, NULL};
-#endif
-
-/*int RTFToBuffer(char* pBuffer, int nBufferSize); */
-int RTFToBuffer(RTF_Info *info, char* pBuffer, int nBufferSize)
-{
-
-   /* check if the buffer is big enough to hold all characters  */
-   /* we require one more for the '\0'                          */
-
-   TRACE("\n");
-
-   if(nBufferSize < info->charlist.nCount + 1) {
-        return info->charlist.nCount + CHARLIST_CountChar(&info->charlist, '\n') + 1;
-   }
-
-   while(info->charlist.nCount)
-   {
-       *pBuffer = CHARLIST_Dequeue(&info->charlist);
-       if(*pBuffer=='\n')
-       {
-         *pBuffer = '\r';
-         pBuffer++;
-         *pBuffer = '\n';
-       }
-       pBuffer++;
-   }
-   *pBuffer = '\0';
-
-   return 0;
-}
-
-
 /*
  * Initialize the writer.
  */
@@ -277,19 +240,31 @@
 	PutLitStr (info, oStr);
 }
 
-
 void PutLitChar (RTF_Info *info, int c)
 {
-	CHARLIST_Enqueue(&info->charlist, (char) c);
-        /* fputc (c, ostream); */
-}
-
-
-static void PutLitStr (RTF_Info *info, char	*s)
-{
-	for(;*s;s++)
-	{
-	  CHARLIST_Enqueue(&info->charlist, *s);
-	}
-	/* fputs (s, ostream); */
+    info->OutputBuffer[info->dwOutputCount++] = c;
+    if( info->dwOutputCount < ( sizeof info->OutputBuffer - 1 ) )
+        return;
+    RTFFlushOutputBuffer( info );
+}
+
+void RTFFlushOutputBuffer( RTF_Info *info )
+{
+    info->OutputBuffer[info->dwOutputCount] = 0;
+    SendMessageA( info->hwndEdit, EM_REPLACESEL, FALSE, (LPARAM) info->OutputBuffer );
+    info->dwOutputCount = 0;
+}
+
+static void PutLitStr (RTF_Info *info, char *str )
+{
+    int len = strlen( str );
+    if( ( len + info->dwOutputCount + 1 ) > sizeof info->OutputBuffer )
+        RTFFlushOutputBuffer( info );
+    if( ( len + 1 ) >= sizeof info->OutputBuffer )
+    {
+        SendMessageA( info->hwndEdit, EM_REPLACESEL, FALSE, (LPARAM) str );
+        return;
+    }
+    strcpy( &info->OutputBuffer[info->dwOutputCount], str );
+    info->dwOutputCount += len;
 }


More information about the wine-patches mailing list