using System; using System.IO; using SabreTools.Hashing; using SabreTools.Text.Extensions; namespace SabreTools.Metadata.DatFiles { /// /// Depot information wrapper /// public class DepotInformation : ICloneable { /// /// Name or path of the Depot /// public string? Name { get; } /// /// Whether to use this Depot or not /// public bool IsActive { get; } /// /// Depot byte-depth /// public int Depth { get; } /// /// Maximum depth allowed for path generation /// private static readonly int MaximumDepth = HashType.SHA1.ZeroBytes.Length; /// /// Constructor /// /// Set active state /// Set depth between 0 and SHA-1's byte length public DepotInformation(bool isActive, int depth) : this(null, isActive, depth) { } /// /// Constructor /// /// Identifier for the depot /// Set active state /// Set depth between 0 and SHA-1's byte length public DepotInformation(string? name, bool isActive, int depth) { Name = name; IsActive = isActive; Depth = depth; // Limit depth value if (Depth == int.MinValue) Depth = 4; else if (Depth < 0) Depth = 0; else if (Depth > MaximumDepth) Depth = MaximumDepth; } #region Cloning /// /// Clone the current object /// public object Clone() => new DepotInformation(Name, IsActive, Depth); #endregion #region Path Generation /// /// Get a proper romba subpath /// /// SHA-1 hash to get the path for /// Positive value representing the depth of the depot /// Subfolder path for the given hash, including the filename and .gz extension public string? GetDepotPath(byte[]? hash) { string? sha1 = hash.ToHexString(); return GetDepotPath(sha1); } /// /// Get a proper romba subpath /// /// SHA-1 hash to get the path for /// Subfolder path for the given hash, including the filename and .gz extension public string? GetDepotPath(string? hash) { // If the hash is null, then we return null if (hash is null) return null; // If the hash isn't the right size, then we return null if (hash.Length != HashType.SHA1.ZeroString.Length) return null; // Cap the depth between 0 and 20, for now int depth = Depth; if (depth < 0) depth = 0; else if (depth > MaximumDepth) depth = MaximumDepth; // Loop through and generate the subdirectory string path = string.Empty; for (int i = 0; i < depth; i++) { path += hash.Substring(i * 2, 2) + Path.DirectorySeparatorChar; } // Now append the filename path += $"{hash}.gz"; return path; } #endregion } }