/// <summary> /// Parses a VersionRange from its string representation. /// </summary> public static bool TryParse(string value, bool allowFloating, out VersionRange versionRange) { versionRange = null; if (value == null) { return(false); } var trimmedValue = value.Trim(); var charArray = trimmedValue.ToCharArray(); // * is the only 1 char range if (allowFloating && charArray.Length == 1 && charArray[0] == '*') { versionRange = new VersionRange(new NuGetVersion(0, 0, 0), true, null, true, FloatRange.Parse(trimmedValue), originalString: value); return(true); } // Fail early if the string is too short to be valid if (charArray.Length < 3) { return(false); } string minVersionString = null; string maxVersionString = null; var isMinInclusive = false; var isMaxInclusive = false; NuGetVersion minVersion = null; NuGetVersion maxVersion = null; FloatRange floatRange = null; if (charArray[0] == '(' || charArray[0] == '[') { // The first character must be [ to ( switch (charArray[0]) { case '[': isMinInclusive = true; break; case '(': isMinInclusive = false; break; default: return(false); } // The last character must be ] ot ) switch (charArray[charArray.Length - 1]) { case ']': isMaxInclusive = true; break; case ')': isMaxInclusive = false; break; default: return(false); } // Get rid of the two brackets trimmedValue = trimmedValue.Substring(1, trimmedValue.Length - 2); // Split by comma, and make sure we don't get more than two pieces var parts = trimmedValue.Split(','); if (parts.Length > 2) { return(false); } else { var allEmpty = true; for (int i = 0; i < parts.Length; i++) { if (!string.IsNullOrEmpty(parts[i])) { allEmpty = false; break; } } // If all parts are empty, then neither of upper or lower bounds were specified. Version spec is of the format (,] if (allEmpty) { return(false); } } // (1.0.0] and [1.0.0),(1.0.0) are invalid. if (parts.Length == 1 && !(isMinInclusive && isMaxInclusive)) { return(false); } // If there is only one piece, we use it for both min and max minVersionString = parts[0]; maxVersionString = (parts.Length == 2) ? parts[1] : parts[0]; } else { // default to min inclusive when there are no braces isMinInclusive = true; // use the entire value as the version minVersionString = trimmedValue; } if (!string.IsNullOrWhiteSpace(minVersionString)) { // parse the min version string if (allowFloating && minVersionString.Contains("*")) { // single floating version if (FloatRange.TryParse(minVersionString, out floatRange) && floatRange.HasMinVersion) { minVersion = floatRange.MinVersion; } else { // invalid float return(false); } } else { // single non-floating version if (!NuGetVersion.TryParse(minVersionString, out minVersion)) { // invalid version return(false); } } } // parse the max version string, the max cannot float if (!string.IsNullOrWhiteSpace(maxVersionString)) { if (!NuGetVersion.TryParse(maxVersionString, out maxVersion)) { // invalid version return(false); } } if (minVersion != null && maxVersion != null) { int result = minVersion.CompareTo(maxVersion); // minVersion > maxVersion if (result > 0) { return(false); } // minVersion is equal to maxVersion (1.0.0, 1.0.0], [1.0.0, 1.0.0) if (result == 0 && (isMinInclusive ^ isMaxInclusive)) { return(false); } } // Successful parse! versionRange = new VersionRange( minVersion: minVersion, includeMinVersion: isMinInclusive, maxVersion: maxVersion, includeMaxVersion: isMaxInclusive, floatRange: floatRange, originalString: value); return(true); }
/// <summary> /// Parses a VersionRange from its string representation. /// </summary> public static bool TryParse(string value, bool allowFloating, out VersionRange versionRange) { if (value == null) { throw new ArgumentNullException("value"); } versionRange = null; var trimmedValue = value.Trim(); char[] charArray = trimmedValue.ToCharArray(); // * is the only range below 3 chars if (allowFloating && charArray.Length == 1 && charArray[0] == '*') { versionRange = new VersionRange(null, true, null, true, false, new FloatRange(NuGetVersionFloatBehavior.Major), originalString: value); return(true); } // Fail early if the string is too short to be valid if (charArray.Length < 3) { return(false); } string minVersionString = null; string maxVersionString = null; bool isMinInclusive = false; bool isMaxInclusive = false; NuGetVersion minVersion = null; NuGetVersion maxVersion = null; FloatRange floatRange = null; if (charArray[0] == '(' || charArray[0] == '[') { // The first character must be [ to ( switch (charArray[0]) { case '[': isMinInclusive = true; break; case '(': isMinInclusive = false; break; default: return(false); } // The last character must be ] ot ) switch (charArray[charArray.Length - 1]) { case ']': isMaxInclusive = true; break; case ')': isMaxInclusive = false; break; default: return(false); } // Get rid of the two brackets trimmedValue = trimmedValue.Substring(1, trimmedValue.Length - 2); // Split by comma, and make sure we don't get more than two pieces string[] parts = trimmedValue.Split(','); if (parts.Length > 2) { return(false); } else if (parts.All(String.IsNullOrEmpty)) { // If all parts are empty, then neither of upper or lower bounds were specified. Version spec is of the format (,] return(false); } // If there is only one piece, we use it for both min and max minVersionString = parts[0]; maxVersionString = (parts.Length == 2) ? parts[1] : parts[0]; } else { // default to min inclusive when there are no braces isMinInclusive = true; // use the entire value as the version minVersionString = trimmedValue; } if (!String.IsNullOrWhiteSpace(minVersionString)) { // parse the min version string if (allowFloating && minVersionString.Contains("*")) { // single floating version if (FloatRange.TryParse(minVersionString, out floatRange) && floatRange.HasMinVersion) { minVersion = floatRange.MinVersion; } else { // invalid float return(false); } } else { // single non-floating version if (!NuGetVersion.TryParse(minVersionString, out minVersion)) { // invalid version return(false); } } } // parse the max version string, the max cannot float if (!String.IsNullOrWhiteSpace(maxVersionString)) { if (!NuGetVersion.TryParse(maxVersionString, out maxVersion)) { // invalid version return(false); } } // Successful parse! versionRange = new VersionRange( minVersion: minVersion, includeMinVersion: isMinInclusive, maxVersion: maxVersion, includeMaxVersion: isMaxInclusive, includePrerelease: null, floatRange: floatRange, originalString: value); return(true); }