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