Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -423,13 +423,25 @@ public static boolean matchesGlob(@Nullable String str, @Nullable String pattern
int strIdxStart = 0;
int strIdxEnd = str.length() - 1;

// Convert both pattern and str to uppercase char arrays once to avoid repeated Character.toUpperCase calls.
final int patLen = pattern.length();
final int strLen = str.length();
char[] patUp = new char[patLen];
for (int i = 0; i < patLen; i++) {
patUp[i] = Character.toUpperCase(pattern.charAt(i));
}
char[] strUp = new char[strLen];
for (int i = 0; i < strLen; i++) {
strUp[i] = Character.toUpperCase(str.charAt(i));
}

// Process characters before first star
while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) {
char ch = pattern.charAt(patIdxStart);
char ch = patUp[patIdxStart];
if (ch == '*') {
break;
}
if (ch != '?' && different(ch, str.charAt(strIdxStart))) {
if (ch != '?' && ch != strUp[strIdxStart]) {
return false; // Character mismatch
}
patIdxStart++;
Expand All @@ -438,19 +450,19 @@ public static boolean matchesGlob(@Nullable String str, @Nullable String pattern
if (strIdxStart > strIdxEnd) {
// All characters in the string are used. Check if only '*'s are
// left in the pattern. If so, we succeeded. Otherwise failure.
return allStars(pattern, patIdxStart, patIdxEnd);
return allStarsChar(patUp, patIdxStart, patIdxEnd);
} else if (patIdxStart > patIdxEnd) {
// String not exhausted by pattern is. Failure
return false;
}

// Process characters after last star
while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) {
char ch = pattern.charAt(patIdxEnd);
char ch = patUp[patIdxEnd];
if (ch == '*') {
break;
}
if (ch != '?' && different(ch, str.charAt(strIdxEnd))) {
if (ch != '?' && ch != strUp[strIdxEnd]) {
return false; // Character mismatch
}
patIdxEnd--;
Expand All @@ -459,15 +471,15 @@ public static boolean matchesGlob(@Nullable String str, @Nullable String pattern
if (strIdxStart > strIdxEnd) {
// All characters in the string are used. Check if only '*'s are
// left in the pattern. If so, we succeeded. Otherwise failure.
return allStars(pattern, patIdxStart, patIdxEnd);
return allStarsChar(patUp, patIdxStart, patIdxEnd);
}

// Process pattern between stars. patIdxStart and patIdxEnd point
// always to a '*'.
while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) {
int patIdxTmp = -1;
for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
if (pattern.charAt(i) == '*') {
if (patUp[i] == '*') {
patIdxTmp = i;
break;
}
Expand All @@ -482,8 +494,8 @@ public static boolean matchesGlob(@Nullable String str, @Nullable String pattern
int patLength = (patIdxTmp - patIdxStart - 1);
int strLength = (strIdxEnd - strIdxStart + 1);

int foundIdx = findPatternInString(pattern, patIdxStart + 1, patLength,
str, strIdxStart, strLength);
int foundIdx = findPatternInCharArray(patUp, patIdxStart + 1, patLength,
strUp, strIdxStart, strLength);

if (foundIdx == -1) {
return false;
Expand All @@ -494,7 +506,7 @@ public static boolean matchesGlob(@Nullable String str, @Nullable String pattern

// All characters in the string are used. Check if only '*'s are left
// in the pattern. If so, we succeeded. Otherwise failure.
return allStars(pattern, patIdxStart, patIdxEnd);
return allStarsChar(patUp, patIdxStart, patIdxEnd);
}

private static int findPatternInString(String pattern, int patStart, int patLength,
Expand Down Expand Up @@ -747,4 +759,29 @@ public static boolean containsWhitespace(String s) {

return false;
}

private static int findPatternInCharArray(char[] patternUp, int patStart, int patLength,
char[] strUp, int strStart, int strLength) {
strLoop:
for (int i = 0; i <= strLength - patLength; i++) {
for (int j = 0; j < patLength; j++) {
char ch = patternUp[patStart + j];
if (ch != '?' && ch != strUp[strStart + i + j]) {
continue strLoop;
}
}
return strStart + i;
}
return -1;
}

private static boolean allStarsChar(char[] charsUp, int start, int end) {
for (int i = start; i <= end; ++i) {
if (charsUp[i] != '*') {
return false;
}
}
return true;
}

}