wabbajack/Wabbajack.Common/Paths.cs

186 lines
4.8 KiB
C#
Raw Normal View History

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;
using System.Runtime.InteropServices;
2020-03-23 12:57:18 +00:00
using System.Text;
using System.Threading.Tasks;
using Alphaleonis.Win32.Filesystem;
using Newtonsoft.Json;
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
public static partial class Utils
{
public static RelativePath ToPath(this string str)
{
return (RelativePath)str;
}
2020-03-25 12:47:25 +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;
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-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
{
return string.Equals(_extension, other._extension, StringComparison.InvariantCultureIgnoreCase);
2020-03-23 12:57:18 +00:00
}
public override bool Equals(object? obj)
2020-03-23 12:57:18 +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()
{
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
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))
{
_nullable_extension = None._extension;
2020-03-24 12:21:19 +00:00
return;
}
_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)
{
_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)
{
_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
}