mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Update PathTools.IsNormalized to handle mount names
This commit is contained in:
parent
b821ba9519
commit
5d32150ad8
3 changed files with 62 additions and 63 deletions
|
@ -138,7 +138,7 @@ namespace LibHac.Fs
|
||||||
return new DirectoryHandle(dir);
|
return new DirectoryHandle(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
long GetFreeSpaceSize(string path)
|
public long GetFreeSpaceSize(string path)
|
||||||
{
|
{
|
||||||
FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath)
|
FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath)
|
||||||
.ThrowIfFailure();
|
.ThrowIfFailure();
|
||||||
|
@ -146,7 +146,7 @@ namespace LibHac.Fs
|
||||||
return fileSystem.GetFreeSpaceSize(subPath.ToString());
|
return fileSystem.GetFreeSpaceSize(subPath.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
long GetTotalSpaceSize(string path)
|
public long GetTotalSpaceSize(string path)
|
||||||
{
|
{
|
||||||
FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath)
|
FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath)
|
||||||
.ThrowIfFailure();
|
.ThrowIfFailure();
|
||||||
|
@ -154,7 +154,7 @@ namespace LibHac.Fs
|
||||||
return fileSystem.GetTotalSpaceSize(subPath.ToString());
|
return fileSystem.GetTotalSpaceSize(subPath.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
FileTimeStampRaw GetFileTimeStamp(string path)
|
public FileTimeStampRaw GetFileTimeStamp(string path)
|
||||||
{
|
{
|
||||||
FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath)
|
FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath)
|
||||||
.ThrowIfFailure();
|
.ThrowIfFailure();
|
||||||
|
|
|
@ -230,6 +230,7 @@ namespace LibHac.Fs
|
||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
case NormalizeState.Initial when c == '/': state = NormalizeState.Delimiter; break;
|
case NormalizeState.Initial when c == '/': state = NormalizeState.Delimiter; break;
|
||||||
|
case NormalizeState.Initial when IsValidMountNameChar(c): state = NormalizeState.MountName; break;
|
||||||
case NormalizeState.Initial: return false;
|
case NormalizeState.Initial: return false;
|
||||||
|
|
||||||
case NormalizeState.Normal when c == '/': state = NormalizeState.Delimiter; break;
|
case NormalizeState.Normal when c == '/': state = NormalizeState.Delimiter; break;
|
||||||
|
@ -244,6 +245,13 @@ namespace LibHac.Fs
|
||||||
|
|
||||||
case NormalizeState.DoubleDot when c == '/': return false;
|
case NormalizeState.DoubleDot when c == '/': return false;
|
||||||
case NormalizeState.DoubleDot: state = NormalizeState.Normal; break;
|
case NormalizeState.DoubleDot: state = NormalizeState.Normal; break;
|
||||||
|
|
||||||
|
case NormalizeState.MountName when IsValidMountNameChar(c): break;
|
||||||
|
case NormalizeState.MountName when c == ':': state = NormalizeState.MountDelimiter; break;
|
||||||
|
case NormalizeState.MountName: return false;
|
||||||
|
|
||||||
|
case NormalizeState.MountDelimiter when c == '/': state = NormalizeState.Delimiter; break;
|
||||||
|
case NormalizeState.MountDelimiter: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,6 +267,7 @@ namespace LibHac.Fs
|
||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
case NormalizeState.Initial when c == '/': state = NormalizeState.Delimiter; break;
|
case NormalizeState.Initial when c == '/': state = NormalizeState.Delimiter; break;
|
||||||
|
case NormalizeState.Initial when IsValidMountNameChar(c): state = NormalizeState.MountName; break;
|
||||||
case NormalizeState.Initial: return false;
|
case NormalizeState.Initial: return false;
|
||||||
|
|
||||||
case NormalizeState.Normal when c == '/': state = NormalizeState.Delimiter; break;
|
case NormalizeState.Normal when c == '/': state = NormalizeState.Delimiter; break;
|
||||||
|
@ -273,6 +282,13 @@ namespace LibHac.Fs
|
||||||
|
|
||||||
case NormalizeState.DoubleDot when c == '/': return false;
|
case NormalizeState.DoubleDot when c == '/': return false;
|
||||||
case NormalizeState.DoubleDot: state = NormalizeState.Normal; break;
|
case NormalizeState.DoubleDot: state = NormalizeState.Normal; break;
|
||||||
|
|
||||||
|
case NormalizeState.MountName when IsValidMountNameChar(c): break;
|
||||||
|
case NormalizeState.MountName when c == ':': state = NormalizeState.MountDelimiter; break;
|
||||||
|
case NormalizeState.MountName: return false;
|
||||||
|
|
||||||
|
case NormalizeState.MountDelimiter when c == '/': state = NormalizeState.Delimiter; break;
|
||||||
|
case NormalizeState.MountDelimiter: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,13 +381,23 @@ namespace LibHac.Fs
|
||||||
return ResultFsInvalidMountName;
|
return ResultFsInvalidMountName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool IsValidMountNameChar(char c)
|
||||||
|
{
|
||||||
|
c |= (char)0x20;
|
||||||
|
return c >= 'a' && c <= 'z';
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsValidMountNameChar(byte c) => IsValidMountNameChar((char)c);
|
||||||
|
|
||||||
private enum NormalizeState
|
private enum NormalizeState
|
||||||
{
|
{
|
||||||
Initial,
|
Initial,
|
||||||
Normal,
|
Normal,
|
||||||
Delimiter,
|
Delimiter,
|
||||||
Dot,
|
Dot,
|
||||||
DoubleDot
|
DoubleDot,
|
||||||
|
MountName,
|
||||||
|
MountDelimiter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using LibHac.Fs;
|
using LibHac.Fs;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
@ -68,62 +70,9 @@ namespace LibHac.Tests
|
||||||
new object[] {"/a/b/c/", "/a/b/cd", false},
|
new object[] {"/a/b/c/", "/a/b/cd", false},
|
||||||
};
|
};
|
||||||
|
|
||||||
public static object[][] IsNormalizedTestItems =
|
public static object[][] IsNormalizedTestItems = GetNormalizedPaths(true);
|
||||||
{
|
|
||||||
new object[] {"", "/"},
|
|
||||||
new object[] {"/"},
|
|
||||||
new object[] {"/a/b/c"},
|
|
||||||
new object[] {"/a/c"},
|
|
||||||
new object[] {"/a/b"},
|
|
||||||
new object[] {"/a/b/c"},
|
|
||||||
new object[] {"/"},
|
|
||||||
new object[] {"/a/b/c"},
|
|
||||||
|
|
||||||
new object[] {"/a/b/c/"},
|
public static object[][] IsNotNormalizedTestItems = GetNormalizedPaths(false);
|
||||||
new object[] {"/a/c/"},
|
|
||||||
new object[] {"/c/"},
|
|
||||||
|
|
||||||
new object[] {"/a"},
|
|
||||||
|
|
||||||
new object[] {"a:/a/b/c"},
|
|
||||||
new object[] {"mount:/a/c"},
|
|
||||||
new object[] {"mount:/"},
|
|
||||||
};
|
|
||||||
|
|
||||||
public static object[][] IsNotNormalizedTestItems =
|
|
||||||
{
|
|
||||||
new object[] {""},
|
|
||||||
new object[] {"/."},
|
|
||||||
new object[] {"/a/b/../c", "/a/c"},
|
|
||||||
new object[] {"/a/b/c/..", "/a/b"},
|
|
||||||
new object[] {"/a/b/c/.", "/a/b/c"},
|
|
||||||
new object[] {"/a/../../..", "/"},
|
|
||||||
new object[] {"/a/../../../a/b/c", "/a/b/c"},
|
|
||||||
new object[] {"//a/b//.//c", "/a/b/c"},
|
|
||||||
new object[] {"/../a/b/c/.", "/a/b/c"},
|
|
||||||
new object[] {"/./a/b/c/.", "/a/b/c"},
|
|
||||||
|
|
||||||
new object[] {"/a/b/c/", "/a/b/c/"},
|
|
||||||
new object[] {"/a/./b/../c/", "/a/c/"},
|
|
||||||
new object[] {"/./b/../c/", "/c/"},
|
|
||||||
new object[] {"/a/../../../", "/"},
|
|
||||||
new object[] {"//a/b//.//c/", "/a/b/c/"},
|
|
||||||
new object[] {"/tmp/../", "/"},
|
|
||||||
|
|
||||||
new object[] {"a", "/a"},
|
|
||||||
new object[] {"a/../../../a/b/c", "/a/b/c"},
|
|
||||||
new object[] {"./b/../c/", "/c/"},
|
|
||||||
new object[] {".", "/"},
|
|
||||||
new object[] {"..", "/"},
|
|
||||||
new object[] {"../a/b/c/.", "/a/b/c"},
|
|
||||||
new object[] {"./a/b/c/.", "/a/b/c"},
|
|
||||||
|
|
||||||
new object[] {"a:/a/b/c", "a:/a/b/c"},
|
|
||||||
new object[] {"mount:/a/b/../c", "mount:/a/c"},
|
|
||||||
new object[] {"mount:/a/b/../c", "mount:/a/c"},
|
|
||||||
new object[] {"mount:", "mount:/"},
|
|
||||||
new object[] {"abc:/a/../../../a/b/c", "abc:/a/b/c"},
|
|
||||||
};
|
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(NormalizedPathTestItems))]
|
[MemberData(nameof(NormalizedPathTestItems))]
|
||||||
|
@ -135,12 +84,17 @@ namespace LibHac.Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(NormalizedPathTestItems))]
|
[MemberData(nameof(IsNormalizedTestItems))]
|
||||||
public static void IsNormalized(string path, string expected)
|
public static void IsNormalized(string path)
|
||||||
{
|
{
|
||||||
string actual = PathTools.Normalize(path);
|
Assert.True(PathTools.IsNormalized(path.AsSpan()));
|
||||||
|
}
|
||||||
|
|
||||||
Assert.Equal(expected, actual);
|
[Theory]
|
||||||
|
[MemberData(nameof(IsNotNormalizedTestItems))]
|
||||||
|
public static void IsNotNormalized(string path)
|
||||||
|
{
|
||||||
|
Assert.False(PathTools.IsNormalized(path.AsSpan()));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
@ -151,5 +105,24 @@ namespace LibHac.Tests
|
||||||
|
|
||||||
Assert.Equal(expected, actual);
|
Assert.Equal(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static object[][] GetNormalizedPaths(bool getNormalized)
|
||||||
|
{
|
||||||
|
var normalizedPaths = new HashSet<string>();
|
||||||
|
var notNormalizedPaths = new HashSet<string>();
|
||||||
|
|
||||||
|
foreach (object[] pair in NormalizedPathTestItems)
|
||||||
|
{
|
||||||
|
string pathNotNorm = (string)pair[0];
|
||||||
|
string pathNorm = (string)pair[1];
|
||||||
|
|
||||||
|
if (pathNorm != pathNotNorm) notNormalizedPaths.Add(pathNotNorm);
|
||||||
|
normalizedPaths.Add(pathNorm);
|
||||||
|
}
|
||||||
|
|
||||||
|
HashSet<string> paths = getNormalized ? normalizedPaths : notNormalizedPaths;
|
||||||
|
|
||||||
|
return paths.Select(x => new object[] { x }).ToArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue