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}";
}
}
}