using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml.Serialization; namespace RainmeterStudio.Core.Utils { /// /// Serializable version of the System.Version class. /// public class Version : ICloneable, IComparable { private int _major, _minor, _build, _revision; /// /// Gets or sets the major. /// /// [XmlAttribute("major")] public int Major { get { return _major; } set { if (value < 0) throw new ArgumentOutOfRangeException("Major out of range."); _major = value; } } /// /// Gets or sets the minor. /// /// [XmlAttribute("minor")] public int Minor { get { return _minor; } set { if (value < -1) throw new ArgumentOutOfRangeException("Minor out of range."); _minor = value; } } /// /// Gets or sets the build. /// /// [XmlAttribute("build")] public int Build { get { return _build; } set { if (value < -1) throw new ArgumentOutOfRangeException("Build out of range."); _build = value; } } /// /// Gets or sets the revision. /// /// [XmlAttribute("revision")] public int Revision { get { return _revision; } set { if (value < -1) throw new ArgumentOutOfRangeException("Revision out of range."); _revision = value; } } /// /// Creates a new instance of version. /// public Version() { Major = 1; Minor = 0; Revision = -1; Build = -1; } /// /// Creates a new instance of Version. /// /// Version string public Version(string version) { // Parse int major, minor, revision, build; Parse(version, out major, out minor, out build, out revision); // Commit Major = major; Minor = minor; Build = build; Revision = revision; } /// /// Creates a new instance of Version. /// /// Major public Version(int major) : this(major, -1, -1, -1) { } /// /// Creates a new instance of Version. /// /// Major /// Minor public Version(int major, int minor) : this(major, minor, -1, -1) { } /// /// Creates a new instance of Version. /// /// Major /// Minor /// Build public Version(int major, int minor, int build) : this(major, minor, build, -1) { } /// /// Creates a new instance of Version. /// /// Major /// Minor /// Build /// Revision public Version(int major, int minor, int build, int revision) { Major = major; Minor = minor; Build = build; Revision = revision; } #region ICloneable Members /// /// Clones this instance. /// /// public object Clone() { return new Version(Major, Minor, Build, Revision); } #endregion #region IComparable Members /// /// Compares to another object. /// /// Other object /// public int CompareTo(object obj) { if (obj == null) { return 1; } Version version = obj as Version; if (version == null) { throw new ArgumentException("Argument must be version"); } if (Major != version.Major) { return (Major - version.Major); } if (Minor != version.Minor) { return (Minor - version.Minor); } if (Build != version.Build) { return (Build - version.Build); } if (Revision != version.Revision) { return (Revision - version.Revision); } return 0; } #endregion /// /// Equalss the specified obj. /// /// Obj. /// public override bool Equals(object obj) { Version version = obj as Version; if (version == null) { return false; } else { return this.CompareTo(obj) == 0; } } /// /// Gets the hash code. /// /// public override int GetHashCode() { int hash = Major; hash = hash * 7 + Minor; hash = hash * 7 + Build; hash = hash * 7 + Revision; return Revision; } /// /// Equals operator. /// /// first object /// second object /// public static bool operator ==(Version v1, Version v2) { return Object.Equals(v1, v2); } /// /// Not equals operator. /// /// first object /// second object /// public static bool operator !=(Version v1, Version v2) { return !Object.Equals(v1, v2); } /// /// Greater than operator. /// /// first object /// second object /// public static bool operator >(Version v1, Version v2) { return v1.CompareTo(v2) > 0; } /// /// Greater or equal than operator. /// /// first object /// second object /// public static bool operator >=(Version v1, Version v2) { return v1.CompareTo(v2) >= 0; } /// /// Less than operator. /// /// first object /// second object /// public static bool operator <(Version v1, Version v2) { return v1.CompareTo(v2) < 0; } /// /// Less or equal than operator. /// /// first object /// second object /// public static bool operator <=(Version v1, Version v2) { return v1.CompareTo(v2) <= 0; } /// /// Converts to string. /// /// String representation public override string ToString() { StringBuilder builder = new StringBuilder(); builder.Append(Major); if (Minor >= 0) { builder.Append('.'); builder.Append(Minor); if (Build >= 0) { builder.Append('.'); builder.Append(Build); if (Revision > 0) { builder.Append('.'); builder.Append(Revision); } } } return builder.ToString(); } /// /// Converts to string. /// /// Field count /// public string ToString(int fieldCount) { StringBuilder builder = new StringBuilder(); if (fieldCount > 0) { builder.Append(Major); if (Minor >= 0 && fieldCount > 1) { builder.Append('.'); builder.Append(Minor); if (Build >= 0 && fieldCount > 2) { builder.Append('.'); builder.Append(Build); if (Revision > 0 && fieldCount > 3) { builder.Append('.'); builder.Append(Revision); } } } } return builder.ToString(); } /// /// Parses a string /// /// private static void Parse(string value, out int major, out int minor, out int build, out int revision) { // Sanity check if (value == null) { throw new ArgumentNullException("version"); } // Split into fields string[] fields = value.Split('.'); major = 0; minor = -1; build = -1; revision = -1; if (fields.Length > 4) { throw new ArgumentException("Invalid version string."); } if (fields.Length > 3) { revision = int.Parse(fields[3], CultureInfo.InvariantCulture); } if (fields.Length > 2) { build = int.Parse(fields[2], CultureInfo.InvariantCulture); } if (fields.Length > 1) { minor = int.Parse(fields[1], CultureInfo.InvariantCulture); } if (fields.Length > 0) { major = int.Parse(fields[0], CultureInfo.InvariantCulture); } else { throw new ArgumentException("Invalid version string."); } } } }