VersionNumber.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text.RegularExpressions;
  4. namespace Wayne.Lib
  5. {
  6. /// <summary>
  7. /// Class representing a version number.
  8. /// </summary>
  9. public class VersionNumber : IComparable<VersionNumber>, IEquatable<VersionNumber>
  10. {
  11. #region Fields
  12. private const char Dot = '.';
  13. private static readonly Regex re = new Regex(@"^\d+(\.\d+)*$");
  14. private readonly string versionString;
  15. #endregion
  16. #region Construction
  17. /// <summary>
  18. /// Constructor
  19. /// </summary>
  20. /// <param name="versionString">Version string that is on a proper version number format.</param>
  21. /// <exception cref="ArgumentException">If versionString is not on correct Version number format.</exception>
  22. public VersionNumber(string versionString)
  23. {
  24. if (!re.IsMatch(versionString))
  25. {
  26. throw new ArgumentException(versionString + " is not a valid version string");
  27. }
  28. this.versionString = versionString;
  29. }
  30. #endregion
  31. #region Methods
  32. /// <summary>
  33. /// CompareTo method
  34. /// </summary>
  35. /// <param name="other"></param>
  36. /// <returns></returns>
  37. public int CompareTo(VersionNumber other)
  38. {
  39. Stack<int> ps = Convert(this.ToString());
  40. Stack<int> qs = Convert(other.ToString());
  41. // Continue while they are equal
  42. while (ps.Count > 0 && qs.Count > 0)
  43. {
  44. int p = ps.Pop();
  45. int q = qs.Pop();
  46. if (p < q)
  47. {
  48. return -1;
  49. }
  50. if (p > q)
  51. {
  52. return 1;
  53. }
  54. }
  55. // Check who ran out
  56. if (ps.Count == 0 && qs.Count == 0)
  57. {
  58. // both ran out, they are equal
  59. return 0;
  60. }
  61. if (ps.Count > 0 && qs.Count == 0)
  62. {
  63. // right ran out, so left must be bigger
  64. return 1;
  65. }
  66. if (ps.Count == 0 && qs.Count > 0)
  67. {
  68. // left ran out, so right must be bigger
  69. return -1;
  70. }
  71. // Should never end up here...
  72. throw new ArgumentException("this cannot happen");
  73. }
  74. private static Stack<int> Convert(string fullString)
  75. {
  76. List<int> list = new List<int>();
  77. foreach (string number in fullString.Split(Dot))
  78. {
  79. list.Add(int.Parse(number));
  80. }
  81. list.Reverse();
  82. return new Stack<int>(list);
  83. }
  84. /// <summary>
  85. /// ToString method
  86. /// </summary>
  87. /// <returns></returns>
  88. public override string ToString()
  89. {
  90. return versionString;
  91. }
  92. /// <summary>
  93. /// Equals method
  94. /// </summary>
  95. /// <param name="obj"></param>
  96. /// <returns></returns>
  97. public override bool Equals(object obj)
  98. {
  99. VersionNumber otherVersionNumber = obj as VersionNumber;
  100. if (otherVersionNumber != null)
  101. return this.Equals(otherVersionNumber);
  102. else
  103. return false;
  104. }
  105. /// <summary>
  106. /// Equals method
  107. /// </summary>
  108. /// <param name="other"></param>
  109. /// <returns></returns>
  110. public bool Equals(VersionNumber other)
  111. {
  112. return this.CompareTo(other) == 0;
  113. }
  114. /// <summary>
  115. /// Hash code generation
  116. /// </summary>
  117. /// <returns></returns>
  118. public override int GetHashCode()
  119. {
  120. return versionString.GetHashCode();
  121. }
  122. #endregion
  123. }
  124. }