diff --git a/Wabbajack.Common/Paths/FullPath.cs b/Wabbajack.Common/Paths/FullPath.cs new file mode 100644 index 00000000..2a9879d5 --- /dev/null +++ b/Wabbajack.Common/Paths/FullPath.cs @@ -0,0 +1,76 @@ +using System; +using System.Linq; + + +namespace Wabbajack.Common +{ + public struct FullPath : IEquatable, IPath + { + public AbsolutePath Base { get; } + + public RelativePath[] Paths { get; } + + private readonly int _hash; + + public FullPath(AbsolutePath basePath, params RelativePath[] paths) + { + Base = basePath; + Paths = paths == null ? Array.Empty() : paths; + _hash = Base.GetHashCode(); + foreach (var itm in Paths) + { + _hash ^= itm.GetHashCode(); + } + } + + public override string ToString() + { + var paths = Paths == null ? EmptyPath : Paths; + return string.Join("|", paths.Select(t => (string)t).Cons((string)Base)); + } + + public override int GetHashCode() + { + return _hash; + } + + private static RelativePath[] EmptyPath = Array.Empty(); + + public static bool operator ==(FullPath a, FullPath b) + { + if (a.Paths == null || b.Paths == null) return false; + + if (a.Base != b.Base || a.Paths.Length != b.Paths.Length) + { + return false; + } + + for (var idx = 0; idx < a.Paths.Length; idx += 1) + { + if (a.Paths[idx] != b.Paths[idx]) + { + return false; + } + } + + return true; + } + + public static bool operator !=(FullPath a, FullPath b) + { + return !(a == b); + } + + public bool Equals(FullPath other) + { + return this == other; + } + + public override bool Equals(object? obj) + { + return obj is FullPath other && Equals(other); + } + + public RelativePath FileName => Paths.Length == 0 ? Base.FileName : Paths.Last().FileName; + } +} diff --git a/Wabbajack.Common/Paths/HashRelativePath.cs b/Wabbajack.Common/Paths/HashRelativePath.cs new file mode 100644 index 00000000..4d2a0482 --- /dev/null +++ b/Wabbajack.Common/Paths/HashRelativePath.cs @@ -0,0 +1,77 @@ +using System; +using System.Linq; + +namespace Wabbajack.Common +{ + public struct HashRelativePath : IEquatable + { + private static RelativePath[] EMPTY_PATH; + public Hash BaseHash { get; } + public RelativePath[] Paths { get; } + + static HashRelativePath() + { + EMPTY_PATH = new RelativePath[0]; + } + + public HashRelativePath(Hash baseHash, params RelativePath[] paths) + { + BaseHash = baseHash; + Paths = paths; + } + + public override string ToString() + { + var paths = Paths == null ? EmptyPath : Paths; + return string.Join("|", paths.Select(t => t.ToString()).Cons(BaseHash.ToString())); + } + + private static RelativePath[] EmptyPath = Array.Empty(); + + public static bool operator ==(HashRelativePath a, HashRelativePath b) + { + if (a.Paths == null || b.Paths == null) return false; + + if (a.BaseHash != b.BaseHash || a.Paths.Length != b.Paths.Length) + { + return false; + } + + for (var idx = 0; idx < a.Paths.Length; idx += 1) + { + if (a.Paths[idx] != b.Paths[idx]) + { + return false; + } + } + + return true; + } + + public static bool operator !=(HashRelativePath a, HashRelativePath b) + { + return !(a == b); + } + + public bool Equals(HashRelativePath other) + { + return this == other; + } + + public override bool Equals(object? obj) + { + return obj is HashRelativePath other && Equals(other); + } + + public override int GetHashCode() + { + return HashCode.Combine(BaseHash, Paths); + } + + public static HashRelativePath FromStrings(string hash, params string[] paths) + { + return new HashRelativePath(Hash.FromBase64(hash), paths.Select(p => (RelativePath)p).ToArray()); + } + } + +}