初始化奇妙小屏幕控制器项目
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
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();
|
||||
}
|
||||
Reference in New Issue
Block a user