Skip to content

Commit 38cec61

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 38cec61

File tree

2 files changed

+82
-5
lines changed

2 files changed

+82
-5
lines changed

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

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

51545154
static String withCrLf (String string) {
5155-
if (string == null) {
5155+
5156+
/* If the string is empty, return the string. */
5157+
int length = string.length ();
5158+
if (length == 0) return string;
5159+
5160+
/*
5161+
* Check for an LF or CR/LF and assume the rest of
5162+
* the string is formated that way. This will not
5163+
* work if the string contains mixed delimiters.
5164+
*/
5165+
int i = string.indexOf ('\n', 0);
5166+
if (i == -1) return string;
5167+
if (i > 0 && string.charAt (i - 1) == '\r') {
51565168
return string;
51575169
}
5158-
// Replace \r\n, \r, or \n with \r\n
5159-
return string.replaceAll("(\r\n|\r|\n)", "\r\n");
5170+
5171+
/*
5172+
* The string is formatted with LF. Compute the
5173+
* number of lines and the size of the buffer
5174+
* needed to hold the result
5175+
*/
5176+
i++;
5177+
int count = 1;
5178+
while (i < length) {
5179+
if ((i = string.indexOf ('\n', i)) == -1) break;
5180+
count++; i++;
5181+
}
5182+
count += length;
5183+
5184+
/* Create a new string with the CR/LF line terminator. */
5185+
i = 0;
5186+
StringBuilder result = new StringBuilder (count);
5187+
while (i < length) {
5188+
int j = string.indexOf ('\n', i);
5189+
if (j > 0 && string.charAt(j - 1) == '\r') {
5190+
result.append(string.substring(i, j + 1));
5191+
i = j + 1;
5192+
} else {
5193+
if (j == -1) j = length;
5194+
result.append (string.substring (i, j));
5195+
if ((i = j) < length) {
5196+
result.append ("\r\n"); //$NON-NLS-1$
5197+
i++;
5198+
}
5199+
}
5200+
}
5201+
return result.toString ();
51605202
}
51615203

51625204
static char [] withCrLf (char [] string) {
5163-
String withCrLf = withCrLf(new String(string));
5164-
return withCrLf.toCharArray();
5205+
/* If the string is empty, return the string. */
5206+
int length = string.length;
5207+
if (length == 0) return string;
5208+
5209+
/*
5210+
* Check for an LF or CR/LF and assume the rest of
5211+
* the string is formated that way. This will not
5212+
* work if the string contains mixed delimiters.
5213+
* Also, compute the number of lines.
5214+
*/
5215+
int count = 0;
5216+
for (int i = 0; i < string.length; i++) {
5217+
if (string [i] == '\n') {
5218+
count++;
5219+
if (count == 1 && i > 0 && string [i - 1] == '\r') return string;
5220+
}
5221+
}
5222+
if (count == 0) return string;
5223+
5224+
/*
5225+
* The string is formatted with LF.
5226+
*/
5227+
count += length;
5228+
5229+
/* Create a new string with the CR/LF line terminator. */
5230+
char [] result = new char [count];
5231+
for (int i = 0, j = 0; i < length && j < count; i++) {
5232+
if (string [i] == '\n') {
5233+
result [j++] = '\r';
5234+
}
5235+
result [j++] = string [i];
5236+
}
5237+
5238+
return result;
51655239
}
51665240

51675241
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)