Katteker/Katteker/ReleaseEntry.cs
2018-07-30 15:07:48 +02:00

155 lines
5.7 KiB
C#

using Semver;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
namespace Katteker
{
/// <inheritdoc cref="IComparable" />
/// <summary>
/// Entry of a Release.
/// </summary>
public class ReleaseEntry : IComparable<ReleaseEntry>, IComparable
{
private const string FilenameRegex = @"(^.*)-((?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(?:\+[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*)?).*-(full|delta)";
private const char Seperator = '|';
/// <summary>
/// Creat an instance of <see cref="ReleaseEntry"/>.
/// </summary>
public ReleaseEntry(string filename, SemVersion version, long fileSize, bool isDelta, string sha1)
{
Filename = filename;
Version = version;
Filesize = fileSize;
IsDelta = isDelta;
SHA1 = sha1;
}
/// <summary>
/// Create an instance of <see cref="ReleaseEntry"/> from string.
/// </summary>
/// <exception cref="ArgumentOutOfRangeException">Argument 'line' has not the right format.</exception>
/// <exception cref="ArgumentNullException">Argument 'line' is null.</exception>
/// <exception cref="FileLoadException">Filename is not compliant.</exception>
public ReleaseEntry(string line)
{
if (line == null) throw new ArgumentNullException(nameof(line));
var elements = line.Split(Seperator);
if (elements.Length != 3)
{
throw new ArgumentOutOfRangeException(nameof(line), elements.Length, "The release entry has not the right format.");
}
SHA1 = elements[0];
Filename = elements[1];
Filesize = long.Parse(elements[2]);
var fileSegments = Regex.Match(Filename, FilenameRegex);
if (fileSegments.Groups.Count < 3) throw new FileLoadException("Filename is not compilant.");
ApplicationName = fileSegments.Groups[1].Value;
Version = SemVersion.Parse(fileSegments.Groups[2].Value);
IsDelta = fileSegments.Groups[3].Value != "full";
}
/// <summary>
/// cunstruct release entry from application name and version.
/// </summary>
/// <param name="applicationName"></param>
/// <param name="version"></param>
public ReleaseEntry(string applicationName, SemVersion version)
{
ApplicationName = applicationName;
Version = version;
}
/// <summary>
/// Version
/// </summary>
public SemVersion Version { get; }
/// <summary>
/// Hashsum of the file.
/// </summary>
public string SHA1 { get; }
/// <summary>
/// filename
/// </summary>
public string Filename { get; }
/// <summary>
/// Size of the file.
/// </summary>
public long Filesize { get; }
/// <summary>
/// Is true if the update is delta file. False otherwise.
/// </summary>
public bool IsDelta { get; }
/// <summary>
/// Name of the application.
/// </summary>
public string ApplicationName { get; }
/// <summary>
/// Format the release entry as line for release file.
/// </summary>
public string EntryAsString => $"{SHA1}{Seperator}{Filename}{Seperator}{Filesize}";
/// <inheritdoc />
public override string ToString() => $"{ApplicationName} {Version}";
/// <inheritdoc />
public int CompareTo(object obj) => CompareTo(obj as ReleaseEntry);
/// <inheritdoc />
public int CompareTo(ReleaseEntry other)
{
if (ReferenceEquals(this, other)) return 0;
if (other is null) return 1;
var versionComparison = Comparer<SemVersion>.Default.Compare(Version, other.Version);
if (versionComparison != 0) return versionComparison;
return string.Compare(Filename, other.Filename, StringComparison.Ordinal);
}
/// <inheritdoc />
public override bool Equals(object obj) => Equals(obj as ReleaseEntry);
/// <summary>
/// Returns true if the instances are equal. False otherwise.
/// </summary>
/// <param name="other"></param>
/// <returns></returns>
protected bool Equals(ReleaseEntry other)
{
return Equals(Version, other.Version) && string.Equals(SHA1, other.SHA1) && string.Equals(Filename, other.Filename) && Filesize == other.Filesize && IsDelta == other.IsDelta;
}
/// <inheritdoc />
public override int GetHashCode()
{
unchecked
{
var hashCode = (Version != null ? Version.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (SHA1 != null ? SHA1.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (Filename != null ? Filename.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ Filesize.GetHashCode();
hashCode = (hashCode * 397) ^ IsDelta.GetHashCode();
return hashCode;
}
}
/// <summary>
/// Returns true if the left and right instances are equal.
/// </summary>
public static bool operator ==(ReleaseEntry left, ReleaseEntry right) => Equals(left, right);
/// <summary>
/// Returns true if the left and right instances are not equal.
/// </summary>
public static bool operator !=(ReleaseEntry left, ReleaseEntry right) => !Equals(left, right);
}
}