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

Mike McCormack mike at codeweavers.com
Fri Aug 27 06:23:56 CDT 2004


OK, I increased the buffer to 0x1000 (4096) bytes.  I'll probably do 
some more work on this control in the near future.

Ge van Geldorp wrote:

> Not that it should matter very much, but the MS control always seems to
> read the input in 4096 byte chunks. Maybe you could enlarge InputBuffer
> from 0x400 to 0x1000?
> 
> 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 09:54:48 -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 09:54:49 -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 09:54:49 -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 09:54:49 -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 09:54:49 -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.
  */
@@ -280,16 +243,30 @@
 
 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;
+    info->OutputBuffer[info->dwOutputCount] = 0;
+    SendMessageA( info->hwndEdit, EM_REPLACESEL, FALSE, (LPARAM) info->OutputBuffer );
+}
+
+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