2020-04-01 20:48:13 +00:00
|
|
|
|
using System;
|
2020-03-25 23:15:19 +00:00
|
|
|
|
using System.Collections;
|
2020-03-23 12:57:18 +00:00
|
|
|
|
using System.Collections.Generic;
|
2020-04-04 04:02:53 +00:00
|
|
|
|
using System.Diagnostics.CodeAnalysis;
|
2020-03-23 12:57:18 +00:00
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
2020-03-28 20:04:22 +00:00
|
|
|
|
using System.Net;
|
2020-03-23 12:57:18 +00:00
|
|
|
|
using System.Reflection;
|
2020-05-04 20:33:45 +00:00
|
|
|
|
using System.Runtime.InteropServices;
|
2020-03-23 12:57:18 +00:00
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using Alphaleonis.Win32.Filesystem;
|
2020-04-26 05:13:42 +00:00
|
|
|
|
using Newtonsoft.Json;
|
2020-04-17 03:52:19 +00:00
|
|
|
|
using Directory = Alphaleonis.Win32.Filesystem.Directory;
|
2020-07-27 21:33:45 +00:00
|
|
|
|
using DriveInfo = Alphaleonis.Win32.Filesystem.DriveInfo;
|
2020-03-23 12:57:18 +00:00
|
|
|
|
using File = Alphaleonis.Win32.Filesystem.File;
|
|
|
|
|
using FileInfo = Alphaleonis.Win32.Filesystem.FileInfo;
|
|
|
|
|
using Path = Alphaleonis.Win32.Filesystem.Path;
|
|
|
|
|
|
|
|
|
|
namespace Wabbajack.Common
|
|
|
|
|
{
|
2020-03-24 21:42:28 +00:00
|
|
|
|
|
2020-08-05 22:01:45 +00:00
|
|
|
|
|
2020-03-23 12:57:18 +00:00
|
|
|
|
|
2020-03-23 23:03:26 +00:00
|
|
|
|
public static partial class Utils
|
|
|
|
|
{
|
|
|
|
|
public static RelativePath ToPath(this string str)
|
|
|
|
|
{
|
|
|
|
|
return (RelativePath)str;
|
|
|
|
|
}
|
2020-03-25 12:47:25 +00:00
|
|
|
|
|
2020-03-23 23:03:26 +00:00
|
|
|
|
public static AbsolutePath RelativeTo(this string str, AbsolutePath path)
|
|
|
|
|
{
|
2020-05-29 04:09:39 +00:00
|
|
|
|
if (Path.IsPathRooted(str)) return (AbsolutePath)str;
|
2020-03-23 23:03:26 +00:00
|
|
|
|
return ((RelativePath)str).RelativeTo(path);
|
|
|
|
|
}
|
2020-03-24 12:21:19 +00:00
|
|
|
|
|
|
|
|
|
public static void Write(this BinaryWriter wtr, IPath path)
|
|
|
|
|
{
|
|
|
|
|
wtr.Write(path is AbsolutePath);
|
|
|
|
|
if (path is AbsolutePath)
|
2020-03-25 12:47:25 +00:00
|
|
|
|
{
|
2020-03-24 12:21:19 +00:00
|
|
|
|
wtr.Write((AbsolutePath)path);
|
2020-03-25 12:47:25 +00:00
|
|
|
|
}
|
2020-03-24 12:21:19 +00:00
|
|
|
|
else
|
2020-03-25 12:47:25 +00:00
|
|
|
|
{
|
2020-03-24 12:21:19 +00:00
|
|
|
|
wtr.Write((RelativePath)path);
|
2020-03-25 12:47:25 +00:00
|
|
|
|
}
|
2020-03-24 12:21:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void Write(this BinaryWriter wtr, AbsolutePath path)
|
|
|
|
|
{
|
|
|
|
|
wtr.Write((string)path);
|
|
|
|
|
}
|
2020-03-25 12:47:25 +00:00
|
|
|
|
|
2020-03-24 12:21:19 +00:00
|
|
|
|
public static void Write(this BinaryWriter wtr, RelativePath path)
|
|
|
|
|
{
|
|
|
|
|
wtr.Write((string)path);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static IPath ReadIPath(this BinaryReader rdr)
|
|
|
|
|
{
|
|
|
|
|
if (rdr.ReadBoolean())
|
2020-03-25 12:47:25 +00:00
|
|
|
|
{
|
2020-03-24 12:21:19 +00:00
|
|
|
|
return rdr.ReadAbsolutePath();
|
2020-03-25 12:47:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-03-24 12:21:19 +00:00
|
|
|
|
return rdr.ReadRelativePath();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static AbsolutePath ReadAbsolutePath(this BinaryReader rdr)
|
|
|
|
|
{
|
|
|
|
|
return new AbsolutePath(rdr.ReadString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static RelativePath ReadRelativePath(this BinaryReader rdr)
|
|
|
|
|
{
|
|
|
|
|
return new RelativePath(rdr.ReadString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static T[] Add<T>(this T[] arr, T itm)
|
|
|
|
|
{
|
|
|
|
|
var newArr = new T[arr.Length + 1];
|
|
|
|
|
Array.Copy(arr, 0, newArr, 0, arr.Length);
|
|
|
|
|
newArr[arr.Length] = itm;
|
|
|
|
|
return newArr;
|
|
|
|
|
}
|
2020-03-23 23:03:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-03-24 12:21:19 +00:00
|
|
|
|
public struct Extension
|
2020-03-23 12:57:18 +00:00
|
|
|
|
{
|
2020-03-25 12:47:25 +00:00
|
|
|
|
public static Extension None = new Extension("", false);
|
|
|
|
|
|
2020-03-23 12:57:18 +00:00
|
|
|
|
#region ObjectEquality
|
2020-03-25 12:47:25 +00:00
|
|
|
|
|
|
|
|
|
private bool Equals(Extension other)
|
2020-03-23 12:57:18 +00:00
|
|
|
|
{
|
2020-04-01 20:48:13 +00:00
|
|
|
|
return string.Equals(_extension, other._extension, StringComparison.InvariantCultureIgnoreCase);
|
2020-03-23 12:57:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-04-03 23:23:13 +00:00
|
|
|
|
public override bool Equals(object? obj)
|
2020-03-23 12:57:18 +00:00
|
|
|
|
{
|
2020-04-01 20:48:13 +00:00
|
|
|
|
return obj is Extension other && Equals(other);
|
2020-03-23 12:57:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-03-28 02:54:14 +00:00
|
|
|
|
public override string ToString()
|
|
|
|
|
{
|
|
|
|
|
return _extension;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-23 12:57:18 +00:00
|
|
|
|
public override int GetHashCode()
|
|
|
|
|
{
|
2020-04-01 20:48:13 +00:00
|
|
|
|
return _extension?.GetHashCode(StringComparison.InvariantCultureIgnoreCase) ?? 0;
|
2020-03-23 12:57:18 +00:00
|
|
|
|
}
|
2020-03-25 12:47:25 +00:00
|
|
|
|
|
2020-03-23 12:57:18 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
2020-04-03 23:23:13 +00:00
|
|
|
|
private readonly string? _nullable_extension;
|
|
|
|
|
private string _extension => _nullable_extension ?? string.Empty;
|
2020-03-23 12:57:18 +00:00
|
|
|
|
|
|
|
|
|
public Extension(string extension)
|
|
|
|
|
{
|
2020-03-24 12:21:19 +00:00
|
|
|
|
if (string.IsNullOrWhiteSpace(extension))
|
|
|
|
|
{
|
2020-04-03 23:23:13 +00:00
|
|
|
|
_nullable_extension = None._extension;
|
2020-03-24 12:21:19 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-03 23:23:13 +00:00
|
|
|
|
_nullable_extension = string.Intern(extension);
|
2020-03-23 12:57:18 +00:00
|
|
|
|
Validate();
|
|
|
|
|
}
|
2020-03-24 12:21:19 +00:00
|
|
|
|
|
|
|
|
|
private Extension(string extension, bool validate)
|
|
|
|
|
{
|
2020-04-03 23:23:13 +00:00
|
|
|
|
_nullable_extension = string.Intern(extension);
|
2020-03-25 12:47:25 +00:00
|
|
|
|
if (validate)
|
|
|
|
|
{
|
|
|
|
|
Validate();
|
|
|
|
|
}
|
2020-03-24 12:21:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Extension(Extension other)
|
|
|
|
|
{
|
2020-04-03 23:23:13 +00:00
|
|
|
|
_nullable_extension = other._extension;
|
2020-03-24 12:21:19 +00:00
|
|
|
|
}
|
2020-03-25 12:47:25 +00:00
|
|
|
|
|
2020-03-23 12:57:18 +00:00
|
|
|
|
private void Validate()
|
|
|
|
|
{
|
|
|
|
|
if (!_extension.StartsWith("."))
|
2020-03-25 12:47:25 +00:00
|
|
|
|
{
|
2020-03-28 21:52:43 +00:00
|
|
|
|
throw new InvalidDataException($"Extensions must start with '.' got {_extension}");
|
2020-03-25 12:47:25 +00:00
|
|
|
|
}
|
2020-03-23 12:57:18 +00:00
|
|
|
|
}
|
2020-03-25 12:47:25 +00:00
|
|
|
|
|
2020-03-23 12:57:18 +00:00
|
|
|
|
public static explicit operator string(Extension path)
|
|
|
|
|
{
|
|
|
|
|
return path._extension;
|
|
|
|
|
}
|
2020-03-25 12:47:25 +00:00
|
|
|
|
|
2020-03-23 12:57:18 +00:00
|
|
|
|
public static explicit operator Extension(string path)
|
|
|
|
|
{
|
|
|
|
|
return new Extension(path);
|
|
|
|
|
}
|
2020-03-25 12:47:25 +00:00
|
|
|
|
|
2020-03-23 12:57:18 +00:00
|
|
|
|
public static bool operator ==(Extension a, Extension b)
|
|
|
|
|
{
|
|
|
|
|
// Super fast comparison because extensions are interned
|
|
|
|
|
return ReferenceEquals(a._extension, b._extension);
|
|
|
|
|
}
|
2020-03-25 12:47:25 +00:00
|
|
|
|
|
2020-03-23 12:57:18 +00:00
|
|
|
|
public static bool operator !=(Extension a, Extension b)
|
|
|
|
|
{
|
2020-03-24 02:58:39 +00:00
|
|
|
|
return !(a == b);
|
2020-03-23 12:57:18 +00:00
|
|
|
|
}
|
2020-03-24 12:21:19 +00:00
|
|
|
|
|
|
|
|
|
public static Extension FromPath(string path)
|
|
|
|
|
{
|
|
|
|
|
var ext = Path.GetExtension(path);
|
|
|
|
|
return !string.IsNullOrWhiteSpace(ext) ? new Extension(ext) : None;
|
|
|
|
|
}
|
2020-03-23 12:57:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2020-03-25 12:47:25 +00:00
|
|
|
|
|
2020-03-23 12:57:18 +00:00
|
|
|
|
}
|