improve jwt parser memory allocation

re-use buffer instead of creating new ones
avoid creating unneeded buffers in the Strings util methods
Stop continuously copying array with StringBuilder#deleteCharAt
work directly on StringBuilder instead of creating a temporary String

test added to cover the modified methods
This commit is contained in:
benoit 2016-08-31 16:39:42 +02:00
parent 0408313d3f
commit 9735d1ad98
3 changed files with 68 additions and 9 deletions

View File

@ -213,7 +213,8 @@ public class DefaultJwtParser implements JwtParser {
if (c == SEPARATOR_CHAR) {
String token = Strings.clean(sb.toString());
CharSequence tokenSeq = Strings.clean(sb);
String token = tokenSeq!=null?tokenSeq.toString():null;
if (delimiterCount == 0) {
base64UrlEncodedHeader = token;
@ -222,7 +223,7 @@ public class DefaultJwtParser implements JwtParser {
}
delimiterCount++;
sb = new StringBuilder(128);
sb.setLength(0);
} else {
sb.append(c);
}

View File

@ -159,22 +159,38 @@ public final class Strings {
* @see java.lang.Character#isWhitespace
*/
public static String trimWhitespace(String str) {
return (String) trimWhitespace((CharSequence)str);
}
private static CharSequence trimWhitespace(CharSequence str) {
if (!hasLength(str)) {
return str;
}
StringBuilder sb = new StringBuilder(str);
while (sb.length() > 0 && Character.isWhitespace(sb.charAt(0))) {
sb.deleteCharAt(0);
final int length = str.length();
int start = 0;
while (start < length && Character.isWhitespace(str.charAt(start))) {
start++;
}
while (sb.length() > 0 && Character.isWhitespace(sb.charAt(sb.length() - 1))) {
sb.deleteCharAt(sb.length() - 1);
int end = length;
while (start < length && Character.isWhitespace(str.charAt(end - 1))) {
end--;
}
return sb.toString();
return ((start > 0) || (end < length)) ? str.subSequence(start, end) : str;
}
public static String clean(String str) {
CharSequence result = clean((CharSequence) str);
return result!=null?result.toString():null;
}
public static CharSequence clean(CharSequence str) {
str = trimWhitespace(str);
if ("".equals(str)) {
if (!hasLength(str)) {
return null;
}
return str;

View File

@ -14,4 +14,46 @@ class StringsTest {
assertTrue Strings.hasText(" foo ");
assertTrue Strings.hasText("foo")
}
@Test
void testClean() {
assertEquals "this is a test", Strings.clean("this is a test")
assertEquals "this is a test", Strings.clean(" this is a test")
assertEquals "this is a test", Strings.clean(" this is a test ")
assertEquals "this is a test", Strings.clean("\nthis is a test \t ")
assertNull Strings.clean(null)
assertNull Strings.clean("")
assertNull Strings.clean("\t")
assertNull Strings.clean(" ")
}
@Test
void testCleanCharSequence() {
def result = Strings.clean(new StringBuilder("this is a test"))
assertNotNull result
assertEquals "this is a test", result.toString()
result = Strings.clean(new StringBuilder(" this is a test"))
assertNotNull result
assertEquals "this is a test", result.toString()
result = Strings.clean(new StringBuilder(" this is a test "))
assertNotNull result
assertEquals "this is a test", result.toString()
result = Strings.clean(new StringBuilder("\nthis is a test \t "))
assertNotNull result
assertEquals "this is a test", result.toString()
assertNull Strings.clean((StringBuilder) null)
assertNull Strings.clean(new StringBuilder(""))
assertNull Strings.clean(new StringBuilder("\t"))
assertNull Strings.clean(new StringBuilder(" "))
}
@Test
void testTrimWhitespace() {
assertEquals "", Strings.trimWhitespace(" ")
}
}