Skip to content

Commit 4cc6304

Browse files
[FIX] Change to old withCrLf for better performance
Changing back to the old withCrLf coding. Regex is causing performance issues. Furthermore, handling of mixed \n and \r\n is improved. Fixes: #1718
1 parent c49cee7 commit 4cc6304

File tree

2 files changed

+68
-5
lines changed

2 files changed

+68
-5
lines changed

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5152,16 +5152,76 @@ String wrapText (String text, long handle, int width) {
51525152
}
51535153

51545154
static String withCrLf (String string) {
5155-
if (string == null) {
5155+
/*
5156+
* Check for an LF or CR/LF and assume the rest of
5157+
* the string is formated that way. This will not
5158+
* work if the string contains mixed delimiters.
5159+
*/
5160+
int i = string.indexOf ('\n', 0);
5161+
if (i == -1) return string;
5162+
if (i > 0 && string.charAt (i - 1) == '\r') {
51565163
return string;
51575164
}
5158-
// Replace \r\n, \r, or \n with \r\n
5159-
return string.replaceAll("(\r\n|\r|\n)", "\r\n");
5165+
5166+
/* Create a new string with the CR/LF line terminator. */
5167+
i = 0;
5168+
int length = string.length();
5169+
StringBuilder result = new StringBuilder (length);
5170+
while (i < length) {
5171+
int j = string.indexOf ('\n', i);
5172+
if (j > 0 && string.charAt(j - 1) == '\r') {
5173+
result.append(string.substring(i, j + 1));
5174+
i = j + 1;
5175+
} else {
5176+
if (j == -1) j = length;
5177+
result.append (string.substring (i, j));
5178+
if ((i = j) < length) {
5179+
result.append ("\r\n"); //$NON-NLS-1$
5180+
i++;
5181+
}
5182+
}
5183+
}
5184+
5185+
/* Avoid creating a copy of the string if it has not changed */
5186+
if (string.length()== result.length()) return string;
5187+
return result.toString ();
51605188
}
51615189

51625190
static char [] withCrLf (char [] string) {
5163-
String withCrLf = withCrLf(new String(string));
5164-
return withCrLf.toCharArray();
5191+
/* If the string is empty, return the string. */
5192+
int length = string.length;
5193+
if (length == 0) return string;
5194+
5195+
/*
5196+
* Check for an LF or CR/LF and assume the rest of
5197+
* the string is formated that way. This will not
5198+
* work if the string contains mixed delimiters.
5199+
* Also, compute the number of lines.
5200+
*/
5201+
int count = 0;
5202+
for (int i = 0; i < string.length; i++) {
5203+
if (string [i] == '\n') {
5204+
count++;
5205+
if (count == 1 && i > 0 && string [i - 1] == '\r') return string;
5206+
}
5207+
}
5208+
if (count == 0) return string;
5209+
5210+
/*
5211+
* The string is formatted with LF.
5212+
*/
5213+
count += length;
5214+
5215+
/* Create a new string with the CR/LF line terminator. */
5216+
char [] result = new char [count];
5217+
for (int i = 0, j = 0; i < length && j < count; i++) {
5218+
if (string [i] == '\n') {
5219+
result [j++] = '\r';
5220+
}
5221+
result [j++] = string [i];
5222+
}
5223+
5224+
return result;
51655225
}
51665226

51675227
static boolean isActivateShellOnForceFocus() {

tests/org.eclipse.swt.tests.win32/JUnit Tests/org/eclipse/swt/tests/win32/widgets/Test_org_eclipse_swt_widgets_Display.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,8 @@ public void test_mixedLfAndCrfl() {
6060

6161
text.setText("First Line \n second line \r\n third line");
6262
assertEquals("First Line \r\n second line \r\n third line", text.getText());
63+
64+
text.setText("First Line \n second line \r\n third line\n");
65+
assertEquals("First Line \r\n second line \r\n third line\r\n", text.getText());
6366
}
6467
}

0 commit comments

Comments
 (0)