using System; namespace UnityEngine.XR.ARKit { /// /// Represents a version number consisting of major, minor, and point compnents. /// Version numbers are often written as Major.Minor.Point. /// public struct OSVersion : IEquatable, IComparable { /// /// The major version component. /// public int major { get; private set; } /// /// The minor version component. /// public int minor { get; private set; } /// /// The point version component. /// public int point { get; private set; } /// /// Constructs a new version number. /// /// The major version component /// The minor version component /// The point version component public OSVersion(int major, int minor = 0, int point = 0) { if (major < 0) throw new ArgumentOutOfRangeException("major", "Version component must be greater than or equal to 0."); if (minor < 0) throw new ArgumentOutOfRangeException("minor", "Version component must be greater than or equal to 0."); if (point < 0) throw new ArgumentOutOfRangeException("point", "Version component must be greater than or equal to 0."); this.major = major; this.minor = minor; this.point = point; } /// /// Parses a string which contains a version number of the form X.Y.Z somewhere in the string. /// If multiple such substrings exists, the first is used. The parser stops when either /// 3 components have been identified, or when less than 3 components have been identified /// and the next character is not a period (".") or a digit (0-9). If /// is null or the empty string, this method returns the version 0.0.0 /// /// The string to parse. /// A new OSVersion representing . public static OSVersion Parse(string version) { if (string.IsNullOrEmpty(version)) return new OSVersion(0); int index = IndexOfFirstDigit(version); return new OSVersion { major = ParseNextComponent(version, ref index), minor = ParseNextComponent(version, ref index), point = ParseNextComponent(version, ref index) }; } static int IndexOfFirstDigit(string version) { for (int index = 0; index < version.Length; ++index) { var digit = (int)version[index] - 48; if (digit >= 0 && digit <= 9) return index; } // Return one past the end of the string so that // ParseNextComponent will early out return version.Length; } static int ParseNextComponent(string version, ref int index) { const int periodCode = -2; int number = 0; for (; index < version.Length; ++index) { var digit = (int)version[index] - 48; if (digit == 0 && number == 0) { // Ignore leading zeroes continue; } else if (digit >= 0 && digit <= 9) { number = number * 10 + digit; } else if (digit == periodCode) { ++index; break; } else { // This is no longer a version string. index = version.Length; break; } } return number; } /// /// Generates a hash code suitable for use in a HashSet or Dictionary. /// /// A hash code. The same OSVersion will produce the same hash code. public override int GetHashCode() { unchecked { var hash = major.GetHashCode(); hash = hash * 486187739 + minor.GetHashCode(); hash = hash * 486187739 + point.GetHashCode(); return hash; } } /// /// IComparable interface. This is useful for sorting routines. /// /// The other version to compare to. /// -1 if this OSVersion is less than , 0 if they are equal, or 1 if this is greater. public int CompareTo(OSVersion version) { if (this < version) return -1; if (this > version) return 1; return 0; } /// /// Compares for equality. /// /// The object to compare against. /// Returns false if is null or is not of type OSVersion. Otherwise, returns the same value as . public override bool Equals(object obj) { if (obj == null || !(obj is OSVersion)) return false; return Equals((OSVersion)obj); } /// /// Compares for equality. The three version components are compared against 's. /// /// The OSVersion to compare for equality. /// True if has the same , , and values. public bool Equals(OSVersion other) { return (major == other.major) && (minor == other.minor) && (point == other.point); } /// /// Tests whether is an earlier version compared to . /// /// The left-hand side of the comparison. /// The right-hand side of the comparison. /// true if is an earlier version compared to ; otherwise, false. public static bool operator <(OSVersion lhs, OSVersion rhs) { if (lhs.major < rhs.major) return true; if (lhs.major > rhs.major) return false; if (lhs.minor < rhs.minor) return true; if (lhs.minor > rhs.minor) return false; return lhs.point < rhs.point; } /// /// Tests whether is a later version compared to . /// /// The left-hand side of the comparison. /// The right-hand side of the comparison. /// true if is a later version compared to ; otherwise, false. public static bool operator >(OSVersion lhs, OSVersion rhs) { if (lhs.major > rhs.major) return true; if (lhs.major < rhs.major) return false; if (lhs.minor > rhs.minor) return true; if (lhs.minor < rhs.minor) return false; return lhs.point > rhs.point; } /// /// Tests whether is the same version as . This is the same as . /// /// The left-hand side of the comparison. /// The right-hand side of the comparison. /// true if is the same version as ; otherwise, false. public static bool operator ==(OSVersion lhs, OSVersion rhs) { return lhs.Equals(rhs); } /// /// Tests whether is a different version from . /// /// The left-hand side of the comparison. /// The right-hand side of the comparison. /// true if is a different version from ; otherwise, false. public static bool operator !=(OSVersion lhs, OSVersion rhs) { return !lhs.Equals(rhs); } /// /// Tests whether is the same or a later version compared to . /// /// The left-hand side of the comparison. /// The right-hand side of the comparison. /// true if is the same or a later version compared to ; otherwise, false. public static bool operator >=(OSVersion lhs, OSVersion rhs) { return (lhs > rhs) || (lhs == rhs); } /// /// Tests whether is the same or an earlier version compared to . /// /// The left-hand side of the comparison. /// The right-hand side of the comparison. /// true if is the same or an earlier version compared to ; otherwise, false. public static bool operator <=(OSVersion lhs, OSVersion rhs) { return (lhs < rhs) || (lhs == rhs); } /// /// Generates a string representation of the version. /// /// A string in the form ... public override string ToString() { return $"{major}.{minor}.{point}"; } } }