//-----------------------------------------------------------------------------
//
// Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License").
// You may not use this file except in compliance with the License.
// A copy of the License is located at
//
// http://aws.amazon.com/apache2.0
//
// or in the "license" file accompanying this file. This file is distributed
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
// express or implied. See the License for the specific language governing
// permissions and limitations under the License.
//
//-----------------------------------------------------------------------------
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Text.RegularExpressions;
namespace Amazon.XRay.Recorder.Core.Internal.Utils
{
///
/// Perform string matching using standard wildcards (globbing pattern).
///
public static class StringExtension
{
///
/// Convert a string from the camel case to snake case.
///
/// The camel case string.
/// The converted snake case string.
[SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Justification = "Camel case start with lower case letter")]
public static string FromCamelCaseToSnakeCase(this string camelCaseStr)
{
camelCaseStr = char.ToLower(camelCaseStr[0], CultureInfo.InvariantCulture) + camelCaseStr.Substring(1);
string snakeCaseString = Regex.Replace(camelCaseStr, "(?[A-Z])", match => '_' + match.Groups["char"].Value.ToLowerInvariant());
return snakeCaseString;
}
///
/// Match the string with a pattern using standard wildcards (globbing pattern).
///
/// The text.
/// The pattern.
/// if set to true [is case insensitive].
/// true if the text matches the pattern; otherwise, false.
public static bool WildcardMatch(this string text, string pattern, bool isCaseInsensitive = true)
{
if (pattern == null || text == null)
{
return false;
}
if (pattern.Length == 0)
{
return text.Length == 0;
}
if (IsWildcardGlob(pattern))
{
return true;
}
int i = 0, p = 0, iStar = text.Length, pStar = 0;
while (i < text.Length)
{
if (p < pattern.Length && text[i] == pattern[p])
{
++i;
++p;
}
else if (p < pattern.Length && isCaseInsensitive && char.ToLower(text[i]) == char.ToLower(pattern[p]))
{
++i;
++p;
}
else if (p < pattern.Length && '?' == pattern[p])
{
++i;
++p;
}
else if (p < pattern.Length && pattern[p] == '*')
{
iStar = i;
pStar = p++;
}
else if (iStar != text.Length)
{
i = ++iStar;
p = pStar + 1;
}
else
return false;
}
while (p < pattern.Length && pattern[p] == '*') ++p;
return p == pattern.Length && i == text.Length;
}
///
/// Simples the wildcard match.
///
/// The text.
/// The pattern.
///
/// true if the text matches the pattern; otherwise, false.
///
private static bool SimpleWildcardMatch(string text, string pattern)
{
int j = 0;
int patternLength = pattern.Length;
int textLength = text.Length;
for (int i = 0; i < patternLength; i++)
{
char p = pattern[i];
if (p == '*')
{
// Presumption for this method is that glob can only occur at end.
return true;
}
if (p == '?')
{
if (j == text.Length)
{
return false; // No character to match
}
j++;
}
else
{
if (j >= text.Length || p != text[j])
{
return false;
}
j++;
}
}
return j == textLength;
}
///
/// Determines whether the passed pattern is "*"
///
/// The pattern.
///
/// true if the passed pattern is "*"; otherwise, false.
///
private static bool IsWildcardGlob(string pattern)
{
return pattern.Length == 1 && pattern[0] == '*';
}
///
/// Used to match incoming request and sampling rule parameters.
///
/// Parameter of incoming request.
/// Instance member of sampling rule to match.
/// True, if the two parameter matches else false.
public static bool IsMatch(string parameterToMatch, string ruleParameter)
{
return (string.IsNullOrEmpty(parameterToMatch) || parameterToMatch.WildcardMatch(ruleParameter));
}
}
}