Files

76 lines
3.5 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Text.RegularExpressions;
namespace MatrixImageEditor;
internal static partial class ImagePathRules
{
public static string ValidateExistingImage(string imagePath)
{
var fullPath = ValidateImageNameAndDirectory(imagePath);
if (!File.Exists(fullPath)) throw new FileNotFoundException("镜像文件不存在", fullPath);
if (Directory.Exists(fullPath + ".sha256")) throw new IOException("同名 SHA-256 摘要路径被文件夹占用");
return fullPath;
}
public static string ValidateNewDestination(string sourcePath, string destinationPath)
{
var source = ValidateExistingImage(sourcePath);
var destination = ValidateImageNameAndDirectory(destinationPath);
if (destination.Equals(source, StringComparison.OrdinalIgnoreCase)) throw new ArgumentException("另存为必须使用与原镜像不同的文件名");
if (File.Exists(destination) || Directory.Exists(destination)) throw new IOException("目标镜像已经存在,请使用新的文件名");
var sidecar = destination + ".sha256";
if (File.Exists(sidecar) || Directory.Exists(sidecar)) throw new IOException("目标镜像的同名 SHA-256 摘要已经存在,请使用新的文件名");
return destination;
}
public static string? CleanupNewDestination(string destinationPath)
{
List<string>? failures = null;
foreach (var target in new[] { destinationPath + ".sha256", destinationPath })
{
try
{
if (File.Exists(target)) File.Delete(target);
}
catch (Exception exception)
{
failures ??= new List<string>();
failures.Add($"{Path.GetFileName(target)}:{exception.Message}");
}
}
return failures is null ? null : string.Join(";", failures);
}
private static string ValidateImageNameAndDirectory(string imagePath)
{
if (string.IsNullOrWhiteSpace(imagePath)) throw new ArgumentException("镜像路径不能为空");
string fullPath;
try
{
fullPath = Path.GetFullPath(imagePath);
}
catch (Exception exception) when (exception is ArgumentException or NotSupportedException or PathTooLongException)
{
throw new ArgumentException("镜像路径格式无效", exception);
}
var fileName = Path.GetFileName(fullPath);
if (string.IsNullOrWhiteSpace(fileName)) throw new ArgumentException("镜像文件名不能为空");
if (fileName.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0 || fileName != fileName.TrimEnd(' ', '.'))
{
throw new ArgumentException("镜像文件名包含 Windows 不允许的字符,或以空格、句点结尾");
}
if (!Path.GetExtension(fileName).Equals(".img", StringComparison.OrdinalIgnoreCase)) throw new ArgumentException("镜像文件名必须以 .img 结尾");
if (ReservedWindowsName().IsMatch(Path.GetFileNameWithoutExtension(fileName))) throw new ArgumentException("镜像文件名使用了 Windows 保留名称,请更换名称");
var directory = Path.GetDirectoryName(fullPath);
if (string.IsNullOrEmpty(directory) || !Directory.Exists(directory)) throw new DirectoryNotFoundException("镜像目标文件夹不存在");
return fullPath;
}
[GeneratedRegex("^(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(?:\\..*)?$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)]
private static partial Regex ReservedWindowsName();
}