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