Sync to Wine-20040914:

Mike McCormack <mike@codeweavers.com>
- Use buffers rather than linked lists for input and out buffers.
- Stop reading input at a nul byte.
Evan Deaubl <wine@warpedview.com>
- Stop processing input stream when the outermost RTF group is closed.

svn path=/trunk/; revision=10908
This commit is contained in:
Gé van Geldorp 2004-09-19 10:28:59 +00:00
parent 95fadd5bb4
commit 414bb6e2c0
7 changed files with 58 additions and 262 deletions

View file

@ -6,7 +6,6 @@ MODULE = riched32.dll
IMPORTS = user32 kernel32
C_SRCS = \
charlist.c \
reader.c \
text-writer.c \
richedit.c

View file

@ -1,130 +0,0 @@
/*
*
* Character List
*
* Copyright (c) 2000 by Jean-Claude Batista
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <ctype.h>
#include <stdlib.h>
#include "charlist.h"
#include "windef.h"
#include "winbase.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(richedit);
extern HANDLE RICHED32_hHeap;
void CHARLIST_Enqueue( CHARLIST* pCharList, char myChar )
{
CHARLISTENTRY* pNewEntry = HeapAlloc(RICHED32_hHeap, 0,sizeof(CHARLISTENTRY));
pNewEntry->pNext = NULL;
pNewEntry->myChar = myChar;
TRACE("\n");
if(pCharList->pTail == NULL)
{
pCharList->pHead = pCharList->pTail = pNewEntry;
}
else
{
CHARLISTENTRY* pCurrent = pCharList->pTail;
pCharList->pTail = pCurrent->pNext = pNewEntry;
}
pCharList->nCount++;
}
char CHARLIST_Dequeue(CHARLIST* pCharList)
{
CHARLISTENTRY* pCurrent;
char myChar;
TRACE("\n");
if(pCharList->nCount == 0)
return 0;
pCharList->nCount--;
myChar = pCharList->pHead->myChar;
pCurrent = pCharList->pHead->pNext;
HeapFree(RICHED32_hHeap, 0,pCharList->pHead);
if(pCharList->nCount == 0)
{
pCharList->pHead = pCharList->pTail = NULL;
}
else
{
pCharList->pHead = pCurrent;
}
return myChar;
}
int CHARLIST_GetNbItems(CHARLIST* pCharList)
{
TRACE("\n");
return pCharList->nCount;
}
void CHARLIST_FreeList(CHARLIST* pCharList){
TRACE("\n");
while(pCharList->nCount)
CHARLIST_Dequeue(pCharList);
}
/* this function counts the number of occurrences of a caracter */
int CHARLIST_CountChar(CHARLIST* pCharList, char myChar)
{
CHARLISTENTRY *pCurrent;
int nCount = 0;
TRACE("\n");
for(pCurrent =pCharList->pHead ;pCurrent;pCurrent=pCurrent->pNext)
if(pCurrent->myChar == myChar)
nCount++;
return nCount;
}
int CHARLIST_toBuffer(CHARLIST* pCharList, char* pBuffer, int nBufferSize)
{
TRACE("\n");
/* we add one to store a NULL caracter */
if(nBufferSize < pCharList->nCount + 1)
return pCharList->nCount;
for(;pCharList->nCount;pBuffer++)
*pBuffer = CHARLIST_Dequeue(pCharList);
*pBuffer = '\0';
return 0;
}

View file

@ -1,45 +0,0 @@
/*
* Character List
*
* Copyright (c) 2000 by Jean-Claude Batista
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _CHARLIST
#define _CHARLIST
typedef struct _tagCHARLISTENTRY
{
struct _tagCHARLISTENTRY *pNext;
char myChar;
} CHARLISTENTRY;
typedef struct _tagCHARLIST
{
unsigned int nCount; /* Entries Count; */
CHARLISTENTRY *pHead;
CHARLISTENTRY *pTail;
} CHARLIST;
void CHARLIST_Enqueue( CHARLIST* pCharList, char myChar);
char CHARLIST_Dequeue(CHARLIST* pCharList);
int CHARLIST_GetNbItems(CHARLIST* pCharList);
void CHARLIST_FreeList(CHARLIST* pCharList);
int CHARLIST_CountChar(CHARLIST* pCharList, char myChar);
int CHARLIST_toBuffer(CHARLIST* pCharList, char* pBuffer, int nBufferSize);
#endif

View file

@ -80,8 +80,6 @@
#include <stdlib.h>
#include "charlist.h"
#include "windef.h"
#include "winbase.h"
#include "wine/debug.h"
@ -118,28 +116,23 @@ static void ReadCharSetMaps (RTF_Info *);
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)
@ -547,10 +540,20 @@ RTFFont *fp;
info->csStack[info->csTop++] = info->curCharSet;
break;
case rtfEndGroup:
/*
* If stack top is 1 at this point, we are ending the
* group started by the initial {, which ends the
* RTF stream
*/
if (info->csTop <= 0)
RTFPanic (info,"_RTFGetToken: stack underflow");
info->curCharSet = info->csStack[--info->csTop];
RTFSetCharSet (info, info->curCharSet);
else if (info->csTop == 1)
info->rtfClass = rtfEOF;
else
{
info->curCharSet = info->csStack[--info->csTop];
RTFSetCharSet (info, info->curCharSet);
}
break;
}
}

View file

@ -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 @@ typedef struct _RTFControl_info
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 @@ static LRESULT WINAPI RICHED32_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
/* 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;

View file

@ -1374,8 +1374,6 @@ struct RTFStyleElt
};
#include "charlist.h"
/*
* Return pointer to new element of type t, or NULL
* if no memory available.
@ -1444,7 +1442,12 @@ struct _RTF_Info {
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 @@ struct _RTF_Info {
char *outMap[rtfSC_MaxChar];
CHARLIST charlist;
DWORD dwOutputCount;
char OutputBuffer[0x1000];
};
@ -1559,6 +1562,7 @@ void RTFSetCharSet( RTF_Info *, int);
void RTFSetOpenLibFileProc ( RTF_Info *, FILE *(*)());
FILE *RTFOpenLibFile ( RTF_Info *, char *, char *);
void RTFFlushOutputBuffer( RTF_Info *info );
void RTFSetEditStream(RTF_Info *, EDITSTREAM *es);
#endif

View file

@ -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 PutStdChar (RTF_Info *info, int stdCode);
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,30 @@ void PutStdChar (RTF_Info *info, int stdCode)
PutLitStr (info, oStr);
}
void PutLitChar (RTF_Info *info, int c)
{
CHARLIST_Enqueue(&info->charlist, (char) c);
/* fputc (c, ostream); */
if( info->dwOutputCount >= ( sizeof info->OutputBuffer - 1 ) )
RTFFlushOutputBuffer( info );
info->OutputBuffer[info->dwOutputCount++] = c;
}
static void PutLitStr (RTF_Info *info, char *s)
void RTFFlushOutputBuffer( RTF_Info *info )
{
for(;*s;s++)
{
CHARLIST_Enqueue(&info->charlist, *s);
}
/* fputs (s, ostream); */
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;
}