public bool IsMatch(string subject) { int finalPosition = 0; #if SPAN var matched = _rootTokenEvaluator.IsMatch(subject.AsSpan(), 0, out finalPosition); #else var matched = _rootTokenEvaluator.IsMatch(subject, 0, out finalPosition); #endif return(matched); }
public bool IsMatch(string allChars, int currentPosition, out int newPosition) { newPosition = currentPosition; if (!_subEvaluator.ConsumesVariableLength) { // The remaining tokens match against a fixed length string, so wildcard **must** consume // a known amount of characters in order for this to have a chance of successful match. // but can't consume past / behind current position! //var matchLength = (allChars.Length - _subEvaluator.ConsumesMinLength); //if (matchLength < currentPosition) //{ // return false; //} //var isMatch = _subEvaluator.IsMatch(allChars, matchLength, out newPosition); //return isMatch; var isMatch = _subEvaluator.IsMatch(allChars, (allChars.Length - _subEvaluator.ConsumesMinLength), out newPosition); return(isMatch); } // if we are at the end of the string, we match! if (currentPosition >= allChars.Length) { return(true); } // otherwise we can consume a variable amount of characters but we can't match more characters than the amount that will take // us past the min required length required by the sub evaluator tokens, and as we are not a directory wildcard, we // can't go past a path seperator. var maxPos = (allChars.Length - _subEvaluator.ConsumesMinLength); for (int i = currentPosition; i <= maxPos; i++) { var currentChar = allChars[i]; if (currentChar == '/' || currentChar == '\\') { return(false); } //int newSubPosition; var isMatch = _subEvaluator.IsMatch(allChars, i, out newPosition); if (isMatch) { return(true); } } return(false); }
public bool IsMatch(string text) { int finalPosition = 0; var matched = _rootTokenEvaluator.IsMatch(text, 0, out finalPosition); return(matched); }
public bool IsMatch(string allChars, int currentPosition, out int newPosition) { newPosition = currentPosition; if (!_requiresSubEvaluation) // We are the last token in the pattern { // If we have reached the end of the string, then we match. if (currentPosition >= allChars.Length) { return(true); } // We dont match if the remaining string has seperators. for (int i = currentPosition; i <= allChars.Length - 1; i++) { var currentChar = allChars[i]; if (currentChar == '/' || currentChar == '\\') { return(false); } } // we have matched upto the new position. newPosition = currentPosition + allChars.Length; return(true); } // We are not the last token in the pattern, and so the _subEvaluator representing the remaining pattern tokens must also match. // Does the sub pattern match a fixed length string, or variable length string? if (!_subEvaluator.ConsumesVariableLength) { // The remaining tokens match against a fixed length string, so we can infer that this wildcard **must** match // a fixed amount of characters in order for the subevaluator to match its fixed amount of characters from the remaining portion // of the string. // So we must match upto that position. We can't match seperators. var requiredMatchPosition = allChars.Length - _subEvaluator.ConsumesMinLength; //if (requiredMatchPosition < currentPosition) //{ // return false; //} for (int i = currentPosition; i < requiredMatchPosition; i++) { var currentChar = allChars[i]; if (currentChar == '/' || currentChar == '\\') { return(false); } } var isMatch = _subEvaluator.IsMatch(allChars, requiredMatchPosition, out newPosition); return(isMatch); } // Sub pattern matches a variable length string. // if we are at the end of the string, we match! //if (currentPosition >= allChars.Length) //{ // return true; //} // otherwise we can consume a variable amount of characters but we can't match more characters than the amount that will take // us past the min required length required by the sub evaluator tokens, and as we are not a directory wildcard, we // can't go past a path seperator. var maxPos = (allChars.Length - _subEvaluator.ConsumesMinLength); for (int i = currentPosition; i <= maxPos; i++) { var currentChar = allChars[i]; //int newSubPosition; var isMatch = _subEvaluator.IsMatch(allChars, i, out newPosition); if (isMatch) { return(true); } if (currentChar == '/' || currentChar == '\\') { return(false); } } return(false); }
public bool IsMatch(string allChars, int currentPosition, out int newPosition) { // We shortcut to success for a ** in some special cases:- // 1. We are already at the end of the test string. // 2. The ** token is the last token - in which case it will math all remaining text // We shortcut to failure for a ** in some special cases:- // A) The token was parsed with a leading seperator (i.e '/**' and the current charater we are matching from doesn't match that seperator. newPosition = currentPosition; // 1. Are we already at the end of the test string? if (currentPosition >= allChars.Length) { return(true); } // A) If leading seperator then current character needs to be that seperator. var currentChar = allChars[currentPosition]; if (this._token.LeadingPathSeperator != null) { if (currentChar != this._token.LeadingPathSeperator.Value) { // expected seperator. return(false); } // advance current position to match the leading seperator. currentPosition = currentPosition + 1; } // 2. if no more tokens require matching (i.e ** is the last token) - we match. if (this._subEvaluator.EvaluatorCount == 0) { newPosition = allChars.Length; return(true); } // Because we know we have more tokens in the pattern (subevaluators) - those will require a minimum amount of characters to match (could be 0 too). // We can therefore calculate a "max" character position that we can match to, as if we exceed that position the remaining tokens cant possibly match. var maxPos = (allChars.Length - _subEvaluator.ConsumesMinLength); // If all of the remaining tokens have a precise length, we can calculate the exact character that we need to macth to in the string. // Otherwise we have to test at multiple character positions until we find a match (less efficient) if (!_subEvaluator.ConsumesVariableLength) { // Fixed length. // As we can only match full segments, make sure character before chacracter at max pos is a seperator, var mustMatchUntilChar = allChars[maxPos - 1]; if (mustMatchUntilChar != '/' && mustMatchUntilChar != '\\') { // can only match full segments. return(false); } // Advance position to max pos. currentPosition = maxPos; return(_subEvaluator.IsMatch(allChars, currentPosition, out newPosition)); } else { // Remaining tokens match a variable length of the test string. // We iterate each position (within acceptable range) and test at each position. bool isMatch; currentChar = allChars[currentPosition]; // If the ** token was parsed with a trailing slash - i.e "**/" then we need to match past it before we test remainijng tokens. if (_token.TrailingPathSeperator != null) { if (currentChar == '/' || currentChar == '\\') { // match the seperator. currentPosition = currentPosition + 1; } } // Match until maxpos, is reached. while (currentPosition <= maxPos) { // Test at current position. isMatch = _subEvaluator.IsMatch(allChars, currentPosition, out newPosition); if (isMatch) { return(isMatch); } if (currentPosition == maxPos) { return(false); } // Iterate until we hit a seperator or maxPos. while (currentPosition < maxPos) { currentPosition = currentPosition + 1; currentChar = allChars[currentPosition]; if (currentChar == '/' || currentChar == '\\') { // advance past the seperator. currentPosition = currentPosition + 1; break; } } } } return(false); }
public bool IsMatch(string allChars, int currentPosition, out int newPosition) #endif { // We shortcut to success for a ** in some special cases:- // 1. The remaining tokens don't need to consume a minimum number of chracters in order to match. // We shortcut to failure for a ** in some special cases:- // A) The token was parsed with a leading path separator (i.e '/**' and the current charater we are matching from isn't a path separator. newPosition = currentPosition; // A) If leading seperator then current character needs to be that seperator. char currentChar = allChars[currentPosition]; if (_token.LeadingPathSeparator != null) { if (!GlobStringReader.IsPathSeparator(currentChar)) { // expected separator. return(false); } //else //{ // advance current position to match the leading separator. currentPosition = currentPosition + 1; //} } else { // no leading seperator, means ** used at start of pattern not /** used within pattern. // If **/ is used for start of pattern then input string doesn't need to start with a / or \ and it will be matched. // i.e **/foo/bar will match foo/bar or /foo/bar. // where as /**/foo/bar will not match foo/bar it will only match /foo/bar. currentChar = allChars[currentPosition]; if (GlobStringReader.IsPathSeparator(currentChar)) { // advance current position to match the leading separator. currentPosition = currentPosition + 1; } } // 1. if no more tokens require matching we match. if (_subEvaluator.ConsumesMinLength == 0) { newPosition = allChars.Length; return(true); } // Because we know we have more tokens in the pattern (subevaluators) - those will require a minimum amount of characters to match (could be 0 too). // We can therefore calculate a "max" character position that we can match to, as if we exceed that position the remaining tokens cant possibly match. int maxPos = (allChars.Length - _subEvaluator.ConsumesMinLength); // If all of the remaining tokens have a precise length, we can calculate the exact character that we need to macth to in the string. // Otherwise we have to test at multiple character positions until we find a match (less efficient) if (!_subEvaluator.ConsumesVariableLength) { // Fixed length. // As we can only match full segments, make sure character before chacracter at max pos is a separator, if (maxPos > 0) { char mustMatchUntilChar = allChars[maxPos - 1]; if (!GlobStringReader.IsPathSeparator(mustMatchUntilChar)) { // can only match full segments. return(false); } } // Advance position to max pos. currentPosition = maxPos; return(_subEvaluator.IsMatch(allChars, currentPosition, out newPosition)); } else { // Remaining tokens match a variable length of the test string. // We iterate each position (within acceptable range) and test at each position. bool isMatch; currentChar = allChars[currentPosition]; // If the ** token was parsed with a trailing slash - i.e "**/" then we need to match past it before we test remainijng tokens. // special exception if **/ is at start of pattern, as then the input string need not have any path separators. if (_token.TrailingPathSeparator != null) { if (GlobStringReader.IsPathSeparator(currentChar)) { // match the separator. currentPosition = currentPosition + 1; } } // Match until maxpos, is reached. while (currentPosition <= maxPos) { // Test at current position. isMatch = _subEvaluator.IsMatch(allChars, currentPosition, out newPosition); if (isMatch) { return(isMatch); } if (currentPosition == maxPos) { return(false); } // Iterate until we hit a separator or maxPos. while (currentPosition < maxPos) { currentPosition = currentPosition + 1; currentChar = allChars[currentPosition]; if (GlobStringReader.IsPathSeparator(currentChar)) { // match the separator. currentPosition = currentPosition + 1; break; } } } } return(false); }
public bool IsMatch(string allChars, int currentPosition, out int newPosition) { newPosition = currentPosition; //if (!_subEvaluator.ConsumesVariableLength) // if we are at the end of the string, we match! if (currentPosition >= allChars.Length) { return(true); } // The max pos we can match upto in the string, because of subtoken match requirements. var maxPos = (allChars.Length - _subEvaluator.ConsumesMinLength); // we can only match full segments at a time, where as match pos could point to a char in the middle of a segment. if (!_subEvaluator.ConsumesVariableLength) { // must match a fixed length of the string (must match all to max pos), but we can only match entire segments, // so for a successful match, the char before maxpos must either be current pos (we match nothing), or a seperator. if (maxPos - 1 != currentPosition) { var precedingchar = allChars[maxPos - 1]; if (precedingchar != '/' && precedingchar != '\\') { return(false); } } return(_subEvaluator.IsMatch(allChars, maxPos, out newPosition)); } else { // can match a variable length, but in compelte segments at a time, not past max pos. int pos = currentPosition; bool isMatch; var currentChar = allChars[pos]; var isSeprator = currentChar == '/' || currentChar == '\\'; if (this._token.LeadingPathSeperator != null && !isSeprator) { // must begin with seperator. return(false); } if (currentChar == '/' || currentChar == '\\') { if (pos == maxPos) { return(false); } pos = pos + 1; } while (pos <= maxPos) { isMatch = _subEvaluator.IsMatch(allChars, pos, out newPosition); if (isMatch) { return(isMatch); } currentChar = allChars[pos]; while (currentChar != '/' && currentChar != '\\' && pos + 1 < maxPos) { pos = pos + 1; currentChar = allChars[pos]; } pos = pos + 1; } } return(false); }