riched20: Continue interpreting data as UTF-8 after the first chunk boundary.
This commit is contained in:
parent
b7709771d1
commit
360afb93b5
|
@ -286,6 +286,9 @@ static LRESULT ME_StreamInText(ME_TextEditor *editor, DWORD dwFormat, ME_InStrea
|
||||||
WCHAR *pText;
|
WCHAR *pText;
|
||||||
LRESULT total_bytes_read = 0;
|
LRESULT total_bytes_read = 0;
|
||||||
BOOL is_read = FALSE;
|
BOOL is_read = FALSE;
|
||||||
|
DWORD cp = CP_ACP, copy = 0;
|
||||||
|
char conv_buf[4 + STREAMIN_BUFFER_SIZE]; /* up to 4 additional UTF-8 bytes */
|
||||||
|
|
||||||
static const char bom_utf8[] = {0xEF, 0xBB, 0xBF};
|
static const char bom_utf8[] = {0xEF, 0xBB, 0xBF};
|
||||||
|
|
||||||
TRACE("%08x %p\n", dwFormat, stream);
|
TRACE("%08x %p\n", dwFormat, stream);
|
||||||
|
@ -307,8 +310,7 @@ static LRESULT ME_StreamInText(ME_TextEditor *editor, DWORD dwFormat, ME_InStrea
|
||||||
if (!(dwFormat & SF_UNICODE))
|
if (!(dwFormat & SF_UNICODE))
|
||||||
{
|
{
|
||||||
char * buf = stream->buffer;
|
char * buf = stream->buffer;
|
||||||
DWORD size = stream->dwSize;
|
DWORD size = stream->dwSize, end;
|
||||||
DWORD cp = CP_ACP;
|
|
||||||
|
|
||||||
if (!is_read)
|
if (!is_read)
|
||||||
{
|
{
|
||||||
|
@ -321,8 +323,56 @@ static LRESULT ME_StreamInText(ME_TextEditor *editor, DWORD dwFormat, ME_InStrea
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nWideChars = MultiByteToWideChar(cp, 0, buf, size, wszText, STREAMIN_BUFFER_SIZE);
|
if (cp == CP_UTF8)
|
||||||
|
{
|
||||||
|
if (copy)
|
||||||
|
{
|
||||||
|
memcpy(conv_buf + copy, buf, size);
|
||||||
|
buf = conv_buf;
|
||||||
|
size += copy;
|
||||||
|
}
|
||||||
|
end = size;
|
||||||
|
while ((buf[end-1] & 0xC0) == 0x80)
|
||||||
|
{
|
||||||
|
--end;
|
||||||
|
--total_bytes_read; /* strange, but seems to match windows */
|
||||||
|
}
|
||||||
|
if (buf[end-1] & 0x80)
|
||||||
|
{
|
||||||
|
DWORD need = 0;
|
||||||
|
if ((buf[end-1] & 0xE0) == 0xC0)
|
||||||
|
need = 1;
|
||||||
|
if ((buf[end-1] & 0xF0) == 0xE0)
|
||||||
|
need = 2;
|
||||||
|
if ((buf[end-1] & 0xF8) == 0xF0)
|
||||||
|
need = 3;
|
||||||
|
|
||||||
|
if (size - end >= need)
|
||||||
|
{
|
||||||
|
/* we have enough bytes for this sequence */
|
||||||
|
end = size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* need more bytes, so don't transcode this sequence */
|
||||||
|
--end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
end = size;
|
||||||
|
|
||||||
|
nWideChars = MultiByteToWideChar(cp, 0, buf, end, wszText, STREAMIN_BUFFER_SIZE);
|
||||||
pText = wszText;
|
pText = wszText;
|
||||||
|
|
||||||
|
if (cp == CP_UTF8)
|
||||||
|
{
|
||||||
|
if (end != size)
|
||||||
|
{
|
||||||
|
memcpy(conv_buf, buf + end, size - end);
|
||||||
|
copy = size - end;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -5035,6 +5035,29 @@ static DWORD CALLBACK test_EM_STREAMIN_esCallback(DWORD_PTR dwCookie,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DWORD CALLBACK test_EM_STREAMIN_esCallback_UTF8Split(DWORD_PTR dwCookie,
|
||||||
|
LPBYTE pbBuff,
|
||||||
|
LONG cb,
|
||||||
|
LONG *pcb)
|
||||||
|
{
|
||||||
|
DWORD *phase = (DWORD *)dwCookie;
|
||||||
|
|
||||||
|
if(*phase == 0){
|
||||||
|
static const char first[] = "\xef\xbb\xbf\xc3\x96\xc3";
|
||||||
|
*pcb = sizeof(first) - 1;
|
||||||
|
memcpy(pbBuff, first, *pcb);
|
||||||
|
}else if(*phase == 1){
|
||||||
|
static const char second[] = "\x8f\xc3\x8b";
|
||||||
|
*pcb = sizeof(second) - 1;
|
||||||
|
memcpy(pbBuff, second, *pcb);
|
||||||
|
}else
|
||||||
|
*pcb = 0;
|
||||||
|
|
||||||
|
++*phase;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct StringWithLength {
|
struct StringWithLength {
|
||||||
int length;
|
int length;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
|
@ -5063,6 +5086,7 @@ static DWORD CALLBACK test_EM_STREAMIN_esCallback2(DWORD_PTR dwCookie,
|
||||||
static void test_EM_STREAMIN(void)
|
static void test_EM_STREAMIN(void)
|
||||||
{
|
{
|
||||||
HWND hwndRichEdit = new_richedit(NULL);
|
HWND hwndRichEdit = new_richedit(NULL);
|
||||||
|
DWORD phase;
|
||||||
LRESULT result;
|
LRESULT result;
|
||||||
EDITSTREAM es;
|
EDITSTREAM es;
|
||||||
char buffer[1024] = {0};
|
char buffer[1024] = {0};
|
||||||
|
@ -5204,6 +5228,21 @@ static void test_EM_STREAMIN(void)
|
||||||
"EM_STREAMIN: Test UTF8WithBOM set wrong text: Result: %s\n",buffer);
|
"EM_STREAMIN: Test UTF8WithBOM set wrong text: Result: %s\n",buffer);
|
||||||
ok(es.dwError == 0, "EM_STREAMIN: Test UTF8WithBOM set error %d, expected %d\n", es.dwError, 0);
|
ok(es.dwError == 0, "EM_STREAMIN: Test UTF8WithBOM set error %d, expected %d\n", es.dwError, 0);
|
||||||
|
|
||||||
|
phase = 0;
|
||||||
|
es.dwCookie = (DWORD_PTR)&phase;
|
||||||
|
es.dwError = 0;
|
||||||
|
es.pfnCallback = test_EM_STREAMIN_esCallback_UTF8Split;
|
||||||
|
result = SendMessage(hwndRichEdit, EM_STREAMIN, SF_TEXT, (LPARAM)&es);
|
||||||
|
ok(result == 8, "got %ld\n", result);
|
||||||
|
|
||||||
|
result = SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
|
||||||
|
ok(result == 3,
|
||||||
|
"EM_STREAMIN: Test UTF8Split returned %ld\n", result);
|
||||||
|
result = memcmp (buffer,"\xd6\xcf\xcb", 3);
|
||||||
|
ok(result == 0,
|
||||||
|
"EM_STREAMIN: Test UTF8Split set wrong text: Result: %s\n",buffer);
|
||||||
|
ok(es.dwError == 0, "EM_STREAMIN: Test UTF8Split set error %d, expected %d\n", es.dwError, 0);
|
||||||
|
|
||||||
es.dwCookie = (DWORD_PTR)&cookieForStream4;
|
es.dwCookie = (DWORD_PTR)&cookieForStream4;
|
||||||
es.dwError = 0;
|
es.dwError = 0;
|
||||||
es.pfnCallback = test_EM_STREAMIN_esCallback2;
|
es.pfnCallback = test_EM_STREAMIN_esCallback2;
|
||||||
|
|
Loading…
Reference in New Issue