* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "editor.h"
+#include "editor.h"
WINE_DEFAULT_DEBUG_CHANNEL(richedit);
-int ME_GetOptimalBuffer(int nLen)
+static int ME_GetOptimalBuffer(int nLen)
{
- return ((2*nLen+1)+128)&~63;
+ /* FIXME: This seems wasteful for tabs and end of lines strings,
+ * since they have a small fixed length. */
+ return ((sizeof(WCHAR) * nLen) + 128) & ~63;
}
-ME_String *ME_MakeString(LPCWSTR szText)
+/* Create a buffer (uninitialized string) of size nMaxChars */
+static ME_String *ME_MakeStringB(int nMaxChars)
{
ME_String *s = ALLOC_OBJ(ME_String);
- s->nLen = lstrlenW(szText);
- s->nBuffer = ME_GetOptimalBuffer(s->nLen+1);
+
+ s->nLen = nMaxChars;
+ s->nBuffer = ME_GetOptimalBuffer(s->nLen + 1);
s->szData = ALLOC_N_OBJ(WCHAR, s->nBuffer);
- lstrcpyW(s->szData, szText);
+ s->szData[s->nLen] = 0;
return s;
}
ME_String *ME_MakeStringN(LPCWSTR szText, int nMaxChars)
{
- ME_String *s = ALLOC_OBJ(ME_String);
-
- s->nLen = nMaxChars;
- s->nBuffer = ME_GetOptimalBuffer(s->nLen+1);
- s->szData = ALLOC_N_OBJ(WCHAR, s->nBuffer);
- /* Native allows NUL chars */
- memmove(s->szData, szText, s->nLen * sizeof(WCHAR));
- s->szData[s->nLen] = 0;
+ ME_String *s = ME_MakeStringB(nMaxChars);
+ /* Native allows NULL chars */
+ memcpy(s->szData, szText, s->nLen * sizeof(WCHAR));
return s;
}
+/* Make a string by repeating a char nMaxChars times */
ME_String *ME_MakeStringR(WCHAR cRepeat, int nMaxChars)
-{ /* Make a string by repeating a char nMaxChars times */
+{
int i;
- ME_String *s = ALLOC_OBJ(ME_String);
-
- s->nLen = nMaxChars;
- s->nBuffer = ME_GetOptimalBuffer(s->nLen+1);
- s->szData = ALLOC_N_OBJ(WCHAR, s->nBuffer);
-
- for (i = 0;i<nMaxChars;i++)
+ ME_String *s = ME_MakeStringB(nMaxChars);
+ for (i = 0; i < nMaxChars; i++)
s->szData[i] = cRepeat;
- s->szData[s->nLen] = 0;
- return s;
-}
-
-ME_String *ME_MakeStringB(int nMaxChars)
-{ /* Create a buffer (uninitialized string) of size nMaxChars */
- ME_String *s = ALLOC_OBJ(ME_String);
-
- s->nLen = nMaxChars;
- s->nBuffer = ME_GetOptimalBuffer(s->nLen+1);
- s->szData = ALLOC_N_OBJ(WCHAR, s->nBuffer);
- s->szData[s->nLen] = 0;
return s;
}
void ME_DestroyString(ME_String *s)
{
+ if (!s) return;
FREE_OBJ(s->szData);
FREE_OBJ(s);
}
void ME_AppendString(ME_String *s1, const ME_String *s2)
{
- if (s1->nLen+s2->nLen+1 <= s1->nBuffer) {
- lstrcpyW(s1->szData+s1->nLen, s2->szData);
- s1->nLen += s2->nLen;
- }
- else
+ if (s1->nLen+s2->nLen+1 <= s1->nBuffer)
{
+ memcpy(s1->szData + s1->nLen, s2->szData, s2->nLen * sizeof(WCHAR));
+ s1->nLen += s2->nLen;
+ s1->szData[s1->nLen] = 0;
+ } else {
WCHAR *buf;
s1->nBuffer = ME_GetOptimalBuffer(s1->nLen+s2->nLen+1);
- buf = ALLOC_N_OBJ(WCHAR, s1->nBuffer);
- lstrcpyW(buf, s1->szData);
- lstrcpyW(buf+s1->nLen, s2->szData);
+ buf = ALLOC_N_OBJ(WCHAR, s1->nBuffer);
+ memcpy(buf, s1->szData, s1->nLen * sizeof(WCHAR));
+ memcpy(buf + s1->nLen, s2->szData, s2->nLen * sizeof(WCHAR));
FREE_OBJ(s1->szData);
s1->szData = buf;
s1->nLen += s2->nLen;
+ s1->szData[s1->nLen] = 0;
}
}
-ME_String *ME_ConcatString(const ME_String *s1, const ME_String *s2)
-{
- ME_String *s = ALLOC_OBJ(ME_String);
- s->nLen = s1->nLen+s2->nLen;
- s->nBuffer = ME_GetOptimalBuffer(s1->nLen+s2->nLen+1);
- s->szData = ALLOC_N_OBJ(WCHAR, s->nBuffer);
- lstrcpyW(s->szData, s1->szData);
- lstrcpyW(s->szData+s1->nLen, s2->szData);
- return s;
-}
-
ME_String *ME_VSplitString(ME_String *orig, int charidx)
{
ME_String *s;
return 0;
}
-/* FIXME multibyte */
-/*
-int ME_CalcSkipChars(ME_String *s)
-{
- int cnt = 0;
- while(cnt < s->nLen && s->szData[s->nLen-1-cnt]==' ')
- cnt++;
- return cnt;
-}
-*/
-
-int ME_StrLen(const ME_String *s) {
- return s->nLen;
-}
-
-int ME_StrVLen(const ME_String *s) {
- return s->nLen;
-}
-
-int ME_StrRelPos(const ME_String *s, int nVChar, int *pRelChars)
-{
- int nRelChars = *pRelChars;
-
- TRACE("%s,%d,&%d\n", debugstr_w(s->szData), nVChar, *pRelChars);
-
- assert(*pRelChars);
- if (!nRelChars)
- return nVChar;
-
- if (nRelChars>0)
- nRelChars = min(*pRelChars, s->nLen - nVChar);
- else
- nRelChars = max(*pRelChars, -nVChar);
- nVChar += nRelChars;
- *pRelChars -= nRelChars;
- return nVChar;
-}
-
-int ME_StrRelPos2(const ME_String *s, int nVChar, int nRelChars)
-{
- return ME_StrRelPos(s, nVChar, &nRelChars);
-}
-
-int ME_VPosToPos(ME_String *s, int nVPos)
-{
- return nVPos;
- /*
- int i = 0, len = 0;
- if (!nVPos)
- return 0;
- while (i < s->nLen)
- {
- if (i == nVPos)
- return len;
- if (s->szData[i]=='\\') i++;
- i++;
- len++;
- }
- return len;
- */
-}
-
-int ME_PosToVPos(const ME_String *s, int nPos)
-{
- if (!nPos)
- return 0;
- return ME_StrRelPos2(s, 0, nPos);
-}
-
void ME_StrDeleteV(ME_String *s, int nVChar, int nChars)
{
- int end_ofs;
-
- assert(nVChar >=0 && nVChar <= s->nLen);
+ int end_ofs = nVChar + nChars;
+
assert(nChars >= 0);
- assert(nVChar+nChars <= s->nLen);
-
- end_ofs = ME_StrRelPos2(s, nVChar, nChars);
+ assert(nVChar >= 0);
assert(end_ofs <= s->nLen);
- memmove(s->szData+nVChar, s->szData+end_ofs, 2*(s->nLen+1-end_ofs));
- s->nLen -= (end_ofs - nVChar);
-}
-int ME_GetCharFwd(const ME_String *s, int nPos)
-{
- int nVPos = 0;
-
- assert(nPos < ME_StrLen(s));
- if (nPos)
- nVPos = ME_StrRelPos2(s, nVPos, nPos);
-
- if (nVPos < s->nLen)
- return s->szData[nVPos];
- return -1;
-}
-
-int ME_GetCharBack(const ME_String *s, int nPos)
-{
- int nVPos = ME_StrVLen(s);
-
- assert(nPos < ME_StrLen(s));
- if (nPos)
- nVPos = ME_StrRelPos2(s, nVPos, -nPos);
-
- if (nVPos < s->nLen)
- return s->szData[nVPos];
- return -1;
+ memmove(s->szData + nVChar, s->szData + end_ofs,
+ (s->nLen - end_ofs + 1) * sizeof(WCHAR));
+ s->nLen -= nChars;
}
int ME_FindNonWhitespaceV(const ME_String *s, int nVChar) {
/* FIXME: Native also knows about punctuation */
TRACE("s==%s, start==%d, len==%d, code==%d\n",
debugstr_wn(s, len), start, len, code);
+ /* convert number of bytes to number of characters. */
+ len /= sizeof(WCHAR);
switch (code)
{
case WB_ISDELIMITER:
int
ME_CallWordBreakProc(ME_TextEditor *editor, ME_String *str, INT start, INT code)
{
- /* FIXME: ANSIfy the string when bEmulateVersion10 is TRUE */
- if (!editor->pfnWordBreak)
- return ME_WordBreakProc(str->szData, start, str->nLen, code);
- else
- return editor->pfnWordBreak(str->szData, start, str->nLen, code);
+ if (!editor->pfnWordBreak) {
+ return ME_WordBreakProc(str->szData, start, str->nLen*sizeof(WCHAR), code);
+ } else if (!editor->bEmulateVersion10) {
+ /* MSDN lied about the third parameter for EditWordBreakProc being the number
+ * of characters, it is actually the number of bytes of the string. */
+ return editor->pfnWordBreak(str->szData, start, str->nLen*sizeof(WCHAR), code);
+ } else {
+ int result;
+ int buffer_size = WideCharToMultiByte(CP_ACP, 0, str->szData, str->nLen,
+ NULL, 0, NULL, NULL);
+ char *buffer = heap_alloc(buffer_size);
+ WideCharToMultiByte(CP_ACP, 0, str->szData, str->nLen,
+ buffer, buffer_size, NULL, NULL);
+ result = editor->pfnWordBreak(str->szData, start, str->nLen, code);
+ heap_free(buffer);
+ return result;
+ }
}
LPWSTR ME_ToUnicode(BOOL unicode, LPVOID psz)
assert(psz != NULL);
if (unicode)
- return (LPWSTR)psz;
+ return psz;
else {
WCHAR *tmp;
- int nChars = MultiByteToWideChar(CP_ACP, 0, (char *)psz, -1, NULL, 0);
+ int nChars = MultiByteToWideChar(CP_ACP, 0, psz, -1, NULL, 0);
if((tmp = ALLOC_N_OBJ(WCHAR, nChars)) != NULL)
- MultiByteToWideChar(CP_ACP, 0, (char *)psz, -1, tmp, nChars);
+ MultiByteToWideChar(CP_ACP, 0, psz, -1, tmp, nChars);
return tmp;
}
}